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