@@ -5199,7 +5199,7 @@ convertTypeTemplateArgumentToTemplate(ASTContext &Context, TypeLoc TLoc) {
5199
5199
}
5200
5200
5201
5201
bool Sema::CheckTemplateArgument (
5202
- NamedDecl *Param, TemplateArgumentLoc &Arg , NamedDecl *Template,
5202
+ NamedDecl *Param, TemplateArgumentLoc &ArgLoc , NamedDecl *Template,
5203
5203
SourceLocation TemplateLoc, SourceLocation RAngleLoc,
5204
5204
unsigned ArgumentPackIndex,
5205
5205
SmallVectorImpl<TemplateArgument> &SugaredConverted,
@@ -5208,9 +5208,10 @@ bool Sema::CheckTemplateArgument(
5208
5208
bool PartialOrderingTTP, bool *MatchedPackOnParmToNonPackOnArg) {
5209
5209
// Check template type parameters.
5210
5210
if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
5211
- return CheckTemplateTypeArgument (TTP, Arg , SugaredConverted,
5211
+ return CheckTemplateTypeArgument (TTP, ArgLoc , SugaredConverted,
5212
5212
CanonicalConverted);
5213
5213
5214
+ const TemplateArgument &Arg = ArgLoc.getArgument ();
5214
5215
// Check non-type template parameters.
5215
5216
if (NonTypeTemplateParmDecl *NTTP =dyn_cast<NonTypeTemplateParmDecl>(Param)) {
5216
5217
// Do substitution on the type of the non-type template parameter
@@ -5252,63 +5253,73 @@ bool Sema::CheckTemplateArgument(
5252
5253
return true ;
5253
5254
}
5254
5255
5255
- switch (Arg.getArgument ().getKind ()) {
5256
- case TemplateArgument::Null:
5257
- llvm_unreachable (" Should never see a NULL template argument here" );
5258
-
5259
- case TemplateArgument::Expression: {
5260
- Expr *E = Arg.getArgument ().getAsExpr ();
5256
+ auto checkExpr = [&](Expr *E) -> Expr * {
5261
5257
TemplateArgument SugaredResult, CanonicalResult;
5262
5258
unsigned CurSFINAEErrors = NumSFINAEErrors;
5263
5259
ExprResult Res =
5264
5260
CheckTemplateArgument (NTTP, NTTPType, E, SugaredResult,
5265
5261
CanonicalResult, PartialOrderingTTP, CTAK);
5266
- if (Res.isInvalid ())
5267
- return true ;
5268
5262
// If the current template argument causes an error, give up now.
5269
- if (CurSFINAEErrors < NumSFINAEErrors)
5270
- return true ;
5263
+ if (Res.isInvalid () || CurSFINAEErrors < NumSFINAEErrors)
5264
+ return nullptr ;
5265
+ SugaredConverted.push_back (SugaredResult);
5266
+ CanonicalConverted.push_back (CanonicalResult);
5267
+ return Res.get ();
5268
+ };
5269
+
5270
+ switch (Arg.getKind ()) {
5271
+ case TemplateArgument::Null:
5272
+ llvm_unreachable (" Should never see a NULL template argument here" );
5271
5273
5274
+ case TemplateArgument::Expression: {
5275
+ Expr *E = Arg.getAsExpr ();
5276
+ Expr *R = checkExpr (E);
5277
+ if (!R)
5278
+ return true ;
5272
5279
// If the resulting expression is new, then use it in place of the
5273
5280
// old expression in the template argument.
5274
- if (Res. get () != E) {
5275
- TemplateArgument TA (Res. get () );
5276
- Arg = TemplateArgumentLoc (TA, Res. get () );
5281
+ if (R != E) {
5282
+ TemplateArgument TA (R );
5283
+ ArgLoc = TemplateArgumentLoc (TA, R );
5277
5284
}
5278
-
5279
- SugaredConverted.push_back (SugaredResult);
5280
- CanonicalConverted.push_back (CanonicalResult);
5281
5285
break ;
5282
5286
}
5283
5287
5284
- case TemplateArgument::Declaration:
5288
+ // As for the converted NTTP kinds, they still might need another
5289
+ // conversion, as the new corresponding parameter might be different.
5290
+ // Ideally, we would always perform substitution starting with sugared types
5291
+ // and never need these, as we would still have expressions. Since these are
5292
+ // needed so rarely, it's probably a better tradeoff to just convert them
5293
+ // back to expressions.
5285
5294
case TemplateArgument::Integral:
5286
- case TemplateArgument::StructuralValue :
5295
+ case TemplateArgument::Declaration :
5287
5296
case TemplateArgument::NullPtr:
5288
- // We've already checked this template argument, so just copy
5289
- // it to the list of converted arguments.
5290
- SugaredConverted.push_back (Arg.getArgument ());
5291
- CanonicalConverted.push_back (
5292
- Context.getCanonicalTemplateArgument (Arg.getArgument ()));
5297
+ case TemplateArgument::StructuralValue: {
5298
+ // FIXME: StructuralValue is untested here.
5299
+ ExprResult R =
5300
+ BuildExpressionFromNonTypeTemplateArgument (Arg, SourceLocation ());
5301
+ assert (R.isUsable ());
5302
+ if (!checkExpr (R.get ()))
5303
+ return true ;
5293
5304
break ;
5305
+ }
5294
5306
5295
5307
case TemplateArgument::Template:
5296
5308
case TemplateArgument::TemplateExpansion:
5297
5309
// We were given a template template argument. It may not be ill-formed;
5298
5310
// see below.
5299
- if (DependentTemplateName *DTN
5300
- = Arg.getArgument ().getAsTemplateOrTemplatePattern ()
5301
- .getAsDependentTemplateName ()) {
5311
+ if (DependentTemplateName *DTN = Arg.getAsTemplateOrTemplatePattern ()
5312
+ .getAsDependentTemplateName ()) {
5302
5313
// We have a template argument such as \c T::template X, which we
5303
5314
// parsed as a template template argument. However, since we now
5304
5315
// know that we need a non-type template argument, convert this
5305
5316
// template name into an expression.
5306
5317
5307
5318
DeclarationNameInfo NameInfo (DTN->getIdentifier (),
5308
- Arg .getTemplateNameLoc ());
5319
+ ArgLoc .getTemplateNameLoc ());
5309
5320
5310
5321
CXXScopeSpec SS;
5311
- SS.Adopt (Arg .getTemplateQualifierLoc ());
5322
+ SS.Adopt (ArgLoc .getTemplateQualifierLoc ());
5312
5323
// FIXME: the template-template arg was a DependentTemplateName,
5313
5324
// so it was provided with a template keyword. However, its source
5314
5325
// location is not stored in the template argument structure.
@@ -5319,8 +5330,8 @@ bool Sema::CheckTemplateArgument(
5319
5330
5320
5331
// If we parsed the template argument as a pack expansion, create a
5321
5332
// pack expansion expression.
5322
- if (Arg.getArgument (). getKind () == TemplateArgument::TemplateExpansion){
5323
- E = ActOnPackExpansion (E.get (), Arg .getTemplateEllipsisLoc ());
5333
+ if (Arg.getKind () == TemplateArgument::TemplateExpansion) {
5334
+ E = ActOnPackExpansion (E.get (), ArgLoc .getTemplateEllipsisLoc ());
5324
5335
if (E.isInvalid ())
5325
5336
return true ;
5326
5337
}
@@ -5340,8 +5351,8 @@ bool Sema::CheckTemplateArgument(
5340
5351
// We have a template argument that actually does refer to a class
5341
5352
// template, alias template, or template template parameter, and
5342
5353
// therefore cannot be a non-type template argument.
5343
- Diag (Arg .getLocation (), diag::err_template_arg_must_be_expr)
5344
- << Arg .getSourceRange ();
5354
+ Diag (ArgLoc .getLocation (), diag::err_template_arg_must_be_expr)
5355
+ << ArgLoc .getSourceRange ();
5345
5356
NoteTemplateParameterLocation (*Param);
5346
5357
5347
5358
return true ;
@@ -5357,8 +5368,8 @@ bool Sema::CheckTemplateArgument(
5357
5368
//
5358
5369
// We warn specifically about this case, since it can be rather
5359
5370
// confusing for users.
5360
- QualType T = Arg.getArgument (). getAsType ();
5361
- SourceRange SR = Arg .getSourceRange ();
5371
+ QualType T = Arg.getAsType ();
5372
+ SourceRange SR = ArgLoc .getSourceRange ();
5362
5373
if (T->isFunctionType ())
5363
5374
Diag (SR.getBegin (), diag::err_template_arg_nontype_ambig) << SR << T;
5364
5375
else
@@ -5409,34 +5420,33 @@ bool Sema::CheckTemplateArgument(
5409
5420
// When [the injected-class-name] is used [...] as a template-argument for
5410
5421
// a template template-parameter [...] it refers to the class template
5411
5422
// itself.
5412
- if (Arg.getArgument (). getKind () == TemplateArgument::Type) {
5423
+ if (Arg.getKind () == TemplateArgument::Type) {
5413
5424
TemplateArgumentLoc ConvertedArg = convertTypeTemplateArgumentToTemplate (
5414
- Context, Arg .getTypeSourceInfo ()->getTypeLoc ());
5425
+ Context, ArgLoc .getTypeSourceInfo ()->getTypeLoc ());
5415
5426
if (!ConvertedArg.getArgument ().isNull ())
5416
- Arg = ConvertedArg;
5427
+ ArgLoc = ConvertedArg;
5417
5428
}
5418
5429
5419
- switch (Arg.getArgument (). getKind ()) {
5430
+ switch (Arg.getKind ()) {
5420
5431
case TemplateArgument::Null:
5421
5432
llvm_unreachable (" Should never see a NULL template argument here" );
5422
5433
5423
5434
case TemplateArgument::Template:
5424
5435
case TemplateArgument::TemplateExpansion:
5425
- if (CheckTemplateTemplateArgument (TempParm, Params, Arg , PartialOrdering,
5436
+ if (CheckTemplateTemplateArgument (TempParm, Params, ArgLoc , PartialOrdering,
5426
5437
MatchedPackOnParmToNonPackOnArg))
5427
5438
return true ;
5428
5439
5429
- SugaredConverted.push_back (Arg.getArgument ());
5430
- CanonicalConverted.push_back (
5431
- Context.getCanonicalTemplateArgument (Arg.getArgument ()));
5440
+ SugaredConverted.push_back (Arg);
5441
+ CanonicalConverted.push_back (Context.getCanonicalTemplateArgument (Arg));
5432
5442
break ;
5433
5443
5434
5444
case TemplateArgument::Expression:
5435
5445
case TemplateArgument::Type:
5436
5446
// We have a template template parameter but the template
5437
5447
// argument does not refer to a template.
5438
- Diag (Arg .getLocation (), diag::err_template_arg_must_be_template)
5439
- << getLangOpts ().CPlusPlus11 ;
5448
+ Diag (ArgLoc .getLocation (), diag::err_template_arg_must_be_template)
5449
+ << getLangOpts ().CPlusPlus11 ;
5440
5450
return true ;
5441
5451
5442
5452
case TemplateArgument::Declaration:
0 commit comments