Skip to content

Commit 2560c12

Browse files
committed
[clang] Instantiate NTTPs and template default arguments with sugar
This makes use of the changes introduced in 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 <[email protected]> Differential Revision: https://reviews.llvm.org/D136564
1 parent c4c2a3c commit 2560c12

File tree

9 files changed

+80
-100
lines changed

9 files changed

+80
-100
lines changed

clang/include/clang/Sema/Sema.h

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8199,14 +8199,11 @@ class Sema final {
81998199
SourceLocation TemplateLoc,
82008200
Declarator &D);
82018201

8202-
TemplateArgumentLoc
8203-
SubstDefaultTemplateArgumentIfAvailable(TemplateDecl *Template,
8204-
SourceLocation TemplateLoc,
8205-
SourceLocation RAngleLoc,
8206-
Decl *Param,
8207-
SmallVectorImpl<TemplateArgument>
8208-
&Converted,
8209-
bool &HasDefaultArg);
8202+
TemplateArgumentLoc SubstDefaultTemplateArgumentIfAvailable(
8203+
TemplateDecl *Template, SourceLocation TemplateLoc,
8204+
SourceLocation RAngleLoc, Decl *Param,
8205+
ArrayRef<TemplateArgument> SugaredConverted,
8206+
ArrayRef<TemplateArgument> CanonicalConverted, bool &HasDefaultArg);
82108207

82118208
/// Specifies the context in which a particular template
82128209
/// argument is being checked.

clang/lib/Sema/SemaTemplate.cpp

Lines changed: 53 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -5261,27 +5261,25 @@ bool Sema::CheckTemplateTypeArgument(
52615261
/// \param Converted the list of template arguments provided for template
52625262
/// parameters that precede \p Param in the template parameter list.
52635263
/// \returns the substituted template argument, or NULL if an error occurred.
5264-
static TypeSourceInfo *
5265-
SubstDefaultTemplateArgument(Sema &SemaRef,
5266-
TemplateDecl *Template,
5267-
SourceLocation TemplateLoc,
5268-
SourceLocation RAngleLoc,
5269-
TemplateTypeParmDecl *Param,
5270-
SmallVectorImpl<TemplateArgument> &Converted) {
5264+
static TypeSourceInfo *SubstDefaultTemplateArgument(
5265+
Sema &SemaRef, TemplateDecl *Template, SourceLocation TemplateLoc,
5266+
SourceLocation RAngleLoc, TemplateTypeParmDecl *Param,
5267+
ArrayRef<TemplateArgument> SugaredConverted,
5268+
ArrayRef<TemplateArgument> CanonicalConverted) {
52715269
TypeSourceInfo *ArgType = Param->getDefaultArgumentInfo();
52725270

52735271
// If the argument type is dependent, instantiate it now based
52745272
// on the previously-computed template arguments.
52755273
if (ArgType->getType()->isInstantiationDependentType()) {
5276-
Sema::InstantiatingTemplate Inst(SemaRef, TemplateLoc,
5277-
Param, Template, Converted,
5274+
Sema::InstantiatingTemplate Inst(SemaRef, TemplateLoc, Param, Template,
5275+
SugaredConverted,
52785276
SourceRange(TemplateLoc, RAngleLoc));
52795277
if (Inst.isInvalid())
52805278
return nullptr;
52815279

52825280
// Only substitute for the innermost template argument list.
5283-
MultiLevelTemplateArgumentList TemplateArgLists(Template, Converted,
5284-
/*Final=*/false);
5281+
MultiLevelTemplateArgumentList TemplateArgLists(Template, SugaredConverted,
5282+
/*Final=*/true);
52855283
for (unsigned i = 0, e = Param->getDepth(); i != e; ++i)
52865284
TemplateArgLists.addOuterTemplateArguments(None);
52875285

@@ -5320,22 +5318,20 @@ SubstDefaultTemplateArgument(Sema &SemaRef,
53205318
/// parameters that precede \p Param in the template parameter list.
53215319
///
53225320
/// \returns the substituted template argument, or NULL if an error occurred.
5323-
static ExprResult
5324-
SubstDefaultTemplateArgument(Sema &SemaRef,
5325-
TemplateDecl *Template,
5326-
SourceLocation TemplateLoc,
5327-
SourceLocation RAngleLoc,
5328-
NonTypeTemplateParmDecl *Param,
5329-
SmallVectorImpl<TemplateArgument> &Converted) {
5330-
Sema::InstantiatingTemplate Inst(SemaRef, TemplateLoc,
5331-
Param, Template, Converted,
5321+
static ExprResult SubstDefaultTemplateArgument(
5322+
Sema &SemaRef, TemplateDecl *Template, SourceLocation TemplateLoc,
5323+
SourceLocation RAngleLoc, NonTypeTemplateParmDecl *Param,
5324+
ArrayRef<TemplateArgument> SugaredConverted,
5325+
ArrayRef<TemplateArgument> CanonicalConverted) {
5326+
Sema::InstantiatingTemplate Inst(SemaRef, TemplateLoc, Param, Template,
5327+
SugaredConverted,
53325328
SourceRange(TemplateLoc, RAngleLoc));
53335329
if (Inst.isInvalid())
53345330
return ExprError();
53355331

53365332
// Only substitute for the innermost template argument list.
5337-
MultiLevelTemplateArgumentList TemplateArgLists(Template, Converted,
5338-
/*Final=*/false);
5333+
MultiLevelTemplateArgumentList TemplateArgLists(Template, SugaredConverted,
5334+
/*Final=*/true);
53395335
for (unsigned i = 0, e = Param->getDepth(); i != e; ++i)
53405336
TemplateArgLists.addOuterTemplateArguments(None);
53415337

@@ -5370,23 +5366,21 @@ SubstDefaultTemplateArgument(Sema &SemaRef,
53705366
/// source-location information) that precedes the template name.
53715367
///
53725368
/// \returns the substituted template argument, or NULL if an error occurred.
5373-
static TemplateName
5374-
SubstDefaultTemplateArgument(Sema &SemaRef,
5375-
TemplateDecl *Template,
5376-
SourceLocation TemplateLoc,
5377-
SourceLocation RAngleLoc,
5378-
TemplateTemplateParmDecl *Param,
5379-
SmallVectorImpl<TemplateArgument> &Converted,
5380-
NestedNameSpecifierLoc &QualifierLoc) {
5369+
static TemplateName SubstDefaultTemplateArgument(
5370+
Sema &SemaRef, TemplateDecl *Template, SourceLocation TemplateLoc,
5371+
SourceLocation RAngleLoc, TemplateTemplateParmDecl *Param,
5372+
ArrayRef<TemplateArgument> SugaredConverted,
5373+
ArrayRef<TemplateArgument> CanonicalConverted,
5374+
NestedNameSpecifierLoc &QualifierLoc) {
53815375
Sema::InstantiatingTemplate Inst(
5382-
SemaRef, TemplateLoc, TemplateParameter(Param), Template, Converted,
5383-
SourceRange(TemplateLoc, RAngleLoc));
5376+
SemaRef, TemplateLoc, TemplateParameter(Param), Template,
5377+
SugaredConverted, SourceRange(TemplateLoc, RAngleLoc));
53845378
if (Inst.isInvalid())
53855379
return TemplateName();
53865380

53875381
// Only substitute for the innermost template argument list.
5388-
MultiLevelTemplateArgumentList TemplateArgLists(Template, Converted,
5389-
/*Final=*/false);
5382+
MultiLevelTemplateArgumentList TemplateArgLists(Template, SugaredConverted,
5383+
/*Final=*/true);
53905384
for (unsigned i = 0, e = Param->getDepth(); i != e; ++i)
53915385
TemplateArgLists.addOuterTemplateArguments(None);
53925386

@@ -5410,26 +5404,21 @@ SubstDefaultTemplateArgument(Sema &SemaRef,
54105404
/// If the given template parameter has a default template
54115405
/// argument, substitute into that default template argument and
54125406
/// return the corresponding template argument.
5413-
TemplateArgumentLoc
5414-
Sema::SubstDefaultTemplateArgumentIfAvailable(TemplateDecl *Template,
5415-
SourceLocation TemplateLoc,
5416-
SourceLocation RAngleLoc,
5417-
Decl *Param,
5418-
SmallVectorImpl<TemplateArgument>
5419-
&Converted,
5420-
bool &HasDefaultArg) {
5407+
TemplateArgumentLoc Sema::SubstDefaultTemplateArgumentIfAvailable(
5408+
TemplateDecl *Template, SourceLocation TemplateLoc,
5409+
SourceLocation RAngleLoc, Decl *Param,
5410+
ArrayRef<TemplateArgument> SugaredConverted,
5411+
ArrayRef<TemplateArgument> CanonicalConverted, bool &HasDefaultArg) {
54215412
HasDefaultArg = false;
54225413

54235414
if (TemplateTypeParmDecl *TypeParm = dyn_cast<TemplateTypeParmDecl>(Param)) {
54245415
if (!hasReachableDefaultArgument(TypeParm))
54255416
return TemplateArgumentLoc();
54265417

54275418
HasDefaultArg = true;
5428-
TypeSourceInfo *DI = SubstDefaultTemplateArgument(*this, Template,
5429-
TemplateLoc,
5430-
RAngleLoc,
5431-
TypeParm,
5432-
Converted);
5419+
TypeSourceInfo *DI = SubstDefaultTemplateArgument(
5420+
*this, Template, TemplateLoc, RAngleLoc, TypeParm, SugaredConverted,
5421+
CanonicalConverted);
54335422
if (DI)
54345423
return TemplateArgumentLoc(TemplateArgument(DI->getType()), DI);
54355424

@@ -5442,11 +5431,9 @@ Sema::SubstDefaultTemplateArgumentIfAvailable(TemplateDecl *Template,
54425431
return TemplateArgumentLoc();
54435432

54445433
HasDefaultArg = true;
5445-
ExprResult Arg = SubstDefaultTemplateArgument(*this, Template,
5446-
TemplateLoc,
5447-
RAngleLoc,
5448-
NonTypeParm,
5449-
Converted);
5434+
ExprResult Arg = SubstDefaultTemplateArgument(
5435+
*this, Template, TemplateLoc, RAngleLoc, NonTypeParm, SugaredConverted,
5436+
CanonicalConverted);
54505437
if (Arg.isInvalid())
54515438
return TemplateArgumentLoc();
54525439

@@ -5461,12 +5448,9 @@ Sema::SubstDefaultTemplateArgumentIfAvailable(TemplateDecl *Template,
54615448

54625449
HasDefaultArg = true;
54635450
NestedNameSpecifierLoc QualifierLoc;
5464-
TemplateName TName = SubstDefaultTemplateArgument(*this, Template,
5465-
TemplateLoc,
5466-
RAngleLoc,
5467-
TempTempParm,
5468-
Converted,
5469-
QualifierLoc);
5451+
TemplateName TName = SubstDefaultTemplateArgument(
5452+
*this, Template, TemplateLoc, RAngleLoc, TempTempParm, SugaredConverted,
5453+
CanonicalConverted, QualifierLoc);
54705454
if (TName.isNull())
54715455
return TemplateArgumentLoc();
54725456

@@ -5562,13 +5546,13 @@ bool Sema::CheckTemplateArgument(
55625546
!Template->getDeclContext()->isDependentContext()) {
55635547
// Do substitution on the type of the non-type template parameter.
55645548
InstantiatingTemplate Inst(*this, TemplateLoc, Template, NTTP,
5565-
CanonicalConverted,
5549+
SugaredConverted,
55665550
SourceRange(TemplateLoc, RAngleLoc));
55675551
if (Inst.isInvalid())
55685552
return true;
55695553

5570-
MultiLevelTemplateArgumentList MLTAL(Template, CanonicalConverted,
5571-
/*Final=*/false);
5554+
MultiLevelTemplateArgumentList MLTAL(Template, SugaredConverted,
5555+
/*Final=*/true);
55725556
// If the parameter is a pack expansion, expand this slice of the pack.
55735557
if (auto *PET = NTTPType->getAs<PackExpansionType>()) {
55745558
Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(*this,
@@ -5733,7 +5717,7 @@ bool Sema::CheckTemplateArgument(
57335717
Params =
57345718
SubstTemplateParams(Params, CurContext,
57355719
MultiLevelTemplateArgumentList(
5736-
Template, CanonicalConverted, /*Final=*/false));
5720+
Template, SugaredConverted, /*Final=*/true));
57375721
if (!Params)
57385722
return true;
57395723
}
@@ -6012,7 +5996,8 @@ bool Sema::CheckTemplateArgumentList(
60125996
NewArgs);
60135997

60145998
TypeSourceInfo *ArgType = SubstDefaultTemplateArgument(
6015-
*this, Template, TemplateLoc, RAngleLoc, TTP, CanonicalConverted);
5999+
*this, Template, TemplateLoc, RAngleLoc, TTP, SugaredConverted,
6000+
CanonicalConverted);
60166001
if (!ArgType)
60176002
return true;
60186003

@@ -6025,7 +6010,8 @@ bool Sema::CheckTemplateArgumentList(
60256010
NewArgs);
60266011

60276012
ExprResult E = SubstDefaultTemplateArgument(
6028-
*this, Template, TemplateLoc, RAngleLoc, NTTP, CanonicalConverted);
6013+
*this, Template, TemplateLoc, RAngleLoc, NTTP, SugaredConverted,
6014+
CanonicalConverted);
60296015
if (E.isInvalid())
60306016
return true;
60316017

@@ -6041,8 +6027,8 @@ bool Sema::CheckTemplateArgumentList(
60416027

60426028
NestedNameSpecifierLoc QualifierLoc;
60436029
TemplateName Name = SubstDefaultTemplateArgument(
6044-
*this, Template, TemplateLoc, RAngleLoc, TempParm, CanonicalConverted,
6045-
QualifierLoc);
6030+
*this, Template, TemplateLoc, RAngleLoc, TempParm, SugaredConverted,
6031+
CanonicalConverted, QualifierLoc);
60466032
if (Name.isNull())
60476033
return true;
60486034

@@ -6056,7 +6042,7 @@ bool Sema::CheckTemplateArgumentList(
60566042
// template here, we just create this object to put a note into the
60576043
// context stack.
60586044
InstantiatingTemplate Inst(*this, RAngleLoc, Template, *Param,
6059-
CanonicalConverted,
6045+
SugaredConverted,
60606046
SourceRange(TemplateLoc, RAngleLoc));
60616047
if (Inst.isInvalid())
60626048
return true;

clang/lib/Sema/SemaTemplateDeduction.cpp

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2687,20 +2687,20 @@ static bool ConvertDeducedTemplateArgument(
26872687
// itself, in case that substitution fails.
26882688
if (SugaredPackedArgsBuilder.empty()) {
26892689
LocalInstantiationScope Scope(S);
2690-
MultiLevelTemplateArgumentList Args(Template, CanonicalOutput,
2691-
/*Final=*/false);
2690+
MultiLevelTemplateArgumentList Args(Template, SugaredOutput,
2691+
/*Final=*/true);
26922692

26932693
if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
26942694
Sema::InstantiatingTemplate Inst(S, Template->getLocation(), Template,
2695-
NTTP, CanonicalOutput,
2695+
NTTP, SugaredOutput,
26962696
Template->getSourceRange());
26972697
if (Inst.isInvalid() ||
26982698
S.SubstType(NTTP->getType(), Args, NTTP->getLocation(),
26992699
NTTP->getDeclName()).isNull())
27002700
return true;
27012701
} else if (auto *TTP = dyn_cast<TemplateTemplateParmDecl>(Param)) {
27022702
Sema::InstantiatingTemplate Inst(S, Template->getLocation(), Template,
2703-
TTP, CanonicalOutput,
2703+
TTP, SugaredOutput,
27042704
Template->getSourceRange());
27052705
if (Inst.isInvalid() || !S.SubstDecl(TTP, S.CurContext, Args))
27062706
return true;
@@ -2810,7 +2810,7 @@ static Sema::TemplateDeductionResult ConvertDeducedTemplateArguments(
28102810

28112811
DefArg = S.SubstDefaultTemplateArgumentIfAvailable(
28122812
TD, TD->getLocation(), TD->getSourceRange().getEnd(), Param,
2813-
CanonicalBuilder, HasDefaultArg);
2813+
SugaredBuilder, CanonicalBuilder, HasDefaultArg);
28142814
}
28152815

28162816
// If there was no default argument, deduction is incomplete.
@@ -2960,10 +2960,9 @@ FinishTemplateArgumentDeduction(
29602960
PartialTemplArgInfo->RAngleLoc);
29612961

29622962
if (S.SubstTemplateArguments(PartialTemplArgInfo->arguments(),
2963-
MultiLevelTemplateArgumentList(
2964-
Partial,
2965-
CanonicalDeducedArgumentList->asArray(),
2966-
/*Final=*/false),
2963+
MultiLevelTemplateArgumentList(Partial,
2964+
SugaredBuilder,
2965+
/*Final=*/true),
29672966
InstArgs)) {
29682967
unsigned ArgIdx = InstArgs.size(), ParamIdx = ArgIdx;
29692968
if (ParamIdx >= Partial->getTemplateParameters()->size())
@@ -3303,8 +3302,8 @@ Sema::TemplateDeductionResult Sema::SubstituteExplicitTemplateArguments(
33033302
ExtParameterInfoBuilder ExtParamInfos;
33043303

33053304
MultiLevelTemplateArgumentList MLTAL(FunctionTemplate,
3306-
CanonicalExplicitArgumentList->asArray(),
3307-
/*Final=*/false);
3305+
SugaredExplicitArgumentList->asArray(),
3306+
/*Final=*/true);
33083307

33093308
// Instantiate the types of each of the function parameters given the
33103309
// explicitly-specified template arguments. If the function has a trailing

clang/test/AST/ast-dump-template-decls.cpp

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -172,11 +172,9 @@ using test1 = D<E, int>;
172172
// 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>>'
173173
// CHECK: TemplateSpecializationType 0x{{[^ ]*}} 'A<int>' sugar A
174174
// CHECK-NEXT: |-TemplateArgument type 'int':'int'
175-
// CHECK-NEXT: | `-SubstTemplateTypeParmType 0x{{[^ ]*}} 'int' sugar class depth 0 index 0 E1
176-
// CHECK-NEXT: | |-ClassTemplate 0x{{[^ ]*}} 'E'
177-
// CHECK-NEXT: | `-SubstTemplateTypeParmType 0x{{[^ ]*}} 'int' sugar class depth 0 index 1 D2
178-
// CHECK-NEXT: | |-TypeAliasTemplate 0x{{[^ ]*}} 'D'
179-
// CHECK-NEXT: | `-BuiltinType 0x{{[^ ]*}} 'int'
175+
// CHECK-NEXT: | `-SubstTemplateTypeParmType 0x{{[^ ]*}} 'int' sugar class depth 0 index 1 D2
176+
// CHECK-NEXT: | |-TypeAliasTemplate 0x{{[^ ]*}} 'D'
177+
// CHECK-NEXT: | `-BuiltinType 0x{{[^ ]*}} 'int'
180178
// CHECK-NEXT: `-RecordType 0x{{[^ ]*}} 'subst_default_argument::A<int>'
181179
// CHECK-NEXT: `-ClassTemplateSpecialization 0x{{[^ ]*}} 'A'
182180
} // namespace subst_default_argument

clang/test/CXX/drs/dr3xx.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -924,9 +924,9 @@ namespace dr367 { // dr367: yes
924924
namespace dr368 { // dr368: yes
925925
template<typename T, T> struct S {}; // expected-note {{here}}
926926
template<typename T> int f(S<T, T()> *); // expected-error {{function type}}
927-
template<typename T> int g(S<T, (T())> *); // cxx98_17-note {{type 'dr368::X'}}
927+
template<typename T> int g(S<T, (T())> *); // cxx98_17-note {{type 'X'}}
928928
// cxx20_2b-note@-1 {{candidate function [with T = dr368::X]}}
929-
template<typename T> int g(S<T, true ? T() : T()> *); // cxx98_17-note {{type 'dr368::X'}}
929+
template<typename T> int g(S<T, true ? T() : T()> *); // cxx98_17-note {{type 'X'}}
930930
// cxx20_2b-note@-1 {{candidate function [with T = dr368::X]}}
931931
struct X {};
932932
int n = g<X>(0); // cxx98_17-error {{no matching}}

clang/test/CXX/expr/expr.const/p3-0x.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ void noexcept_true() noexcept(true);
8888
Val<decltype(&noexcept_false), &noexcept_true> remove_noexcept;
8989
Val<decltype(&noexcept_true), &noexcept_false> add_noexcept;
9090
#if __cplusplus > 201402L
91-
// expected-error@-2 {{value of type 'void (*)() noexcept(false)' is not implicitly convertible to 'void (*)() noexcept'}}
91+
// expected-error@-2 {{value of type 'void (*)() noexcept(false)' is not implicitly convertible to 'decltype(&noexcept_true)' (aka 'void (*)() noexcept(true)')}}
9292
#endif
9393

9494
// (no other conversions are permitted)

clang/test/Misc/diag-template-diffing.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1454,7 +1454,7 @@ void run() {
14541454
D<X::X1>(VectorType<X::X2>());
14551455
}
14561456
// CHECK-ELIDE-NOTREE: error: no matching function for call to 'D'
1457-
// 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
1457+
// CHECK-ELIDE-NOTREE: note: candidate function template not viable: no known conversion from 'VectorType<X::X2>' to 'const VectorType<(X)0>' for 1st argument
14581458
}
14591459

14601460
namespace TypeAlias2 {

clang/test/SemaTemplate/instantiation-default-1.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ void test_Def2(Def2<int, int const*> *d2) {
3333
}
3434

3535
typedef int& int_ref_t;
36-
Def2<int_ref_t> *d2; // expected-note{{in instantiation of default argument for 'Def2<int &>' required here}}
36+
Def2<int_ref_t> *d2; // expected-note{{in instantiation of default argument for 'Def2<int_ref_t>' required here}}
3737

3838

3939
template<> struct Def1<const int> { }; // expected-error{{redefinition of 'Def1<const int>'}}

0 commit comments

Comments
 (0)