//===-- include/flang/Parser/dump-parse-tree.h ------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #ifndef FORTRAN_PARSER_DUMP_PARSE_TREE_H_ #define FORTRAN_PARSER_DUMP_PARSE_TREE_H_ #include "format-specification.h" #include "parse-tree-visitor.h" #include "parse-tree.h" #include "tools.h" #include "unparse.h" #include "flang/Common/Fortran.h" #include "flang/Common/idioms.h" #include "flang/Common/indirection.h" #include "llvm/Support/raw_ostream.h" #include #include namespace Fortran::parser { // // Dump the Parse Tree hierarchy of any node 'x' of the parse tree. // class ParseTreeDumper { public: explicit ParseTreeDumper(llvm::raw_ostream &out, const AnalyzedObjectsAsFortran *asFortran = nullptr) : out_(out), asFortran_{asFortran} {} static constexpr const char *GetNodeName(const char *) { return "char *"; } #define NODE_NAME(T, N) \ static constexpr const char *GetNodeName(const T &) { return N; } #define NODE_ENUM(T, E) \ static std::string GetNodeName(const T::E &x) { \ return #E " = "s + std::string{T::EnumToString(x)}; \ } #define NODE(T1, T2) NODE_NAME(T1::T2, #T2) NODE_NAME(bool, "bool") NODE_NAME(int, "int") NODE(std, string) NODE(std, int64_t) NODE(std, uint64_t) NODE_ENUM(common, CUDADataAttr) NODE_ENUM(common, CUDASubprogramAttrs) NODE_ENUM(common, OpenACCDeviceType) NODE(format, ControlEditDesc) NODE(format::ControlEditDesc, Kind) NODE(format, DerivedTypeDataEditDesc) NODE(format, FormatItem) NODE(format, FormatSpecification) NODE(format, IntrinsicTypeDataEditDesc) NODE(format::IntrinsicTypeDataEditDesc, Kind) NODE(parser, Abstract) NODE(parser, AccAtomicCapture) NODE(AccAtomicCapture, Stmt1) NODE(AccAtomicCapture, Stmt2) NODE(parser, AccAtomicRead) NODE(parser, AccAtomicUpdate) NODE(parser, AccAtomicWrite) NODE(parser, AccBeginBlockDirective) NODE(parser, AccBeginCombinedDirective) NODE(parser, AccBeginLoopDirective) NODE(parser, AccBlockDirective) NODE(parser, AccClause) #define GEN_FLANG_DUMP_PARSE_TREE_CLAUSES #include "llvm/Frontend/OpenACC/ACC.inc" NODE(parser, AccBindClause) NODE(parser, AccDefaultClause) static std::string GetNodeName(const llvm::acc::DefaultValue &x) { return llvm::Twine( "llvm::acc::DefaultValue = ", llvm::acc::getOpenACCDefaultValueName(x)) .str(); } NODE(parser, AccClauseList) NODE(parser, AccCombinedDirective) NODE(parser, AccDataModifier) NODE_ENUM(parser::AccDataModifier, Modifier) NODE(parser, AccDeclarativeDirective) NODE(parser, AccEndAtomic) NODE(parser, AccEndBlockDirective) NODE(parser, AccEndCombinedDirective) NODE(parser, AccCollapseArg) NODE(parser, AccGangArg) NODE(AccGangArg, Num) NODE(AccGangArg, Dim) NODE(AccGangArg, Static) NODE(parser, AccGangArgList) NODE(parser, AccObject) NODE(parser, AccObjectList) NODE(parser, AccObjectListWithModifier) NODE(parser, AccObjectListWithReduction) NODE(parser, AccReductionOperator) NODE_ENUM(parser::AccReductionOperator, Operator) NODE(parser, AccSizeExpr) NODE(parser, AccSizeExprList) NODE(parser, AccSelfClause) NODE(parser, AccStandaloneDirective) NODE(parser, AccDeviceTypeExpr) NODE(parser, AccDeviceTypeExprList) NODE(parser, AccTileExpr) NODE(parser, AccTileExprList) NODE(parser, AccLoopDirective) NODE(parser, AccEndLoop) NODE(parser, AccWaitArgument) static std::string GetNodeName(const llvm::acc::Directive &x) { return llvm::Twine( "llvm::acc::Directive = ", llvm::acc::getOpenACCDirectiveName(x)) .str(); } NODE(parser, AcImpliedDo) NODE(parser, AcImpliedDoControl) NODE(parser, AcValue) NODE(parser, AccessStmt) NODE(parser, AccessId) NODE(parser, AccessSpec) NODE_ENUM(AccessSpec, Kind) NODE(parser, AcSpec) NODE(parser, ActionStmt) NODE(parser, ActualArg) NODE(ActualArg, PercentRef) NODE(ActualArg, PercentVal) NODE(parser, ActualArgSpec) NODE(AcValue, Triplet) NODE(parser, AllocOpt) NODE(AllocOpt, Mold) NODE(AllocOpt, Source) NODE(AllocOpt, Stream) NODE(AllocOpt, Pinned) NODE(parser, Allocatable) NODE(parser, AllocatableStmt) NODE(parser, AllocateCoarraySpec) NODE(parser, AllocateObject) NODE(parser, AllocateShapeSpec) NODE(parser, AllocateStmt) NODE(parser, Allocation) NODE(parser, AltReturnSpec) NODE(parser, ArithmeticIfStmt) NODE(parser, ArrayConstructor) NODE(parser, ArrayElement) NODE(parser, ArraySpec) NODE(parser, AssignStmt) NODE(parser, AssignedGotoStmt) NODE(parser, AssignmentStmt) NODE(parser, AssociateConstruct) NODE(parser, AssociateStmt) NODE(parser, Association) NODE(parser, AssumedImpliedSpec) NODE(parser, AssumedRankSpec) NODE(parser, AssumedShapeSpec) NODE(parser, AssumedSizeSpec) NODE(parser, Asynchronous) NODE(parser, AsynchronousStmt) NODE(parser, AttrSpec) NODE(parser, BOZLiteralConstant) NODE(parser, BackspaceStmt) NODE(parser, BasedPointer) NODE(parser, BasedPointerStmt) NODE(parser, BindAttr) NODE(BindAttr, Deferred) NODE(BindAttr, Non_Overridable) NODE(parser, BindEntity) NODE_ENUM(BindEntity, Kind) NODE(parser, BindStmt) NODE(parser, Block) NODE(parser, BlockConstruct) NODE(parser, BlockData) NODE(parser, BlockDataStmt) NODE(parser, BlockSpecificationPart) NODE(parser, BlockStmt) NODE(parser, BoundsRemapping) NODE(parser, BoundsSpec) NODE(parser, Call) NODE(parser, CallStmt) NODE(CallStmt, Chevrons) NODE(parser, CaseConstruct) NODE(CaseConstruct, Case) NODE(parser, CaseSelector) NODE(parser, CaseStmt) NODE(parser, CaseValueRange) NODE(CaseValueRange, Range) NODE(parser, ChangeTeamConstruct) NODE(parser, ChangeTeamStmt) NODE(parser, CharLength) NODE(parser, CharLiteralConstant) NODE(parser, CharLiteralConstantSubstring) NODE(parser, CharSelector) NODE(CharSelector, LengthAndKind) NODE(parser, CloseStmt) NODE(CloseStmt, CloseSpec) NODE(parser, CoarrayAssociation) NODE(parser, CoarraySpec) NODE(parser, CodimensionDecl) NODE(parser, CodimensionStmt) NODE(parser, CoindexedNamedObject) NODE(parser, CommonBlockObject) NODE(parser, CommonStmt) NODE(CommonStmt, Block) NODE(parser, CompilerDirective) NODE(CompilerDirective, IgnoreTKR) NODE(CompilerDirective, LoopCount) NODE(CompilerDirective, NameValue) NODE(parser, ComplexLiteralConstant) NODE(parser, ComplexPart) NODE(parser, ComponentArraySpec) NODE(parser, ComponentAttrSpec) NODE(parser, ComponentDataSource) NODE(parser, ComponentDecl) NODE(parser, FillDecl) NODE(parser, ComponentOrFill) NODE(parser, ComponentDefStmt) NODE(parser, ComponentSpec) NODE(parser, ComputedGotoStmt) NODE(parser, ConcurrentControl) NODE(parser, ConcurrentHeader) NODE(parser, ConnectSpec) NODE(ConnectSpec, CharExpr) NODE_ENUM(ConnectSpec::CharExpr, Kind) NODE(ConnectSpec, Newunit) NODE(ConnectSpec, Recl) NODE(parser, ContainsStmt) NODE(parser, Contiguous) NODE(parser, ContiguousStmt) NODE(parser, ContinueStmt) NODE(parser, CriticalConstruct) NODE(parser, CriticalStmt) NODE(parser, CUDAAttributesStmt) NODE(parser, CUFKernelDoConstruct) NODE(CUFKernelDoConstruct, Directive) NODE(parser, CycleStmt) NODE(parser, DataComponentDefStmt) NODE(parser, DataIDoObject) NODE(parser, DataImpliedDo) NODE(parser, DataRef) NODE(parser, DataStmt) NODE(parser, DataStmtConstant) NODE(parser, DataStmtObject) NODE(parser, DataStmtRepeat) NODE(parser, DataStmtSet) NODE(parser, DataStmtValue) NODE(parser, DeallocateStmt) NODE(parser, DeclarationConstruct) NODE(parser, DeclarationTypeSpec) NODE(DeclarationTypeSpec, Class) NODE(DeclarationTypeSpec, ClassStar) NODE(DeclarationTypeSpec, Record) NODE(DeclarationTypeSpec, Type) NODE(DeclarationTypeSpec, TypeStar) NODE(parser, Default) NODE(parser, DeferredCoshapeSpecList) NODE(parser, DeferredShapeSpecList) NODE(parser, DefinedOpName) NODE(parser, DefinedOperator) NODE_ENUM(DefinedOperator, IntrinsicOperator) NODE(parser, DerivedTypeDef) NODE(parser, DerivedTypeSpec) NODE(parser, DerivedTypeStmt) NODE(parser, Designator) NODE(parser, DimensionStmt) NODE(DimensionStmt, Declaration) NODE(parser, DoConstruct) NODE(parser, DummyArg) NODE(parser, ElseIfStmt) NODE(parser, ElseStmt) NODE(parser, ElsewhereStmt) NODE(parser, EndAssociateStmt) NODE(parser, EndBlockDataStmt) NODE(parser, EndBlockStmt) NODE(parser, EndChangeTeamStmt) NODE(parser, EndCriticalStmt) NODE(parser, EndDoStmt) NODE(parser, EndEnumStmt) NODE(parser, EndForallStmt) NODE(parser, EndFunctionStmt) NODE(parser, EndIfStmt) NODE(parser, EndInterfaceStmt) NODE(parser, EndLabel) NODE(parser, EndModuleStmt) NODE(parser, EndMpSubprogramStmt) NODE(parser, EndProgramStmt) NODE(parser, EndSelectStmt) NODE(parser, EndSubmoduleStmt) NODE(parser, EndSubroutineStmt) NODE(parser, EndTypeStmt) NODE(parser, EndWhereStmt) NODE(parser, EndfileStmt) NODE(parser, EntityDecl) NODE(parser, EntryStmt) NODE(parser, EnumDef) NODE(parser, EnumDefStmt) NODE(parser, Enumerator) NODE(parser, EnumeratorDefStmt) NODE(parser, EorLabel) NODE(parser, EquivalenceObject) NODE(parser, EquivalenceStmt) NODE(parser, ErrLabel) NODE(parser, ErrorRecovery) NODE(parser, EventPostStmt) NODE(parser, EventWaitSpec) NODE(parser, EventWaitStmt) NODE(parser, ExecutableConstruct) NODE(parser, ExecutionPart) NODE(parser, ExecutionPartConstruct) NODE(parser, ExitStmt) NODE(parser, ExplicitCoshapeSpec) NODE(parser, ExplicitShapeSpec) NODE(parser, Expr) NODE(Expr, Parentheses) NODE(Expr, UnaryPlus) NODE(Expr, Negate) NODE(Expr, NOT) NODE(Expr, PercentLoc) NODE(Expr, DefinedUnary) NODE(Expr, Power) NODE(Expr, Multiply) NODE(Expr, Divide) NODE(Expr, Add) NODE(Expr, Subtract) NODE(Expr, Concat) NODE(Expr, LT) NODE(Expr, LE) NODE(Expr, EQ) NODE(Expr, NE) NODE(Expr, GE) NODE(Expr, GT) NODE(Expr, AND) NODE(Expr, OR) NODE(Expr, EQV) NODE(Expr, NEQV) NODE(Expr, DefinedBinary) NODE(Expr, ComplexConstructor) NODE(parser, External) NODE(parser, ExternalStmt) NODE(parser, FailImageStmt) NODE(parser, FileUnitNumber) NODE(parser, FinalProcedureStmt) NODE(parser, FlushStmt) NODE(parser, ForallAssignmentStmt) NODE(parser, ForallBodyConstruct) NODE(parser, ForallConstruct) NODE(parser, ForallConstructStmt) NODE(parser, ForallStmt) NODE(parser, FormTeamStmt) NODE(FormTeamStmt, FormTeamSpec) NODE(parser, Format) NODE(parser, FormatStmt) NODE(parser, FunctionReference) NODE(parser, FunctionStmt) NODE(parser, FunctionSubprogram) NODE(parser, GenericSpec) NODE(GenericSpec, Assignment) NODE(GenericSpec, ReadFormatted) NODE(GenericSpec, ReadUnformatted) NODE(GenericSpec, WriteFormatted) NODE(GenericSpec, WriteUnformatted) NODE(parser, GenericStmt) NODE(parser, GotoStmt) NODE(parser, HollerithLiteralConstant) NODE(parser, IdExpr) NODE(parser, IdVariable) NODE(parser, IfConstruct) NODE(IfConstruct, ElseBlock) NODE(IfConstruct, ElseIfBlock) NODE(parser, IfStmt) NODE(parser, IfThenStmt) NODE(parser, TeamValue) NODE(parser, ImageSelector) NODE(parser, ImageSelectorSpec) NODE(ImageSelectorSpec, Stat) NODE(ImageSelectorSpec, Team_Number) NODE(parser, ImplicitPart) NODE(parser, ImplicitPartStmt) NODE(parser, ImplicitSpec) NODE(parser, ImplicitStmt) NODE_ENUM(ImplicitStmt, ImplicitNoneNameSpec) NODE(parser, ImpliedShapeSpec) NODE(parser, ImportStmt) NODE(parser, Initialization) NODE(parser, InputImpliedDo) NODE(parser, InputItem) NODE(parser, InquireSpec) NODE(InquireSpec, CharVar) NODE_ENUM(InquireSpec::CharVar, Kind) NODE(InquireSpec, IntVar) NODE_ENUM(InquireSpec::IntVar, Kind) NODE(InquireSpec, LogVar) NODE_ENUM(InquireSpec::LogVar, Kind) NODE(parser, InquireStmt) NODE(InquireStmt, Iolength) NODE(parser, IntegerTypeSpec) NODE(parser, IntentSpec) NODE_ENUM(IntentSpec, Intent) NODE(parser, IntentStmt) NODE(parser, InterfaceBlock) NODE(parser, InterfaceBody) NODE(InterfaceBody, Function) NODE(InterfaceBody, Subroutine) NODE(parser, InterfaceSpecification) NODE(parser, InterfaceStmt) NODE(parser, InternalSubprogram) NODE(parser, InternalSubprogramPart) NODE(parser, Intrinsic) NODE(parser, IntrinsicStmt) NODE(parser, IntrinsicTypeSpec) NODE(IntrinsicTypeSpec, Character) NODE(IntrinsicTypeSpec, Complex) NODE(IntrinsicTypeSpec, DoubleComplex) NODE(IntrinsicTypeSpec, DoublePrecision) NODE(IntrinsicTypeSpec, Logical) NODE(IntrinsicTypeSpec, Real) NODE(parser, IoControlSpec) NODE(IoControlSpec, Asynchronous) NODE(IoControlSpec, CharExpr) NODE_ENUM(IoControlSpec::CharExpr, Kind) NODE(IoControlSpec, Pos) NODE(IoControlSpec, Rec) NODE(IoControlSpec, Size) NODE(parser, IoUnit) NODE(parser, Keyword) NODE(parser, KindParam) NODE(parser, KindSelector) NODE(KindSelector, StarSize) NODE(parser, LabelDoStmt) NODE(parser, LanguageBindingSpec) NODE(parser, LengthSelector) NODE(parser, LetterSpec) NODE(parser, LiteralConstant) NODE(parser, IntLiteralConstant) NODE(parser, LocalitySpec) NODE(LocalitySpec, DefaultNone) NODE(LocalitySpec, Local) NODE(LocalitySpec, LocalInit) NODE(LocalitySpec, Shared) NODE(parser, LockStmt) NODE(LockStmt, LockStat) NODE(parser, LogicalLiteralConstant) NODE_NAME(LoopControl::Bounds, "LoopBounds") NODE_NAME(AcImpliedDoControl::Bounds, "LoopBounds") NODE_NAME(DataImpliedDo::Bounds, "LoopBounds") NODE(parser, LoopControl) NODE(LoopControl, Concurrent) NODE(parser, MainProgram) NODE(parser, Map) NODE(Map, EndMapStmt) NODE(Map, MapStmt) NODE(parser, MaskedElsewhereStmt) NODE(parser, Module) NODE(parser, ModuleStmt) NODE(parser, ModuleSubprogram) NODE(parser, ModuleSubprogramPart) NODE(parser, MpSubprogramStmt) NODE(parser, MsgVariable) NODE(parser, Name) NODE(parser, NamedConstant) NODE(parser, NamedConstantDef) NODE(parser, NamelistStmt) NODE(NamelistStmt, Group) NODE(parser, NonLabelDoStmt) NODE(parser, NoPass) NODE(parser, NotifyWaitStmt) NODE(parser, NullifyStmt) NODE(parser, NullInit) NODE(parser, ObjectDecl) NODE(parser, OldParameterStmt) NODE(parser, OmpAlignedClause) NODE(parser, OmpAtomic) NODE(parser, OmpAtomicCapture) NODE(OmpAtomicCapture, Stmt1) NODE(OmpAtomicCapture, Stmt2) NODE(parser, OmpAtomicRead) NODE(parser, OmpAtomicUpdate) NODE(parser, OmpAtomicWrite) NODE(parser, OmpBeginBlockDirective) NODE(parser, OmpBeginLoopDirective) NODE(parser, OmpBeginSectionsDirective) NODE(parser, OmpBlockDirective) static std::string GetNodeName(const llvm::omp::Directive &x) { return llvm::Twine( "llvm::omp::Directive = ", llvm::omp::getOpenMPDirectiveName(x)) .str(); } NODE(parser, OmpCancelType) NODE_ENUM(OmpCancelType, Type) NODE(parser, OmpClause) #define GEN_FLANG_DUMP_PARSE_TREE_CLAUSES #include "llvm/Frontend/OpenMP/OMP.inc" NODE(parser, OmpClauseList) NODE(parser, OmpCriticalDirective) NODE(parser, OmpDeclareTargetSpecifier) NODE(parser, OmpDeclareTargetWithClause) NODE(parser, OmpDeclareTargetWithList) NODE(parser, OmpDefaultClause) NODE_ENUM(OmpDefaultClause, Type) NODE(parser, OmpDefaultmapClause) NODE_ENUM(OmpDefaultmapClause, ImplicitBehavior) NODE_ENUM(OmpDefaultmapClause, VariableCategory) NODE(parser, OmpDependClause) NODE(OmpDependClause, InOut) NODE(OmpDependClause, Sink) NODE(OmpDependClause, Source) NODE(parser, OmpDependenceType) NODE_ENUM(OmpDependenceType, Type) NODE(parser, OmpDependSinkVec) NODE(parser, OmpDependSinkVecLength) NODE(parser, OmpEndAllocators) NODE(parser, OmpEndAtomic) NODE(parser, OmpEndBlockDirective) NODE(parser, OmpEndCriticalDirective) NODE(parser, OmpEndLoopDirective) NODE(parser, OmpEndSectionsDirective) NODE(parser, OmpIfClause) NODE_ENUM(OmpIfClause, DirectiveNameModifier) NODE(parser, OmpLinearClause) NODE(OmpLinearClause, WithModifier) NODE(OmpLinearClause, WithoutModifier) NODE(parser, OmpLinearModifier) NODE_ENUM(OmpLinearModifier, Type) NODE(parser, OmpLoopDirective) NODE(parser, OmpMapClause) NODE(parser, OmpMapType) NODE(OmpMapType, Always) NODE_ENUM(OmpMapType, Type) static std::string GetNodeName(const llvm::omp::Clause &x) { return llvm::Twine( "llvm::omp::Clause = ", llvm::omp::getOpenMPClauseName(x)) .str(); } NODE(parser, OmpObject) NODE(parser, OmpObjectList) NODE(parser, OmpOrderClause) NODE_ENUM(OmpOrderClause, Type) NODE(parser, OmpOrderModifier) NODE_ENUM(OmpOrderModifier, Kind) NODE(parser, OmpProcBindClause) NODE_ENUM(OmpProcBindClause, Type) NODE(parser, OmpReductionClause) NODE(parser, OmpInReductionClause) NODE(parser, OmpReductionCombiner) NODE(OmpReductionCombiner, FunctionCombiner) NODE(parser, OmpReductionInitializerClause) NODE(parser, OmpReductionOperator) NODE(parser, OmpAllocateClause) NODE(OmpAllocateClause, AllocateModifier) NODE(OmpAllocateClause::AllocateModifier, Allocator) NODE(OmpAllocateClause::AllocateModifier, ComplexModifier) NODE(OmpAllocateClause::AllocateModifier, Align) NODE(parser, OmpScheduleClause) NODE_ENUM(OmpScheduleClause, ScheduleType) NODE(parser, OmpDeviceClause) NODE_ENUM(OmpDeviceClause, DeviceModifier) NODE(parser, OmpDeviceTypeClause) NODE_ENUM(OmpDeviceTypeClause, Type) NODE(parser, OmpScheduleModifier) NODE(OmpScheduleModifier, Modifier1) NODE(OmpScheduleModifier, Modifier2) NODE(parser, OmpScheduleModifierType) NODE_ENUM(OmpScheduleModifierType, ModType) NODE(parser, OmpSectionBlocks) NODE(parser, OmpSectionsDirective) NODE(parser, OmpSimpleStandaloneDirective) NODE(parser, Only) NODE(parser, OpenACCAtomicConstruct) NODE(parser, OpenACCBlockConstruct) NODE(parser, OpenACCCacheConstruct) NODE(parser, OpenACCCombinedConstruct) NODE(parser, OpenACCConstruct) NODE(parser, OpenACCDeclarativeConstruct) NODE(parser, OpenACCEndConstruct) NODE(parser, OpenACCLoopConstruct) NODE(parser, OpenACCRoutineConstruct) NODE(parser, OpenACCStandaloneDeclarativeConstruct) NODE(parser, OpenACCStandaloneConstruct) NODE(parser, OpenACCWaitConstruct) NODE(parser, OpenMPAtomicConstruct) NODE(parser, OpenMPBlockConstruct) NODE(parser, OpenMPCancelConstruct) NODE(OpenMPCancelConstruct, If) NODE(parser, OpenMPCancellationPointConstruct) NODE(parser, OpenMPConstruct) NODE(parser, OpenMPCriticalConstruct) NODE(parser, OpenMPDeclarativeAllocate) NODE(parser, OpenMPDeclarativeConstruct) NODE(parser, OpenMPDeclareReductionConstruct) NODE(parser, OpenMPDeclareSimdConstruct) NODE(parser, OpenMPDeclareTargetConstruct) NODE(parser, OmpMemoryOrderClause) NODE(parser, OmpAtomicClause) NODE(parser, OmpAtomicClauseList) NODE(parser, OmpAtomicDefaultMemOrderClause) NODE_ENUM(common, OmpAtomicDefaultMemOrderType) NODE(parser, OpenMPFlushConstruct) NODE(parser, OpenMPLoopConstruct) NODE(parser, OpenMPExecutableAllocate) NODE(parser, OpenMPAllocatorsConstruct) NODE(parser, OpenMPRequiresConstruct) NODE(parser, OpenMPSimpleStandaloneConstruct) NODE(parser, OpenMPStandaloneConstruct) NODE(parser, OpenMPSectionConstruct) NODE(parser, OpenMPSectionsConstruct) NODE(parser, OpenMPThreadprivate) NODE(parser, OpenStmt) NODE(parser, Optional) NODE(parser, OptionalStmt) NODE(parser, OtherSpecificationStmt) NODE(parser, OutputImpliedDo) NODE(parser, OutputItem) NODE(parser, Parameter) NODE(parser, ParameterStmt) NODE(parser, ParentIdentifier) NODE(parser, Pass) NODE(parser, PauseStmt) NODE(parser, Pointer) NODE(parser, PointerAssignmentStmt) NODE(PointerAssignmentStmt, Bounds) NODE(parser, PointerDecl) NODE(parser, PointerObject) NODE(parser, PointerStmt) NODE(parser, PositionOrFlushSpec) NODE(parser, PrefixSpec) NODE(PrefixSpec, Elemental) NODE(PrefixSpec, Impure) NODE(PrefixSpec, Module) NODE(PrefixSpec, Non_Recursive) NODE(PrefixSpec, Pure) NODE(PrefixSpec, Recursive) NODE(PrefixSpec, Attributes) NODE(PrefixSpec, Launch_Bounds) NODE(PrefixSpec, Cluster_Dims) NODE(parser, PrintStmt) NODE(parser, PrivateStmt) NODE(parser, PrivateOrSequence) NODE(parser, ProcAttrSpec) NODE(parser, ProcComponentAttrSpec) NODE(parser, ProcComponentDefStmt) NODE(parser, ProcComponentRef) NODE(parser, ProcDecl) NODE(parser, ProcInterface) NODE(parser, ProcPointerInit) NODE(parser, ProcedureDeclarationStmt) NODE(parser, ProcedureDesignator) NODE(parser, ProcedureStmt) NODE_ENUM(ProcedureStmt, Kind) NODE(parser, Program) NODE(parser, ProgramStmt) NODE(parser, ProgramUnit) NODE(parser, Protected) NODE(parser, ProtectedStmt) NODE(parser, ReadStmt) NODE(parser, RealLiteralConstant) NODE(RealLiteralConstant, Real) NODE(parser, Rename) NODE(Rename, Names) NODE(Rename, Operators) NODE(parser, ReturnStmt) NODE(parser, RewindStmt) NODE(parser, Save) NODE(parser, SaveStmt) NODE(parser, SavedEntity) NODE_ENUM(SavedEntity, Kind) NODE(parser, SectionSubscript) NODE(parser, SelectCaseStmt) NODE(parser, SelectRankCaseStmt) NODE(SelectRankCaseStmt, Rank) NODE(parser, SelectRankConstruct) NODE(SelectRankConstruct, RankCase) NODE(parser, SelectRankStmt) NODE(parser, SelectTypeConstruct) NODE(SelectTypeConstruct, TypeCase) NODE(parser, SelectTypeStmt) NODE(parser, Selector) NODE(parser, SeparateModuleSubprogram) NODE(parser, SequenceStmt) NODE(parser, Sign) NODE(parser, SignedComplexLiteralConstant) NODE(parser, SignedIntLiteralConstant) NODE(parser, SignedRealLiteralConstant) NODE(parser, SpecificationConstruct) NODE(parser, SpecificationExpr) NODE(parser, SpecificationPart) NODE(parser, Star) NODE(parser, StatOrErrmsg) NODE(parser, StatVariable) NODE(parser, StatusExpr) NODE(parser, StmtFunctionStmt) NODE(parser, StopCode) NODE(parser, StopStmt) NODE_ENUM(StopStmt, Kind) NODE(parser, StructureComponent) NODE(parser, StructureConstructor) NODE(parser, StructureDef) NODE(StructureDef, EndStructureStmt) NODE(parser, StructureField) NODE(parser, StructureStmt) NODE(parser, Submodule) NODE(parser, SubmoduleStmt) NODE(parser, SubroutineStmt) NODE(parser, SubroutineSubprogram) NODE(parser, SubscriptTriplet) NODE(parser, Substring) NODE(parser, SubstringInquiry) NODE(parser, SubstringRange) NODE(parser, Suffix) NODE(parser, SyncAllStmt) NODE(parser, SyncImagesStmt) NODE(SyncImagesStmt, ImageSet) NODE(parser, SyncMemoryStmt) NODE(parser, SyncTeamStmt) NODE(parser, Target) NODE(parser, TargetStmt) NODE(parser, TypeAttrSpec) NODE(TypeAttrSpec, BindC) NODE(TypeAttrSpec, Extends) NODE(parser, TypeBoundGenericStmt) NODE(parser, TypeBoundProcBinding) NODE(parser, TypeBoundProcDecl) NODE(parser, TypeBoundProcedurePart) NODE(parser, TypeBoundProcedureStmt) NODE(TypeBoundProcedureStmt, WithInterface) NODE(TypeBoundProcedureStmt, WithoutInterface) NODE(parser, TypeDeclarationStmt) NODE(parser, TypeGuardStmt) NODE(TypeGuardStmt, Guard) NODE(parser, TypeParamDecl) NODE(parser, TypeParamDefStmt) NODE(common, TypeParamAttr) NODE(parser, TypeParamSpec) NODE(parser, TypeParamValue) NODE(TypeParamValue, Deferred) NODE(parser, TypeSpec) NODE(parser, Union) NODE(Union, EndUnionStmt) NODE(Union, UnionStmt) NODE(parser, UnlockStmt) NODE(parser, UnsignedTypeSpec) NODE(parser, UseStmt) NODE_ENUM(UseStmt, ModuleNature) NODE(parser, Value) NODE(parser, ValueStmt) NODE(parser, Variable) NODE(parser, VectorTypeSpec) NODE(VectorTypeSpec, PairVectorTypeSpec) NODE(VectorTypeSpec, QuadVectorTypeSpec) NODE(parser, IntrinsicVectorTypeSpec) NODE(parser, VectorElementType) NODE(parser, Verbatim) NODE(parser, Volatile) NODE(parser, VolatileStmt) NODE(parser, WaitSpec) NODE(parser, WaitStmt) NODE(parser, WhereBodyConstruct) NODE(parser, WhereConstruct) NODE(WhereConstruct, Elsewhere) NODE(WhereConstruct, MaskedElsewhere) NODE(parser, WhereConstructStmt) NODE(parser, WhereStmt) NODE(parser, WriteStmt) #undef NODE #undef NODE_NAME template bool Pre(const T &x) { std::string fortran{AsFortran(x)}; if (fortran.empty() && (UnionTrait || WrapperTrait)) { Prefix(GetNodeName(x)); } else { IndentEmptyLine(); out_ << GetNodeName(x); if (!fortran.empty()) { out_ << " = '" << fortran << '\''; } EndLine(); ++indent_; } return true; } template void Post(const T &x) { if (AsFortran(x).empty() && (UnionTrait || WrapperTrait)) { EndLineIfNonempty(); } else { --indent_; } } // A few types we want to ignore bool Pre(const CharBlock &) { return true; } void Post(const CharBlock &) {} template bool Pre(const Statement &) { return true; } template void Post(const Statement &) {} template bool Pre(const UnlabeledStatement &) { return true; } template void Post(const UnlabeledStatement &) {} template bool Pre(const common::Indirection &) { return true; } template void Post(const common::Indirection &) {} template bool Pre(const Scalar &) { Prefix("Scalar"); return true; } template void Post(const Scalar &) { EndLineIfNonempty(); } template bool Pre(const Constant &) { Prefix("Constant"); return true; } template void Post(const Constant &) { EndLineIfNonempty(); } template bool Pre(const Integer &) { Prefix("Integer"); return true; } template void Post(const Integer &) { EndLineIfNonempty(); } template bool Pre(const Logical &) { Prefix("Logical"); return true; } template void Post(const Logical &) { EndLineIfNonempty(); } template bool Pre(const DefaultChar &) { Prefix("DefaultChar"); return true; } template void Post(const DefaultChar &) { EndLineIfNonempty(); } template bool Pre(const std::tuple &) { return true; } template void Post(const std::tuple &) {} template bool Pre(const std::variant &) { return true; } template void Post(const std::variant &) {} protected: // Return a Fortran representation of this node to include in the dump template std::string AsFortran(const T &x) { std::string buf; llvm::raw_string_ostream ss{buf}; if constexpr (HasTypedExpr::value) { if (asFortran_ && x.typedExpr) { asFortran_->expr(ss, *x.typedExpr); } } else if constexpr (std::is_same_v || std::is_same_v) { if (asFortran_ && x.typedAssignment) { asFortran_->assignment(ss, *x.typedAssignment); } } else if constexpr (std::is_same_v) { if (asFortran_ && x.typedCall) { asFortran_->call(ss, *x.typedCall); } } else if constexpr (std::is_same_v || std::is_same_v) { ss << std::get(x.t); } else if constexpr (std::is_same_v) { ss << x.source; } else if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) { ss << x; } if (ss.tell()) { return ss.str(); } if constexpr (std::is_same_v) { return x.source.ToString(); #ifdef SHOW_ALL_SOURCE_MEMBERS } else if constexpr (HasSource::value) { return x.source.ToString(); #endif } else if constexpr (std::is_same_v) { return x; } else { return ""; } } void IndentEmptyLine() { if (emptyline_ && indent_ > 0) { for (int i{0}; i < indent_; ++i) { out_ << "| "; } emptyline_ = false; } } void Prefix(const char *str) { IndentEmptyLine(); out_ << str << " -> "; emptyline_ = false; } void Prefix(const std::string &str) { IndentEmptyLine(); out_ << str << " -> "; emptyline_ = false; } void EndLine() { out_ << '\n'; emptyline_ = true; } void EndLineIfNonempty() { if (!emptyline_) { EndLine(); } } private: int indent_{0}; llvm::raw_ostream &out_; const AnalyzedObjectsAsFortran *const asFortran_; bool emptyline_{false}; }; template llvm::raw_ostream &DumpTree(llvm::raw_ostream &out, const T &x, const AnalyzedObjectsAsFortran *asFortran = nullptr) { ParseTreeDumper dumper{out, asFortran}; Walk(x, dumper); return out; } } // namespace Fortran::parser #endif // FORTRAN_PARSER_DUMP_PARSE_TREE_H_