https://github.com/cor3ntin updated 
https://github.com/llvm/llvm-project/pull/217637

>From 48a31aad53a8ed58da9fd216232580f4260fafc9 Mon Sep 17 00:00:00 2001
From: Corentin Jabot <[email protected]>
Date: Thu, 20 Aug 2026 15:13:02 +0200
Subject: [PATCH 1/2] [Clang] use TemplateName in AutoType / TypeConstraint to
 store a concept.

This is in preparation of implementing P3670 - ie we are going to
have pack indexing to model a concept, so a TemplateDecl* is not sufficient.

This is fairly mechanical.
There are still some places, especially in tooling & json dumping
where we reach to the underlying TemplateDecl - which will have to change later.
But I think we need to have pack insdexing first to update these places.

The serialization of AutoType was changed to work around a weirdness
of TemplateName which makes serialization of an null TemplateName
impossible.
---
 clang-tools-extra/clang-doc/Serialize.cpp     |  8 ++--
 clang-tools-extra/clangd/DumpAST.cpp          |  2 +-
 clang-tools-extra/clangd/FindTarget.cpp       |  4 +-
 clang/include/clang/AST/ASTConcept.h          | 12 +++---
 clang/include/clang/AST/ASTContext.h          |  2 +-
 clang/include/clang/AST/ExprConcepts.h        |  6 ++-
 clang/include/clang/AST/TextNodeDumper.h      |  1 +
 clang/include/clang/AST/TypeBase.h            | 12 +++---
 clang/include/clang/AST/TypeLoc.h             |  4 +-
 clang/include/clang/AST/TypeProperties.td     | 11 +++--
 clang/include/clang/ExtractAPI/API.h          | 18 +++++++--
 clang/lib/AST/ASTConcept.cpp                  |  2 +-
 clang/lib/AST/ASTContext.cpp                  | 40 ++++++++++---------
 clang/lib/AST/ASTDumper.cpp                   |  2 +-
 clang/lib/AST/ASTImporter.cpp                 | 14 ++++---
 clang/lib/AST/ASTStructuralEquivalence.cpp    |  4 +-
 clang/lib/AST/ItaniumMangle.cpp               | 15 +++----
 clang/lib/AST/JSONNodeDumper.cpp              |  3 +-
 clang/lib/AST/ODRHash.cpp                     |  2 +-
 clang/lib/AST/StmtPrinter.cpp                 |  2 +-
 clang/lib/AST/StmtProfile.cpp                 |  2 +-
 clang/lib/AST/TextNodeDumper.cpp              | 28 ++++++++++---
 clang/lib/AST/Type.cpp                        | 17 +++-----
 clang/lib/AST/TypeLoc.cpp                     |  6 +--
 clang/lib/AST/TypePrinter.cpp                 | 10 +++--
 clang/lib/ExtractAPI/DeclarationFragments.cpp |  1 +
 clang/lib/Index/IndexBody.cpp                 |  6 +--
 clang/lib/Index/IndexDecl.cpp                 |  5 ++-
 clang/lib/Index/IndexTypeSourceInfo.cpp       |  2 +-
 clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp |  4 +-
 clang/lib/Sema/SemaChecking.cpp               |  3 +-
 clang/lib/Sema/SemaCodeComplete.cpp           |  4 +-
 clang/lib/Sema/SemaConcept.cpp                | 25 +++++++-----
 clang/lib/Sema/SemaTemplate.cpp               | 21 +++++-----
 clang/lib/Sema/SemaTemplateDeduction.cpp      | 11 +++--
 clang/lib/Sema/SemaTemplateInstantiate.cpp    |  5 +--
 clang/lib/Sema/SemaType.cpp                   | 33 ++++++++-------
 clang/lib/Sema/TreeTransform.h                | 20 ++++++----
 clang/lib/Serialization/ASTReader.cpp         |  2 +-
 clang/lib/Serialization/ASTWriter.cpp         |  2 +-
 clang/tools/libclang/CIndex.cpp               | 14 +++----
 41 files changed, 218 insertions(+), 167 deletions(-)

diff --git a/clang-tools-extra/clang-doc/Serialize.cpp 
b/clang-tools-extra/clang-doc/Serialize.cpp
index 5fa23416949c4..e490ae1d08bfb 100644
--- a/clang-tools-extra/clang-doc/Serialize.cpp
+++ b/clang-tools-extra/clang-doc/Serialize.cpp
@@ -842,8 +842,8 @@ void Serializer::handleCompoundConstraints(
   } else if (Constraint->getStmtClass() ==
              Stmt::ConceptSpecializationExprClass) {
     auto *Concept = dyn_cast<ConceptSpecializationExpr>(Constraint);
-    ConstraintInfo CI(getUSRForDecl(Concept->getNamedConcept()),
-                      Concept->getNamedConcept()->getNameAsString());
+    ConstraintInfo CI(getUSRForDecl(Concept->getConceptDecl()),
+                      Concept->getConceptDecl()->getNameAsString());
     CI.ConstraintExpr = internString(exprToString(Concept));
     ConstraintInfos.push_back(CI);
   }
@@ -864,8 +864,8 @@ void Serializer::populateConstraints(TemplateInfo &I, const 
TemplateDecl *D) {
     if (const auto *ConstraintExpr =
             dyn_cast_or_null<ConceptSpecializationExpr>(
                 Constraint.ConstraintExpr)) {
-      ConstraintInfo CI(getUSRForDecl(ConstraintExpr->getNamedConcept()),
-                        ConstraintExpr->getNamedConcept()->getNameAsString());
+      ConstraintInfo CI(getUSRForDecl(ConstraintExpr->getConceptDecl()),
+                        ConstraintExpr->getConceptDecl()->getNameAsString());
       CI.ConstraintExpr = internString(exprToString(ConstraintExpr));
       LocalConstraints.push_back(std::move(CI));
     } else {
diff --git a/clang-tools-extra/clangd/DumpAST.cpp 
b/clang-tools-extra/clangd/DumpAST.cpp
index 2b673128493b3..2bcbbc09d90fe 100644
--- a/clang-tools-extra/clangd/DumpAST.cpp
+++ b/clang-tools-extra/clangd/DumpAST.cpp
@@ -303,7 +303,7 @@ class DumpVisitor : public RecursiveASTVisitor<DumpVisitor> 
{
     return CBS.isVirtual() ? "virtual" : "";
   }
   std::string getDetail(const ConceptReference *CR) {
-    return CR->getNamedConcept()->getNameAsString();
+    return CR->getNamedConcept().getAsTemplateDecl()->getNameAsString();
   }
 
   /// Arcana is produced by TextNodeDumper, for the types it supports.
diff --git a/clang-tools-extra/clangd/FindTarget.cpp 
b/clang-tools-extra/clangd/FindTarget.cpp
index 41c9cddfebbbc..aea04e14b2cf8 100644
--- a/clang-tools-extra/clangd/FindTarget.cpp
+++ b/clang-tools-extra/clangd/FindTarget.cpp
@@ -519,7 +519,7 @@ struct TargetFinder {
   }
 
   void add(const ConceptReference *CR, RelSet Flags) {
-    add(CR->getNamedConcept(), Flags);
+    add(CR->getNamedConcept().getAsTemplateDecl(), Flags);
   }
 };
 
@@ -1081,7 +1081,7 @@ class ExplicitReferenceCollector
       return {ReferenceLoc{CR->getNestedNameSpecifierLoc(),
                            CR->getConceptNameLoc(),
                            /*IsDecl=*/false,
-                           {CR->getNamedConcept()}}};
+                           {CR->getNamedConcept().getAsTemplateDecl()}}};
     if (const OffsetOfNode *OON = N.get<OffsetOfNode>()) {
       if (OON->getKind() == OffsetOfNode::Field)
         return {ReferenceLoc{NestedNameSpecifierLoc(),
diff --git a/clang/include/clang/AST/ASTConcept.h 
b/clang/include/clang/AST/ASTConcept.h
index 4319df35ab7e5..9a65c32b5ca1e 100644
--- a/clang/include/clang/AST/ASTConcept.h
+++ b/clang/include/clang/AST/ASTConcept.h
@@ -146,7 +146,7 @@ class ConceptReference {
   NamedDecl *FoundDecl;
 
   /// \brief The concept named.
-  TemplateDecl *NamedConcept;
+  TemplateName NamedConcept;
 
   /// \brief The template argument list source info used to specialize the
   /// concept.
@@ -154,7 +154,7 @@ class ConceptReference {
 
   ConceptReference(NestedNameSpecifierLoc NNS, SourceLocation TemplateKWLoc,
                    DeclarationNameInfo ConceptNameInfo, NamedDecl *FoundDecl,
-                   TemplateDecl *NamedConcept,
+                   TemplateName NamedConcept,
                    const ASTTemplateArgumentListInfo *ArgsAsWritten)
       : NestedNameSpec(NNS), TemplateKWLoc(TemplateKWLoc),
         ConceptName(ConceptNameInfo), FoundDecl(FoundDecl),
@@ -164,7 +164,7 @@ class ConceptReference {
   static ConceptReference *
   Create(const ASTContext &C, NestedNameSpecifierLoc NNS,
          SourceLocation TemplateKWLoc, DeclarationNameInfo ConceptNameInfo,
-         NamedDecl *FoundDecl, TemplateDecl *NamedConcept,
+         NamedDecl *FoundDecl, TemplateName NamedConcept,
          const ASTTemplateArgumentListInfo *ArgsAsWritten);
 
   const NestedNameSpecifierLoc &getNestedNameSpecifierLoc() const {
@@ -198,7 +198,7 @@ class ConceptReference {
     return FoundDecl;
   }
 
-  TemplateDecl *getNamedConcept() const { return NamedConcept; }
+  TemplateName getNamedConcept() const { return NamedConcept; }
 
   const ASTTemplateArgumentListInfo *getTemplateArgsAsWritten() const {
     return ArgsAsWritten;
@@ -251,9 +251,7 @@ class TypeConstraint {
 
   // FIXME: Instead of using these concept related functions the callers should
   // directly work with the corresponding ConceptReference.
-  TemplateDecl *getNamedConcept() const {
-    return ConceptRef->getNamedConcept();
-  }
+  TemplateName getNamedConcept() const { return ConceptRef->getNamedConcept(); 
}
 
   SourceLocation getConceptNameLoc() const {
     return ConceptRef->getConceptNameLoc();
diff --git a/clang/include/clang/AST/ASTContext.h 
b/clang/include/clang/AST/ASTContext.h
index 56b51566f58f5..0539149105633 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -2155,7 +2155,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
   /// C++11 deduced auto type.
   QualType
   getAutoType(DeducedKind DK, QualType DeducedAsType, AutoTypeKeyword Keyword,
-              TemplateDecl *TypeConstraintConcept = nullptr,
+              TemplateName TypeConstraintConcept = TemplateName(),
               ArrayRef<TemplateArgument> TypeConstraintArgs = {}) const;
 
   /// C++11 deduction pattern for 'auto' type.
diff --git a/clang/include/clang/AST/ExprConcepts.h 
b/clang/include/clang/AST/ExprConcepts.h
index 4f162b6ffc8af..18ce5a94ebef3 100644
--- a/clang/include/clang/AST/ExprConcepts.h
+++ b/clang/include/clang/AST/ExprConcepts.h
@@ -84,8 +84,10 @@ class ConceptSpecializationExpr final : public Expr {
 
   ConceptReference *getConceptReference() const { return ConceptRef; }
 
-  ConceptDecl *getNamedConcept() const {
-    return cast<ConceptDecl>(ConceptRef->getNamedConcept());
+  TemplateName getNamedConcept() const { return ConceptRef->getNamedConcept(); 
}
+
+  ConceptDecl *getConceptDecl() const {
+    return cast<ConceptDecl>(getNamedConcept().getAsTemplateDecl());
   }
 
   // FIXME: Several of the following functions can be removed. Instead the
diff --git a/clang/include/clang/AST/TextNodeDumper.h 
b/clang/include/clang/AST/TextNodeDumper.h
index 5d4a4456b40a1..1cdd8c37c7fc6 100644
--- a/clang/include/clang/AST/TextNodeDumper.h
+++ b/clang/include/clang/AST/TextNodeDumper.h
@@ -216,6 +216,7 @@ class TextNodeDumper
   void dumpConceptReference(const ConceptReference *R);
   void dumpTemplateArgument(const TemplateArgument &TA);
   void dumpBareTemplateName(TemplateName TN);
+  void dumpBareConcept(TemplateName TN);
   void dumpTemplateName(TemplateName TN, StringRef Label = {});
 
   void dumpDeclRef(const Decl *D, StringRef Label = {});
diff --git a/clang/include/clang/AST/TypeBase.h 
b/clang/include/clang/AST/TypeBase.h
index eb05a068934ea..12bfd192287d7 100644
--- a/clang/include/clang/AST/TypeBase.h
+++ b/clang/include/clang/AST/TypeBase.h
@@ -7381,10 +7381,10 @@ class DeducedType : public Type {
 class AutoType : public DeducedType, public llvm::FoldingSetNode {
   friend class ASTContext; // ASTContext creates these
 
-  TemplateDecl *TypeConstraintConcept;
+  TemplateName TypeConstraintConcept;
 
   AutoType(DeducedKind DK, QualType DeducedAsTypeOrCanon,
-           AutoTypeKeyword Keyword, TemplateDecl *TypeConstraintConcept,
+           AutoTypeKeyword Keyword, TemplateName TypeConstraintConcept,
            ArrayRef<TemplateArgument> TypeConstraintArgs);
 
 public:
@@ -7393,13 +7393,11 @@ class AutoType : public DeducedType, public 
llvm::FoldingSetNode {
             AutoTypeBits.NumArgs};
   }
 
-  TemplateDecl *getTypeConstraintConcept() const {
+  TemplateName getTypeConstraintConcept() const {
     return TypeConstraintConcept;
   }
 
-  bool isConstrained() const {
-    return TypeConstraintConcept != nullptr;
-  }
+  bool isConstrained() const { return !TypeConstraintConcept.isNull(); }
 
   bool isDecltypeAuto() const {
     return getKeyword() == AutoTypeKeyword::DecltypeAuto;
@@ -7416,7 +7414,7 @@ class AutoType : public DeducedType, public 
llvm::FoldingSetNode {
   void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context);
   static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
                       DeducedKind DK, QualType Deduced, AutoTypeKeyword 
Keyword,
-                      TemplateDecl *CD, ArrayRef<TemplateArgument> Arguments);
+                      TemplateName CD, ArrayRef<TemplateArgument> Arguments);
 
   static bool classof(const Type *T) {
     return T->getTypeClass() == Auto;
diff --git a/clang/include/clang/AST/TypeLoc.h 
b/clang/include/clang/AST/TypeLoc.h
index 2648806ac687a..b3cb4d0f33629 100644
--- a/clang/include/clang/AST/TypeLoc.h
+++ b/clang/include/clang/AST/TypeLoc.h
@@ -2463,10 +2463,10 @@ class AutoTypeLoc
     return nullptr;
   }
 
-  TemplateDecl *getNamedConcept() const {
+  TemplateName getNamedConcept() const {
     if (const auto *CR = getConceptReference())
       return CR->getNamedConcept();
-    return nullptr;
+    return TemplateName();
   }
 
   DeclarationNameInfo getConceptNameInfo() const {
diff --git a/clang/include/clang/AST/TypeProperties.td 
b/clang/include/clang/AST/TypeProperties.td
index 1723fed7bfd91..5b3966db9001b 100644
--- a/clang/include/clang/AST/TypeProperties.td
+++ b/clang/include/clang/AST/TypeProperties.td
@@ -531,9 +531,12 @@ let Class = AutoType in {
   def : Property<"keyword", AutoTypeKeyword> {
     let Read = [{ node->getKeyword() }];
   }
-  def : Property<"typeConstraintConcept", Optional<TemplateDeclRef>> {
-    let Read = [{ makeOptionalFromPointer(
-        node->getTypeConstraintConcept()) }];
+  def : Property<"isConstrained", Bool> {
+    let Read = [{ node->isConstrained() }];
+  }
+  def : Property<"typeConstraintConcept", TemplateName> {
+    let Conditional = [{ isConstrained }];
+    let Read = [{ node->getTypeConstraintConcept() }];
   }
   def : Property<"typeConstraintArguments", Array<TemplateArgument>> {
     let Read = [{ node->getTypeConstraintArguments() }];
@@ -541,7 +544,7 @@ let Class = AutoType in {
 
   def : Creator<[{
     return ctx.getAutoType(deducedKind, makeNullableFromOptional(deducedType), 
keyword,
-                           makePointerFromOptional(typeConstraintConcept),
+                           isConstrained ? *typeConstraintConcept : 
TemplateName(),
                            typeConstraintArguments);
   }]>;
 }
diff --git a/clang/include/clang/ExtractAPI/API.h 
b/clang/include/clang/ExtractAPI/API.h
index 62483bcf2cdc9..d0d05fcab4af6 100644
--- a/clang/include/clang/ExtractAPI/API.h
+++ b/clang/include/clang/ExtractAPI/API.h
@@ -71,7 +71,11 @@ class Template {
         continue;
       std::string Type;
       if (Param->hasTypeConstraint())
-        Type = Param->getTypeConstraint()->getNamedConcept()->getName().str();
+        Type = Param->getTypeConstraint()
+                   ->getNamedConcept()
+                   .getAsTemplateDecl()
+                   ->getName()
+                   .str();
       else if (Param->wasDeclaredWithTypename())
         Type = "typename";
       else
@@ -89,7 +93,11 @@ class Template {
         continue;
       std::string Type;
       if (Param->hasTypeConstraint())
-        Type = Param->getTypeConstraint()->getNamedConcept()->getName().str();
+        Type = Param->getTypeConstraint()
+                   ->getNamedConcept()
+                   .getAsTemplateDecl()
+                   ->getName()
+                   .str();
       else if (Param->wasDeclaredWithTypename())
         Type = "typename";
       else
@@ -107,7 +115,11 @@ class Template {
         continue;
       std::string Type;
       if (Param->hasTypeConstraint())
-        Type = Param->getTypeConstraint()->getNamedConcept()->getName().str();
+        Type = Param->getTypeConstraint()
+                   ->getNamedConcept()
+                   .getAsTemplateDecl()
+                   ->getName()
+                   .str();
       else if (Param->wasDeclaredWithTypename())
         Type = "typename";
       else
diff --git a/clang/lib/AST/ASTConcept.cpp b/clang/lib/AST/ASTConcept.cpp
index fd12bc4e83827..c843aa797f9ba 100644
--- a/clang/lib/AST/ASTConcept.cpp
+++ b/clang/lib/AST/ASTConcept.cpp
@@ -93,7 +93,7 @@ ConceptReference *
 ConceptReference::Create(const ASTContext &C, NestedNameSpecifierLoc NNS,
                          SourceLocation TemplateKWLoc,
                          DeclarationNameInfo ConceptNameInfo,
-                         NamedDecl *FoundDecl, TemplateDecl *NamedConcept,
+                         NamedDecl *FoundDecl, TemplateName NamedConcept,
                          const ASTTemplateArgumentListInfo *ArgsAsWritten) {
   return new (C) ConceptReference(NNS, TemplateKWLoc, ConceptNameInfo,
                                   FoundDecl, NamedConcept, ArgsAsWritten);
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 35a2a0b131a3f..df6d03b4f17ed 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -6912,10 +6912,10 @@ ASTContext::getUnaryTransformType(QualType BaseType, 
QualType UnderlyingType,
 QualType
 ASTContext::getAutoType(DeducedKind DK, QualType DeducedAsType,
                         AutoTypeKeyword Keyword,
-                        TemplateDecl *TypeConstraintConcept,
+                        TemplateName TypeConstraintConcept,
                         ArrayRef<TemplateArgument> TypeConstraintArgs) const {
   if (DK == DeducedKind::Undeduced && Keyword == AutoTypeKeyword::Auto &&
-      !TypeConstraintConcept) {
+      TypeConstraintConcept.isNull()) {
     assert(DeducedAsType.isNull() && "");
     assert(TypeConstraintArgs.empty() && "");
     return getAutoDeductType();
@@ -6932,10 +6932,10 @@ ASTContext::getAutoType(DeducedKind DK, QualType 
DeducedAsType,
     assert(!DeducedAsType.isNull() && "deduced type must be provided");
   } else {
     assert(DeducedAsType.isNull() && "deduced type must not be provided");
-    if (TypeConstraintConcept) {
+    if (!TypeConstraintConcept.isNull()) {
       bool AnyNonCanonArgs = false;
-      auto *CanonicalConcept =
-          cast<TemplateDecl>(TypeConstraintConcept->getCanonicalDecl());
+      TemplateName CanonicalConcept =
+          getCanonicalTemplateName(TypeConstraintConcept);
       auto CanonicalConceptArgs = ::getCanonicalTemplateArguments(
           *this, TypeConstraintArgs, AnyNonCanonArgs);
       if (TypeConstraintConcept != CanonicalConcept || AnyNonCanonArgs)
@@ -7056,12 +7056,12 @@ QualType ASTContext::getAtomicType(QualType T) const {
 /// getAutoDeductType - Get type pattern for deducing against 'auto'.
 QualType ASTContext::getAutoDeductType() const {
   if (AutoDeductTy.isNull())
-    AutoDeductTy = QualType(new (*this, alignof(AutoType))
-                                AutoType(DeducedKind::Undeduced, QualType(),
-                                         AutoTypeKeyword::Auto,
-                                         /*TypeConstraintConcept=*/nullptr,
-                                         /*TypeConstraintArgs=*/{}),
-                            0);
+    AutoDeductTy = QualType(
+        new (*this, alignof(AutoType))
+            AutoType(DeducedKind::Undeduced, QualType(), AutoTypeKeyword::Auto,
+                     /*TypeConstraintConcept=*/TemplateName(),
+                     /*TypeConstraintArgs=*/{}),
+        0);
   return AutoDeductTy;
 }
 
@@ -7555,8 +7555,8 @@ bool ASTContext::isSameTypeConstraint(const 
TypeConstraint *XTC,
   if (!XTC)
     return true;
 
-  auto *NCX = XTC->getNamedConcept();
-  auto *NCY = YTC->getNamedConcept();
+  TemplateDecl *NCX = XTC->getNamedConcept().getAsTemplateDecl();
+  TemplateDecl *NCY = YTC->getNamedConcept().getAsTemplateDecl();
   if (!NCX || !NCY || !isSameEntity(NCX, NCY))
     return false;
   if (XTC->getConceptReference()->hasExplicitTemplateArgs() !=
@@ -14442,8 +14442,9 @@ static QualType getCommonNonSugarTypeNode(const 
ASTContext &Ctx, const Type *X,
     assert(AX->getDeducedKind() == AY->getDeducedKind());
     assert(AX->getDeducedKind() != DeducedKind::Deduced);
     assert(AX->getKeyword() == AY->getKeyword());
-    TemplateDecl *CD = ::getCommonDecl(AX->getTypeConstraintConcept(),
-                                       AY->getTypeConstraintConcept());
+    TemplateDecl *CD =
+        ::getCommonDecl(AX->getTypeConstraintConcept().getAsTemplateDecl(),
+                        AY->getTypeConstraintConcept().getAsTemplateDecl());
     SmallVector<TemplateArgument, 8> As;
     if (CD &&
         getCommonTemplateArguments(Ctx, As, AX->getTypeConstraintArguments(),
@@ -14452,7 +14453,7 @@ static QualType getCommonNonSugarTypeNode(const 
ASTContext &Ctx, const Type *X,
       As.clear();
     }
     return Ctx.getAutoType(AX->getDeducedKind(), QualType(), AX->getKeyword(),
-                           CD, As);
+                           TemplateName(CD), As);
   }
   case Type::IncompleteArray: {
     const auto *AX = cast<IncompleteArrayType>(X),
@@ -14833,8 +14834,9 @@ static QualType getCommonSugarTypeNode(const ASTContext 
&Ctx, const Type *X,
     if (KW != AY->getKeyword())
       return QualType();
 
-    TemplateDecl *CD = ::getCommonDecl(AX->getTypeConstraintConcept(),
-                                       AY->getTypeConstraintConcept());
+    TemplateDecl *CD =
+        ::getCommonDecl(AX->getTypeConstraintConcept().getAsTemplateDecl(),
+                        AY->getTypeConstraintConcept().getAsTemplateDecl());
     SmallVector<TemplateArgument, 8> As;
     if (CD &&
         getCommonTemplateArguments(Ctx, As, AX->getTypeConstraintArguments(),
@@ -14847,7 +14849,7 @@ static QualType getCommonSugarTypeNode(const ASTContext 
&Ctx, const Type *X,
     // sugar. This implies they can't contain unexpanded packs either.
     return Ctx.getAutoType(DeducedKind::Deduced,
                            Ctx.getQualifiedType(Underlying), AX->getKeyword(),
-                           CD, As);
+                           TemplateName(CD), As);
   }
   case Type::PackIndexing:
   case Type::Decltype:
diff --git a/clang/lib/AST/ASTDumper.cpp b/clang/lib/AST/ASTDumper.cpp
index 146fc5ea5caad..f74fec07b6175 100644
--- a/clang/lib/AST/ASTDumper.cpp
+++ b/clang/lib/AST/ASTDumper.cpp
@@ -362,7 +362,7 @@ LLVM_DUMP_METHOD void ConceptReference::dump() const {
 }
 
 LLVM_DUMP_METHOD void ConceptReference::dump(raw_ostream &OS) const {
-  auto &Ctx = getNamedConcept()->getASTContext();
+  auto &Ctx = getNamedConcept().getAsTemplateDecl()->getASTContext();
   ASTDumper P(OS, Ctx, showColorsForStream(Ctx, OS));
   P.Visit(this);
 }
diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index c2164352126ef..69f50bce925a0 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -1748,10 +1748,14 @@ ExpectedType ASTNodeImporter::VisitAutoType(const 
AutoType *T) {
   if (!ToDeducedTypeOrErr)
     return ToDeducedTypeOrErr.takeError();
 
-  Expected<TemplateDecl *> ToTypeConstraint =
-      import(T->getTypeConstraintConcept());
-  if (!ToTypeConstraint)
-    return ToTypeConstraint.takeError();
+  TemplateName ToTypeConstraint;
+  if (TemplateName FromTypeConstraint = T->getTypeConstraintConcept();
+      !FromTypeConstraint.isNull()) {
+    Expected<TemplateName> ToTypeConstraintOrErr = import(FromTypeConstraint);
+    if (!ToTypeConstraintOrErr)
+      return ToTypeConstraintOrErr.takeError();
+    ToTypeConstraint = *ToTypeConstraintOrErr;
+  }
 
   SmallVector<TemplateArgument, 2> ToTemplateArgs;
   if (Error Err = ImportTemplateArguments(T->getTypeConstraintArguments(),
@@ -1760,7 +1764,7 @@ ExpectedType ASTNodeImporter::VisitAutoType(const 
AutoType *T) {
 
   return Importer.getToContext().getAutoType(
       T->getDeducedKind(), *ToDeducedTypeOrErr, T->getKeyword(),
-      *ToTypeConstraint, ToTemplateArgs);
+      ToTypeConstraint, ToTemplateArgs);
 }
 
 ExpectedType ASTNodeImporter::VisitDeducedTemplateSpecializationType(
diff --git a/clang/lib/AST/ASTStructuralEquivalence.cpp 
b/clang/lib/AST/ASTStructuralEquivalence.cpp
index ebf4507e6e67d..d6d527f0641a3 100644
--- a/clang/lib/AST/ASTStructuralEquivalence.cpp
+++ b/clang/lib/AST/ASTStructuralEquivalence.cpp
@@ -1340,8 +1340,8 @@ bool ASTStructuralEquivalence::isEquivalent(
     if (Auto1->isConstrained() != Auto2->isConstrained())
       return false;
     if (Auto1->isConstrained()) {
-      if (Auto1->getTypeConstraintConcept() !=
-          Auto2->getTypeConstraintConcept())
+      if (Auto1->getTypeConstraintConcept().getAsTemplateDecl() !=
+          Auto2->getTypeConstraintConcept().getAsTemplateDecl())
         return false;
       if (!IsStructurallyEquivalent(Context,
                                     Auto1->getTypeConstraintArguments(),
diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index c77d9d979e932..7528aa1b9bbcd 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -518,7 +518,7 @@ class CXXNameMangler {
   void mangleUnqualifiedBlock(const BlockDecl *Block);
   void mangleTemplateParamDecl(const NamedDecl *Decl);
   void mangleTemplateParameterList(const TemplateParameterList *Params);
-  void mangleTypeConstraint(const TemplateDecl *Concept,
+  void mangleTypeConstraint(TemplateName Concept,
                             ArrayRef<TemplateArgument> Arguments);
   void mangleTypeConstraint(const TypeConstraint *Constraint);
   void mangleRequiresClause(const Expr *RequiresClause);
@@ -2095,14 +2095,15 @@ void CXXNameMangler::mangleTemplateParameterList(
 }
 
 void CXXNameMangler::mangleTypeConstraint(
-    const TemplateDecl *Concept, ArrayRef<TemplateArgument> Arguments) {
-  const DeclContext *DC = Context.getEffectiveDeclContext(Concept);
+    TemplateName Concept, ArrayRef<TemplateArgument> Arguments) {
+  const TemplateDecl *TD = Concept.getAsTemplateDecl();
+  const DeclContext *DC = Context.getEffectiveDeclContext(TD);
   if (!Arguments.empty())
-    mangleTemplateName(Concept, Arguments);
+    mangleTemplateName(TD, Arguments);
   else if (DC->isTranslationUnit() || isStdNamespace(DC))
-    mangleUnscopedName(Concept, DC);
+    mangleUnscopedName(TD, DC);
   else
-    mangleNestedName(Concept, DC);
+    mangleNestedName(TD, DC);
 }
 
 void CXXNameMangler::mangleTypeConstraint(const TypeConstraint *Constraint) {
@@ -5710,7 +5711,7 @@ void CXXNameMangler::mangleExpression(const Expr *E, 
unsigned Arity,
       // entity, meaning that references to enclosing template arguments don't
       // work.
       Out << "L_Z";
-      mangleTemplateName(CSE->getNamedConcept(), CSE->getTemplateArguments());
+      mangleTemplateName(CSE->getConceptDecl(), CSE->getTemplateArguments());
       Out << 'E';
       break;
     }
diff --git a/clang/lib/AST/JSONNodeDumper.cpp b/clang/lib/AST/JSONNodeDumper.cpp
index b9c2272b97a4b..4cea437db4150 100644
--- a/clang/lib/AST/JSONNodeDumper.cpp
+++ b/clang/lib/AST/JSONNodeDumper.cpp
@@ -241,7 +241,8 @@ void JSONNodeDumper::Visit(const APValue &Value, QualType 
Ty) {
 
 void JSONNodeDumper::Visit(const ConceptReference *CR) {
   JOS.attribute("kind", "ConceptReference");
-  JOS.attribute("id", createPointerRepresentation(CR->getNamedConcept()));
+  JOS.attribute("id", createPointerRepresentation(
+                          CR->getNamedConcept().getAsTemplateDecl()));
   if (const auto *Args = CR->getTemplateArgsAsWritten()) {
     JOS.attributeArray("templateArgsAsWritten", [Args, this] {
       for (const TemplateArgumentLoc &TAL : Args->arguments())
diff --git a/clang/lib/AST/ODRHash.cpp b/clang/lib/AST/ODRHash.cpp
index 297d6ba5b7686..386979d0f9ce2 100644
--- a/clang/lib/AST/ODRHash.cpp
+++ b/clang/lib/AST/ODRHash.cpp
@@ -1039,7 +1039,7 @@ class ODRTypeVisitor : public TypeVisitor<ODRTypeVisitor> 
{
     ID.AddInteger((unsigned)T->getKeyword());
     ID.AddInteger(T->isConstrained());
     if (T->isConstrained()) {
-      AddDecl(T->getTypeConstraintConcept());
+      Hash.AddTemplateName(T->getTypeConstraintConcept());
       ID.AddInteger(T->getTypeConstraintArguments().size());
       for (const auto &TA : T->getTypeConstraintArguments())
         Hash.AddTemplateArgument(TA);
diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp
index e08566e5ae011..e957b03b7e898 100644
--- a/clang/lib/AST/StmtPrinter.cpp
+++ b/clang/lib/AST/StmtPrinter.cpp
@@ -2793,7 +2793,7 @@ void 
StmtPrinter::VisitConceptSpecializationExpr(ConceptSpecializationExpr *E) {
   OS << E->getFoundDecl()->getName();
   printTemplateArgumentList(OS, E->getTemplateArgsAsWritten()->arguments(),
                             Policy,
-                            E->getNamedConcept()->getTemplateParameters());
+                            E->getConceptDecl()->getTemplateParameters());
 }
 
 void StmtPrinter::VisitRequiresExpr(RequiresExpr *E) {
diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp
index dca2c49ac45d5..08b42c1477664 100644
--- a/clang/lib/AST/StmtProfile.cpp
+++ b/clang/lib/AST/StmtProfile.cpp
@@ -1775,7 +1775,7 @@ void StmtProfiler::VisitAtomicExpr(const AtomicExpr *S) {
 void StmtProfiler::VisitConceptSpecializationExpr(
                                            const ConceptSpecializationExpr *S) 
{
   VisitExpr(S);
-  VisitDecl(S->getNamedConcept());
+  VisitTemplateName(S->getNamedConcept());
   for (const TemplateArgument &Arg : S->getTemplateArguments())
     VisitTemplateArgument(Arg);
 }
diff --git a/clang/lib/AST/TextNodeDumper.cpp b/clang/lib/AST/TextNodeDumper.cpp
index 55e71cf58f248..f58cc4f5761b7 100644
--- a/clang/lib/AST/TextNodeDumper.cpp
+++ b/clang/lib/AST/TextNodeDumper.cpp
@@ -555,7 +555,7 @@ void TextNodeDumper::Visit(const ConceptReference *R) {
   dumpPointer(R);
   dumpSourceRange(R->getSourceRange());
   OS << ' ';
-  dumpBareDeclRef(R->getNamedConcept());
+  dumpBareConcept(R->getNamedConcept());
 }
 
 void TextNodeDumper::Visit(const concepts::Requirement *R) {
@@ -957,6 +957,21 @@ void TextNodeDumper::dumpType(QualType T) {
   dumpBareType(T);
 }
 
+void TextNodeDumper::dumpBareConcept(TemplateName TN) {
+  {
+    ColorScope Color(OS, ShowColors, ASTDumpColor::DeclKindName);
+    OS << "Concept";
+  }
+
+  const TemplateDecl *TD = TN.getAsTemplateDecl();
+  dumpPointer(TD);
+
+  ColorScope Color(OS, ShowColors, ASTDumpColor::DeclName);
+  OS << " '";
+  OS << TD->getDeclName();
+  OS << '\'';
+}
+
 void TextNodeDumper::dumpBareDeclRef(const Decl *D) {
   if (!D) {
     ColorScope Color(OS, ShowColors, ASTDumpColor::Null);
@@ -2317,7 +2332,7 @@ void TextNodeDumper::VisitAutoType(const AutoType *T) {
   // Not necessary to dump the keyword since it's spelled plainly in the 
printed
   // type anyway.
   if (T->isConstrained())
-    dumpDeclRef(T->getTypeConstraintConcept());
+    AddChild([=] { dumpBareConcept(T->getTypeConstraintConcept()); });
 }
 
 void TextNodeDumper::VisitDeducedTemplateSpecializationType(
@@ -2931,11 +2946,12 @@ void TextNodeDumper::VisitBuiltinTemplateDecl(const 
BuiltinTemplateDecl *D) {
 
 void TextNodeDumper::VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) {
   if (const auto *TC = D->getTypeConstraint()) {
-    OS << " ";
-    dumpBareDeclRef(TC->getNamedConcept());
-    if (TC->getNamedConcept() != TC->getFoundDecl()) {
+    OS << ' ';
+    dumpBareConcept(TC->getNamedConcept());
+    if (const auto *USD =
+            dyn_cast_if_present<UsingShadowDecl>(TC->getFoundDecl())) {
       OS << " (";
-      dumpBareDeclRef(TC->getFoundDecl());
+      dumpBareDeclRef(USD);
       OS << ")";
     }
   } else if (D->wasDeclaredWithTypename())
diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index 4063d03f7750e..fa346856a260c 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -5740,20 +5740,15 @@ DeducedType::DeducedType(TypeClass TC, DeducedKind DK,
 }
 
 AutoType::AutoType(DeducedKind DK, QualType DeducedAsTypeOrCanon,
-                   AutoTypeKeyword Keyword, TemplateDecl 
*TypeConstraintConcept,
+                   AutoTypeKeyword Keyword, TemplateName TypeConstraintConcept,
                    ArrayRef<TemplateArgument> TypeConstraintArgs)
     : DeducedType(Auto, DK, DeducedAsTypeOrCanon) {
   AutoTypeBits.Keyword = llvm::to_underlying(Keyword);
   AutoTypeBits.NumArgs = TypeConstraintArgs.size();
   this->TypeConstraintConcept = TypeConstraintConcept;
-  assert(TypeConstraintConcept || AutoTypeBits.NumArgs == 0);
-  if (TypeConstraintConcept) {
-    auto Dep = TypeDependence::None;
-    if (const auto *TTP =
-            dyn_cast<TemplateTemplateParmDecl>(TypeConstraintConcept))
-      Dep = TypeDependence::DependentInstantiation |
-            (TTP->isParameterPack() ? TypeDependence::UnexpandedPack
-                                    : TypeDependence::None);
+  assert(!TypeConstraintConcept.isNull() || AutoTypeBits.NumArgs == 0);
+  if (!TypeConstraintConcept.isNull()) {
+    auto Dep = toTypeDependence(TypeConstraintConcept.getDependence());
 
     auto *ArgBuffer =
         const_cast<TemplateArgument *>(getTypeConstraintArguments().data());
@@ -5770,11 +5765,11 @@ AutoType::AutoType(DeducedKind DK, QualType 
DeducedAsTypeOrCanon,
 
 void AutoType::Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
                        DeducedKind DK, QualType Deduced,
-                       AutoTypeKeyword Keyword, TemplateDecl *CD,
+                       AutoTypeKeyword Keyword, TemplateName CD,
                        ArrayRef<TemplateArgument> Arguments) {
   DeducedType::Profile(ID, DK, Deduced);
   ID.AddInteger(llvm::to_underlying(Keyword));
-  ID.AddPointer(CD);
+  CD.Profile(ID);
   for (const TemplateArgument &Arg : Arguments)
     Arg.Profile(ID, Context);
 }
diff --git a/clang/lib/AST/TypeLoc.cpp b/clang/lib/AST/TypeLoc.cpp
index e4bd490e5dd77..06406b805c402 100644
--- a/clang/lib/AST/TypeLoc.cpp
+++ b/clang/lib/AST/TypeLoc.cpp
@@ -767,9 +767,9 @@ void TemplateSpecializationTypeLoc::initializeArgLocs(
 static ConceptReference *createTrivialConceptReference(ASTContext &Context,
                                                        SourceLocation Loc,
                                                        const AutoType *AT) {
-  DeclarationNameInfo DNI =
-      DeclarationNameInfo(AT->getTypeConstraintConcept()->getDeclName(), Loc,
-                          AT->getTypeConstraintConcept()->getDeclName());
+  DeclarationName ConceptName =
+      AT->getTypeConstraintConcept().getAsTemplateDecl()->getDeclName();
+  DeclarationNameInfo DNI = DeclarationNameInfo(ConceptName, Loc, ConceptName);
   unsigned size = AT->getTypeConstraintArguments().size();
   llvm::SmallVector<TemplateArgumentLocInfo, 8> TALI(size);
   TemplateSpecializationTypeLoc::initializeArgLocs(
diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp
index bb3aa2bd22e77..90d9e13a8646e 100644
--- a/clang/lib/AST/TypePrinter.cpp
+++ b/clang/lib/AST/TypePrinter.cpp
@@ -1412,12 +1412,14 @@ void TypePrinter::printAutoBefore(const AutoType *T, 
raw_ostream &OS) {
     if (T->isConstrained()) {
       // FIXME: Track a TypeConstraint as type sugar, so that we can print the
       // type as it was written.
-      T->getTypeConstraintConcept()->getDeclName().print(OS, Policy);
+      T->getTypeConstraintConcept().getAsTemplateDecl()->getDeclName().print(
+          OS, Policy);
       auto Args = T->getTypeConstraintArguments();
       if (!Args.empty())
-        printTemplateArgumentList(
-            OS, Args, Policy,
-            T->getTypeConstraintConcept()->getTemplateParameters());
+        printTemplateArgumentList(OS, Args, Policy,
+                                  T->getTypeConstraintConcept()
+                                      .getAsTemplateDecl()
+                                      ->getTemplateParameters());
       OS << ' ';
     }
     switch (T->getKeyword()) {
diff --git a/clang/lib/ExtractAPI/DeclarationFragments.cpp 
b/clang/lib/ExtractAPI/DeclarationFragments.cpp
index 1ebaf2e7e2456..47b4b8c864a89 100644
--- a/clang/lib/ExtractAPI/DeclarationFragments.cpp
+++ b/clang/lib/ExtractAPI/DeclarationFragments.cpp
@@ -1013,6 +1013,7 @@ 
DeclarationFragmentsBuilder::getFragmentsForTemplateParameters(
       if (TemplateParam->hasTypeConstraint())
         Fragments.append(TemplateParam->getTypeConstraint()
                              ->getNamedConcept()
+                             .getAsTemplateDecl()
                              ->getName()
                              .str(),
                          DeclarationFragments::FragmentKind::TypeIdentifier);
diff --git a/clang/lib/Index/IndexBody.cpp b/clang/lib/Index/IndexBody.cpp
index 1979117d4695c..e380d9c604492 100644
--- a/clang/lib/Index/IndexBody.cpp
+++ b/clang/lib/Index/IndexBody.cpp
@@ -500,14 +500,14 @@ class BodyIndexer : public 
RecursiveASTVisitor<BodyIndexer> {
   }
 
   bool VisitConceptSpecializationExpr(ConceptSpecializationExpr *R) {
-    IndexCtx.handleReference(R->getNamedConcept(), R->getConceptNameLoc(),
+    IndexCtx.handleReference(R->getConceptDecl(), R->getConceptNameLoc(),
                              Parent, ParentDC);
     return true;
   }
 
   bool TraverseTypeConstraint(const TypeConstraint *C) {
-    IndexCtx.handleReference(C->getNamedConcept(), C->getConceptNameLoc(),
-                             Parent, ParentDC);
+    IndexCtx.handleReference(C->getNamedConcept().getAsTemplateDecl(),
+                             C->getConceptNameLoc(), Parent, ParentDC);
     return RecursiveASTVisitor::TraverseTypeConstraint(C);
   }
 };
diff --git a/clang/lib/Index/IndexDecl.cpp b/clang/lib/Index/IndexDecl.cpp
index 8b32a48483a67..311beb68a3daf 100644
--- a/clang/lib/Index/IndexDecl.cpp
+++ b/clang/lib/Index/IndexDecl.cpp
@@ -706,8 +706,9 @@ class IndexingDeclVisitor : public 
ConstDeclVisitor<IndexingDeclVisitor, bool> {
           handleTemplateArgumentLoc(TTP->getDefaultArgument(), Parent,
                                     TP->getLexicalDeclContext());
         if (auto *C = TTP->getTypeConstraint())
-          IndexCtx.handleReference(C->getNamedConcept(), 
C->getConceptNameLoc(),
-                                   Parent, TTP->getLexicalDeclContext());
+          IndexCtx.handleReference(C->getNamedConcept().getAsTemplateDecl(),
+                                   C->getConceptNameLoc(), Parent,
+                                   TTP->getLexicalDeclContext());
       } else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(TP)) {
         IndexCtx.indexTypeSourceInfo(NTTP->getTypeSourceInfo(), Parent);
         if (NTTP->hasDefaultArgument())
diff --git a/clang/lib/Index/IndexTypeSourceInfo.cpp 
b/clang/lib/Index/IndexTypeSourceInfo.cpp
index c9ad36b5406c5..6f599ababcaf5 100644
--- a/clang/lib/Index/IndexTypeSourceInfo.cpp
+++ b/clang/lib/Index/IndexTypeSourceInfo.cpp
@@ -82,7 +82,7 @@ class TypeIndexer : public RecursiveASTVisitor<TypeIndexer> {
   }
 
   bool VisitAutoTypeLoc(AutoTypeLoc TL) {
-    if (auto *C = TL.getNamedConcept())
+    if (auto *C = TL.getNamedConcept().getAsTemplateDecl())
       return IndexCtx.handleReference(C, TL.getConceptNameLoc(), Parent,
                                       ParentDC);
     return true;
diff --git a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp 
b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp
index 5c17f0ebf6fdc..ab1dc5c6ff39c 100644
--- a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp
+++ b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp
@@ -406,8 +406,8 @@ 
TemplateParameterListBuilder::constructConceptSpecializationExpr(
 
   // In the concept reference, ATALI is what adds the extra
   // TemplateArgument node underneath CSE
-  ConceptReference *CR =
-      ConceptReference::Create(Context, NNSLoc, Loc, DNI, CD, CD, ATALI);
+  ConceptReference *CR = ConceptReference::Create(Context, NNSLoc, Loc, DNI, 
CD,
+                                                  TemplateName(CD), ATALI);
 
   ConceptSpecializationExpr *CSE =
       ConceptSpecializationExpr::Create(Context, CR, ImplicitCSEDecl, &CS);
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 3e6266b8ac542..ff3d4b0a4b4c7 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -4723,7 +4723,8 @@ void Sema::checkCall(NamedDecl *FDecl, const 
FunctionProtoType *Proto,
 }
 
 void Sema::CheckConstrainedAuto(const AutoType *AutoT, SourceLocation Loc) {
-  if (TemplateDecl *Decl = AutoT->getTypeConstraintConcept()) {
+  if (TemplateDecl *Decl =
+          AutoT->getTypeConstraintConcept().getAsTemplateDecl()) {
     DiagnoseUseOfDecl(Decl, Loc);
   }
 }
diff --git a/clang/lib/Sema/SemaCodeComplete.cpp 
b/clang/lib/Sema/SemaCodeComplete.cpp
index 3b3c9a476421d..c5250acb6541d 100644
--- a/clang/lib/Sema/SemaCodeComplete.cpp
+++ b/clang/lib/Sema/SemaCodeComplete.cpp
@@ -5716,7 +5716,7 @@ class ConceptInfo {
       // For simplicity:
       // - we don't attempt to substitute int for A
       // - when T is used in other ways (like CD<T*>) we ignore it
-      ConceptDecl *CD = CSE->getNamedConcept();
+      ConceptDecl *CD = CSE->getConceptDecl();
       TemplateParameterList *Params = CD->getTemplateParameters();
       unsigned Index = 0;
       for (const auto &Arg : CSE->getTemplateArguments()) {
@@ -5949,7 +5949,7 @@ class ConceptInfo {
   static QualType deduceType(const TypeConstraint &T) {
     // Assume a same_as<T> return type constraint is std::same_as or 
equivalent.
     // In this case the return type is T.
-    DeclarationName DN = T.getNamedConcept()->getDeclName();
+    DeclarationName DN = 
T.getNamedConcept().getAsTemplateDecl()->getDeclName();
     if (DN.isIdentifier() && DN.getAsIdentifierInfo()->isStr("same_as"))
       if (const auto *Args = T.getTemplateArgsAsWritten())
         if (Args->getNumTemplateArgs() == 1) {
diff --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp
index 606cfe7bdcf73..514df9c754482 100644
--- a/clang/lib/Sema/SemaConcept.cpp
+++ b/clang/lib/Sema/SemaConcept.cpp
@@ -1045,7 +1045,8 @@ ExprResult ConstraintSatisfactionChecker::EvaluateSlow(
   // There's a concern that even with the same concept, they may not have the
   // same ConceptReference, if they come from modules.
   if (TopLevelConceptId &&
-      ConceptId->getNamedConcept() == TopLevelConceptId->getNamedConcept()) {
+      ConceptId->getNamedConcept().getAsTemplateDecl() ==
+          TopLevelConceptId->getNamedConcept().getAsTemplateDecl()) {
     for (auto &A : Ori->arguments())
       OutArgs.addArgument(A);
   } else if (S.SubstTemplateArguments(Ori->arguments(), *SubstitutedArgs,
@@ -1077,7 +1078,8 @@ ExprResult ConstraintSatisfactionChecker::EvaluateSlow(
 
   ExprResult SubstitutedConceptId = S.CheckConceptTemplateId(
       SS, ConceptId->getTemplateKWLoc(), ConceptId->getConceptNameInfo(),
-      ConceptId->getFoundDecl(), ConceptId->getNamedConcept(), &OutArgs,
+      ConceptId->getFoundDecl(),
+      ConceptId->getNamedConcept().getAsTemplateDecl(), &OutArgs,
       /*DoCheckConstraintSatisfaction=*/false);
 
   if (SubstitutedConceptId.isInvalid() || Trap.hasErrorOccurred())
@@ -1101,7 +1103,7 @@ ExprResult ConstraintSatisfactionChecker::Evaluate(
   Sema::InstantiatingTemplate InstTemplate(
       S, ConceptId->getBeginLoc(),
       Sema::InstantiatingTemplate::ConstraintsCheck{},
-      ConceptId->getNamedConcept(),
+      ConceptId->getNamedConcept().getAsTemplateDecl(),
       // We may have empty template arguments when checking non-dependent
       // nested constraint expressions.
       // In such cases, non-SFINAE errors would have already been diagnosed
@@ -1116,7 +1118,8 @@ ExprResult ConstraintSatisfactionChecker::Evaluate(
   unsigned Size = Satisfaction.Details.size();
 
   llvm::SaveAndRestore PushConceptDecl(
-      ParentConcept, cast<ConceptDecl>(ConceptId->getNamedConcept()));
+      ParentConcept,
+      cast<ConceptDecl>(ConceptId->getNamedConcept().getAsTemplateDecl()));
 
   ExprResult E = Evaluate(Constraint.getNormalizedConstraint(), MLTAL);
 
@@ -1342,7 +1345,7 @@ bool Sema::CheckConstraintSatisfaction(
 
   const NamedDecl *Owner = Template;
   if (TopLevelConceptId)
-    Owner = TopLevelConceptId->getNamedConcept();
+    Owner = TopLevelConceptId->getNamedConcept().getAsTemplateDecl();
 
   llvm::FoldingSetNodeID ID;
   ConstraintSatisfaction::Profile(ID, Context, Owner, FlattenedArgs);
@@ -1394,7 +1397,7 @@ SubstituteConceptsInConstraintExpression(Sema &S, const 
NamedDecl *D,
   // If any such substitution results in an invalid concept-id,
   // the program is ill-formed; no diagnostic is required.
 
-  ConceptDecl *Concept = CSE->getNamedConcept()->getCanonicalDecl();
+  ConceptDecl *Concept = CSE->getConceptDecl()->getCanonicalDecl();
   Sema::ArgPackSubstIndexRAII _(S, SubstIndex);
 
   const ASTTemplateArgumentListInfo *ArgsAsWritten =
@@ -1915,7 +1918,7 @@ static void diagnoseUnsatisfiedConceptIdExpr(Sema &S,
             
note_single_arg_concept_specialization_constraint_evaluated_to_false)
         << (int)First
         << Concept->getTemplateArgsAsWritten()->arguments()[0].getArgument()
-        << Concept->getNamedConcept();
+        << Concept->getNamedConcept().getAsTemplateDecl();
   } else {
     S.Diag(Loc, 
diag::note_concept_specialization_constraint_evaluated_to_false)
         << (int)First << Concept;
@@ -2325,14 +2328,14 @@ bool 
SubstituteParameterMappings::substitute(ConceptIdConstraint &CC) {
           ArgsAsWritten->arguments(), CC.getBeginLoc(), *MLTAL, Out))
     return true;
   Sema::CheckTemplateArgumentInfo CTAI;
-  if (SemaRef.CheckTemplateArgumentList(CSE->getNamedConcept(),
+  if (SemaRef.CheckTemplateArgumentList(CSE->getConceptDecl(),
                                         CSE->getConceptNameInfo().getLoc(), 
Out,
                                         /*DefaultArgs=*/{},
                                         /*PartialTemplateArgs=*/false, CTAI,
                                         /*UpdateArgsWithConversions=*/false))
     return true;
   auto TemplateArgs = *MLTAL;
-  TemplateArgs.replaceOutermostTemplateArguments(CSE->getNamedConcept(),
+  TemplateArgs.replaceOutermostTemplateArguments(CSE->getConceptDecl(),
                                                  CTAI.SugaredConverted);
   return SubstituteParameterMappings(SemaRef, &TemplateArgs, ArgsAsWritten,
                                      RemovePacksForFoldExpr)
@@ -2377,7 +2380,7 @@ bool 
SubstituteParameterMappings::substitute(NormalizedConstraint &N) {
         const_cast<ImplicitConceptSpecializationDecl *>(
             CSE->getSpecializationDecl()));
     SmallVector<TemplateArgument> InnerArgs(CSE->getTemplateArguments());
-    ConceptDecl *Concept = CSE->getNamedConcept();
+    ConceptDecl *Concept = CSE->getConceptDecl();
     if (RemovePacksForFoldExpr) {
       TemplateArgumentListInfo OutArgs;
       ArrayRef<TemplateArgumentLoc> InputArgLoc =
@@ -2490,7 +2493,7 @@ NormalizedConstraint 
*NormalizedConstraint::fromConstraintExpr(
       // Use canonical declarations to merge ConceptDecls across different
       // modules.
       SubNF = NormalizedConstraint::fromAssociatedConstraints(
-          S, CSE->getNamedConcept()->getCanonicalDecl(),
+          S, CSE->getConceptDecl()->getCanonicalDecl(),
           AssociatedConstraint(Res.get(), SubstIndex));
     else
       return nullptr;
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 1fde412749cc9..67289855685db 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -1296,12 +1296,13 @@ bool Sema::AttachTypeConstraint(NestedNameSpecifierLoc 
NS,
   if (ImmediatelyDeclaredConstraint.isInvalid())
     return true;
 
-  auto *CL = ConceptReference::Create(Context, /*NNS=*/NS,
-                                      /*TemplateKWLoc=*/SourceLocation{},
-                                      /*ConceptNameInfo=*/NameInfo,
-                                      /*FoundDecl=*/FoundDecl,
-                                      /*NamedConcept=*/NamedConcept,
-                                      /*ArgsWritten=*/ArgsAsWritten);
+  auto *CL =
+      ConceptReference::Create(Context, /*NNS=*/NS,
+                               /*TemplateKWLoc=*/SourceLocation{},
+                               /*ConceptNameInfo=*/NameInfo,
+                               /*FoundDecl=*/FoundDecl,
+                               /*NamedConcept=*/TemplateName(NamedConcept),
+                               /*ArgsWritten=*/ArgsAsWritten);
   ConstrainedParameter->setTypeConstraint(
       CL, ImmediatelyDeclaredConstraint.get(), std::nullopt);
   return false;
@@ -1330,9 +1331,9 @@ bool Sema::AttachTypeConstraint(AutoTypeLoc TL,
     return true;
   ExprResult ImmediatelyDeclaredConstraint = formImmediatelyDeclaredConstraint(
       *this, TL.getNestedNameSpecifierLoc(), TL.getConceptNameInfo(),
-      TL.getNamedConcept(), /*FoundDecl=*/TL.getFoundDecl(), TL.getLAngleLoc(),
-      TL.getRAngleLoc(), BuildDecltypeType(Ref),
-      OrigConstrainedParm->getLocation(),
+      TL.getNamedConcept().getAsTemplateDecl(),
+      /*FoundDecl=*/TL.getFoundDecl(), TL.getLAngleLoc(), TL.getRAngleLoc(),
+      BuildDecltypeType(Ref), OrigConstrainedParm->getLocation(),
       [&](TemplateArgumentListInfo &ConstraintArgs) {
         for (unsigned I = 0, C = TL.getNumArgs(); I != C; ++I)
           ConstraintArgs.addArgument(TL.getArgLoc(I));
@@ -4913,7 +4914,7 @@ ExprResult Sema::CheckConceptTemplateId(
   auto *CL = ConceptReference::Create(
       Context,
       SS.isSet() ? SS.getWithLocInContext(Context) : NestedNameSpecifierLoc{},
-      TemplateKWLoc, ConceptNameInfo, FoundDecl, NamedConcept,
+      TemplateKWLoc, ConceptNameInfo, FoundDecl, TemplateName(NamedConcept),
       ASTTemplateArgumentListInfo::Create(Context, *TemplateArgs));
 
   bool Error = false;
diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp 
b/clang/lib/Sema/SemaTemplateDeduction.cpp
index 21190031b95ea..8b9bc48bacd69 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -5350,7 +5350,8 @@ static bool CheckDeducedPlaceholderConstraints(Sema &S, 
const AutoType &Type,
                                                AutoTypeLoc TypeLoc,
                                                QualType Deduced) {
   ConstraintSatisfaction Satisfaction;
-  ConceptDecl *Concept = cast<ConceptDecl>(Type.getTypeConstraintConcept());
+  ConceptDecl *Concept =
+      cast<ConceptDecl>(Type.getTypeConstraintConcept().getAsTemplateDecl());
   TemplateArgumentListInfo TemplateArgs(TypeLoc.getLAngleLoc(),
                                         TypeLoc.getRAngleLoc());
   TemplateArgs.addArgument(
@@ -5376,9 +5377,11 @@ static bool CheckDeducedPlaceholderConstraints(Sema &S, 
const AutoType &Type,
     llvm::raw_string_ostream OS(Buf);
     OS << "'" << Concept->getName();
     if (TypeLoc.hasExplicitTemplateArgs()) {
-      printTemplateArgumentList(
-          OS, Type.getTypeConstraintArguments(), S.getPrintingPolicy(),
-          Type.getTypeConstraintConcept()->getTemplateParameters());
+      printTemplateArgumentList(OS, Type.getTypeConstraintArguments(),
+                                S.getPrintingPolicy(),
+                                Type.getTypeConstraintConcept()
+                                    .getAsTemplateDecl()
+                                    ->getTemplateParameters());
     }
     OS << "'";
     S.Diag(TypeLoc.getConceptNameLoc(),
diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp 
b/clang/lib/Sema/SemaTemplateInstantiate.cpp
index f107811be868f..21781f7474e56 100644
--- a/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -3158,7 +3158,7 @@ bool Sema::SubstTypeConstraint(
   }
   return AttachTypeConstraint(
       TC->getNestedNameSpecifierLoc(), TC->getConceptNameInfo(),
-      TC->getNamedConcept(),
+      TC->getNamedConcept().getAsTemplateDecl(),
       /*FoundDecl=*/TC->getConceptReference()->getFoundDecl(), &InstArgs, Inst,
       Inst->isParameterPack()
           ? cast<CXXFoldExpr>(TC->getImmediatelyDeclaredConstraint())
@@ -4560,8 +4560,7 @@ ExprResult Sema::SubstConceptTemplateArguments(
 
   MultiLevelTemplateArgumentList MLTALForConstraint =
       getTemplateInstantiationArgs(
-          CSE->getNamedConcept(),
-          CSE->getNamedConcept()->getLexicalDeclContext(),
+          CSE->getConceptDecl(), 
CSE->getConceptDecl()->getLexicalDeclContext(),
           /*Final=*/false,
           /*Innermost=*/NewArgList,
           /*RelativeToPrimary=*/true,
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index 42ef93b98aa0a..630720c56c903 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -1344,7 +1344,8 @@ static QualType ConvertDeclSpecToType(TypeProcessingState 
&state) {
       }
     }
     Result = S.Context.getAutoType(DeducedKind::Undeduced, QualType(), AutoKW,
-                                   TypeConstraintConcept, TemplateArgs);
+                                   TemplateName(TypeConstraintConcept),
+                                   TemplateArgs);
     break;
   }
 
@@ -3084,15 +3085,15 @@ InventTemplateParameter(TypeProcessingState &state, 
QualType T,
   // Create the TemplateTypeParmDecl here to retrieve the corresponding
   // template parameter type. Template parameters are temporarily added
   // to the TU until the associated TemplateDecl is created.
-  TemplateTypeParmDecl *InventedTemplateParam =
-      TemplateTypeParmDecl::Create(
-          S.Context, S.Context.getTranslationUnitDecl(),
-          /*KeyLoc=*/D.getDeclSpec().getTypeSpecTypeLoc(),
-          /*NameLoc=*/D.getIdentifierLoc(),
-          TemplateParameterDepth, AutoParameterPosition,
-          S.InventAbbreviatedTemplateParameterTypeName(
-              D.getIdentifier(), AutoParameterPosition), false,
-          IsParameterPack, /*HasTypeConstraint=*/Auto->isConstrained());
+  TemplateTypeParmDecl *InventedTemplateParam = TemplateTypeParmDecl::Create(
+      S.Context, S.Context.getTranslationUnitDecl(),
+      /*KeyLoc=*/D.getDeclSpec().getTypeSpecTypeLoc(),
+      /*NameLoc=*/D.getIdentifierLoc(), TemplateParameterDepth,
+      AutoParameterPosition,
+      S.InventAbbreviatedTemplateParameterTypeName(D.getIdentifier(),
+                                                   AutoParameterPosition),
+      false, IsParameterPack,
+      /*HasTypeConstraint=*/Auto->isConstrained());
   InventedTemplateParam->setImplicit();
   Info.TemplateParams.push_back(InventedTemplateParam);
 
@@ -3115,7 +3116,8 @@ InventTemplateParameter(TypeProcessingState &state, 
QualType T,
       if (!Invalid) {
         S.AttachTypeConstraint(
             AutoLoc.getNestedNameSpecifierLoc(), AutoLoc.getConceptNameInfo(),
-            AutoLoc.getNamedConcept(), /*FoundDecl=*/AutoLoc.getFoundDecl(),
+            AutoLoc.getNamedConcept().getAsTemplateDecl(),
+            /*FoundDecl=*/AutoLoc.getFoundDecl(),
             AutoLoc.hasExplicitTemplateArgs() ? &TAL : nullptr,
             InventedTemplateParam, D.getEllipsisLoc());
       }
@@ -6138,9 +6140,12 @@ namespace {
                                            TemplateId->NumArgs);
         SemaRef.translateTemplateArguments(TemplateArgsPtr, TemplateArgsInfo);
       }
-      DeclarationNameInfo DNI = DeclarationNameInfo(
-          TL.getTypePtr()->getTypeConstraintConcept()->getDeclName(),
-          TemplateId->TemplateNameLoc);
+      DeclarationNameInfo DNI =
+          DeclarationNameInfo(TL.getTypePtr()
+                                  ->getTypeConstraintConcept()
+                                  .getAsTemplateDecl()
+                                  ->getDeclName(),
+                              TemplateId->TemplateNameLoc);
 
       NamedDecl *FoundDecl;
       if (auto TN = TemplateId->Template.get();
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index b397447ee0e52..6ce9603f633d2 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -1145,8 +1145,9 @@ class TreeTransform {
                            AutoTypeKeyword Keyword,
                            ConceptDecl *TypeConstraintConcept,
                            ArrayRef<TemplateArgument> TypeConstraintArgs) {
-    return SemaRef.Context.getAutoType(
-        DK, DeducedAsType, Keyword, TypeConstraintConcept, TypeConstraintArgs);
+    return SemaRef.Context.getAutoType(DK, DeducedAsType, Keyword,
+                                       TemplateName(TypeConstraintConcept),
+                                       TypeConstraintArgs);
   }
 
   /// By default, builds a new DeducedTemplateSpecializationType with the given
@@ -7568,7 +7569,8 @@ QualType 
TreeTransform<Derived>::TransformAutoType(TypeLocBuilder &TLB,
   if (T->isConstrained()) {
     assert(TL.getConceptReference());
     NewCD = cast_or_null<ConceptDecl>(getDerived().TransformDecl(
-        TL.getConceptNameLoc(), T->getTypeConstraintConcept()));
+        TL.getConceptNameLoc(),
+        T->getTypeConstraintConcept().getAsTemplateDecl()));
 
     NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
     NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
@@ -7608,10 +7610,12 @@ QualType 
TreeTransform<Derived>::TransformAutoType(TypeLocBuilder &TLB,
   NewTL.setConceptReference(nullptr);
 
   if (T->isConstrained()) {
-    DeclarationNameInfo DNI = DeclarationNameInfo(
-        TL.getTypePtr()->getTypeConstraintConcept()->getDeclName(),
-        TL.getConceptNameLoc(),
-        TL.getTypePtr()->getTypeConstraintConcept()->getDeclName());
+    DeclarationName ConceptName = TL.getTypePtr()
+                                      ->getTypeConstraintConcept()
+                                      .getAsTemplateDecl()
+                                      ->getDeclName();
+    DeclarationNameInfo DNI =
+        DeclarationNameInfo(ConceptName, TL.getConceptNameLoc(), ConceptName);
     auto *CR = ConceptReference::Create(
         SemaRef.Context, NewNestedNameSpec, TL.getTemplateKWLoc(), DNI,
         TL.getFoundDecl(), TL.getTypePtr()->getTypeConstraintConcept(),
@@ -15629,7 +15633,7 @@ 
TreeTransform<Derived>::TransformConceptSpecializationExpr(
 
   return getDerived().RebuildConceptSpecializationExpr(
       E->getNestedNameSpecifierLoc(), E->getTemplateKWLoc(),
-      E->getConceptNameInfo(), E->getFoundDecl(), E->getNamedConcept(),
+      E->getConceptNameInfo(), E->getFoundDecl(), E->getConceptDecl(),
       &TransArgs);
 }
 
diff --git a/clang/lib/Serialization/ASTReader.cpp 
b/clang/lib/Serialization/ASTReader.cpp
index c4c4b22f85093..68021fb05be16 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -7665,7 +7665,7 @@ ConceptReference *ASTRecordReader::readConceptReference() 
{
   auto TemplateKWLoc = readSourceLocation();
   auto ConceptNameLoc = readDeclarationNameInfo();
   auto FoundDecl = readDeclAs<NamedDecl>();
-  auto NamedConcept = readDeclAs<ConceptDecl>();
+  auto NamedConcept = readTemplateName();
   auto *CR = ConceptReference::Create(
       getContext(), NNS, TemplateKWLoc, ConceptNameLoc, FoundDecl, 
NamedConcept,
       (readBool() ? readASTTemplateArgumentListInfo() : nullptr));
diff --git a/clang/lib/Serialization/ASTWriter.cpp 
b/clang/lib/Serialization/ASTWriter.cpp
index 4e9af7c721d2f..5d5f3f473fd0d 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -538,7 +538,7 @@ void ASTRecordWriter::AddConceptReference(const 
ConceptReference *CR) {
   AddSourceLocation(CR->getTemplateKWLoc());
   AddDeclarationNameInfo(CR->getConceptNameInfo());
   AddDeclRef(CR->getFoundDecl());
-  AddDeclRef(CR->getNamedConcept());
+  AddTemplateName(CR->getNamedConcept());
   push_back(CR->getTemplateArgsAsWritten() != nullptr);
   if (CR->getTemplateArgsAsWritten())
     AddASTTemplateArgumentListInfo(CR->getTemplateArgsAsWritten());
diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp
index 47d6d2cb51efd..2c5e799d12f18 100644
--- a/clang/tools/libclang/CIndex.cpp
+++ b/clang/tools/libclang/CIndex.cpp
@@ -1344,9 +1344,8 @@ bool CursorVisitor::VisitTypeConstraint(const 
TypeConstraint &TC) {
     if (VisitNestedNameSpecifierLoc(TC.getNestedNameSpecifierLoc()))
       return true;
   }
-  if (TC.getNamedConcept()) {
-    if (Visit(MakeCursorTemplateRef(TC.getNamedConcept(),
-                                    TC.getConceptNameLoc(), TU)))
+  if (TemplateDecl *TD = TC.getNamedConcept().getAsTemplateDecl()) {
+    if (Visit(MakeCursorTemplateRef(TD, TC.getConceptNameLoc(), TU)))
       return true;
   }
   if (auto Args = TC.getTemplateArgsAsWritten()) {
@@ -1805,9 +1804,8 @@ bool CursorVisitor::VisitAutoTypeLoc(AutoTypeLoc TL) {
 
   if (TL.isConstrained()) {
     if (auto *CR = TL.getConceptReference()) {
-      if (CR->getNamedConcept()) {
-        return Visit(MakeCursorTemplateRef(CR->getNamedConcept(),
-                                           CR->getConceptNameLoc(), TU));
+      if (TemplateDecl *TD = CR->getNamedConcept().getAsTemplateDecl()) {
+        return Visit(MakeCursorTemplateRef(TD, CR->getConceptNameLoc(), TU));
       }
     }
   }
@@ -3993,8 +3991,8 @@ bool CursorVisitor::RunVisitorWorkList(VisitorWorkList 
&WL) {
           return true;
       }
 
-      if (E->getNamedConcept() &&
-          Visit(MakeCursorTemplateRef(E->getNamedConcept(),
+      if (E->getNamedConcept().getAsTemplateDecl() &&
+          Visit(MakeCursorTemplateRef(E->getConceptDecl(),
                                       E->getConceptNameLoc(), TU)))
         return true;
 

>From 7e42b78d8ef352f61dd62f94a0aabad268d7eceb Mon Sep 17 00:00:00 2001
From: Corentin Jabot <[email protected]>
Date: Fri, 21 Aug 2026 11:20:06 +0200
Subject: [PATCH 2/2] Assert that the TemplateName is a TemplateDecl

---
 clang/lib/AST/ASTConcept.cpp | 3 +++
 clang/lib/AST/Type.cpp       | 3 +++
 2 files changed, 6 insertions(+)

diff --git a/clang/lib/AST/ASTConcept.cpp b/clang/lib/AST/ASTConcept.cpp
index c843aa797f9ba..6a90d214de7fd 100644
--- a/clang/lib/AST/ASTConcept.cpp
+++ b/clang/lib/AST/ASTConcept.cpp
@@ -95,6 +95,9 @@ ConceptReference::Create(const ASTContext &C, 
NestedNameSpecifierLoc NNS,
                          DeclarationNameInfo ConceptNameInfo,
                          NamedDecl *FoundDecl, TemplateName NamedConcept,
                          const ASTTemplateArgumentListInfo *ArgsAsWritten) {
+
+  assert(NamedConcept.getKind() == TemplateName::Template);
+
   return new (C) ConceptReference(NNS, TemplateKWLoc, ConceptNameInfo,
                                   FoundDecl, NamedConcept, ArgsAsWritten);
 }
diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index fa346856a260c..8823843222308 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -5748,6 +5748,9 @@ AutoType::AutoType(DeducedKind DK, QualType 
DeducedAsTypeOrCanon,
   this->TypeConstraintConcept = TypeConstraintConcept;
   assert(!TypeConstraintConcept.isNull() || AutoTypeBits.NumArgs == 0);
   if (!TypeConstraintConcept.isNull()) {
+
+    assert(TypeConstraintConcept.getKind() == TemplateName::Template);
+
     auto Dep = toTypeDependence(TypeConstraintConcept.getDependence());
 
     auto *ArgBuffer =

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to