blob: 150b011ad8ba0748d3138dc1c6dfcc58061242ee [file] [log] [blame]
//===-- 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/idioms.h"
#include "flang/Common/indirection.h"
#include "llvm/Support/raw_ostream.h"
#include <string>
#include <type_traits>
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 + 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(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, AccGangArgument)
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, AccTileExpr)
NODE(parser, AccTileExprList)
NODE(parser, AccLoopDirective)
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(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(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, NameValue)
NODE(parser, ComplexLiteralConstant)
NODE(parser, ComplexPart)
NODE(parser, ComponentArraySpec)
NODE(parser, ComponentAttrSpec)
NODE(parser, ComponentDataSource)
NODE(parser, ComponentDecl)
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, 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, EventWaitStmt)
NODE(EventWaitStmt, EventWaitSpec)
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, 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, 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, OmpProcBindClause)
NODE_ENUM(OmpProcBindClause, Type)
NODE(parser, OmpReductionClause)
NODE(parser, OmpReductionCombiner)
NODE(OmpReductionCombiner, FunctionCombiner)
NODE(parser, OmpReductionInitializerClause)
NODE(parser, OmpReductionOperator)
NODE(parser, OmpAllocateClause)
NODE(OmpAllocateClause, Allocator)
NODE(parser, OmpScheduleClause)
NODE_ENUM(OmpScheduleClause, ScheduleType)
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, 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, OpenMPFlushConstruct)
NODE(parser, OpenMPLoopConstruct)
NODE(parser, OpenMPExecutableAllocate)
NODE(parser, OpenMPSimpleStandaloneConstruct)
NODE(parser, OpenMPStandaloneConstruct)
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(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, 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, UseStmt)
NODE_ENUM(UseStmt, ModuleNature)
NODE(parser, Value)
NODE(parser, ValueStmt)
NODE(parser, Variable)
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 <typename T> bool Pre(const T &x) {
std::string fortran{AsFortran<T>(x)};
if (fortran.empty() && (UnionTrait<T> || WrapperTrait<T>)) {
Prefix(GetNodeName(x));
} else {
IndentEmptyLine();
out_ << GetNodeName(x);
if (!fortran.empty()) {
out_ << " = '" << fortran << '\'';
}
EndLine();
++indent_;
}
return true;
}
template <typename T> void Post(const T &x) {
if (AsFortran<T>(x).empty() && (UnionTrait<T> || WrapperTrait<T>)) {
EndLineIfNonempty();
} else {
--indent_;
}
}
// A few types we want to ignore
bool Pre(const CharBlock &) { return true; }
void Post(const CharBlock &) {}
template <typename T> bool Pre(const Statement<T> &) { return true; }
template <typename T> void Post(const Statement<T> &) {}
template <typename T> bool Pre(const UnlabeledStatement<T> &) { return true; }
template <typename T> void Post(const UnlabeledStatement<T> &) {}
template <typename T> bool Pre(const common::Indirection<T> &) {
return true;
}
template <typename T> void Post(const common::Indirection<T> &) {}
template <typename A> bool Pre(const Scalar<A> &) {
Prefix("Scalar");
return true;
}
template <typename A> void Post(const Scalar<A> &) { EndLineIfNonempty(); }
template <typename A> bool Pre(const Constant<A> &) {
Prefix("Constant");
return true;
}
template <typename A> void Post(const Constant<A> &) { EndLineIfNonempty(); }
template <typename A> bool Pre(const Integer<A> &) {
Prefix("Integer");
return true;
}
template <typename A> void Post(const Integer<A> &) { EndLineIfNonempty(); }
template <typename A> bool Pre(const Logical<A> &) {
Prefix("Logical");
return true;
}
template <typename A> void Post(const Logical<A> &) { EndLineIfNonempty(); }
template <typename A> bool Pre(const DefaultChar<A> &) {
Prefix("DefaultChar");
return true;
}
template <typename A> void Post(const DefaultChar<A> &) {
EndLineIfNonempty();
}
template <typename... A> bool Pre(const std::tuple<A...> &) { return true; }
template <typename... A> void Post(const std::tuple<A...> &) {}
template <typename... A> bool Pre(const std::variant<A...> &) { return true; }
template <typename... A> void Post(const std::variant<A...> &) {}
protected:
// Return a Fortran representation of this node to include in the dump
template <typename T> std::string AsFortran(const T &x) {
std::string buf;
llvm::raw_string_ostream ss{buf};
if constexpr (HasTypedExpr<T>::value) {
if (asFortran_ && x.typedExpr) {
asFortran_->expr(ss, *x.typedExpr);
}
} else if constexpr (std::is_same_v<T, AssignmentStmt> ||
std::is_same_v<T, PointerAssignmentStmt>) {
if (asFortran_ && x.typedAssignment) {
asFortran_->assignment(ss, *x.typedAssignment);
}
} else if constexpr (std::is_same_v<T, CallStmt>) {
if (asFortran_ && x.typedCall) {
asFortran_->call(ss, *x.typedCall);
}
} else if constexpr (std::is_same_v<T, IntLiteralConstant> ||
std::is_same_v<T, SignedIntLiteralConstant>) {
ss << std::get<CharBlock>(x.t);
} else if constexpr (std::is_same_v<T, RealLiteralConstant::Real>) {
ss << x.source;
} else if constexpr (std::is_same_v<T, std::string> ||
std::is_same_v<T, std::int64_t> || std::is_same_v<T, std::uint64_t>) {
ss << x;
}
if (ss.tell()) {
return ss.str();
}
if constexpr (std::is_same_v<T, Name>) {
return x.source.ToString();
#ifdef SHOW_ALL_SOURCE_MEMBERS
} else if constexpr (HasSource<T>::value) {
return x.source.ToString();
#endif
} else if constexpr (std::is_same_v<T, std::string>) {
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 <typename T>
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_