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