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