40 OffsetSymbol(
const Symbol &symbol, std::size_t bytes)
41 : symbol_{symbol}, size_{bytes} {}
42 DECLARE_CONSTRUCTORS_AND_ASSIGNMENTS(OffsetSymbol)
44 const Symbol &symbol()
const {
return *symbol_; }
45 void set_symbol(
const Symbol &symbol) { symbol_ = symbol; };
46 ConstantSubscript offset()
const {
return offset_; }
47 void Augment(ConstantSubscript n) { offset_ += n; }
48 std::size_t size()
const {
return size_; }
49 void set_size(std::size_t bytes) { size_ = bytes; }
53 ConstantSubscript offset_{0};
60class DesignatorFolder {
67 explicit DesignatorFolder(
FoldingContext &c,
bool getLastComponent =
false,
68 bool foldNamedConstants =
false)
69 : context_{c}, getLastComponent_{getLastComponent},
70 foldNamedConstants_{foldNamedConstants} {}
72 bool isEmpty()
const {
return isEmpty_; }
73 bool isOutOfRange()
const {
return isOutOfRange_; }
76 std::optional<OffsetSymbol> FoldDesignator(
const Expr<T> &expr) {
78 [&](
const auto &x) {
return FoldDesignator(x, elementNumber_++); },
83 std::optional<OffsetSymbol> FoldDesignator(
const Symbol &, ConstantSubscript);
84 std::optional<OffsetSymbol> FoldDesignator(
85 const SymbolRef &x, ConstantSubscript which) {
86 return FoldDesignator(*x, which);
88 std::optional<OffsetSymbol> FoldDesignator(
89 const ArrayRef &, ConstantSubscript);
90 std::optional<OffsetSymbol> FoldDesignator(
92 std::optional<OffsetSymbol> FoldDesignator(
94 std::optional<OffsetSymbol> FoldDesignator(
96 std::optional<OffsetSymbol> FoldDesignator(
97 const DataRef &, ConstantSubscript);
98 std::optional<OffsetSymbol> FoldDesignator(
100 std::optional<OffsetSymbol> FoldDesignator(
102 std::optional<OffsetSymbol> FoldDesignator(
105 template <
typename T>
106 std::optional<OffsetSymbol> FoldDesignator(
107 const Expr<T> &expr, ConstantSubscript which) {
108 return common::visit(
109 [&](
const auto &x) {
return FoldDesignator(x, which); }, expr.u);
112 template <
typename A>
113 std::optional<OffsetSymbol> FoldDesignator(
const A &, ConstantSubscript) {
117 template <
typename T>
118 std::optional<OffsetSymbol> FoldDesignator(
120 return common::visit(
121 [&](
const auto &x) {
return FoldDesignator(x, which); }, designator.u);
124 std::optional<OffsetSymbol> FoldDesignator(
126 ConstantSubscript which) {
127 return common::visit(
130 if (
const auto *dataRef{ss.GetParentIf<
DataRef>()}) {
131 if (
auto result{FoldDesignator(*dataRef, which)}) {
132 if (
auto start{ToInt64(ss.lower())}) {
133 std::optional<ConstantSubscript> end;
134 auto len{dataRef->LEN()};
136 end = ToInt64(*ss.upper());
142 isOutOfRange_ =
true;
144 result->Augment(KIND * (*start - 1));
146 *end >= *start ? KIND * (*end - *start + 1) : 0);
148 if (
auto lenVal{ToInt64(*len)}) {
149 if (*end > *lenVal) {
150 isOutOfRange_ =
true;
159 return std::optional<OffsetSymbol>{};
161 [&](
const auto &x) {
return FoldDesignator(x, which); },
167 bool getLastComponent_{
false};
168 bool foldNamedConstants_{
false};
169 ConstantSubscript elementNumber_{0};
170 bool isEmpty_{
false};
171 bool isOutOfRange_{
false};