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

Reply via email to