9#ifndef FORTRAN_PARSER_PARSE_TREE_VISITOR_H_
10#define FORTRAN_PARSER_PARSE_TREE_VISITOR_H_
12#include "parse-tree.h"
13#include "flang/Common/visit.h"
32template <
typename A,
typename V>
void Walk(
const A &x, V &visitor);
33template <
typename A,
typename M>
void Walk(A &x, M &mutator);
43 template <
typename A,
typename V>
44 static std::enable_if_t<!std::is_class_v<A> ||
45 std::is_same_v<std::string, A> || std::is_same_v<CharBlock, A>>
46 Walk(
const A &x, V &visitor) {
51 template <
typename A,
typename M>
52 static std::enable_if_t<!std::is_class_v<A> ||
53 std::is_same_v<std::string, A> || std::is_same_v<CharBlock, A>>
54 Walk(A &x, M &mutator) {
64 template <
typename T,
typename V>
65 static void Walk(
const std::list<T> &x, V &visitor) {
66 for (
const auto &elem : x) {
70 template <
typename T,
typename M>
71 static void Walk(std::list<T> &x, M &mutator) {
72 for (
auto &elem : x) {
76 template <
typename V>
static void Walk(
const Block &x, V &visitor) {
78 for (
const auto &elem : x) {
84 template <
typename M>
static void Walk(Block &x, M &mutator) {
86 for (
auto &elem : x) {
92 template <
typename T,
typename V>
93 static void Walk(
const std::optional<T> &x, V &visitor) {
98 template <
typename T,
typename M>
99 static void Walk(std::optional<T> &x, M &mutator) {
104 template <std::
size_t I = 0,
typename Func,
typename T>
105 static void ForEachInTuple(
const T &tuple, Func func) {
106 func(std::get<I>(tuple));
107 if constexpr (I + 1 < std::tuple_size_v<T>) {
108 ForEachInTuple<I + 1>(tuple, func);
111 template <
typename V,
typename... A>
112 static void Walk(
const std::tuple<A...> &x, V &visitor) {
113 if (
sizeof...(A) > 0) {
114 if (visitor.Pre(x)) {
115 ForEachInTuple(x, [&](
const auto &y) { Walk(y, visitor); });
120 template <std::
size_t I = 0,
typename Func,
typename T>
121 static void ForEachInTuple(T &tuple, Func func) {
122 func(std::get<I>(tuple));
123 if constexpr (I + 1 < std::tuple_size_v<T>) {
124 ForEachInTuple<I + 1>(tuple, func);
127 template <
typename M,
typename... A>
128 static void Walk(std::tuple<A...> &x, M &mutator) {
129 if (
sizeof...(A) > 0) {
130 if (mutator.Pre(x)) {
131 ForEachInTuple(x, [&](
auto &y) { Walk(y, mutator); });
136 template <
typename V,
typename... A>
137 static void Walk(
const std::variant<A...> &x, V &visitor) {
138 if (visitor.Pre(x)) {
139 common::visit([&](
const auto &y) { Walk(y, visitor); }, x);
143 template <
typename M,
typename... A>
144 static void Walk(std::variant<A...> &x, M &mutator) {
145 if (mutator.Pre(x)) {
146 common::visit([&](
auto &y) { Walk(y, mutator); }, x);
150 template <
typename A,
typename B,
typename V>
151 static void Walk(
const std::pair<A, B> &x, V &visitor) {
152 if (visitor.Pre(x)) {
153 Walk(x.first, visitor);
154 Walk(x.second, visitor);
157 template <
typename A,
typename B,
typename M>
158 static void Walk(std::pair<A, B> &x, M &mutator) {
159 if (mutator.Pre(x)) {
160 Walk(x.first, mutator);
161 Walk(x.second, mutator);
167 template <
typename A,
typename V>
168 static std::enable_if_t<EmptyTrait<A>> Walk(
const A &x, V &visitor) {
169 if (visitor.Pre(x)) {
173 template <
typename A,
typename M>
174 static std::enable_if_t<EmptyTrait<A>> Walk(A &x, M &mutator) {
175 if (mutator.Pre(x)) {
180 template <
typename A,
typename V>
181 static std::enable_if_t<TupleTrait<A>> Walk(
const A &x, V &visitor) {
182 if (visitor.Pre(x)) {
187 template <
typename A,
typename M>
188 static std::enable_if_t<TupleTrait<A>> Walk(A &x, M &mutator) {
189 if (mutator.Pre(x)) {
195 template <
typename A,
typename V>
196 static std::enable_if_t<UnionTrait<A>> Walk(
const A &x, V &visitor) {
197 if (visitor.Pre(x)) {
202 template <
typename A,
typename M>
203 static std::enable_if_t<UnionTrait<A>> Walk(A &x, M &mutator) {
204 if (mutator.Pre(x)) {
210 template <
typename A,
typename V>
211 static std::enable_if_t<WrapperTrait<A>> Walk(
const A &x, V &visitor) {
212 if (visitor.Pre(x)) {
217 template <
typename A,
typename M>
218 static std::enable_if_t<WrapperTrait<A>> Walk(A &x, M &mutator) {
219 if (mutator.Pre(x)) {
225 template <
typename A,
typename V>
226 static std::enable_if_t<ConstraintTrait<A>> Walk(
const A &x, V &visitor) {
227 if (visitor.Pre(x)) {
228 Walk(x.thing, visitor);
232 template <
typename A,
typename M>
233 static std::enable_if_t<ConstraintTrait<A>> Walk(A &x, M &mutator) {
234 if (mutator.Pre(x)) {
235 Walk(x.thing, mutator);
240 template <
typename T,
typename V>
242 Walk(x.value(), visitor);
244 template <
typename T,
typename M>
246 Walk(x.value(), mutator);
249 template <
typename T,
typename V>
251 if (visitor.Pre(x)) {
253 Walk(x.source, visitor);
254 Walk(x.statement, visitor);
258 template <
typename T,
typename M>
260 if (mutator.Pre(x)) {
262 Walk(x.source, mutator);
263 Walk(x.statement, mutator);
268 template <
typename T,
typename V>
270 if (visitor.Pre(x)) {
271 Walk(x.source, visitor);
272 Walk(x.statement, visitor);
276 template <
typename T,
typename M>
278 if (mutator.Pre(x)) {
279 Walk(x.source, mutator);
280 Walk(x.statement, mutator);
285 template <
typename V>
static void Walk(
const Name &x, V &visitor) {
286 if (visitor.Pre(x)) {
287 Walk(x.source, visitor);
291 template <
typename M>
static void Walk(
Name &x, M &mutator) {
292 if (mutator.Pre(x)) {
293 Walk(x.source, mutator);
298 template <
typename V>
static void Walk(
const AcSpec &x, V &visitor) {
299 if (visitor.Pre(x)) {
300 Walk(x.type, visitor);
301 Walk(x.values, visitor);
305 template <
typename M>
static void Walk(
AcSpec &x, M &mutator) {
306 if (mutator.Pre(x)) {
307 Walk(x.type, mutator);
308 Walk(x.values, mutator);
312 template <
typename V>
static void Walk(
const ArrayElement &x, V &visitor) {
313 if (visitor.Pre(x)) {
314 Walk(x.base, visitor);
315 Walk(x.subscripts, visitor);
319 template <
typename M>
static void Walk(
ArrayElement &x, M &mutator) {
320 if (mutator.Pre(x)) {
321 Walk(x.base, mutator);
322 Walk(x.subscripts, mutator);
326 template <
typename V>
328 if (visitor.Pre(x)) {
329 Walk(x.length, visitor);
330 Walk(x.kind, visitor);
334 template <
typename M>
336 if (mutator.Pre(x)) {
337 Walk(x.length, mutator);
338 Walk(x.kind, mutator);
342 template <
typename V>
344 if (visitor.Pre(x)) {
345 Walk(x.lower, visitor);
346 Walk(x.upper, visitor);
351 if (mutator.Pre(x)) {
352 Walk(x.lower, mutator);
353 Walk(x.upper, mutator);
357 template <
typename V>
359 if (visitor.Pre(x)) {
360 Walk(x.base, visitor);
361 Walk(x.imageSelector, visitor);
366 if (mutator.Pre(x)) {
367 Walk(x.base, mutator);
368 Walk(x.imageSelector, mutator);
372 template <
typename V>
374 if (visitor.Pre(x)) {
375 Walk(x.derived, visitor);
379 template <
typename M>
381 if (mutator.Pre(x)) {
382 Walk(x.derived, mutator);
386 template <
typename V>
388 if (visitor.Pre(x)) {
389 Walk(x.derived, visitor);
393 template <
typename M>
395 if (mutator.Pre(x)) {
396 Walk(x.derived, mutator);
400 template <
typename V>
static void Walk(
const ImportStmt &x, V &visitor) {
401 if (visitor.Pre(x)) {
402 Walk(x.names, visitor);
406 template <
typename M>
static void Walk(
ImportStmt &x, M &mutator) {
407 if (mutator.Pre(x)) {
408 Walk(x.names, mutator);
412 template <
typename V>
414 if (visitor.Pre(x)) {
415 Walk(x.selector, visitor);
419 template <
typename M>
421 if (mutator.Pre(x)) {
422 Walk(x.selector, mutator);
426 template <
typename V>
428 if (visitor.Pre(x)) {
429 Walk(x.kind, visitor);
433 template <
typename M>
435 if (mutator.Pre(x)) {
436 Walk(x.kind, mutator);
440 template <
typename V>
442 if (visitor.Pre(x)) {
443 Walk(x.kind, visitor);
447 template <
typename M>
449 if (mutator.Pre(x)) {
450 Walk(x.kind, mutator);
454 template <
typename V>
456 if (visitor.Pre(x)) {
457 Walk(x.kind, visitor);
461 template <
typename M>
463 if (mutator.Pre(x)) {
464 Walk(x.kind, mutator);
468 template <
typename A,
typename B,
typename V>
470 if (visitor.Pre(x)) {
471 Walk(x.name, visitor);
472 Walk(x.lower, visitor);
473 Walk(x.upper, visitor);
474 Walk(x.step, visitor);
478 template <
typename A,
typename B,
typename M>
480 if (mutator.Pre(x)) {
481 Walk(x.name, mutator);
482 Walk(x.lower, mutator);
483 Walk(x.upper, mutator);
484 Walk(x.step, mutator);
488 template <
typename V>
static void Walk(
const CommonStmt &x, V &visitor) {
489 if (visitor.Pre(x)) {
490 Walk(x.blocks, visitor);
494 template <
typename M>
static void Walk(
CommonStmt &x, M &mutator) {
495 if (mutator.Pre(x)) {
496 Walk(x.blocks, mutator);
512 template <
typename A,
typename V,
typename UNARY,
typename BINARY>
513 static void IterativeWalk(A &start, V &visitor) {
514 struct ExprWorkList {
515 ExprWorkList(A &x) : expr(&x) {}
516 bool doPostExpr{
false}, doPostOpr{
false};
519 std::vector<ExprWorkList> stack;
520 stack.emplace_back(start);
522 A &expr{*stack.back().expr};
523 if (stack.back().doPostOpr) {
524 stack.back().doPostOpr =
false;
525 common::visit([&visitor](
auto &y) { visitor.Post(y); }, expr.u);
526 }
else if (stack.back().doPostExpr) {
529 }
else if (!visitor.Pre(expr)) {
532 stack.back().doPostExpr =
true;
533 Walk(expr.source, visitor);
534 UNARY *unary{
nullptr};
535 BINARY *binary{
nullptr};
537 [&unary, &binary](
auto &y) {
538 if constexpr (std::is_convertible_v<
decltype(&y), UNARY *>) {
540 }
else if constexpr (std::is_convertible_v<
decltype(&y),
546 if (!unary && !binary) {
547 Walk(expr.u, visitor);
548 }
else if (common::visit([&visitor](
auto &y) {
return visitor.Pre(y); },
550 stack.back().doPostOpr =
true;
552 stack.emplace_back(unary->v.value());
554 stack.emplace_back(std::get<1>(binary->t).value());
555 stack.emplace_back(std::get<0>(binary->t).value());
559 }
while (!stack.empty());
561 template <
typename V>
static void Walk(
const Expr &x, V &visitor) {
562 IterativeWalk<
const Expr, V,
const Expr::IntrinsicUnary,
565 template <
typename M>
static void Walk(
Expr &x, M &mutator) {
566 IterativeWalk<Expr, M, Expr::IntrinsicUnary, Expr::IntrinsicBinary>(
570 template <
typename V>
static void Walk(
const Designator &x, V &visitor) {
571 if (visitor.Pre(x)) {
572 Walk(x.source, visitor);
577 template <
typename M>
static void Walk(
Designator &x, M &mutator) {
578 if (mutator.Pre(x)) {
579 Walk(x.source, mutator);
584 template <
typename V>
586 if (visitor.Pre(x)) {
587 Walk(x.source, visitor);
593 if (mutator.Pre(x)) {
594 Walk(x.source, mutator);
599 template <
typename V>
static void Walk(
const CallStmt &x, V &visitor) {
600 if (visitor.Pre(x)) {
601 Walk(x.source, visitor);
602 Walk(x.call, visitor);
603 Walk(x.chevrons, visitor);
607 template <
typename M>
static void Walk(
CallStmt &x, M &mutator) {
608 if (mutator.Pre(x)) {
609 Walk(x.source, mutator);
610 Walk(x.call, mutator);
611 Walk(x.chevrons, mutator);
615 template <
typename V>
static void Walk(
const PartRef &x, V &visitor) {
616 if (visitor.Pre(x)) {
617 Walk(x.name, visitor);
618 Walk(x.subscripts, visitor);
619 Walk(x.imageSelector, visitor);
623 template <
typename M>
static void Walk(
PartRef &x, M &mutator) {
624 if (mutator.Pre(x)) {
625 Walk(x.name, mutator);
626 Walk(x.subscripts, mutator);
627 Walk(x.imageSelector, mutator);
631 template <
typename V>
static void Walk(
const ReadStmt &x, V &visitor) {
632 if (visitor.Pre(x)) {
633 Walk(x.iounit, visitor);
634 Walk(x.format, visitor);
635 Walk(x.controls, visitor);
636 Walk(x.items, visitor);
640 template <
typename M>
static void Walk(
ReadStmt &x, M &mutator) {
641 if (mutator.Pre(x)) {
642 Walk(x.iounit, mutator);
643 Walk(x.format, mutator);
644 Walk(x.controls, mutator);
645 Walk(x.items, mutator);
649 template <
typename V>
651 if (visitor.Pre(x)) {
652 Walk(x.source, visitor);
657 template <
typename M>
659 if (mutator.Pre(x)) {
660 Walk(x.source, mutator);
665 template <
typename V>
667 if (visitor.Pre(x)) {
668 Walk(x.real, visitor);
669 Walk(x.kind, visitor);
674 if (mutator.Pre(x)) {
675 Walk(x.real, mutator);
676 Walk(x.kind, mutator);
680 template <
typename V>
682 if (visitor.Pre(x)) {
683 Walk(x.source, visitor);
687 template <
typename M>
689 if (mutator.Pre(x)) {
690 Walk(x.source, mutator);
694 template <
typename V>
696 if (visitor.Pre(x)) {
697 Walk(x.base, visitor);
698 Walk(x.component, visitor);
703 if (mutator.Pre(x)) {
704 Walk(x.base, mutator);
705 Walk(x.component, mutator);
709 template <
typename V>
static void Walk(
const Suffix &x, V &visitor) {
710 if (visitor.Pre(x)) {
711 Walk(x.binding, visitor);
712 Walk(x.resultName, visitor);
716 template <
typename M>
static void Walk(
Suffix &x, M &mutator) {
717 if (mutator.Pre(x)) {
718 Walk(x.binding, mutator);
719 Walk(x.resultName, mutator);
723 template <
typename V>
725 if (visitor.Pre(x)) {
726 Walk(x.interfaceName, visitor);
727 Walk(x.attributes, visitor);
728 Walk(x.bindingNames, visitor);
732 template <
typename M>
734 if (mutator.Pre(x)) {
735 Walk(x.interfaceName, mutator);
736 Walk(x.attributes, mutator);
737 Walk(x.bindingNames, mutator);
741 template <
typename V>
744 if (visitor.Pre(x)) {
745 Walk(x.attributes, visitor);
746 Walk(x.declarations, visitor);
750 template <
typename M>
752 if (mutator.Pre(x)) {
753 Walk(x.attributes, mutator);
754 Walk(x.declarations, mutator);
758 template <
typename V>
static void Walk(
const UseStmt &x, V &visitor) {
759 if (visitor.Pre(x)) {
760 Walk(x.nature, visitor);
761 Walk(x.moduleName, visitor);
766 template <
typename M>
static void Walk(
UseStmt &x, M &mutator) {
767 if (mutator.Pre(x)) {
768 Walk(x.nature, mutator);
769 Walk(x.moduleName, mutator);
774 template <
typename V>
static void Walk(
const WriteStmt &x, V &visitor) {
775 if (visitor.Pre(x)) {
776 Walk(x.iounit, visitor);
777 Walk(x.format, visitor);
778 Walk(x.controls, visitor);
779 Walk(x.items, visitor);
783 template <
typename M>
static void Walk(
WriteStmt &x, M &mutator) {
784 if (mutator.Pre(x)) {
785 Walk(x.iounit, mutator);
786 Walk(x.format, mutator);
787 Walk(x.controls, mutator);
788 Walk(x.items, mutator);
792 template <
typename V>
794 if (visitor.Pre(x)) {
795 Walk(x.kind, visitor);
799 template <
typename M>
801 if (mutator.Pre(x)) {
802 Walk(x.kind, mutator);
806 template <
typename V>
808 if (visitor.Pre(x)) {
809 Walk(x.type, visitor);
810 Walk(x.parameters, visitor);
814 template <
typename M>
816 if (mutator.Pre(x)) {
817 Walk(x.type, mutator);
818 Walk(x.parameters, mutator);
822 template <
typename V>
824 if (visitor.Pre(x)) {
825 Walk(x.repeatCount, visitor);
831 if (mutator.Pre(x)) {
832 Walk(x.repeatCount, mutator);
837 template <
typename V>
839 if (visitor.Pre(x)) {
840 Walk(x.items, visitor);
841 Walk(x.unlimitedItems, visitor);
845 template <
typename M>
847 if (mutator.Pre(x)) {
848 Walk(x.items, mutator);
849 Walk(x.unlimitedItems, mutator);
853 template <
typename V>
855 if (visitor.Pre(x)) {
856 Walk(x.kind, visitor);
857 Walk(x.width, visitor);
858 Walk(x.digits, visitor);
859 Walk(x.exponentWidth, visitor);
863 template <
typename M>
865 if (mutator.Pre(x)) {
866 Walk(x.kind, mutator);
867 Walk(x.width, mutator);
868 Walk(x.digits, mutator);
869 Walk(x.exponentWidth, mutator);
873 template <
typename V>
875 if (visitor.Pre(x)) {
876 Walk(x.source, visitor);
882 if (mutator.Pre(x)) {
883 Walk(x.source, mutator);
888 template <
typename V>
889 static void Walk(
const CompilerDirective::Unrecognized &x, V &visitor) {
890 if (visitor.Pre(x)) {
894 template <
typename M>
895 static void Walk(CompilerDirective::Unrecognized &x, M &mutator) {
896 if (mutator.Pre(x)) {
903template <
typename A,
typename V>
void Walk(
const A &x, V &visitor) {
904 detail::ParseTreeVisitorLookupScope::Walk(x, visitor);
907template <
typename A,
typename M>
void Walk(A &x, M &mutator) {
908 detail::ParseTreeVisitorLookupScope::Walk(x, mutator);
Definition: indirection.h:31
Definition: check-expression.h:19
Definition: parse-tree.h:1269
Definition: parse-tree.h:1911
Definition: parse-tree.h:3276
Definition: parse-tree.h:2407
Definition: parse-tree.h:681
Definition: parse-tree.h:1902
Definition: parse-tree.h:1634
Definition: parse-tree.h:3353
Definition: parse-tree.h:775
Definition: parse-tree.h:770
Definition: parse-tree.h:1857
Definition: parse-tree.h:1724
Definition: parse-tree.h:1700
Definition: parse-tree.h:3264
Definition: parse-tree.h:618
Definition: parse-tree.h:713
Definition: parse-tree.h:708
Definition: parse-tree.h:718
Definition: parse-tree.h:702
Definition: parse-tree.h:1284
Definition: parse-tree.h:580
Definition: parse-tree.h:1806
Definition: parse-tree.h:2754
Definition: parse-tree.h:823
Definition: parse-tree.h:821
Definition: parse-tree.h:795
Definition: parse-tree.h:355
Definition: parse-tree.h:1887
Definition: parse-tree.h:3135
Definition: parse-tree.h:1155
Definition: parse-tree.h:1147
Definition: parse-tree.h:350
Definition: parse-tree.h:3080
Definition: parse-tree.h:2776
Definition: parse-tree-visitor.h:40