@@ -199,9 +199,9 @@ calculateConstraintSatisfaction(Sema &S, const Expr *ConstraintExpr,
199
199
}
200
200
201
201
static bool calculateConstraintSatisfaction (
202
- Sema &S, const NamedDecl *Template, ArrayRef<TemplateArgument> TemplateArgs ,
203
- SourceLocation TemplateNameLoc, MultiLevelTemplateArgumentList &MLTAL,
204
- const Expr *ConstraintExpr, ConstraintSatisfaction &Satisfaction) {
202
+ Sema &S, const NamedDecl *Template, SourceLocation TemplateNameLoc ,
203
+ const MultiLevelTemplateArgumentList &MLTAL, const Expr *ConstraintExpr ,
204
+ ConstraintSatisfaction &Satisfaction) {
205
205
return calculateConstraintSatisfaction (
206
206
S, ConstraintExpr, Satisfaction, [&](const Expr *AtomicExpr) {
207
207
EnterExpressionEvaluationContext ConstantEvaluated (
@@ -268,36 +268,35 @@ static bool calculateConstraintSatisfaction(
268
268
});
269
269
}
270
270
271
- static bool CheckConstraintSatisfaction (Sema &S, const NamedDecl *Template,
272
- ArrayRef<const Expr *> ConstraintExprs,
273
- ArrayRef<TemplateArgument> TemplateArgs,
274
- SourceRange TemplateIDRange,
275
- ConstraintSatisfaction &Satisfaction) {
271
+ static bool CheckConstraintSatisfaction (
272
+ Sema &S, const NamedDecl *Template, ArrayRef<const Expr *> ConstraintExprs,
273
+ const MultiLevelTemplateArgumentList &TemplateArgsLists,
274
+ SourceRange TemplateIDRange, ConstraintSatisfaction &Satisfaction) {
276
275
if (ConstraintExprs.empty ()) {
277
276
Satisfaction.IsSatisfied = true ;
278
277
return false ;
279
278
}
280
279
281
- for (auto & Arg : TemplateArgs)
282
- if (Arg.isInstantiationDependent ()) {
283
- // No need to check satisfaction for dependent constraint expressions.
284
- Satisfaction.IsSatisfied = true ;
285
- return false ;
286
- }
280
+ if (TemplateArgsLists.isAnyArgInstantiationDependent ()) {
281
+ // No need to check satisfaction for dependent constraint expressions.
282
+ Satisfaction.IsSatisfied = true ;
283
+ return false ;
284
+ }
287
285
286
+ ArrayRef<TemplateArgument> TemplateArgs =
287
+ TemplateArgsLists.getNumSubstitutedLevels () > 0
288
+ ? TemplateArgsLists.getOutermost ()
289
+ : ArrayRef<TemplateArgument> {};
288
290
Sema::InstantiatingTemplate Inst (S, TemplateIDRange.getBegin (),
289
291
Sema::InstantiatingTemplate::ConstraintsCheck{},
290
292
const_cast <NamedDecl *>(Template), TemplateArgs, TemplateIDRange);
291
293
if (Inst.isInvalid ())
292
294
return true ;
293
295
294
- MultiLevelTemplateArgumentList MLTAL;
295
- MLTAL.addOuterTemplateArguments (TemplateArgs);
296
-
297
296
for (const Expr *ConstraintExpr : ConstraintExprs) {
298
- if (calculateConstraintSatisfaction (S, Template, TemplateArgs ,
299
- TemplateIDRange. getBegin (), MLTAL ,
300
- ConstraintExpr, Satisfaction))
297
+ if (calculateConstraintSatisfaction (S, Template, TemplateIDRange. getBegin () ,
298
+ TemplateArgsLists, ConstraintExpr ,
299
+ Satisfaction))
301
300
return true ;
302
301
if (!Satisfaction.IsSatisfied )
303
302
// [temp.constr.op] p2
@@ -311,28 +310,37 @@ static bool CheckConstraintSatisfaction(Sema &S, const NamedDecl *Template,
311
310
312
311
bool Sema::CheckConstraintSatisfaction (
313
312
const NamedDecl *Template, ArrayRef<const Expr *> ConstraintExprs,
314
- ArrayRef<TemplateArgument> TemplateArgs, SourceRange TemplateIDRange ,
315
- ConstraintSatisfaction &OutSatisfaction) {
313
+ const MultiLevelTemplateArgumentList &TemplateArgsLists ,
314
+ SourceRange TemplateIDRange, ConstraintSatisfaction &OutSatisfaction) {
316
315
if (ConstraintExprs.empty ()) {
317
316
OutSatisfaction.IsSatisfied = true ;
318
317
return false ;
319
318
}
320
319
if (!Template) {
321
320
return ::CheckConstraintSatisfaction (*this , nullptr , ConstraintExprs,
322
- TemplateArgs , TemplateIDRange,
321
+ TemplateArgsLists , TemplateIDRange,
323
322
OutSatisfaction);
324
323
}
324
+
325
+ // A list of the template argument list flattened in a predictible manner for
326
+ // the purposes of caching. The ConstraintSatisfaction type is in AST so it
327
+ // has no access to the MultiLevelTemplateArgumentList, so this has to happen
328
+ // here.
329
+ llvm::SmallVector<TemplateArgument, 4 > FlattenedArgs;
330
+ for (ArrayRef<TemplateArgument> List : TemplateArgsLists)
331
+ FlattenedArgs.insert (FlattenedArgs.end (), List.begin (), List.end ());
332
+
325
333
llvm::FoldingSetNodeID ID;
326
- ConstraintSatisfaction::Profile (ID, Context, Template, TemplateArgs );
334
+ ConstraintSatisfaction::Profile (ID, Context, Template, FlattenedArgs );
327
335
void *InsertPos;
328
336
if (auto *Cached = SatisfactionCache.FindNodeOrInsertPos (ID, InsertPos)) {
329
337
OutSatisfaction = *Cached;
330
338
return false ;
331
339
}
332
340
auto Satisfaction =
333
- std::make_unique<ConstraintSatisfaction>(Template, TemplateArgs );
341
+ std::make_unique<ConstraintSatisfaction>(Template, FlattenedArgs );
334
342
if (::CheckConstraintSatisfaction (*this , Template, ConstraintExprs,
335
- TemplateArgs , TemplateIDRange,
343
+ TemplateArgsLists , TemplateIDRange,
336
344
*Satisfaction)) {
337
345
return true ;
338
346
}
@@ -379,20 +387,21 @@ bool Sema::CheckFunctionConstraints(const FunctionDecl *FD,
379
387
}
380
388
381
389
bool Sema::EnsureTemplateArgumentListConstraints (
382
- TemplateDecl *TD, ArrayRef<TemplateArgument> TemplateArgs ,
390
+ TemplateDecl *TD, const MultiLevelTemplateArgumentList &TemplateArgsLists ,
383
391
SourceRange TemplateIDRange) {
384
392
ConstraintSatisfaction Satisfaction;
385
393
llvm::SmallVector<const Expr *, 3 > AssociatedConstraints;
386
394
TD->getAssociatedConstraints (AssociatedConstraints);
387
- if (CheckConstraintSatisfaction (TD, AssociatedConstraints, TemplateArgs ,
395
+ if (CheckConstraintSatisfaction (TD, AssociatedConstraints, TemplateArgsLists ,
388
396
TemplateIDRange, Satisfaction))
389
397
return true ;
390
398
391
399
if (!Satisfaction.IsSatisfied ) {
392
400
SmallString<128 > TemplateArgString;
393
401
TemplateArgString = " " ;
394
402
TemplateArgString += getTemplateArgumentBindingsText (
395
- TD->getTemplateParameters (), TemplateArgs.data (), TemplateArgs.size ());
403
+ TD->getTemplateParameters (), TemplateArgsLists.getInnermost ().data (),
404
+ TemplateArgsLists.getInnermost ().size ());
396
405
397
406
Diag (TemplateIDRange.getBegin (),
398
407
diag::err_template_arg_list_constraints_not_satisfied)
@@ -423,6 +432,10 @@ bool Sema::CheckInstantiatedFunctionTemplateConstraints(
423
432
// PushDeclContext because we don't have a scope.
424
433
Sema::ContextRAII savedContext (*this , Decl);
425
434
LocalInstantiationScope Scope (*this );
435
+ MultiLevelTemplateArgumentList MLTAL;
436
+ // FIXME: This will be replaced with some logic to get all the template
437
+ // arguments when we switch to deferred template instantiation.
438
+ MLTAL.addOuterTemplateArguments (TemplateArgs);
426
439
427
440
// If this is not an explicit specialization - we need to get the instantiated
428
441
// version of the template arguments and add them to scope for the
@@ -446,7 +459,7 @@ bool Sema::CheckInstantiatedFunctionTemplateConstraints(
446
459
Record = Method->getParent ();
447
460
}
448
461
CXXThisScopeRAII ThisScope (*this , Record, ThisQuals, Record != nullptr );
449
- return CheckConstraintSatisfaction (Template, TemplateAC, TemplateArgs ,
462
+ return CheckConstraintSatisfaction (Template, TemplateAC, MLTAL ,
450
463
PointOfInstantiation, Satisfaction);
451
464
}
452
465
0 commit comments