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 return visitor_(x.UnwrapExpr());
184 return Combine(x.proc(), x.arguments());
186 template <
typename T> Result operator()(
const FunctionRef<T> &x)
const {
191 template <
typename T>
193 return visitor_(x.u);
195 template <
typename T>
197 return CombineContents(x);
199 template <
typename T> Result operator()(
const ImpliedDo<T> &x)
const {
200 return Combine(x.lower(), x.upper(), x.stride(), x.values());
203 return visitor_(x.GetExplicit());
206 const semantics::DerivedTypeSpec::ParameterMapType::value_type &x)
const {
207 return visitor_(x.second);
210 const semantics::DerivedTypeSpec::ParameterMapType &x)
const {
211 return CombineContents(x);
214 return Combine(x.originalTypeSymbol(), x.parameters());
216 Result operator()(
const StructureConstructorValues::value_type &x)
const {
217 return visitor_(x.second);
219 Result operator()(
const StructureConstructorValues &x)
const {
220 return CombineContents(x);
223 return visitor_.Combine(visitor_(x.derivedTypeSpec()), CombineContents(x));
227 return Combine(x.condition(), x.thenValue(), x.elseValue());
232 template <
typename D,
typename R,
typename... Os>
234 if constexpr (
sizeof...(Os) == 1) {
235 return visitor_(op.left());
237 return CombineOperands(op, std::index_sequence_for<Os...>{});
241 return visitor_(x.u);
243 template <
typename T> Result operator()(
const Expr<T> &x)
const {
244 return visitor_(x.u);
246 Result operator()(
const Assignment &x)
const {
247 return Combine(x.lhs, x.rhs, x.u);
250 return visitor_.Default();
254 return visitor_(x.v);
258 template <
typename ITER> Result CombineRange(ITER iter, ITER end)
const {
260 return visitor_.Default();
262 Result result{visitor_(*iter)};
263 for (++iter; iter != end; ++iter) {
264 result = visitor_.Combine(std::move(result), visitor_(*iter));
270 template <
typename A> Result CombineContents(
const A &x)
const {
271 return CombineRange(x.begin(), x.end());
274 template <
typename D,
typename R,
typename... Os,
size_t... Is>
275 Result CombineOperands(
277 static_assert(
sizeof...(Os) > 1 &&
"Expecting multiple operands");
278 return Combine(op.template operand<Is>()...);
281 template <
typename A,
typename... Bs>
282 Result Combine(
const A &x,
const Bs &...ys)
const {
283 if constexpr (
sizeof...(Bs) == 0) {
286 return visitor_.Combine(visitor_(x), Combine(ys...));