From 63f465b7f45d374f92d0e7697fddb3fb9b74241e Mon Sep 17 00:00:00 2001 From: Matheus Izvekov Date: Sun, 23 Oct 2022 13:38:39 +0200 Subject: [PATCH] [clang] Perform sugared substitution of builtin templates Since these are much like template type aliases, where we don't track a specialization for them and just substitute them eagerly, we can't resugar them anyway, and there is no relevant cost in just performing a finalizing sugared substitution. Signed-off-by: Matheus Izvekov Differential Revision: https://reviews.llvm.org/D136563 --- clang/lib/Sema/SemaTemplate.cpp | 30 ++++++++------------------- clang/test/SemaTemplate/make_integer_seq.cpp | 22 +++++++++----------- clang/test/SemaTemplate/type_pack_element.cpp | 10 ++++----- 3 files changed, 23 insertions(+), 39 deletions(-) diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 86c7ce1..9c22fd9 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -3577,18 +3577,11 @@ void Sema::NoteAllFoundTemplates(TemplateName Name) { static QualType checkBuiltinTemplateIdType(Sema &SemaRef, BuiltinTemplateDecl *BTD, - const SmallVectorImpl &Converted, + ArrayRef Converted, SourceLocation TemplateLoc, TemplateArgumentListInfo &TemplateArgs) { ASTContext &Context = SemaRef.getASTContext(); - // Wrap the type in substitution sugar. - auto getSubstType = [&](QualType Replacement, unsigned IndexReplaced, - Optional PackIndexReplaced) { - return SemaRef.Context.getSubstTemplateTypeParmType( - Replacement, BTD, IndexReplaced, PackIndexReplaced); - }; - switch (BTD->getBuiltinTemplateKind()) { case BTK__make_integer_seq: { // Specializations of __make_integer_seq are treated like @@ -3611,19 +3604,18 @@ checkBuiltinTemplateIdType(Sema &SemaRef, BuiltinTemplateDecl *BTD, TemplateArgumentListInfo SyntheticTemplateArgs; // The type argument, wrapped in substitution sugar, gets reused as the // first template argument in the synthetic template argument list. - QualType SyntheticType = getSubstType(OrigType, 1, None); SyntheticTemplateArgs.addArgument( - TemplateArgumentLoc(TemplateArgument(SyntheticType), + TemplateArgumentLoc(TemplateArgument(OrigType), SemaRef.Context.getTrivialTypeSourceInfo( - SyntheticType, TemplateArgs[1].getLocation()))); + OrigType, TemplateArgs[1].getLocation()))); if (llvm::APSInt NumArgs = NumArgsArg.getAsIntegral(); NumArgs >= 0) { // Expand N into 0 ... N-1. for (llvm::APSInt I(NumArgs.getBitWidth(), NumArgs.isUnsigned()); I < NumArgs; ++I) { - TemplateArgument TA(Context, I, SyntheticType); + TemplateArgument TA(Context, I, OrigType); SyntheticTemplateArgs.addArgument(SemaRef.getTrivialTemplateArgumentLoc( - TA, SyntheticType, TemplateArgs[2].getLocation())); + TA, OrigType, TemplateArgs[2].getLocation())); } } else { // C++14 [inteseq.make]p1: @@ -3633,13 +3625,10 @@ checkBuiltinTemplateIdType(Sema &SemaRef, BuiltinTemplateDecl *BTD, return QualType(); } - // Wrap the template in substitution sugar. - TemplateName TN = SemaRef.Context.getSubstTemplateTemplateParm( - Converted[0].getAsTemplate(), BTD, 0, None); - // The first template argument will be reused as the template decl that // our synthetic template arguments will be applied to. - return SemaRef.CheckTemplateIdType(TN, TemplateLoc, SyntheticTemplateArgs); + return SemaRef.CheckTemplateIdType(Converted[0].getAsTemplate(), + TemplateLoc, SyntheticTemplateArgs); } case BTK__type_pack_element: @@ -3666,8 +3655,7 @@ checkBuiltinTemplateIdType(Sema &SemaRef, BuiltinTemplateDecl *BTD, // We simply return the type at index `Index`. int64_t N = Index.getExtValue(); - return getSubstType(Ts.getPackAsArray()[N].getAsType(), 1, - Ts.pack_size() - 1 - N); + return Ts.getPackAsArray()[N].getAsType(); } llvm_unreachable("unexpected BuiltinTemplateDecl!"); } @@ -3915,7 +3903,7 @@ QualType Sema::CheckTemplateIdType(TemplateName Name, return QualType(); } } else if (auto *BTD = dyn_cast(Template)) { - CanonType = checkBuiltinTemplateIdType(*this, BTD, CanonicalConverted, + CanonType = checkBuiltinTemplateIdType(*this, BTD, SugaredConverted, TemplateLoc, TemplateArgs); } else if (Name.isDependent() || TemplateSpecializationType::anyDependentTemplateArguments( diff --git a/clang/test/SemaTemplate/make_integer_seq.cpp b/clang/test/SemaTemplate/make_integer_seq.cpp index 576169e..b51eed5 100644 --- a/clang/test/SemaTemplate/make_integer_seq.cpp +++ b/clang/test/SemaTemplate/make_integer_seq.cpp @@ -14,20 +14,18 @@ using test1 = __make_integer_seq; // CHECK-NEXT: | |-value: Int 1 // CHECK-NEXT: | `-IntegerLiteral 0x{{[0-9A-Fa-f]+}} 'int' 1 // CHECK-NEXT: `-TemplateSpecializationType 0x{{[0-9A-Fa-f]+}} 'A' sugar A -// CHECK-NEXT: |-TemplateArgument type 'int':'int' -// CHECK-NEXT: | `-SubstTemplateTypeParmType 0x{{[0-9A-Fa-f]+}} 'int' sugar typename depth 0 index 1 -// CHECK-NEXT: | |-BuiltinTemplate 0x{{[0-9A-Fa-f]+}} '__make_integer_seq' -// CHECK-NEXT: | `-BuiltinType 0x{{[0-9A-Fa-f]+}} 'int' +// CHECK-NEXT: |-TemplateArgument type 'int' +// CHECK-NEXT: | `-BuiltinType 0x{{[0-9A-Fa-f]+}} 'int' // CHECK-NEXT: |-TemplateArgument expr // CHECK-NEXT: | `-ConstantExpr 0x{{[0-9A-Fa-f]+}} 'int' // CHECK-NEXT: | |-value: Int 0 -// CHECK-NEXT: | `-IntegerLiteral 0x{{[0-9A-Fa-f]+}} 'int':'int' 0 +// CHECK-NEXT: | `-IntegerLiteral 0x{{[0-9A-Fa-f]+}} 'int' 0 // CHECK-NEXT: `-RecordType 0x{{[0-9A-Fa-f]+}} 'A' // CHECK-NEXT: `-ClassTemplateSpecialization 0x{{[0-9A-Fa-f]+}} 'A' template using B = __make_integer_seq; using test2 = B; -// CHECK: |-TypeAliasDecl 0x{{[0-9A-Fa-f]+}} col:7 test2 'B':'A' +// CHECK: |-TypeAliasDecl 0x{{[0-9A-Fa-f]+}} col:7 test2 'B':'A' // CHECK-NEXT: `-ElaboratedType 0x{{[0-9A-Fa-f]+}} 'B' sugar // CHECK-NEXT: `-TemplateSpecializationType 0x{{[0-9A-Fa-f]+}} 'B' sugar alias B // CHECK-NEXT: |-TemplateArgument type 'int' @@ -44,15 +42,15 @@ using test2 = B; // CHECK-NEXT: | |-TypeAliasTemplate 0x{{[0-9A-Fa-f]+}} 'B' // CHECK-NEXT: | `-BuiltinType 0x{{[0-9A-Fa-f]+}} 'int' // CHECK-NEXT: |-TemplateArgument expr -// CHECK-NEXT: | `-ConstantExpr 0x{{[0-9A-Fa-f]+}} 'int' +// CHECK-NEXT: | `-ConstantExpr 0x{{[0-9A-Fa-f]+}} 'int' // CHECK-NEXT: | |-value: Int 1 // CHECK-NEXT: | `-SubstNonTypeTemplateParmExpr 0x{{[0-9A-Fa-f]+}} 'int' // CHECK-NEXT: | |-NonTypeTemplateParmDecl 0x{{[0-9A-Fa-f]+}} col:24 referenced 'B1' depth 0 index 1 B2 // CHECK-NEXT: | `-IntegerLiteral 0x{{[0-9A-Fa-f]+}} 'int' 1 // CHECK-NEXT: `-TemplateSpecializationType 0x{{[0-9A-Fa-f]+}} 'A' sugar A // CHECK-NEXT: |-TemplateArgument type 'int':'int' -// CHECK-NEXT: | `-SubstTemplateTypeParmType 0x{{[0-9A-Fa-f]+}} 'int' sugar typename depth 0 index 1 -// CHECK-NEXT: | |-BuiltinTemplate 0x{{[0-9A-Fa-f]+}} '__make_integer_seq' +// CHECK-NEXT: | `-SubstTemplateTypeParmType 0x{{[0-9A-Fa-f]+}} 'int' sugar class depth 0 index 0 B1 +// CHECK-NEXT: | |-TypeAliasTemplate 0x{{[0-9A-Fa-f]+}} 'B' // CHECK-NEXT: | `-BuiltinType 0x{{[0-9A-Fa-f]+}} 'int' // CHECK-NEXT: |-TemplateArgument expr // CHECK-NEXT: | `-ConstantExpr 0x{{[0-9A-Fa-f]+}} 'int' @@ -63,7 +61,7 @@ using test2 = B; template