[clang] [clang-tools-extra] Revert "[clang] Improved canonicalization for template specialization types" (PR #135354)

via cfe-commits cfe-commits at lists.llvm.org
Fri Apr 11 05:15:05 PDT 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clangd

Author: Dmitry Vasilyev (slydiman)

<details>
<summary>Changes</summary>

Reverts llvm/llvm-project#<!-- -->135119 because of the assert in ASTContext.cpp, line 5619.
See #<!-- -->135352 for details.



---

Patch is 89.49 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/135354.diff


28 Files Affected:

- (modified) clang-tools-extra/clangd/AST.cpp (+1-2) 
- (modified) clang/docs/ReleaseNotes.rst (-2) 
- (modified) clang/include/clang/AST/ASTContext.h (+15-31) 
- (modified) clang/include/clang/AST/PropertiesBase.td (+1-4) 
- (modified) clang/include/clang/AST/TemplateBase.h (+2-11) 
- (modified) clang/include/clang/AST/Type.h (+4-3) 
- (modified) clang/include/clang/AST/TypeProperties.td (+25-5) 
- (modified) clang/lib/AST/ASTContext.cpp (+107-129) 
- (modified) clang/lib/AST/ASTDiagnostic.cpp (+4-4) 
- (modified) clang/lib/AST/ASTImporter.cpp (+13-21) 
- (modified) clang/lib/AST/DeclTemplate.cpp (+2-5) 
- (modified) clang/lib/AST/QualTypeNames.cpp (+1-2) 
- (modified) clang/lib/AST/TemplateBase.cpp (+4-15) 
- (modified) clang/lib/AST/Type.cpp (+23-27) 
- (modified) clang/lib/Sema/SemaCXXScopeSpec.cpp (+10-8) 
- (modified) clang/lib/Sema/SemaExpr.cpp (+3-17) 
- (modified) clang/lib/Sema/SemaLookup.cpp (+1-2) 
- (modified) clang/lib/Sema/SemaTemplate.cpp (+84-78) 
- (modified) clang/lib/Sema/SemaTemplateDeduction.cpp (+18-27) 
- (modified) clang/lib/Sema/SemaTemplateInstantiateDecl.cpp (+5-6) 
- (modified) clang/lib/Sema/SemaTemplateVariadic.cpp (+1-2) 
- (modified) clang/lib/Sema/TreeTransform.h (+4-9) 
- (modified) clang/test/CXX/class.derived/class.derived.general/p2.cpp (+1-1) 
- (modified) clang/test/CXX/temp/temp.decls/temp.class.spec/p6.cpp (+2-2) 
- (modified) clang/test/SemaCXX/undefined-partial-specialization.cpp (+1-1) 
- (modified) clang/test/SemaTemplate/make_integer_seq.cpp (+45-16) 
- (modified) clang/test/SemaTemplate/type_pack_element.cpp (+42-15) 
- (modified) clang/unittests/AST/TypePrinterTest.cpp (+3-3) 


``````````diff
diff --git a/clang-tools-extra/clangd/AST.cpp b/clang-tools-extra/clangd/AST.cpp
index 3b991e5e9013f..66b587f00ff4a 100644
--- a/clang-tools-extra/clangd/AST.cpp
+++ b/clang-tools-extra/clangd/AST.cpp
@@ -439,8 +439,7 @@ QualType declaredType(const TypeDecl *D) {
   if (const auto *CTSD = llvm::dyn_cast<ClassTemplateSpecializationDecl>(D))
     if (const auto *Args = CTSD->getTemplateArgsAsWritten())
       return Context.getTemplateSpecializationType(
-          TemplateName(CTSD->getSpecializedTemplate()), Args->arguments(),
-          /*CanonicalArgs=*/std::nullopt);
+          TemplateName(CTSD->getSpecializedTemplate()), Args->arguments());
   return Context.getTypeDeclType(D);
 }
 
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 69c7369755c67..db8dad268a8a7 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -301,8 +301,6 @@ Improvements to Clang's diagnostics
 - Clang now better preserves the sugared types of pointers to member.
 - Clang now better preserves the presence of the template keyword with dependent
   prefixes.
-- Clang now in more cases avoids printing 'type-parameter-X-X' instead of the name of
-  the template parameter.
 - Clang now respects the current language mode when printing expressions in
   diagnostics. This fixes a bunch of `bool` being printed as `_Bool`, and also
   a bunch of HLSL types being printed as their C++ equivalents.
diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h
index b8ea2af9215d2..b1e6344576eb5 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -367,6 +367,9 @@ class ASTContext : public RefCountedBase<ASTContext> {
                                      const ASTContext&>
     CanonTemplateTemplateParms;
 
+  TemplateTemplateParmDecl *
+    getCanonicalTemplateTemplateParmDecl(TemplateTemplateParmDecl *TTP) const;
+
   /// The typedef for the __int128_t type.
   mutable TypedefDecl *Int128Decl = nullptr;
 
@@ -1808,26 +1811,22 @@ class ASTContext : public RefCountedBase<ASTContext> {
                           bool ParameterPack,
                           TemplateTypeParmDecl *ParmDecl = nullptr) const;
 
-  QualType getCanonicalTemplateSpecializationType(
-      TemplateName T, ArrayRef<TemplateArgument> CanonicalArgs) const;
+  QualType getTemplateSpecializationType(TemplateName T,
+                                         ArrayRef<TemplateArgument> Args,
+                                         QualType Canon = QualType()) const;
 
   QualType
-  getTemplateSpecializationType(TemplateName T,
-                                ArrayRef<TemplateArgument> SpecifiedArgs,
-                                ArrayRef<TemplateArgument> CanonicalArgs,
-                                QualType Underlying = QualType()) const;
+  getCanonicalTemplateSpecializationType(TemplateName T,
+                                         ArrayRef<TemplateArgument> Args) const;
 
-  QualType
-  getTemplateSpecializationType(TemplateName T,
-                                ArrayRef<TemplateArgumentLoc> SpecifiedArgs,
-                                ArrayRef<TemplateArgument> CanonicalArgs,
-                                QualType Canon = QualType()) const;
+  QualType getTemplateSpecializationType(TemplateName T,
+                                         ArrayRef<TemplateArgumentLoc> Args,
+                                         QualType Canon = QualType()) const;
 
-  TypeSourceInfo *getTemplateSpecializationTypeInfo(
-      TemplateName T, SourceLocation TLoc,
-      const TemplateArgumentListInfo &SpecifiedArgs,
-      ArrayRef<TemplateArgument> CanonicalArgs,
-      QualType Canon = QualType()) const;
+  TypeSourceInfo *
+  getTemplateSpecializationTypeInfo(TemplateName T, SourceLocation TLoc,
+                                    const TemplateArgumentListInfo &Args,
+                                    QualType Canon = QualType()) const;
 
   QualType getParenType(QualType NamedType) const;
 
@@ -2943,21 +2942,6 @@ class ASTContext : public RefCountedBase<ASTContext> {
   TemplateArgument getCanonicalTemplateArgument(const TemplateArgument &Arg)
     const;
 
-  /// Canonicalize the given template argument list.
-  ///
-  /// Returns true if any arguments were non-canonical, false otherwise.
-  bool
-  canonicalizeTemplateArguments(MutableArrayRef<TemplateArgument> Args) const;
-
-  /// Canonicalize the given TemplateTemplateParmDecl.
-  TemplateTemplateParmDecl *
-  getCanonicalTemplateTemplateParmDecl(TemplateTemplateParmDecl *TTP) const;
-
-  TemplateTemplateParmDecl *findCanonicalTemplateTemplateParmDeclInternal(
-      TemplateTemplateParmDecl *TTP) const;
-  TemplateTemplateParmDecl *insertCanonicalTemplateTemplateParmDeclInternal(
-      TemplateTemplateParmDecl *CanonTTP) const;
-
   /// Type Query functions.  If the type is an instance of the specified class,
   /// return the Type pointer for the underlying maximally pretty type.  This
   /// is a member of ASTContext because this may need to do some amount of
diff --git a/clang/include/clang/AST/PropertiesBase.td b/clang/include/clang/AST/PropertiesBase.td
index 33336d57b6298..90537d47dd9c9 100644
--- a/clang/include/clang/AST/PropertiesBase.td
+++ b/clang/include/clang/AST/PropertiesBase.td
@@ -877,14 +877,11 @@ let Class = PropertyTypeCase<TemplateArgument, "Expression"> in {
   def : Property<"expression", ExprRef> {
     let Read = [{ node.getAsExpr() }];
   }
-  def : Property<"IsCanonical", Bool> {
-    let Read = [{ node.isCanonicalExpr() }];
-  }
   def : Property<"isDefaulted", Bool> {
     let Read = [{ node.getIsDefaulted() }];
   }
   def : Creator<[{
-    return TemplateArgument(expression, IsCanonical, isDefaulted);
+    return TemplateArgument(expression, isDefaulted);
   }]>;
 }
 let Class = PropertyTypeCase<TemplateArgument, "Pack"> in {
diff --git a/clang/include/clang/AST/TemplateBase.h b/clang/include/clang/AST/TemplateBase.h
index 279feb858e665..bea624eb04942 100644
--- a/clang/include/clang/AST/TemplateBase.h
+++ b/clang/include/clang/AST/TemplateBase.h
@@ -167,8 +167,6 @@ class TemplateArgument {
     unsigned Kind : 31;
     LLVM_PREFERRED_TYPE(bool)
     unsigned IsDefaulted : 1;
-    LLVM_PREFERRED_TYPE(bool)
-    unsigned IsCanonicalExpr : 1;
     uintptr_t V;
   };
   union {
@@ -189,8 +187,7 @@ class TemplateArgument {
 
 public:
   /// Construct an empty, invalid template argument.
-  constexpr TemplateArgument()
-      : TypeOrValue{Null, /*IsDefaulted=*/0, /*IsCanonicalExpr=*/0, /*V=*/0} {}
+  constexpr TemplateArgument() : TypeOrValue({Null, 0, /* IsDefaulted */ 0}) {}
 
   /// Construct a template type argument.
   TemplateArgument(QualType T, bool isNullPtr = false,
@@ -265,10 +262,9 @@ class TemplateArgument {
   /// This form of template argument only occurs in template argument
   /// lists used for dependent types and for expression; it will not
   /// occur in a non-dependent, canonical template argument list.
-  TemplateArgument(Expr *E, bool IsCanonical, bool IsDefaulted = false) {
+  explicit TemplateArgument(Expr *E, bool IsDefaulted = false) {
     TypeOrValue.Kind = Expression;
     TypeOrValue.IsDefaulted = IsDefaulted;
-    TypeOrValue.IsCanonicalExpr = IsCanonical;
     TypeOrValue.V = reinterpret_cast<uintptr_t>(E);
   }
 
@@ -411,11 +407,6 @@ class TemplateArgument {
     return reinterpret_cast<Expr *>(TypeOrValue.V);
   }
 
-  bool isCanonicalExpr() const {
-    assert(getKind() == Expression && "Unexpected kind");
-    return TypeOrValue.IsCanonicalExpr;
-  }
-
   /// Iterator that traverses the elements of a template argument pack.
   using pack_iterator = const TemplateArgument *;
 
diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index dc57170bf9160..9f6189440fabf 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -6676,9 +6676,10 @@ class TemplateSpecializationType : public Type, public llvm::FoldingSetNode {
   /// replacement must, recursively, be one of these).
   TemplateName Template;
 
-  TemplateSpecializationType(TemplateName T, bool IsAlias,
+  TemplateSpecializationType(TemplateName T,
                              ArrayRef<TemplateArgument> Args,
-                             QualType Underlying);
+                             QualType Canon,
+                             QualType Aliased);
 
 public:
   /// Determine whether any of the given template arguments are dependent.
@@ -6746,7 +6747,7 @@ class TemplateSpecializationType : public Type, public llvm::FoldingSetNode {
 
   void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx);
   static void Profile(llvm::FoldingSetNodeID &ID, TemplateName T,
-                      ArrayRef<TemplateArgument> Args, QualType Underlying,
+                      ArrayRef<TemplateArgument> Args,
                       const ASTContext &Context);
 
   static bool classof(const Type *T) {
diff --git a/clang/include/clang/AST/TypeProperties.td b/clang/include/clang/AST/TypeProperties.td
index 3bf9239e9cbf5..66d490850678a 100644
--- a/clang/include/clang/AST/TypeProperties.td
+++ b/clang/include/clang/AST/TypeProperties.td
@@ -737,19 +737,39 @@ let Class = DependentAddressSpaceType in {
 }
 
 let Class = TemplateSpecializationType in {
+  def : Property<"dependent", Bool> {
+    let Read = [{ node->isDependentType() }];
+  }
   def : Property<"templateName", TemplateName> {
     let Read = [{ node->getTemplateName() }];
   }
-  def : Property<"args", Array<TemplateArgument>> {
+  def : Property<"templateArguments", Array<TemplateArgument>> {
     let Read = [{ node->template_arguments() }];
   }
-  def : Property<"UnderlyingType", QualType> {
-    let Read = [{ node->isCanonicalUnqualified() ? QualType() :
-                                                   node->desugar() }];
+  def : Property<"underlyingType", Optional<QualType>> {
+    let Read = [{
+      node->isTypeAlias()
+        ? std::optional<QualType>(node->getAliasedType())
+        : node->isCanonicalUnqualified()
+            ? std::nullopt
+            : std::optional<QualType>(node->getCanonicalTypeInternal())
+    }];
   }
 
   def : Creator<[{
-    return ctx.getTemplateSpecializationType(templateName, args, std::nullopt, UnderlyingType);
+    QualType result;
+    if (!underlyingType) {
+      result = ctx.getCanonicalTemplateSpecializationType(templateName,
+                                                          templateArguments);
+    } else {
+      result = ctx.getTemplateSpecializationType(templateName,
+                                                 templateArguments,
+                                                 *underlyingType);
+    }
+    if (dependent)
+      const_cast<Type *>(result.getTypePtr())
+          ->addDependence(TypeDependence::DependentInstantiation);
+    return result;
   }]>;
 }
 
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index b8e6245230475..00e2fa267a460 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -844,31 +844,6 @@ ASTContext::getCanonicalTemplateTemplateParmDecl(
   return CanonTTP;
 }
 
-TemplateTemplateParmDecl *
-ASTContext::findCanonicalTemplateTemplateParmDeclInternal(
-    TemplateTemplateParmDecl *TTP) const {
-  llvm::FoldingSetNodeID ID;
-  CanonicalTemplateTemplateParm::Profile(ID, *this, TTP);
-  void *InsertPos = nullptr;
-  CanonicalTemplateTemplateParm *Canonical =
-      CanonTemplateTemplateParms.FindNodeOrInsertPos(ID, InsertPos);
-  return Canonical ? Canonical->getParam() : nullptr;
-}
-
-TemplateTemplateParmDecl *
-ASTContext::insertCanonicalTemplateTemplateParmDeclInternal(
-    TemplateTemplateParmDecl *CanonTTP) const {
-  llvm::FoldingSetNodeID ID;
-  CanonicalTemplateTemplateParm::Profile(ID, *this, CanonTTP);
-  void *InsertPos = nullptr;
-  if (auto *Existing =
-          CanonTemplateTemplateParms.FindNodeOrInsertPos(ID, InsertPos))
-    return Existing->getParam();
-  CanonTemplateTemplateParms.InsertNode(
-      new (*this) CanonicalTemplateTemplateParm(CanonTTP), InsertPos);
-  return CanonTTP;
-}
-
 /// Check if a type can have its sanitizer instrumentation elided based on its
 /// presence within an ignorelist.
 bool ASTContext::isTypeIgnoredBySanitizer(const SanitizerMask &Mask,
@@ -3108,19 +3083,12 @@ static auto getCanonicalTemplateArguments(const ASTContext &C,
                                           ArrayRef<TemplateArgument> Args,
                                           bool &AnyNonCanonArgs) {
   SmallVector<TemplateArgument, 16> CanonArgs(Args);
-  AnyNonCanonArgs |= C.canonicalizeTemplateArguments(CanonArgs);
-  return CanonArgs;
-}
-
-bool ASTContext::canonicalizeTemplateArguments(
-    MutableArrayRef<TemplateArgument> Args) const {
-  bool AnyNonCanonArgs = false;
-  for (auto &Arg : Args) {
+  for (auto &Arg : CanonArgs) {
     TemplateArgument OrigArg = Arg;
-    Arg = getCanonicalTemplateArgument(Arg);
+    Arg = C.getCanonicalTemplateArgument(Arg);
     AnyNonCanonArgs |= !Arg.structurallyEquals(OrigArg);
   }
-  return AnyNonCanonArgs;
+  return CanonArgs;
 }
 
 //===----------------------------------------------------------------------===//
@@ -5570,121 +5538,132 @@ QualType ASTContext::getTemplateTypeParmType(unsigned Depth, unsigned Index,
   return QualType(TypeParm, 0);
 }
 
-TypeSourceInfo *ASTContext::getTemplateSpecializationTypeInfo(
-    TemplateName Name, SourceLocation NameLoc,
-    const TemplateArgumentListInfo &SpecifiedArgs,
-    ArrayRef<TemplateArgument> CanonicalArgs, QualType Underlying) const {
-  QualType TST = getTemplateSpecializationType(Name, SpecifiedArgs.arguments(),
-                                               CanonicalArgs, Underlying);
+TypeSourceInfo *
+ASTContext::getTemplateSpecializationTypeInfo(TemplateName Name,
+                                              SourceLocation NameLoc,
+                                        const TemplateArgumentListInfo &Args,
+                                              QualType Underlying) const {
+  assert(!Name.getAsDependentTemplateName() &&
+         "No dependent template names here!");
+  QualType TST =
+      getTemplateSpecializationType(Name, Args.arguments(), Underlying);
 
   TypeSourceInfo *DI = CreateTypeSourceInfo(TST);
   TemplateSpecializationTypeLoc TL =
       DI->getTypeLoc().castAs<TemplateSpecializationTypeLoc>();
   TL.setTemplateKeywordLoc(SourceLocation());
   TL.setTemplateNameLoc(NameLoc);
-  TL.setLAngleLoc(SpecifiedArgs.getLAngleLoc());
-  TL.setRAngleLoc(SpecifiedArgs.getRAngleLoc());
+  TL.setLAngleLoc(Args.getLAngleLoc());
+  TL.setRAngleLoc(Args.getRAngleLoc());
   for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i)
-    TL.setArgLocInfo(i, SpecifiedArgs[i].getLocInfo());
+    TL.setArgLocInfo(i, Args[i].getLocInfo());
   return DI;
 }
 
-QualType ASTContext::getTemplateSpecializationType(
-    TemplateName Template, ArrayRef<TemplateArgumentLoc> SpecifiedArgs,
-    ArrayRef<TemplateArgument> CanonicalArgs, QualType Underlying) const {
-  SmallVector<TemplateArgument, 4> SpecifiedArgVec;
-  SpecifiedArgVec.reserve(SpecifiedArgs.size());
-  for (const TemplateArgumentLoc &Arg : SpecifiedArgs)
-    SpecifiedArgVec.push_back(Arg.getArgument());
+QualType
+ASTContext::getTemplateSpecializationType(TemplateName Template,
+                                          ArrayRef<TemplateArgumentLoc> Args,
+                                          QualType Underlying) const {
+  assert(!Template.getAsDependentTemplateName() &&
+         "No dependent template names here!");
 
-  return getTemplateSpecializationType(Template, SpecifiedArgVec, CanonicalArgs,
-                                       Underlying);
+  SmallVector<TemplateArgument, 4> ArgVec;
+  ArgVec.reserve(Args.size());
+  for (const TemplateArgumentLoc &Arg : Args)
+    ArgVec.push_back(Arg.getArgument());
+
+  return getTemplateSpecializationType(Template, ArgVec, Underlying);
 }
 
-[[maybe_unused]] static bool
-hasAnyPackExpansions(ArrayRef<TemplateArgument> Args) {
+#ifndef NDEBUG
+static bool hasAnyPackExpansions(ArrayRef<TemplateArgument> Args) {
   for (const TemplateArgument &Arg : Args)
     if (Arg.isPackExpansion())
       return true;
-  return false;
-}
 
-QualType ASTContext::getCanonicalTemplateSpecializationType(
-    TemplateName Template, ArrayRef<TemplateArgument> Args) const {
-  assert(Template ==
-         getCanonicalTemplateName(Template, /*IgnoreDeduced=*/true));
-  assert(!Args.empty());
-#ifndef NDEBUG
-  for (const auto &Arg : Args)
-    assert(Arg.structurallyEquals(getCanonicalTemplateArgument(Arg)));
-#endif
-
-  llvm::FoldingSetNodeID ID;
-  TemplateSpecializationType::Profile(ID, Template, Args, QualType(), *this);
-  void *InsertPos = nullptr;
-  if (auto *T = TemplateSpecializationTypes.FindNodeOrInsertPos(ID, InsertPos))
-    return QualType(T, 0);
-
-  void *Mem = Allocate(sizeof(TemplateSpecializationType) +
-                           sizeof(TemplateArgument) * Args.size(),
-                       alignof(TemplateSpecializationType));
-  auto *Spec = new (Mem)
-      TemplateSpecializationType(Template, /*IsAlias=*/false, Args, QualType());
-  assert(Spec->isDependentType() &&
-         "canonical template specialization must be dependent");
-  Types.push_back(Spec);
-  TemplateSpecializationTypes.InsertNode(Spec, InsertPos);
-  return QualType(Spec, 0);
+  return true;
 }
+#endif
 
-QualType ASTContext::getTemplateSpecializationType(
-    TemplateName Template, ArrayRef<TemplateArgument> SpecifiedArgs,
-    ArrayRef<TemplateArgument> CanonicalArgs, QualType Underlying) const {
-  assert(!Template.getUnderlying().getAsDependentTemplateName() &&
+QualType
+ASTContext::getTemplateSpecializationType(TemplateName Template,
+                                          ArrayRef<TemplateArgument> Args,
+                                          QualType Underlying) const {
+  assert(!Template.getAsDependentTemplateName() &&
          "No dependent template names here!");
 
   const auto *TD = Template.getAsTemplateDecl(/*IgnoreDeduced=*/true);
   bool IsTypeAlias = TD && TD->isTypeAlias();
-  if (Underlying.isNull()) {
-    TemplateName CanonTemplate =
-        getCanonicalTemplateName(Template, /*IgnoreDeduced=*/true);
-    bool NonCanonical = Template != CanonTemplate;
-    SmallVector<TemplateArgument, 4> CanonArgsVec;
-    if (CanonicalArgs.empty()) {
-      CanonArgsVec = SmallVector<TemplateArgument, 4>(SpecifiedArgs);
-      NonCanonical |= canonicalizeTemplateArguments(CanonArgsVec);
-      CanonicalArgs = CanonArgsVec;
-    } else {
-      NonCanonical |= !llvm::equal(
-          SpecifiedArgs, CanonicalArgs,
-          [](const TemplateArgument &A, const TemplateArgument &B) {
-            return A.structurallyEquals(B);
-          });
-    }
-
-    // We can get here with an alias template when the specialization
-    // contains a pack expansion that does not match up with a parameter
-    // pack, or a builtin template which cannot be resolved due to dependency.
-    assert((!isa_and_nonnull<TypeAliasTemplateDecl>(TD) ||
-            hasAnyPackExpansions(CanonicalArgs)) &&
+  QualType CanonType;
+  if (!Underlying.isNull())
+    CanonType = getCanonicalType(Underlying);
+  else {
+    // We can get here with an alias template when the specialization contains
+    // a pack expansion that does not match up with a parameter pack.
+    assert((!IsTypeAlias || hasAnyPackExpansions(Args)) &&
            "Caller must compute aliased type");
     IsTypeAlias = false;
-
-    Underlying =
-        getCanonicalTemplateSpecializationType(CanonTemplate, CanonicalArgs);
-    if (!NonCanonical)
-      return Underlying;
+    CanonType = getCanonicalTemplateSpecializationType(Template, Args);
   }
+
+  // Allocate the (non-canonical) template specialization type, but don't
+  // try to unique it: these types typically have location information that
+  // we don't unique and don't want to lose.
   void *Mem = Allocate(sizeof(TemplateSpecializationType) +
-                           sizeof(TemplateArgument) * SpecifiedArgs.size() +
+                           sizeof(TemplateArgument) * Args.size() +
                            (IsTypeAlias ? sizeof(QualType) : 0),
                        alignof(TemplateSpecializationType));
-  auto *Spec = new (Mem) TemplateSpecializationType(Template, IsTypeAlias,
-                                                    SpecifiedArgs, Underly...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/135354


More information about the cfe-commits mailing list