SemaConcept.cpp revision 1.1.1.1.4.1 1 1.1 joerg //===-- SemaConcept.cpp - Semantic Analysis for Constraints and Concepts --===//
2 1.1 joerg //
3 1.1 joerg // The LLVM Compiler Infrastructure
4 1.1 joerg //
5 1.1 joerg // This file is distributed under the University of Illinois Open Source
6 1.1 joerg // License. See LICENSE.TXT for details.
7 1.1 joerg //
8 1.1 joerg //===----------------------------------------------------------------------===//
9 1.1 joerg //
10 1.1 joerg // This file implements semantic analysis for C++ constraints and concepts.
11 1.1 joerg //
12 1.1 joerg //===----------------------------------------------------------------------===//
13 1.1 joerg
14 1.1.1.1.4.1 cjep #include "clang/Sema/SemaConcept.h"
15 1.1 joerg #include "clang/Sema/Sema.h"
16 1.1.1.1.4.1 cjep #include "clang/Sema/SemaInternal.h"
17 1.1 joerg #include "clang/Sema/SemaDiagnostic.h"
18 1.1 joerg #include "clang/Sema/TemplateDeduction.h"
19 1.1 joerg #include "clang/Sema/Template.h"
20 1.1.1.1.4.1 cjep #include "clang/Sema/Overload.h"
21 1.1.1.1.4.1 cjep #include "clang/Sema/Initialization.h"
22 1.1.1.1.4.1 cjep #include "clang/Sema/SemaInternal.h"
23 1.1.1.1.4.1 cjep #include "clang/AST/ExprConcepts.h"
24 1.1.1.1.4.1 cjep #include "clang/AST/RecursiveASTVisitor.h"
25 1.1.1.1.4.1 cjep #include "clang/Basic/OperatorPrecedence.h"
26 1.1.1.1.4.1 cjep #include "llvm/ADT/DenseMap.h"
27 1.1.1.1.4.1 cjep #include "llvm/ADT/PointerUnion.h"
28 1.1 joerg using namespace clang;
29 1.1 joerg using namespace sema;
30 1.1 joerg
31 1.1.1.1.4.1 cjep namespace {
32 1.1.1.1.4.1 cjep class LogicalBinOp {
33 1.1.1.1.4.1 cjep OverloadedOperatorKind Op = OO_None;
34 1.1.1.1.4.1 cjep const Expr *LHS = nullptr;
35 1.1.1.1.4.1 cjep const Expr *RHS = nullptr;
36 1.1.1.1.4.1 cjep
37 1.1.1.1.4.1 cjep public:
38 1.1.1.1.4.1 cjep LogicalBinOp(const Expr *E) {
39 1.1.1.1.4.1 cjep if (auto *BO = dyn_cast<BinaryOperator>(E)) {
40 1.1.1.1.4.1 cjep Op = BinaryOperator::getOverloadedOperator(BO->getOpcode());
41 1.1.1.1.4.1 cjep LHS = BO->getLHS();
42 1.1.1.1.4.1 cjep RHS = BO->getRHS();
43 1.1.1.1.4.1 cjep } else if (auto *OO = dyn_cast<CXXOperatorCallExpr>(E)) {
44 1.1.1.1.4.1 cjep Op = OO->getOperator();
45 1.1.1.1.4.1 cjep LHS = OO->getArg(0);
46 1.1.1.1.4.1 cjep RHS = OO->getArg(1);
47 1.1.1.1.4.1 cjep }
48 1.1.1.1.4.1 cjep }
49 1.1.1.1.4.1 cjep
50 1.1.1.1.4.1 cjep bool isAnd() const { return Op == OO_AmpAmp; }
51 1.1.1.1.4.1 cjep bool isOr() const { return Op == OO_PipePipe; }
52 1.1.1.1.4.1 cjep explicit operator bool() const { return isAnd() || isOr(); }
53 1.1.1.1.4.1 cjep
54 1.1.1.1.4.1 cjep const Expr *getLHS() const { return LHS; }
55 1.1.1.1.4.1 cjep const Expr *getRHS() const { return RHS; }
56 1.1.1.1.4.1 cjep };
57 1.1.1.1.4.1 cjep }
58 1.1.1.1.4.1 cjep
59 1.1.1.1.4.1 cjep bool Sema::CheckConstraintExpression(const Expr *ConstraintExpression,
60 1.1.1.1.4.1 cjep Token NextToken, bool *PossibleNonPrimary,
61 1.1.1.1.4.1 cjep bool IsTrailingRequiresClause) {
62 1.1 joerg // C++2a [temp.constr.atomic]p1
63 1.1 joerg // ..E shall be a constant expression of type bool.
64 1.1 joerg
65 1.1 joerg ConstraintExpression = ConstraintExpression->IgnoreParenImpCasts();
66 1.1 joerg
67 1.1.1.1.4.1 cjep if (LogicalBinOp BO = ConstraintExpression) {
68 1.1.1.1.4.1 cjep return CheckConstraintExpression(BO.getLHS(), NextToken,
69 1.1.1.1.4.1 cjep PossibleNonPrimary) &&
70 1.1.1.1.4.1 cjep CheckConstraintExpression(BO.getRHS(), NextToken,
71 1.1.1.1.4.1 cjep PossibleNonPrimary);
72 1.1 joerg } else if (auto *C = dyn_cast<ExprWithCleanups>(ConstraintExpression))
73 1.1.1.1.4.1 cjep return CheckConstraintExpression(C->getSubExpr(), NextToken,
74 1.1.1.1.4.1 cjep PossibleNonPrimary);
75 1.1.1.1.4.1 cjep
76 1.1.1.1.4.1 cjep QualType Type = ConstraintExpression->getType();
77 1.1.1.1.4.1 cjep
78 1.1.1.1.4.1 cjep auto CheckForNonPrimary = [&] {
79 1.1.1.1.4.1 cjep if (PossibleNonPrimary)
80 1.1.1.1.4.1 cjep *PossibleNonPrimary =
81 1.1.1.1.4.1 cjep // We have the following case:
82 1.1.1.1.4.1 cjep // template<typename> requires func(0) struct S { };
83 1.1.1.1.4.1 cjep // The user probably isn't aware of the parentheses required around
84 1.1.1.1.4.1 cjep // the function call, and we're only going to parse 'func' as the
85 1.1.1.1.4.1 cjep // primary-expression, and complain that it is of non-bool type.
86 1.1.1.1.4.1 cjep (NextToken.is(tok::l_paren) &&
87 1.1.1.1.4.1 cjep (IsTrailingRequiresClause ||
88 1.1.1.1.4.1 cjep (Type->isDependentType() &&
89 1.1.1.1.4.1 cjep isa<UnresolvedLookupExpr>(ConstraintExpression)) ||
90 1.1.1.1.4.1 cjep Type->isFunctionType() ||
91 1.1.1.1.4.1 cjep Type->isSpecificBuiltinType(BuiltinType::Overload))) ||
92 1.1.1.1.4.1 cjep // We have the following case:
93 1.1.1.1.4.1 cjep // template<typename T> requires size_<T> == 0 struct S { };
94 1.1.1.1.4.1 cjep // The user probably isn't aware of the parentheses required around
95 1.1.1.1.4.1 cjep // the binary operator, and we're only going to parse 'func' as the
96 1.1.1.1.4.1 cjep // first operand, and complain that it is of non-bool type.
97 1.1.1.1.4.1 cjep getBinOpPrecedence(NextToken.getKind(),
98 1.1.1.1.4.1 cjep /*GreaterThanIsOperator=*/true,
99 1.1.1.1.4.1 cjep getLangOpts().CPlusPlus11) > prec::LogicalAnd;
100 1.1.1.1.4.1 cjep };
101 1.1 joerg
102 1.1 joerg // An atomic constraint!
103 1.1.1.1.4.1 cjep if (ConstraintExpression->isTypeDependent()) {
104 1.1.1.1.4.1 cjep CheckForNonPrimary();
105 1.1 joerg return true;
106 1.1.1.1.4.1 cjep }
107 1.1 joerg
108 1.1 joerg if (!Context.hasSameUnqualifiedType(Type, Context.BoolTy)) {
109 1.1 joerg Diag(ConstraintExpression->getExprLoc(),
110 1.1 joerg diag::err_non_bool_atomic_constraint) << Type
111 1.1 joerg << ConstraintExpression->getSourceRange();
112 1.1.1.1.4.1 cjep CheckForNonPrimary();
113 1.1 joerg return false;
114 1.1 joerg }
115 1.1.1.1.4.1 cjep
116 1.1.1.1.4.1 cjep if (PossibleNonPrimary)
117 1.1.1.1.4.1 cjep *PossibleNonPrimary = false;
118 1.1 joerg return true;
119 1.1 joerg }
120 1.1 joerg
121 1.1.1.1.4.1 cjep template <typename AtomicEvaluator>
122 1.1.1.1.4.1 cjep static bool
123 1.1.1.1.4.1 cjep calculateConstraintSatisfaction(Sema &S, const Expr *ConstraintExpr,
124 1.1.1.1.4.1 cjep ConstraintSatisfaction &Satisfaction,
125 1.1.1.1.4.1 cjep AtomicEvaluator &&Evaluator) {
126 1.1 joerg ConstraintExpr = ConstraintExpr->IgnoreParenImpCasts();
127 1.1 joerg
128 1.1.1.1.4.1 cjep if (LogicalBinOp BO = ConstraintExpr) {
129 1.1.1.1.4.1 cjep if (calculateConstraintSatisfaction(S, BO.getLHS(), Satisfaction,
130 1.1.1.1.4.1 cjep Evaluator))
131 1.1.1.1.4.1 cjep return true;
132 1.1 joerg
133 1.1.1.1.4.1 cjep bool IsLHSSatisfied = Satisfaction.IsSatisfied;
134 1.1 joerg
135 1.1.1.1.4.1 cjep if (BO.isOr() && IsLHSSatisfied)
136 1.1.1.1.4.1 cjep // [temp.constr.op] p3
137 1.1.1.1.4.1 cjep // A disjunction is a constraint taking two operands. To determine if
138 1.1.1.1.4.1 cjep // a disjunction is satisfied, the satisfaction of the first operand
139 1.1.1.1.4.1 cjep // is checked. If that is satisfied, the disjunction is satisfied.
140 1.1.1.1.4.1 cjep // Otherwise, the disjunction is satisfied if and only if the second
141 1.1.1.1.4.1 cjep // operand is satisfied.
142 1.1.1.1.4.1 cjep return false;
143 1.1 joerg
144 1.1.1.1.4.1 cjep if (BO.isAnd() && !IsLHSSatisfied)
145 1.1.1.1.4.1 cjep // [temp.constr.op] p2
146 1.1.1.1.4.1 cjep // A conjunction is a constraint taking two operands. To determine if
147 1.1.1.1.4.1 cjep // a conjunction is satisfied, the satisfaction of the first operand
148 1.1.1.1.4.1 cjep // is checked. If that is not satisfied, the conjunction is not
149 1.1.1.1.4.1 cjep // satisfied. Otherwise, the conjunction is satisfied if and only if
150 1.1.1.1.4.1 cjep // the second operand is satisfied.
151 1.1 joerg return false;
152 1.1.1.1.4.1 cjep
153 1.1.1.1.4.1 cjep return calculateConstraintSatisfaction(
154 1.1.1.1.4.1 cjep S, BO.getRHS(), Satisfaction, std::forward<AtomicEvaluator>(Evaluator));
155 1.1.1.1.4.1 cjep } else if (auto *C = dyn_cast<ExprWithCleanups>(ConstraintExpr)) {
156 1.1.1.1.4.1 cjep return calculateConstraintSatisfaction(S, C->getSubExpr(), Satisfaction,
157 1.1.1.1.4.1 cjep std::forward<AtomicEvaluator>(Evaluator));
158 1.1 joerg }
159 1.1 joerg
160 1.1.1.1.4.1 cjep // An atomic constraint expression
161 1.1.1.1.4.1 cjep ExprResult SubstitutedAtomicExpr = Evaluator(ConstraintExpr);
162 1.1.1.1.4.1 cjep
163 1.1.1.1.4.1 cjep if (SubstitutedAtomicExpr.isInvalid())
164 1.1 joerg return true;
165 1.1 joerg
166 1.1.1.1.4.1 cjep if (!SubstitutedAtomicExpr.isUsable())
167 1.1.1.1.4.1 cjep // Evaluator has decided satisfaction without yielding an expression.
168 1.1.1.1.4.1 cjep return false;
169 1.1.1.1.4.1 cjep
170 1.1.1.1.4.1 cjep EnterExpressionEvaluationContext ConstantEvaluated(
171 1.1.1.1.4.1 cjep S, Sema::ExpressionEvaluationContext::ConstantEvaluated);
172 1.1 joerg SmallVector<PartialDiagnosticAt, 2> EvaluationDiags;
173 1.1 joerg Expr::EvalResult EvalResult;
174 1.1 joerg EvalResult.Diag = &EvaluationDiags;
175 1.1.1.1.4.1 cjep if (!SubstitutedAtomicExpr.get()->EvaluateAsConstantExpr(EvalResult,
176 1.1.1.1.4.1 cjep S.Context) ||
177 1.1.1.1.4.1 cjep !EvaluationDiags.empty()) {
178 1.1 joerg // C++2a [temp.constr.atomic]p1
179 1.1 joerg // ...E shall be a constant expression of type bool.
180 1.1.1.1.4.1 cjep S.Diag(SubstitutedAtomicExpr.get()->getBeginLoc(),
181 1.1.1.1.4.1 cjep diag::err_non_constant_constraint_expression)
182 1.1.1.1.4.1 cjep << SubstitutedAtomicExpr.get()->getSourceRange();
183 1.1 joerg for (const PartialDiagnosticAt &PDiag : EvaluationDiags)
184 1.1.1.1.4.1 cjep S.Diag(PDiag.first, PDiag.second);
185 1.1.1.1.4.1 cjep return true;
186 1.1.1.1.4.1 cjep }
187 1.1.1.1.4.1 cjep
188 1.1.1.1.4.1 cjep assert(EvalResult.Val.isInt() &&
189 1.1.1.1.4.1 cjep "evaluating bool expression didn't produce int");
190 1.1.1.1.4.1 cjep Satisfaction.IsSatisfied = EvalResult.Val.getInt().getBoolValue();
191 1.1.1.1.4.1 cjep if (!Satisfaction.IsSatisfied)
192 1.1.1.1.4.1 cjep Satisfaction.Details.emplace_back(ConstraintExpr,
193 1.1.1.1.4.1 cjep SubstitutedAtomicExpr.get());
194 1.1.1.1.4.1 cjep
195 1.1.1.1.4.1 cjep return false;
196 1.1.1.1.4.1 cjep }
197 1.1.1.1.4.1 cjep
198 1.1.1.1.4.1 cjep static bool calculateConstraintSatisfaction(
199 1.1.1.1.4.1 cjep Sema &S, const NamedDecl *Template, ArrayRef<TemplateArgument> TemplateArgs,
200 1.1.1.1.4.1 cjep SourceLocation TemplateNameLoc, MultiLevelTemplateArgumentList &MLTAL,
201 1.1.1.1.4.1 cjep const Expr *ConstraintExpr, ConstraintSatisfaction &Satisfaction) {
202 1.1.1.1.4.1 cjep return calculateConstraintSatisfaction(
203 1.1.1.1.4.1 cjep S, ConstraintExpr, Satisfaction, [&](const Expr *AtomicExpr) {
204 1.1.1.1.4.1 cjep EnterExpressionEvaluationContext ConstantEvaluated(
205 1.1.1.1.4.1 cjep S, Sema::ExpressionEvaluationContext::ConstantEvaluated);
206 1.1.1.1.4.1 cjep
207 1.1.1.1.4.1 cjep // Atomic constraint - substitute arguments and check satisfaction.
208 1.1.1.1.4.1 cjep ExprResult SubstitutedExpression;
209 1.1.1.1.4.1 cjep {
210 1.1.1.1.4.1 cjep TemplateDeductionInfo Info(TemplateNameLoc);
211 1.1.1.1.4.1 cjep Sema::InstantiatingTemplate Inst(S, AtomicExpr->getBeginLoc(),
212 1.1.1.1.4.1 cjep Sema::InstantiatingTemplate::ConstraintSubstitution{},
213 1.1.1.1.4.1 cjep const_cast<NamedDecl *>(Template), Info,
214 1.1.1.1.4.1 cjep AtomicExpr->getSourceRange());
215 1.1.1.1.4.1 cjep if (Inst.isInvalid())
216 1.1.1.1.4.1 cjep return ExprError();
217 1.1.1.1.4.1 cjep // We do not want error diagnostics escaping here.
218 1.1.1.1.4.1 cjep Sema::SFINAETrap Trap(S);
219 1.1.1.1.4.1 cjep SubstitutedExpression = S.SubstExpr(const_cast<Expr *>(AtomicExpr),
220 1.1.1.1.4.1 cjep MLTAL);
221 1.1.1.1.4.1 cjep // Substitution might have stripped off a contextual conversion to
222 1.1.1.1.4.1 cjep // bool if this is the operand of an '&&' or '||'. For example, we
223 1.1.1.1.4.1 cjep // might lose an lvalue-to-rvalue conversion here. If so, put it back
224 1.1.1.1.4.1 cjep // before we try to evaluate.
225 1.1.1.1.4.1 cjep if (!SubstitutedExpression.isInvalid())
226 1.1.1.1.4.1 cjep SubstitutedExpression =
227 1.1.1.1.4.1 cjep S.PerformContextuallyConvertToBool(SubstitutedExpression.get());
228 1.1.1.1.4.1 cjep if (SubstitutedExpression.isInvalid() || Trap.hasErrorOccurred()) {
229 1.1.1.1.4.1 cjep // C++2a [temp.constr.atomic]p1
230 1.1.1.1.4.1 cjep // ...If substitution results in an invalid type or expression, the
231 1.1.1.1.4.1 cjep // constraint is not satisfied.
232 1.1.1.1.4.1 cjep if (!Trap.hasErrorOccurred())
233 1.1.1.1.4.1 cjep // A non-SFINAE error has occured as a result of this
234 1.1.1.1.4.1 cjep // substitution.
235 1.1.1.1.4.1 cjep return ExprError();
236 1.1.1.1.4.1 cjep
237 1.1.1.1.4.1 cjep PartialDiagnosticAt SubstDiag{SourceLocation(),
238 1.1.1.1.4.1 cjep PartialDiagnostic::NullDiagnostic()};
239 1.1.1.1.4.1 cjep Info.takeSFINAEDiagnostic(SubstDiag);
240 1.1.1.1.4.1 cjep // FIXME: Concepts: This is an unfortunate consequence of there
241 1.1.1.1.4.1 cjep // being no serialization code for PartialDiagnostics and the fact
242 1.1.1.1.4.1 cjep // that serializing them would likely take a lot more storage than
243 1.1.1.1.4.1 cjep // just storing them as strings. We would still like, in the
244 1.1.1.1.4.1 cjep // future, to serialize the proper PartialDiagnostic as serializing
245 1.1.1.1.4.1 cjep // it as a string defeats the purpose of the diagnostic mechanism.
246 1.1.1.1.4.1 cjep SmallString<128> DiagString;
247 1.1.1.1.4.1 cjep DiagString = ": ";
248 1.1.1.1.4.1 cjep SubstDiag.second.EmitToString(S.getDiagnostics(), DiagString);
249 1.1.1.1.4.1 cjep unsigned MessageSize = DiagString.size();
250 1.1.1.1.4.1 cjep char *Mem = new (S.Context) char[MessageSize];
251 1.1.1.1.4.1 cjep memcpy(Mem, DiagString.c_str(), MessageSize);
252 1.1.1.1.4.1 cjep Satisfaction.Details.emplace_back(
253 1.1.1.1.4.1 cjep AtomicExpr,
254 1.1.1.1.4.1 cjep new (S.Context) ConstraintSatisfaction::SubstitutionDiagnostic{
255 1.1.1.1.4.1 cjep SubstDiag.first, StringRef(Mem, MessageSize)});
256 1.1.1.1.4.1 cjep Satisfaction.IsSatisfied = false;
257 1.1.1.1.4.1 cjep return ExprEmpty();
258 1.1.1.1.4.1 cjep }
259 1.1.1.1.4.1 cjep }
260 1.1.1.1.4.1 cjep
261 1.1.1.1.4.1 cjep if (!S.CheckConstraintExpression(SubstitutedExpression.get()))
262 1.1.1.1.4.1 cjep return ExprError();
263 1.1.1.1.4.1 cjep
264 1.1.1.1.4.1 cjep return SubstitutedExpression;
265 1.1.1.1.4.1 cjep });
266 1.1.1.1.4.1 cjep }
267 1.1.1.1.4.1 cjep
268 1.1.1.1.4.1 cjep static bool CheckConstraintSatisfaction(Sema &S, const NamedDecl *Template,
269 1.1.1.1.4.1 cjep ArrayRef<const Expr *> ConstraintExprs,
270 1.1.1.1.4.1 cjep ArrayRef<TemplateArgument> TemplateArgs,
271 1.1.1.1.4.1 cjep SourceRange TemplateIDRange,
272 1.1.1.1.4.1 cjep ConstraintSatisfaction &Satisfaction) {
273 1.1.1.1.4.1 cjep if (ConstraintExprs.empty()) {
274 1.1.1.1.4.1 cjep Satisfaction.IsSatisfied = true;
275 1.1.1.1.4.1 cjep return false;
276 1.1.1.1.4.1 cjep }
277 1.1.1.1.4.1 cjep
278 1.1.1.1.4.1 cjep for (auto& Arg : TemplateArgs)
279 1.1.1.1.4.1 cjep if (Arg.isInstantiationDependent()) {
280 1.1.1.1.4.1 cjep // No need to check satisfaction for dependent constraint expressions.
281 1.1.1.1.4.1 cjep Satisfaction.IsSatisfied = true;
282 1.1.1.1.4.1 cjep return false;
283 1.1.1.1.4.1 cjep }
284 1.1.1.1.4.1 cjep
285 1.1.1.1.4.1 cjep Sema::InstantiatingTemplate Inst(S, TemplateIDRange.getBegin(),
286 1.1.1.1.4.1 cjep Sema::InstantiatingTemplate::ConstraintsCheck{},
287 1.1.1.1.4.1 cjep const_cast<NamedDecl *>(Template), TemplateArgs, TemplateIDRange);
288 1.1.1.1.4.1 cjep if (Inst.isInvalid())
289 1.1.1.1.4.1 cjep return true;
290 1.1.1.1.4.1 cjep
291 1.1.1.1.4.1 cjep MultiLevelTemplateArgumentList MLTAL;
292 1.1.1.1.4.1 cjep MLTAL.addOuterTemplateArguments(TemplateArgs);
293 1.1.1.1.4.1 cjep
294 1.1.1.1.4.1 cjep for (const Expr *ConstraintExpr : ConstraintExprs) {
295 1.1.1.1.4.1 cjep if (calculateConstraintSatisfaction(S, Template, TemplateArgs,
296 1.1.1.1.4.1 cjep TemplateIDRange.getBegin(), MLTAL,
297 1.1.1.1.4.1 cjep ConstraintExpr, Satisfaction))
298 1.1.1.1.4.1 cjep return true;
299 1.1.1.1.4.1 cjep if (!Satisfaction.IsSatisfied)
300 1.1.1.1.4.1 cjep // [temp.constr.op] p2
301 1.1.1.1.4.1 cjep // [...] To determine if a conjunction is satisfied, the satisfaction
302 1.1.1.1.4.1 cjep // of the first operand is checked. If that is not satisfied, the
303 1.1.1.1.4.1 cjep // conjunction is not satisfied. [...]
304 1.1.1.1.4.1 cjep return false;
305 1.1.1.1.4.1 cjep }
306 1.1.1.1.4.1 cjep return false;
307 1.1.1.1.4.1 cjep }
308 1.1.1.1.4.1 cjep
309 1.1.1.1.4.1 cjep bool Sema::CheckConstraintSatisfaction(
310 1.1.1.1.4.1 cjep const NamedDecl *Template, ArrayRef<const Expr *> ConstraintExprs,
311 1.1.1.1.4.1 cjep ArrayRef<TemplateArgument> TemplateArgs, SourceRange TemplateIDRange,
312 1.1.1.1.4.1 cjep ConstraintSatisfaction &OutSatisfaction) {
313 1.1.1.1.4.1 cjep if (ConstraintExprs.empty()) {
314 1.1.1.1.4.1 cjep OutSatisfaction.IsSatisfied = true;
315 1.1.1.1.4.1 cjep return false;
316 1.1.1.1.4.1 cjep }
317 1.1.1.1.4.1 cjep
318 1.1.1.1.4.1 cjep llvm::FoldingSetNodeID ID;
319 1.1.1.1.4.1 cjep void *InsertPos;
320 1.1.1.1.4.1 cjep ConstraintSatisfaction *Satisfaction = nullptr;
321 1.1.1.1.4.1 cjep bool ShouldCache = LangOpts.ConceptSatisfactionCaching && Template;
322 1.1.1.1.4.1 cjep if (ShouldCache) {
323 1.1.1.1.4.1 cjep ConstraintSatisfaction::Profile(ID, Context, Template, TemplateArgs);
324 1.1.1.1.4.1 cjep Satisfaction = SatisfactionCache.FindNodeOrInsertPos(ID, InsertPos);
325 1.1.1.1.4.1 cjep if (Satisfaction) {
326 1.1.1.1.4.1 cjep OutSatisfaction = *Satisfaction;
327 1.1.1.1.4.1 cjep return false;
328 1.1.1.1.4.1 cjep }
329 1.1.1.1.4.1 cjep Satisfaction = new ConstraintSatisfaction(Template, TemplateArgs);
330 1.1.1.1.4.1 cjep } else {
331 1.1.1.1.4.1 cjep Satisfaction = &OutSatisfaction;
332 1.1.1.1.4.1 cjep }
333 1.1.1.1.4.1 cjep if (::CheckConstraintSatisfaction(*this, Template, ConstraintExprs,
334 1.1.1.1.4.1 cjep TemplateArgs, TemplateIDRange,
335 1.1.1.1.4.1 cjep *Satisfaction)) {
336 1.1.1.1.4.1 cjep if (ShouldCache)
337 1.1.1.1.4.1 cjep delete Satisfaction;
338 1.1 joerg return true;
339 1.1 joerg }
340 1.1 joerg
341 1.1.1.1.4.1 cjep if (ShouldCache) {
342 1.1.1.1.4.1 cjep // We cannot use InsertNode here because CheckConstraintSatisfaction might
343 1.1.1.1.4.1 cjep // have invalidated it.
344 1.1.1.1.4.1 cjep SatisfactionCache.InsertNode(Satisfaction);
345 1.1.1.1.4.1 cjep OutSatisfaction = *Satisfaction;
346 1.1.1.1.4.1 cjep }
347 1.1.1.1.4.1 cjep return false;
348 1.1.1.1.4.1 cjep }
349 1.1.1.1.4.1 cjep
350 1.1.1.1.4.1 cjep bool Sema::CheckConstraintSatisfaction(const Expr *ConstraintExpr,
351 1.1.1.1.4.1 cjep ConstraintSatisfaction &Satisfaction) {
352 1.1.1.1.4.1 cjep return calculateConstraintSatisfaction(
353 1.1.1.1.4.1 cjep *this, ConstraintExpr, Satisfaction,
354 1.1.1.1.4.1 cjep [](const Expr *AtomicExpr) -> ExprResult {
355 1.1.1.1.4.1 cjep return ExprResult(const_cast<Expr *>(AtomicExpr));
356 1.1.1.1.4.1 cjep });
357 1.1.1.1.4.1 cjep }
358 1.1.1.1.4.1 cjep
359 1.1.1.1.4.1 cjep bool Sema::CheckFunctionConstraints(const FunctionDecl *FD,
360 1.1.1.1.4.1 cjep ConstraintSatisfaction &Satisfaction,
361 1.1.1.1.4.1 cjep SourceLocation UsageLoc) {
362 1.1.1.1.4.1 cjep const Expr *RC = FD->getTrailingRequiresClause();
363 1.1.1.1.4.1 cjep if (RC->isInstantiationDependent()) {
364 1.1.1.1.4.1 cjep Satisfaction.IsSatisfied = true;
365 1.1.1.1.4.1 cjep return false;
366 1.1.1.1.4.1 cjep }
367 1.1.1.1.4.1 cjep Qualifiers ThisQuals;
368 1.1.1.1.4.1 cjep CXXRecordDecl *Record = nullptr;
369 1.1.1.1.4.1 cjep if (auto *Method = dyn_cast<CXXMethodDecl>(FD)) {
370 1.1.1.1.4.1 cjep ThisQuals = Method->getMethodQualifiers();
371 1.1.1.1.4.1 cjep Record = const_cast<CXXRecordDecl *>(Method->getParent());
372 1.1.1.1.4.1 cjep }
373 1.1.1.1.4.1 cjep CXXThisScopeRAII ThisScope(*this, Record, ThisQuals, Record != nullptr);
374 1.1.1.1.4.1 cjep // We substitute with empty arguments in order to rebuild the atomic
375 1.1.1.1.4.1 cjep // constraint in a constant-evaluated context.
376 1.1.1.1.4.1 cjep // FIXME: Should this be a dedicated TreeTransform?
377 1.1.1.1.4.1 cjep return CheckConstraintSatisfaction(
378 1.1.1.1.4.1 cjep FD, {RC}, /*TemplateArgs=*/{},
379 1.1.1.1.4.1 cjep SourceRange(UsageLoc.isValid() ? UsageLoc : FD->getLocation()),
380 1.1.1.1.4.1 cjep Satisfaction);
381 1.1.1.1.4.1 cjep }
382 1.1.1.1.4.1 cjep
383 1.1.1.1.4.1 cjep bool Sema::EnsureTemplateArgumentListConstraints(
384 1.1.1.1.4.1 cjep TemplateDecl *TD, ArrayRef<TemplateArgument> TemplateArgs,
385 1.1.1.1.4.1 cjep SourceRange TemplateIDRange) {
386 1.1.1.1.4.1 cjep ConstraintSatisfaction Satisfaction;
387 1.1.1.1.4.1 cjep llvm::SmallVector<const Expr *, 3> AssociatedConstraints;
388 1.1.1.1.4.1 cjep TD->getAssociatedConstraints(AssociatedConstraints);
389 1.1.1.1.4.1 cjep if (CheckConstraintSatisfaction(TD, AssociatedConstraints, TemplateArgs,
390 1.1.1.1.4.1 cjep TemplateIDRange, Satisfaction))
391 1.1.1.1.4.1 cjep return true;
392 1.1.1.1.4.1 cjep
393 1.1.1.1.4.1 cjep if (!Satisfaction.IsSatisfied) {
394 1.1.1.1.4.1 cjep SmallString<128> TemplateArgString;
395 1.1.1.1.4.1 cjep TemplateArgString = " ";
396 1.1.1.1.4.1 cjep TemplateArgString += getTemplateArgumentBindingsText(
397 1.1.1.1.4.1 cjep TD->getTemplateParameters(), TemplateArgs.data(), TemplateArgs.size());
398 1.1 joerg
399 1.1.1.1.4.1 cjep Diag(TemplateIDRange.getBegin(),
400 1.1.1.1.4.1 cjep diag::err_template_arg_list_constraints_not_satisfied)
401 1.1.1.1.4.1 cjep << (int)getTemplateNameKindForDiagnostics(TemplateName(TD)) << TD
402 1.1.1.1.4.1 cjep << TemplateArgString << TemplateIDRange;
403 1.1.1.1.4.1 cjep DiagnoseUnsatisfiedConstraint(Satisfaction);
404 1.1.1.1.4.1 cjep return true;
405 1.1.1.1.4.1 cjep }
406 1.1 joerg return false;
407 1.1.1.1.4.1 cjep }
408 1.1.1.1.4.1 cjep
409 1.1.1.1.4.1 cjep static void diagnoseUnsatisfiedRequirement(Sema &S,
410 1.1.1.1.4.1 cjep concepts::ExprRequirement *Req,
411 1.1.1.1.4.1 cjep bool First) {
412 1.1.1.1.4.1 cjep assert(!Req->isSatisfied()
413 1.1.1.1.4.1 cjep && "Diagnose() can only be used on an unsatisfied requirement");
414 1.1.1.1.4.1 cjep switch (Req->getSatisfactionStatus()) {
415 1.1.1.1.4.1 cjep case concepts::ExprRequirement::SS_Dependent:
416 1.1.1.1.4.1 cjep llvm_unreachable("Diagnosing a dependent requirement");
417 1.1.1.1.4.1 cjep break;
418 1.1.1.1.4.1 cjep case concepts::ExprRequirement::SS_ExprSubstitutionFailure: {
419 1.1.1.1.4.1 cjep auto *SubstDiag = Req->getExprSubstitutionDiagnostic();
420 1.1.1.1.4.1 cjep if (!SubstDiag->DiagMessage.empty())
421 1.1.1.1.4.1 cjep S.Diag(SubstDiag->DiagLoc,
422 1.1.1.1.4.1 cjep diag::note_expr_requirement_expr_substitution_error)
423 1.1.1.1.4.1 cjep << (int)First << SubstDiag->SubstitutedEntity
424 1.1.1.1.4.1 cjep << SubstDiag->DiagMessage;
425 1.1.1.1.4.1 cjep else
426 1.1.1.1.4.1 cjep S.Diag(SubstDiag->DiagLoc,
427 1.1.1.1.4.1 cjep diag::note_expr_requirement_expr_unknown_substitution_error)
428 1.1.1.1.4.1 cjep << (int)First << SubstDiag->SubstitutedEntity;
429 1.1.1.1.4.1 cjep break;
430 1.1.1.1.4.1 cjep }
431 1.1.1.1.4.1 cjep case concepts::ExprRequirement::SS_NoexceptNotMet:
432 1.1.1.1.4.1 cjep S.Diag(Req->getNoexceptLoc(),
433 1.1.1.1.4.1 cjep diag::note_expr_requirement_noexcept_not_met)
434 1.1.1.1.4.1 cjep << (int)First << Req->getExpr();
435 1.1.1.1.4.1 cjep break;
436 1.1.1.1.4.1 cjep case concepts::ExprRequirement::SS_TypeRequirementSubstitutionFailure: {
437 1.1.1.1.4.1 cjep auto *SubstDiag =
438 1.1.1.1.4.1 cjep Req->getReturnTypeRequirement().getSubstitutionDiagnostic();
439 1.1.1.1.4.1 cjep if (!SubstDiag->DiagMessage.empty())
440 1.1.1.1.4.1 cjep S.Diag(SubstDiag->DiagLoc,
441 1.1.1.1.4.1 cjep diag::note_expr_requirement_type_requirement_substitution_error)
442 1.1.1.1.4.1 cjep << (int)First << SubstDiag->SubstitutedEntity
443 1.1.1.1.4.1 cjep << SubstDiag->DiagMessage;
444 1.1.1.1.4.1 cjep else
445 1.1.1.1.4.1 cjep S.Diag(SubstDiag->DiagLoc,
446 1.1.1.1.4.1 cjep diag::note_expr_requirement_type_requirement_unknown_substitution_error)
447 1.1.1.1.4.1 cjep << (int)First << SubstDiag->SubstitutedEntity;
448 1.1.1.1.4.1 cjep break;
449 1.1.1.1.4.1 cjep }
450 1.1.1.1.4.1 cjep case concepts::ExprRequirement::SS_ConstraintsNotSatisfied: {
451 1.1.1.1.4.1 cjep ConceptSpecializationExpr *ConstraintExpr =
452 1.1.1.1.4.1 cjep Req->getReturnTypeRequirementSubstitutedConstraintExpr();
453 1.1.1.1.4.1 cjep if (ConstraintExpr->getTemplateArgsAsWritten()->NumTemplateArgs == 1) {
454 1.1.1.1.4.1 cjep // A simple case - expr type is the type being constrained and the concept
455 1.1.1.1.4.1 cjep // was not provided arguments.
456 1.1.1.1.4.1 cjep Expr *e = Req->getExpr();
457 1.1.1.1.4.1 cjep S.Diag(e->getBeginLoc(),
458 1.1.1.1.4.1 cjep diag::note_expr_requirement_constraints_not_satisfied_simple)
459 1.1.1.1.4.1 cjep << (int)First << S.getDecltypeForParenthesizedExpr(e)
460 1.1.1.1.4.1 cjep << ConstraintExpr->getNamedConcept();
461 1.1.1.1.4.1 cjep } else {
462 1.1.1.1.4.1 cjep S.Diag(ConstraintExpr->getBeginLoc(),
463 1.1.1.1.4.1 cjep diag::note_expr_requirement_constraints_not_satisfied)
464 1.1.1.1.4.1 cjep << (int)First << ConstraintExpr;
465 1.1.1.1.4.1 cjep }
466 1.1.1.1.4.1 cjep S.DiagnoseUnsatisfiedConstraint(ConstraintExpr->getSatisfaction());
467 1.1.1.1.4.1 cjep break;
468 1.1.1.1.4.1 cjep }
469 1.1.1.1.4.1 cjep case concepts::ExprRequirement::SS_Satisfied:
470 1.1.1.1.4.1 cjep llvm_unreachable("We checked this above");
471 1.1.1.1.4.1 cjep }
472 1.1.1.1.4.1 cjep }
473 1.1.1.1.4.1 cjep
474 1.1.1.1.4.1 cjep static void diagnoseUnsatisfiedRequirement(Sema &S,
475 1.1.1.1.4.1 cjep concepts::TypeRequirement *Req,
476 1.1.1.1.4.1 cjep bool First) {
477 1.1.1.1.4.1 cjep assert(!Req->isSatisfied()
478 1.1.1.1.4.1 cjep && "Diagnose() can only be used on an unsatisfied requirement");
479 1.1.1.1.4.1 cjep switch (Req->getSatisfactionStatus()) {
480 1.1.1.1.4.1 cjep case concepts::TypeRequirement::SS_Dependent:
481 1.1.1.1.4.1 cjep llvm_unreachable("Diagnosing a dependent requirement");
482 1.1.1.1.4.1 cjep return;
483 1.1.1.1.4.1 cjep case concepts::TypeRequirement::SS_SubstitutionFailure: {
484 1.1.1.1.4.1 cjep auto *SubstDiag = Req->getSubstitutionDiagnostic();
485 1.1.1.1.4.1 cjep if (!SubstDiag->DiagMessage.empty())
486 1.1.1.1.4.1 cjep S.Diag(SubstDiag->DiagLoc,
487 1.1.1.1.4.1 cjep diag::note_type_requirement_substitution_error) << (int)First
488 1.1.1.1.4.1 cjep << SubstDiag->SubstitutedEntity << SubstDiag->DiagMessage;
489 1.1.1.1.4.1 cjep else
490 1.1.1.1.4.1 cjep S.Diag(SubstDiag->DiagLoc,
491 1.1.1.1.4.1 cjep diag::note_type_requirement_unknown_substitution_error)
492 1.1.1.1.4.1 cjep << (int)First << SubstDiag->SubstitutedEntity;
493 1.1.1.1.4.1 cjep return;
494 1.1.1.1.4.1 cjep }
495 1.1.1.1.4.1 cjep default:
496 1.1.1.1.4.1 cjep llvm_unreachable("Unknown satisfaction status");
497 1.1.1.1.4.1 cjep return;
498 1.1.1.1.4.1 cjep }
499 1.1.1.1.4.1 cjep }
500 1.1.1.1.4.1 cjep
501 1.1.1.1.4.1 cjep static void diagnoseUnsatisfiedRequirement(Sema &S,
502 1.1.1.1.4.1 cjep concepts::NestedRequirement *Req,
503 1.1.1.1.4.1 cjep bool First) {
504 1.1.1.1.4.1 cjep if (Req->isSubstitutionFailure()) {
505 1.1.1.1.4.1 cjep concepts::Requirement::SubstitutionDiagnostic *SubstDiag =
506 1.1.1.1.4.1 cjep Req->getSubstitutionDiagnostic();
507 1.1.1.1.4.1 cjep if (!SubstDiag->DiagMessage.empty())
508 1.1.1.1.4.1 cjep S.Diag(SubstDiag->DiagLoc,
509 1.1.1.1.4.1 cjep diag::note_nested_requirement_substitution_error)
510 1.1.1.1.4.1 cjep << (int)First << SubstDiag->SubstitutedEntity
511 1.1.1.1.4.1 cjep << SubstDiag->DiagMessage;
512 1.1.1.1.4.1 cjep else
513 1.1.1.1.4.1 cjep S.Diag(SubstDiag->DiagLoc,
514 1.1.1.1.4.1 cjep diag::note_nested_requirement_unknown_substitution_error)
515 1.1.1.1.4.1 cjep << (int)First << SubstDiag->SubstitutedEntity;
516 1.1.1.1.4.1 cjep return;
517 1.1.1.1.4.1 cjep }
518 1.1.1.1.4.1 cjep S.DiagnoseUnsatisfiedConstraint(Req->getConstraintSatisfaction(), First);
519 1.1.1.1.4.1 cjep }
520 1.1.1.1.4.1 cjep
521 1.1.1.1.4.1 cjep
522 1.1.1.1.4.1 cjep static void diagnoseWellFormedUnsatisfiedConstraintExpr(Sema &S,
523 1.1.1.1.4.1 cjep Expr *SubstExpr,
524 1.1.1.1.4.1 cjep bool First = true) {
525 1.1.1.1.4.1 cjep SubstExpr = SubstExpr->IgnoreParenImpCasts();
526 1.1.1.1.4.1 cjep if (BinaryOperator *BO = dyn_cast<BinaryOperator>(SubstExpr)) {
527 1.1.1.1.4.1 cjep switch (BO->getOpcode()) {
528 1.1.1.1.4.1 cjep // These two cases will in practice only be reached when using fold
529 1.1.1.1.4.1 cjep // expressions with || and &&, since otherwise the || and && will have been
530 1.1.1.1.4.1 cjep // broken down into atomic constraints during satisfaction checking.
531 1.1.1.1.4.1 cjep case BO_LOr:
532 1.1.1.1.4.1 cjep // Or evaluated to false - meaning both RHS and LHS evaluated to false.
533 1.1.1.1.4.1 cjep diagnoseWellFormedUnsatisfiedConstraintExpr(S, BO->getLHS(), First);
534 1.1.1.1.4.1 cjep diagnoseWellFormedUnsatisfiedConstraintExpr(S, BO->getRHS(),
535 1.1.1.1.4.1 cjep /*First=*/false);
536 1.1.1.1.4.1 cjep return;
537 1.1.1.1.4.1 cjep case BO_LAnd: {
538 1.1.1.1.4.1 cjep bool LHSSatisfied =
539 1.1.1.1.4.1 cjep BO->getLHS()->EvaluateKnownConstInt(S.Context).getBoolValue();
540 1.1.1.1.4.1 cjep if (LHSSatisfied) {
541 1.1.1.1.4.1 cjep // LHS is true, so RHS must be false.
542 1.1.1.1.4.1 cjep diagnoseWellFormedUnsatisfiedConstraintExpr(S, BO->getRHS(), First);
543 1.1.1.1.4.1 cjep return;
544 1.1.1.1.4.1 cjep }
545 1.1.1.1.4.1 cjep // LHS is false
546 1.1.1.1.4.1 cjep diagnoseWellFormedUnsatisfiedConstraintExpr(S, BO->getLHS(), First);
547 1.1.1.1.4.1 cjep
548 1.1.1.1.4.1 cjep // RHS might also be false
549 1.1.1.1.4.1 cjep bool RHSSatisfied =
550 1.1.1.1.4.1 cjep BO->getRHS()->EvaluateKnownConstInt(S.Context).getBoolValue();
551 1.1.1.1.4.1 cjep if (!RHSSatisfied)
552 1.1.1.1.4.1 cjep diagnoseWellFormedUnsatisfiedConstraintExpr(S, BO->getRHS(),
553 1.1.1.1.4.1 cjep /*First=*/false);
554 1.1.1.1.4.1 cjep return;
555 1.1.1.1.4.1 cjep }
556 1.1.1.1.4.1 cjep case BO_GE:
557 1.1.1.1.4.1 cjep case BO_LE:
558 1.1.1.1.4.1 cjep case BO_GT:
559 1.1.1.1.4.1 cjep case BO_LT:
560 1.1.1.1.4.1 cjep case BO_EQ:
561 1.1.1.1.4.1 cjep case BO_NE:
562 1.1.1.1.4.1 cjep if (BO->getLHS()->getType()->isIntegerType() &&
563 1.1.1.1.4.1 cjep BO->getRHS()->getType()->isIntegerType()) {
564 1.1.1.1.4.1 cjep Expr::EvalResult SimplifiedLHS;
565 1.1.1.1.4.1 cjep Expr::EvalResult SimplifiedRHS;
566 1.1.1.1.4.1 cjep BO->getLHS()->EvaluateAsInt(SimplifiedLHS, S.Context,
567 1.1.1.1.4.1 cjep Expr::SE_NoSideEffects,
568 1.1.1.1.4.1 cjep /*InConstantContext=*/true);
569 1.1.1.1.4.1 cjep BO->getRHS()->EvaluateAsInt(SimplifiedRHS, S.Context,
570 1.1.1.1.4.1 cjep Expr::SE_NoSideEffects,
571 1.1.1.1.4.1 cjep /*InConstantContext=*/true);
572 1.1.1.1.4.1 cjep if (!SimplifiedLHS.Diag && ! SimplifiedRHS.Diag) {
573 1.1.1.1.4.1 cjep S.Diag(SubstExpr->getBeginLoc(),
574 1.1.1.1.4.1 cjep diag::note_atomic_constraint_evaluated_to_false_elaborated)
575 1.1.1.1.4.1 cjep << (int)First << SubstExpr
576 1.1.1.1.4.1 cjep << SimplifiedLHS.Val.getInt().toString(10)
577 1.1.1.1.4.1 cjep << BinaryOperator::getOpcodeStr(BO->getOpcode())
578 1.1.1.1.4.1 cjep << SimplifiedRHS.Val.getInt().toString(10);
579 1.1.1.1.4.1 cjep return;
580 1.1.1.1.4.1 cjep }
581 1.1.1.1.4.1 cjep }
582 1.1.1.1.4.1 cjep break;
583 1.1.1.1.4.1 cjep
584 1.1.1.1.4.1 cjep default:
585 1.1.1.1.4.1 cjep break;
586 1.1.1.1.4.1 cjep }
587 1.1.1.1.4.1 cjep } else if (auto *CSE = dyn_cast<ConceptSpecializationExpr>(SubstExpr)) {
588 1.1.1.1.4.1 cjep if (CSE->getTemplateArgsAsWritten()->NumTemplateArgs == 1) {
589 1.1.1.1.4.1 cjep S.Diag(
590 1.1.1.1.4.1 cjep CSE->getSourceRange().getBegin(),
591 1.1.1.1.4.1 cjep diag::
592 1.1.1.1.4.1 cjep note_single_arg_concept_specialization_constraint_evaluated_to_false)
593 1.1.1.1.4.1 cjep << (int)First
594 1.1.1.1.4.1 cjep << CSE->getTemplateArgsAsWritten()->arguments()[0].getArgument()
595 1.1.1.1.4.1 cjep << CSE->getNamedConcept();
596 1.1.1.1.4.1 cjep } else {
597 1.1.1.1.4.1 cjep S.Diag(SubstExpr->getSourceRange().getBegin(),
598 1.1.1.1.4.1 cjep diag::note_concept_specialization_constraint_evaluated_to_false)
599 1.1.1.1.4.1 cjep << (int)First << CSE;
600 1.1.1.1.4.1 cjep }
601 1.1.1.1.4.1 cjep S.DiagnoseUnsatisfiedConstraint(CSE->getSatisfaction());
602 1.1.1.1.4.1 cjep return;
603 1.1.1.1.4.1 cjep } else if (auto *RE = dyn_cast<RequiresExpr>(SubstExpr)) {
604 1.1.1.1.4.1 cjep for (concepts::Requirement *Req : RE->getRequirements())
605 1.1.1.1.4.1 cjep if (!Req->isDependent() && !Req->isSatisfied()) {
606 1.1.1.1.4.1 cjep if (auto *E = dyn_cast<concepts::ExprRequirement>(Req))
607 1.1.1.1.4.1 cjep diagnoseUnsatisfiedRequirement(S, E, First);
608 1.1.1.1.4.1 cjep else if (auto *T = dyn_cast<concepts::TypeRequirement>(Req))
609 1.1.1.1.4.1 cjep diagnoseUnsatisfiedRequirement(S, T, First);
610 1.1.1.1.4.1 cjep else
611 1.1.1.1.4.1 cjep diagnoseUnsatisfiedRequirement(
612 1.1.1.1.4.1 cjep S, cast<concepts::NestedRequirement>(Req), First);
613 1.1.1.1.4.1 cjep break;
614 1.1.1.1.4.1 cjep }
615 1.1.1.1.4.1 cjep return;
616 1.1.1.1.4.1 cjep }
617 1.1.1.1.4.1 cjep
618 1.1.1.1.4.1 cjep S.Diag(SubstExpr->getSourceRange().getBegin(),
619 1.1.1.1.4.1 cjep diag::note_atomic_constraint_evaluated_to_false)
620 1.1.1.1.4.1 cjep << (int)First << SubstExpr;
621 1.1.1.1.4.1 cjep }
622 1.1.1.1.4.1 cjep
623 1.1.1.1.4.1 cjep template<typename SubstitutionDiagnostic>
624 1.1.1.1.4.1 cjep static void diagnoseUnsatisfiedConstraintExpr(
625 1.1.1.1.4.1 cjep Sema &S, const Expr *E,
626 1.1.1.1.4.1 cjep const llvm::PointerUnion<Expr *, SubstitutionDiagnostic *> &Record,
627 1.1.1.1.4.1 cjep bool First = true) {
628 1.1.1.1.4.1 cjep if (auto *Diag = Record.template dyn_cast<SubstitutionDiagnostic *>()){
629 1.1.1.1.4.1 cjep S.Diag(Diag->first, diag::note_substituted_constraint_expr_is_ill_formed)
630 1.1.1.1.4.1 cjep << Diag->second;
631 1.1.1.1.4.1 cjep return;
632 1.1.1.1.4.1 cjep }
633 1.1.1.1.4.1 cjep
634 1.1.1.1.4.1 cjep diagnoseWellFormedUnsatisfiedConstraintExpr(S,
635 1.1.1.1.4.1 cjep Record.template get<Expr *>(), First);
636 1.1.1.1.4.1 cjep }
637 1.1.1.1.4.1 cjep
638 1.1.1.1.4.1 cjep void
639 1.1.1.1.4.1 cjep Sema::DiagnoseUnsatisfiedConstraint(const ConstraintSatisfaction& Satisfaction,
640 1.1.1.1.4.1 cjep bool First) {
641 1.1.1.1.4.1 cjep assert(!Satisfaction.IsSatisfied &&
642 1.1.1.1.4.1 cjep "Attempted to diagnose a satisfied constraint");
643 1.1.1.1.4.1 cjep for (auto &Pair : Satisfaction.Details) {
644 1.1.1.1.4.1 cjep diagnoseUnsatisfiedConstraintExpr(*this, Pair.first, Pair.second, First);
645 1.1.1.1.4.1 cjep First = false;
646 1.1.1.1.4.1 cjep }
647 1.1.1.1.4.1 cjep }
648 1.1.1.1.4.1 cjep
649 1.1.1.1.4.1 cjep void Sema::DiagnoseUnsatisfiedConstraint(
650 1.1.1.1.4.1 cjep const ASTConstraintSatisfaction &Satisfaction,
651 1.1.1.1.4.1 cjep bool First) {
652 1.1.1.1.4.1 cjep assert(!Satisfaction.IsSatisfied &&
653 1.1.1.1.4.1 cjep "Attempted to diagnose a satisfied constraint");
654 1.1.1.1.4.1 cjep for (auto &Pair : Satisfaction) {
655 1.1.1.1.4.1 cjep diagnoseUnsatisfiedConstraintExpr(*this, Pair.first, Pair.second, First);
656 1.1.1.1.4.1 cjep First = false;
657 1.1.1.1.4.1 cjep }
658 1.1.1.1.4.1 cjep }
659 1.1.1.1.4.1 cjep
660 1.1.1.1.4.1 cjep const NormalizedConstraint *
661 1.1.1.1.4.1 cjep Sema::getNormalizedAssociatedConstraints(
662 1.1.1.1.4.1 cjep NamedDecl *ConstrainedDecl, ArrayRef<const Expr *> AssociatedConstraints) {
663 1.1.1.1.4.1 cjep auto CacheEntry = NormalizationCache.find(ConstrainedDecl);
664 1.1.1.1.4.1 cjep if (CacheEntry == NormalizationCache.end()) {
665 1.1.1.1.4.1 cjep auto Normalized =
666 1.1.1.1.4.1 cjep NormalizedConstraint::fromConstraintExprs(*this, ConstrainedDecl,
667 1.1.1.1.4.1 cjep AssociatedConstraints);
668 1.1.1.1.4.1 cjep CacheEntry =
669 1.1.1.1.4.1 cjep NormalizationCache
670 1.1.1.1.4.1 cjep .try_emplace(ConstrainedDecl,
671 1.1.1.1.4.1 cjep Normalized
672 1.1.1.1.4.1 cjep ? new (Context) NormalizedConstraint(
673 1.1.1.1.4.1 cjep std::move(*Normalized))
674 1.1.1.1.4.1 cjep : nullptr)
675 1.1.1.1.4.1 cjep .first;
676 1.1.1.1.4.1 cjep }
677 1.1.1.1.4.1 cjep return CacheEntry->second;
678 1.1.1.1.4.1 cjep }
679 1.1.1.1.4.1 cjep
680 1.1.1.1.4.1 cjep static bool substituteParameterMappings(Sema &S, NormalizedConstraint &N,
681 1.1.1.1.4.1 cjep ConceptDecl *Concept, ArrayRef<TemplateArgument> TemplateArgs,
682 1.1.1.1.4.1 cjep const ASTTemplateArgumentListInfo *ArgsAsWritten) {
683 1.1.1.1.4.1 cjep if (!N.isAtomic()) {
684 1.1.1.1.4.1 cjep if (substituteParameterMappings(S, N.getLHS(), Concept, TemplateArgs,
685 1.1.1.1.4.1 cjep ArgsAsWritten))
686 1.1.1.1.4.1 cjep return true;
687 1.1.1.1.4.1 cjep return substituteParameterMappings(S, N.getRHS(), Concept, TemplateArgs,
688 1.1.1.1.4.1 cjep ArgsAsWritten);
689 1.1.1.1.4.1 cjep }
690 1.1.1.1.4.1 cjep TemplateParameterList *TemplateParams = Concept->getTemplateParameters();
691 1.1.1.1.4.1 cjep
692 1.1.1.1.4.1 cjep AtomicConstraint &Atomic = *N.getAtomicConstraint();
693 1.1.1.1.4.1 cjep TemplateArgumentListInfo SubstArgs;
694 1.1.1.1.4.1 cjep MultiLevelTemplateArgumentList MLTAL;
695 1.1.1.1.4.1 cjep MLTAL.addOuterTemplateArguments(TemplateArgs);
696 1.1.1.1.4.1 cjep if (!Atomic.ParameterMapping) {
697 1.1.1.1.4.1 cjep llvm::SmallBitVector OccurringIndices(TemplateParams->size());
698 1.1.1.1.4.1 cjep S.MarkUsedTemplateParameters(Atomic.ConstraintExpr, /*OnlyDeduced=*/false,
699 1.1.1.1.4.1 cjep /*Depth=*/0, OccurringIndices);
700 1.1.1.1.4.1 cjep Atomic.ParameterMapping.emplace(
701 1.1.1.1.4.1 cjep MutableArrayRef<TemplateArgumentLoc>(
702 1.1.1.1.4.1 cjep new (S.Context) TemplateArgumentLoc[OccurringIndices.count()],
703 1.1.1.1.4.1 cjep OccurringIndices.count()));
704 1.1.1.1.4.1 cjep for (unsigned I = 0, J = 0, C = TemplateParams->size(); I != C; ++I)
705 1.1.1.1.4.1 cjep if (OccurringIndices[I])
706 1.1.1.1.4.1 cjep new (&(*Atomic.ParameterMapping)[J++]) TemplateArgumentLoc(
707 1.1.1.1.4.1 cjep S.getIdentityTemplateArgumentLoc(TemplateParams->begin()[I],
708 1.1.1.1.4.1 cjep // Here we assume we do not support things like
709 1.1.1.1.4.1 cjep // template<typename A, typename B>
710 1.1.1.1.4.1 cjep // concept C = ...;
711 1.1.1.1.4.1 cjep //
712 1.1.1.1.4.1 cjep // template<typename... Ts> requires C<Ts...>
713 1.1.1.1.4.1 cjep // struct S { };
714 1.1.1.1.4.1 cjep // The above currently yields a diagnostic.
715 1.1.1.1.4.1 cjep // We still might have default arguments for concept parameters.
716 1.1.1.1.4.1 cjep ArgsAsWritten->NumTemplateArgs > I ?
717 1.1.1.1.4.1 cjep ArgsAsWritten->arguments()[I].getLocation() :
718 1.1.1.1.4.1 cjep SourceLocation()));
719 1.1.1.1.4.1 cjep }
720 1.1.1.1.4.1 cjep Sema::InstantiatingTemplate Inst(
721 1.1.1.1.4.1 cjep S, ArgsAsWritten->arguments().front().getSourceRange().getBegin(),
722 1.1.1.1.4.1 cjep Sema::InstantiatingTemplate::ParameterMappingSubstitution{}, Concept,
723 1.1.1.1.4.1 cjep SourceRange(ArgsAsWritten->arguments()[0].getSourceRange().getBegin(),
724 1.1.1.1.4.1 cjep ArgsAsWritten->arguments().back().getSourceRange().getEnd()));
725 1.1.1.1.4.1 cjep if (S.SubstTemplateArguments(*Atomic.ParameterMapping, MLTAL, SubstArgs))
726 1.1.1.1.4.1 cjep return true;
727 1.1.1.1.4.1 cjep Atomic.ParameterMapping.emplace(
728 1.1.1.1.4.1 cjep MutableArrayRef<TemplateArgumentLoc>(
729 1.1.1.1.4.1 cjep new (S.Context) TemplateArgumentLoc[SubstArgs.size()],
730 1.1.1.1.4.1 cjep SubstArgs.size()));
731 1.1.1.1.4.1 cjep std::copy(SubstArgs.arguments().begin(), SubstArgs.arguments().end(),
732 1.1.1.1.4.1 cjep N.getAtomicConstraint()->ParameterMapping->begin());
733 1.1.1.1.4.1 cjep return false;
734 1.1.1.1.4.1 cjep }
735 1.1.1.1.4.1 cjep
736 1.1.1.1.4.1 cjep Optional<NormalizedConstraint>
737 1.1.1.1.4.1 cjep NormalizedConstraint::fromConstraintExprs(Sema &S, NamedDecl *D,
738 1.1.1.1.4.1 cjep ArrayRef<const Expr *> E) {
739 1.1.1.1.4.1 cjep assert(E.size() != 0);
740 1.1.1.1.4.1 cjep auto First = fromConstraintExpr(S, D, E[0]);
741 1.1.1.1.4.1 cjep if (E.size() == 1)
742 1.1.1.1.4.1 cjep return First;
743 1.1.1.1.4.1 cjep auto Second = fromConstraintExpr(S, D, E[1]);
744 1.1.1.1.4.1 cjep if (!Second)
745 1.1.1.1.4.1 cjep return None;
746 1.1.1.1.4.1 cjep llvm::Optional<NormalizedConstraint> Conjunction;
747 1.1.1.1.4.1 cjep Conjunction.emplace(S.Context, std::move(*First), std::move(*Second),
748 1.1.1.1.4.1 cjep CCK_Conjunction);
749 1.1.1.1.4.1 cjep for (unsigned I = 2; I < E.size(); ++I) {
750 1.1.1.1.4.1 cjep auto Next = fromConstraintExpr(S, D, E[I]);
751 1.1.1.1.4.1 cjep if (!Next)
752 1.1.1.1.4.1 cjep return llvm::Optional<NormalizedConstraint>{};
753 1.1.1.1.4.1 cjep NormalizedConstraint NewConjunction(S.Context, std::move(*Conjunction),
754 1.1.1.1.4.1 cjep std::move(*Next), CCK_Conjunction);
755 1.1.1.1.4.1 cjep *Conjunction = std::move(NewConjunction);
756 1.1.1.1.4.1 cjep }
757 1.1.1.1.4.1 cjep return Conjunction;
758 1.1.1.1.4.1 cjep }
759 1.1.1.1.4.1 cjep
760 1.1.1.1.4.1 cjep llvm::Optional<NormalizedConstraint>
761 1.1.1.1.4.1 cjep NormalizedConstraint::fromConstraintExpr(Sema &S, NamedDecl *D, const Expr *E) {
762 1.1.1.1.4.1 cjep assert(E != nullptr);
763 1.1.1.1.4.1 cjep
764 1.1.1.1.4.1 cjep // C++ [temp.constr.normal]p1.1
765 1.1.1.1.4.1 cjep // [...]
766 1.1.1.1.4.1 cjep // - The normal form of an expression (E) is the normal form of E.
767 1.1.1.1.4.1 cjep // [...]
768 1.1.1.1.4.1 cjep E = E->IgnoreParenImpCasts();
769 1.1.1.1.4.1 cjep if (LogicalBinOp BO = E) {
770 1.1.1.1.4.1 cjep auto LHS = fromConstraintExpr(S, D, BO.getLHS());
771 1.1.1.1.4.1 cjep if (!LHS)
772 1.1.1.1.4.1 cjep return None;
773 1.1.1.1.4.1 cjep auto RHS = fromConstraintExpr(S, D, BO.getRHS());
774 1.1.1.1.4.1 cjep if (!RHS)
775 1.1.1.1.4.1 cjep return None;
776 1.1.1.1.4.1 cjep
777 1.1.1.1.4.1 cjep return NormalizedConstraint(S.Context, std::move(*LHS), std::move(*RHS),
778 1.1.1.1.4.1 cjep BO.isAnd() ? CCK_Conjunction : CCK_Disjunction);
779 1.1.1.1.4.1 cjep } else if (auto *CSE = dyn_cast<const ConceptSpecializationExpr>(E)) {
780 1.1.1.1.4.1 cjep const NormalizedConstraint *SubNF;
781 1.1.1.1.4.1 cjep {
782 1.1.1.1.4.1 cjep Sema::InstantiatingTemplate Inst(
783 1.1.1.1.4.1 cjep S, CSE->getExprLoc(),
784 1.1.1.1.4.1 cjep Sema::InstantiatingTemplate::ConstraintNormalization{}, D,
785 1.1.1.1.4.1 cjep CSE->getSourceRange());
786 1.1.1.1.4.1 cjep // C++ [temp.constr.normal]p1.1
787 1.1.1.1.4.1 cjep // [...]
788 1.1.1.1.4.1 cjep // The normal form of an id-expression of the form C<A1, A2, ..., AN>,
789 1.1.1.1.4.1 cjep // where C names a concept, is the normal form of the
790 1.1.1.1.4.1 cjep // constraint-expression of C, after substituting A1, A2, ..., AN for Cs
791 1.1.1.1.4.1 cjep // respective template parameters in the parameter mappings in each atomic
792 1.1.1.1.4.1 cjep // constraint. If any such substitution results in an invalid type or
793 1.1.1.1.4.1 cjep // expression, the program is ill-formed; no diagnostic is required.
794 1.1.1.1.4.1 cjep // [...]
795 1.1.1.1.4.1 cjep ConceptDecl *CD = CSE->getNamedConcept();
796 1.1.1.1.4.1 cjep SubNF = S.getNormalizedAssociatedConstraints(CD,
797 1.1.1.1.4.1 cjep {CD->getConstraintExpr()});
798 1.1.1.1.4.1 cjep if (!SubNF)
799 1.1.1.1.4.1 cjep return None;
800 1.1.1.1.4.1 cjep }
801 1.1.1.1.4.1 cjep
802 1.1.1.1.4.1 cjep Optional<NormalizedConstraint> New;
803 1.1.1.1.4.1 cjep New.emplace(S.Context, *SubNF);
804 1.1.1.1.4.1 cjep
805 1.1.1.1.4.1 cjep if (substituteParameterMappings(
806 1.1.1.1.4.1 cjep S, *New, CSE->getNamedConcept(),
807 1.1.1.1.4.1 cjep CSE->getTemplateArguments(), CSE->getTemplateArgsAsWritten()))
808 1.1.1.1.4.1 cjep return None;
809 1.1.1.1.4.1 cjep
810 1.1.1.1.4.1 cjep return New;
811 1.1.1.1.4.1 cjep }
812 1.1.1.1.4.1 cjep return NormalizedConstraint{new (S.Context) AtomicConstraint(S, E)};
813 1.1.1.1.4.1 cjep }
814 1.1.1.1.4.1 cjep
815 1.1.1.1.4.1 cjep using NormalForm =
816 1.1.1.1.4.1 cjep llvm::SmallVector<llvm::SmallVector<AtomicConstraint *, 2>, 4>;
817 1.1.1.1.4.1 cjep
818 1.1.1.1.4.1 cjep static NormalForm makeCNF(const NormalizedConstraint &Normalized) {
819 1.1.1.1.4.1 cjep if (Normalized.isAtomic())
820 1.1.1.1.4.1 cjep return {{Normalized.getAtomicConstraint()}};
821 1.1.1.1.4.1 cjep
822 1.1.1.1.4.1 cjep NormalForm LCNF = makeCNF(Normalized.getLHS());
823 1.1.1.1.4.1 cjep NormalForm RCNF = makeCNF(Normalized.getRHS());
824 1.1.1.1.4.1 cjep if (Normalized.getCompoundKind() == NormalizedConstraint::CCK_Conjunction) {
825 1.1.1.1.4.1 cjep LCNF.reserve(LCNF.size() + RCNF.size());
826 1.1.1.1.4.1 cjep while (!RCNF.empty())
827 1.1.1.1.4.1 cjep LCNF.push_back(RCNF.pop_back_val());
828 1.1.1.1.4.1 cjep return LCNF;
829 1.1.1.1.4.1 cjep }
830 1.1.1.1.4.1 cjep
831 1.1.1.1.4.1 cjep // Disjunction
832 1.1.1.1.4.1 cjep NormalForm Res;
833 1.1.1.1.4.1 cjep Res.reserve(LCNF.size() * RCNF.size());
834 1.1.1.1.4.1 cjep for (auto &LDisjunction : LCNF)
835 1.1.1.1.4.1 cjep for (auto &RDisjunction : RCNF) {
836 1.1.1.1.4.1 cjep NormalForm::value_type Combined;
837 1.1.1.1.4.1 cjep Combined.reserve(LDisjunction.size() + RDisjunction.size());
838 1.1.1.1.4.1 cjep std::copy(LDisjunction.begin(), LDisjunction.end(),
839 1.1.1.1.4.1 cjep std::back_inserter(Combined));
840 1.1.1.1.4.1 cjep std::copy(RDisjunction.begin(), RDisjunction.end(),
841 1.1.1.1.4.1 cjep std::back_inserter(Combined));
842 1.1.1.1.4.1 cjep Res.emplace_back(Combined);
843 1.1.1.1.4.1 cjep }
844 1.1.1.1.4.1 cjep return Res;
845 1.1.1.1.4.1 cjep }
846 1.1.1.1.4.1 cjep
847 1.1.1.1.4.1 cjep static NormalForm makeDNF(const NormalizedConstraint &Normalized) {
848 1.1.1.1.4.1 cjep if (Normalized.isAtomic())
849 1.1.1.1.4.1 cjep return {{Normalized.getAtomicConstraint()}};
850 1.1.1.1.4.1 cjep
851 1.1.1.1.4.1 cjep NormalForm LDNF = makeDNF(Normalized.getLHS());
852 1.1.1.1.4.1 cjep NormalForm RDNF = makeDNF(Normalized.getRHS());
853 1.1.1.1.4.1 cjep if (Normalized.getCompoundKind() == NormalizedConstraint::CCK_Disjunction) {
854 1.1.1.1.4.1 cjep LDNF.reserve(LDNF.size() + RDNF.size());
855 1.1.1.1.4.1 cjep while (!RDNF.empty())
856 1.1.1.1.4.1 cjep LDNF.push_back(RDNF.pop_back_val());
857 1.1.1.1.4.1 cjep return LDNF;
858 1.1.1.1.4.1 cjep }
859 1.1.1.1.4.1 cjep
860 1.1.1.1.4.1 cjep // Conjunction
861 1.1.1.1.4.1 cjep NormalForm Res;
862 1.1.1.1.4.1 cjep Res.reserve(LDNF.size() * RDNF.size());
863 1.1.1.1.4.1 cjep for (auto &LConjunction : LDNF) {
864 1.1.1.1.4.1 cjep for (auto &RConjunction : RDNF) {
865 1.1.1.1.4.1 cjep NormalForm::value_type Combined;
866 1.1.1.1.4.1 cjep Combined.reserve(LConjunction.size() + RConjunction.size());
867 1.1.1.1.4.1 cjep std::copy(LConjunction.begin(), LConjunction.end(),
868 1.1.1.1.4.1 cjep std::back_inserter(Combined));
869 1.1.1.1.4.1 cjep std::copy(RConjunction.begin(), RConjunction.end(),
870 1.1.1.1.4.1 cjep std::back_inserter(Combined));
871 1.1.1.1.4.1 cjep Res.emplace_back(Combined);
872 1.1.1.1.4.1 cjep }
873 1.1.1.1.4.1 cjep }
874 1.1.1.1.4.1 cjep return Res;
875 1.1.1.1.4.1 cjep }
876 1.1.1.1.4.1 cjep
877 1.1.1.1.4.1 cjep template<typename AtomicSubsumptionEvaluator>
878 1.1.1.1.4.1 cjep static bool subsumes(NormalForm PDNF, NormalForm QCNF,
879 1.1.1.1.4.1 cjep AtomicSubsumptionEvaluator E) {
880 1.1.1.1.4.1 cjep // C++ [temp.constr.order] p2
881 1.1.1.1.4.1 cjep // Then, P subsumes Q if and only if, for every disjunctive clause Pi in the
882 1.1.1.1.4.1 cjep // disjunctive normal form of P, Pi subsumes every conjunctive clause Qj in
883 1.1.1.1.4.1 cjep // the conjuctive normal form of Q, where [...]
884 1.1.1.1.4.1 cjep for (const auto &Pi : PDNF) {
885 1.1.1.1.4.1 cjep for (const auto &Qj : QCNF) {
886 1.1.1.1.4.1 cjep // C++ [temp.constr.order] p2
887 1.1.1.1.4.1 cjep // - [...] a disjunctive clause Pi subsumes a conjunctive clause Qj if
888 1.1.1.1.4.1 cjep // and only if there exists an atomic constraint Pia in Pi for which
889 1.1.1.1.4.1 cjep // there exists an atomic constraint, Qjb, in Qj such that Pia
890 1.1.1.1.4.1 cjep // subsumes Qjb.
891 1.1.1.1.4.1 cjep bool Found = false;
892 1.1.1.1.4.1 cjep for (const AtomicConstraint *Pia : Pi) {
893 1.1.1.1.4.1 cjep for (const AtomicConstraint *Qjb : Qj) {
894 1.1.1.1.4.1 cjep if (E(*Pia, *Qjb)) {
895 1.1.1.1.4.1 cjep Found = true;
896 1.1.1.1.4.1 cjep break;
897 1.1.1.1.4.1 cjep }
898 1.1.1.1.4.1 cjep }
899 1.1.1.1.4.1 cjep if (Found)
900 1.1.1.1.4.1 cjep break;
901 1.1.1.1.4.1 cjep }
902 1.1.1.1.4.1 cjep if (!Found)
903 1.1.1.1.4.1 cjep return false;
904 1.1.1.1.4.1 cjep }
905 1.1.1.1.4.1 cjep }
906 1.1.1.1.4.1 cjep return true;
907 1.1.1.1.4.1 cjep }
908 1.1.1.1.4.1 cjep
909 1.1.1.1.4.1 cjep template<typename AtomicSubsumptionEvaluator>
910 1.1.1.1.4.1 cjep static bool subsumes(Sema &S, NamedDecl *DP, ArrayRef<const Expr *> P,
911 1.1.1.1.4.1 cjep NamedDecl *DQ, ArrayRef<const Expr *> Q, bool &Subsumes,
912 1.1.1.1.4.1 cjep AtomicSubsumptionEvaluator E) {
913 1.1.1.1.4.1 cjep // C++ [temp.constr.order] p2
914 1.1.1.1.4.1 cjep // In order to determine if a constraint P subsumes a constraint Q, P is
915 1.1.1.1.4.1 cjep // transformed into disjunctive normal form, and Q is transformed into
916 1.1.1.1.4.1 cjep // conjunctive normal form. [...]
917 1.1.1.1.4.1 cjep auto *PNormalized = S.getNormalizedAssociatedConstraints(DP, P);
918 1.1.1.1.4.1 cjep if (!PNormalized)
919 1.1.1.1.4.1 cjep return true;
920 1.1.1.1.4.1 cjep const NormalForm PDNF = makeDNF(*PNormalized);
921 1.1.1.1.4.1 cjep
922 1.1.1.1.4.1 cjep auto *QNormalized = S.getNormalizedAssociatedConstraints(DQ, Q);
923 1.1.1.1.4.1 cjep if (!QNormalized)
924 1.1.1.1.4.1 cjep return true;
925 1.1.1.1.4.1 cjep const NormalForm QCNF = makeCNF(*QNormalized);
926 1.1.1.1.4.1 cjep
927 1.1.1.1.4.1 cjep Subsumes = subsumes(PDNF, QCNF, E);
928 1.1.1.1.4.1 cjep return false;
929 1.1.1.1.4.1 cjep }
930 1.1.1.1.4.1 cjep
931 1.1.1.1.4.1 cjep bool Sema::IsAtLeastAsConstrained(NamedDecl *D1, ArrayRef<const Expr *> AC1,
932 1.1.1.1.4.1 cjep NamedDecl *D2, ArrayRef<const Expr *> AC2,
933 1.1.1.1.4.1 cjep bool &Result) {
934 1.1.1.1.4.1 cjep if (AC1.empty()) {
935 1.1.1.1.4.1 cjep Result = AC2.empty();
936 1.1.1.1.4.1 cjep return false;
937 1.1.1.1.4.1 cjep }
938 1.1.1.1.4.1 cjep if (AC2.empty()) {
939 1.1.1.1.4.1 cjep // TD1 has associated constraints and TD2 does not.
940 1.1.1.1.4.1 cjep Result = true;
941 1.1.1.1.4.1 cjep return false;
942 1.1.1.1.4.1 cjep }
943 1.1.1.1.4.1 cjep
944 1.1.1.1.4.1 cjep std::pair<NamedDecl *, NamedDecl *> Key{D1, D2};
945 1.1.1.1.4.1 cjep auto CacheEntry = SubsumptionCache.find(Key);
946 1.1.1.1.4.1 cjep if (CacheEntry != SubsumptionCache.end()) {
947 1.1.1.1.4.1 cjep Result = CacheEntry->second;
948 1.1.1.1.4.1 cjep return false;
949 1.1.1.1.4.1 cjep }
950 1.1.1.1.4.1 cjep
951 1.1.1.1.4.1 cjep if (subsumes(*this, D1, AC1, D2, AC2, Result,
952 1.1.1.1.4.1 cjep [this] (const AtomicConstraint &A, const AtomicConstraint &B) {
953 1.1.1.1.4.1 cjep return A.subsumes(Context, B);
954 1.1.1.1.4.1 cjep }))
955 1.1.1.1.4.1 cjep return true;
956 1.1.1.1.4.1 cjep SubsumptionCache.try_emplace(Key, Result);
957 1.1.1.1.4.1 cjep return false;
958 1.1.1.1.4.1 cjep }
959 1.1.1.1.4.1 cjep
960 1.1.1.1.4.1 cjep bool Sema::MaybeEmitAmbiguousAtomicConstraintsDiagnostic(NamedDecl *D1,
961 1.1.1.1.4.1 cjep ArrayRef<const Expr *> AC1, NamedDecl *D2, ArrayRef<const Expr *> AC2) {
962 1.1.1.1.4.1 cjep if (isSFINAEContext())
963 1.1.1.1.4.1 cjep // No need to work here because our notes would be discarded.
964 1.1.1.1.4.1 cjep return false;
965 1.1.1.1.4.1 cjep
966 1.1.1.1.4.1 cjep if (AC1.empty() || AC2.empty())
967 1.1.1.1.4.1 cjep return false;
968 1.1.1.1.4.1 cjep
969 1.1.1.1.4.1 cjep auto NormalExprEvaluator =
970 1.1.1.1.4.1 cjep [this] (const AtomicConstraint &A, const AtomicConstraint &B) {
971 1.1.1.1.4.1 cjep return A.subsumes(Context, B);
972 1.1.1.1.4.1 cjep };
973 1.1.1.1.4.1 cjep
974 1.1.1.1.4.1 cjep const Expr *AmbiguousAtomic1 = nullptr, *AmbiguousAtomic2 = nullptr;
975 1.1.1.1.4.1 cjep auto IdenticalExprEvaluator =
976 1.1.1.1.4.1 cjep [&] (const AtomicConstraint &A, const AtomicConstraint &B) {
977 1.1.1.1.4.1 cjep if (!A.hasMatchingParameterMapping(Context, B))
978 1.1.1.1.4.1 cjep return false;
979 1.1.1.1.4.1 cjep const Expr *EA = A.ConstraintExpr, *EB = B.ConstraintExpr;
980 1.1.1.1.4.1 cjep if (EA == EB)
981 1.1.1.1.4.1 cjep return true;
982 1.1.1.1.4.1 cjep
983 1.1.1.1.4.1 cjep // Not the same source level expression - are the expressions
984 1.1.1.1.4.1 cjep // identical?
985 1.1.1.1.4.1 cjep llvm::FoldingSetNodeID IDA, IDB;
986 1.1.1.1.4.1 cjep EA->Profile(IDA, Context, /*Cannonical=*/true);
987 1.1.1.1.4.1 cjep EB->Profile(IDB, Context, /*Cannonical=*/true);
988 1.1.1.1.4.1 cjep if (IDA != IDB)
989 1.1.1.1.4.1 cjep return false;
990 1.1.1.1.4.1 cjep
991 1.1.1.1.4.1 cjep AmbiguousAtomic1 = EA;
992 1.1.1.1.4.1 cjep AmbiguousAtomic2 = EB;
993 1.1.1.1.4.1 cjep return true;
994 1.1.1.1.4.1 cjep };
995 1.1.1.1.4.1 cjep
996 1.1.1.1.4.1 cjep {
997 1.1.1.1.4.1 cjep // The subsumption checks might cause diagnostics
998 1.1.1.1.4.1 cjep SFINAETrap Trap(*this);
999 1.1.1.1.4.1 cjep auto *Normalized1 = getNormalizedAssociatedConstraints(D1, AC1);
1000 1.1.1.1.4.1 cjep if (!Normalized1)
1001 1.1.1.1.4.1 cjep return false;
1002 1.1.1.1.4.1 cjep const NormalForm DNF1 = makeDNF(*Normalized1);
1003 1.1.1.1.4.1 cjep const NormalForm CNF1 = makeCNF(*Normalized1);
1004 1.1.1.1.4.1 cjep
1005 1.1.1.1.4.1 cjep auto *Normalized2 = getNormalizedAssociatedConstraints(D2, AC2);
1006 1.1.1.1.4.1 cjep if (!Normalized2)
1007 1.1.1.1.4.1 cjep return false;
1008 1.1.1.1.4.1 cjep const NormalForm DNF2 = makeDNF(*Normalized2);
1009 1.1.1.1.4.1 cjep const NormalForm CNF2 = makeCNF(*Normalized2);
1010 1.1.1.1.4.1 cjep
1011 1.1.1.1.4.1 cjep bool Is1AtLeastAs2Normally = subsumes(DNF1, CNF2, NormalExprEvaluator);
1012 1.1.1.1.4.1 cjep bool Is2AtLeastAs1Normally = subsumes(DNF2, CNF1, NormalExprEvaluator);
1013 1.1.1.1.4.1 cjep bool Is1AtLeastAs2 = subsumes(DNF1, CNF2, IdenticalExprEvaluator);
1014 1.1.1.1.4.1 cjep bool Is2AtLeastAs1 = subsumes(DNF2, CNF1, IdenticalExprEvaluator);
1015 1.1.1.1.4.1 cjep if (Is1AtLeastAs2 == Is1AtLeastAs2Normally &&
1016 1.1.1.1.4.1 cjep Is2AtLeastAs1 == Is2AtLeastAs1Normally)
1017 1.1.1.1.4.1 cjep // Same result - no ambiguity was caused by identical atomic expressions.
1018 1.1.1.1.4.1 cjep return false;
1019 1.1.1.1.4.1 cjep }
1020 1.1.1.1.4.1 cjep
1021 1.1.1.1.4.1 cjep // A different result! Some ambiguous atomic constraint(s) caused a difference
1022 1.1.1.1.4.1 cjep assert(AmbiguousAtomic1 && AmbiguousAtomic2);
1023 1.1.1.1.4.1 cjep
1024 1.1.1.1.4.1 cjep Diag(AmbiguousAtomic1->getBeginLoc(), diag::note_ambiguous_atomic_constraints)
1025 1.1.1.1.4.1 cjep << AmbiguousAtomic1->getSourceRange();
1026 1.1.1.1.4.1 cjep Diag(AmbiguousAtomic2->getBeginLoc(),
1027 1.1.1.1.4.1 cjep diag::note_ambiguous_atomic_constraints_similar_expression)
1028 1.1.1.1.4.1 cjep << AmbiguousAtomic2->getSourceRange();
1029 1.1.1.1.4.1 cjep return true;
1030 1.1.1.1.4.1 cjep }
1031 1.1.1.1.4.1 cjep
1032 1.1.1.1.4.1 cjep concepts::ExprRequirement::ExprRequirement(
1033 1.1.1.1.4.1 cjep Expr *E, bool IsSimple, SourceLocation NoexceptLoc,
1034 1.1.1.1.4.1 cjep ReturnTypeRequirement Req, SatisfactionStatus Status,
1035 1.1.1.1.4.1 cjep ConceptSpecializationExpr *SubstitutedConstraintExpr) :
1036 1.1.1.1.4.1 cjep Requirement(IsSimple ? RK_Simple : RK_Compound, Status == SS_Dependent,
1037 1.1.1.1.4.1 cjep Status == SS_Dependent &&
1038 1.1.1.1.4.1 cjep (E->containsUnexpandedParameterPack() ||
1039 1.1.1.1.4.1 cjep Req.containsUnexpandedParameterPack()),
1040 1.1.1.1.4.1 cjep Status == SS_Satisfied), Value(E), NoexceptLoc(NoexceptLoc),
1041 1.1.1.1.4.1 cjep TypeReq(Req), SubstitutedConstraintExpr(SubstitutedConstraintExpr),
1042 1.1.1.1.4.1 cjep Status(Status) {
1043 1.1.1.1.4.1 cjep assert((!IsSimple || (Req.isEmpty() && NoexceptLoc.isInvalid())) &&
1044 1.1.1.1.4.1 cjep "Simple requirement must not have a return type requirement or a "
1045 1.1.1.1.4.1 cjep "noexcept specification");
1046 1.1.1.1.4.1 cjep assert((Status > SS_TypeRequirementSubstitutionFailure && Req.isTypeConstraint()) ==
1047 1.1.1.1.4.1 cjep (SubstitutedConstraintExpr != nullptr));
1048 1.1.1.1.4.1 cjep }
1049 1.1.1.1.4.1 cjep
1050 1.1.1.1.4.1 cjep concepts::ExprRequirement::ExprRequirement(
1051 1.1.1.1.4.1 cjep SubstitutionDiagnostic *ExprSubstDiag, bool IsSimple,
1052 1.1.1.1.4.1 cjep SourceLocation NoexceptLoc, ReturnTypeRequirement Req) :
1053 1.1.1.1.4.1 cjep Requirement(IsSimple ? RK_Simple : RK_Compound, Req.isDependent(),
1054 1.1.1.1.4.1 cjep Req.containsUnexpandedParameterPack(), /*IsSatisfied=*/false),
1055 1.1.1.1.4.1 cjep Value(ExprSubstDiag), NoexceptLoc(NoexceptLoc), TypeReq(Req),
1056 1.1.1.1.4.1 cjep Status(SS_ExprSubstitutionFailure) {
1057 1.1.1.1.4.1 cjep assert((!IsSimple || (Req.isEmpty() && NoexceptLoc.isInvalid())) &&
1058 1.1.1.1.4.1 cjep "Simple requirement must not have a return type requirement or a "
1059 1.1.1.1.4.1 cjep "noexcept specification");
1060 1.1.1.1.4.1 cjep }
1061 1.1.1.1.4.1 cjep
1062 1.1.1.1.4.1 cjep concepts::ExprRequirement::ReturnTypeRequirement::
1063 1.1.1.1.4.1 cjep ReturnTypeRequirement(TemplateParameterList *TPL) :
1064 1.1.1.1.4.1 cjep TypeConstraintInfo(TPL, 0) {
1065 1.1.1.1.4.1 cjep assert(TPL->size() == 1);
1066 1.1.1.1.4.1 cjep const TypeConstraint *TC =
1067 1.1.1.1.4.1 cjep cast<TemplateTypeParmDecl>(TPL->getParam(0))->getTypeConstraint();
1068 1.1.1.1.4.1 cjep assert(TC &&
1069 1.1.1.1.4.1 cjep "TPL must have a template type parameter with a type constraint");
1070 1.1.1.1.4.1 cjep auto *Constraint =
1071 1.1.1.1.4.1 cjep cast_or_null<ConceptSpecializationExpr>(
1072 1.1.1.1.4.1 cjep TC->getImmediatelyDeclaredConstraint());
1073 1.1.1.1.4.1 cjep bool Dependent =
1074 1.1.1.1.4.1 cjep Constraint->getTemplateArgsAsWritten() &&
1075 1.1.1.1.4.1 cjep TemplateSpecializationType::anyInstantiationDependentTemplateArguments(
1076 1.1.1.1.4.1 cjep Constraint->getTemplateArgsAsWritten()->arguments().drop_front(1));
1077 1.1.1.1.4.1 cjep TypeConstraintInfo.setInt(Dependent ? 1 : 0);
1078 1.1.1.1.4.1 cjep }
1079 1.1.1.1.4.1 cjep
1080 1.1.1.1.4.1 cjep concepts::TypeRequirement::TypeRequirement(TypeSourceInfo *T) :
1081 1.1.1.1.4.1 cjep Requirement(RK_Type, T->getType()->isInstantiationDependentType(),
1082 1.1.1.1.4.1 cjep T->getType()->containsUnexpandedParameterPack(),
1083 1.1.1.1.4.1 cjep // We reach this ctor with either dependent types (in which
1084 1.1.1.1.4.1 cjep // IsSatisfied doesn't matter) or with non-dependent type in
1085 1.1.1.1.4.1 cjep // which the existence of the type indicates satisfaction.
1086 1.1.1.1.4.1 cjep /*IsSatisfied=*/true),
1087 1.1.1.1.4.1 cjep Value(T),
1088 1.1.1.1.4.1 cjep Status(T->getType()->isInstantiationDependentType() ? SS_Dependent
1089 1.1.1.1.4.1 cjep : SS_Satisfied) {}
1090