mizvekov created this revision.
Herald added a subscriber: jeroen.dobbelaere.
Herald added a project: All.
mizvekov requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

We change the template specialization of __make_integer_seq to
be an alias to a synthesized template specialization type of the
underlying template, making the resulting type correctly represent
the template arguments used to specialize the underlying template.

When performing member access on the resulting type, it's now
possible to map from a Subst* node to the template argument
as-written used in a regular fashion, without special casing.

Depends on D133261 <https://reviews.llvm.org/D133261>

Signed-off-by: Matheus Izvekov <mizve...@gmail.com>


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D133262

Files:
  clang/include/clang/AST/ASTContext.h
  clang/include/clang/AST/DeclTemplate.h
  clang/lib/AST/ASTContext.cpp
  clang/lib/AST/DeclTemplate.cpp
  clang/lib/CodeGen/CGDebugInfo.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/test/SemaTemplate/make_integer_seq.cpp

Index: clang/test/SemaTemplate/make_integer_seq.cpp
===================================================================
--- clang/test/SemaTemplate/make_integer_seq.cpp
+++ clang/test/SemaTemplate/make_integer_seq.cpp
@@ -5,7 +5,7 @@
 using test1 = __make_integer_seq<A, int, 1>;
 //      CHECK: |-TypeAliasDecl 0x{{[0-9A-Fa-f]+}} <line:5:1, col:43> col:7 test1 '__make_integer_seq<A, int, 1>':'A<int, 0>'
 // CHECK-NEXT: | `-ElaboratedType 0x{{[0-9A-Fa-f]+}} '__make_integer_seq<A, int, 1>' sugar
-// CHECK-NEXT: |   `-TemplateSpecializationType 0x{{[0-9A-Fa-f]+}} '__make_integer_seq<A, int, 1>' sugar __make_integer_seq
+// CHECK-NEXT: |   `-TemplateSpecializationType 0x{{[0-9A-Fa-f]+}} '__make_integer_seq<A, int, 1>' sugar alias __make_integer_seq
 // CHECK-NEXT: |     |-TemplateArgument template A
 // CHECK-NEXT: |     |-TemplateArgument type 'int'
 // CHECK-NEXT: |     | `-BuiltinType 0x{{[0-9A-Fa-f]+}} 'int'
@@ -13,12 +13,22 @@
 // CHECK-NEXT: |     | `-ConstantExpr 0x{{[0-9A-Fa-f]+}} <col:42> 'int'
 // CHECK-NEXT: |     |   |-value: Int 1
 // CHECK-NEXT: |     |   `-IntegerLiteral 0x{{[0-9A-Fa-f]+}} <col:42> 'int' 1
-// CHECK-NEXT: |     `-RecordType 0x{{[0-9A-Fa-f]+}} 'A<int, 0>'
-// CHECK-NEXT: |       `-ClassTemplateSpecialization 0x{{[0-9A-Fa-f]+}} 'A'
+// CHECK-NEXT: |     `-TemplateSpecializationType 0x{{[0-9A-Fa-f]+}} 'A<int, 0>' sugar A
+// CHECK-NEXT: |       |-TemplateArgument type 'int':'int'
+// CHECK-NEXT: |       | `-SubstTemplateTypeParmType 0x{{[0-9A-Fa-f]+}} 'int' sugar
+// CHECK-NEXT: |       |   |-TemplateTypeParmType 0x{{[0-9A-Fa-f]+}} 'auto' dependent depth 0 index 1
+// CHECK-NEXT: |       |   | `-TemplateTypeParm 0x{{[0-9A-Fa-f]+}} ''
+// CHECK-NEXT: |       |   `-BuiltinType 0x{{[0-9A-Fa-f]+}} 'int'
+// CHECK-NEXT: |       |-TemplateArgument expr
+// CHECK-NEXT: |       | `-ConstantExpr 0x{{[0-9A-Fa-f]+}} <col:42> 'int'
+// CHECK-NEXT: |       |   |-value: Int 0
+// CHECK-NEXT: |       |   `-IntegerLiteral 0x{{[0-9A-Fa-f]+}} <col:42> 'int' 0
+// CHECK-NEXT: |       `-RecordType 0x{{[0-9A-Fa-f]+}} 'A<int, 0>'
+// CHECK-NEXT: |         `-ClassTemplateSpecialization 0x{{[0-9A-Fa-f]+}} 'A'
 
 template <class B1, B1 B2> using B = __make_integer_seq<A, B1, B2>;
 using test2 = B<int, 1>;
-//      CHECK: `-TypeAliasDecl 0x{{[0-9A-Fa-f]+}} <line:20:1, col:23> col:7 test2 'B<int, 1>':'A<int, 0>'
+//      CHECK: `-TypeAliasDecl 0x{{[0-9A-Fa-f]+}} <line:30:1, col:23> col:7 test2 'B<int, 1>':'A<int, 0>'
 // CHECK-NEXT:   `-ElaboratedType 0x{{[0-9A-Fa-f]+}} 'B<int, 1>' sugar
 // CHECK-NEXT:     `-TemplateSpecializationType 0x{{[0-9A-Fa-f]+}} 'B<int, 1>' sugar alias B
 // CHECK-NEXT:       |-TemplateArgument type 'int'
@@ -28,7 +38,7 @@
 // CHECK-NEXT:       |   |-value: Int 1
 // CHECK-NEXT:       |   `-IntegerLiteral 0x{{[0-9A-Fa-f]+}} <col:22> 'int' 1
 // CHECK-NEXT:       `-ElaboratedType 0x{{[0-9A-Fa-f]+}} '__make_integer_seq<A, int, 1>' sugar
-// CHECK-NEXT:         `-TemplateSpecializationType 0x{{[0-9A-Fa-f]+}} '__make_integer_seq<A, int, 1>' sugar __make_integer_seq
+// CHECK-NEXT:         `-TemplateSpecializationType 0x{{[0-9A-Fa-f]+}} '__make_integer_seq<A, int, 1>' sugar alias __make_integer_seq
 // CHECK-NEXT:           |-TemplateArgument template A
 // CHECK-NEXT:           |-TemplateArgument type 'int':'int'
 // CHECK-NEXT:           | `-SubstTemplateTypeParmType 0x{{[0-9A-Fa-f]+}} 'int' sugar
@@ -36,10 +46,20 @@
 // CHECK-NEXT:           |   | `-TemplateTypeParm 0x{{[0-9A-Fa-f]+}} 'B1'
 // CHECK-NEXT:           |   `-BuiltinType 0x{{[0-9A-Fa-f]+}} 'int'
 // CHECK-NEXT:           |-TemplateArgument expr
-// CHECK-NEXT:           | `-ConstantExpr 0x{{[0-9A-Fa-f]+}} <line:19:64> 'int'
+// CHECK-NEXT:           | `-ConstantExpr 0x{{[0-9A-Fa-f]+}} <line:29:64> 'int'
 // CHECK-NEXT:           |   |-value: Int 1
 // CHECK-NEXT:           |   `-SubstNonTypeTemplateParmExpr 0x{{[0-9A-Fa-f]+}} <col:64> 'int'
 // CHECK-NEXT:           |     |-NonTypeTemplateParmDecl 0x{{[0-9A-Fa-f]+}} <col:21, col:24> col:24 referenced 'B1' depth 0 index 1 B2
 // CHECK-NEXT:           |     `-IntegerLiteral 0x{{[0-9A-Fa-f]+}} <col:64> 'int' 1
-// CHECK-NEXT:           `-RecordType 0x{{[0-9A-Fa-f]+}} 'A<int, 0>'
-// CHECK-NEXT:             `-ClassTemplateSpecialization 0x{{[0-9A-Fa-f]+}} 'A'
+// CHECK-NEXT:           `-TemplateSpecializationType 0x{{[0-9A-Fa-f]+}} 'A<int, 0>' sugar A
+// CHECK-NEXT:             |-TemplateArgument type 'int':'int'
+// CHECK-NEXT:             | `-SubstTemplateTypeParmType 0x{{[0-9A-Fa-f]+}} 'int' sugar
+// CHECK-NEXT:             |   |-TemplateTypeParmType 0x{{[0-9A-Fa-f]+}} 'auto' dependent depth 0 index 1
+// CHECK-NEXT:             |   | `-TemplateTypeParm 0x{{[0-9A-Fa-f]+}} ''
+// CHECK-NEXT:             |   `-BuiltinType 0x{{[0-9A-Fa-f]+}} 'int'
+// CHECK-NEXT:             |-TemplateArgument expr
+// CHECK-NEXT:             | `-ConstantExpr 0x{{[0-9A-Fa-f]+}} <col:64> 'int'
+// CHECK-NEXT:             |   |-value: Int 0
+// CHECK-NEXT:             |   `-IntegerLiteral 0x{{[0-9A-Fa-f]+}} <col:64> 'int' 0
+// CHECK-NEXT:             `-RecordType 0x{{[0-9A-Fa-f]+}} 'A<int, 0>'
+// CHECK-NEXT:               `-ClassTemplateSpecialization 0x{{[0-9A-Fa-f]+}} 'A'
Index: clang/lib/Sema/SemaTemplate.cpp
===================================================================
--- clang/lib/Sema/SemaTemplate.cpp
+++ clang/lib/Sema/SemaTemplate.cpp
@@ -3528,7 +3528,17 @@
     TemplateArgumentListInfo SyntheticTemplateArgs;
     // The type argument gets reused as the first template argument in the
     // synthetic template argument list.
-    SyntheticTemplateArgs.addArgument(TemplateArgs[1]);
+    auto *TTPD =
+        cast<TemplateTypeParmDecl>(BTD->getTemplateParameters()->getParam(1));
+    const auto *TTP = cast<TemplateTypeParmType>(
+        SemaRef.Context.getTemplateTypeParmType(0, 1, false, TTPD));
+    QualType OrigType = TemplateArgs[1].getArgument().getAsType();
+    QualType SyntheticType = SemaRef.Context.getSubstTemplateTypeParmType(
+        TTP, OrigType.getCanonicalType());
+    SyntheticTemplateArgs.addArgument(
+        TemplateArgumentLoc(TemplateArgument(SyntheticType),
+                            SemaRef.Context.getTrivialTypeSourceInfo(
+                                SyntheticType, TemplateArgs[1].getLocation())));
     // Expand N into 0 ... N-1.
     for (llvm::APSInt I(NumArgs.getBitWidth(), NumArgs.isUnsigned());
          I < NumArgs; ++I) {
@@ -3730,7 +3740,8 @@
     // We might have a substituted template template parameter pack. If so,
     // build a template specialization type for it.
     if (Name.getAsSubstTemplateTemplateParmPack())
-      return Context.getTemplateSpecializationType(Name, TemplateArgs);
+      return Context.getTemplateSpecializationType(Name,
+                                                   TemplateArgs.arguments());
 
     Diag(TemplateLoc, diag::err_template_id_not_a_type)
       << Name;
@@ -3903,7 +3914,8 @@
   // Build the fully-sugared type for this class template
   // specialization, which refers back to the class template
   // specialization we created or found.
-  return Context.getTemplateSpecializationType(Name, TemplateArgs, CanonType);
+  return Context.getTemplateSpecializationType(Name, TemplateArgs.arguments(),
+                                               CanonType);
 }
 
 void Sema::ActOnUndeclaredTypeTemplateName(Scope *S, TemplateTy &ParsedName,
Index: clang/lib/CodeGen/CGDebugInfo.cpp
===================================================================
--- clang/lib/CodeGen/CGDebugInfo.cpp
+++ clang/lib/CodeGen/CGDebugInfo.cpp
@@ -1263,10 +1263,11 @@
   assert(Ty->isTypeAlias());
   llvm::DIType *Src = getOrCreateType(Ty->getAliasedType(), Unit);
 
-  auto *AliasDecl =
-      cast<TypeAliasTemplateDecl>(Ty->getTemplateName().getAsTemplateDecl())
-          ->getTemplatedDecl();
+  const TemplateDecl *TD = Ty->getTemplateName().getAsTemplateDecl();
+  if (isa<BuiltinTemplateDecl>(TD))
+    return Src;
 
+  const auto *AliasDecl = cast<TypeAliasTemplateDecl>(TD)->getTemplatedDecl();
   if (AliasDecl->hasAttr<NoDebugAttr>())
     return Src;
 
Index: clang/lib/AST/DeclTemplate.cpp
===================================================================
--- clang/lib/AST/DeclTemplate.cpp
+++ clang/lib/AST/DeclTemplate.cpp
@@ -250,6 +250,23 @@
   return false;
 }
 
+bool TemplateDecl::isTypeAlias() const {
+  switch (getKind()) {
+  case TemplateDecl::TypeAliasTemplate:
+    return true;
+  case TemplateDecl::BuiltinTemplate: {
+    const auto *BT = cast<BuiltinTemplateDecl>(this);
+    if (BT->getBuiltinTemplateKind() ==
+        BuiltinTemplateKind::BTK__make_integer_seq)
+      return true;
+    return false;
+  }
+  default:
+    return false;
+  };
+  llvm_unreachable("unknown template kind");
+}
+
 //===----------------------------------------------------------------------===//
 // RedeclarableTemplateDecl Implementation
 //===----------------------------------------------------------------------===//
Index: clang/lib/AST/ASTContext.cpp
===================================================================
--- clang/lib/AST/ASTContext.cpp
+++ clang/lib/AST/ASTContext.cpp
@@ -4841,7 +4841,8 @@
                                               QualType Underlying) const {
   assert(!Name.getAsDependentTemplateName() &&
          "No dependent template names here!");
-  QualType TST = getTemplateSpecializationType(Name, Args, Underlying);
+  QualType TST =
+      getTemplateSpecializationType(Name, Args.arguments(), Underlying);
 
   TypeSourceInfo *DI = CreateTypeSourceInfo(TST);
   TemplateSpecializationTypeLoc TL =
@@ -4857,14 +4858,14 @@
 
 QualType
 ASTContext::getTemplateSpecializationType(TemplateName Template,
-                                          const TemplateArgumentListInfo &Args,
+                                          ArrayRef<TemplateArgumentLoc> Args,
                                           QualType Underlying) const {
   assert(!Template.getAsDependentTemplateName() &&
          "No dependent template names here!");
 
   SmallVector<TemplateArgument, 4> ArgVec;
   ArgVec.reserve(Args.size());
-  for (const TemplateArgumentLoc &Arg : Args.arguments())
+  for (const TemplateArgumentLoc &Arg : Args)
     ArgVec.push_back(Arg.getArgument());
 
   return getTemplateSpecializationType(Template, ArgVec, Underlying);
@@ -4890,8 +4891,8 @@
   if (QualifiedTemplateName *QTN = Template.getAsQualifiedTemplateName())
     Template = QTN->getUnderlyingTemplate();
 
-  bool IsTypeAlias =
-      isa_and_nonnull<TypeAliasTemplateDecl>(Template.getAsTemplateDecl());
+  const auto *TD = Template.getAsTemplateDecl();
+  bool IsTypeAlias = TD && TD->isTypeAlias();
   QualType CanonType;
   if (!Underlying.isNull())
     CanonType = getCanonicalType(Underlying);
Index: clang/include/clang/AST/DeclTemplate.h
===================================================================
--- clang/include/clang/AST/DeclTemplate.h
+++ clang/include/clang/AST/DeclTemplate.h
@@ -452,6 +452,8 @@
                        TemplatedDecl->getSourceRange().getEnd());
   }
 
+  bool isTypeAlias() const;
+
 protected:
   NamedDecl *TemplatedDecl;
   TemplateParameterList *TemplateParams;
Index: clang/include/clang/AST/ASTContext.h
===================================================================
--- clang/include/clang/AST/ASTContext.h
+++ clang/include/clang/AST/ASTContext.h
@@ -1633,7 +1633,7 @@
                                          ArrayRef<TemplateArgument> Args) const;
 
   QualType getTemplateSpecializationType(TemplateName T,
-                                         const TemplateArgumentListInfo &Args,
+                                         ArrayRef<TemplateArgumentLoc> Args,
                                          QualType Canon = QualType()) const;
 
   TypeSourceInfo *
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to