54 std::optional<Expr<SubscriptInteger>> LEN()
const;
55 llvm::raw_ostream &AsFortran(llvm::raw_ostream &)
const;
56 const Symbol *symbol()
const {
57 if (
const auto *result{std::get_if<SymbolRef>(&u)}) {
58 return &result->get();
63 std::variant<SymbolRef, StaticDataObject::Pointer> u;
75 CLASS_BOILERPLATE(Component)
76 Component(
const DataRef &b,
const Symbol &c) : base_{b}, symbol_{c} {}
77 Component(
DataRef &&b,
const Symbol &c) : base_{std::move(b)}, symbol_{c} {}
78 Component(common::CopyableIndirection<DataRef> &&b,
const Symbol &c)
79 : base_{std::move(b)}, symbol_{c} {}
81 const DataRef &base()
const {
return base_.value(); }
82 DataRef &base() {
return base_.value(); }
83 const SymbolRef &symbol()
const {
return symbol_; }
84 SymbolRef &symbol() {
return symbol_; }
88 const Symbol &GetFirstSymbol()
const;
89 const Symbol &GetLastSymbol()
const {
return symbol_; }
90 std::optional<Expr<SubscriptInteger>> LEN()
const;
91 bool operator==(
const Component &)
const;
92 llvm::raw_ostream &AsFortran(llvm::raw_ostream &)
const;
95 common::CopyableIndirection<DataRef> base_;
103 CLASS_BOILERPLATE(NamedEntity)
104 explicit NamedEntity(
const Symbol &symbol) : u_{symbol} {}
105 explicit NamedEntity(
Component &&c) : u_{std::move(c)} {}
107 bool IsSymbol()
const {
return std::holds_alternative<SymbolRef>(u_); }
108 const Symbol &GetFirstSymbol()
const;
109 const Symbol &GetLastSymbol()
const;
110 const Component &GetComponent()
const {
return std::get<Component>(u_); }
111 Component &GetComponent() {
return std::get<Component>(u_); }
112 const SymbolRef *UnwrapSymbolRef()
const;
113 SymbolRef *UnwrapSymbolRef();
114 const Component *UnwrapComponent()
const;
119 std::optional<Expr<SubscriptInteger>> LEN()
const;
120 bool operator==(
const NamedEntity &)
const;
121 llvm::raw_ostream &AsFortran(llvm::raw_ostream &)
const;
124 std::variant<SymbolRef, Component> u_;
136class TypeParamInquiry {
138 using Result = SubscriptInteger;
139 CLASS_BOILERPLATE(TypeParamInquiry)
141 : base_{std::move(x)}, parameter_{param} {}
142 TypeParamInquiry(std::optional<NamedEntity> &&x,
const Symbol ¶m)
143 : base_{std::move(x)}, parameter_{param} {}
145 const std::optional<NamedEntity> &base()
const {
return base_; }
146 std::optional<NamedEntity> &base() {
return base_; }
147 const Symbol ¶meter()
const {
return parameter_; }
149 static constexpr int Rank() {
return 0; }
150 static constexpr int Corank() {
return 0; }
151 bool operator==(
const TypeParamInquiry &)
const;
152 llvm::raw_ostream &AsFortran(llvm::raw_ostream &)
const;
155 std::optional<NamedEntity> base_;
156 SymbolRef parameter_;
163 DEFAULT_CONSTRUCTORS_AND_ASSIGNMENTS(Triplet)
168 std::optional<Expr<SubscriptInteger>> lower()
const;
170 return lower_.has_value() ? &lower_->value() :
nullptr;
173 std::optional<Expr<SubscriptInteger>> upper()
const;
175 return upper_.has_value() ? &upper_->value() :
nullptr;
182 bool operator==(
const Triplet &)
const;
183 llvm::raw_ostream &AsFortran(llvm::raw_ostream &)
const;
186 std::optional<IndirectSubscriptIntegerExpr> lower_, upper_;
187 IndirectSubscriptIntegerExpr stride_;
207 CLASS_BOILERPLATE(ArrayRef)
208 ArrayRef(
const Symbol &symbol, std::vector<Subscript> &&ss)
209 : base_{symbol}, subscript_(std::move(ss)) {}
210 ArrayRef(
Component &&c, std::vector<Subscript> &&ss)
211 : base_{std::move(c)}, subscript_(std::move(ss)) {}
212 ArrayRef(
NamedEntity &&base, std::vector<Subscript> &&ss)
213 : base_{std::move(base)}, subscript_(std::move(ss)) {}
217 std::vector<Subscript> &subscript() {
return subscript_; }
218 const std::vector<Subscript> &subscript()
const {
return subscript_; }
220 int size()
const {
return static_cast<int>(subscript_.size()); }
221 Subscript &at(
int n) {
return subscript_.at(n); }
222 const Subscript &at(
int n)
const {
return subscript_.at(n); }
223 template <
typename A> common::IfNoLvalue<Subscript &, A> emplace_back(A &&x) {
224 return subscript_.emplace_back(std::move(x));
229 const Symbol &GetFirstSymbol()
const;
230 const Symbol &GetLastSymbol()
const;
231 std::optional<Expr<SubscriptInteger>> LEN()
const;
232 bool operator==(
const ArrayRef &)
const;
233 llvm::raw_ostream &AsFortran(llvm::raw_ostream &)
const;
237 std::vector<Subscript> subscript_;
245 CLASS_BOILERPLATE(CoarrayRef)
248 const DataRef &base()
const {
return base_.value(); }
249 DataRef &base() {
return base_.value(); }
250 const std::vector<Expr<SubscriptInteger>> &cosubscript()
const {
253 std::vector<Expr<SubscriptInteger>> &cosubscript() {
return cosubscript_; }
257 std::optional<Expr<SomeInteger>> stat()
const;
261 std::optional<Expr<SomeType>> team()
const;
265 int Corank()
const {
return 0; }
266 const Symbol &GetFirstSymbol()
const;
267 const Symbol &GetLastSymbol()
const;
268 std::optional<Expr<SubscriptInteger>> LEN()
const;
269 bool operator==(
const CoarrayRef &)
const;
270 llvm::raw_ostream &AsFortran(llvm::raw_ostream &)
const;
273 common::CopyableIndirection<DataRef> base_;
274 std::vector<Expr<SubscriptInteger>> cosubscript_;
275 std::optional<common::CopyableIndirection<Expr<SomeInteger>>> stat_;
276 std::optional<common::CopyableIndirection<Expr<SomeType>>> team_;
285 EVALUATE_UNION_CLASS_BOILERPLATE(
DataRef)
288 const Symbol &GetFirstSymbol()
const;
289 const Symbol &GetLastSymbol()
const;
290 std::optional<Expr<SubscriptInteger>> LEN()
const;
291 llvm::raw_ostream &AsFortran(llvm::raw_ostream &)
const;
293 std::variant<SymbolRef, Component, ArrayRef, CoarrayRef> u;
301 using Parent = std::variant<DataRef, StaticDataObject::Pointer>;
304 CLASS_BOILERPLATE(Substring)
307 : parent_{std::move(parent)} {
308 SetBounds(lower, upper);
310 Substring(StaticDataObject::Pointer &&parent,
313 : parent_{std::move(parent)} {
314 SetBounds(lower, upper);
319 return lower_.has_value() ? &lower_->value() :
nullptr;
322 std::optional<Expr<SubscriptInteger>> upper()
const;
324 return upper_.has_value() ? &upper_->value() :
nullptr;
327 const Parent &parent()
const {
return parent_; }
328 Parent &parent() {
return parent_; }
332 template <
typename A>
const A *GetParentIf()
const {
333 return std::get_if<A>(&parent_);
336 const Symbol *GetLastSymbol()
const;
337 std::optional<Expr<SubscriptInteger>> LEN()
const;
338 bool operator==(
const Substring &)
const;
339 llvm::raw_ostream &AsFortran(llvm::raw_ostream &)
const;
347 std::optional<IndirectSubscriptIntegerExpr> lower_, upper_;
355 ENUM_CLASS(Part, RE, IM)
356 CLASS_BOILERPLATE(ComplexPart)
357 ComplexPart(
DataRef &&z, Part p) : complex_{std::move(z)}, part_{p} {}
358 DataRef &complex() {
return complex_; }
359 const DataRef &complex()
const {
return complex_; }
360 Part part()
const {
return part_; }
363 const Symbol &GetFirstSymbol()
const {
return complex_.GetFirstSymbol(); }
364 const Symbol &GetLastSymbol()
const {
return complex_.GetLastSymbol(); }
365 bool operator==(
const ComplexPart &)
const;
366 llvm::raw_ostream &AsFortran(llvm::raw_ostream &)
const;
377template <
typename T>
class Designator {
378 using DataRefs = std::decay_t<
decltype(DataRef::u)>;
379 using MaybeSubstring =
380 std::conditional_t<T::category == TypeCategory::Character,
381 std::variant<Substring>, std::variant<>>;
382 using MaybeComplexPart = std::conditional_t<T::category == TypeCategory::Real,
383 std::variant<ComplexPart>, std::variant<>>;
385 common::CombineVariants<DataRefs, MaybeSubstring, MaybeComplexPart>;
390 IsSpecificIntrinsicType<Result> || std::is_same_v<Result, SomeDerived>);
391 EVALUATE_UNION_CLASS_BOILERPLATE(Designator)
392 Designator(
const DataRef &that) : u{common::CopyVariant<Variant>(that.u)} {}
394 : u{common::MoveVariant<Variant>(std::move(that.u))} {}
396 std::optional<DynamicType> GetType()
const;
400 const Symbol *GetLastSymbol()
const;
401 std::optional<Expr<SubscriptInteger>> LEN()
const;
402 llvm::raw_ostream &AsFortran(llvm::raw_ostream &o)
const;
409class DescriptorInquiry {
411 using Result = SubscriptInteger;
412 ENUM_CLASS(Field, LowerBound, Extent, Stride, Rank, Len)
414 CLASS_BOILERPLATE(DescriptorInquiry)
415 DescriptorInquiry(
const NamedEntity &, Field,
int = 0);
420 Field field()
const {
return field_; }
421 int dimension()
const {
return dimension_; }
423 static constexpr int Rank() {
return 0; }
424 static constexpr int Corank() {
return 0; }
425 bool operator==(
const DescriptorInquiry &)
const;
426 llvm::raw_ostream &AsFortran(llvm::raw_ostream &)
const;