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 {
149 return Combine(x.base(), x.cosubscript(), x.stat(), x.team());
151 Result operator()(
const DataRef &x)
const {
return visitor_(x.u); }
152 Result operator()(
const Substring &x)
const {
153 return Combine(x.parent(), x.GetLower(), x.GetUpper());
156 return visitor_(x.complex());
158 template <
typename T> Result operator()(
const Designator<T> &x)
const {
159 return visitor_(x.u);
162 return visitor_(x.base());
167 return visitor_.Default();
170 if (
const Component * component{x.GetComponent()}) {
171 return visitor_(*component);
172 }
else if (
const Symbol * symbol{x.GetSymbol()}) {
173 return visitor_(*symbol);
175 return visitor_(DEREF(x.GetSpecificIntrinsic()));
179 if (
const auto *symbol{x.GetAssumedTypeDummy()}) {
180 return visitor_(*symbol);
182 return visitor_(x.UnwrapExpr());
186 return Combine(x.proc(), x.arguments());
188 template <
typename T> Result operator()(
const FunctionRef<T> &x)
const {
193 template <
typename T>
195 return visitor_(x.u);
197 template <
typename T>
199 return CombineContents(x);
201 template <
typename T> Result operator()(
const ImpliedDo<T> &x)
const {
202 return Combine(x.lower(), x.upper(), x.stride(), x.values());
205 return visitor_(x.GetExplicit());
208 const semantics::DerivedTypeSpec::ParameterMapType::value_type &x)
const {
209 return visitor_(x.second);
212 const semantics::DerivedTypeSpec::ParameterMapType &x)
const {
213 return CombineContents(x);
216 return Combine(x.originalTypeSymbol(), x.parameters());
218 Result operator()(
const StructureConstructorValues::value_type &x)
const {
219 return visitor_(x.second);
221 Result operator()(
const StructureConstructorValues &x)
const {
222 return CombineContents(x);
225 return visitor_.Combine(visitor_(x.derivedTypeSpec()), CombineContents(x));
230 template <
typename D,
typename R,
typename... Os>
232 if constexpr (
sizeof...(Os) == 1) {
233 return visitor_(op.left());
235 return CombineOperands(op, std::index_sequence_for<Os...>{});
239 return visitor_(x.u);
241 template <
typename T> Result operator()(
const Expr<T> &x)
const {
242 return visitor_(x.u);
244 Result operator()(
const Assignment &x)
const {
245 return Combine(x.lhs, x.rhs, x.u);
248 return visitor_.Default();
252 return visitor_(x.v);
256 template <
typename ITER> Result CombineRange(ITER iter, ITER end)
const {
258 return visitor_.Default();
260 Result result{visitor_(*iter)};
261 for (++iter; iter != end; ++iter) {
262 result = visitor_.Combine(std::move(result), visitor_(*iter));
268 template <
typename A> Result CombineContents(
const A &x)
const {
269 return CombineRange(x.begin(), x.end());
272 template <
typename D,
typename R,
typename... Os,
size_t... Is>
273 Result CombineOperands(
275 static_assert(
sizeof...(Os) > 1 &&
"Expecting multiple operands");
276 return Combine(op.template operand<Is>()...);
279 template <
typename A,
typename... Bs>
280 Result Combine(
const A &x,
const Bs &...ys)
const {
281 if constexpr (
sizeof...(Bs) == 0) {
284 return visitor_.Combine(visitor_(x), Combine(ys...));