llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Corentin Jabot (cor3ntin) <details> <summary>Changes</summary> The initial implementation of concept template parameter piggy-backed on UnresolvedLookupExpr, because it did _mostly_ what we wanted and I was lazy (it led to some akwardness in a few places) However, to implement template pack indexing we need to store a TemplateName rather than a template decl. So this PR adds this new node, as preparatory work for P3670. --- Opus 5 was used to make the initial version of this PR, with quite a bit of cleaning after. --- Patch is 35.65 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/216729.diff 26 Files Affected: - (modified) clang/include/clang/AST/ComputeDependence.h (+2) - (modified) clang/include/clang/AST/ExprCXX.h (+104-28) - (modified) clang/include/clang/AST/RecursiveASTVisitor.h (+7) - (modified) clang/include/clang/AST/TextNodeDumper.h (+1) - (modified) clang/include/clang/Basic/StmtNodes.td (+1) - (modified) clang/include/clang/Serialization/ASTBitCodes.h (+1) - (modified) clang/lib/AST/ASTImporter.cpp (+27) - (modified) clang/lib/AST/ComputeDependence.cpp (+13-1) - (modified) clang/lib/AST/Expr.cpp (+1) - (modified) clang/lib/AST/ExprCXX.cpp (+43-13) - (modified) clang/lib/AST/ExprClassification.cpp (+1) - (modified) clang/lib/AST/ExprConstant.cpp (+1) - (modified) clang/lib/AST/ItaniumMangle.cpp (+9) - (modified) clang/lib/AST/StmtPrinter.cpp (+9) - (modified) clang/lib/AST/StmtProfile.cpp (+9) - (modified) clang/lib/AST/TextNodeDumper.cpp (+8) - (modified) clang/lib/Sema/SemaExceptionSpec.cpp (+1) - (modified) clang/lib/Sema/SemaTemplate.cpp (+8-25) - (modified) clang/lib/Sema/SemaTemplateDeduction.cpp (+11-21) - (modified) clang/lib/Sema/SemaTemplateInstantiate.cpp (+34-30) - (modified) clang/lib/Sema/TreeTransform.h (+35) - (modified) clang/lib/Serialization/ASTReaderStmt.cpp (+18) - (modified) clang/lib/Serialization/ASTWriter.cpp (+1) - (modified) clang/lib/Serialization/ASTWriterStmt.cpp (+11) - (modified) clang/lib/StaticAnalyzer/Core/ExprEngine.cpp (+1) - (modified) clang/tools/libclang/CXCursor.cpp (+1) ``````````diff diff --git a/clang/include/clang/AST/ComputeDependence.h b/clang/include/clang/AST/ComputeDependence.h index 3a3c86842501a..6430081a40350 100644 --- a/clang/include/clang/AST/ComputeDependence.h +++ b/clang/include/clang/AST/ComputeDependence.h @@ -80,6 +80,7 @@ class CXXDefaultArgExpr; class LambdaExpr; class CXXUnresolvedConstructExpr; class CXXDependentScopeMemberExpr; +class DependentTemplateIdExpr; class MaterializeTemporaryExpr; class CXXFoldExpr; class CXXParenListInitExpr; @@ -175,6 +176,7 @@ ExprDependence computeDependence(LambdaExpr *E, bool ContainsUnexpandedParameterPack); ExprDependence computeDependence(CXXUnresolvedConstructExpr *E); ExprDependence computeDependence(CXXDependentScopeMemberExpr *E); +ExprDependence computeDependence(DependentTemplateIdExpr *E); ExprDependence computeDependence(MaterializeTemporaryExpr *E); ExprDependence computeDependence(CXXFoldExpr *E); ExprDependence computeDependence(CXXParenListInitExpr *E); diff --git a/clang/include/clang/AST/ExprCXX.h b/clang/include/clang/AST/ExprCXX.h index d3d3b9c6d6326..8a234b953e44a 100644 --- a/clang/include/clang/AST/ExprCXX.h +++ b/clang/include/clang/AST/ExprCXX.h @@ -3287,39 +3287,11 @@ class OverloadExpr : public Expr { getTrailingASTTemplateKWAndArgsInfo()->NumTemplateArgs; } - bool isConceptReference() const { - return getNumDecls() == 1 && [&]() { - if (auto *TTP = dyn_cast_or_null<TemplateTemplateParmDecl>( - getTrailingResults()->getDecl())) - return TTP->templateParameterKind() == TNK_Concept_template; - if (isa<ConceptDecl>(getTrailingResults()->getDecl())) - return true; - return false; - }(); - } - - bool isVarDeclReference() const { - return getNumDecls() == 1 && [&]() { - if (auto *TTP = dyn_cast_or_null<TemplateTemplateParmDecl>( - getTrailingResults()->getDecl())) - return TTP->templateParameterKind() == TNK_Var_template; - if (isa<VarTemplateDecl>(getTrailingResults()->getDecl())) - return true; - return false; - }(); - } - TemplateDecl *getTemplateDecl() const { assert(getNumDecls() == 1); return dyn_cast_or_null<TemplateDecl>(getTrailingResults()->getDecl()); } - TemplateTemplateParmDecl *getTemplateTemplateDecl() const { - assert(getNumDecls() == 1); - return dyn_cast_or_null<TemplateTemplateParmDecl>( - getTrailingResults()->getDecl()); - } - TemplateArgumentLoc const *getTemplateArgs() const { if (!hasExplicitTemplateArgs()) return nullptr; @@ -3488,6 +3460,110 @@ class UnresolvedLookupExpr final } }; +/// A template-id naming a variable template or a concept through a template +/// template parameter. +class DependentTemplateIdExpr final + : public Expr, + private llvm::TrailingObjects<DependentTemplateIdExpr, + ASTTemplateKWAndArgsInfo, + TemplateArgumentLoc> { + friend class ASTStmtReader; + friend class ASTStmtWriter; + friend TrailingObjects; + + NestedNameSpecifierLoc QualifierLoc; + + DeclarationNameInfo NameInfo; + + TemplateName Name; + + DependentTemplateIdExpr(const ASTContext &Context, + NestedNameSpecifierLoc QualifierLoc, + SourceLocation TemplateKWLoc, + const DeclarationNameInfo &NameInfo, + TemplateName Name, + const TemplateArgumentListInfo &TemplateArgs); + + DependentTemplateIdExpr(EmptyShell Empty, unsigned NumTemplateArgs); + + unsigned numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>) const { + return 1; + } + +public: + static DependentTemplateIdExpr * + Create(const ASTContext &Context, NestedNameSpecifierLoc QualifierLoc, + SourceLocation TemplateKWLoc, const DeclarationNameInfo &NameInfo, + TemplateName Name, const TemplateArgumentListInfo &TemplateArgs); + + static DependentTemplateIdExpr *CreateEmpty(const ASTContext &Context, + unsigned NumTemplateArgs); + + NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; } + NestedNameSpecifier getQualifier() const { + return QualifierLoc.getNestedNameSpecifier(); + } + + const DeclarationNameInfo &getNameInfo() const { return NameInfo; } + DeclarationName getName() const { return NameInfo.getName(); } + SourceLocation getNameLoc() const { return NameInfo.getLoc(); } + + TemplateName getTemplateName() const { return Name; } + + TemplateTemplateParmDecl *getParameter() const { + return cast<TemplateTemplateParmDecl>(Name.getAsTemplateDecl()); + } + + bool isConceptReference() const { + return getParameter()->templateParameterKind() == TNK_Concept_template; + } + + SourceLocation getTemplateKeywordLoc() const { + return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->TemplateKWLoc; + } + SourceLocation getLAngleLoc() const { + return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->LAngleLoc; + } + SourceLocation getRAngleLoc() const { + return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->RAngleLoc; + } + + unsigned getNumTemplateArgs() const { + return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->NumTemplateArgs; + } + + ArrayRef<TemplateArgumentLoc> template_arguments() const { + return getTrailingObjects<TemplateArgumentLoc>(getNumTemplateArgs()); + } + + SourceLocation getBeginLoc() const { + if (QualifierLoc) + return QualifierLoc.getBeginLoc(); + if (SourceLocation TemplateKWLoc = getTemplateKeywordLoc(); + TemplateKWLoc.isValid()) + return TemplateKWLoc; + return getNameLoc(); + } + + SourceLocation getEndLoc() const { + if (SourceLocation RAngleLoc = getRAngleLoc(); RAngleLoc.isValid()) + return RAngleLoc; + return NameInfo.getEndLoc(); + } + + child_range children() { + return child_range(child_iterator(), child_iterator()); + } + + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + + static bool classof(const Stmt *T) { + return T->getStmtClass() == DependentTemplateIdExprClass; + } +}; + /// A qualified reference to a name whose declaration cannot /// yet be resolved. /// diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h index d435cda19fa49..01f8f960c9039 100644 --- a/clang/include/clang/AST/RecursiveASTVisitor.h +++ b/clang/include/clang/AST/RecursiveASTVisitor.h @@ -2646,6 +2646,13 @@ DEF_TRAVERSE_STMT(CXXDependentScopeMemberExpr, { } }) +DEF_TRAVERSE_STMT(DependentTemplateIdExpr, { + TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc())); + TRY_TO(TraverseDeclarationNameInfo(S->getNameInfo())); + TRY_TO(TraverseTemplateArgumentLocsHelper(S->template_arguments().data(), + S->getNumTemplateArgs())); +}) + DEF_TRAVERSE_STMT(DeclRefExpr, { TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc())); TRY_TO(TraverseDeclarationNameInfo(S->getNameInfo())); diff --git a/clang/include/clang/AST/TextNodeDumper.h b/clang/include/clang/AST/TextNodeDumper.h index 1eaafd49c2f06..5d4a4456b40a1 100644 --- a/clang/include/clang/AST/TextNodeDumper.h +++ b/clang/include/clang/AST/TextNodeDumper.h @@ -277,6 +277,7 @@ class TextNodeDumper void VisitImplicitCastExpr(const ImplicitCastExpr *Node); void VisitDeclRefExpr(const DeclRefExpr *Node); void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *Node); + void VisitDependentTemplateIdExpr(const DependentTemplateIdExpr *Node); void VisitSYCLUniqueStableNameExpr(const SYCLUniqueStableNameExpr *Node); void VisitPredefinedExpr(const PredefinedExpr *Node); void VisitCharacterLiteral(const CharacterLiteral *Node); diff --git a/clang/include/clang/Basic/StmtNodes.td b/clang/include/clang/Basic/StmtNodes.td index 6df244d7a8c90..84804d6705d2b 100644 --- a/clang/include/clang/Basic/StmtNodes.td +++ b/clang/include/clang/Basic/StmtNodes.td @@ -161,6 +161,7 @@ def ExprWithCleanups : StmtNode<FullExpr>; def CXXTemporaryObjectExpr : StmtNode<CXXConstructExpr>; def CXXUnresolvedConstructExpr : StmtNode<Expr>; def CXXDependentScopeMemberExpr : StmtNode<Expr>; +def DependentTemplateIdExpr : StmtNode<Expr>; def OverloadExpr : StmtNode<Expr, 1>; def UnresolvedLookupExpr : StmtNode<OverloadExpr>; def UnresolvedMemberExpr : StmtNode<OverloadExpr>; diff --git a/clang/include/clang/Serialization/ASTBitCodes.h b/clang/include/clang/Serialization/ASTBitCodes.h index 974761b236411..6a52a9e4fa780 100644 --- a/clang/include/clang/Serialization/ASTBitCodes.h +++ b/clang/include/clang/Serialization/ASTBitCodes.h @@ -1929,6 +1929,7 @@ enum StmtCode { EXPR_CXX_DEPENDENT_SCOPE_MEMBER, // CXXDependentScopeMemberExpr EXPR_CXX_DEPENDENT_SCOPE_DECL_REF, // DependentScopeDeclRefExpr + EXPR_DEPENDENT_TEMPLATE_ID, // DependentTemplateIdExpr EXPR_CXX_UNRESOLVED_CONSTRUCT, // CXXUnresolvedConstructExpr EXPR_CXX_UNRESOLVED_MEMBER, // UnresolvedMemberExpr EXPR_CXX_UNRESOLVED_LOOKUP, // UnresolvedLookupExpr diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp index 725ebbd6ec987..af2950af2134f 100644 --- a/clang/lib/AST/ASTImporter.cpp +++ b/clang/lib/AST/ASTImporter.cpp @@ -682,6 +682,7 @@ namespace clang { ExpectedStmt VisitCXXMemberCallExpr(CXXMemberCallExpr *E); ExpectedStmt VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E); ExpectedStmt VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E); + ExpectedStmt VisitDependentTemplateIdExpr(DependentTemplateIdExpr *E); ExpectedStmt VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *E); ExpectedStmt VisitUnresolvedLookupExpr(UnresolvedLookupExpr *E); ExpectedStmt VisitUnresolvedMemberExpr(UnresolvedMemberExpr *E); @@ -8825,6 +8826,32 @@ ExpectedStmt ASTNodeImporter::VisitCXXDependentScopeMemberExpr( ToMemberNameInfo, ResInfo); } +ExpectedStmt +ASTNodeImporter::VisitDependentTemplateIdExpr(DependentTemplateIdExpr *E) { + Error Err = Error::success(); + auto ToQualifierLoc = importChecked(Err, E->getQualifierLoc()); + auto ToTemplateKeywordLoc = importChecked(Err, E->getTemplateKeywordLoc()); + auto ToName = importChecked(Err, E->getTemplateName()); + auto ToDeclName = importChecked(Err, E->getName()); + auto ToNameLoc = importChecked(Err, E->getNameLoc()); + if (Err) + return std::move(Err); + + DeclarationNameInfo ToNameInfo(ToDeclName, ToNameLoc); + if (Error Err = ImportDeclarationNameLoc(E->getNameInfo(), ToNameInfo)) + return std::move(Err); + + TemplateArgumentListInfo ToTAInfo; + if (Error Err = + ImportTemplateArgumentListInfo(E->getLAngleLoc(), E->getRAngleLoc(), + E->template_arguments(), ToTAInfo)) + return std::move(Err); + + return DependentTemplateIdExpr::Create(Importer.getToContext(), + ToQualifierLoc, ToTemplateKeywordLoc, + ToNameInfo, ToName, ToTAInfo); +} + ExpectedStmt ASTNodeImporter::VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) { Error Err = Error::success(); diff --git a/clang/lib/AST/ComputeDependence.cpp b/clang/lib/AST/ComputeDependence.cpp index 7e6bd69711c5b..0ee723ee5f04f 100644 --- a/clang/lib/AST/ComputeDependence.cpp +++ b/clang/lib/AST/ComputeDependence.cpp @@ -831,7 +831,7 @@ clang::computeDependence(OverloadExpr *E, bool KnownDependent, ~NestedNameSpecifierDependence::Dependent); for (auto *D : E->decls()) { if (D->getDeclContext()->isDependentContext() || - isa<UnresolvedUsingValueDecl>(D) || isa<TemplateTemplateParmDecl>(D)) + isa<UnresolvedUsingValueDecl>(D)) Deps |= ExprDependence::TypeValueInstantiation; } // If we have explicit template arguments, check for dependent @@ -903,6 +903,18 @@ ExprDependence clang::computeDependence(CXXDependentScopeMemberExpr *E) { return D; } +ExprDependence clang::computeDependence(DependentTemplateIdExpr *E) { + auto D = ExprDependence::TypeValueInstantiation; + if (E->getTemplateName().getDependence() & + TemplateNameDependence::UnexpandedPack) + D |= ExprDependence::UnexpandedPack; + D |= toExprDependence(E->getQualifier().getDependence()); + D |= getDependenceInExpr(E->getNameInfo()); + for (const auto &A : E->template_arguments()) + D |= toExprDependence(A.getArgument().getDependence()); + return D; +} + ExprDependence clang::computeDependence(MaterializeTemporaryExpr *E) { return E->getSubExpr()->getDependence(); } diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index 5d7ee4710481c..e501527ed9b04 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -3714,6 +3714,7 @@ bool Expr::HasSideEffects(const ASTContext &Ctx, llvm_unreachable("unexpected Expr kind"); case DependentScopeDeclRefExprClass: + case DependentTemplateIdExprClass: case CXXUnresolvedConstructExprClass: case CXXDependentScopeMemberExprClass: case UnresolvedLookupExprClass: diff --git a/clang/lib/AST/ExprCXX.cpp b/clang/lib/AST/ExprCXX.cpp index 6c1cde6540d85..484a2d06c857d 100644 --- a/clang/lib/AST/ExprCXX.cpp +++ b/clang/lib/AST/ExprCXX.cpp @@ -401,14 +401,45 @@ SourceLocation CXXPseudoDestructorExpr::getEndLoc() const { return End; } -static bool UnresolvedLookupExprIsVariableOrConceptParameterPack( - UnresolvedSetIterator Begin, UnresolvedSetIterator End) { - if (std::distance(Begin, End) != 1) - return false; - NamedDecl *ND = *Begin; - if (const auto *TTP = llvm::dyn_cast<TemplateTemplateParmDecl>(ND)) - return TTP->isParameterPack(); - return false; +DependentTemplateIdExpr::DependentTemplateIdExpr( + const ASTContext &Context, NestedNameSpecifierLoc QualifierLoc, + SourceLocation TemplateKWLoc, const DeclarationNameInfo &NameInfo, + TemplateName Name, const TemplateArgumentListInfo &TemplateArgs) + : Expr(DependentTemplateIdExprClass, Context.DependentTy, VK_LValue, + OK_Ordinary), + QualifierLoc(QualifierLoc), NameInfo(NameInfo), Name(Name) { + getTrailingObjects<ASTTemplateKWAndArgsInfo>()->initializeFrom( + TemplateKWLoc, TemplateArgs, getTrailingObjects<TemplateArgumentLoc>()); + setDependence(computeDependence(this)); +} + +DependentTemplateIdExpr::DependentTemplateIdExpr(EmptyShell Empty, + unsigned NumTemplateArgs) + : Expr(DependentTemplateIdExprClass, Empty) { + getTrailingObjects<ASTTemplateKWAndArgsInfo>()->NumTemplateArgs = + NumTemplateArgs; +} + +DependentTemplateIdExpr *DependentTemplateIdExpr::Create( + const ASTContext &Context, NestedNameSpecifierLoc QualifierLoc, + SourceLocation TemplateKWLoc, const DeclarationNameInfo &NameInfo, + TemplateName Name, const TemplateArgumentListInfo &TemplateArgs) { + void *Mem = Context.Allocate( + totalSizeToAlloc<ASTTemplateKWAndArgsInfo, TemplateArgumentLoc>( + 1, TemplateArgs.size()), + alignof(DependentTemplateIdExpr)); + return new (Mem) DependentTemplateIdExpr(Context, QualifierLoc, TemplateKWLoc, + NameInfo, Name, TemplateArgs); +} + +DependentTemplateIdExpr * +DependentTemplateIdExpr::CreateEmpty(const ASTContext &Context, + unsigned NumTemplateArgs) { + void *Mem = Context.Allocate( + totalSizeToAlloc<ASTTemplateKWAndArgsInfo, TemplateArgumentLoc>( + 1, NumTemplateArgs), + alignof(DependentTemplateIdExpr)); + return new (Mem) DependentTemplateIdExpr(EmptyShell(), NumTemplateArgs); } // UnresolvedLookupExpr @@ -419,11 +450,10 @@ UnresolvedLookupExpr::UnresolvedLookupExpr( const TemplateArgumentListInfo *TemplateArgs, UnresolvedSetIterator Begin, UnresolvedSetIterator End, bool KnownDependent, bool KnownInstantiationDependent) - : OverloadExpr( - UnresolvedLookupExprClass, Context, QualifierLoc, TemplateKWLoc, - NameInfo, TemplateArgs, Begin, End, KnownDependent, - KnownInstantiationDependent, - UnresolvedLookupExprIsVariableOrConceptParameterPack(Begin, End)), + : OverloadExpr(UnresolvedLookupExprClass, Context, QualifierLoc, + TemplateKWLoc, NameInfo, TemplateArgs, Begin, End, + KnownDependent, KnownInstantiationDependent, + /*KnownContainsUnexpandedParameterPack=*/false), NamingClass(NamingClass) { UnresolvedLookupExprBits.RequiresADL = RequiresADL; } diff --git a/clang/lib/AST/ExprClassification.cpp b/clang/lib/AST/ExprClassification.cpp index ef071cdef66b6..eebae17d7b948 100644 --- a/clang/lib/AST/ExprClassification.cpp +++ b/clang/lib/AST/ExprClassification.cpp @@ -130,6 +130,7 @@ static Cl::Kinds ClassifyInternal(ASTContext &Ctx, const Expr *E) { // FIXME: Is this wise? Should they get their own kind? case Expr::UnresolvedLookupExprClass: case Expr::UnresolvedMemberExprClass: + case Expr::DependentTemplateIdExprClass: case Expr::DependentCoawaitExprClass: case Expr::CXXDependentScopeMemberExprClass: case Expr::DependentScopeDeclRefExprClass: diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 05f981f671e62..ddcef9e7bfc6f 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -22340,6 +22340,7 @@ static ICEDiag CheckICE(const Expr* E, const ASTContext &Ctx) { case Expr::UnresolvedLookupExprClass: case Expr::RecoveryExprClass: case Expr::DependentScopeDeclRefExprClass: + case Expr::DependentTemplateIdExprClass: case Expr::CXXConstructExprClass: case Expr::CXXInheritedCtorInitExprClass: case Expr::CXXStdInitializerListExprClass: diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp index f6c4ca1ae6ba8..26776164e9692 100644 --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -5318,6 +5318,15 @@ void CXXNameMangler::mangleExpression(const Expr *E, unsigned Arity, break; } + case Expr::DependentTemplateIdExprClass: { + NotPrimaryExpr(); + const auto *DTI = cast<DependentTemplateIdExpr>(E); + mangleUnresolvedName(DTI->getQualifier(), DTI->getName(), + DTI->template_arguments().data(), + DTI->getNumTemplateArgs(), Arity); + break; + } + case Expr::CXXUnresolvedConstructExprClass: { NotPrimaryExpr(); const CXXUnresolvedConstructExpr *CE = cast<CXXUnresolvedConstructExpr>(E); diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp index eeb377c794e05..4bbf9e083fd29 100644 --- a/clang/lib/AST/StmtPrinter.cpp +++ b/clang/lib/AST/StmtPrinter.cpp @@ -2671,6 +2671,15 @@ void StmtPrinter::VisitCXXReflectExpr(CXXReflectExpr *S) { assert(false && "not implemented yet"); } +void StmtPrinter::VisitDependentTemplateIdExpr(DependentTemplateIdExpr *Node) { + Node->getQualifier().print(OS, Policy); + if (Node->getTemplateKeywordLoc().isValid()) + OS << "template "; + OS << Node->getNameInfo(); + printTemplateArgumentList(OS, Node->template_arguments(), Policy, + Node->getParameter()->getTemplateParameters()); +} + void StmtPrinter::VisitCXXDependentScopeMemberExpr( CXXDependentScopeMemberExpr *Node) { if (!Node->isImplicitAccess()) { diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp index 45c962aa27553..65673971b2096 100644 --- a/clang/lib/AST/StmtProfile.cpp +++ b/clang/lib/AST/StmtProfile.cpp @@ -2353,6 +2353,15 @@ void StmtProfiler::VisitCXXUnresolvedConstructExpr( ID.AddInteger(S->isListInitialization()); } +void StmtProfiler::VisitDependentTemplateIdExpr( + const DependentTemplateIdExpr *S) { + VisitExpr(S); + VisitNestedNameSpecifier(S->getQualifier()); + VisitTemplateName(S->getTemplateName()); + VisitTemplateArguments(S->template_arguments().data(), + S->getNumTemplateArgs()); +} + void StmtProfiler::VisitCXXDependentScopeMemberExpr( const CXXDependentScopeMemberExpr *S) { ID.AddBoolean(S->isImplicitAccess()); diff --git a/clang/lib/AST/TextNodeDumper.cpp b/clang/lib/AST/TextNodeDumper.cpp index d07767aab2068..3976969f79... [truncated] `````````` </details> https://github.com/llvm/llvm-project/pull/216729 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
