clang  12.0.0git
SemaConcept.h
Go to the documentation of this file.
1 //===-- SemaConcept.h - Semantic Analysis for Constraints and Concepts ----===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 ///
10 // This file provides semantic analysis for C++ constraints and concepts.
11 ///
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_CLANG_SEMA_SEMACONCEPT_H
15 #define LLVM_CLANG_SEMA_SEMACONCEPT_H
16 #include "clang/AST/ASTConcept.h"
17 #include "clang/AST/ASTContext.h"
18 #include "clang/AST/Expr.h"
19 #include "clang/AST/DeclTemplate.h"
21 #include "llvm/ADT/PointerUnion.h"
22 #include "llvm/ADT/Optional.h"
23 #include "llvm/ADT/SmallVector.h"
24 #include <string>
25 #include <utility>
26 
27 namespace clang {
28 class Sema;
29 
33 
34  AtomicConstraint(Sema &S, const Expr *ConstraintExpr) :
35  ConstraintExpr(ConstraintExpr) { };
36 
38  const AtomicConstraint &Other) const {
39  if (!ParameterMapping != !Other.ParameterMapping)
40  return false;
41  if (!ParameterMapping)
42  return true;
43  if (ParameterMapping->size() != Other.ParameterMapping->size())
44  return false;
45 
46  for (unsigned I = 0, S = ParameterMapping->size(); I < S; ++I) {
47  llvm::FoldingSetNodeID IDA, IDB;
48  C.getCanonicalTemplateArgument((*ParameterMapping)[I].getArgument())
49  .Profile(IDA, C);
50  C.getCanonicalTemplateArgument((*Other.ParameterMapping)[I].getArgument())
51  .Profile(IDB, C);
52  if (IDA != IDB)
53  return false;
54  }
55  return true;
56  }
57 
58  bool subsumes(ASTContext &C, const AtomicConstraint &Other) const {
59  // C++ [temp.constr.order] p2
60  // - an atomic constraint A subsumes another atomic constraint B
61  // if and only if the A and B are identical [...]
62  //
63  // C++ [temp.constr.atomic] p2
64  // Two atomic constraints are identical if they are formed from the
65  // same expression and the targets of the parameter mappings are
66  // equivalent according to the rules for expressions [...]
67 
68  // We do not actually substitute the parameter mappings into the
69  // constraint expressions, therefore the constraint expressions are
70  // the originals, and comparing them will suffice.
71  if (ConstraintExpr != Other.ConstraintExpr)
72  return false;
73 
74  // Check that the parameter lists are identical
75  return hasMatchingParameterMapping(C, Other);
76  }
77 };
78 
79 /// \brief A normalized constraint, as defined in C++ [temp.constr.normal], is
80 /// either an atomic constraint, a conjunction of normalized constraints or a
81 /// disjunction of normalized constraints.
83  friend class Sema;
84 
85  enum CompoundConstraintKind { CCK_Conjunction, CCK_Disjunction };
86 
87  using CompoundConstraint = llvm::PointerIntPair<
88  std::pair<NormalizedConstraint, NormalizedConstraint> *, 1,
90 
91  llvm::PointerUnion<AtomicConstraint *, CompoundConstraint> Constraint;
92 
93  NormalizedConstraint(AtomicConstraint *C): Constraint{C} { };
96  : Constraint{CompoundConstraint{
97  new (C) std::pair<NormalizedConstraint, NormalizedConstraint>{
98  std::move(LHS), std::move(RHS)}, Kind}} { };
99 
101  if (Other.isAtomic()) {
102  Constraint = new (C) AtomicConstraint(*Other.getAtomicConstraint());
103  } else {
104  Constraint = CompoundConstraint(
105  new (C) std::pair<NormalizedConstraint, NormalizedConstraint>{
106  NormalizedConstraint(C, Other.getLHS()),
107  NormalizedConstraint(C, Other.getRHS())},
108  Other.getCompoundKind());
109  }
110  }
112  Constraint(Other.Constraint) {
113  Other.Constraint = nullptr;
114  }
115  NormalizedConstraint &operator=(const NormalizedConstraint &Other) = delete;
117  if (&Other != this) {
118  NormalizedConstraint Temp(std::move(Other));
119  std::swap(Constraint, Temp.Constraint);
120  }
121  return *this;
122  }
123 
125  assert(!isAtomic() && "getCompoundKind called on atomic constraint.");
126  return Constraint.get<CompoundConstraint>().getInt();
127  }
128 
129  bool isAtomic() const { return Constraint.is<AtomicConstraint *>(); }
130 
132  assert(!isAtomic() && "getLHS called on atomic constraint.");
133  return Constraint.get<CompoundConstraint>().getPointer()->first;
134  }
135 
137  assert(!isAtomic() && "getRHS called on atomic constraint.");
138  return Constraint.get<CompoundConstraint>().getPointer()->second;
139  }
140 
142  assert(isAtomic() &&
143  "getAtomicConstraint called on non-atomic constraint.");
144  return Constraint.get<AtomicConstraint *>();
145  }
146 
147 private:
149  fromConstraintExprs(Sema &S, NamedDecl *D, ArrayRef<const Expr *> E);
151  fromConstraintExpr(Sema &S, NamedDecl *D, const Expr *E);
152 };
153 
154 } // clang
155 
156 #endif //LLVM_CLANG_SEMA_SEMACONCEPT_H
Defines the clang::ASTContext interface.
static const TemplateArgument & getArgument(const TemplateArgument &A)
bool subsumes(ASTContext &C, const AtomicConstraint &Other) const
Definition: SemaConcept.h:58
Defines the C++ template declaration subclasses.
NormalizedConstraint(AtomicConstraint *C)
Definition: SemaConcept.h:93
const Expr * ConstraintExpr
Definition: SemaConcept.h:31
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) const
Used to insert TemplateArguments into FoldingSets.
AtomicConstraint(Sema &S, const Expr *ConstraintExpr)
Definition: SemaConcept.h:34
TemplateArgument getCanonicalTemplateArgument(const TemplateArgument &Arg) const
Retrieve the "canonical" template argument.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:174
llvm::PointerUnion< AtomicConstraint *, CompoundConstraint > Constraint
Definition: SemaConcept.h:91
bool hasMatchingParameterMapping(ASTContext &C, const AtomicConstraint &Other) const
Definition: SemaConcept.h:37
llvm::PointerIntPair< std::pair< NormalizedConstraint, NormalizedConstraint > *, 1, CompoundConstraintKind > CompoundConstraint
Definition: SemaConcept.h:89
Sema - This implements semantic analysis and AST building for C.
Definition: Sema.h:340
This represents one expression.
Definition: Expr.h:110
NormalizedConstraint & operator=(NormalizedConstraint &&Other)
Definition: SemaConcept.h:116
NormalizedConstraint & getRHS() const
Definition: SemaConcept.h:136
CompoundConstraintKind getCompoundKind() const
Definition: SemaConcept.h:124
Kind
Dataflow Directional Tag Classes.
NormalizedConstraint(ASTContext &C, const NormalizedConstraint &Other)
Definition: SemaConcept.h:100
NormalizedConstraint & getLHS() const
Definition: SemaConcept.h:131
NormalizedConstraint(NormalizedConstraint &&Other)
Definition: SemaConcept.h:111
Defines the clang::SourceLocation class and associated facilities.
NormalizedConstraint(ASTContext &C, NormalizedConstraint LHS, NormalizedConstraint RHS, CompoundConstraintKind Kind)
Definition: SemaConcept.h:94
AtomicConstraint * getAtomicConstraint() const
Definition: SemaConcept.h:141
This represents a decl that may have a name.
Definition: Decl.h:223
Optional< MutableArrayRef< TemplateArgumentLoc > > ParameterMapping
Definition: SemaConcept.h:32
This file provides AST data structures related to concepts.
A normalized constraint, as defined in C++ [temp.constr.normal], is either an atomic constraint...
Definition: SemaConcept.h:82