diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h --- a/clang/include/clang/Sema/Sema.h +++ b/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, diff --git a/clang/lib/Sema/SemaCXXScopeSpec.cpp b/clang/lib/Sema/SemaCXXScopeSpec.cpp --- a/clang/lib/Sema/SemaCXXScopeSpec.cpp +++ b/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; diff --git a/clang/lib/Sema/SemaCoroutine.cpp b/clang/lib/Sema/SemaCoroutine.cpp --- a/clang/lib/Sema/SemaCoroutine.cpp +++ b/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, diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/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) { diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -4257,8 +4257,8 @@ } static QualType checkBuiltinTemplateIdType( - Sema &SemaRef, TemplateName Name, BuiltinTemplateDecl *BTD, - ArrayRef SugaredConverted, + Sema &SemaRef, const NestedNameSpecifier *NNS, TemplateName Name, + BuiltinTemplateDecl *BTD, ArrayRef SugaredConverted, ArrayRef 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(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; diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/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(); diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h --- a/clang/lib/Sema/TreeTransform.h +++ b/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 diff --git a/clang/test/AST/ast-dump-template-decls.cpp b/clang/test/AST/ast-dump-template-decls.cpp --- a/clang/test/AST/ast-dump-template-decls.cpp +++ b/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::bind; -// CHECK: TypeAliasDecl 0x{{[^ ]*}} col:11 bound_type 'int (int (*)(float, int), int (*)(char, short))' +// CHECK: TypeAliasDecl 0x{{[^ ]*}} 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 diff --git a/clang/test/Sema/Resugar/resugar-types.cpp b/clang/test/Sema/Resugar/resugar-types.cpp --- a/clang/test/Sema/Resugar/resugar-types.cpp +++ b/clang/test/Sema/Resugar/resugar-types.cpp @@ -88,7 +88,7 @@ }; using T1 = foo::apply; TEST_NOT(T1::type1); -TEST_NOT(T1::type2); // FIXME: Needs resugaring on the pattern of template type aliases. +TEST(T1::type2); using T2 = foo::apply; TEST(T2::type1); @@ -106,7 +106,7 @@ }; using T1 = foo::bind; TEST_NOT(T1::type1); -TEST_NOT(T1::type2); // FIXME: Needs resugaring on the pattern of template type aliases. +TEST(T1::type2); using T2 = foo::bind; TEST(T2::type1); @@ -148,7 +148,7 @@ using T1 = typename foo::template bind; 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::template bind; TEST(typename T2::type1);