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 #ifndef FORTRAN_PARSER_DUMP_PARSE_TREE_H_
15 #define FORTRAN_PARSER_DUMP_PARSE_TREE_H_
16 
17 #include "format-specification.h"
18 #include "parse-tree-visitor.h"
19 #include "parse-tree.h"
20 #include "../common/idioms.h"
21 #include "../common/indirection.h"
22 #include <ostream>
23 #include <string>
24 #include <type_traits>
25 
26 namespace Fortran::parser {
27 
28 using namespace std::string_literals;
29 
30 // When SHOW_ALL_SOURCE_MEMBERS is defined, HasSource<T>::value is true if T has
31 // a member named source
32 template<typename T, typename = int> struct HasSource : std::false_type {};
33 #ifdef SHOW_ALL_SOURCE_MEMBERS
34 template<typename T>
35 struct HasSource<T, decltype((void)T::source, 0)> : std::true_type {};
36 #endif
37 
38 //
39 // Dump the Parse Tree hierarchy of any node 'x' of the parse tree.
40 //
41 
42 class ParseTreeDumper {
43 public:
44   explicit ParseTreeDumper(std::ostream &out) : out_(out) {}
45 
46   constexpr const char *GetNodeName(const char *) { return "char *"; }
47 #define NODE_NAME(T, N) \
48   constexpr const char *GetNodeName(const T &) { return N; }
49 #define NODE_ENUM(T, E) \
50   std::string GetNodeName(const T::E &x) { \
51     return #E " = "s + T::EnumToString(x); \
52   }
53 #define NODE(T1, T2) NODE_NAME(T1::T2, #T2)
54   NODE_NAME(bool, "bool")
55   NODE_NAME(int, "int")
56   NODE(format, ControlEditDesc)
57   NODE(format::ControlEditDesc, Kind)
58   NODE(format, DerivedTypeDataEditDesc)
59   NODE(format, FormatItem)
60   NODE(format, FormatSpecification)
61   NODE(format, IntrinsicTypeDataEditDesc)
62   NODE(format::IntrinsicTypeDataEditDesc, Kind)
63   NODE(parser, Abstract)
64   NODE(parser, AcImpliedDo)
65   NODE(parser, AcImpliedDoControl)
66   NODE(parser, AcValue)
67   NODE(parser, AccessStmt)
68   NODE(parser, AccessId)
69   NODE(parser, AccessSpec)
70   NODE_ENUM(parser::AccessSpec, Kind)
71   NODE(parser, AcSpec)
72   NODE(parser, ActionStmt)
73   NODE(parser, ActualArg)
74   NODE(parser::ActualArg, PercentRef)
75   NODE(parser::ActualArg, PercentVal)
76   NODE(parser, ActualArgSpec)
77   NODE(parser::AcValue, Triplet)
78   NODE(parser, AllocOpt)
79   NODE(parser::AllocOpt, Mold)
80   NODE(parser::AllocOpt, Source)
81   NODE(parser, Allocatable)
82   NODE(parser, AllocatableStmt)
83   NODE(parser, AllocateCoarraySpec)
84   NODE(parser, AllocateObject)
85   NODE(parser, AllocateShapeSpec)
86   NODE(parser, AllocateStmt)
87   NODE(parser, Allocation)
88   NODE(parser, AltReturnSpec)
89   NODE(parser, ArithmeticIfStmt)
90   NODE(parser, ArrayConstructor)
91   NODE(parser, ArrayElement)
92   NODE(parser, ArraySpec)
93   NODE(parser, AssignStmt)
94   NODE(parser, AssignedGotoStmt)
95   NODE(parser, AssignmentStmt)
96   NODE(parser, AssociateConstruct)
97   NODE(parser, AssociateStmt)
98   NODE(parser, Association)
99   NODE(parser, AssumedImpliedSpec)
100   NODE(parser, AssumedRankSpec)
101   NODE(parser, AssumedShapeSpec)
102   NODE(parser, AssumedSizeSpec)
103   NODE(parser, Asynchronous)
104   NODE(parser, AsynchronousStmt)
105   NODE(parser, AttrSpec)
106   NODE(parser, BOZLiteralConstant)
107   NODE(parser, BackspaceStmt)
108   NODE(parser, BasedPointer)
109   NODE(parser, BasedPointerStmt)
110   NODE(parser, BindAttr)
111   NODE(parser::BindAttr, Deferred)
112   NODE(parser::BindAttr, Non_Overridable)
113   NODE(parser, BindEntity)
114   NODE_ENUM(parser::BindEntity, Kind)
115   NODE(parser, BindStmt)
116   NODE(parser, Block)
117   NODE(parser, BlockConstruct)
118   NODE(parser, BlockData)
119   NODE(parser, BlockDataStmt)
120   NODE(parser, BlockSpecificationPart)
121   NODE(parser, BlockStmt)
122   NODE(parser, BoundsRemapping)
123   NODE(parser, BoundsSpec)
124   NODE(parser, Call)
125   NODE(parser, CallStmt)
126   NODE(parser, CaseConstruct)
127   NODE(parser::CaseConstruct, Case)
128   NODE(parser, CaseSelector)
129   NODE(parser, CaseStmt)
130   NODE(parser, CaseValueRange)
131   NODE(parser::CaseValueRange, Range)
132   NODE(parser, ChangeTeamConstruct)
133   NODE(parser, ChangeTeamStmt)
134   NODE(parser, CharLength)
135   NODE(parser, CharLiteralConstant)
136   NODE(parser, CharLiteralConstantSubstring)
137   NODE(parser, CharSelector)
138   NODE(parser::CharSelector, LengthAndKind)
139   NODE(parser, CloseStmt)
140   NODE(parser::CloseStmt, CloseSpec)
141   NODE(parser, CoarrayAssociation)
142   NODE(parser, CoarraySpec)
143   NODE(parser, CodimensionDecl)
144   NODE(parser, CodimensionStmt)
145   NODE(parser, CoindexedNamedObject)
146   NODE(parser, CommonBlockObject)
147   NODE(parser, CommonStmt)
148   NODE(parser::CommonStmt, Block)
149   NODE(parser, CompilerDirective)
150   NODE(parser::CompilerDirective, IgnoreTKR)
151   NODE(parser, ComplexLiteralConstant)
152   NODE(parser, ComplexPart)
153   NODE(parser, ComponentArraySpec)
154   NODE(parser, ComponentAttrSpec)
155   NODE(parser, ComponentDataSource)
156   NODE(parser, ComponentDecl)
157   NODE(parser, ComponentDefStmt)
158   NODE(parser, ComponentSpec)
159   NODE(parser, ComputedGotoStmt)
160   NODE(parser, ConcurrentControl)
161   NODE(parser, ConcurrentHeader)
162   NODE(parser, ConnectSpec)
163   NODE(parser::ConnectSpec, CharExpr)
164   NODE_ENUM(parser::ConnectSpec::CharExpr, Kind)
165   NODE(parser::ConnectSpec, Newunit)
166   NODE(parser::ConnectSpec, Recl)
167   NODE(parser, ConstantValue)
168   NODE(parser, ContainsStmt)
169   NODE(parser, Contiguous)
170   NODE(parser, ContiguousStmt)
171   NODE(parser, ContinueStmt)
172   NODE(parser, CriticalConstruct)
173   NODE(parser, CriticalStmt)
174   NODE(parser, CycleStmt)
175   NODE(parser, DataComponentDefStmt)
176   NODE(parser, DataIDoObject)
177   NODE(parser, DataImpliedDo)
178   NODE(parser, DataRef)
179   NODE(parser, DataStmt)
180   NODE(parser, DataStmtConstant)
181   NODE(parser, DataStmtObject)
182   NODE(parser, DataStmtRepeat)
183   NODE(parser, DataStmtSet)
184   NODE(parser, DataStmtValue)
185   NODE(parser, DeallocateStmt)
186   NODE(parser, DeclarationConstruct)
187   NODE(parser, DeclarationTypeSpec)
188   NODE(parser::DeclarationTypeSpec, Class)
189   NODE(parser::DeclarationTypeSpec, ClassStar)
190   NODE(parser::DeclarationTypeSpec, Record)
191   NODE(parser::DeclarationTypeSpec, Type)
192   NODE(parser::DeclarationTypeSpec, TypeStar)
193   NODE(parser, Default)
194   NODE(parser, DeferredCoshapeSpecList)
195   NODE(parser, DeferredShapeSpecList)
196   NODE(parser, DefinedOpName)
197   NODE(parser, DefinedOperator)
198   NODE_ENUM(parser::DefinedOperator, IntrinsicOperator)
199   NODE(parser, DerivedTypeDef)
200   NODE(parser, DerivedTypeSpec)
201   NODE(parser, DerivedTypeStmt)
202   NODE(parser, Designator)
203   NODE(parser, DimensionStmt)
204   NODE(parser::DimensionStmt, Declaration)
205   NODE(parser, DoConstruct)
206   NODE(parser, DummyArg)
207   NODE(parser, ElseIfStmt)
208   NODE(parser, ElseStmt)
209   NODE(parser, ElsewhereStmt)
210   NODE(parser, EndAssociateStmt)
211   NODE(parser, EndBlockDataStmt)
212   NODE(parser, EndBlockStmt)
213   NODE(parser, EndChangeTeamStmt)
214   NODE(parser, EndCriticalStmt)
215   NODE(parser, EndDoStmt)
216   NODE(parser, EndEnumStmt)
217   NODE(parser, EndForallStmt)
218   NODE(parser, EndFunctionStmt)
219   NODE(parser, EndIfStmt)
220   NODE(parser, EndInterfaceStmt)
221   NODE(parser, EndLabel)
222   NODE(parser, EndModuleStmt)
223   NODE(parser, EndMpSubprogramStmt)
224   NODE(parser, EndProgramStmt)
225   NODE(parser, EndSelectStmt)
226   NODE(parser, EndSubmoduleStmt)
227   NODE(parser, EndSubroutineStmt)
228   NODE(parser, EndTypeStmt)
229   NODE(parser, EndWhereStmt)
230   NODE(parser, EndfileStmt)
231   NODE(parser, EntityDecl)
232   NODE(parser, EntryStmt)
233   NODE(parser, EnumDef)
234   NODE(parser, EnumDefStmt)
235   NODE(parser, Enumerator)
236   NODE(parser, EnumeratorDefStmt)
237   NODE(parser, EorLabel)
238   NODE(parser, EquivalenceObject)
239   NODE(parser, EquivalenceStmt)
240   NODE(parser, ErrLabel)
241   NODE(parser, ErrorRecovery)
242   NODE(parser, EventPostStmt)
243   NODE(parser, EventWaitStmt)
244   NODE(parser::EventWaitStmt, EventWaitSpec)
245   NODE(parser, ExecutableConstruct)
246   NODE(parser, ExecutionPart)
247   NODE(parser, ExecutionPartConstruct)
248   NODE(parser, ExitStmt)
249   NODE(parser, ExplicitCoshapeSpec)
250   NODE(parser, ExplicitShapeSpec)
251   NODE(parser, Expr)
252   NODE(parser::Expr, Parentheses)
253   NODE(parser::Expr, UnaryPlus)
254   NODE(parser::Expr, Negate)
255   NODE(parser::Expr, NOT)
256   NODE(parser::Expr, PercentLoc)
257   NODE(parser::Expr, DefinedUnary)
258   NODE(parser::Expr, Power)
259   NODE(parser::Expr, Multiply)
260   NODE(parser::Expr, Divide)
261   NODE(parser::Expr, Add)
262   NODE(parser::Expr, Subtract)
263   NODE(parser::Expr, Concat)
264   NODE(parser::Expr, LT)
265   NODE(parser::Expr, LE)
266   NODE(parser::Expr, EQ)
267   NODE(parser::Expr, NE)
268   NODE(parser::Expr, GE)
269   NODE(parser::Expr, GT)
270   NODE(parser::Expr, AND)
271   NODE(parser::Expr, OR)
272   NODE(parser::Expr, EQV)
273   NODE(parser::Expr, NEQV)
274   NODE(parser::Expr, XOR)
275   NODE(parser::Expr, DefinedBinary)
276   NODE(parser::Expr, ComplexConstructor)
277   NODE(parser, External)
278   NODE(parser, ExternalStmt)
279   NODE(parser, FailImageStmt)
280   NODE(parser, FileUnitNumber)
281   NODE(parser, FinalProcedureStmt)
282   NODE(parser, FlushStmt)
283   NODE(parser, ForallAssignmentStmt)
284   NODE(parser, ForallBodyConstruct)
285   NODE(parser, ForallConstruct)
286   NODE(parser, ForallConstructStmt)
287   NODE(parser, ForallStmt)
288   NODE(parser, FormTeamStmt)
289   NODE(parser::FormTeamStmt, FormTeamSpec)
290   NODE(parser, Format)
291   NODE(parser, FormatStmt)
292   NODE(parser, FunctionReference)
293   NODE(parser, FunctionStmt)
294   NODE(parser, FunctionSubprogram)
295   NODE(parser, GenericSpec)
296   NODE(parser::GenericSpec, Assignment)
297   NODE(parser::GenericSpec, ReadFormatted)
298   NODE(parser::GenericSpec, ReadUnformatted)
299   NODE(parser::GenericSpec, WriteFormatted)
300   NODE(parser::GenericSpec, WriteUnformatted)
301   NODE(parser, GenericStmt)
302   NODE(parser, GotoStmt)
303   NODE(parser, HollerithLiteralConstant)
304   NODE(parser, IdExpr)
305   NODE(parser, IdVariable)
306   NODE(parser, IfConstruct)
307   NODE(parser::IfConstruct, ElseBlock)
308   NODE(parser::IfConstruct, ElseIfBlock)
309   NODE(parser, IfStmt)
310   NODE(parser, IfThenStmt)
311   NODE(parser, TeamValue)
312   NODE(parser, ImageSelector)
313   NODE(parser, ImageSelectorSpec)
314   NODE(parser::ImageSelectorSpec, Stat)
315   NODE(parser::ImageSelectorSpec, Team_Number)
316   NODE(parser, ImplicitPart)
317   NODE(parser, ImplicitPartStmt)
318   NODE(parser, ImplicitSpec)
319   NODE(parser, ImplicitStmt)
320   NODE_ENUM(parser::ImplicitStmt, ImplicitNoneNameSpec)
321   NODE(parser, ImpliedShapeSpec)
322   NODE(parser, ImportStmt)
323   NODE(parser, Initialization)
324   NODE(parser, InputImpliedDo)
325   NODE(parser, InputItem)
326   NODE(parser, InquireSpec)
327   NODE(parser::InquireSpec, CharVar)
328   NODE_ENUM(parser::InquireSpec::CharVar, Kind)
329   NODE(parser::InquireSpec, IntVar)
330   NODE_ENUM(parser::InquireSpec::IntVar, Kind)
331   NODE(parser::InquireSpec, LogVar)
332   NODE_ENUM(parser::InquireSpec::LogVar, Kind)
333   NODE(parser, InquireStmt)
334   NODE(parser::InquireStmt, Iolength)
335   NODE(parser, IntegerTypeSpec)
336   NODE(parser, IntentSpec)
337   NODE_ENUM(parser::IntentSpec, Intent)
338   NODE(parser, IntentStmt)
339   NODE(parser, InterfaceBlock)
340   NODE(parser, InterfaceBody)
341   NODE(parser::InterfaceBody, Function)
342   NODE(parser::InterfaceBody, Subroutine)
343   NODE(parser, InterfaceSpecification)
344   NODE(parser, InterfaceStmt)
345   NODE(parser, InternalSubprogram)
346   NODE(parser, InternalSubprogramPart)
347   NODE(parser, Intrinsic)
348   NODE(parser, IntrinsicStmt)
349   NODE(parser, IntrinsicTypeSpec)
350   NODE(parser::IntrinsicTypeSpec, Character)
351   NODE(parser::IntrinsicTypeSpec, Complex)
352   NODE(parser::IntrinsicTypeSpec, DoubleComplex)
353   NODE(parser::IntrinsicTypeSpec, DoublePrecision)
354   NODE(parser::IntrinsicTypeSpec, Logical)
355   NODE(parser::IntrinsicTypeSpec, Real)
356   NODE(parser, IoControlSpec)
357   NODE(parser::IoControlSpec, Asynchronous)
358   NODE(parser::IoControlSpec, CharExpr)
359   NODE_ENUM(parser::IoControlSpec::CharExpr, Kind)
360   NODE(parser::IoControlSpec, Pos)
361   NODE(parser::IoControlSpec, Rec)
362   NODE(parser::IoControlSpec, Size)
363   NODE(parser, IoUnit)
364   NODE(parser, Keyword)
365   NODE(parser, KindParam)
366   NODE(parser, KindSelector)
367   NODE(parser::KindSelector, StarSize)
368   NODE(parser, LabelDoStmt)
369   NODE(parser, LanguageBindingSpec)
370   NODE(parser, LengthSelector)
371   NODE(parser, LetterSpec)
372   NODE(parser, LiteralConstant)
373   NODE(parser, LocalitySpec)
374   NODE(parser::LocalitySpec, DefaultNone)
375   NODE(parser::LocalitySpec, Local)
376   NODE(parser::LocalitySpec, LocalInit)
377   NODE(parser::LocalitySpec, Shared)
378   NODE(parser, LockStmt)
379   NODE(parser::LockStmt, LockStat)
380   NODE(parser, LogicalLiteralConstant)
381   NODE_NAME(parser::LoopControl::Bounds, "LoopBounds")
382   NODE_NAME(parser::AcImpliedDoControl::Bounds, "LoopBounds")
383   NODE_NAME(parser::DataImpliedDo::Bounds, "LoopBounds")
384   NODE(parser, LoopControl)
385   NODE(parser::LoopControl, Concurrent)
386   NODE(parser, MainProgram)
387   NODE(parser, Map)
388   NODE(parser::Map, EndMapStmt)
389   NODE(parser::Map, MapStmt)
390   NODE(parser, MaskedElsewhereStmt)
391   NODE(parser, Module)
392   NODE(parser, ModuleStmt)
393   NODE(parser, ModuleSubprogram)
394   NODE(parser, ModuleSubprogramPart)
395   NODE(parser, MpSubprogramStmt)
396   NODE(parser, MsgVariable)
397   NODE(parser, NamedConstant)
398   NODE(parser, NamedConstantDef)
399   NODE(parser, NamelistStmt)
400   NODE(parser::NamelistStmt, Group)
401   NODE(parser, NonLabelDoStmt)
402   NODE(parser, NoPass)
403   NODE(parser, NullifyStmt)
404   NODE(parser, NullInit)
405   NODE(parser, ObjectDecl)
406   NODE(parser, OldParameterStmt)
407   NODE(parser, OmpAlignedClause)
408   NODE(parser, OmpAtomic)
409   NODE(parser, OmpAtomicCapture)
410   NODE(parser::OmpAtomicCapture, Stmt1)
411   NODE(parser::OmpAtomicCapture, Stmt2)
412   NODE(parser, OmpAtomicRead)
413   NODE(parser, OmpAtomicUpdate)
414   NODE(parser, OmpAtomicWrite)
415   NODE(parser, OmpBeginBlockDirective)
416   NODE(parser, OmpBeginLoopDirective)
417   NODE(parser, OmpBeginSectionsDirective)
418   NODE(parser, OmpBlockDirective)
419   NODE_ENUM(parser::OmpBlockDirective, Directive)
420   NODE(parser, OmpCancelType)
421   NODE_ENUM(parser::OmpCancelType, Type)
422   NODE(parser, OmpClause)
423   NODE(parser, OmpClauseList)
424   NODE(parser::OmpClause, Collapse)
425   NODE(parser::OmpClause, Copyin)
426   NODE(parser::OmpClause, Copyprivate)
427   NODE(parser::OmpClause, Device)
428   NODE(parser::OmpClause, DistSchedule)
429   NODE(parser::OmpClause, Final)
430   NODE(parser::OmpClause, Firstprivate)
431   NODE(parser::OmpClause, From)
432   NODE(parser::OmpClause, Grainsize)
433   NODE(parser::OmpClause, Inbranch)
434   NODE(parser::OmpClause, Lastprivate)
435   NODE(parser::OmpClause, Mergeable)
436   NODE(parser::OmpClause, Nogroup)
437   NODE(parser::OmpClause, Notinbranch)
438   NODE(parser::OmpClause, Threads)
439   NODE(parser::OmpClause, Simd)
440   NODE(parser::OmpClause, NumTasks)
441   NODE(parser::OmpClause, NumTeams)
442   NODE(parser::OmpClause, NumThreads)
443   NODE(parser::OmpClause, Ordered)
444   NODE(parser::OmpClause, Priority)
445   NODE(parser::OmpClause, Private)
446   NODE(parser::OmpClause, Safelen)
447   NODE(parser::OmpClause, Shared)
448   NODE(parser::OmpClause, Simdlen)
449   NODE(parser::OmpClause, ThreadLimit)
450   NODE(parser::OmpClause, To)
451   NODE(parser::OmpClause, Link)
452   NODE(parser::OmpClause, Uniform)
453   NODE(parser::OmpClause, Untied)
454   NODE(parser::OmpClause, UseDevicePtr)
455   NODE(parser::OmpClause, IsDevicePtr)
456   NODE(parser, OmpCriticalDirective)
457   NODE(parser::OmpCriticalDirective, Hint)
458   NODE(parser, OmpDeclareTargetSpecifier)
459   NODE(parser, OmpDeclareTargetWithClause)
460   NODE(parser, OmpDeclareTargetWithList)
461   NODE(parser, OmpDefaultClause)
462   NODE_ENUM(parser::OmpDefaultClause, Type)
463   NODE(parser, OmpDefaultmapClause)
464   NODE_ENUM(parser::OmpDefaultmapClause, ImplicitBehavior)
465   NODE_ENUM(parser::OmpDefaultmapClause, VariableCategory)
466   NODE(parser, OmpDependClause)
467   NODE(parser::OmpDependClause, InOut)
468   NODE(parser::OmpDependClause, Sink)
469   NODE(parser::OmpDependClause, Source)
470   NODE(parser, OmpDependenceType)
471   NODE_ENUM(parser::OmpDependenceType, Type)
472   NODE(parser, OmpDependSinkVec)
473   NODE(parser, OmpDependSinkVecLength)
474   NODE(parser, OmpEndAtomic)
475   NODE(parser, OmpEndBlockDirective)
476   NODE(parser, OmpEndCriticalDirective)
477   NODE(parser, OmpEndLoopDirective)
478   NODE(parser, OmpEndSectionsDirective)
479   NODE(parser, OmpIfClause)
480   NODE_ENUM(parser::OmpIfClause, DirectiveNameModifier)
481   NODE(parser, OmpLinearClause)
482   NODE(parser::OmpLinearClause, WithModifier)
483   NODE(parser::OmpLinearClause, WithoutModifier)
484   NODE(parser, OmpLinearModifier)
485   NODE_ENUM(parser::OmpLinearModifier, Type)
486   NODE(parser, OmpLoopDirective)
487   NODE_ENUM(parser::OmpLoopDirective, Directive)
488   NODE(parser, OmpMapClause)
489   NODE(parser, OmpMapType)
490   NODE(parser::OmpMapType, Always)
491   NODE_ENUM(parser::OmpMapType, Type)
492   NODE(parser, OmpMemoryClause)
493   NODE_ENUM(parser::OmpMemoryClause, MemoryOrder)
494   NODE(parser, OmpMemoryClauseList)
495   NODE(parser, OmpMemoryClausePostList)
496   NODE(parser, OmpNowait)
497   NODE(parser, OmpObject)
498   NODE(parser, OmpObjectList)
499   NODE(parser, OmpProcBindClause)
500   NODE_ENUM(parser::OmpProcBindClause, Type)
501   NODE(parser, OmpReductionClause)
502   NODE(parser, OmpReductionCombiner)
503   NODE(parser::OmpReductionCombiner, FunctionCombiner)
504   NODE(parser, OmpReductionInitializerClause)
505   NODE(parser, OmpReductionOperator)
506   NODE(parser, OmpScheduleClause)
507   NODE_ENUM(parser::OmpScheduleClause, ScheduleType)
508   NODE(parser, OmpScheduleModifier)
509   NODE(parser::OmpScheduleModifier, Modifier1)
510   NODE(parser::OmpScheduleModifier, Modifier2)
511   NODE(parser, OmpScheduleModifierType)
512   NODE_ENUM(parser::OmpScheduleModifierType, ModType)
513   NODE(parser, OmpSectionBlocks)
514   NODE(parser, OmpSectionsDirective)
515   NODE_ENUM(parser::OmpSectionsDirective, Directive)
516   NODE(parser, OmpSimpleStandaloneDirective)
517   NODE_ENUM(parser::OmpSimpleStandaloneDirective, Directive)
518   NODE(parser, Only)
519   NODE(parser, OpenMPAtomicConstruct)
520   NODE(parser, OpenMPBlockConstruct)
521   NODE(parser, OpenMPCancelConstruct)
522   NODE(parser::OpenMPCancelConstruct, If)
523   NODE(parser, OpenMPCancellationPointConstruct)
524   NODE(parser, OpenMPConstruct)
525   NODE(parser, OpenMPCriticalConstruct)
526   NODE(parser, OpenMPDeclarativeConstruct)
527   NODE(parser, OpenMPDeclareReductionConstruct)
528   NODE(parser, OpenMPDeclareSimdConstruct)
529   NODE(parser, OpenMPDeclareTargetConstruct)
530   NODE(parser, OpenMPFlushConstruct)
531   NODE(parser, OpenMPLoopConstruct)
532   NODE(parser, OpenMPSimpleStandaloneConstruct)
533   NODE(parser, OpenMPStandaloneConstruct)
534   NODE(parser, OpenMPSectionsConstruct)
535   NODE(parser, OpenMPThreadprivate)
536   NODE(parser, OpenStmt)
537   NODE(parser, Optional)
538   NODE(parser, OptionalStmt)
539   NODE(parser, OtherSpecificationStmt)
540   NODE(parser, OutputImpliedDo)
541   NODE(parser, OutputItem)
542   NODE(parser, Parameter)
543   NODE(parser, ParameterStmt)
544   NODE(parser, ParentIdentifier)
545   NODE(parser, Pass)
546   NODE(parser, PauseStmt)
547   NODE(parser, Pointer)
548   NODE(parser, PointerAssignmentStmt)
549   NODE(parser::PointerAssignmentStmt, Bounds)
550   NODE(parser, PointerDecl)
551   NODE(parser, PointerObject)
552   NODE(parser, PointerStmt)
553   NODE(parser, PositionOrFlushSpec)
554   NODE(parser, PrefixSpec)
555   NODE(parser::PrefixSpec, Elemental)
556   NODE(parser::PrefixSpec, Impure)
557   NODE(parser::PrefixSpec, Module)
558   NODE(parser::PrefixSpec, Non_Recursive)
559   NODE(parser::PrefixSpec, Pure)
560   NODE(parser::PrefixSpec, Recursive)
561   NODE(parser, PrintStmt)
562   NODE(parser, PrivateStmt)
563   NODE(parser, PrivateOrSequence)
564   NODE(parser, ProcAttrSpec)
565   NODE(parser, ProcComponentAttrSpec)
566   NODE(parser, ProcComponentDefStmt)
567   NODE(parser, ProcComponentRef)
568   NODE(parser, ProcDecl)
569   NODE(parser, ProcInterface)
570   NODE(parser, ProcPointerInit)
571   NODE(parser, ProcedureDeclarationStmt)
572   NODE(parser, ProcedureDesignator)
573   NODE(parser, ProcedureStmt)
574   NODE_ENUM(parser::ProcedureStmt, Kind)
575   NODE(parser, Program)
576   NODE(parser, ProgramStmt)
577   NODE(parser, ProgramUnit)
578   NODE(parser, Protected)
579   NODE(parser, ProtectedStmt)
580   NODE(parser, ReadStmt)
581   NODE(parser, RealLiteralConstant)
582   NODE(parser::RealLiteralConstant, Real)
583   NODE(parser, Rename)
584   NODE(parser::Rename, Names)
585   NODE(parser::Rename, Operators)
586   NODE(parser, ReturnStmt)
587   NODE(parser, RewindStmt)
588   NODE(parser, Save)
589   NODE(parser, SaveStmt)
590   NODE(parser, SavedEntity)
591   NODE_ENUM(parser::SavedEntity, Kind)
592   NODE(parser, SectionSubscript)
593   NODE(parser, SelectCaseStmt)
594   NODE(parser, SelectRankCaseStmt)
595   NODE(parser::SelectRankCaseStmt, Rank)
596   NODE(parser, SelectRankConstruct)
597   NODE(parser::SelectRankConstruct, RankCase)
598   NODE(parser, SelectRankStmt)
599   NODE(parser, SelectTypeConstruct)
600   NODE(parser::SelectTypeConstruct, TypeCase)
601   NODE(parser, SelectTypeStmt)
602   NODE(parser, Selector)
603   NODE(parser, SeparateModuleSubprogram)
604   NODE(parser, SequenceStmt)
605   NODE(parser, Sign)
606   NODE(parser, SignedComplexLiteralConstant)
607   NODE(parser, SignedRealLiteralConstant)
608   NODE(parser, SpecificationConstruct)
609   NODE(parser, SpecificationExpr)
610   NODE(parser, SpecificationPart)
611   NODE(parser, Star)
612   NODE(parser, StatOrErrmsg)
613   NODE(parser, StatVariable)
614   NODE(parser, StatusExpr)
615   NODE(parser, StmtFunctionStmt)
616   NODE(parser, StopCode)
617   NODE(parser, StopStmt)
618   NODE_ENUM(parser::StopStmt, Kind)
619   NODE(parser, StructureComponent)
620   NODE(parser, StructureConstructor)
621   NODE(parser, StructureDef)
622   NODE(parser::StructureDef, EndStructureStmt)
623   NODE(parser, StructureField)
624   NODE(parser, StructureStmt)
625   NODE(parser, Submodule)
626   NODE(parser, SubmoduleStmt)
627   NODE(parser, SubroutineStmt)
628   NODE(parser, SubroutineSubprogram)
629   NODE(parser, SubscriptTriplet)
630   NODE(parser, Substring)
631   NODE(parser, SubstringRange)
632   NODE(parser, Suffix)
633   NODE(parser, SyncAllStmt)
634   NODE(parser, SyncImagesStmt)
635   NODE(parser::SyncImagesStmt, ImageSet)
636   NODE(parser, SyncMemoryStmt)
637   NODE(parser, SyncTeamStmt)
638   NODE(parser, Target)
639   NODE(parser, TargetStmt)
640   NODE(parser, TypeAttrSpec)
641   NODE(parser::TypeAttrSpec, BindC)
642   NODE(parser::TypeAttrSpec, Extends)
643   NODE(parser, TypeBoundGenericStmt)
644   NODE(parser, TypeBoundProcBinding)
645   NODE(parser, TypeBoundProcDecl)
646   NODE(parser, TypeBoundProcedurePart)
647   NODE(parser, TypeBoundProcedureStmt)
648   NODE(parser::TypeBoundProcedureStmt, WithInterface)
649   NODE(parser::TypeBoundProcedureStmt, WithoutInterface)
650   NODE(parser, TypeDeclarationStmt)
651   NODE(parser, TypeGuardStmt)
652   NODE(parser::TypeGuardStmt, Guard)
653   NODE(parser, TypeParamDecl)
654   NODE(parser, TypeParamDefStmt)
655   NODE(common, TypeParamAttr)
656   NODE(parser, TypeParamSpec)
657   NODE(parser, TypeParamValue)
658   NODE(parser::TypeParamValue, Deferred)
659   NODE(parser, TypeSpec)
660   NODE(parser, Union)
661   NODE(parser::Union, EndUnionStmt)
662   NODE(parser::Union, UnionStmt)
663   NODE(parser, UnlockStmt)
664   NODE(parser, UseStmt)
665   NODE_ENUM(parser::UseStmt, ModuleNature)
666   NODE(parser, Value)
667   NODE(parser, ValueStmt)
668   NODE(parser, Variable)
669   NODE(parser, Verbatim)
670   NODE(parser, Volatile)
671   NODE(parser, VolatileStmt)
672   NODE(parser, WaitSpec)
673   NODE(parser, WaitStmt)
674   NODE(parser, WhereBodyConstruct)
675   NODE(parser, WhereConstruct)
676   NODE(parser::WhereConstruct, Elsewhere)
677   NODE(parser::WhereConstruct, MaskedElsewhere)
678   NODE(parser, WhereConstructStmt)
679   NODE(parser, WhereStmt)
680   NODE(parser, WriteStmt)
681 #undef NODE
682 #undef NODE_NAME
683 
684   template<typename T> bool Pre(const T &x) {
685     if constexpr (!HasSource<T>::value && (UnionTrait<T> || WrapperTrait<T>)) {
686       Prefix(GetNodeName(x));
687     } else {
688       IndentEmptyLine();
689       out_ << GetNodeName(x);
690       if constexpr (HasSource<T>::value) {
691         out_ << " = '" << x.source.ToString() << '\'';
692       }
693       EndLine();
694       ++indent_;
695     }
696     return true;
697   }
698 
699   template<typename T> void Post(const T &) {
700     if constexpr (!HasSource<T>::value && (UnionTrait<T> || WrapperTrait<T>)) {
701       EndLineIfNonempty();
702     } else {
703       --indent_;
704     }
705   }
706 
707   bool Pre(const parser::Name &x) {
708     IndentEmptyLine();
709     out_ << "Name = '" << x.ToString() << '\'';
710     EndLine();
711     return false;
712   }
713   bool Pre(const std::string &x) {
714     IndentEmptyLine();
715     out_ << "string = '" << x << '\'';
716     EndLine();
717     return false;
718   }
719 
720   bool Pre(const std::int64_t &x) {
721     IndentEmptyLine();
722     out_ << "int = '" << x << '\'';
723     ++indent_;
724     EndLine();
725     return true;
726   }
727   void Post(const std::int64_t &) { --indent_; }
728 
729   bool Pre(const std::uint64_t &x) {
730     IndentEmptyLine();
731     out_ << "int = '" << x << '\'';
732     EndLine();
733     return false;
734   }
735 
736   bool Pre(const parser::IntLiteralConstant &x) {
737     IndentEmptyLine();
738     out_ << "int = '" << std::get<parser::CharBlock>(x.t).ToString() << '\'';
739     EndLine();
740     ++indent_;
741     Walk(std::get<std::optional<KindParam>>(x.t), *this);
742     --indent_;
743     return false;
744   }
745 
746   bool Pre(const parser::SignedIntLiteralConstant &x) {
747     IndentEmptyLine();
748     out_ << "int = '" << std::get<parser::CharBlock>(x.t).ToString() << '\'';
749     EndLine();
750     ++indent_;
751     Walk(std::get<std::optional<KindParam>>(x.t), *this);
752     --indent_;
753     return false;
754   }
755 
756   bool Pre(const parser::RealLiteralConstant &x) {
757     Prefix(GetNodeName(x));
758     out_ << "Real = '" << x.real.source.ToString() << '\'';
759     EndLine();
760     ++indent_;
761     Walk(x.kind, *this);
762     --indent_;
763     return false;
764   }
765 
766   // A few types we want to ignore
767 
768   bool Pre(const parser::CharBlock &) { return true; }
769   void Post(const parser::CharBlock &) {}
770 
771   template<typename T> bool Pre(const parser::Statement<T> &) { return true; }
772   template<typename T> void Post(const parser::Statement<T> &) {}
773   template<typename T> bool Pre(const parser::UnlabeledStatement<T> &) {
774     return true;
775   }
776   template<typename T> void Post(const parser::UnlabeledStatement<T> &) {}
777 
778   template<typename T> bool Pre(const common::Indirection<T> &) { return true; }
779   template<typename T> void Post(const common::Indirection<T> &) {}
780 
781   template<typename A> bool Pre(const parser::Scalar<A> &) {
782     Prefix("Scalar");
783     return true;
784   }
785   template<typename A> void Post(const parser::Scalar<A> &) {
786     EndLineIfNonempty();
787   }
788 
789   template<typename A> bool Pre(const parser::Constant<A> &) {
790     Prefix("Constant");
791     return true;
792   }
793   template<typename A> void Post(const parser::Constant<A> &) {
794     EndLineIfNonempty();
795   }
796 
797   template<typename A> bool Pre(const parser::Integer<A> &) {
798     Prefix("Integer");
799     return true;
800   }
801   template<typename A> void Post(const parser::Integer<A> &) {
802     EndLineIfNonempty();
803   }
804 
805   template<typename A> bool Pre(const parser::Logical<A> &) {
806     Prefix("Logical");
807     return true;
808   }
809   template<typename A> void Post(const parser::Logical<A> &) {
810     EndLineIfNonempty();
811   }
812 
813   template<typename A> bool Pre(const parser::DefaultChar<A> &) {
814     Prefix("DefaultChar");
815     return true;
816   }
817   template<typename A> void Post(const parser::DefaultChar<A> &) {
818     EndLineIfNonempty();
819   }
820 
821   template<typename... A> bool Pre(const std::tuple<A...> &) { return true; }
822   template<typename... A> void Post(const std::tuple<A...> &) {}
823 
824   template<typename... A> bool Pre(const std::variant<A...> &) { return true; }
825   template<typename... A> void Post(const std::variant<A...> &) {}
826 
827 protected:
828   void IndentEmptyLine() {
829     if (emptyline_ && indent_ > 0) {
830       for (int i{0}; i < indent_; ++i) {
831         out_ << "| ";
832       }
833       emptyline_ = false;
834     }
835   }
836 
837   void Prefix(const char *str) {
838     IndentEmptyLine();
839     out_ << str << " -> ";
840     emptyline_ = false;
841   }
842 
843   void Prefix(const std::string &str) {
844     IndentEmptyLine();
845     out_ << str << " -> ";
846     emptyline_ = false;
847   }
848 
849   void EndLine() {
850     out_ << '\n';
851     emptyline_ = true;
852   }
853 
854   void EndLineIfNonempty() {
855     if (!emptyline_) {
856       EndLine();
857     }
858   }
859 
860 private:
861   int indent_{0};
862   std::ostream &out_;
863   bool emptyline_{false};
864 };
865 
866 template<typename T> void DumpTree(std::ostream &out, const T &x) {
867   ParseTreeDumper dumper{out};
868   parser::Walk(x, dumper);
869 }
870 }
871 #endif  // FORTRAN_PARSER_DUMP_PARSE_TREE_H_
872