mizvekov created this revision. Herald added a project: All. mizvekov requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
This makes use of the changes introduced in D134604 <https://reviews.llvm.org/D134604>, in order to instantiate non-type template parameters and default template arguments with a final sugared substitution. This comes at no additional relevant cost. Since we don't track / unique them in specializations, we wouldn't be able to resugar them later anyway. Signed-off-by: Matheus Izvekov <mizve...@gmail.com> Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D136564 Files: clang/include/clang/Sema/Sema.h clang/lib/Sema/SemaTemplate.cpp clang/lib/Sema/SemaTemplateDeduction.cpp clang/test/AST/ast-dump-template-decls.cpp clang/test/CXX/drs/dr3xx.cpp clang/test/CXX/expr/expr.const/p3-0x.cpp clang/test/Misc/diag-template-diffing.cpp clang/test/SemaTemplate/instantiation-default-1.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 @@ -69,14 +69,14 @@ // CHECK-NEXT: | `-TemplateTypeParmType 0x{{[0-9A-Fa-f]+}} 'T' dependent depth 0 index 1 // CHECK-NEXT: | `-TemplateTypeParm 0x{{[0-9A-Fa-f]+}} 'T' // CHECK-NEXT: |-TemplateArgument expr -// CHECK-NEXT: | `-ImplicitCastExpr 0x{{[0-9A-Fa-f]+}} <col:42> 'type-parameter-0-1':'type-parameter-0-1' <Dependent> +// CHECK-NEXT: | `-ImplicitCastExpr 0x{{[0-9A-Fa-f]+}} <col:42> 'T' <Dependent> // CHECK-NEXT: | `-DeclRefExpr 0x{{[0-9A-Fa-f]+}} <col:42> 'int' NonTypeTemplateParm 0x{{[0-9A-Fa-f]+}} 'N' 'int' // CHECK-NEXT: `-TemplateSpecializationType 0x{{[0-9A-Fa-f]+}} '__make_integer_seq<type-parameter-0-1, N>' dependent __make_integer_seq // CHECK-NEXT: |-TemplateArgument template // CHECK-NEXT: |-TemplateArgument type 'type-parameter-0-1' // CHECK-NEXT: | `-TemplateTypeParmType 0x{{[0-9A-Fa-f]+}} 'type-parameter-0-1' dependent depth 0 index 1 // CHECK-NEXT: `-TemplateArgument expr -// CHECK-NEXT: `-ImplicitCastExpr 0x{{[0-9A-Fa-f]+}} <col:42> 'type-parameter-0-1':'type-parameter-0-1' <Dependent> +// CHECK-NEXT: `-ImplicitCastExpr 0x{{[0-9A-Fa-f]+}} <col:42> 'T' <Dependent> // CHECK-NEXT: `-DeclRefExpr 0x{{[0-9A-Fa-f]+}} <col:42> 'int' NonTypeTemplateParm 0x{{[0-9A-Fa-f]+}} 'N' 'int' using test4 = __make_integer_seq<A, T, 1>; @@ -88,14 +88,14 @@ // CHECK-NEXT: | `-TemplateTypeParmType 0x{{[0-9A-Fa-f]+}} 'T' dependent depth 0 index 1 // CHECK-NEXT: | `-TemplateTypeParm 0x{{[0-9A-Fa-f]+}} 'T' // CHECK-NEXT: |-TemplateArgument expr -// CHECK-NEXT: | `-ImplicitCastExpr 0x{{[0-9A-Fa-f]+}} <col:42> 'type-parameter-0-1':'type-parameter-0-1' <Dependent> +// CHECK-NEXT: | `-ImplicitCastExpr 0x{{[0-9A-Fa-f]+}} <col:42> 'T' <Dependent> // CHECK-NEXT: | `-IntegerLiteral 0x{{[0-9A-Fa-f]+}} <col:42> 'int' 1 // CHECK-NEXT: `-TemplateSpecializationType 0x{{[0-9A-Fa-f]+}} '__make_integer_seq<A, type-parameter-0-1, 1>' dependent __make_integer_seq // CHECK-NEXT: |-TemplateArgument template A // CHECK-NEXT: |-TemplateArgument type 'type-parameter-0-1' // CHECK-NEXT: | `-TemplateTypeParmType 0x{{[0-9A-Fa-f]+}} 'type-parameter-0-1' dependent depth 0 index 1 // CHECK-NEXT: `-TemplateArgument expr -// CHECK-NEXT: `-ImplicitCastExpr 0x{{[0-9A-Fa-f]+}} <col:42> 'type-parameter-0-1':'type-parameter-0-1' <Dependent> +// CHECK-NEXT: `-ImplicitCastExpr 0x{{[0-9A-Fa-f]+}} <col:42> 'T' <Dependent> // CHECK-NEXT: `-IntegerLiteral 0x{{[0-9A-Fa-f]+}} <col:42> 'int' 1 using test5 = __make_integer_seq<A, int, N>; Index: clang/test/SemaTemplate/instantiation-default-1.cpp =================================================================== --- clang/test/SemaTemplate/instantiation-default-1.cpp +++ clang/test/SemaTemplate/instantiation-default-1.cpp @@ -33,7 +33,7 @@ } typedef int& int_ref_t; -Def2<int_ref_t> *d2; // expected-note{{in instantiation of default argument for 'Def2<int &>' required here}} +Def2<int_ref_t> *d2; // expected-note{{in instantiation of default argument for 'Def2<int_ref_t>' required here}} template<> struct Def1<const int> { }; // expected-error{{redefinition of 'Def1<const int>'}} Index: clang/test/Misc/diag-template-diffing.cpp =================================================================== --- clang/test/Misc/diag-template-diffing.cpp +++ clang/test/Misc/diag-template-diffing.cpp @@ -1454,7 +1454,7 @@ D<X::X1>(VectorType<X::X2>()); } // CHECK-ELIDE-NOTREE: error: no matching function for call to 'D' -// CHECK-ELIDE-NOTREE: note: candidate function template not viable: no known conversion from 'VectorType<X::X2>' to 'const VectorType<(TypeAlias::X)0>' for 1st argument +// CHECK-ELIDE-NOTREE: note: candidate function template not viable: no known conversion from 'VectorType<X::X2>' to 'const VectorType<(X)0>' for 1st argument } namespace TypeAlias2 { Index: clang/test/CXX/expr/expr.const/p3-0x.cpp =================================================================== --- clang/test/CXX/expr/expr.const/p3-0x.cpp +++ clang/test/CXX/expr/expr.const/p3-0x.cpp @@ -88,7 +88,7 @@ Val<decltype(&noexcept_false), &noexcept_true> remove_noexcept; Val<decltype(&noexcept_true), &noexcept_false> add_noexcept; #if __cplusplus > 201402L -// expected-error@-2 {{value of type 'void (*)() noexcept(false)' is not implicitly convertible to 'void (*)() noexcept'}} +// expected-error@-2 {{value of type 'void (*)() noexcept(false)' is not implicitly convertible to 'decltype(&noexcept_true)' (aka 'void (*)() noexcept(true)')}} #endif // (no other conversions are permitted) Index: clang/test/CXX/drs/dr3xx.cpp =================================================================== --- clang/test/CXX/drs/dr3xx.cpp +++ clang/test/CXX/drs/dr3xx.cpp @@ -924,9 +924,9 @@ namespace dr368 { // dr368: yes template<typename T, T> struct S {}; // expected-note {{here}} template<typename T> int f(S<T, T()> *); // expected-error {{function type}} - template<typename T> int g(S<T, (T())> *); // cxx98_17-note {{type 'dr368::X'}} + template<typename T> int g(S<T, (T())> *); // cxx98_17-note {{type 'X'}} // cxx20_2b-note@-1 {{candidate function [with T = dr368::X]}} - template<typename T> int g(S<T, true ? T() : T()> *); // cxx98_17-note {{type 'dr368::X'}} + template<typename T> int g(S<T, true ? T() : T()> *); // cxx98_17-note {{type 'X'}} // cxx20_2b-note@-1 {{candidate function [with T = dr368::X]}} struct X {}; int n = g<X>(0); // cxx98_17-error {{no matching}} 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 @@ -172,11 +172,9 @@ // CHECK: TypeAliasDecl 0x{{[^ ]*}} <line:{{[1-9]+}}:1, col:23> col:7 test1 'D<subst_default_argument::E, int>':'subst_default_argument::E<int, subst_default_argument::A<int>>' // CHECK: TemplateSpecializationType 0x{{[^ ]*}} 'A<int>' sugar A // CHECK-NEXT: |-TemplateArgument type 'int':'int' -// CHECK-NEXT: | `-SubstTemplateTypeParmType 0x{{[^ ]*}} 'int' sugar class depth 0 index 0 E1 -// CHECK-NEXT: | |-ClassTemplate 0x{{[^ ]*}} 'E' -// CHECK-NEXT: | `-SubstTemplateTypeParmType 0x{{[^ ]*}} 'int' sugar class depth 0 index 1 D2 -// CHECK-NEXT: | |-TypeAliasTemplate 0x{{[^ ]*}} 'D' -// CHECK-NEXT: | `-BuiltinType 0x{{[^ ]*}} 'int' +// CHECK-NEXT: | `-SubstTemplateTypeParmType 0x{{[^ ]*}} 'int' sugar class depth 0 index 1 D2 +// CHECK-NEXT: | |-TypeAliasTemplate 0x{{[^ ]*}} 'D' +// CHECK-NEXT: | `-BuiltinType 0x{{[^ ]*}} 'int' // CHECK-NEXT: `-RecordType 0x{{[^ ]*}} 'subst_default_argument::A<int>' // CHECK-NEXT: `-ClassTemplateSpecialization 0x{{[^ ]*}} 'A' } // namespace subst_default_argument Index: clang/lib/Sema/SemaTemplateDeduction.cpp =================================================================== --- clang/lib/Sema/SemaTemplateDeduction.cpp +++ clang/lib/Sema/SemaTemplateDeduction.cpp @@ -2687,12 +2687,12 @@ // itself, in case that substitution fails. if (SugaredPackedArgsBuilder.empty()) { LocalInstantiationScope Scope(S); - MultiLevelTemplateArgumentList Args(Template, CanonicalOutput, - /*Final=*/false); + MultiLevelTemplateArgumentList Args(Template, SugaredOutput, + /*Final=*/true); if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Param)) { Sema::InstantiatingTemplate Inst(S, Template->getLocation(), Template, - NTTP, CanonicalOutput, + NTTP, SugaredOutput, Template->getSourceRange()); if (Inst.isInvalid() || S.SubstType(NTTP->getType(), Args, NTTP->getLocation(), @@ -2700,7 +2700,7 @@ return true; } else if (auto *TTP = dyn_cast<TemplateTemplateParmDecl>(Param)) { Sema::InstantiatingTemplate Inst(S, Template->getLocation(), Template, - TTP, CanonicalOutput, + TTP, SugaredOutput, Template->getSourceRange()); if (Inst.isInvalid() || !S.SubstDecl(TTP, S.CurContext, Args)) return true; @@ -2810,7 +2810,7 @@ DefArg = S.SubstDefaultTemplateArgumentIfAvailable( TD, TD->getLocation(), TD->getSourceRange().getEnd(), Param, - CanonicalBuilder, HasDefaultArg); + SugaredBuilder, CanonicalBuilder, HasDefaultArg); } // If there was no default argument, deduction is incomplete. @@ -2960,10 +2960,9 @@ PartialTemplArgInfo->RAngleLoc); if (S.SubstTemplateArguments(PartialTemplArgInfo->arguments(), - MultiLevelTemplateArgumentList( - Partial, - CanonicalDeducedArgumentList->asArray(), - /*Final=*/false), + MultiLevelTemplateArgumentList(Partial, + SugaredBuilder, + /*Final=*/true), InstArgs)) { unsigned ArgIdx = InstArgs.size(), ParamIdx = ArgIdx; if (ParamIdx >= Partial->getTemplateParameters()->size()) @@ -3303,8 +3302,8 @@ ExtParameterInfoBuilder ExtParamInfos; MultiLevelTemplateArgumentList MLTAL(FunctionTemplate, - CanonicalExplicitArgumentList->asArray(), - /*Final=*/false); + SugaredExplicitArgumentList->asArray(), + /*Final=*/true); // Instantiate the types of each of the function parameters given the // explicitly-specified template arguments. If the function has a trailing Index: clang/lib/Sema/SemaTemplate.cpp =================================================================== --- clang/lib/Sema/SemaTemplate.cpp +++ clang/lib/Sema/SemaTemplate.cpp @@ -5256,27 +5256,25 @@ /// \param Converted the list of template arguments provided for template /// parameters that precede \p Param in the template parameter list. /// \returns the substituted template argument, or NULL if an error occurred. -static TypeSourceInfo * -SubstDefaultTemplateArgument(Sema &SemaRef, - TemplateDecl *Template, - SourceLocation TemplateLoc, - SourceLocation RAngleLoc, - TemplateTypeParmDecl *Param, - SmallVectorImpl<TemplateArgument> &Converted) { +static TypeSourceInfo *SubstDefaultTemplateArgument( + Sema &SemaRef, TemplateDecl *Template, SourceLocation TemplateLoc, + SourceLocation RAngleLoc, TemplateTypeParmDecl *Param, + ArrayRef<TemplateArgument> SugaredConverted, + ArrayRef<TemplateArgument> CanonicalConverted) { TypeSourceInfo *ArgType = Param->getDefaultArgumentInfo(); // If the argument type is dependent, instantiate it now based // on the previously-computed template arguments. if (ArgType->getType()->isInstantiationDependentType()) { - Sema::InstantiatingTemplate Inst(SemaRef, TemplateLoc, - Param, Template, Converted, + Sema::InstantiatingTemplate Inst(SemaRef, TemplateLoc, Param, Template, + SugaredConverted, SourceRange(TemplateLoc, RAngleLoc)); if (Inst.isInvalid()) return nullptr; // Only substitute for the innermost template argument list. - MultiLevelTemplateArgumentList TemplateArgLists(Template, Converted, - /*Final=*/false); + MultiLevelTemplateArgumentList TemplateArgLists(Template, SugaredConverted, + /*Final=*/true); for (unsigned i = 0, e = Param->getDepth(); i != e; ++i) TemplateArgLists.addOuterTemplateArguments(None); @@ -5315,22 +5313,20 @@ /// parameters that precede \p Param in the template parameter list. /// /// \returns the substituted template argument, or NULL if an error occurred. -static ExprResult -SubstDefaultTemplateArgument(Sema &SemaRef, - TemplateDecl *Template, - SourceLocation TemplateLoc, - SourceLocation RAngleLoc, - NonTypeTemplateParmDecl *Param, - SmallVectorImpl<TemplateArgument> &Converted) { - Sema::InstantiatingTemplate Inst(SemaRef, TemplateLoc, - Param, Template, Converted, +static ExprResult SubstDefaultTemplateArgument( + Sema &SemaRef, TemplateDecl *Template, SourceLocation TemplateLoc, + SourceLocation RAngleLoc, NonTypeTemplateParmDecl *Param, + ArrayRef<TemplateArgument> SugaredConverted, + ArrayRef<TemplateArgument> CanonicalConverted) { + Sema::InstantiatingTemplate Inst(SemaRef, TemplateLoc, Param, Template, + SugaredConverted, SourceRange(TemplateLoc, RAngleLoc)); if (Inst.isInvalid()) return ExprError(); // Only substitute for the innermost template argument list. - MultiLevelTemplateArgumentList TemplateArgLists(Template, Converted, - /*Final=*/false); + MultiLevelTemplateArgumentList TemplateArgLists(Template, SugaredConverted, + /*Final=*/true); for (unsigned i = 0, e = Param->getDepth(); i != e; ++i) TemplateArgLists.addOuterTemplateArguments(None); @@ -5365,23 +5361,21 @@ /// source-location information) that precedes the template name. /// /// \returns the substituted template argument, or NULL if an error occurred. -static TemplateName -SubstDefaultTemplateArgument(Sema &SemaRef, - TemplateDecl *Template, - SourceLocation TemplateLoc, - SourceLocation RAngleLoc, - TemplateTemplateParmDecl *Param, - SmallVectorImpl<TemplateArgument> &Converted, - NestedNameSpecifierLoc &QualifierLoc) { +static TemplateName SubstDefaultTemplateArgument( + Sema &SemaRef, TemplateDecl *Template, SourceLocation TemplateLoc, + SourceLocation RAngleLoc, TemplateTemplateParmDecl *Param, + ArrayRef<TemplateArgument> SugaredConverted, + ArrayRef<TemplateArgument> CanonicalConverted, + NestedNameSpecifierLoc &QualifierLoc) { Sema::InstantiatingTemplate Inst( - SemaRef, TemplateLoc, TemplateParameter(Param), Template, Converted, - SourceRange(TemplateLoc, RAngleLoc)); + SemaRef, TemplateLoc, TemplateParameter(Param), Template, + SugaredConverted, SourceRange(TemplateLoc, RAngleLoc)); if (Inst.isInvalid()) return TemplateName(); // Only substitute for the innermost template argument list. - MultiLevelTemplateArgumentList TemplateArgLists(Template, Converted, - /*Final=*/false); + MultiLevelTemplateArgumentList TemplateArgLists(Template, SugaredConverted, + /*Final=*/true); for (unsigned i = 0, e = Param->getDepth(); i != e; ++i) TemplateArgLists.addOuterTemplateArguments(None); @@ -5405,14 +5399,11 @@ /// If the given template parameter has a default template /// argument, substitute into that default template argument and /// return the corresponding template argument. -TemplateArgumentLoc -Sema::SubstDefaultTemplateArgumentIfAvailable(TemplateDecl *Template, - SourceLocation TemplateLoc, - SourceLocation RAngleLoc, - Decl *Param, - SmallVectorImpl<TemplateArgument> - &Converted, - bool &HasDefaultArg) { +TemplateArgumentLoc Sema::SubstDefaultTemplateArgumentIfAvailable( + TemplateDecl *Template, SourceLocation TemplateLoc, + SourceLocation RAngleLoc, Decl *Param, + ArrayRef<TemplateArgument> SugaredConverted, + ArrayRef<TemplateArgument> CanonicalConverted, bool &HasDefaultArg) { HasDefaultArg = false; if (TemplateTypeParmDecl *TypeParm = dyn_cast<TemplateTypeParmDecl>(Param)) { @@ -5420,11 +5411,9 @@ return TemplateArgumentLoc(); HasDefaultArg = true; - TypeSourceInfo *DI = SubstDefaultTemplateArgument(*this, Template, - TemplateLoc, - RAngleLoc, - TypeParm, - Converted); + TypeSourceInfo *DI = SubstDefaultTemplateArgument( + *this, Template, TemplateLoc, RAngleLoc, TypeParm, SugaredConverted, + CanonicalConverted); if (DI) return TemplateArgumentLoc(TemplateArgument(DI->getType()), DI); @@ -5437,11 +5426,9 @@ return TemplateArgumentLoc(); HasDefaultArg = true; - ExprResult Arg = SubstDefaultTemplateArgument(*this, Template, - TemplateLoc, - RAngleLoc, - NonTypeParm, - Converted); + ExprResult Arg = SubstDefaultTemplateArgument( + *this, Template, TemplateLoc, RAngleLoc, NonTypeParm, SugaredConverted, + CanonicalConverted); if (Arg.isInvalid()) return TemplateArgumentLoc(); @@ -5456,12 +5443,9 @@ HasDefaultArg = true; NestedNameSpecifierLoc QualifierLoc; - TemplateName TName = SubstDefaultTemplateArgument(*this, Template, - TemplateLoc, - RAngleLoc, - TempTempParm, - Converted, - QualifierLoc); + TemplateName TName = SubstDefaultTemplateArgument( + *this, Template, TemplateLoc, RAngleLoc, TempTempParm, SugaredConverted, + CanonicalConverted, QualifierLoc); if (TName.isNull()) return TemplateArgumentLoc(); @@ -5557,13 +5541,13 @@ !Template->getDeclContext()->isDependentContext()) { // Do substitution on the type of the non-type template parameter. InstantiatingTemplate Inst(*this, TemplateLoc, Template, NTTP, - CanonicalConverted, + SugaredConverted, SourceRange(TemplateLoc, RAngleLoc)); if (Inst.isInvalid()) return true; - MultiLevelTemplateArgumentList MLTAL(Template, CanonicalConverted, - /*Final=*/false); + MultiLevelTemplateArgumentList MLTAL(Template, SugaredConverted, + /*Final=*/true); // If the parameter is a pack expansion, expand this slice of the pack. if (auto *PET = NTTPType->getAs<PackExpansionType>()) { Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(*this, @@ -5728,7 +5712,7 @@ Params = SubstTemplateParams(Params, CurContext, MultiLevelTemplateArgumentList( - Template, CanonicalConverted, /*Final=*/false)); + Template, SugaredConverted, /*Final=*/true)); if (!Params) return true; } @@ -6007,7 +5991,8 @@ NewArgs); TypeSourceInfo *ArgType = SubstDefaultTemplateArgument( - *this, Template, TemplateLoc, RAngleLoc, TTP, CanonicalConverted); + *this, Template, TemplateLoc, RAngleLoc, TTP, SugaredConverted, + CanonicalConverted); if (!ArgType) return true; @@ -6020,7 +6005,8 @@ NewArgs); ExprResult E = SubstDefaultTemplateArgument( - *this, Template, TemplateLoc, RAngleLoc, NTTP, CanonicalConverted); + *this, Template, TemplateLoc, RAngleLoc, NTTP, SugaredConverted, + CanonicalConverted); if (E.isInvalid()) return true; @@ -6036,8 +6022,8 @@ NestedNameSpecifierLoc QualifierLoc; TemplateName Name = SubstDefaultTemplateArgument( - *this, Template, TemplateLoc, RAngleLoc, TempParm, CanonicalConverted, - QualifierLoc); + *this, Template, TemplateLoc, RAngleLoc, TempParm, SugaredConverted, + CanonicalConverted, QualifierLoc); if (Name.isNull()) return true; @@ -6051,7 +6037,7 @@ // template here, we just create this object to put a note into the // context stack. InstantiatingTemplate Inst(*this, RAngleLoc, Template, *Param, - CanonicalConverted, + SugaredConverted, SourceRange(TemplateLoc, RAngleLoc)); if (Inst.isInvalid()) return true; Index: clang/include/clang/Sema/Sema.h =================================================================== --- clang/include/clang/Sema/Sema.h +++ clang/include/clang/Sema/Sema.h @@ -8203,14 +8203,11 @@ SourceLocation TemplateLoc, Declarator &D); - TemplateArgumentLoc - SubstDefaultTemplateArgumentIfAvailable(TemplateDecl *Template, - SourceLocation TemplateLoc, - SourceLocation RAngleLoc, - Decl *Param, - SmallVectorImpl<TemplateArgument> - &Converted, - bool &HasDefaultArg); + TemplateArgumentLoc SubstDefaultTemplateArgumentIfAvailable( + TemplateDecl *Template, SourceLocation TemplateLoc, + SourceLocation RAngleLoc, Decl *Param, + ArrayRef<TemplateArgument> SugaredConverted, + ArrayRef<TemplateArgument> CanonicalConverted, bool &HasDefaultArg); /// Specifies the context in which a particular template /// argument is being checked.
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits