================ @@ -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 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits