50 explicit Traverse(Visitor &v) : visitor_{v} {}
53 template <
typename A,
bool C>
55 return visitor_(x.value());
59 return visitor_(p.get());
61 template <
typename _> Result operator()(
const SymbolRef x)
const {
64 template <
typename A> Result operator()(
const std::unique_ptr<A> &x)
const {
65 return visitor_(x.get());
67 template <
typename A> Result operator()(
const std::shared_ptr<A> &x)
const {
68 return visitor_(x.get());
70 template <
typename A> Result operator()(
const A *x)
const {
74 return visitor_.Default();
77 template <
typename A> Result operator()(
const std::optional<A> &x)
const {
81 return visitor_.Default();
84 template <
typename... As>
85 Result operator()(
const std::variant<As...> &u)
const {
86 return common::visit([=](
const auto &y) {
return visitor_(y); }, u);
88 template <
typename A> Result operator()(
const std::vector<A> &x)
const {
89 return CombineContents(x);
91 template <
typename A,
typename B>
92 Result operator()(
const std::pair<A, B> &x)
const {
93 return Combine(x.first, x.second);
97 Result operator()(
const BOZLiteralConstant &)
const {
98 return visitor_.Default();
100 Result operator()(
const NullPointer &)
const {
return visitor_.Default(); }
101 template <
typename T> Result operator()(
const Constant<T> &x)
const {
102 if constexpr (T::category == TypeCategory::Derived) {
103 return visitor_.Combine(
104 visitor_(x.result().derivedTypeSpec()), CombineContents(x.values()));
106 return visitor_.Default();
109 Result operator()(
const Symbol &symbol)
const {
110 const Symbol &ultimate{symbol.GetUltimate()};
111 if constexpr (TraverseAssocEntityDetails) {
112 if (
const auto *assoc{
114 return visitor_(assoc->expr());
117 return visitor_.Default();
120 return visitor_.Default();
122 Result operator()(
const ImpliedDoIndex &)
const {
return visitor_.Default(); }
125 Result operator()(
const BaseObject &x)
const {
return visitor_(x.u); }
126 Result operator()(
const Component &x)
const {
127 return Combine(x.base(), x.symbol());
130 if (
const Component * component{x.UnwrapComponent()}) {
131 return visitor_(*component);
133 return visitor_(DEREF(x.UnwrapSymbolRef()));
137 return visitor_(x.base());
139 Result operator()(
const Triplet &x)
const {
140 return Combine(x.GetLower(), x.GetUpper(), x.GetStride());
142 Result operator()(
const Subscript &x)
const {
return visitor_(x.u); }
143 Result operator()(
const ArrayRef &x)
const {
144 return Combine(x.base(), x.subscript());
146 Result operator()(
const CoarrayRef &x)
const {
147 return Combine(x.base(), x.cosubscript(), x.notify(), x.stat(), x.team());
149 Result operator()(
const DataRef &x)
const {
return visitor_(x.u); }
150 Result operator()(
const Substring &x)
const {
151 return Combine(x.parent(), x.GetLower(), x.GetUpper());
154 return visitor_(x.complex());
156 template <
typename T> Result operator()(
const Designator<T> &x)
const {
157 return visitor_(x.u);
160 return visitor_(x.base());
165 return visitor_.Default();
168 if (
const Component * component{x.GetComponent()}) {
169 return visitor_(*component);
170 }
else if (
const Symbol * symbol{x.GetSymbol()}) {
171 return visitor_(*symbol);
173 return visitor_(DEREF(x.GetSpecificIntrinsic()));
177 if (
const auto *symbol{x.GetAssumedTypeDummy()}) {
178 return visitor_(*symbol);
180 if (
const auto *condArg{x.GetConditionalArg()}) {
181 return TraverseConditionalArg(*condArg);
183 return visitor_(x.UnwrapExpr());
185 Result TraverseConditionalArg(
187 Result result{visitor_.Default()};
188 result = visitor_.Combine(std::move(result), visitor_(ca.condition()));
189 if (ca.consequent()) {
190 result = visitor_.Combine(
191 std::move(result), visitor_(ca.consequent()->value()));
195 return visitor_.Combine(
196 std::move(result), TraverseConditionalArg(inner));
198 [&](
const ActualArgument::ConditionalArg::Consequent &cons) -> Result {
200 return visitor_.Combine(std::move(result), visitor_(cons->value()));
206 return Combine(x.proc(), x.arguments());
208 template <
typename T> Result operator()(
const FunctionRef<T> &x)
const {
213 template <
typename T>
215 return visitor_(x.u);
217 template <
typename T>
219 return CombineContents(x);
221 template <
typename T> Result operator()(
const ImpliedDo<T> &x)
const {
222 return Combine(x.lower(), x.upper(), x.stride(), x.values());
225 return visitor_(x.GetExplicit());
228 const semantics::DerivedTypeSpec::ParameterMapType::value_type &x)
const {
229 return visitor_(x.second);
232 const semantics::DerivedTypeSpec::ParameterMapType &x)
const {
233 return CombineContents(x);
236 return Combine(x.originalTypeSymbol(), x.parameters());
238 Result operator()(
const StructureConstructorValues::value_type &x)
const {
239 return visitor_(x.second);
241 Result operator()(
const StructureConstructorValues &x)
const {
242 return CombineContents(x);
245 return visitor_.Combine(visitor_(x.derivedTypeSpec()), CombineContents(x));
249 return Combine(x.condition(), x.thenValue(), x.elseValue());
254 template <
typename D,
typename R,
typename... Os>
256 if constexpr (
sizeof...(Os) == 1) {
257 return visitor_(op.left());
259 return CombineOperands(op, std::index_sequence_for<Os...>{});
263 return visitor_(x.u);
265 template <
typename T> Result operator()(
const Expr<T> &x)
const {
266 return visitor_(x.u);
268 Result operator()(
const Assignment &x)
const {
269 return Combine(x.lhs, x.rhs, x.u);
272 return visitor_.Default();
276 return visitor_(x.v);
280 template <
typename ITER> Result CombineRange(ITER iter, ITER end)
const {
282 return visitor_.Default();
284 Result result{visitor_(*iter)};
285 for (++iter; iter != end; ++iter) {
286 result = visitor_.Combine(std::move(result), visitor_(*iter));
292 template <
typename A> Result CombineContents(
const A &x)
const {
293 return CombineRange(x.begin(), x.end());
296 template <
typename D,
typename R,
typename... Os,
size_t... Is>
297 Result CombineOperands(
299 static_assert(
sizeof...(Os) > 1 &&
"Expecting multiple operands");
300 return Combine(op.template operand<Is>()...);
303 template <
typename A,
typename... Bs>
304 Result Combine(
const A &x,
const Bs &...ys)
const {
305 if constexpr (
sizeof...(Bs) == 0) {
308 return visitor_.Combine(visitor_(x), Combine(ys...));