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