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