1 //===-- include/flang/Parser/parse-tree-visitor.h ---------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 #ifndef FORTRAN_PARSER_PARSE_TREE_VISITOR_H_
10 #define FORTRAN_PARSER_PARSE_TREE_VISITOR_H_
11
12 #include "parse-tree.h"
13 #include "flang/Common/visit.h"
14 #include <cstddef>
15 #include <optional>
16 #include <tuple>
17 #include <utility>
18 #include <variant>
19
20 /// Parse tree visitor
21 /// Call Walk(x, visitor) to visit x and, by default, each node under x.
22 /// If x is non-const, the visitor member functions can modify the tree.
23 ///
24 /// visitor.Pre(x) is called before visiting x and its children are not
25 /// visited if it returns false.
26 ///
27 /// visitor.Post(x) is called after visiting x.
28
29 namespace Fortran::parser {
30
31 // Default case for visitation of non-class data members, strings, and
32 // any other non-decomposable values.
33 template <typename A, typename V>
34 std::enable_if_t<!std::is_class_v<A> || std::is_same_v<std::string, A> ||
35 std::is_same_v<CharBlock, A>>
Walk(const A & x,V & visitor)36 Walk(const A &x, V &visitor) {
37 if (visitor.Pre(x)) {
38 visitor.Post(x);
39 }
40 }
41 template <typename A, typename M>
42 std::enable_if_t<!std::is_class_v<A> || std::is_same_v<std::string, A> ||
43 std::is_same_v<CharBlock, A>>
Walk(A & x,M & mutator)44 Walk(A &x, M &mutator) {
45 if (mutator.Pre(x)) {
46 mutator.Post(x);
47 }
48 }
49
50 template <typename V> void Walk(const format::ControlEditDesc &, V &);
51 template <typename M> void Walk(format::ControlEditDesc &, M &);
52 template <typename V> void Walk(const format::DerivedTypeDataEditDesc &, V &);
53 template <typename M> void Walk(format::DerivedTypeDataEditDesc &, M &);
54 template <typename V> void Walk(const format::FormatItem &, V &);
55 template <typename M> void Walk(format::FormatItem &, M &);
56 template <typename V> void Walk(const format::FormatSpecification &, V &);
57 template <typename M> void Walk(format::FormatSpecification &, M &);
58 template <typename V> void Walk(const format::IntrinsicTypeDataEditDesc &, V &);
59 template <typename M> void Walk(format::IntrinsicTypeDataEditDesc &, M &);
60
61 // Traversal of needed STL template classes (optional, list, tuple, variant)
62 template <typename T, typename V>
Walk(const std::optional<T> & x,V & visitor)63 void Walk(const std::optional<T> &x, V &visitor) {
64 if (x) {
65 Walk(*x, visitor);
66 }
67 }
Walk(std::optional<T> & x,M & mutator)68 template <typename T, typename M> void Walk(std::optional<T> &x, M &mutator) {
69 if (x) {
70 Walk(*x, mutator);
71 }
72 }
73 // For most lists, just traverse the elements; but when a list constitutes
74 // a Block (i.e., std::list<ExecutionPartConstruct>), also invoke the
75 // visitor/mutator on the list itself.
Walk(const std::list<T> & x,V & visitor)76 template <typename T, typename V> void Walk(const std::list<T> &x, V &visitor) {
77 for (const auto &elem : x) {
78 Walk(elem, visitor);
79 }
80 }
Walk(std::list<T> & x,M & mutator)81 template <typename T, typename M> void Walk(std::list<T> &x, M &mutator) {
82 for (auto &elem : x) {
83 Walk(elem, mutator);
84 }
85 }
Walk(const Block & x,V & visitor)86 template <typename V> void Walk(const Block &x, V &visitor) {
87 if (visitor.Pre(x)) {
88 for (const auto &elem : x) {
89 Walk(elem, visitor);
90 }
91 visitor.Post(x);
92 }
93 }
Walk(Block & x,M & mutator)94 template <typename M> void Walk(Block &x, M &mutator) {
95 if (mutator.Pre(x)) {
96 for (auto &elem : x) {
97 Walk(elem, mutator);
98 }
99 mutator.Post(x);
100 }
101 }
102 template <std::size_t I = 0, typename Func, typename T>
ForEachInTuple(const T & tuple,Func func)103 void ForEachInTuple(const T &tuple, Func func) {
104 func(std::get<I>(tuple));
105 if constexpr (I + 1 < std::tuple_size_v<T>) {
106 ForEachInTuple<I + 1>(tuple, func);
107 }
108 }
109 template <typename V, typename... A>
Walk(const std::tuple<A...> & x,V & visitor)110 void Walk(const std::tuple<A...> &x, V &visitor) {
111 if (sizeof...(A) > 0) {
112 if (visitor.Pre(x)) {
113 ForEachInTuple(x, [&](const auto &y) { Walk(y, visitor); });
114 visitor.Post(x);
115 }
116 }
117 }
118 template <std::size_t I = 0, typename Func, typename T>
ForEachInTuple(T & tuple,Func func)119 void ForEachInTuple(T &tuple, Func func) {
120 func(std::get<I>(tuple));
121 if constexpr (I + 1 < std::tuple_size_v<T>) {
122 ForEachInTuple<I + 1>(tuple, func);
123 }
124 }
125 template <typename M, typename... A>
Walk(std::tuple<A...> & x,M & mutator)126 void Walk(std::tuple<A...> &x, M &mutator) {
127 if (sizeof...(A) > 0) {
128 if (mutator.Pre(x)) {
129 ForEachInTuple(x, [&](auto &y) { Walk(y, mutator); });
130 mutator.Post(x);
131 }
132 }
133 }
134 template <typename V, typename... A>
Walk(const std::variant<A...> & x,V & visitor)135 void Walk(const std::variant<A...> &x, V &visitor) {
136 if (visitor.Pre(x)) {
137 common::visit([&](const auto &y) { Walk(y, visitor); }, x);
138 visitor.Post(x);
139 }
140 }
141 template <typename M, typename... A>
Walk(std::variant<A...> & x,M & mutator)142 void Walk(std::variant<A...> &x, M &mutator) {
143 if (mutator.Pre(x)) {
144 common::visit([&](auto &y) { Walk(y, mutator); }, x);
145 mutator.Post(x);
146 }
147 }
148 template <typename A, typename B, typename V>
Walk(const std::pair<A,B> & x,V & visitor)149 void Walk(const std::pair<A, B> &x, V &visitor) {
150 if (visitor.Pre(x)) {
151 Walk(x.first, visitor);
152 Walk(x.second, visitor);
153 }
154 }
155 template <typename A, typename B, typename M>
Walk(std::pair<A,B> & x,M & mutator)156 void Walk(std::pair<A, B> &x, M &mutator) {
157 if (mutator.Pre(x)) {
158 Walk(x.first, mutator);
159 Walk(x.second, mutator);
160 }
161 }
162
163 // Trait-determined traversal of empty, tuple, union, wrapper,
164 // and constraint-checking classes.
165 template <typename A, typename V>
Walk(const A & x,V & visitor)166 std::enable_if_t<EmptyTrait<A>> Walk(const A &x, V &visitor) {
167 if (visitor.Pre(x)) {
168 visitor.Post(x);
169 }
170 }
171 template <typename A, typename M>
Walk(A & x,M & mutator)172 std::enable_if_t<EmptyTrait<A>> Walk(A &x, M &mutator) {
173 if (mutator.Pre(x)) {
174 mutator.Post(x);
175 }
176 }
177
178 template <typename A, typename V>
Walk(const A & x,V & visitor)179 std::enable_if_t<TupleTrait<A>> Walk(const A &x, V &visitor) {
180 if (visitor.Pre(x)) {
181 Walk(x.t, visitor);
182 visitor.Post(x);
183 }
184 }
185 template <typename A, typename M>
Walk(A & x,M & mutator)186 std::enable_if_t<TupleTrait<A>> Walk(A &x, M &mutator) {
187 if (mutator.Pre(x)) {
188 Walk(x.t, mutator);
189 mutator.Post(x);
190 }
191 }
192
193 template <typename A, typename V>
Walk(const A & x,V & visitor)194 std::enable_if_t<UnionTrait<A>> Walk(const A &x, V &visitor) {
195 if (visitor.Pre(x)) {
196 Walk(x.u, visitor);
197 visitor.Post(x);
198 }
199 }
200 template <typename A, typename M>
Walk(A & x,M & mutator)201 std::enable_if_t<UnionTrait<A>> Walk(A &x, M &mutator) {
202 if (mutator.Pre(x)) {
203 Walk(x.u, mutator);
204 mutator.Post(x);
205 }
206 }
207
208 template <typename A, typename V>
Walk(const A & x,V & visitor)209 std::enable_if_t<WrapperTrait<A>> Walk(const A &x, V &visitor) {
210 if (visitor.Pre(x)) {
211 Walk(x.v, visitor);
212 visitor.Post(x);
213 }
214 }
215 template <typename A, typename M>
Walk(A & x,M & mutator)216 std::enable_if_t<WrapperTrait<A>> Walk(A &x, M &mutator) {
217 if (mutator.Pre(x)) {
218 Walk(x.v, mutator);
219 mutator.Post(x);
220 }
221 }
222
223 template <typename A, typename V>
Walk(const A & x,V & visitor)224 std::enable_if_t<ConstraintTrait<A>> Walk(const A &x, V &visitor) {
225 if (visitor.Pre(x)) {
226 Walk(x.thing, visitor);
227 visitor.Post(x);
228 }
229 }
230 template <typename A, typename M>
Walk(A & x,M & mutator)231 std::enable_if_t<ConstraintTrait<A>> Walk(A &x, M &mutator) {
232 if (mutator.Pre(x)) {
233 Walk(x.thing, mutator);
234 mutator.Post(x);
235 }
236 }
237
238 template <typename T, typename V>
Walk(const common::Indirection<T> & x,V & visitor)239 void Walk(const common::Indirection<T> &x, V &visitor) {
240 Walk(x.value(), visitor);
241 }
242 template <typename T, typename M>
Walk(common::Indirection<T> & x,M & mutator)243 void Walk(common::Indirection<T> &x, M &mutator) {
244 Walk(x.value(), mutator);
245 }
246
Walk(const Statement<T> & x,V & visitor)247 template <typename T, typename V> void Walk(const Statement<T> &x, V &visitor) {
248 if (visitor.Pre(x)) {
249 // N.B. The label, if any, is not visited.
250 Walk(x.source, visitor);
251 Walk(x.statement, visitor);
252 visitor.Post(x);
253 }
254 }
Walk(Statement<T> & x,M & mutator)255 template <typename T, typename M> void Walk(Statement<T> &x, M &mutator) {
256 if (mutator.Pre(x)) {
257 // N.B. The label, if any, is not visited.
258 Walk(x.source, mutator);
259 Walk(x.statement, mutator);
260 mutator.Post(x);
261 }
262 }
263
264 template <typename T, typename V>
Walk(const UnlabeledStatement<T> & x,V & visitor)265 void Walk(const UnlabeledStatement<T> &x, V &visitor) {
266 if (visitor.Pre(x)) {
267 Walk(x.source, visitor);
268 Walk(x.statement, visitor);
269 visitor.Post(x);
270 }
271 }
272 template <typename T, typename M>
Walk(UnlabeledStatement<T> & x,M & mutator)273 void Walk(UnlabeledStatement<T> &x, M &mutator) {
274 if (mutator.Pre(x)) {
275 Walk(x.source, mutator);
276 Walk(x.statement, mutator);
277 mutator.Post(x);
278 }
279 }
280
Walk(const Name & x,V & visitor)281 template <typename V> void Walk(const Name &x, V &visitor) {
282 if (visitor.Pre(x)) {
283 Walk(x.source, visitor);
284 visitor.Post(x);
285 }
286 }
Walk(Name & x,M & mutator)287 template <typename M> void Walk(Name &x, M &mutator) {
288 if (mutator.Pre(x)) {
289 Walk(x.source, mutator);
290 mutator.Post(x);
291 }
292 }
293
Walk(const AcSpec & x,V & visitor)294 template <typename V> void Walk(const AcSpec &x, V &visitor) {
295 if (visitor.Pre(x)) {
296 Walk(x.type, visitor);
297 Walk(x.values, visitor);
298 visitor.Post(x);
299 }
300 }
Walk(AcSpec & x,M & mutator)301 template <typename M> void Walk(AcSpec &x, M &mutator) {
302 if (mutator.Pre(x)) {
303 Walk(x.type, mutator);
304 Walk(x.values, mutator);
305 mutator.Post(x);
306 }
307 }
Walk(const ArrayElement & x,V & visitor)308 template <typename V> void Walk(const ArrayElement &x, V &visitor) {
309 if (visitor.Pre(x)) {
310 Walk(x.base, visitor);
311 Walk(x.subscripts, visitor);
312 visitor.Post(x);
313 }
314 }
Walk(ArrayElement & x,M & mutator)315 template <typename M> void Walk(ArrayElement &x, M &mutator) {
316 if (mutator.Pre(x)) {
317 Walk(x.base, mutator);
318 Walk(x.subscripts, mutator);
319 mutator.Post(x);
320 }
321 }
322 template <typename V>
Walk(const CharSelector::LengthAndKind & x,V & visitor)323 void Walk(const CharSelector::LengthAndKind &x, V &visitor) {
324 if (visitor.Pre(x)) {
325 Walk(x.length, visitor);
326 Walk(x.kind, visitor);
327 visitor.Post(x);
328 }
329 }
Walk(CharSelector::LengthAndKind & x,M & mutator)330 template <typename M> void Walk(CharSelector::LengthAndKind &x, M &mutator) {
331 if (mutator.Pre(x)) {
332 Walk(x.length, mutator);
333 Walk(x.kind, mutator);
334 mutator.Post(x);
335 }
336 }
Walk(const CaseValueRange::Range & x,V & visitor)337 template <typename V> void Walk(const CaseValueRange::Range &x, V &visitor) {
338 if (visitor.Pre(x)) {
339 Walk(x.lower, visitor);
340 Walk(x.upper, visitor);
341 visitor.Post(x);
342 }
343 }
Walk(CaseValueRange::Range & x,M & mutator)344 template <typename M> void Walk(CaseValueRange::Range &x, M &mutator) {
345 if (mutator.Pre(x)) {
346 Walk(x.lower, mutator);
347 Walk(x.upper, mutator);
348 mutator.Post(x);
349 }
350 }
Walk(const CoindexedNamedObject & x,V & visitor)351 template <typename V> void Walk(const CoindexedNamedObject &x, V &visitor) {
352 if (visitor.Pre(x)) {
353 Walk(x.base, visitor);
354 Walk(x.imageSelector, visitor);
355 visitor.Post(x);
356 }
357 }
Walk(CoindexedNamedObject & x,M & mutator)358 template <typename M> void Walk(CoindexedNamedObject &x, M &mutator) {
359 if (mutator.Pre(x)) {
360 Walk(x.base, mutator);
361 Walk(x.imageSelector, mutator);
362 mutator.Post(x);
363 }
364 }
365 template <typename V>
Walk(const DeclarationTypeSpec::Class & x,V & visitor)366 void Walk(const DeclarationTypeSpec::Class &x, V &visitor) {
367 if (visitor.Pre(x)) {
368 Walk(x.derived, visitor);
369 visitor.Post(x);
370 }
371 }
Walk(DeclarationTypeSpec::Class & x,M & mutator)372 template <typename M> void Walk(DeclarationTypeSpec::Class &x, M &mutator) {
373 if (mutator.Pre(x)) {
374 Walk(x.derived, mutator);
375 mutator.Post(x);
376 }
377 }
378 template <typename V>
Walk(const DeclarationTypeSpec::Type & x,V & visitor)379 void Walk(const DeclarationTypeSpec::Type &x, V &visitor) {
380 if (visitor.Pre(x)) {
381 Walk(x.derived, visitor);
382 visitor.Post(x);
383 }
384 }
Walk(DeclarationTypeSpec::Type & x,M & mutator)385 template <typename M> void Walk(DeclarationTypeSpec::Type &x, M &mutator) {
386 if (mutator.Pre(x)) {
387 Walk(x.derived, mutator);
388 mutator.Post(x);
389 }
390 }
Walk(const ImportStmt & x,V & visitor)391 template <typename V> void Walk(const ImportStmt &x, V &visitor) {
392 if (visitor.Pre(x)) {
393 Walk(x.names, visitor);
394 visitor.Post(x);
395 }
396 }
Walk(ImportStmt & x,M & mutator)397 template <typename M> void Walk(ImportStmt &x, M &mutator) {
398 if (mutator.Pre(x)) {
399 Walk(x.names, mutator);
400 mutator.Post(x);
401 }
402 }
403 template <typename V>
Walk(const IntrinsicTypeSpec::Character & x,V & visitor)404 void Walk(const IntrinsicTypeSpec::Character &x, V &visitor) {
405 if (visitor.Pre(x)) {
406 Walk(x.selector, visitor);
407 visitor.Post(x);
408 }
409 }
Walk(IntrinsicTypeSpec::Character & x,M & mutator)410 template <typename M> void Walk(IntrinsicTypeSpec::Character &x, M &mutator) {
411 if (mutator.Pre(x)) {
412 Walk(x.selector, mutator);
413 mutator.Post(x);
414 }
415 }
416 template <typename V>
Walk(const IntrinsicTypeSpec::Complex & x,V & visitor)417 void Walk(const IntrinsicTypeSpec::Complex &x, V &visitor) {
418 if (visitor.Pre(x)) {
419 Walk(x.kind, visitor);
420 visitor.Post(x);
421 }
422 }
Walk(IntrinsicTypeSpec::Complex & x,M & mutator)423 template <typename M> void Walk(IntrinsicTypeSpec::Complex &x, M &mutator) {
424 if (mutator.Pre(x)) {
425 Walk(x.kind, mutator);
426 mutator.Post(x);
427 }
428 }
429 template <typename V>
Walk(const IntrinsicTypeSpec::Logical & x,V & visitor)430 void Walk(const IntrinsicTypeSpec::Logical &x, V &visitor) {
431 if (visitor.Pre(x)) {
432 Walk(x.kind, visitor);
433 visitor.Post(x);
434 }
435 }
Walk(IntrinsicTypeSpec::Logical & x,M & mutator)436 template <typename M> void Walk(IntrinsicTypeSpec::Logical &x, M &mutator) {
437 if (mutator.Pre(x)) {
438 Walk(x.kind, mutator);
439 mutator.Post(x);
440 }
441 }
Walk(const IntrinsicTypeSpec::Real & x,V & visitor)442 template <typename V> void Walk(const IntrinsicTypeSpec::Real &x, V &visitor) {
443 if (visitor.Pre(x)) {
444 Walk(x.kind, visitor);
445 visitor.Post(x);
446 }
447 }
Walk(IntrinsicTypeSpec::Real & x,M & mutator)448 template <typename M> void Walk(IntrinsicTypeSpec::Real &x, M &mutator) {
449 if (mutator.Pre(x)) {
450 Walk(x.kind, mutator);
451 mutator.Post(x);
452 }
453 }
454 template <typename A, typename B, typename V>
Walk(const LoopBounds<A,B> & x,V & visitor)455 void Walk(const LoopBounds<A, B> &x, V &visitor) {
456 if (visitor.Pre(x)) {
457 Walk(x.name, visitor);
458 Walk(x.lower, visitor);
459 Walk(x.upper, visitor);
460 Walk(x.step, visitor);
461 visitor.Post(x);
462 }
463 }
464 template <typename A, typename B, typename M>
Walk(LoopBounds<A,B> & x,M & mutator)465 void Walk(LoopBounds<A, B> &x, M &mutator) {
466 if (mutator.Pre(x)) {
467 Walk(x.name, mutator);
468 Walk(x.lower, mutator);
469 Walk(x.upper, mutator);
470 Walk(x.step, mutator);
471 mutator.Post(x);
472 }
473 }
Walk(const CommonStmt & x,V & visitor)474 template <typename V> void Walk(const CommonStmt &x, V &visitor) {
475 if (visitor.Pre(x)) {
476 Walk(x.blocks, visitor);
477 visitor.Post(x);
478 }
479 }
Walk(CommonStmt & x,M & mutator)480 template <typename M> void Walk(CommonStmt &x, M &mutator) {
481 if (mutator.Pre(x)) {
482 Walk(x.blocks, mutator);
483 mutator.Post(x);
484 }
485 }
Walk(const Expr & x,V & visitor)486 template <typename V> void Walk(const Expr &x, V &visitor) {
487 if (visitor.Pre(x)) {
488 Walk(x.source, visitor);
489 Walk(x.u, visitor);
490 visitor.Post(x);
491 }
492 }
Walk(Expr & x,M & mutator)493 template <typename M> void Walk(Expr &x, M &mutator) {
494 if (mutator.Pre(x)) {
495 Walk(x.source, mutator);
496 Walk(x.u, mutator);
497 mutator.Post(x);
498 }
499 }
Walk(const Designator & x,V & visitor)500 template <typename V> void Walk(const Designator &x, V &visitor) {
501 if (visitor.Pre(x)) {
502 Walk(x.source, visitor);
503 Walk(x.u, visitor);
504 visitor.Post(x);
505 }
506 }
Walk(Designator & x,M & mutator)507 template <typename M> void Walk(Designator &x, M &mutator) {
508 if (mutator.Pre(x)) {
509 Walk(x.source, mutator);
510 Walk(x.u, mutator);
511 mutator.Post(x);
512 }
513 }
Walk(const Call & x,V & visitor)514 template <typename V> void Walk(const Call &x, V &visitor) {
515 if (visitor.Pre(x)) {
516 Walk(x.source, visitor);
517 Walk(x.t, visitor);
518 visitor.Post(x);
519 }
520 }
Walk(Call & x,M & mutator)521 template <typename M> void Walk(Call &x, M &mutator) {
522 if (mutator.Pre(x)) {
523 Walk(x.source, mutator);
524 Walk(x.t, mutator);
525 mutator.Post(x);
526 }
527 }
Walk(const PartRef & x,V & visitor)528 template <typename V> void Walk(const PartRef &x, V &visitor) {
529 if (visitor.Pre(x)) {
530 Walk(x.name, visitor);
531 Walk(x.subscripts, visitor);
532 Walk(x.imageSelector, visitor);
533 visitor.Post(x);
534 }
535 }
Walk(PartRef & x,M & mutator)536 template <typename M> void Walk(PartRef &x, M &mutator) {
537 if (mutator.Pre(x)) {
538 Walk(x.name, mutator);
539 Walk(x.subscripts, mutator);
540 Walk(x.imageSelector, mutator);
541 mutator.Post(x);
542 }
543 }
Walk(const ReadStmt & x,V & visitor)544 template <typename V> void Walk(const ReadStmt &x, V &visitor) {
545 if (visitor.Pre(x)) {
546 Walk(x.iounit, visitor);
547 Walk(x.format, visitor);
548 Walk(x.controls, visitor);
549 Walk(x.items, visitor);
550 visitor.Post(x);
551 }
552 }
Walk(ReadStmt & x,M & mutator)553 template <typename M> void Walk(ReadStmt &x, M &mutator) {
554 if (mutator.Pre(x)) {
555 Walk(x.iounit, mutator);
556 Walk(x.format, mutator);
557 Walk(x.controls, mutator);
558 Walk(x.items, mutator);
559 mutator.Post(x);
560 }
561 }
Walk(const SignedIntLiteralConstant & x,V & visitor)562 template <typename V> void Walk(const SignedIntLiteralConstant &x, V &visitor) {
563 if (visitor.Pre(x)) {
564 Walk(x.source, visitor);
565 Walk(x.t, visitor);
566 visitor.Post(x);
567 }
568 }
Walk(SignedIntLiteralConstant & x,M & mutator)569 template <typename M> void Walk(SignedIntLiteralConstant &x, M &mutator) {
570 if (mutator.Pre(x)) {
571 Walk(x.source, mutator);
572 Walk(x.t, mutator);
573 mutator.Post(x);
574 }
575 }
Walk(const RealLiteralConstant & x,V & visitor)576 template <typename V> void Walk(const RealLiteralConstant &x, V &visitor) {
577 if (visitor.Pre(x)) {
578 Walk(x.real, visitor);
579 Walk(x.kind, visitor);
580 visitor.Post(x);
581 }
582 }
Walk(RealLiteralConstant & x,M & mutator)583 template <typename M> void Walk(RealLiteralConstant &x, M &mutator) {
584 if (mutator.Pre(x)) {
585 Walk(x.real, mutator);
586 Walk(x.kind, mutator);
587 mutator.Post(x);
588 }
589 }
590 template <typename V>
Walk(const RealLiteralConstant::Real & x,V & visitor)591 void Walk(const RealLiteralConstant::Real &x, V &visitor) {
592 if (visitor.Pre(x)) {
593 Walk(x.source, visitor);
594 visitor.Post(x);
595 }
596 }
Walk(RealLiteralConstant::Real & x,M & mutator)597 template <typename M> void Walk(RealLiteralConstant::Real &x, M &mutator) {
598 if (mutator.Pre(x)) {
599 Walk(x.source, mutator);
600 mutator.Post(x);
601 }
602 }
Walk(const StructureComponent & x,V & visitor)603 template <typename V> void Walk(const StructureComponent &x, V &visitor) {
604 if (visitor.Pre(x)) {
605 Walk(x.base, visitor);
606 Walk(x.component, visitor);
607 visitor.Post(x);
608 }
609 }
Walk(StructureComponent & x,M & mutator)610 template <typename M> void Walk(StructureComponent &x, M &mutator) {
611 if (mutator.Pre(x)) {
612 Walk(x.base, mutator);
613 Walk(x.component, mutator);
614 mutator.Post(x);
615 }
616 }
Walk(const Suffix & x,V & visitor)617 template <typename V> void Walk(const Suffix &x, V &visitor) {
618 if (visitor.Pre(x)) {
619 Walk(x.binding, visitor);
620 Walk(x.resultName, visitor);
621 visitor.Post(x);
622 }
623 }
Walk(Suffix & x,M & mutator)624 template <typename M> void Walk(Suffix &x, M &mutator) {
625 if (mutator.Pre(x)) {
626 Walk(x.binding, mutator);
627 Walk(x.resultName, mutator);
628 mutator.Post(x);
629 }
630 }
631 template <typename V>
Walk(const TypeBoundProcedureStmt::WithInterface & x,V & visitor)632 void Walk(const TypeBoundProcedureStmt::WithInterface &x, V &visitor) {
633 if (visitor.Pre(x)) {
634 Walk(x.interfaceName, visitor);
635 Walk(x.attributes, visitor);
636 Walk(x.bindingNames, visitor);
637 visitor.Post(x);
638 }
639 }
640 template <typename M>
Walk(TypeBoundProcedureStmt::WithInterface & x,M & mutator)641 void Walk(TypeBoundProcedureStmt::WithInterface &x, M &mutator) {
642 if (mutator.Pre(x)) {
643 Walk(x.interfaceName, mutator);
644 Walk(x.attributes, mutator);
645 Walk(x.bindingNames, mutator);
646 mutator.Post(x);
647 }
648 }
649 template <typename V>
Walk(const TypeBoundProcedureStmt::WithoutInterface & x,V & visitor)650 void Walk(const TypeBoundProcedureStmt::WithoutInterface &x, V &visitor) {
651 if (visitor.Pre(x)) {
652 Walk(x.attributes, visitor);
653 Walk(x.declarations, visitor);
654 visitor.Post(x);
655 }
656 }
657 template <typename M>
Walk(TypeBoundProcedureStmt::WithoutInterface & x,M & mutator)658 void Walk(TypeBoundProcedureStmt::WithoutInterface &x, M &mutator) {
659 if (mutator.Pre(x)) {
660 Walk(x.attributes, mutator);
661 Walk(x.declarations, mutator);
662 mutator.Post(x);
663 }
664 }
Walk(const UseStmt & x,V & visitor)665 template <typename V> void Walk(const UseStmt &x, V &visitor) {
666 if (visitor.Pre(x)) {
667 Walk(x.nature, visitor);
668 Walk(x.moduleName, visitor);
669 Walk(x.u, visitor);
670 visitor.Post(x);
671 }
672 }
Walk(UseStmt & x,M & mutator)673 template <typename M> void Walk(UseStmt &x, M &mutator) {
674 if (mutator.Pre(x)) {
675 Walk(x.nature, mutator);
676 Walk(x.moduleName, mutator);
677 Walk(x.u, mutator);
678 mutator.Post(x);
679 }
680 }
Walk(const WriteStmt & x,V & visitor)681 template <typename V> void Walk(const WriteStmt &x, V &visitor) {
682 if (visitor.Pre(x)) {
683 Walk(x.iounit, visitor);
684 Walk(x.format, visitor);
685 Walk(x.controls, visitor);
686 Walk(x.items, visitor);
687 visitor.Post(x);
688 }
689 }
Walk(WriteStmt & x,M & mutator)690 template <typename M> void Walk(WriteStmt &x, M &mutator) {
691 if (mutator.Pre(x)) {
692 Walk(x.iounit, mutator);
693 Walk(x.format, mutator);
694 Walk(x.controls, mutator);
695 Walk(x.items, mutator);
696 mutator.Post(x);
697 }
698 }
Walk(const format::ControlEditDesc & x,V & visitor)699 template <typename V> void Walk(const format::ControlEditDesc &x, V &visitor) {
700 if (visitor.Pre(x)) {
701 Walk(x.kind, visitor);
702 visitor.Post(x);
703 }
704 }
Walk(format::ControlEditDesc & x,M & mutator)705 template <typename M> void Walk(format::ControlEditDesc &x, M &mutator) {
706 if (mutator.Pre(x)) {
707 Walk(x.kind, mutator);
708 mutator.Post(x);
709 }
710 }
711 template <typename V>
Walk(const format::DerivedTypeDataEditDesc & x,V & visitor)712 void Walk(const format::DerivedTypeDataEditDesc &x, V &visitor) {
713 if (visitor.Pre(x)) {
714 Walk(x.type, visitor);
715 Walk(x.parameters, visitor);
716 visitor.Post(x);
717 }
718 }
719 template <typename M>
Walk(format::DerivedTypeDataEditDesc & x,M & mutator)720 void Walk(format::DerivedTypeDataEditDesc &x, M &mutator) {
721 if (mutator.Pre(x)) {
722 Walk(x.type, mutator);
723 Walk(x.parameters, mutator);
724 mutator.Post(x);
725 }
726 }
Walk(const format::FormatItem & x,V & visitor)727 template <typename V> void Walk(const format::FormatItem &x, V &visitor) {
728 if (visitor.Pre(x)) {
729 Walk(x.repeatCount, visitor);
730 Walk(x.u, visitor);
731 visitor.Post(x);
732 }
733 }
Walk(format::FormatItem & x,M & mutator)734 template <typename M> void Walk(format::FormatItem &x, M &mutator) {
735 if (mutator.Pre(x)) {
736 Walk(x.repeatCount, mutator);
737 Walk(x.u, mutator);
738 mutator.Post(x);
739 }
740 }
741 template <typename V>
Walk(const format::FormatSpecification & x,V & visitor)742 void Walk(const format::FormatSpecification &x, V &visitor) {
743 if (visitor.Pre(x)) {
744 Walk(x.items, visitor);
745 Walk(x.unlimitedItems, visitor);
746 visitor.Post(x);
747 }
748 }
Walk(format::FormatSpecification & x,M & mutator)749 template <typename M> void Walk(format::FormatSpecification &x, M &mutator) {
750 if (mutator.Pre(x)) {
751 Walk(x.items, mutator);
752 Walk(x.unlimitedItems, mutator);
753 mutator.Post(x);
754 }
755 }
756 template <typename V>
Walk(const format::IntrinsicTypeDataEditDesc & x,V & visitor)757 void Walk(const format::IntrinsicTypeDataEditDesc &x, V &visitor) {
758 if (visitor.Pre(x)) {
759 Walk(x.kind, visitor);
760 Walk(x.width, visitor);
761 Walk(x.digits, visitor);
762 Walk(x.exponentWidth, visitor);
763 visitor.Post(x);
764 }
765 }
766 template <typename M>
Walk(format::IntrinsicTypeDataEditDesc & x,M & mutator)767 void Walk(format::IntrinsicTypeDataEditDesc &x, M &mutator) {
768 if (mutator.Pre(x)) {
769 Walk(x.kind, mutator);
770 Walk(x.width, mutator);
771 Walk(x.digits, mutator);
772 Walk(x.exponentWidth, mutator);
773 mutator.Post(x);
774 }
775 }
Walk(const CompilerDirective & x,V & visitor)776 template <typename V> void Walk(const CompilerDirective &x, V &visitor) {
777 if (visitor.Pre(x)) {
778 Walk(x.source, visitor);
779 Walk(x.u, visitor);
780 visitor.Post(x);
781 }
782 }
Walk(CompilerDirective & x,M & mutator)783 template <typename M> void Walk(CompilerDirective &x, M &mutator) {
784 if (mutator.Pre(x)) {
785 Walk(x.source, mutator);
786 Walk(x.u, mutator);
787 mutator.Post(x);
788 }
789 }
790 template <typename V>
Walk(const OmpLinearClause::WithModifier & x,V & visitor)791 void Walk(const OmpLinearClause::WithModifier &x, V &visitor) {
792 if (visitor.Pre(x)) {
793 Walk(x.modifier, visitor);
794 Walk(x.names, visitor);
795 Walk(x.step, visitor);
796 visitor.Post(x);
797 }
798 }
Walk(OmpLinearClause::WithModifier & x,M & mutator)799 template <typename M> void Walk(OmpLinearClause::WithModifier &x, M &mutator) {
800 if (mutator.Pre(x)) {
801 Walk(x.modifier, mutator);
802 Walk(x.names, mutator);
803 Walk(x.step, mutator);
804 mutator.Post(x);
805 }
806 }
807 template <typename V>
Walk(const OmpLinearClause::WithoutModifier & x,V & visitor)808 void Walk(const OmpLinearClause::WithoutModifier &x, V &visitor) {
809 if (visitor.Pre(x)) {
810 Walk(x.names, visitor);
811 Walk(x.step, visitor);
812 visitor.Post(x);
813 }
814 }
815 template <typename M>
Walk(OmpLinearClause::WithoutModifier & x,M & mutator)816 void Walk(OmpLinearClause::WithoutModifier &x, M &mutator) {
817 if (mutator.Pre(x)) {
818 Walk(x.names, mutator);
819 Walk(x.step, mutator);
820 mutator.Post(x);
821 }
822 }
823 } // namespace Fortran::parser
824 #endif // FORTRAN_PARSER_PARSE_TREE_VISITOR_H_
825