diff options
Diffstat (limited to 'contrib/llvm-project/clang/lib/AST/TextNodeDumper.cpp')
-rw-r--r-- | contrib/llvm-project/clang/lib/AST/TextNodeDumper.cpp | 646 |
1 files changed, 597 insertions, 49 deletions
diff --git a/contrib/llvm-project/clang/lib/AST/TextNodeDumper.cpp b/contrib/llvm-project/clang/lib/AST/TextNodeDumper.cpp index 33f914f9f886..5ba952350425 100644 --- a/contrib/llvm-project/clang/lib/AST/TextNodeDumper.cpp +++ b/contrib/llvm-project/clang/lib/AST/TextNodeDumper.cpp @@ -16,7 +16,9 @@ #include "clang/AST/DeclOpenMP.h" #include "clang/AST/DeclTemplate.h" #include "clang/AST/LocInfoType.h" +#include "clang/AST/NestedNameSpecifier.h" #include "clang/AST/Type.h" +#include "clang/AST/TypeLocVisitor.h" #include "clang/Basic/Module.h" #include "clang/Basic/SourceManager.h" #include "clang/Basic/Specifiers.h" @@ -239,6 +241,27 @@ void TextNodeDumper::Visit(QualType T) { OS << " " << T.split().Quals.getAsString(); } +void TextNodeDumper::Visit(TypeLoc TL) { + if (!TL) { + ColorScope Color(OS, ShowColors, NullColor); + OS << "<<<NULL>>>"; + return; + } + + { + ColorScope Color(OS, ShowColors, TypeColor); + OS << (TL.getTypeLocClass() == TypeLoc::Qualified + ? "Qualified" + : TL.getType()->getTypeClassName()) + << "TypeLoc"; + } + dumpSourceRange(TL.getSourceRange()); + OS << ' '; + dumpBareType(TL.getType(), /*Desugar=*/false); + + TypeLocVisitor<TextNodeDumper>::Visit(TL); +} + void TextNodeDumper::Visit(const Decl *D) { if (!D) { ColorScope Color(OS, ShowColors, NullColor); @@ -283,6 +306,10 @@ void TextNodeDumper::Visit(const Decl *D) { OS << " constexpr"; if (FD->isConsteval()) OS << " consteval"; + else if (FD->isImmediateFunction()) + OS << " immediate"; + if (FD->isMultiVersion()) + OS << " multiversion"; } if (!isa<FunctionDecl>(*D)) { @@ -296,6 +323,17 @@ void TextNodeDumper::Visit(const Decl *D) { } } + switch (D->getFriendObjectKind()) { + case Decl::FOK_None: + break; + case Decl::FOK_Declared: + OS << " friend"; + break; + case Decl::FOK_Undeclared: + OS << " friend_undeclared"; + break; + } + ConstDeclVisitor<TextNodeDumper>::Visit(D); } @@ -343,6 +381,98 @@ void TextNodeDumper::Visit(const OMPClause *C) { OS << " <implicit>"; } +void TextNodeDumper::Visit(const OpenACCClause *C) { + if (!C) { + ColorScope Color(OS, ShowColors, NullColor); + OS << "<<<NULL>>> OpenACCClause"; + return; + } + { + ColorScope Color(OS, ShowColors, AttrColor); + OS << C->getClauseKind(); + + // Handle clauses with parens for types that have no children, likely + // because there is no sub expression. + switch (C->getClauseKind()) { + case OpenACCClauseKind::Default: + OS << '(' << cast<OpenACCDefaultClause>(C)->getDefaultClauseKind() << ')'; + break; + case OpenACCClauseKind::Async: + case OpenACCClauseKind::Auto: + case OpenACCClauseKind::Attach: + case OpenACCClauseKind::Copy: + case OpenACCClauseKind::PCopy: + case OpenACCClauseKind::PresentOrCopy: + case OpenACCClauseKind::If: + case OpenACCClauseKind::Independent: + case OpenACCClauseKind::DevicePtr: + case OpenACCClauseKind::FirstPrivate: + case OpenACCClauseKind::NoCreate: + case OpenACCClauseKind::NumGangs: + case OpenACCClauseKind::NumWorkers: + case OpenACCClauseKind::Present: + case OpenACCClauseKind::Private: + case OpenACCClauseKind::Self: + case OpenACCClauseKind::Seq: + case OpenACCClauseKind::VectorLength: + // The condition expression will be printed as a part of the 'children', + // but print 'clause' here so it is clear what is happening from the dump. + OS << " clause"; + break; + case OpenACCClauseKind::CopyIn: + case OpenACCClauseKind::PCopyIn: + case OpenACCClauseKind::PresentOrCopyIn: + OS << " clause"; + if (cast<OpenACCCopyInClause>(C)->isReadOnly()) + OS << " : readonly"; + break; + case OpenACCClauseKind::CopyOut: + case OpenACCClauseKind::PCopyOut: + case OpenACCClauseKind::PresentOrCopyOut: + OS << " clause"; + if (cast<OpenACCCopyOutClause>(C)->isZero()) + OS << " : zero"; + break; + case OpenACCClauseKind::Create: + case OpenACCClauseKind::PCreate: + case OpenACCClauseKind::PresentOrCreate: + OS << " clause"; + if (cast<OpenACCCreateClause>(C)->isZero()) + OS << " : zero"; + break; + case OpenACCClauseKind::Wait: + OS << " clause"; + if (cast<OpenACCWaitClause>(C)->hasDevNumExpr()) + OS << " has devnum"; + if (cast<OpenACCWaitClause>(C)->hasQueuesTag()) + OS << " has queues tag"; + break; + case OpenACCClauseKind::DeviceType: + case OpenACCClauseKind::DType: + OS << "("; + llvm::interleaveComma( + cast<OpenACCDeviceTypeClause>(C)->getArchitectures(), OS, + [&](const DeviceTypeArgument &Arch) { + if (Arch.first == nullptr) + OS << "*"; + else + OS << Arch.first->getName(); + }); + OS << ")"; + break; + case OpenACCClauseKind::Reduction: + OS << " clause Operator: " + << cast<OpenACCReductionClause>(C)->getReductionOp(); + break; + default: + // Nothing to do here. + break; + } + } + dumpPointer(C); + dumpSourceRange(SourceRange(C->getBeginLoc(), C->getEndLoc())); +} + void TextNodeDumper::Visit(const GenericSelectionExpr::ConstAssociation &A) { const TypeSourceInfo *TSI = A.getTypeSourceInfo(); if (TSI) { @@ -356,6 +486,20 @@ void TextNodeDumper::Visit(const GenericSelectionExpr::ConstAssociation &A) { OS << " selected"; } +void TextNodeDumper::Visit(const ConceptReference *R) { + if (!R) { + ColorScope Color(OS, ShowColors, NullColor); + OS << "<<<NULL>>> ConceptReference"; + return; + } + + OS << "ConceptReference"; + dumpPointer(R); + dumpSourceRange(R->getSourceRange()); + OS << ' '; + dumpBareDeclRef(R->getNamedConcept()); +} + void TextNodeDumper::Visit(const concepts::Requirement *R) { if (!R) { ColorScope Color(OS, ShowColors, NullColor); @@ -662,13 +806,18 @@ void TextNodeDumper::dumpBareType(QualType T, bool Desugar) { ColorScope Color(OS, ShowColors, TypeColor); SplitQualType T_split = T.split(); - OS << "'" << QualType::getAsString(T_split, PrintPolicy) << "'"; + std::string T_str = QualType::getAsString(T_split, PrintPolicy); + OS << "'" << T_str << "'"; if (Desugar && !T.isNull()) { - // If the type is sugared, also dump a (shallow) desugared type. + // If the type is sugared, also dump a (shallow) desugared type when + // it is visibly different. SplitQualType D_split = T.getSplitDesugaredType(); - if (T_split != D_split) - OS << ":'" << QualType::getAsString(D_split, PrintPolicy) << "'"; + if (T_split != D_split) { + std::string D_str = QualType::getAsString(D_split, PrintPolicy); + if (T_str != D_str) + OS << ":'" << QualType::getAsString(D_split, PrintPolicy) << "'"; + } } } @@ -730,6 +879,66 @@ void TextNodeDumper::dumpCleanupObject( llvm_unreachable("unexpected cleanup type"); } +void clang::TextNodeDumper::dumpTemplateSpecializationKind( + TemplateSpecializationKind TSK) { + switch (TSK) { + case TSK_Undeclared: + break; + case TSK_ImplicitInstantiation: + OS << " implicit_instantiation"; + break; + case TSK_ExplicitSpecialization: + OS << " explicit_specialization"; + break; + case TSK_ExplicitInstantiationDeclaration: + OS << " explicit_instantiation_declaration"; + break; + case TSK_ExplicitInstantiationDefinition: + OS << " explicit_instantiation_definition"; + break; + } +} + +void clang::TextNodeDumper::dumpNestedNameSpecifier(const NestedNameSpecifier *NNS) { + if (!NNS) + return; + + AddChild([=] { + OS << "NestedNameSpecifier"; + + switch (NNS->getKind()) { + case NestedNameSpecifier::Identifier: + OS << " Identifier"; + OS << " '" << NNS->getAsIdentifier()->getName() << "'"; + break; + case NestedNameSpecifier::Namespace: + OS << " "; // "Namespace" is printed as the decl kind. + dumpBareDeclRef(NNS->getAsNamespace()); + break; + case NestedNameSpecifier::NamespaceAlias: + OS << " "; // "NamespaceAlias" is printed as the decl kind. + dumpBareDeclRef(NNS->getAsNamespaceAlias()); + break; + case NestedNameSpecifier::TypeSpec: + OS << " TypeSpec"; + dumpType(QualType(NNS->getAsType(), 0)); + break; + case NestedNameSpecifier::TypeSpecWithTemplate: + OS << " TypeSpecWithTemplate"; + dumpType(QualType(NNS->getAsType(), 0)); + break; + case NestedNameSpecifier::Global: + OS << " Global"; + break; + case NestedNameSpecifier::Super: + OS << " Super"; + break; + } + + dumpNestedNameSpecifier(NNS->getPrefix()); + }); +} + void TextNodeDumper::dumpDeclRef(const Decl *D, StringRef Label) { if (!D) return; @@ -741,6 +950,29 @@ void TextNodeDumper::dumpDeclRef(const Decl *D, StringRef Label) { }); } +void TextNodeDumper::dumpTemplateArgument(const TemplateArgument &TA) { + llvm::SmallString<128> Str; + { + llvm::raw_svector_ostream SS(Str); + TA.print(PrintPolicy, SS, /*IncludeType=*/true); + } + OS << " '" << Str << "'"; + + if (!Context) + return; + + if (TemplateArgument CanonTA = Context->getCanonicalTemplateArgument(TA); + !CanonTA.structurallyEquals(TA)) { + llvm::SmallString<128> CanonStr; + { + llvm::raw_svector_ostream SS(CanonStr); + CanonTA.print(PrintPolicy, SS, /*IncludeType=*/true); + } + if (CanonStr != Str) + OS << ":'" << CanonStr << "'"; + } +} + const char *TextNodeDumper::getCommandName(unsigned CommandID) { if (Traits) return Traits->getCommandInfo(CommandID)->Name; @@ -767,19 +999,19 @@ void TextNodeDumper::visitInlineCommandComment( const comments::InlineCommandComment *C, const comments::FullComment *) { OS << " Name=\"" << getCommandName(C->getCommandID()) << "\""; switch (C->getRenderKind()) { - case comments::InlineCommandComment::RenderNormal: + case comments::InlineCommandRenderKind::Normal: OS << " RenderNormal"; break; - case comments::InlineCommandComment::RenderBold: + case comments::InlineCommandRenderKind::Bold: OS << " RenderBold"; break; - case comments::InlineCommandComment::RenderMonospaced: + case comments::InlineCommandRenderKind::Monospaced: OS << " RenderMonospaced"; break; - case comments::InlineCommandComment::RenderEmphasized: + case comments::InlineCommandRenderKind::Emphasized: OS << " RenderEmphasized"; break; - case comments::InlineCommandComment::RenderAnchor: + case comments::InlineCommandRenderKind::Anchor: OS << " RenderAnchor"; break; } @@ -880,40 +1112,128 @@ void TextNodeDumper::VisitNullTemplateArgument(const TemplateArgument &) { void TextNodeDumper::VisitTypeTemplateArgument(const TemplateArgument &TA) { OS << " type"; - dumpType(TA.getAsType()); + dumpTemplateArgument(TA); } void TextNodeDumper::VisitDeclarationTemplateArgument( const TemplateArgument &TA) { OS << " decl"; + dumpTemplateArgument(TA); dumpDeclRef(TA.getAsDecl()); } -void TextNodeDumper::VisitNullPtrTemplateArgument(const TemplateArgument &) { +void TextNodeDumper::VisitNullPtrTemplateArgument(const TemplateArgument &TA) { OS << " nullptr"; + dumpTemplateArgument(TA); } void TextNodeDumper::VisitIntegralTemplateArgument(const TemplateArgument &TA) { - OS << " integral " << TA.getAsIntegral(); + OS << " integral"; + dumpTemplateArgument(TA); +} + +void TextNodeDumper::dumpTemplateName(TemplateName TN, StringRef Label) { + AddChild(Label, [=] { + { + llvm::SmallString<128> Str; + { + llvm::raw_svector_ostream SS(Str); + TN.print(SS, PrintPolicy); + } + OS << "'" << Str << "'"; + + if (Context) { + if (TemplateName CanonTN = Context->getCanonicalTemplateName(TN); + CanonTN != TN) { + llvm::SmallString<128> CanonStr; + { + llvm::raw_svector_ostream SS(CanonStr); + CanonTN.print(SS, PrintPolicy); + } + if (CanonStr != Str) + OS << ":'" << CanonStr << "'"; + } + } + } + dumpBareTemplateName(TN); + }); +} + +void TextNodeDumper::dumpBareTemplateName(TemplateName TN) { + switch (TN.getKind()) { + case TemplateName::Template: + AddChild([=] { Visit(TN.getAsTemplateDecl()); }); + return; + case TemplateName::UsingTemplate: { + const UsingShadowDecl *USD = TN.getAsUsingShadowDecl(); + AddChild([=] { Visit(USD); }); + AddChild("target", [=] { Visit(USD->getTargetDecl()); }); + return; + } + case TemplateName::QualifiedTemplate: { + OS << " qualified"; + const QualifiedTemplateName *QTN = TN.getAsQualifiedTemplateName(); + if (QTN->hasTemplateKeyword()) + OS << " keyword"; + dumpNestedNameSpecifier(QTN->getQualifier()); + dumpBareTemplateName(QTN->getUnderlyingTemplate()); + return; + } + case TemplateName::DependentTemplate: { + OS << " dependent"; + const DependentTemplateName *DTN = TN.getAsDependentTemplateName(); + dumpNestedNameSpecifier(DTN->getQualifier()); + return; + } + case TemplateName::SubstTemplateTemplateParm: { + OS << " subst"; + const SubstTemplateTemplateParmStorage *STS = + TN.getAsSubstTemplateTemplateParm(); + OS << " index " << STS->getIndex(); + if (std::optional<unsigned int> PackIndex = STS->getPackIndex()) + OS << " pack_index " << *PackIndex; + if (const TemplateTemplateParmDecl *P = STS->getParameter()) + AddChild("parameter", [=] { Visit(P); }); + dumpDeclRef(STS->getAssociatedDecl(), "associated"); + dumpTemplateName(STS->getReplacement(), "replacement"); + return; + } + // FIXME: Implement these. + case TemplateName::OverloadedTemplate: + OS << " overloaded"; + return; + case TemplateName::AssumedTemplate: + OS << " assumed"; + return; + case TemplateName::SubstTemplateTemplateParmPack: + OS << " subst_pack"; + return; + } + llvm_unreachable("Unexpected TemplateName Kind"); } void TextNodeDumper::VisitTemplateTemplateArgument(const TemplateArgument &TA) { - OS << " template "; - TA.getAsTemplate().dump(OS); + OS << " template"; + dumpTemplateArgument(TA); + dumpBareTemplateName(TA.getAsTemplate()); } void TextNodeDumper::VisitTemplateExpansionTemplateArgument( const TemplateArgument &TA) { - OS << " template expansion "; - TA.getAsTemplateOrTemplatePattern().dump(OS); + OS << " template expansion"; + dumpTemplateArgument(TA); + dumpBareTemplateName(TA.getAsTemplateOrTemplatePattern()); } -void TextNodeDumper::VisitExpressionTemplateArgument(const TemplateArgument &) { +void TextNodeDumper::VisitExpressionTemplateArgument( + const TemplateArgument &TA) { OS << " expr"; + dumpTemplateArgument(TA); } -void TextNodeDumper::VisitPackTemplateArgument(const TemplateArgument &) { +void TextNodeDumper::VisitPackTemplateArgument(const TemplateArgument &TA) { OS << " pack"; + dumpTemplateArgument(TA); } static void dumpBasePath(raw_ostream &OS, const CastExpr *Node) { @@ -948,6 +1268,14 @@ void TextNodeDumper::VisitIfStmt(const IfStmt *Node) { OS << " has_var"; if (Node->hasElseStorage()) OS << " has_else"; + if (Node->isConstexpr()) + OS << " constexpr"; + if (Node->isConsteval()) { + OS << " "; + if (Node->isNegatedConsteval()) + OS << "!"; + OS << "consteval"; + } } void TextNodeDumper::VisitSwitchStmt(const SwitchStmt *Node) { @@ -978,6 +1306,24 @@ void TextNodeDumper::VisitCaseStmt(const CaseStmt *Node) { OS << " gnu_range"; } +void clang::TextNodeDumper::VisitReturnStmt(const ReturnStmt *Node) { + if (const VarDecl *Cand = Node->getNRVOCandidate()) { + OS << " nrvo_candidate("; + dumpBareDeclRef(Cand); + OS << ")"; + } +} + +void clang::TextNodeDumper::VisitCoawaitExpr(const CoawaitExpr *Node) { + if (Node->isImplicit()) + OS << " implicit"; +} + +void clang::TextNodeDumper::VisitCoreturnStmt(const CoreturnStmt *Node) { + if (Node->isImplicit()) + OS << " implicit"; +} + void TextNodeDumper::VisitConstantExpr(const ConstantExpr *Node) { if (Node->hasAPValueResult()) AddChild("value", @@ -1020,6 +1366,7 @@ void TextNodeDumper::VisitImplicitCastExpr(const ImplicitCastExpr *Node) { void TextNodeDumper::VisitDeclRefExpr(const DeclRefExpr *Node) { OS << " "; dumpBareDeclRef(Node->getDecl()); + dumpNestedNameSpecifier(Node->getQualifier()); if (Node->getDecl() != Node->getFoundDecl()) { OS << " ("; dumpBareDeclRef(Node->getFoundDecl()); @@ -1031,6 +1378,19 @@ void TextNodeDumper::VisitDeclRefExpr(const DeclRefExpr *Node) { case NOUR_Constant: OS << " non_odr_use_constant"; break; case NOUR_Discarded: OS << " non_odr_use_discarded"; break; } + if (Node->isCapturedByCopyInLambdaWithExplicitObjectParameter()) + OS << " dependent_capture"; + else if (Node->refersToEnclosingVariableOrCapture()) + OS << " refers_to_enclosing_variable_or_capture"; + + if (Node->isImmediateEscalating()) + OS << " immediate-escalating"; +} + +void clang::TextNodeDumper::VisitDependentScopeDeclRefExpr( + const DependentScopeDeclRefExpr *Node) { + + dumpNestedNameSpecifier(Node->getQualifier()); } void TextNodeDumper::VisitUnresolvedLookupExpr( @@ -1127,6 +1487,7 @@ void TextNodeDumper::VisitUnaryExprOrTypeTraitExpr( void TextNodeDumper::VisitMemberExpr(const MemberExpr *Node) { OS << " " << (Node->isArrow() ? "->" : ".") << *Node->getMemberDecl(); dumpPointer(Node->getMemberDecl()); + dumpNestedNameSpecifier(Node->getQualifier()); switch (Node->isNonOdrUse()) { case NOUR_None: break; case NOUR_Unevaluated: OS << " non_odr_use_unevaluated"; break; @@ -1177,6 +1538,8 @@ void TextNodeDumper::VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *Node) { void TextNodeDumper::VisitCXXThisExpr(const CXXThisExpr *Node) { if (Node->isImplicit()) OS << " implicit"; + if (Node->isCapturedByCopyInLambdaWithExplicitObjectParameter()) + OS << " dependent_capture"; OS << " this"; } @@ -1212,6 +1575,8 @@ void TextNodeDumper::VisitCXXConstructExpr(const CXXConstructExpr *Node) { OS << " std::initializer_list"; if (Node->requiresZeroInitialization()) OS << " zeroing"; + if (Node->isImmediateEscalating()) + OS << " immediate-escalating"; } void TextNodeDumper::VisitCXXBindTemporaryExpr( @@ -1257,6 +1622,16 @@ void TextNodeDumper::VisitExpressionTraitExpr(const ExpressionTraitExpr *Node) { OS << " " << getTraitSpelling(Node->getTrait()); } +void TextNodeDumper::VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *Node) { + if (Node->hasRewrittenInit()) + OS << " has rewritten init"; +} + +void TextNodeDumper::VisitCXXDefaultInitExpr(const CXXDefaultInitExpr *Node) { + if (Node->hasRewrittenInit()) + OS << " has rewritten init"; +} + void TextNodeDumper::VisitMaterializeTemporaryExpr( const MaterializeTemporaryExpr *Node) { if (const ValueDecl *VD = Node->getExtendingDecl()) { @@ -1419,12 +1794,12 @@ void TextNodeDumper::VisitRValueReferenceType(const ReferenceType *T) { void TextNodeDumper::VisitArrayType(const ArrayType *T) { switch (T->getSizeModifier()) { - case ArrayType::Normal: + case ArraySizeModifier::Normal: break; - case ArrayType::Static: + case ArraySizeModifier::Static: OS << " static"; break; - case ArrayType::Star: + case ArraySizeModifier::Star: OS << " *"; break; } @@ -1457,29 +1832,35 @@ void TextNodeDumper::VisitDependentSizedExtVectorType( void TextNodeDumper::VisitVectorType(const VectorType *T) { switch (T->getVectorKind()) { - case VectorType::GenericVector: + case VectorKind::Generic: break; - case VectorType::AltiVecVector: + case VectorKind::AltiVecVector: OS << " altivec"; break; - case VectorType::AltiVecPixel: + case VectorKind::AltiVecPixel: OS << " altivec pixel"; break; - case VectorType::AltiVecBool: + case VectorKind::AltiVecBool: OS << " altivec bool"; break; - case VectorType::NeonVector: + case VectorKind::Neon: OS << " neon"; break; - case VectorType::NeonPolyVector: + case VectorKind::NeonPoly: OS << " neon poly"; break; - case VectorType::SveFixedLengthDataVector: + case VectorKind::SveFixedLengthData: OS << " fixed-length sve data vector"; break; - case VectorType::SveFixedLengthPredicateVector: + case VectorKind::SveFixedLengthPredicate: OS << " fixed-length sve predicate vector"; break; + case VectorKind::RVVFixedLengthData: + OS << " fixed-length rvv data vector"; + break; + case VectorKind::RVVFixedLengthMask: + OS << " fixed-length rvv mask vector"; + break; } OS << " " << T->getNumElements(); } @@ -1517,7 +1898,64 @@ void TextNodeDumper::VisitFunctionProtoType(const FunctionProtoType *T) { OS << " &&"; break; } - // FIXME: Exception specification. + + switch (EPI.ExceptionSpec.Type) { + case EST_None: + break; + case EST_DynamicNone: + OS << " exceptionspec_dynamic_none"; + break; + case EST_Dynamic: + OS << " exceptionspec_dynamic"; + break; + case EST_MSAny: + OS << " exceptionspec_ms_any"; + break; + case EST_NoThrow: + OS << " exceptionspec_nothrow"; + break; + case EST_BasicNoexcept: + OS << " exceptionspec_basic_noexcept"; + break; + case EST_DependentNoexcept: + OS << " exceptionspec_dependent_noexcept"; + break; + case EST_NoexceptFalse: + OS << " exceptionspec_noexcept_false"; + break; + case EST_NoexceptTrue: + OS << " exceptionspec_noexcept_true"; + break; + case EST_Unevaluated: + OS << " exceptionspec_unevaluated"; + break; + case EST_Uninstantiated: + OS << " exceptionspec_uninstantiated"; + break; + case EST_Unparsed: + OS << " exceptionspec_unparsed"; + break; + } + if (!EPI.ExceptionSpec.Exceptions.empty()) { + AddChild([=] { + OS << "Exceptions:"; + for (unsigned I = 0, N = EPI.ExceptionSpec.Exceptions.size(); I != N; + ++I) { + if (I) + OS << ","; + dumpType(EPI.ExceptionSpec.Exceptions[I]); + } + }); + } + if (EPI.ExceptionSpec.NoexceptExpr) { + AddChild([=] { + OS << "NoexceptExpr: "; + Visit(EPI.ExceptionSpec.NoexceptExpr); + }); + } + dumpDeclRef(EPI.ExceptionSpec.SourceDecl, "ExceptionSourceDecl"); + dumpDeclRef(EPI.ExceptionSpec.SourceTemplate, "ExceptionSourceTemplate"); + // FIXME: Consumed parameters. VisitFunctionType(T); } @@ -1526,15 +1964,25 @@ void TextNodeDumper::VisitUnresolvedUsingType(const UnresolvedUsingType *T) { dumpDeclRef(T->getDecl()); } +void TextNodeDumper::VisitUsingType(const UsingType *T) { + dumpDeclRef(T->getFoundDecl()); + if (!T->typeMatchesDecl()) + OS << " divergent"; +} + void TextNodeDumper::VisitTypedefType(const TypedefType *T) { dumpDeclRef(T->getDecl()); + if (!T->typeMatchesDecl()) + OS << " divergent"; } void TextNodeDumper::VisitUnaryTransformType(const UnaryTransformType *T) { switch (T->getUTTKind()) { - case UnaryTransformType::EnumUnderlyingType: - OS << " underlying_type"; +#define TRANSFORM_TYPE_TRAIT_DEF(Enum, Trait) \ + case UnaryTransformType::Enum: \ + OS << " " #Trait; \ break; +#include "clang/Basic/TransformTypeTraits.def" } } @@ -1549,24 +1997,39 @@ void TextNodeDumper::VisitTemplateTypeParmType(const TemplateTypeParmType *T) { dumpDeclRef(T->getDecl()); } +void TextNodeDumper::VisitSubstTemplateTypeParmType( + const SubstTemplateTypeParmType *T) { + dumpDeclRef(T->getAssociatedDecl()); + VisitTemplateTypeParmDecl(T->getReplacedParameter()); + if (auto PackIndex = T->getPackIndex()) + OS << " pack_index " << *PackIndex; +} + +void TextNodeDumper::VisitSubstTemplateTypeParmPackType( + const SubstTemplateTypeParmPackType *T) { + dumpDeclRef(T->getAssociatedDecl()); + VisitTemplateTypeParmDecl(T->getReplacedParameter()); +} + void TextNodeDumper::VisitAutoType(const AutoType *T) { if (T->isDecltypeAuto()) OS << " decltype(auto)"; if (!T->isDeduced()) OS << " undeduced"; - if (T->isConstrained()) { + if (T->isConstrained()) dumpDeclRef(T->getTypeConstraintConcept()); - for (const auto &Arg : T->getTypeConstraintArguments()) - VisitTemplateArgument(Arg); - } +} + +void TextNodeDumper::VisitDeducedTemplateSpecializationType( + const DeducedTemplateSpecializationType *T) { + dumpTemplateName(T->getTemplateName(), "name"); } void TextNodeDumper::VisitTemplateSpecializationType( const TemplateSpecializationType *T) { if (T->isTypeAlias()) OS << " alias"; - OS << " "; - T->getTemplateName().dump(OS); + dumpTemplateName(T->getTemplateName(), "name"); } void TextNodeDumper::VisitInjectedClassNameType( @@ -1583,6 +2046,13 @@ void TextNodeDumper::VisitPackExpansionType(const PackExpansionType *T) { OS << " expansions " << *N; } +void TextNodeDumper::VisitTypeLoc(TypeLoc TL) { + // By default, add extra Type details with no extra loc info. + TypeVisitor<TextNodeDumper>::Visit(TL.getTypePtr()); +} +// FIXME: override behavior for TypeLocs that have interesting location +// information, such as the qualifier in ElaboratedTypeLoc. + void TextNodeDumper::VisitLabelDecl(const LabelDecl *D) { dumpName(D); } void TextNodeDumper::VisitTypedefDecl(const TypedefDecl *D) { @@ -1631,6 +2101,7 @@ void TextNodeDumper::VisitIndirectFieldDecl(const IndirectFieldDecl *D) { void TextNodeDumper::VisitFunctionDecl(const FunctionDecl *D) { dumpName(D); dumpType(D->getType()); + dumpTemplateSpecializationKind(D->getTemplateSpecializationKind()); StorageClass SC = D->getStorageClass(); if (SC != SC_None) @@ -1642,7 +2113,7 @@ void TextNodeDumper::VisitFunctionDecl(const FunctionDecl *D) { if (D->isModulePrivate()) OS << " __module_private__"; - if (D->isPure()) + if (D->isPureVirtual()) OS << " pure"; if (D->isDefaulted()) { OS << " default"; @@ -1654,6 +2125,12 @@ void TextNodeDumper::VisitFunctionDecl(const FunctionDecl *D) { if (D->isTrivial()) OS << " trivial"; + if (const StringLiteral *M = D->getDeletedMessage()) + AddChild("delete message", [=] { Visit(M); }); + + if (D->isIneligibleOrNotSelected()) + OS << (isa<CXXDestructorDecl>(D) ? " not_selected" : " ineligible"); + if (const auto *FPT = D->getType()->getAs<FunctionProtoType>()) { FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo(); switch (EPI.ExceptionSpec.Type) { @@ -1680,8 +2157,7 @@ void TextNodeDumper::VisitFunctionDecl(const FunctionDecl *D) { auto Overrides = MD->overridden_methods(); OS << "Overrides: [ "; dumpOverride(*Overrides.begin()); - for (const auto *Override : - llvm::make_range(Overrides.begin() + 1, Overrides.end())) { + for (const auto *Override : llvm::drop_begin(Overrides)) { OS << ", "; dumpOverride(Override); } @@ -1690,12 +2166,33 @@ void TextNodeDumper::VisitFunctionDecl(const FunctionDecl *D) { } } + if (!D->isInlineSpecified() && D->isInlined()) { + OS << " implicit-inline"; + } // Since NumParams comes from the FunctionProtoType of the FunctionDecl and // the Params are set later, it is possible for a dump during debugging to // encounter a FunctionDecl that has been created but hasn't been assigned // ParmVarDecls yet. if (!D->param_empty() && !D->param_begin()) OS << " <<<NULL params x " << D->getNumParams() << ">>>"; + + if (const auto *Instance = D->getInstantiatedFromMemberFunction()) { + OS << " instantiated_from"; + dumpPointer(Instance); + } +} + +void TextNodeDumper::VisitCXXDeductionGuideDecl( + const CXXDeductionGuideDecl *D) { + VisitFunctionDecl(D); + switch (D->getDeductionCandidateKind()) { + case DeductionCandidate::Normal: + case DeductionCandidate::Copy: + return; + case DeductionCandidate::Aggregate: + OS << " aggregate "; + break; + } } void TextNodeDumper::VisitLifetimeExtendedTemporaryDecl( @@ -1719,8 +2216,14 @@ void TextNodeDumper::VisitFieldDecl(const FieldDecl *D) { } void TextNodeDumper::VisitVarDecl(const VarDecl *D) { + dumpNestedNameSpecifier(D->getQualifier()); dumpName(D); + if (const auto *P = dyn_cast<ParmVarDecl>(D); + P && P->isExplicitObjectParameter()) + OS << " this"; + dumpType(D->getType()); + dumpTemplateSpecializationKind(D->getTemplateSpecializationKind()); StorageClass SC = D->getStorageClass(); if (SC != SC_None) OS << ' ' << VarDecl::getStorageClassSpecifierString(SC); @@ -1753,6 +2256,8 @@ void TextNodeDumper::VisitVarDecl(const VarDecl *D) { case VarDecl::ListInit: OS << " listinit"; break; + case VarDecl::ParenListInit: + OS << " parenlistinit"; } } if (D->needsDestruction(D->getASTContext())) @@ -1763,7 +2268,8 @@ void TextNodeDumper::VisitVarDecl(const VarDecl *D) { if (D->hasInit()) { const Expr *E = D->getInit(); // Only dump the value of constexpr VarDecls for now. - if (E && !E->isValueDependent() && D->isConstexpr()) { + if (E && !E->isValueDependent() && D->isConstexpr() && + !D->getType()->isDependentType()) { const APValue *Value = D->evaluateValue(); if (Value) AddChild("value", [=] { Visit(*Value, E->getType()); }); @@ -1836,13 +2342,13 @@ void TextNodeDumper::VisitOMPDeclareReductionDecl( OS << " initializer"; dumpPointer(Initializer); switch (D->getInitializerKind()) { - case OMPDeclareReductionDecl::DirectInit: + case OMPDeclareReductionInitKind::Direct: OS << " omp_priv = "; break; - case OMPDeclareReductionDecl::CopyInit: + case OMPDeclareReductionInitKind::Copy: OS << " omp_priv ()"; break; - case OMPDeclareReductionDecl::CallInit: + case OMPDeclareReductionInitKind::Call: break; } } @@ -1878,8 +2384,10 @@ void TextNodeDumper::VisitNamespaceDecl(const NamespaceDecl *D) { dumpName(D); if (D->isInline()) OS << " inline"; - if (!D->isOriginalNamespace()) - dumpDeclRef(D->getOriginalNamespace(), "original"); + if (D->isNested()) + OS << " nested"; + if (!D->isFirstDecl()) + dumpDeclRef(D->getFirstDecl(), "original"); } void TextNodeDumper::VisitUsingDirectiveDecl(const UsingDirectiveDecl *D) { @@ -1904,6 +2412,15 @@ void TextNodeDumper::VisitTypeAliasTemplateDecl( void TextNodeDumper::VisitCXXRecordDecl(const CXXRecordDecl *D) { VisitRecordDecl(D); + if (const auto *Instance = D->getInstantiatedFromMemberClass()) { + OS << " instantiated_from"; + dumpPointer(Instance); + } + if (const auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(D)) + dumpTemplateSpecializationKind(CTSD->getSpecializationKind()); + + dumpNestedNameSpecifier(D->getQualifier()); + if (!D->isCompleteDefinition()) return; @@ -2103,6 +2620,7 @@ void TextNodeDumper::VisitUsingDecl(const UsingDecl *D) { if (D->getQualifier()) D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy()); OS << D->getDeclName(); + dumpNestedNameSpecifier(D->getQualifier()); } void TextNodeDumper::VisitUsingEnumDecl(const UsingEnumDecl *D) { @@ -2159,10 +2677,10 @@ void TextNodeDumper::VisitConstructorUsingShadowDecl( void TextNodeDumper::VisitLinkageSpecDecl(const LinkageSpecDecl *D) { switch (D->getLanguage()) { - case LinkageSpecDecl::lang_c: + case LinkageSpecLanguageIDs::C: OS << " C"; break; - case LinkageSpecDecl::lang_cxx: + case LinkageSpecLanguageIDs::CXX: OS << " C++"; break; } @@ -2341,3 +2859,33 @@ void TextNodeDumper::VisitBlockDecl(const BlockDecl *D) { void TextNodeDumper::VisitConceptDecl(const ConceptDecl *D) { dumpName(D); } + +void TextNodeDumper::VisitCompoundStmt(const CompoundStmt *S) { + VisitStmt(S); + if (S->hasStoredFPFeatures()) + printFPOptions(S->getStoredFPFeatures()); +} + +void TextNodeDumper::VisitHLSLBufferDecl(const HLSLBufferDecl *D) { + if (D->isCBuffer()) + OS << " cbuffer"; + else + OS << " tbuffer"; + dumpName(D); +} + +void TextNodeDumper::VisitOpenACCConstructStmt(const OpenACCConstructStmt *S) { + OS << " " << S->getDirectiveKind(); +} +void TextNodeDumper::VisitOpenACCLoopConstruct(const OpenACCLoopConstruct *S) { + + if (S->isOrphanedLoopConstruct()) + OS << " <orphan>"; + else + OS << " parent: " << S->getParentComputeConstruct(); +} + +void TextNodeDumper::VisitEmbedExpr(const EmbedExpr *S) { + AddChild("begin", [=] { OS << S->getStartingElementPos(); }); + AddChild("number of elements", [=] { OS << S->getDataElementCount(); }); +} |