[clang] [Clang] Improve subsumption. (PR #132849)
via cfe-commits
cfe-commits at lists.llvm.org
Sun Mar 30 02:28:42 PDT 2025
================
@@ -170,102 +132,112 @@ struct alignas(ConstraintAlignment) FoldExpandedConstraint {
const Expr *Pattern)
: Kind(K), Constraint(std::move(C)), Pattern(Pattern) {};
- template <typename AtomicSubsumptionEvaluator>
- bool subsumes(const FoldExpandedConstraint &Other,
- const AtomicSubsumptionEvaluator &E) const;
-
static bool AreCompatibleForSubsumption(const FoldExpandedConstraint &A,
const FoldExpandedConstraint &B);
+
+ llvm::FoldingSetNodeID ProfileForSubsumption() const;
};
const NormalizedConstraint *getNormalizedAssociatedConstraints(
Sema &S, NamedDecl *ConstrainedDecl,
ArrayRef<const Expr *> AssociatedConstraints);
-template <typename AtomicSubsumptionEvaluator>
-bool subsumes(const NormalForm &PDNF, const NormalForm &QCNF,
- const AtomicSubsumptionEvaluator &E) {
- // C++ [temp.constr.order] p2
- // Then, P subsumes Q if and only if, for every disjunctive clause Pi in the
- // disjunctive normal form of P, Pi subsumes every conjunctive clause Qj in
- // the conjuctive normal form of Q, where [...]
- for (const auto &Pi : PDNF) {
- for (const auto &Qj : QCNF) {
- // C++ [temp.constr.order] p2
- // - [...] a disjunctive clause Pi subsumes a conjunctive clause Qj if
- // and only if there exists an atomic constraint Pia in Pi for which
- // there exists an atomic constraint, Qjb, in Qj such that Pia
- // subsumes Qjb.
- bool Found = false;
- for (NormalFormConstraint Pia : Pi) {
- for (NormalFormConstraint Qjb : Qj) {
- if (isa<FoldExpandedConstraint *>(Pia) &&
- isa<FoldExpandedConstraint *>(Qjb)) {
- if (cast<FoldExpandedConstraint *>(Pia)->subsumes(
- *cast<FoldExpandedConstraint *>(Qjb), E)) {
- Found = true;
- break;
- }
- } else if (isa<AtomicConstraint *>(Pia) &&
- isa<AtomicConstraint *>(Qjb)) {
- if (E(*cast<AtomicConstraint *>(Pia),
- *cast<AtomicConstraint *>(Qjb))) {
- Found = true;
- break;
- }
- }
- }
- if (Found)
- break;
- }
- if (!Found)
- return false;
- }
- }
- return true;
-}
-
-template <typename AtomicSubsumptionEvaluator>
-bool subsumes(Sema &S, NamedDecl *DP, ArrayRef<const Expr *> P, NamedDecl *DQ,
- ArrayRef<const Expr *> Q, bool &Subsumes,
- const AtomicSubsumptionEvaluator &E) {
- // C++ [temp.constr.order] p2
- // In order to determine if a constraint P subsumes a constraint Q, P is
- // transformed into disjunctive normal form, and Q is transformed into
- // conjunctive normal form. [...]
- const NormalizedConstraint *PNormalized =
- getNormalizedAssociatedConstraints(S, DP, P);
- if (!PNormalized)
- return true;
- NormalForm PDNF = makeDNF(*PNormalized);
+/// \brief SubsumptionChecker establishes subsumption
+/// between two set of constraints.
+class SubsumptionChecker {
+public:
+ using SubsumptionCallable = llvm::function_ref<bool(
+ const AtomicConstraint &, const AtomicConstraint &)>;
- const NormalizedConstraint *QNormalized =
- getNormalizedAssociatedConstraints(S, DQ, Q);
- if (!QNormalized)
- return true;
- NormalForm QCNF = makeCNF(*QNormalized);
-
- Subsumes = subsumes(PDNF, QCNF, E);
- return false;
-}
-
-template <typename AtomicSubsumptionEvaluator>
-bool FoldExpandedConstraint::subsumes(
- const FoldExpandedConstraint &Other,
- const AtomicSubsumptionEvaluator &E) const {
+ SubsumptionChecker(Sema &SemaRef, SubsumptionCallable Callable = {});
- // [C++26] [temp.constr.order]
- // a fold expanded constraint A subsumes another fold expanded constraint B if
- // they are compatible for subsumption, have the same fold-operator, and the
- // constraint of A subsumes that of B
+ std::optional<bool> Subsumes(NamedDecl *DP, ArrayRef<const Expr *> P,
+ NamedDecl *DQ, ArrayRef<const Expr *> Q);
----------------
cor3ntin wrote:
https://github.com/llvm/llvm-project/pull/133633
https://github.com/llvm/llvm-project/pull/132849
More information about the cfe-commits
mailing list