aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Sema/SemaConcept.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Sema/SemaConcept.cpp')
-rw-r--r--clang/lib/Sema/SemaConcept.cpp94
1 files changed, 50 insertions, 44 deletions
diff --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp
index ebee599..e6117f9 100644
--- a/clang/lib/Sema/SemaConcept.cpp
+++ b/clang/lib/Sema/SemaConcept.cpp
@@ -567,11 +567,12 @@ static ExprResult calculateConstraintSatisfaction(
}
static bool CheckConstraintSatisfaction(
- Sema &S, const NamedDecl *Template, ArrayRef<const Expr *> ConstraintExprs,
+ Sema &S, const NamedDecl *Template,
+ ArrayRef<AssociatedConstraint> AssociatedConstraints,
llvm::SmallVectorImpl<Expr *> &Converted,
const MultiLevelTemplateArgumentList &TemplateArgsLists,
SourceRange TemplateIDRange, ConstraintSatisfaction &Satisfaction) {
- if (ConstraintExprs.empty()) {
+ if (AssociatedConstraints.empty()) {
Satisfaction.IsSatisfied = true;
return false;
}
@@ -592,10 +593,12 @@ static bool CheckConstraintSatisfaction(
if (Inst.isInvalid())
return true;
- for (const Expr *ConstraintExpr : ConstraintExprs) {
+ for (const AssociatedConstraint &AC : AssociatedConstraints) {
+ Sema::ArgumentPackSubstitutionIndexRAII _(S,
+ AC.ArgumentPackSubstitutionIndex);
ExprResult Res = calculateConstraintSatisfaction(
S, Template, TemplateIDRange.getBegin(), TemplateArgsLists,
- ConstraintExpr, Satisfaction);
+ AC.ConstraintExpr, Satisfaction);
if (Res.isInvalid())
return true;
@@ -603,7 +606,8 @@ static bool CheckConstraintSatisfaction(
if (!Satisfaction.IsSatisfied) {
// Backfill the 'converted' list with nulls so we can keep the Converted
// and unconverted lists in sync.
- Converted.append(ConstraintExprs.size() - Converted.size(), nullptr);
+ Converted.append(AssociatedConstraints.size() - Converted.size(),
+ nullptr);
// [temp.constr.op] p2
// [...] To determine if a conjunction is satisfied, the satisfaction
// of the first operand is checked. If that is not satisfied, the
@@ -615,17 +619,18 @@ static bool CheckConstraintSatisfaction(
}
bool Sema::CheckConstraintSatisfaction(
- const NamedDecl *Template, ArrayRef<const Expr *> ConstraintExprs,
+ const NamedDecl *Template,
+ ArrayRef<AssociatedConstraint> AssociatedConstraints,
llvm::SmallVectorImpl<Expr *> &ConvertedConstraints,
const MultiLevelTemplateArgumentList &TemplateArgsLists,
SourceRange TemplateIDRange, ConstraintSatisfaction &OutSatisfaction) {
- if (ConstraintExprs.empty()) {
+ if (AssociatedConstraints.empty()) {
OutSatisfaction.IsSatisfied = true;
return false;
}
if (!Template) {
return ::CheckConstraintSatisfaction(
- *this, nullptr, ConstraintExprs, ConvertedConstraints,
+ *this, nullptr, AssociatedConstraints, ConvertedConstraints,
TemplateArgsLists, TemplateIDRange, OutSatisfaction);
}
// Invalid templates could make their way here. Substituting them could result
@@ -654,7 +659,7 @@ bool Sema::CheckConstraintSatisfaction(
auto Satisfaction =
std::make_unique<ConstraintSatisfaction>(Template, FlattenedArgs);
- if (::CheckConstraintSatisfaction(*this, Template, ConstraintExprs,
+ if (::CheckConstraintSatisfaction(*this, Template, AssociatedConstraints,
ConvertedConstraints, TemplateArgsLists,
TemplateIDRange, *Satisfaction)) {
OutSatisfaction = *Satisfaction;
@@ -923,8 +928,10 @@ bool Sema::CheckFunctionConstraints(const FunctionDecl *FD,
ForOverloadResolution);
return CheckConstraintSatisfaction(
- FD, {FD->getTrailingRequiresClause()}, *MLTAL,
- SourceRange(UsageLoc.isValid() ? UsageLoc : FD->getLocation()),
+ FD,
+ AssociatedConstraint(FD->getTrailingRequiresClause(),
+ ArgumentPackSubstitutionIndex),
+ *MLTAL, SourceRange(UsageLoc.isValid() ? UsageLoc : FD->getLocation()),
Satisfaction);
}
@@ -1099,13 +1106,13 @@ bool Sema::FriendConstraintsDependOnEnclosingTemplate(const FunctionDecl *FD) {
assert(FD->getDescribedFunctionTemplate() &&
"Non-function templates don't need to be checked");
- SmallVector<const Expr *, 3> ACs;
+ SmallVector<AssociatedConstraint, 3> ACs;
FD->getDescribedFunctionTemplate()->getAssociatedConstraints(ACs);
unsigned OldTemplateDepth = CalculateTemplateDepthForConstraints(*this, FD);
- for (const Expr *Constraint : ACs)
+ for (const AssociatedConstraint &AC : ACs)
if (ConstraintExpressionDependsOnEnclosingTemplate(FD, OldTemplateDepth,
- Constraint))
+ AC.ConstraintExpr))
return true;
return false;
@@ -1115,7 +1122,7 @@ bool Sema::EnsureTemplateArgumentListConstraints(
TemplateDecl *TD, const MultiLevelTemplateArgumentList &TemplateArgsLists,
SourceRange TemplateIDRange) {
ConstraintSatisfaction Satisfaction;
- llvm::SmallVector<const Expr *, 3> AssociatedConstraints;
+ llvm::SmallVector<AssociatedConstraint, 3> AssociatedConstraints;
TD->getAssociatedConstraints(AssociatedConstraints);
if (CheckConstraintSatisfaction(TD, AssociatedConstraints, TemplateArgsLists,
TemplateIDRange, Satisfaction))
@@ -1146,7 +1153,7 @@ bool Sema::CheckInstantiatedFunctionTemplateConstraints(
FunctionTemplateDecl *Template = Decl->getPrimaryTemplate();
// Note - code synthesis context for the constraints check is created
// inside CheckConstraintsSatisfaction.
- SmallVector<const Expr *, 3> TemplateAC;
+ SmallVector<AssociatedConstraint, 3> TemplateAC;
Template->getAssociatedConstraints(TemplateAC);
if (TemplateAC.empty()) {
Satisfaction.IsSatisfied = true;
@@ -1438,7 +1445,7 @@ void Sema::DiagnoseUnsatisfiedConstraint(
const NormalizedConstraint *Sema::getNormalizedAssociatedConstraints(
const NamedDecl *ConstrainedDecl,
- ArrayRef<const Expr *> AssociatedConstraints) {
+ ArrayRef<AssociatedConstraint> AssociatedConstraints) {
// In case the ConstrainedDecl comes from modules, it is necessary to use
// the canonical decl to avoid different atomic constraints with the 'same'
// declarations.
@@ -1446,9 +1453,8 @@ const NormalizedConstraint *Sema::getNormalizedAssociatedConstraints(
auto CacheEntry = NormalizationCache.find(ConstrainedDecl);
if (CacheEntry == NormalizationCache.end()) {
- auto Normalized =
- NormalizedConstraint::fromConstraintExprs(*this, ConstrainedDecl,
- AssociatedConstraints);
+ auto Normalized = NormalizedConstraint::fromAssociatedConstraints(
+ *this, ConstrainedDecl, AssociatedConstraints);
CacheEntry =
NormalizationCache
.try_emplace(ConstrainedDecl,
@@ -1463,7 +1469,7 @@ const NormalizedConstraint *Sema::getNormalizedAssociatedConstraints(
const NormalizedConstraint *clang::getNormalizedAssociatedConstraints(
Sema &S, const NamedDecl *ConstrainedDecl,
- ArrayRef<const Expr *> AssociatedConstraints) {
+ ArrayRef<AssociatedConstraint> AssociatedConstraints) {
return S.getNormalizedAssociatedConstraints(ConstrainedDecl,
AssociatedConstraints);
}
@@ -1593,14 +1599,14 @@ NormalizedConstraint &NormalizedConstraint::getRHS() const {
}
std::optional<NormalizedConstraint>
-NormalizedConstraint::fromConstraintExprs(Sema &S, const NamedDecl *D,
- ArrayRef<const Expr *> E) {
- assert(E.size() != 0);
- auto Conjunction = fromConstraintExpr(S, D, E[0]);
+NormalizedConstraint::fromAssociatedConstraints(
+ Sema &S, const NamedDecl *D, ArrayRef<AssociatedConstraint> ACs) {
+ assert(ACs.size() != 0);
+ auto Conjunction = fromConstraintExpr(S, D, ACs[0].ConstraintExpr);
if (!Conjunction)
return std::nullopt;
- for (unsigned I = 1; I < E.size(); ++I) {
- auto Next = fromConstraintExpr(S, D, E[I]);
+ for (unsigned I = 1; I < ACs.size(); ++I) {
+ auto Next = fromConstraintExpr(S, D, ACs[I].ConstraintExpr);
if (!Next)
return std::nullopt;
*Conjunction = NormalizedConstraint(S.Context, std::move(*Conjunction),
@@ -1655,8 +1661,8 @@ NormalizedConstraint::fromConstraintExpr(Sema &S, const NamedDecl *D,
// expression, the program is ill-formed; no diagnostic is required.
// [...]
ConceptDecl *CD = CSE->getNamedConcept();
- SubNF = S.getNormalizedAssociatedConstraints(CD,
- {CD->getConstraintExpr()});
+ SubNF = S.getNormalizedAssociatedConstraints(
+ CD, AssociatedConstraint(CD->getConstraintExpr()));
if (!SubNF)
return std::nullopt;
}
@@ -1731,9 +1737,9 @@ bool FoldExpandedConstraint::AreCompatibleForSubsumption(
}
bool Sema::IsAtLeastAsConstrained(const NamedDecl *D1,
- MutableArrayRef<const Expr *> AC1,
+ MutableArrayRef<AssociatedConstraint> AC1,
const NamedDecl *D2,
- MutableArrayRef<const Expr *> AC2,
+ MutableArrayRef<AssociatedConstraint> AC2,
bool &Result) {
#ifndef NDEBUG
if (const auto *FD1 = dyn_cast<FunctionDecl>(D1)) {
@@ -1771,13 +1777,15 @@ bool Sema::IsAtLeastAsConstrained(const NamedDecl *D1,
for (size_t I = 0; I != AC1.size() && I != AC2.size(); ++I) {
if (Depth2 > Depth1) {
- AC1[I] = AdjustConstraintDepth(*this, Depth2 - Depth1)
- .TransformExpr(const_cast<Expr *>(AC1[I]))
- .get();
+ AC1[I].ConstraintExpr =
+ AdjustConstraintDepth(*this, Depth2 - Depth1)
+ .TransformExpr(const_cast<Expr *>(AC1[I].ConstraintExpr))
+ .get();
} else if (Depth1 > Depth2) {
- AC2[I] = AdjustConstraintDepth(*this, Depth1 - Depth2)
- .TransformExpr(const_cast<Expr *>(AC2[I]))
- .get();
+ AC2[I].ConstraintExpr =
+ AdjustConstraintDepth(*this, Depth1 - Depth2)
+ .TransformExpr(const_cast<Expr *>(AC2[I].ConstraintExpr))
+ .get();
}
}
@@ -1793,9 +1801,8 @@ bool Sema::IsAtLeastAsConstrained(const NamedDecl *D1,
}
bool Sema::MaybeEmitAmbiguousAtomicConstraintsDiagnostic(
- const NamedDecl *D1, ArrayRef<const Expr *> AC1, const NamedDecl *D2,
- ArrayRef<const Expr *> AC2) {
-
+ const NamedDecl *D1, ArrayRef<AssociatedConstraint> AC1,
+ const NamedDecl *D2, ArrayRef<AssociatedConstraint> AC2) {
if (isSFINAEContext())
// No need to work here because our notes would be discarded.
return false;
@@ -2106,10 +2113,9 @@ void SubsumptionChecker::AddUniqueClauseToFormula(Formula &F, Clause C) {
F.push_back(C);
}
-std::optional<bool> SubsumptionChecker::Subsumes(const NamedDecl *DP,
- ArrayRef<const Expr *> P,
- const NamedDecl *DQ,
- ArrayRef<const Expr *> Q) {
+std::optional<bool> SubsumptionChecker::Subsumes(
+ const NamedDecl *DP, ArrayRef<AssociatedConstraint> P, const NamedDecl *DQ,
+ ArrayRef<AssociatedConstraint> Q) {
const NormalizedConstraint *PNormalized =
getNormalizedAssociatedConstraints(SemaRef, DP, P);
if (!PNormalized)