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