9#ifndef FORTRAN_EVALUATE_VARIABLE_H_
10#define FORTRAN_EVALUATE_VARIABLE_H_
20#include "formatting.h"
21#include "static-data.h"
23#include "flang/Common/idioms.h"
24#include "flang/Common/reference.h"
25#include "flang/Common/template.h"
26#include "flang/Parser/char-block.h"
35namespace Fortran::semantics {
41using semantics::Symbol;
42using SymbolRef = common::Reference<const Symbol>;
43using SymbolVector = std::vector<SymbolRef>;
55 std::optional<Expr<SubscriptInteger>> LEN()
const;
56 llvm::raw_ostream &AsFortran(llvm::raw_ostream &)
const;
57 const Symbol *symbol()
const {
58 if (
const auto *result{std::get_if<SymbolRef>(&u)}) {
59 return &result->get();
64 std::variant<SymbolRef, StaticDataObject::Pointer> u;
80 : base_{std::move(b)}, symbol_{c} {}
82 const DataRef &base()
const {
return base_.value(); }
83 DataRef &base() {
return base_.value(); }
84 const SymbolRef &symbol()
const {
return symbol_; }
89 const Symbol &GetFirstSymbol()
const;
90 const Symbol &GetLastSymbol()
const {
return symbol_; }
91 std::optional<Expr<SubscriptInteger>> LEN()
const;
93 llvm::raw_ostream &AsFortran(llvm::raw_ostream &)
const;
110 bool IsSymbol()
const {
return std::holds_alternative<SymbolRef>(u_); }
111 const Symbol &GetFirstSymbol()
const;
112 const Symbol &GetLastSymbol()
const;
113 const Component &GetComponent()
const {
return std::get<Component>(u_); }
114 Component &GetComponent() {
return std::get<Component>(u_); }
115 const SymbolRef *UnwrapSymbolRef()
const;
117 const Component *UnwrapComponent()
const;
122 std::optional<Expr<SubscriptInteger>> LEN()
const;
124 llvm::raw_ostream &AsFortran(llvm::raw_ostream &)
const;
127 std::variant<SymbolRef, Component> u_;
144 : base_{std::move(x)}, parameter_{param} {}
146 : base_{std::move(x)}, parameter_{param} {}
148 const std::optional<NamedEntity> &base()
const {
return base_; }
149 std::optional<NamedEntity> &base() {
return base_; }
150 const Symbol ¶meter()
const {
return parameter_; }
152 static constexpr int Rank() {
return 0; }
153 static constexpr int Corank() {
return 0; }
155 llvm::raw_ostream &AsFortran(llvm::raw_ostream &)
const;
158 std::optional<NamedEntity> base_;
166 DEFAULT_CONSTRUCTORS_AND_ASSIGNMENTS(
Triplet)
171 std::optional<Expr<SubscriptInteger>> lower()
const;
173 return lower_.has_value() ? &lower_->value() :
nullptr;
176 std::optional<Expr<SubscriptInteger>> upper()
const;
178 return upper_.has_value() ? &upper_->value() :
nullptr;
185 bool operator==(
const Triplet &)
const;
186 llvm::raw_ostream &AsFortran(llvm::raw_ostream &)
const;
189 std::optional<IndirectSubscriptIntegerExpr> lower_, upper_;
195 EVALUATE_UNION_CLASS_BOILERPLATE(
Subscript)
197 : u{IndirectSubscriptIntegerExpr::Make(std::move(s))} {}
199 llvm::raw_ostream &AsFortran(llvm::raw_ostream &)
const;
200 std::variant<IndirectSubscriptIntegerExpr, Triplet> u;
212 : base_{symbol}, subscript_(std::move(ss)) {}
214 : base_{std::move(c)}, subscript_(std::move(ss)) {}
216 : base_{std::move(base)}, subscript_(std::move(ss)) {}
220 std::vector<Subscript> &subscript() {
return subscript_; }
221 const std::vector<Subscript> &subscript()
const {
return subscript_; }
223 int size()
const {
return static_cast<int>(subscript_.size()); }
224 Subscript &at(
int n) {
return subscript_.at(n); }
225 const Subscript &at(
int n)
const {
return subscript_.at(n); }
226 template <
typename A> common::IfNoLvalue<Subscript &, A> emplace_back(A &&x) {
227 return subscript_.emplace_back(std::move(x));
232 const Symbol &GetFirstSymbol()
const;
233 const Symbol &GetLastSymbol()
const;
234 std::optional<Expr<SubscriptInteger>> LEN()
const;
235 bool operator==(
const ArrayRef &)
const;
236 llvm::raw_ostream &AsFortran(llvm::raw_ostream &)
const;
240 std::vector<Subscript> subscript_;
258 CoarrayRef(SymbolVector &&, std::vector<Subscript> &&,
261 const SymbolVector &base()
const {
return base_; }
262 SymbolVector &base() {
return base_; }
263 const std::vector<Subscript> &subscript()
const {
return subscript_; }
264 std::vector<Subscript> &subscript() {
return subscript_; }
265 const std::vector<Expr<SubscriptInteger>> &cosubscript()
const {
268 std::vector<Expr<SubscriptInteger>> &cosubscript() {
return cosubscript_; }
272 std::optional<Expr<SomeInteger>> stat()
const;
274 std::optional<Expr<SomeInteger>> team()
const;
275 bool teamIsTeamNumber()
const {
return teamIsTeamNumber_; }
279 int Corank()
const {
return 0; }
280 const Symbol &GetFirstSymbol()
const;
281 const Symbol &GetLastSymbol()
const;
283 std::optional<Expr<SubscriptInteger>> LEN()
const;
285 llvm::raw_ostream &AsFortran(llvm::raw_ostream &)
const;
289 std::vector<Subscript> subscript_;
290 std::vector<Expr<SubscriptInteger>> cosubscript_;
291 std::optional<common::CopyableIndirection<Expr<SomeInteger>>> stat_, team_;
292 bool teamIsTeamNumber_{
false};
301 EVALUATE_UNION_CLASS_BOILERPLATE(
DataRef)
304 const Symbol &GetFirstSymbol()
const;
305 const Symbol &GetLastSymbol()
const;
306 std::optional<Expr<SubscriptInteger>> LEN()
const;
307 llvm::raw_ostream &AsFortran(llvm::raw_ostream &)
const;
309 std::variant<SymbolRef, Component, ArrayRef, CoarrayRef> u;
317 using Parent = std::variant<DataRef, StaticDataObject::Pointer>;
323 : parent_{std::move(parent)} {
324 SetBounds(lower, upper);
326 Substring(StaticDataObject::Pointer &&parent,
329 : parent_{std::move(parent)} {
330 SetBounds(lower, upper);
335 return lower_.has_value() ? &lower_->value() :
nullptr;
338 std::optional<Expr<SubscriptInteger>> upper()
const;
340 return upper_.has_value() ? &upper_->value() :
nullptr;
343 const Parent &parent()
const {
return parent_; }
344 Parent &parent() {
return parent_; }
348 template <
typename A>
const A *GetParentIf()
const {
349 return std::get_if<A>(&parent_);
352 const Symbol *GetLastSymbol()
const;
353 std::optional<Expr<SubscriptInteger>> LEN()
const;
354 bool operator==(
const Substring &)
const;
355 llvm::raw_ostream &AsFortran(llvm::raw_ostream &)
const;
363 std::optional<IndirectSubscriptIntegerExpr> lower_, upper_;
371 ENUM_CLASS(Part, RE, IM)
374 DataRef &complex() {
return complex_; }
375 const DataRef &complex()
const {
return complex_; }
376 Part part()
const {
return part_; }
379 const Symbol &GetFirstSymbol()
const {
return complex_.GetFirstSymbol(); }
380 const Symbol &GetLastSymbol()
const {
return complex_.GetLastSymbol(); }
382 llvm::raw_ostream &AsFortran(llvm::raw_ostream &)
const;
394 using DataRefs = std::decay_t<
decltype(DataRef::u)>;
395 using MaybeSubstring =
396 std::conditional_t<T::category == TypeCategory::Character,
397 std::variant<Substring>, std::variant<>>;
398 using MaybeComplexPart = std::conditional_t<T::category == TypeCategory::Real,
399 std::variant<ComplexPart>, std::variant<>>;
401 common::CombineVariants<DataRefs, MaybeSubstring, MaybeComplexPart>;
406 IsSpecificIntrinsicType<Result> || std::is_same_v<Result, SomeDerived>);
410 : u{common::MoveVariant<Variant>(std::move(that.u))} {}
412 std::optional<DynamicType> GetType()
const;
416 const Symbol *GetLastSymbol()
const;
417 std::optional<Expr<SubscriptInteger>> LEN()
const;
418 llvm::raw_ostream &AsFortran(llvm::raw_ostream &o)
const;
423FOR_EACH_CHARACTER_KIND(
extern template class Designator, )
428 ENUM_CLASS(Field, LowerBound, Extent, Stride, Rank, Len)
436 Field field()
const {
return field_; }
437 int dimension()
const {
return dimension_; }
439 static constexpr int Rank() {
return 0; }
440 static constexpr int Corank() {
return 0; }
442 llvm::raw_ostream &AsFortran(llvm::raw_ostream &)
const;
450#define INSTANTIATE_VARIABLE_TEMPLATES \
451 FOR_EACH_SPECIFIC_TYPE(template class Designator, )
Definition: indirection.h:72
Definition: variable.h:208
Definition: variable.h:255
Definition: variable.h:369
Definition: variable.h:74
Definition: variable.h:425
Definition: variable.h:393
Definition: variable.h:104
Definition: variable.h:316
Definition: variable.h:163
Definition: variable.h:139
Definition: variable.h:51
Definition: variable.h:300
Definition: variable.h:194
Definition: variable.h:47