================ @@ -16,130 +16,385 @@ #include "clang/AST/ASTContext.h" #include "clang/AST/DeclTemplate.h" #include "clang/AST/Expr.h" +#include "clang/AST/ExprConcepts.h" #include "clang/Basic/SourceLocation.h" +#include "clang/Sema/Ownership.h" #include "llvm/ADT/FoldingSet.h" -#include "llvm/ADT/PointerUnion.h" #include "llvm/ADT/STLFunctionalExtras.h" +#include "llvm/ADT/SmallBitVector.h" #include "llvm/ADT/SmallVector.h" #include <optional> #include <utility> namespace clang { class Sema; +class MultiLevelTemplateArgumentList; -enum { ConstraintAlignment = 8 }; +/// \brief A normalized constraint, as defined in C++ [temp.constr.normal], is +/// either an atomic constraint, a conjunction of normalized constraints or a +/// disjunction of normalized constraints. +struct NormalizedConstraint { + + enum class ConstraintKind : unsigned char { + Atomic = 0, + ConceptId, + FoldExpanded, + Compound, + }; + + enum CompoundConstraintKind : unsigned char { + CCK_Conjunction, + CCK_Disjunction + }; + enum class FoldOperatorKind : unsigned char { And, Or }; + + using OccurenceList = llvm::SmallBitVector; + + friend bool + substituteParameterMappings(Sema &S, NormalizedConstraint &N, + const MultiLevelTemplateArgumentList &MLTAL, + const ASTTemplateArgumentListInfo *ArgsAsWritten, + TemplateParameterList *TemplateParams, + const NamedDecl *D); + +protected: + using ExprOrConcept = + llvm::PointerUnion<const Expr *, const ConceptReference *>; + + struct AtomicConstraintBits { + LLVM_PREFERRED_TYPE(ConstraintKind) + // Kind is the first member of all union members, + // as we rely on their initial common sequence. + unsigned Kind : 5; + unsigned Placeholder : 1; + unsigned PackSubstitutionIndex : 26; + // Indexes and Args are part of the common initial sequences + // of constraints that do have a mapping. + OccurenceList Indexes; + TemplateArgumentLoc *Args; + TemplateParameterList *ParamList; + ExprOrConcept ConstraintExpr; + const NamedDecl *ConstraintDecl; + }; + + struct FoldExpandedConstraintBits { + LLVM_PREFERRED_TYPE(ConstraintKind) + unsigned Kind : 5; + LLVM_PREFERRED_TYPE(FoldOperatorKind) + unsigned FoldOperator : 1; + unsigned Placeholder : 26; + OccurenceList Indexes; + TemplateArgumentLoc *Args; + TemplateParameterList *ParamList; + const Expr *Pattern; + const NamedDecl *ConstraintDecl; + NormalizedConstraint *Constraint; + }; + + struct ConceptIdBits : AtomicConstraintBits { + NormalizedConstraint *Sub; + + // Only used for parameter mapping. + const ConceptSpecializationExpr *CSE; + }; + + struct CompoundConstraintBits { + LLVM_PREFERRED_TYPE(ConstraintKind) + unsigned Kind : 5; + LLVM_PREFERRED_TYPE(CompoundConstraintKind) + unsigned CCK : 1; + NormalizedConstraint *LHS; + NormalizedConstraint *RHS; + }; + + union { + AtomicConstraintBits Atomic; + FoldExpandedConstraintBits FoldExpanded; + ConceptIdBits ConceptId; + CompoundConstraintBits Compound; + }; + + ~NormalizedConstraint() { + if (getKind() != ConstraintKind::Compound) + Atomic.Indexes.llvm::SmallBitVector::~SmallBitVector(); ---------------- cor3ntin wrote:
Given that we do not put a small bound on the number of template arguments, no https://github.com/llvm/llvm-project/pull/141776 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits