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

This implements resugaring of the pattern of template type aliases,
utilizing the resugaring transform implemented in D127695 
<https://reviews.llvm.org/D127695>.

For more details and discussion see:
https://discourse.llvm.org/t/rfc-improving-diagnostics-with-template-specialization-resugaring/64294

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

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


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D137199

Files:
  clang/include/clang/Sema/Sema.h
  clang/lib/Sema/SemaCXXScopeSpec.cpp
  clang/lib/Sema/SemaCoroutine.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
  clang/lib/Sema/TreeTransform.h
  clang/test/AST/ast-dump-template-decls.cpp
  clang/test/Sema/Resugar/resugar-types.cpp

Index: clang/test/Sema/Resugar/resugar-types.cpp
===================================================================
--- clang/test/Sema/Resugar/resugar-types.cpp
+++ clang/test/Sema/Resugar/resugar-types.cpp
@@ -88,7 +88,7 @@
 };
 using T1 = foo<Bar>::apply<char>;
 TEST_NOT(T1::type1);
-TEST_NOT(T1::type2); // FIXME: Needs resugaring on the pattern of template type aliases.
+TEST(T1::type2);
 
 using T2 = foo<int>::apply<Bar>;
 TEST(T2::type1);
@@ -106,7 +106,7 @@
 };
 using T1 = foo<Bar>::bind<char>;
 TEST_NOT(T1::type1);
-TEST_NOT(T1::type2); // FIXME: Needs resugaring on the pattern of template type aliases.
+TEST(T1::type2);
 
 using T2 = foo<int>::bind<Bar>;
 TEST(T2::type1);
@@ -148,7 +148,7 @@
 
 using T1 = typename foo<Z, Bar>::template bind<int>;
 TEST_NOT(typename T1::type1);
-TEST_NOT(typename T1::type2); // FIXME: Needs resugaring on the pattern of template type aliases.
+TEST(typename T1::type2);
 
 using T2 = typename foo<Z, int>::template bind<Bar>;
 TEST(typename T2::type1);
Index: clang/test/AST/ast-dump-template-decls.cpp
===================================================================
--- clang/test/AST/ast-dump-template-decls.cpp
+++ clang/test/AST/ast-dump-template-decls.cpp
@@ -121,8 +121,6 @@
 // CHECK-NEXT: BuiltinType 0x{{[^ ]*}} 'void'
 // CHECK-NEXT: FunctionProtoType 0x{{[^ ]*}} 'void (int)' cdecl
 // CHECK-NEXT: BuiltinType 0x{{[^ ]*}} 'void'
-// CHECK-NEXT: SubstTemplateTypeParmType 0x{{[^ ]*}} 'int' sugar class depth 0 index 0 T
-// CHECK-NEXT: ClassTemplateSpecialization 0x{{[^ ]*}} 'C'
 // CHECK-NEXT: BuiltinType 0x{{[^ ]*}} 'int'
 } // namespace PR55886
 
@@ -133,7 +131,7 @@
   };
 };
 template struct D<float, char>::bind<int, short>;
-// CHECK:      TypeAliasDecl 0x{{[^ ]*}} <line:{{[1-9]+}}:5, col:45> col:11 bound_type 'int (int (*)(float, int), int (*)(char, short))'
+// CHECK:      TypeAliasDecl 0x{{[^ ]*}} <line:{{[0-9]+}}:5, col:45> col:11 bound_type 'int (int (*)(float, int), int (*)(char, short))'
 // CHECK:      FunctionProtoType 0x{{[^ ]*}} 'int (int (*)(float, int), int (*)(char, short))' cdecl
 // CHECK:      FunctionProtoType 0x{{[^ ]*}} 'int (float, int)' cdecl
 // CHECK:      SubstTemplateTypeParmType 0x{{[^ ]*}} 'float' sugar typename depth 0 index 0 ... T pack_index 1
Index: clang/lib/Sema/TreeTransform.h
===================================================================
--- clang/lib/Sema/TreeTransform.h
+++ clang/lib/Sema/TreeTransform.h
@@ -14831,7 +14831,8 @@
                                                       TemplateName Template,
                                              SourceLocation TemplateNameLoc,
                                      TemplateArgumentListInfo &TemplateArgs) {
-  return SemaRef.CheckTemplateIdType(Template, TemplateNameLoc, TemplateArgs);
+  return SemaRef.CheckTemplateIdType(nullptr, Template, TemplateNameLoc,
+                                     TemplateArgs);
 }
 
 template<typename Derived>
Index: clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
===================================================================
--- clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -6158,7 +6158,8 @@
               Args.addArgument(
                   getTrivialTemplateArgumentLoc(UnpackedArg, QualType(), Loc));
           }
-          QualType T = CheckTemplateIdType(TemplateName(TD), Loc, Args);
+          QualType T =
+              CheckTemplateIdType(nullptr, TemplateName(TD), Loc, Args);
           if (T.isNull())
             return nullptr;
           auto *SubstRecord = T->getAsCXXRecordDecl();
Index: clang/lib/Sema/SemaTemplate.cpp
===================================================================
--- clang/lib/Sema/SemaTemplate.cpp
+++ clang/lib/Sema/SemaTemplate.cpp
@@ -4257,8 +4257,8 @@
 }
 
 static QualType checkBuiltinTemplateIdType(
-    Sema &SemaRef, TemplateName Name, BuiltinTemplateDecl *BTD,
-    ArrayRef<TemplateArgument> SugaredConverted,
+    Sema &SemaRef, const NestedNameSpecifier *NNS, TemplateName Name,
+    BuiltinTemplateDecl *BTD, ArrayRef<TemplateArgument> SugaredConverted,
     ArrayRef<TemplateArgument> CanonicalConverted, SourceLocation TemplateLoc,
     TemplateArgumentListInfo &TemplateArgs) {
   ASTContext &Context = SemaRef.getASTContext();
@@ -4310,7 +4310,7 @@
     // The first template argument will be reused as the template decl that
     // our synthetic template arguments will be applied to.
     QualType Result =
-        SemaRef.CheckTemplateIdType(SugaredConverted[0].getAsTemplate(),
+        SemaRef.CheckTemplateIdType(NNS, SugaredConverted[0].getAsTemplate(),
                                     TemplateLoc, SyntheticTemplateArgs);
     return SemaRef.Context.getTemplateSpecializationType(
         Name, TemplateArgs.arguments(), SugaredConverted, CanonicalConverted,
@@ -4487,7 +4487,8 @@
   return { FailedCond, Description };
 }
 
-QualType Sema::CheckTemplateIdType(TemplateName Name,
+QualType Sema::CheckTemplateIdType(const NestedNameSpecifier *NNS,
+                                   TemplateName Name,
                                    SourceLocation TemplateLoc,
                                    TemplateArgumentListInfo &TemplateArgs) {
   DependentTemplateName *DTN
@@ -4552,8 +4553,8 @@
     if (Inst.isInvalid())
       return QualType();
 
-    CanonType = SubstType(Pattern->getUnderlyingType(),
-                          TemplateArgLists, AliasTemplate->getLocation(),
+    QualType T = resugar(NNS, Pattern->getUnderlyingType());
+    CanonType = SubstType(T, TemplateArgLists, AliasTemplate->getLocation(),
                           AliasTemplate->getDeclName());
     if (CanonType.isNull()) {
       // If this was enable_if and we failed to find the nested type
@@ -4591,7 +4592,7 @@
       return QualType();
     }
   } else if (auto *BTD = dyn_cast<BuiltinTemplateDecl>(Template)) {
-    return checkBuiltinTemplateIdType(*this, Name, BTD, SugaredConverted,
+    return checkBuiltinTemplateIdType(*this, NNS, Name, BTD, SugaredConverted,
                                       CanonicalConverted, TemplateLoc,
                                       TemplateArgs);
   } else if (Name.isDependent() ||
@@ -4834,7 +4835,8 @@
     return CreateParsedType(T, TLB.getTypeSourceInfo(Context, T));
   }
 
-  QualType SpecTy = CheckTemplateIdType(Template, TemplateIILoc, TemplateArgs);
+  QualType SpecTy = CheckTemplateIdType(SS.getScopeRep(), Template,
+                                        TemplateIILoc, TemplateArgs);
   if (SpecTy.isNull())
     return true;
 
@@ -4915,7 +4917,8 @@
     Diag(TAT->getLocation(), diag::note_declared_at);
   }
 
-  QualType Result = CheckTemplateIdType(Template, TemplateLoc, TemplateArgs);
+  QualType Result = CheckTemplateIdType(SS.getScopeRep(), Template, TemplateLoc,
+                                        TemplateArgs);
   if (Result.isNull())
     return TypeResult(true);
 
@@ -11473,7 +11476,8 @@
     return CreateParsedType(T, Builder.getTypeSourceInfo(Context, T));
   }
 
-  QualType T = CheckTemplateIdType(Template, TemplateIILoc, TemplateArgs);
+  QualType T = CheckTemplateIdType(SS.getScopeRep(), Template, TemplateIILoc,
+                                   TemplateArgs);
   if (T.isNull())
     return true;
 
Index: clang/lib/Sema/SemaDeclCXX.cpp
===================================================================
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -1033,7 +1033,8 @@
   }
 
   // Build the template-id.
-  QualType TraitTy = S.CheckTemplateIdType(TemplateName(TraitTD), Loc, Args);
+  QualType TraitTy =
+      S.CheckTemplateIdType(nullptr, TemplateName(TraitTD), Loc, Args);
   if (TraitTy.isNull())
     return true;
   if (!S.isCompleteType(Loc, TraitTy)) {
@@ -11607,7 +11608,8 @@
   return Context.getElaboratedType(
       ElaboratedTypeKeyword::ETK_None,
       NestedNameSpecifier::Create(Context, nullptr, getStdNamespace()),
-      CheckTemplateIdType(TemplateName(StdInitializerList), Loc, Args));
+      CheckTemplateIdType(nullptr, TemplateName(StdInitializerList), Loc,
+                          Args));
 }
 
 bool Sema::isInitListConstructor(const FunctionDecl *Ctor) {
Index: clang/lib/Sema/SemaCoroutine.cpp
===================================================================
--- clang/lib/Sema/SemaCoroutine.cpp
+++ clang/lib/Sema/SemaCoroutine.cpp
@@ -92,7 +92,7 @@
 
   // Build the template-id.
   QualType CoroTrait =
-      S.CheckTemplateIdType(TemplateName(CoroTraits), KwLoc, Args);
+      S.CheckTemplateIdType(nullptr, TemplateName(CoroTraits), KwLoc, Args);
   if (CoroTrait.isNull())
     return QualType();
   if (S.RequireCompleteType(KwLoc, CoroTrait,
@@ -171,7 +171,7 @@
 
   // Build the template-id.
   QualType CoroHandleType =
-      S.CheckTemplateIdType(TemplateName(CoroHandle), Loc, Args);
+      S.CheckTemplateIdType(nullptr, TemplateName(CoroHandle), Loc, Args);
   if (CoroHandleType.isNull())
     return QualType();
   if (S.RequireCompleteType(Loc, CoroHandleType,
Index: clang/lib/Sema/SemaCXXScopeSpec.cpp
===================================================================
--- clang/lib/Sema/SemaCXXScopeSpec.cpp
+++ clang/lib/Sema/SemaCXXScopeSpec.cpp
@@ -975,7 +975,8 @@
 
   // We were able to resolve the template name to an actual template.
   // Build an appropriate nested-name-specifier.
-  QualType T = CheckTemplateIdType(Template, TemplateNameLoc, TemplateArgs);
+  QualType T = CheckTemplateIdType(SS.getScopeRep(), Template, TemplateNameLoc,
+                                   TemplateArgs);
   if (T.isNull())
     return true;
 
Index: clang/include/clang/Sema/Sema.h
===================================================================
--- clang/include/clang/Sema/Sema.h
+++ clang/include/clang/Sema/Sema.h
@@ -8077,9 +8077,10 @@
 
   void NoteAllFoundTemplates(TemplateName Name);
 
-  QualType CheckTemplateIdType(TemplateName Template,
+  QualType CheckTemplateIdType(const NestedNameSpecifier *NNS,
+                               TemplateName Template,
                                SourceLocation TemplateLoc,
-                              TemplateArgumentListInfo &TemplateArgs);
+                               TemplateArgumentListInfo &TemplateArgs);
 
   TypeResult
   ActOnTemplateIdType(Scope *S, CXXScopeSpec &SS, SourceLocation TemplateKWLoc,
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to