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