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