9#ifndef FORTRAN_EVALUATE_TRAVERSE_H_
10#define FORTRAN_EVALUATE_TRAVERSE_H_
40#include "expression.h"
41#include "flang/Common/indirection.h"
42#include "flang/Semantics/symbol.h"
43#include "flang/Semantics/type.h"
48template <
typename Visitor,
typename Result,
49 bool TraverseAssocEntityDetails =
true>
52 explicit Traverse(Visitor &v) : visitor_{v} {}
55 template <
typename A,
bool C>
57 return visitor_(x.value());
61 return visitor_(p.get());
63 template <
typename _> Result operator()(
const SymbolRef x)
const {
66 template <
typename A> Result operator()(
const std::unique_ptr<A> &x)
const {
67 return visitor_(x.get());
69 template <
typename A> Result operator()(
const std::shared_ptr<A> &x)
const {
70 return visitor_(x.get());
72 template <
typename A> Result operator()(
const A *x)
const {
76 return visitor_.Default();
79 template <
typename A> Result operator()(
const std::optional<A> &x)
const {
83 return visitor_.Default();
86 template <
typename... As>
87 Result operator()(
const std::variant<As...> &u)
const {
88 return common::visit([=](
const auto &y) {
return visitor_(y); }, u);
90 template <
typename A> Result operator()(
const std::vector<A> &x)
const {
91 return CombineContents(x);
93 template <
typename A,
typename B>
94 Result operator()(
const std::pair<A, B> &x)
const {
95 return Combine(x.first, x.second);
99 Result operator()(
const BOZLiteralConstant &)
const {
100 return visitor_.Default();
102 Result operator()(
const NullPointer &)
const {
return visitor_.Default(); }
103 template <
typename T> Result operator()(
const Constant<T> &x)
const {
104 if constexpr (T::category == TypeCategory::Derived) {
105 return visitor_.Combine(
106 visitor_(x.result().derivedTypeSpec()), CombineContents(x.values()));
108 return visitor_.Default();
111 Result operator()(
const Symbol &symbol)
const {
112 const Symbol &ultimate{symbol.GetUltimate()};
113 if constexpr (TraverseAssocEntityDetails) {
114 if (
const auto *assoc{
116 return visitor_(assoc->expr());
119 return visitor_.Default();
122 return visitor_.Default();
124 Result operator()(
const ImpliedDoIndex &)
const {
return visitor_.Default(); }
127 Result operator()(
const BaseObject &x)
const {
return visitor_(x.u); }
128 Result operator()(
const Component &x)
const {
129 return Combine(x.base(), x.symbol());
132 if (
const Component * component{x.UnwrapComponent()}) {
133 return visitor_(*component);
135 return visitor_(DEREF(x.UnwrapSymbolRef()));
139 return visitor_(x.base());
141 Result operator()(
const Triplet &x)
const {
142 return Combine(x.GetLower(), x.GetUpper(), x.GetStride());
144 Result operator()(
const Subscript &x)
const {
return visitor_(x.u); }
145 Result operator()(
const ArrayRef &x)
const {
146 return Combine(x.base(), x.subscript());
148 Result operator()(
const CoarrayRef &x)
const {
150 x.base(), x.subscript(), x.cosubscript(), x.stat(), x.team());
152 Result operator()(
const DataRef &x)
const {
return visitor_(x.u); }
153 Result operator()(
const Substring &x)
const {
154 return Combine(x.parent(), x.GetLower(), x.GetUpper());
157 return visitor_(x.complex());
159 template <
typename T> Result operator()(
const Designator<T> &x)
const {
160 return visitor_(x.u);
162 template <
typename T> Result operator()(
const Variable<T> &x)
const {
163 return visitor_(x.u);
166 return visitor_(x.base());
171 return visitor_.Default();
174 if (
const Component * component{x.GetComponent()}) {
175 return visitor_(*component);
176 }
else if (
const Symbol * symbol{x.GetSymbol()}) {
177 return visitor_(*symbol);
179 return visitor_(DEREF(x.GetSpecificIntrinsic()));
183 if (
const auto *symbol{x.GetAssumedTypeDummy()}) {
184 return visitor_(*symbol);
186 return visitor_(x.UnwrapExpr());
190 return Combine(x.proc(), x.arguments());
192 template <
typename T> Result operator()(
const FunctionRef<T> &x)
const {
197 template <
typename T>
199 return visitor_(x.u);
201 template <
typename T>
203 return CombineContents(x);
205 template <
typename T> Result operator()(
const ImpliedDo<T> &x)
const {
206 return Combine(x.lower(), x.upper(), x.stride(), x.values());
209 return visitor_(x.GetExplicit());
212 const semantics::DerivedTypeSpec::ParameterMapType::value_type &x)
const {
213 return visitor_(x.second);
216 const semantics::DerivedTypeSpec::ParameterMapType &x)
const {
217 return CombineContents(x);
220 return Combine(x.originalTypeSymbol(), x.parameters());
222 Result operator()(
const StructureConstructorValues::value_type &x)
const {
223 return visitor_(x.second);
225 Result operator()(
const StructureConstructorValues &x)
const {
226 return CombineContents(x);
229 return visitor_.Combine(visitor_(x.derivedTypeSpec()), CombineContents(x));
233 template <
typename D,
typename R,
typename O>
235 return visitor_(op.left());
237 template <
typename D,
typename R,
typename LO,
typename RO>
239 return Combine(op.left(), op.right());
242 return visitor_(x.u);
244 template <
typename T> Result operator()(
const Expr<T> &x)
const {
245 return visitor_(x.u);
247 Result operator()(
const Assignment &x)
const {
248 return Combine(x.lhs, x.rhs, x.u);
251 return visitor_.Default();
255 return visitor_(x.v);
259 template <
typename ITER> Result CombineRange(ITER iter, ITER end)
const {
261 return visitor_.Default();
263 Result result{visitor_(*iter)};
264 for (++iter; iter != end; ++iter) {
265 result = visitor_.Combine(std::move(result), visitor_(*iter));
271 template <
typename A> Result CombineContents(
const A &x)
const {
272 return CombineRange(x.begin(), x.end());
275 template <
typename A,
typename... Bs>
276 Result Combine(
const A &x,
const Bs &...ys)
const {
277 if constexpr (
sizeof...(Bs) == 0) {
280 return visitor_.Combine(visitor_(x), Combine(ys...));
289template <
typename Visitor,
bool DefaultValue,
290 bool TraverseAssocEntityDetails =
true,
294 using Base::operator();
295 static bool Default() {
return DefaultValue; }
296 static bool Combine(
bool x,
bool y) {
return x && y; }
302template <
typename Visitor,
typename Result = bool,
303 bool TraverseAssocEntityDetails =
true,
308 using Base::operator();
309 Result Default()
const {
return default_; }
310 static Result Combine(Result &&x, Result &&y) {
322template <
typename Visitor,
typename Set,
323 bool TraverseAssocEntityDetails =
true,
327 using Base::operator();
328 static Set Default() {
return {}; }
329 static Set Combine(Set &&x, Set &&y) {
330#if defined __GNUC__ && !defined __APPLE__ && !(CLANG_LIBRARIES)
334 for (
auto &value : y) {
335 x.insert(std::move(value));
Definition: indirection.h:127
Definition: indirection.h:31
Definition: traverse.h:305
Definition: expression.h:438
Definition: variable.h:208
Definition: expression.h:878
Definition: variable.h:255
Definition: variable.h:369
Definition: variable.h:74
Definition: constant.h:141
Definition: variable.h:425
Definition: variable.h:393
Definition: expression.h:404
Definition: variable.h:104
Definition: expression.h:114
Definition: expression.h:656
Definition: static-data.h:29
Definition: expression.h:740
Definition: variable.h:316
Definition: traverse.h:50
Definition: variable.h:163
Definition: variable.h:139
Definition: traverse.h:292
Definition: expression.h:432
Definition: expression.h:883
Definition: variable.h:51
Definition: variable.h:300
Definition: expression.h:906
Definition: expression.h:896
Definition: expression.h:396
Definition: expression.h:827
Definition: traverse.h:325
Definition: variable.h:194
Definition: variable.h:47