Skip to content

Commit b259027

Browse files
author
Erich Keane
committed
[NFCI] Propagate MLTAL through more concepts in prep of deferred inst.
In preperation of the deferred instantation progress, this patch propagates the multi-level template argument lists further through the API to reduce the size of that patch.
1 parent fbe022f commit b259027

File tree

4 files changed

+73
-44
lines changed

4 files changed

+73
-44
lines changed

clang/include/clang/Sema/Sema.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7153,7 +7153,7 @@ class Sema final {
71537153
/// false otherwise.
71547154
bool CheckConstraintSatisfaction(
71557155
const NamedDecl *Template, ArrayRef<const Expr *> ConstraintExprs,
7156-
ArrayRef<TemplateArgument> TemplateArgs,
7156+
const MultiLevelTemplateArgumentList &TemplateArgLists,
71577157
SourceRange TemplateIDRange, ConstraintSatisfaction &Satisfaction);
71587158

71597159
/// \brief Check whether the given non-dependent constraint expression is
@@ -7189,9 +7189,10 @@ class Sema final {
71897189
///
71907190
/// \returns true if the constrains are not satisfied or could not be checked
71917191
/// for satisfaction, false if the constraints are satisfied.
7192-
bool EnsureTemplateArgumentListConstraints(TemplateDecl *Template,
7193-
ArrayRef<TemplateArgument> TemplateArgs,
7194-
SourceRange TemplateIDRange);
7192+
bool EnsureTemplateArgumentListConstraints(
7193+
TemplateDecl *Template,
7194+
const MultiLevelTemplateArgumentList &TemplateArgs,
7195+
SourceRange TemplateIDRange);
71957196

71967197
/// \brief Emit diagnostics explaining why a constraint expression was deemed
71977198
/// unsatisfied.

clang/lib/Sema/SemaConcept.cpp

Lines changed: 43 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -199,9 +199,9 @@ calculateConstraintSatisfaction(Sema &S, const Expr *ConstraintExpr,
199199
}
200200

201201
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) {
205205
return calculateConstraintSatisfaction(
206206
S, ConstraintExpr, Satisfaction, [&](const Expr *AtomicExpr) {
207207
EnterExpressionEvaluationContext ConstantEvaluated(
@@ -268,36 +268,35 @@ static bool calculateConstraintSatisfaction(
268268
});
269269
}
270270

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) {
276275
if (ConstraintExprs.empty()) {
277276
Satisfaction.IsSatisfied = true;
278277
return false;
279278
}
280279

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+
}
287285

286+
ArrayRef<TemplateArgument> TemplateArgs =
287+
TemplateArgsLists.getNumSubstitutedLevels() > 0
288+
? TemplateArgsLists.getOutermost()
289+
: ArrayRef<TemplateArgument> {};
288290
Sema::InstantiatingTemplate Inst(S, TemplateIDRange.getBegin(),
289291
Sema::InstantiatingTemplate::ConstraintsCheck{},
290292
const_cast<NamedDecl *>(Template), TemplateArgs, TemplateIDRange);
291293
if (Inst.isInvalid())
292294
return true;
293295

294-
MultiLevelTemplateArgumentList MLTAL;
295-
MLTAL.addOuterTemplateArguments(TemplateArgs);
296-
297296
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))
301300
return true;
302301
if (!Satisfaction.IsSatisfied)
303302
// [temp.constr.op] p2
@@ -311,28 +310,37 @@ static bool CheckConstraintSatisfaction(Sema &S, const NamedDecl *Template,
311310

312311
bool Sema::CheckConstraintSatisfaction(
313312
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) {
316315
if (ConstraintExprs.empty()) {
317316
OutSatisfaction.IsSatisfied = true;
318317
return false;
319318
}
320319
if (!Template) {
321320
return ::CheckConstraintSatisfaction(*this, nullptr, ConstraintExprs,
322-
TemplateArgs, TemplateIDRange,
321+
TemplateArgsLists, TemplateIDRange,
323322
OutSatisfaction);
324323
}
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+
325333
llvm::FoldingSetNodeID ID;
326-
ConstraintSatisfaction::Profile(ID, Context, Template, TemplateArgs);
334+
ConstraintSatisfaction::Profile(ID, Context, Template, FlattenedArgs);
327335
void *InsertPos;
328336
if (auto *Cached = SatisfactionCache.FindNodeOrInsertPos(ID, InsertPos)) {
329337
OutSatisfaction = *Cached;
330338
return false;
331339
}
332340
auto Satisfaction =
333-
std::make_unique<ConstraintSatisfaction>(Template, TemplateArgs);
341+
std::make_unique<ConstraintSatisfaction>(Template, FlattenedArgs);
334342
if (::CheckConstraintSatisfaction(*this, Template, ConstraintExprs,
335-
TemplateArgs, TemplateIDRange,
343+
TemplateArgsLists, TemplateIDRange,
336344
*Satisfaction)) {
337345
return true;
338346
}
@@ -379,20 +387,21 @@ bool Sema::CheckFunctionConstraints(const FunctionDecl *FD,
379387
}
380388

381389
bool Sema::EnsureTemplateArgumentListConstraints(
382-
TemplateDecl *TD, ArrayRef<TemplateArgument> TemplateArgs,
390+
TemplateDecl *TD, const MultiLevelTemplateArgumentList &TemplateArgsLists,
383391
SourceRange TemplateIDRange) {
384392
ConstraintSatisfaction Satisfaction;
385393
llvm::SmallVector<const Expr *, 3> AssociatedConstraints;
386394
TD->getAssociatedConstraints(AssociatedConstraints);
387-
if (CheckConstraintSatisfaction(TD, AssociatedConstraints, TemplateArgs,
395+
if (CheckConstraintSatisfaction(TD, AssociatedConstraints, TemplateArgsLists,
388396
TemplateIDRange, Satisfaction))
389397
return true;
390398

391399
if (!Satisfaction.IsSatisfied) {
392400
SmallString<128> TemplateArgString;
393401
TemplateArgString = " ";
394402
TemplateArgString += getTemplateArgumentBindingsText(
395-
TD->getTemplateParameters(), TemplateArgs.data(), TemplateArgs.size());
403+
TD->getTemplateParameters(), TemplateArgsLists.getInnermost().data(),
404+
TemplateArgsLists.getInnermost().size());
396405

397406
Diag(TemplateIDRange.getBegin(),
398407
diag::err_template_arg_list_constraints_not_satisfied)
@@ -423,6 +432,10 @@ bool Sema::CheckInstantiatedFunctionTemplateConstraints(
423432
// PushDeclContext because we don't have a scope.
424433
Sema::ContextRAII savedContext(*this, Decl);
425434
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);
426439

427440
// If this is not an explicit specialization - we need to get the instantiated
428441
// version of the template arguments and add them to scope for the
@@ -446,7 +459,7 @@ bool Sema::CheckInstantiatedFunctionTemplateConstraints(
446459
Record = Method->getParent();
447460
}
448461
CXXThisScopeRAII ThisScope(*this, Record, ThisQuals, Record != nullptr);
449-
return CheckConstraintSatisfaction(Template, TemplateAC, TemplateArgs,
462+
return CheckConstraintSatisfaction(Template, TemplateAC, MLTAL,
450463
PointOfInstantiation, Satisfaction);
451464
}
452465

clang/lib/Sema/SemaTemplate.cpp

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4751,9 +4751,12 @@ Sema::CheckConceptTemplateId(const CXXScopeSpec &SS,
47514751
bool AreArgsDependent =
47524752
TemplateSpecializationType::anyDependentTemplateArguments(*TemplateArgs,
47534753
Converted);
4754+
MultiLevelTemplateArgumentList MLTAL;
4755+
MLTAL.addOuterTemplateArguments(Converted);
4756+
LocalInstantiationScope Scope(*this);
47544757
if (!AreArgsDependent &&
47554758
CheckConstraintSatisfaction(
4756-
NamedConcept, {NamedConcept->getConstraintExpr()}, Converted,
4759+
NamedConcept, {NamedConcept->getConstraintExpr()}, MLTAL,
47574760
SourceRange(SS.isSet() ? SS.getBeginLoc() : ConceptNameInfo.getLoc(),
47584761
TemplateArgs->getRAngleLoc()),
47594762
Satisfaction))
@@ -5970,13 +5973,18 @@ bool Sema::CheckTemplateArgumentList(
59705973
if (UpdateArgsWithConversions)
59715974
TemplateArgs = std::move(NewArgs);
59725975

5973-
if (!PartialTemplateArgs &&
5974-
EnsureTemplateArgumentListConstraints(
5975-
Template, Converted, SourceRange(TemplateLoc,
5976-
TemplateArgs.getRAngleLoc()))) {
5977-
if (ConstraintsNotSatisfied)
5978-
*ConstraintsNotSatisfied = true;
5979-
return true;
5976+
if (!PartialTemplateArgs) {
5977+
// FIXME: This will be changed a bit once deferred concept instantiation is
5978+
// implemented.
5979+
MultiLevelTemplateArgumentList MLTAL;
5980+
MLTAL.addOuterTemplateArguments(Converted);
5981+
if (EnsureTemplateArgumentListConstraints(
5982+
Template, MLTAL,
5983+
SourceRange(TemplateLoc, TemplateArgs.getRAngleLoc()))) {
5984+
if (ConstraintsNotSatisfied)
5985+
*ConstraintsNotSatisfied = true;
5986+
return true;
5987+
}
59805988
}
59815989

59825990
return false;

clang/lib/Sema/SemaTemplateDeduction.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2791,8 +2791,13 @@ CheckDeducedArgumentConstraints(Sema& S, TemplateDeclT *Template,
27912791
TemplateDeductionInfo& Info) {
27922792
llvm::SmallVector<const Expr *, 3> AssociatedConstraints;
27932793
Template->getAssociatedConstraints(AssociatedConstraints);
2794+
// FIXME: This will change quite a bit once deferred concept instantiation is
2795+
// implemented.
2796+
MultiLevelTemplateArgumentList MLTAL;
2797+
MLTAL.addOuterTemplateArguments(DeducedArgs);
2798+
27942799
if (S.CheckConstraintSatisfaction(Template, AssociatedConstraints,
2795-
DeducedArgs, Info.getLocation(),
2800+
MLTAL, Info.getLocation(),
27962801
Info.AssociatedConstraintsSatisfaction) ||
27972802
!Info.AssociatedConstraintsSatisfaction.IsSatisfied) {
27982803
Info.reset(TemplateArgumentList::CreateCopy(S.Context, DeducedArgs));
@@ -4572,8 +4577,10 @@ CheckDeducedPlaceholderConstraints(Sema &S, const AutoType &Type,
45724577
if (S.CheckTemplateArgumentList(Concept, SourceLocation(), TemplateArgs,
45734578
/*PartialTemplateArgs=*/false, Converted))
45744579
return Sema::DAR_FailedAlreadyDiagnosed;
4580+
MultiLevelTemplateArgumentList MLTAL;
4581+
MLTAL.addOuterTemplateArguments(Converted);
45754582
if (S.CheckConstraintSatisfaction(Concept, {Concept->getConstraintExpr()},
4576-
Converted, TypeLoc.getLocalSourceRange(),
4583+
MLTAL, TypeLoc.getLocalSourceRange(),
45774584
Satisfaction))
45784585
return Sema::DAR_FailedAlreadyDiagnosed;
45794586
if (!Satisfaction.IsSatisfied) {

0 commit comments

Comments
 (0)