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 {
62 explicit DesignatorFolder(
FoldingContext &c,
bool getLastComponent =
false)
63 : context_{c}, getLastComponent_{getLastComponent} {}
65 bool isEmpty()
const {
return isEmpty_; }
66 bool isOutOfRange()
const {
return isOutOfRange_; }
69 std::optional<OffsetSymbol> FoldDesignator(
const Expr<T> &expr) {
71 [&](
const auto &x) {
return FoldDesignator(x, elementNumber_++); },
76 std::optional<OffsetSymbol> FoldDesignator(
const Symbol &, ConstantSubscript);
77 std::optional<OffsetSymbol> FoldDesignator(
78 const SymbolRef &x, ConstantSubscript which) {
79 return FoldDesignator(*x, which);
81 std::optional<OffsetSymbol> FoldDesignator(
82 const ArrayRef &, ConstantSubscript);
83 std::optional<OffsetSymbol> FoldDesignator(
85 std::optional<OffsetSymbol> FoldDesignator(
87 std::optional<OffsetSymbol> FoldDesignator(
89 std::optional<OffsetSymbol> FoldDesignator(
90 const DataRef &, ConstantSubscript);
91 std::optional<OffsetSymbol> FoldDesignator(
93 std::optional<OffsetSymbol> FoldDesignator(
95 std::optional<OffsetSymbol> FoldDesignator(
99 std::optional<OffsetSymbol> FoldDesignator(
100 const Expr<T> &expr, ConstantSubscript which) {
101 return common::visit(
102 [&](
const auto &x) {
return FoldDesignator(x, which); }, expr.u);
105 template <
typename A>
106 std::optional<OffsetSymbol> FoldDesignator(
const A &, ConstantSubscript) {
110 template <
typename T>
111 std::optional<OffsetSymbol> FoldDesignator(
113 return common::visit(
114 [&](
const auto &x) {
return FoldDesignator(x, which); }, designator.u);
117 std::optional<OffsetSymbol> FoldDesignator(
119 ConstantSubscript which) {
120 return common::visit(
123 if (
const auto *dataRef{ss.GetParentIf<
DataRef>()}) {
124 if (
auto result{FoldDesignator(*dataRef, which)}) {
125 if (
auto start{ToInt64(ss.lower())}) {
126 std::optional<ConstantSubscript> end;
127 auto len{dataRef->LEN()};
129 end = ToInt64(*ss.upper());
135 isOutOfRange_ =
true;
137 result->Augment(KIND * (*start - 1));
139 *end >= *start ? KIND * (*end - *start + 1) : 0);
141 if (
auto lenVal{ToInt64(*len)}) {
142 if (*end > *lenVal) {
143 isOutOfRange_ =
true;
152 return std::optional<OffsetSymbol>{};
154 [&](
const auto &x) {
return FoldDesignator(x, which); },
160 bool getLastComponent_{
false};
161 ConstantSubscript elementNumber_{0};
162 bool isEmpty_{
false};
163 bool isOutOfRange_{
false};