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