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;
264 std::optional<Expr<SomeType>> notify()
const;
268 int Corank()
const {
return 0; }
269 const Symbol &GetFirstSymbol()
const;
270 const Symbol &GetLastSymbol()
const;
271 std::optional<Expr<SubscriptInteger>> LEN()
const;
272 bool operator==(
const CoarrayRef &)
const;
273 llvm::raw_ostream &AsFortran(llvm::raw_ostream &)
const;
276 common::CopyableIndirection<DataRef> base_;
277 std::vector<Expr<SubscriptInteger>> cosubscript_;
278 std::optional<common::CopyableIndirection<Expr<SomeType>>> notify_;
279 std::optional<common::CopyableIndirection<Expr<SomeInteger>>> stat_;
280 std::optional<common::CopyableIndirection<Expr<SomeType>>> team_;
289 EVALUATE_UNION_CLASS_BOILERPLATE(
DataRef)
292 const Symbol &GetFirstSymbol()
const;
293 const Symbol &GetLastSymbol()
const;
294 std::optional<Expr<SubscriptInteger>> LEN()
const;
295 llvm::raw_ostream &AsFortran(llvm::raw_ostream &)
const;
297 std::variant<SymbolRef, Component, ArrayRef, CoarrayRef> u;
305 using Parent = std::variant<DataRef, StaticDataObject::Pointer>;
308 CLASS_BOILERPLATE(Substring)
311 : parent_{std::move(parent)} {
312 SetBounds(lower, upper);
314 Substring(StaticDataObject::Pointer &&parent,
317 : parent_{std::move(parent)} {
318 SetBounds(lower, upper);
323 return lower_.has_value() ? &lower_->value() :
nullptr;
326 std::optional<Expr<SubscriptInteger>> upper()
const;
328 return upper_.has_value() ? &upper_->value() :
nullptr;
331 const Parent &parent()
const {
return parent_; }
332 Parent &parent() {
return parent_; }
336 template <
typename A>
const A *GetParentIf()
const {
337 return std::get_if<A>(&parent_);
340 const Symbol *GetLastSymbol()
const;
341 std::optional<Expr<SubscriptInteger>> LEN()
const;
342 bool operator==(
const Substring &)
const;
343 llvm::raw_ostream &AsFortran(llvm::raw_ostream &)
const;
351 std::optional<IndirectSubscriptIntegerExpr> lower_, upper_;
359 ENUM_CLASS(Part, RE, IM)
360 CLASS_BOILERPLATE(ComplexPart)
361 ComplexPart(
DataRef &&z, Part p) : complex_{std::move(z)}, part_{p} {}
362 DataRef &complex() {
return complex_; }
363 const DataRef &complex()
const {
return complex_; }
364 Part part()
const {
return part_; }
367 const Symbol &GetFirstSymbol()
const {
return complex_.GetFirstSymbol(); }
368 const Symbol &GetLastSymbol()
const {
return complex_.GetLastSymbol(); }
369 bool operator==(
const ComplexPart &)
const;
370 llvm::raw_ostream &AsFortran(llvm::raw_ostream &)
const;
381template <
typename T>
class Designator {
382 using DataRefs = std::decay_t<
decltype(DataRef::u)>;
383 using MaybeSubstring =
384 std::conditional_t<T::category == TypeCategory::Character,
385 std::variant<Substring>, std::variant<>>;
386 using MaybeComplexPart = std::conditional_t<T::category == TypeCategory::Real,
387 std::variant<ComplexPart>, std::variant<>>;
389 common::CombineVariants<DataRefs, MaybeSubstring, MaybeComplexPart>;
394 IsSpecificIntrinsicType<Result> || std::is_same_v<Result, SomeDerived>);
395 EVALUATE_UNION_CLASS_BOILERPLATE(Designator)
396 Designator(
const DataRef &that) : u{common::CopyVariant<Variant>(that.u)} {}
398 : u{common::MoveVariant<Variant>(std::move(that.u))} {}
400 std::optional<DynamicType> GetType()
const;
404 const Symbol *GetLastSymbol()
const;
405 std::optional<Expr<SubscriptInteger>> LEN()
const;
406 llvm::raw_ostream &AsFortran(llvm::raw_ostream &o)
const;
413class DescriptorInquiry {
415 using Result = SubscriptInteger;
416 ENUM_CLASS(Field, LowerBound, Extent, Stride, Rank, Len)
418 CLASS_BOILERPLATE(DescriptorInquiry)
419 DescriptorInquiry(
const NamedEntity &, Field,
int = 0);
424 Field field()
const {
return field_; }
425 int dimension()
const {
return dimension_; }
427 static constexpr int Rank() {
return 0; }
428 static constexpr int Corank() {
return 0; }
429 bool operator==(
const DescriptorInquiry &)
const;
430 llvm::raw_ostream &AsFortran(llvm::raw_ostream &)
const;