[clang] [Clang][C++26] Implement "Ordering of constraints involving fold expressions (PR #98160)

via cfe-commits cfe-commits at lists.llvm.org
Tue Jul 9 09:26:28 PDT 2024


================
@@ -143,13 +148,116 @@ struct NormalizedConstraint {
     return Constraint.get<AtomicConstraint *>();
   }
 
+  FoldExpandedConstraint *getFoldExpandedConstraint() const {
+    assert(isFoldExpanded() &&
+           "getFoldExpandedConstraint called on non-fold-expanded constraint.");
+    return Constraint.get<FoldExpandedConstraint *>();
+  }
+
 private:
   static std::optional<NormalizedConstraint>
   fromConstraintExprs(Sema &S, NamedDecl *D, ArrayRef<const Expr *> E);
   static std::optional<NormalizedConstraint>
   fromConstraintExpr(Sema &S, NamedDecl *D, const Expr *E);
 };
 
+struct FoldExpandedConstraint {
+  enum class FoldOperatorKind { FoAnd, FoOr } Kind;
+  NormalizedConstraint Constraint;
+  const Expr *Pattern;
+
+  FoldExpandedConstraint(FoldOperatorKind K, NormalizedConstraint C,
+                         const Expr *Pattern)
+      : Kind(K), Constraint(std::move(C)), Pattern(Pattern) {};
+
+  template <typename AtomicSubsumptionEvaluator>
+  bool subsumes(const FoldExpandedConstraint &Other,
+                AtomicSubsumptionEvaluator E) const;
+
+  static bool AreSubsumptionElligible(const FoldExpandedConstraint &A,
+                                      const FoldExpandedConstraint &B);
+};
+
+const NormalizedConstraint *getNormalizedAssociatedConstraints(
+    Sema &S, NamedDecl *ConstrainedDecl,
+    ArrayRef<const Expr *> AssociatedConstraints);
+
+template <typename AtomicSubsumptionEvaluator>
+bool subsumes(const NormalForm &PDNF, const NormalForm &QCNF,
+              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 (Pia.is<FoldExpandedConstraint *>() &&
+              Qjb.is<FoldExpandedConstraint *>()) {
+            if (Pia.get<FoldExpandedConstraint *>()->subsumes(
+                    *Qjb.get<FoldExpandedConstraint *>(), E)) {
+              Found = true;
+              break;
+            }
+          } else if (Pia.is<AtomicConstraint *>() &&
+                     Qjb.is<AtomicConstraint *>()) {
+            if (E(*Pia.get<AtomicConstraint *>(),
+                  *Qjb.get<AtomicConstraint *>())) {
+              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,
----------------
cor3ntin wrote:

Preexisting (I just shifted code around there)

https://github.com/llvm/llvm-project/pull/98160


More information about the cfe-commits mailing list