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