@@ -167,9 +167,8 @@ calculateConstraintSatisfaction(Sema &S, const Expr *ConstraintExpr,
167
167
return false ;
168
168
}
169
169
170
- template <typename TemplateDeclT>
171
170
static bool calculateConstraintSatisfaction (
172
- Sema &S, TemplateDeclT *Template, ArrayRef<TemplateArgument> TemplateArgs,
171
+ Sema &S, const NamedDecl *Template, ArrayRef<TemplateArgument> TemplateArgs,
173
172
SourceLocation TemplateNameLoc, MultiLevelTemplateArgumentList &MLTAL,
174
173
const Expr *ConstraintExpr, ConstraintSatisfaction &Satisfaction) {
175
174
return calculateConstraintSatisfaction (
@@ -182,8 +181,9 @@ static bool calculateConstraintSatisfaction(
182
181
{
183
182
TemplateDeductionInfo Info (TemplateNameLoc);
184
183
Sema::InstantiatingTemplate Inst (S, AtomicExpr->getBeginLoc (),
185
- Sema::InstantiatingTemplate::ConstraintSubstitution{}, Template,
186
- Info, AtomicExpr->getSourceRange ());
184
+ Sema::InstantiatingTemplate::ConstraintSubstitution{},
185
+ const_cast <NamedDecl *>(Template), Info,
186
+ AtomicExpr->getSourceRange ());
187
187
if (Inst.isInvalid ())
188
188
return ExprError ();
189
189
// We do not want error diagnostics escaping here.
@@ -230,8 +230,7 @@ static bool calculateConstraintSatisfaction(
230
230
});
231
231
}
232
232
233
- template <typename TemplateDeclT>
234
- static bool CheckConstraintSatisfaction (Sema &S, TemplateDeclT *Template,
233
+ static bool CheckConstraintSatisfaction (Sema &S, const NamedDecl *Template,
235
234
ArrayRef<const Expr *> ConstraintExprs,
236
235
ArrayRef<TemplateArgument> TemplateArgs,
237
236
SourceRange TemplateIDRange,
@@ -249,8 +248,8 @@ static bool CheckConstraintSatisfaction(Sema &S, TemplateDeclT *Template,
249
248
}
250
249
251
250
Sema::InstantiatingTemplate Inst (S, TemplateIDRange.getBegin (),
252
- Sema::InstantiatingTemplate::ConstraintsCheck{}, Template, TemplateArgs,
253
- TemplateIDRange);
251
+ Sema::InstantiatingTemplate::ConstraintsCheck{},
252
+ const_cast <NamedDecl *>(Template), TemplateArgs, TemplateIDRange);
254
253
if (Inst.isInvalid ())
255
254
return true ;
256
255
@@ -273,7 +272,7 @@ static bool CheckConstraintSatisfaction(Sema &S, TemplateDeclT *Template,
273
272
}
274
273
275
274
bool Sema::CheckConstraintSatisfaction (
276
- NamedDecl *Template, ArrayRef<const Expr *> ConstraintExprs,
275
+ const NamedDecl *Template, ArrayRef<const Expr *> ConstraintExprs,
277
276
ArrayRef<TemplateArgument> TemplateArgs, SourceRange TemplateIDRange,
278
277
ConstraintSatisfaction &OutSatisfaction) {
279
278
if (ConstraintExprs.empty ()) {
@@ -284,7 +283,8 @@ bool Sema::CheckConstraintSatisfaction(
284
283
llvm::FoldingSetNodeID ID;
285
284
void *InsertPos;
286
285
ConstraintSatisfaction *Satisfaction = nullptr ;
287
- if (LangOpts.ConceptSatisfactionCaching ) {
286
+ bool ShouldCache = LangOpts.ConceptSatisfactionCaching && Template;
287
+ if (ShouldCache) {
288
288
ConstraintSatisfaction::Profile (ID, Context, Template, TemplateArgs);
289
289
Satisfaction = SatisfactionCache.FindNodeOrInsertPos (ID, InsertPos);
290
290
if (Satisfaction) {
@@ -295,27 +295,15 @@ bool Sema::CheckConstraintSatisfaction(
295
295
} else {
296
296
Satisfaction = &OutSatisfaction;
297
297
}
298
- bool Failed;
299
- if (auto *T = dyn_cast<TemplateDecl>(Template))
300
- Failed = ::CheckConstraintSatisfaction (*this , T, ConstraintExprs,
301
- TemplateArgs, TemplateIDRange,
302
- *Satisfaction);
303
- else if (auto *P =
304
- dyn_cast<ClassTemplatePartialSpecializationDecl>(Template))
305
- Failed = ::CheckConstraintSatisfaction (*this , P, ConstraintExprs,
306
- TemplateArgs, TemplateIDRange,
307
- *Satisfaction);
308
- else
309
- Failed = ::CheckConstraintSatisfaction (
310
- *this , cast<VarTemplatePartialSpecializationDecl>(Template),
311
- ConstraintExprs, TemplateArgs, TemplateIDRange, *Satisfaction);
312
- if (Failed) {
313
- if (LangOpts.ConceptSatisfactionCaching )
298
+ if (::CheckConstraintSatisfaction (*this , Template, ConstraintExprs,
299
+ TemplateArgs, TemplateIDRange,
300
+ *Satisfaction)) {
301
+ if (ShouldCache)
314
302
delete Satisfaction;
315
303
return true ;
316
304
}
317
305
318
- if (LangOpts. ConceptSatisfactionCaching ) {
306
+ if (ShouldCache ) {
319
307
// We cannot use InsertNode here because CheckConstraintSatisfaction might
320
308
// have invalidated it.
321
309
SatisfactionCache.InsertNode (Satisfaction);
@@ -333,6 +321,22 @@ bool Sema::CheckConstraintSatisfaction(const Expr *ConstraintExpr,
333
321
});
334
322
}
335
323
324
+ bool Sema::CheckFunctionConstraints (const FunctionDecl *FD,
325
+ ConstraintSatisfaction &Satisfaction,
326
+ SourceLocation UsageLoc) {
327
+ const Expr *RC = FD->getTrailingRequiresClause ();
328
+ assert (!RC->isInstantiationDependent () &&
329
+ " CheckFunctionConstraints can only be used with functions with "
330
+ " non-dependent constraints" );
331
+ // We substitute with empty arguments in order to rebuild the atomic
332
+ // constraint in a constant-evaluated context.
333
+ // FIXME: Should this be a dedicated TreeTransform?
334
+ return CheckConstraintSatisfaction (
335
+ FD, {RC}, /* TemplateArgs=*/ {},
336
+ SourceRange (UsageLoc.isValid () ? UsageLoc : FD->getLocation ()),
337
+ Satisfaction);
338
+ }
339
+
336
340
bool Sema::EnsureTemplateArgumentListConstraints (
337
341
TemplateDecl *TD, ArrayRef<TemplateArgument> TemplateArgs,
338
342
SourceRange TemplateIDRange) {
0 commit comments