forked from OSchip/llvm-project
[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.
This commit is contained in:
parent
fbe022f189
commit
b25902736c
|
@ -7153,7 +7153,7 @@ public:
|
|||
/// false otherwise.
|
||||
bool CheckConstraintSatisfaction(
|
||||
const NamedDecl *Template, ArrayRef<const Expr *> ConstraintExprs,
|
||||
ArrayRef<TemplateArgument> TemplateArgs,
|
||||
const MultiLevelTemplateArgumentList &TemplateArgLists,
|
||||
SourceRange TemplateIDRange, ConstraintSatisfaction &Satisfaction);
|
||||
|
||||
/// \brief Check whether the given non-dependent constraint expression is
|
||||
|
@ -7189,9 +7189,10 @@ public:
|
|||
///
|
||||
/// \returns true if the constrains are not satisfied or could not be checked
|
||||
/// for satisfaction, false if the constraints are satisfied.
|
||||
bool EnsureTemplateArgumentListConstraints(TemplateDecl *Template,
|
||||
ArrayRef<TemplateArgument> TemplateArgs,
|
||||
SourceRange TemplateIDRange);
|
||||
bool EnsureTemplateArgumentListConstraints(
|
||||
TemplateDecl *Template,
|
||||
const MultiLevelTemplateArgumentList &TemplateArgs,
|
||||
SourceRange TemplateIDRange);
|
||||
|
||||
/// \brief Emit diagnostics explaining why a constraint expression was deemed
|
||||
/// unsatisfied.
|
||||
|
|
|
@ -199,9 +199,9 @@ calculateConstraintSatisfaction(Sema &S, const Expr *ConstraintExpr,
|
|||
}
|
||||
|
||||
static bool calculateConstraintSatisfaction(
|
||||
Sema &S, const NamedDecl *Template, ArrayRef<TemplateArgument> TemplateArgs,
|
||||
SourceLocation TemplateNameLoc, MultiLevelTemplateArgumentList &MLTAL,
|
||||
const Expr *ConstraintExpr, ConstraintSatisfaction &Satisfaction) {
|
||||
Sema &S, const NamedDecl *Template, SourceLocation TemplateNameLoc,
|
||||
const MultiLevelTemplateArgumentList &MLTAL, const Expr *ConstraintExpr,
|
||||
ConstraintSatisfaction &Satisfaction) {
|
||||
return calculateConstraintSatisfaction(
|
||||
S, ConstraintExpr, Satisfaction, [&](const Expr *AtomicExpr) {
|
||||
EnterExpressionEvaluationContext ConstantEvaluated(
|
||||
|
@ -268,36 +268,35 @@ static bool calculateConstraintSatisfaction(
|
|||
});
|
||||
}
|
||||
|
||||
static bool CheckConstraintSatisfaction(Sema &S, const NamedDecl *Template,
|
||||
ArrayRef<const Expr *> ConstraintExprs,
|
||||
ArrayRef<TemplateArgument> TemplateArgs,
|
||||
SourceRange TemplateIDRange,
|
||||
ConstraintSatisfaction &Satisfaction) {
|
||||
static bool CheckConstraintSatisfaction(
|
||||
Sema &S, const NamedDecl *Template, ArrayRef<const Expr *> ConstraintExprs,
|
||||
const MultiLevelTemplateArgumentList &TemplateArgsLists,
|
||||
SourceRange TemplateIDRange, ConstraintSatisfaction &Satisfaction) {
|
||||
if (ConstraintExprs.empty()) {
|
||||
Satisfaction.IsSatisfied = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
for (auto& Arg : TemplateArgs)
|
||||
if (Arg.isInstantiationDependent()) {
|
||||
// No need to check satisfaction for dependent constraint expressions.
|
||||
Satisfaction.IsSatisfied = true;
|
||||
return false;
|
||||
}
|
||||
if (TemplateArgsLists.isAnyArgInstantiationDependent()) {
|
||||
// No need to check satisfaction for dependent constraint expressions.
|
||||
Satisfaction.IsSatisfied = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
ArrayRef<TemplateArgument> TemplateArgs =
|
||||
TemplateArgsLists.getNumSubstitutedLevels() > 0
|
||||
? TemplateArgsLists.getOutermost()
|
||||
: ArrayRef<TemplateArgument> {};
|
||||
Sema::InstantiatingTemplate Inst(S, TemplateIDRange.getBegin(),
|
||||
Sema::InstantiatingTemplate::ConstraintsCheck{},
|
||||
const_cast<NamedDecl *>(Template), TemplateArgs, TemplateIDRange);
|
||||
if (Inst.isInvalid())
|
||||
return true;
|
||||
|
||||
MultiLevelTemplateArgumentList MLTAL;
|
||||
MLTAL.addOuterTemplateArguments(TemplateArgs);
|
||||
|
||||
for (const Expr *ConstraintExpr : ConstraintExprs) {
|
||||
if (calculateConstraintSatisfaction(S, Template, TemplateArgs,
|
||||
TemplateIDRange.getBegin(), MLTAL,
|
||||
ConstraintExpr, Satisfaction))
|
||||
if (calculateConstraintSatisfaction(S, Template, TemplateIDRange.getBegin(),
|
||||
TemplateArgsLists, ConstraintExpr,
|
||||
Satisfaction))
|
||||
return true;
|
||||
if (!Satisfaction.IsSatisfied)
|
||||
// [temp.constr.op] p2
|
||||
|
@ -311,28 +310,37 @@ static bool CheckConstraintSatisfaction(Sema &S, const NamedDecl *Template,
|
|||
|
||||
bool Sema::CheckConstraintSatisfaction(
|
||||
const NamedDecl *Template, ArrayRef<const Expr *> ConstraintExprs,
|
||||
ArrayRef<TemplateArgument> TemplateArgs, SourceRange TemplateIDRange,
|
||||
ConstraintSatisfaction &OutSatisfaction) {
|
||||
const MultiLevelTemplateArgumentList &TemplateArgsLists,
|
||||
SourceRange TemplateIDRange, ConstraintSatisfaction &OutSatisfaction) {
|
||||
if (ConstraintExprs.empty()) {
|
||||
OutSatisfaction.IsSatisfied = true;
|
||||
return false;
|
||||
}
|
||||
if (!Template) {
|
||||
return ::CheckConstraintSatisfaction(*this, nullptr, ConstraintExprs,
|
||||
TemplateArgs, TemplateIDRange,
|
||||
TemplateArgsLists, TemplateIDRange,
|
||||
OutSatisfaction);
|
||||
}
|
||||
|
||||
// A list of the template argument list flattened in a predictible manner for
|
||||
// the purposes of caching. The ConstraintSatisfaction type is in AST so it
|
||||
// has no access to the MultiLevelTemplateArgumentList, so this has to happen
|
||||
// here.
|
||||
llvm::SmallVector<TemplateArgument, 4> FlattenedArgs;
|
||||
for (ArrayRef<TemplateArgument> List : TemplateArgsLists)
|
||||
FlattenedArgs.insert(FlattenedArgs.end(), List.begin(), List.end());
|
||||
|
||||
llvm::FoldingSetNodeID ID;
|
||||
ConstraintSatisfaction::Profile(ID, Context, Template, TemplateArgs);
|
||||
ConstraintSatisfaction::Profile(ID, Context, Template, FlattenedArgs);
|
||||
void *InsertPos;
|
||||
if (auto *Cached = SatisfactionCache.FindNodeOrInsertPos(ID, InsertPos)) {
|
||||
OutSatisfaction = *Cached;
|
||||
return false;
|
||||
}
|
||||
auto Satisfaction =
|
||||
std::make_unique<ConstraintSatisfaction>(Template, TemplateArgs);
|
||||
std::make_unique<ConstraintSatisfaction>(Template, FlattenedArgs);
|
||||
if (::CheckConstraintSatisfaction(*this, Template, ConstraintExprs,
|
||||
TemplateArgs, TemplateIDRange,
|
||||
TemplateArgsLists, TemplateIDRange,
|
||||
*Satisfaction)) {
|
||||
return true;
|
||||
}
|
||||
|
@ -379,12 +387,12 @@ bool Sema::CheckFunctionConstraints(const FunctionDecl *FD,
|
|||
}
|
||||
|
||||
bool Sema::EnsureTemplateArgumentListConstraints(
|
||||
TemplateDecl *TD, ArrayRef<TemplateArgument> TemplateArgs,
|
||||
TemplateDecl *TD, const MultiLevelTemplateArgumentList &TemplateArgsLists,
|
||||
SourceRange TemplateIDRange) {
|
||||
ConstraintSatisfaction Satisfaction;
|
||||
llvm::SmallVector<const Expr *, 3> AssociatedConstraints;
|
||||
TD->getAssociatedConstraints(AssociatedConstraints);
|
||||
if (CheckConstraintSatisfaction(TD, AssociatedConstraints, TemplateArgs,
|
||||
if (CheckConstraintSatisfaction(TD, AssociatedConstraints, TemplateArgsLists,
|
||||
TemplateIDRange, Satisfaction))
|
||||
return true;
|
||||
|
||||
|
@ -392,7 +400,8 @@ bool Sema::EnsureTemplateArgumentListConstraints(
|
|||
SmallString<128> TemplateArgString;
|
||||
TemplateArgString = " ";
|
||||
TemplateArgString += getTemplateArgumentBindingsText(
|
||||
TD->getTemplateParameters(), TemplateArgs.data(), TemplateArgs.size());
|
||||
TD->getTemplateParameters(), TemplateArgsLists.getInnermost().data(),
|
||||
TemplateArgsLists.getInnermost().size());
|
||||
|
||||
Diag(TemplateIDRange.getBegin(),
|
||||
diag::err_template_arg_list_constraints_not_satisfied)
|
||||
|
@ -423,6 +432,10 @@ bool Sema::CheckInstantiatedFunctionTemplateConstraints(
|
|||
// PushDeclContext because we don't have a scope.
|
||||
Sema::ContextRAII savedContext(*this, Decl);
|
||||
LocalInstantiationScope Scope(*this);
|
||||
MultiLevelTemplateArgumentList MLTAL;
|
||||
// FIXME: This will be replaced with some logic to get all the template
|
||||
// arguments when we switch to deferred template instantiation.
|
||||
MLTAL.addOuterTemplateArguments(TemplateArgs);
|
||||
|
||||
// If this is not an explicit specialization - we need to get the instantiated
|
||||
// version of the template arguments and add them to scope for the
|
||||
|
@ -446,7 +459,7 @@ bool Sema::CheckInstantiatedFunctionTemplateConstraints(
|
|||
Record = Method->getParent();
|
||||
}
|
||||
CXXThisScopeRAII ThisScope(*this, Record, ThisQuals, Record != nullptr);
|
||||
return CheckConstraintSatisfaction(Template, TemplateAC, TemplateArgs,
|
||||
return CheckConstraintSatisfaction(Template, TemplateAC, MLTAL,
|
||||
PointOfInstantiation, Satisfaction);
|
||||
}
|
||||
|
||||
|
|
|
@ -4751,9 +4751,12 @@ Sema::CheckConceptTemplateId(const CXXScopeSpec &SS,
|
|||
bool AreArgsDependent =
|
||||
TemplateSpecializationType::anyDependentTemplateArguments(*TemplateArgs,
|
||||
Converted);
|
||||
MultiLevelTemplateArgumentList MLTAL;
|
||||
MLTAL.addOuterTemplateArguments(Converted);
|
||||
LocalInstantiationScope Scope(*this);
|
||||
if (!AreArgsDependent &&
|
||||
CheckConstraintSatisfaction(
|
||||
NamedConcept, {NamedConcept->getConstraintExpr()}, Converted,
|
||||
NamedConcept, {NamedConcept->getConstraintExpr()}, MLTAL,
|
||||
SourceRange(SS.isSet() ? SS.getBeginLoc() : ConceptNameInfo.getLoc(),
|
||||
TemplateArgs->getRAngleLoc()),
|
||||
Satisfaction))
|
||||
|
@ -5970,13 +5973,18 @@ bool Sema::CheckTemplateArgumentList(
|
|||
if (UpdateArgsWithConversions)
|
||||
TemplateArgs = std::move(NewArgs);
|
||||
|
||||
if (!PartialTemplateArgs &&
|
||||
EnsureTemplateArgumentListConstraints(
|
||||
Template, Converted, SourceRange(TemplateLoc,
|
||||
TemplateArgs.getRAngleLoc()))) {
|
||||
if (ConstraintsNotSatisfied)
|
||||
*ConstraintsNotSatisfied = true;
|
||||
return true;
|
||||
if (!PartialTemplateArgs) {
|
||||
// FIXME: This will be changed a bit once deferred concept instantiation is
|
||||
// implemented.
|
||||
MultiLevelTemplateArgumentList MLTAL;
|
||||
MLTAL.addOuterTemplateArguments(Converted);
|
||||
if (EnsureTemplateArgumentListConstraints(
|
||||
Template, MLTAL,
|
||||
SourceRange(TemplateLoc, TemplateArgs.getRAngleLoc()))) {
|
||||
if (ConstraintsNotSatisfied)
|
||||
*ConstraintsNotSatisfied = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
|
@ -2791,8 +2791,13 @@ CheckDeducedArgumentConstraints(Sema& S, TemplateDeclT *Template,
|
|||
TemplateDeductionInfo& Info) {
|
||||
llvm::SmallVector<const Expr *, 3> AssociatedConstraints;
|
||||
Template->getAssociatedConstraints(AssociatedConstraints);
|
||||
// FIXME: This will change quite a bit once deferred concept instantiation is
|
||||
// implemented.
|
||||
MultiLevelTemplateArgumentList MLTAL;
|
||||
MLTAL.addOuterTemplateArguments(DeducedArgs);
|
||||
|
||||
if (S.CheckConstraintSatisfaction(Template, AssociatedConstraints,
|
||||
DeducedArgs, Info.getLocation(),
|
||||
MLTAL, Info.getLocation(),
|
||||
Info.AssociatedConstraintsSatisfaction) ||
|
||||
!Info.AssociatedConstraintsSatisfaction.IsSatisfied) {
|
||||
Info.reset(TemplateArgumentList::CreateCopy(S.Context, DeducedArgs));
|
||||
|
@ -4572,8 +4577,10 @@ CheckDeducedPlaceholderConstraints(Sema &S, const AutoType &Type,
|
|||
if (S.CheckTemplateArgumentList(Concept, SourceLocation(), TemplateArgs,
|
||||
/*PartialTemplateArgs=*/false, Converted))
|
||||
return Sema::DAR_FailedAlreadyDiagnosed;
|
||||
MultiLevelTemplateArgumentList MLTAL;
|
||||
MLTAL.addOuterTemplateArguments(Converted);
|
||||
if (S.CheckConstraintSatisfaction(Concept, {Concept->getConstraintExpr()},
|
||||
Converted, TypeLoc.getLocalSourceRange(),
|
||||
MLTAL, TypeLoc.getLocalSourceRange(),
|
||||
Satisfaction))
|
||||
return Sema::DAR_FailedAlreadyDiagnosed;
|
||||
if (!Satisfaction.IsSatisfied) {
|
||||
|
|
Loading…
Reference in New Issue