clang  16.0.0git
SemaConcept.cpp
Go to the documentation of this file.
1 //===-- SemaConcept.cpp - Semantic Analysis for Constraints and Concepts --===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file implements semantic analysis for C++ constraints and concepts.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "TreeTransform.h"
14 #include "clang/Sema/SemaConcept.h"
15 #include "clang/Sema/Sema.h"
19 #include "clang/Sema/Template.h"
20 #include "clang/Sema/Overload.h"
22 #include "clang/AST/ASTLambda.h"
23 #include "clang/AST/ExprConcepts.h"
26 #include "llvm/ADT/DenseMap.h"
27 #include "llvm/ADT/PointerUnion.h"
28 #include "llvm/ADT/StringExtras.h"
29 
30 using namespace clang;
31 using namespace sema;
32 
33 namespace {
34 class LogicalBinOp {
35  SourceLocation Loc;
37  const Expr *LHS = nullptr;
38  const Expr *RHS = nullptr;
39 
40 public:
41  LogicalBinOp(const Expr *E) {
42  if (auto *BO = dyn_cast<BinaryOperator>(E)) {
43  Op = BinaryOperator::getOverloadedOperator(BO->getOpcode());
44  LHS = BO->getLHS();
45  RHS = BO->getRHS();
46  Loc = BO->getExprLoc();
47  } else if (auto *OO = dyn_cast<CXXOperatorCallExpr>(E)) {
48  // If OO is not || or && it might not have exactly 2 arguments.
49  if (OO->getNumArgs() == 2) {
50  Op = OO->getOperator();
51  LHS = OO->getArg(0);
52  RHS = OO->getArg(1);
53  Loc = OO->getOperatorLoc();
54  }
55  }
56  }
57 
58  bool isAnd() const { return Op == OO_AmpAmp; }
59  bool isOr() const { return Op == OO_PipePipe; }
60  explicit operator bool() const { return isAnd() || isOr(); }
61 
62  const Expr *getLHS() const { return LHS; }
63  const Expr *getRHS() const { return RHS; }
64 
65  ExprResult recreateBinOp(Sema &SemaRef, ExprResult LHS) const {
66  return recreateBinOp(SemaRef, LHS, const_cast<Expr *>(getRHS()));
67  }
68 
69  ExprResult recreateBinOp(Sema &SemaRef, ExprResult LHS,
70  ExprResult RHS) const {
71  assert((isAnd() || isOr()) && "Not the right kind of op?");
72  assert((!LHS.isInvalid() && !RHS.isInvalid()) && "not good expressions?");
73 
74  if (!LHS.isUsable() || !RHS.isUsable())
75  return ExprEmpty();
76 
77  // We should just be able to 'normalize' these to the builtin Binary
78  // Operator, since that is how they are evaluated in constriant checks.
79  return BinaryOperator::Create(SemaRef.Context, LHS.get(), RHS.get(),
81  SemaRef.Context.BoolTy, VK_PRValue,
83  }
84 };
85 }
86 
87 bool Sema::CheckConstraintExpression(const Expr *ConstraintExpression,
88  Token NextToken, bool *PossibleNonPrimary,
89  bool IsTrailingRequiresClause) {
90  // C++2a [temp.constr.atomic]p1
91  // ..E shall be a constant expression of type bool.
92 
93  ConstraintExpression = ConstraintExpression->IgnoreParenImpCasts();
94 
95  if (LogicalBinOp BO = ConstraintExpression) {
96  return CheckConstraintExpression(BO.getLHS(), NextToken,
97  PossibleNonPrimary) &&
98  CheckConstraintExpression(BO.getRHS(), NextToken,
99  PossibleNonPrimary);
100  } else if (auto *C = dyn_cast<ExprWithCleanups>(ConstraintExpression))
101  return CheckConstraintExpression(C->getSubExpr(), NextToken,
102  PossibleNonPrimary);
103 
104  QualType Type = ConstraintExpression->getType();
105 
106  auto CheckForNonPrimary = [&] {
107  if (PossibleNonPrimary)
108  *PossibleNonPrimary =
109  // We have the following case:
110  // template<typename> requires func(0) struct S { };
111  // The user probably isn't aware of the parentheses required around
112  // the function call, and we're only going to parse 'func' as the
113  // primary-expression, and complain that it is of non-bool type.
114  (NextToken.is(tok::l_paren) &&
115  (IsTrailingRequiresClause ||
116  (Type->isDependentType() &&
117  isa<UnresolvedLookupExpr>(ConstraintExpression)) ||
118  Type->isFunctionType() ||
119  Type->isSpecificBuiltinType(BuiltinType::Overload))) ||
120  // We have the following case:
121  // template<typename T> requires size_<T> == 0 struct S { };
122  // The user probably isn't aware of the parentheses required around
123  // the binary operator, and we're only going to parse 'func' as the
124  // first operand, and complain that it is of non-bool type.
125  getBinOpPrecedence(NextToken.getKind(),
126  /*GreaterThanIsOperator=*/true,
127  getLangOpts().CPlusPlus11) > prec::LogicalAnd;
128  };
129 
130  // An atomic constraint!
131  if (ConstraintExpression->isTypeDependent()) {
132  CheckForNonPrimary();
133  return true;
134  }
135 
136  if (!Context.hasSameUnqualifiedType(Type, Context.BoolTy)) {
137  Diag(ConstraintExpression->getExprLoc(),
138  diag::err_non_bool_atomic_constraint) << Type
139  << ConstraintExpression->getSourceRange();
140  CheckForNonPrimary();
141  return false;
142  }
143 
144  if (PossibleNonPrimary)
145  *PossibleNonPrimary = false;
146  return true;
147 }
148 
149 namespace {
150 struct SatisfactionStackRAII {
151  Sema &SemaRef;
152  SatisfactionStackRAII(Sema &SemaRef, llvm::FoldingSetNodeID FSNID)
153  : SemaRef(SemaRef) {
154  SemaRef.PushSatisfactionStackEntry(FSNID);
155  }
156  ~SatisfactionStackRAII() { SemaRef.PopSatisfactionStackEntry(); }
157 };
158 } // namespace
159 
160 template <typename AtomicEvaluator>
161 static ExprResult
162 calculateConstraintSatisfaction(Sema &S, const Expr *ConstraintExpr,
163  ConstraintSatisfaction &Satisfaction,
164  AtomicEvaluator &&Evaluator) {
165  ConstraintExpr = ConstraintExpr->IgnoreParenImpCasts();
166 
167  if (LogicalBinOp BO = ConstraintExpr) {
169  S, BO.getLHS(), Satisfaction, Evaluator);
170 
171  if (LHSRes.isInvalid())
172  return ExprError();
173 
174  bool IsLHSSatisfied = Satisfaction.IsSatisfied;
175 
176  if (BO.isOr() && IsLHSSatisfied)
177  // [temp.constr.op] p3
178  // A disjunction is a constraint taking two operands. To determine if
179  // a disjunction is satisfied, the satisfaction of the first operand
180  // is checked. If that is satisfied, the disjunction is satisfied.
181  // Otherwise, the disjunction is satisfied if and only if the second
182  // operand is satisfied.
183  return BO.recreateBinOp(S, LHSRes);
184 
185  if (BO.isAnd() && !IsLHSSatisfied)
186  // [temp.constr.op] p2
187  // A conjunction is a constraint taking two operands. To determine if
188  // a conjunction is satisfied, the satisfaction of the first operand
189  // is checked. If that is not satisfied, the conjunction is not
190  // satisfied. Otherwise, the conjunction is satisfied if and only if
191  // the second operand is satisfied.
192  return BO.recreateBinOp(S, LHSRes);
193 
195  S, BO.getRHS(), Satisfaction, std::forward<AtomicEvaluator>(Evaluator));
196  if (RHSRes.isInvalid())
197  return ExprError();
198 
199  return BO.recreateBinOp(S, LHSRes, RHSRes);
200  }
201 
202  if (auto *C = dyn_cast<ExprWithCleanups>(ConstraintExpr)) {
203  // These aren't evaluated, so we don't care about cleanups, so we can just
204  // evaluate these as if the cleanups didn't exist.
206  S, C->getSubExpr(), Satisfaction,
207  std::forward<AtomicEvaluator>(Evaluator));
208  }
209 
210  // An atomic constraint expression
211  ExprResult SubstitutedAtomicExpr = Evaluator(ConstraintExpr);
212 
213  if (SubstitutedAtomicExpr.isInvalid())
214  return ExprError();
215 
216  if (!SubstitutedAtomicExpr.isUsable())
217  // Evaluator has decided satisfaction without yielding an expression.
218  return ExprEmpty();
219 
220  // We don't have the ability to evaluate this, since it contains a
221  // RecoveryExpr, so we want to fail overload resolution. Otherwise,
222  // we'd potentially pick up a different overload, and cause confusing
223  // diagnostics. SO, add a failure detail that will cause us to make this
224  // overload set not viable.
225  if (SubstitutedAtomicExpr.get()->containsErrors()) {
226  Satisfaction.IsSatisfied = false;
227  Satisfaction.ContainsErrors = true;
228 
229  PartialDiagnostic Msg = S.PDiag(diag::note_constraint_references_error);
230  SmallString<128> DiagString;
231  DiagString = ": ";
232  Msg.EmitToString(S.getDiagnostics(), DiagString);
233  unsigned MessageSize = DiagString.size();
234  char *Mem = new (S.Context) char[MessageSize];
235  memcpy(Mem, DiagString.c_str(), MessageSize);
236  Satisfaction.Details.emplace_back(
237  ConstraintExpr,
239  SubstitutedAtomicExpr.get()->getBeginLoc(),
240  StringRef(Mem, MessageSize)});
241  return SubstitutedAtomicExpr;
242  }
243 
244  EnterExpressionEvaluationContext ConstantEvaluated(
246  SmallVector<PartialDiagnosticAt, 2> EvaluationDiags;
247  Expr::EvalResult EvalResult;
248  EvalResult.Diag = &EvaluationDiags;
249  if (!SubstitutedAtomicExpr.get()->EvaluateAsConstantExpr(EvalResult,
250  S.Context) ||
251  !EvaluationDiags.empty()) {
252  // C++2a [temp.constr.atomic]p1
253  // ...E shall be a constant expression of type bool.
254  S.Diag(SubstitutedAtomicExpr.get()->getBeginLoc(),
255  diag::err_non_constant_constraint_expression)
256  << SubstitutedAtomicExpr.get()->getSourceRange();
257  for (const PartialDiagnosticAt &PDiag : EvaluationDiags)
258  S.Diag(PDiag.first, PDiag.second);
259  return ExprError();
260  }
261 
262  assert(EvalResult.Val.isInt() &&
263  "evaluating bool expression didn't produce int");
264  Satisfaction.IsSatisfied = EvalResult.Val.getInt().getBoolValue();
265  if (!Satisfaction.IsSatisfied)
266  Satisfaction.Details.emplace_back(ConstraintExpr,
267  SubstitutedAtomicExpr.get());
268 
269  return SubstitutedAtomicExpr;
270 }
271 
272 static bool
273 DiagRecursiveConstraintEval(Sema &S, llvm::FoldingSetNodeID &ID, const Expr *E,
274  const MultiLevelTemplateArgumentList &MLTAL) {
275  E->Profile(ID, S.Context, /*Canonical=*/true);
276  for (const auto &List : MLTAL)
277  for (const auto &TemplateArg : List.Args)
278  TemplateArg.Profile(ID, S.Context);
279 
280  // Note that we have to do this with our own collection, because there are
281  // times where a constraint-expression check can cause us to need to evaluate
282  // other constriants that are unrelated, such as when evaluating a recovery
283  // expression, or when trying to determine the constexpr-ness of special
284  // members. Otherwise we could just use the
285  // Sema::InstantiatingTemplate::isAlreadyBeingInstantiated function.
286  if (S.SatisfactionStackContains(ID)) {
287  S.Diag(E->getExprLoc(), diag::err_constraint_depends_on_self)
288  << const_cast<Expr *>(E) << E->getSourceRange();
289  return true;
290  }
291 
292  return false;
293 }
294 
296  Sema &S, const NamedDecl *Template, SourceLocation TemplateNameLoc,
297  const MultiLevelTemplateArgumentList &MLTAL, const Expr *ConstraintExpr,
298  ConstraintSatisfaction &Satisfaction) {
300  S, ConstraintExpr, Satisfaction, [&](const Expr *AtomicExpr) {
301  EnterExpressionEvaluationContext ConstantEvaluated(
304 
305  // Atomic constraint - substitute arguments and check satisfaction.
306  ExprResult SubstitutedExpression;
307  {
308  TemplateDeductionInfo Info(TemplateNameLoc);
311  const_cast<NamedDecl *>(Template), Info,
313  if (Inst.isInvalid())
314  return ExprError();
315 
316  llvm::FoldingSetNodeID ID;
317  if (DiagRecursiveConstraintEval(S, ID, AtomicExpr, MLTAL)) {
318  Satisfaction.IsSatisfied = false;
319  Satisfaction.ContainsErrors = true;
320  return ExprEmpty();
321  }
322 
323  SatisfactionStackRAII StackRAII(S, ID);
324 
325  // We do not want error diagnostics escaping here.
326  Sema::SFINAETrap Trap(S);
327  SubstitutedExpression =
328  S.SubstConstraintExpr(const_cast<Expr *>(AtomicExpr), MLTAL);
329  // Substitution might have stripped off a contextual conversion to
330  // bool if this is the operand of an '&&' or '||'. For example, we
331  // might lose an lvalue-to-rvalue conversion here. If so, put it back
332  // before we try to evaluate.
333  if (!SubstitutedExpression.isInvalid())
334  SubstitutedExpression =
335  S.PerformContextuallyConvertToBool(SubstitutedExpression.get());
336  if (SubstitutedExpression.isInvalid() || Trap.hasErrorOccurred()) {
337  // C++2a [temp.constr.atomic]p1
338  // ...If substitution results in an invalid type or expression, the
339  // constraint is not satisfied.
340  if (!Trap.hasErrorOccurred())
341  // A non-SFINAE error has occurred as a result of this
342  // substitution.
343  return ExprError();
344 
347  Info.takeSFINAEDiagnostic(SubstDiag);
348  // FIXME: Concepts: This is an unfortunate consequence of there
349  // being no serialization code for PartialDiagnostics and the fact
350  // that serializing them would likely take a lot more storage than
351  // just storing them as strings. We would still like, in the
352  // future, to serialize the proper PartialDiagnostic as serializing
353  // it as a string defeats the purpose of the diagnostic mechanism.
354  SmallString<128> DiagString;
355  DiagString = ": ";
356  SubstDiag.second.EmitToString(S.getDiagnostics(), DiagString);
357  unsigned MessageSize = DiagString.size();
358  char *Mem = new (S.Context) char[MessageSize];
359  memcpy(Mem, DiagString.c_str(), MessageSize);
360  Satisfaction.Details.emplace_back(
361  AtomicExpr,
363  SubstDiag.first, StringRef(Mem, MessageSize)});
364  Satisfaction.IsSatisfied = false;
365  return ExprEmpty();
366  }
367  }
368 
369  if (!S.CheckConstraintExpression(SubstitutedExpression.get()))
370  return ExprError();
371 
372  return SubstitutedExpression;
373  });
374 }
375 
377  Sema &S, const NamedDecl *Template, ArrayRef<const Expr *> ConstraintExprs,
379  const MultiLevelTemplateArgumentList &TemplateArgsLists,
380  SourceRange TemplateIDRange, ConstraintSatisfaction &Satisfaction) {
381  if (ConstraintExprs.empty()) {
382  Satisfaction.IsSatisfied = true;
383  return false;
384  }
385 
386  if (TemplateArgsLists.isAnyArgInstantiationDependent()) {
387  // No need to check satisfaction for dependent constraint expressions.
388  Satisfaction.IsSatisfied = true;
389  return false;
390  }
391 
392  ArrayRef<TemplateArgument> TemplateArgs =
393  TemplateArgsLists.getNumSubstitutedLevels() > 0
394  ? TemplateArgsLists.getOutermost()
396  Sema::InstantiatingTemplate Inst(S, TemplateIDRange.getBegin(),
398  const_cast<NamedDecl *>(Template), TemplateArgs, TemplateIDRange);
399  if (Inst.isInvalid())
400  return true;
401 
402  for (const Expr *ConstraintExpr : ConstraintExprs) {
404  S, Template, TemplateIDRange.getBegin(), TemplateArgsLists,
405  ConstraintExpr, Satisfaction);
406  if (Res.isInvalid())
407  return true;
408 
409  Converted.push_back(Res.get());
410  if (!Satisfaction.IsSatisfied) {
411  // Backfill the 'converted' list with nulls so we can keep the Converted
412  // and unconverted lists in sync.
413  Converted.append(ConstraintExprs.size() - Converted.size(), nullptr);
414  // [temp.constr.op] p2
415  // [...] To determine if a conjunction is satisfied, the satisfaction
416  // of the first operand is checked. If that is not satisfied, the
417  // conjunction is not satisfied. [...]
418  return false;
419  }
420  }
421  return false;
422 }
423 
425  const NamedDecl *Template, ArrayRef<const Expr *> ConstraintExprs,
426  llvm::SmallVectorImpl<Expr *> &ConvertedConstraints,
427  const MultiLevelTemplateArgumentList &TemplateArgsLists,
428  SourceRange TemplateIDRange, ConstraintSatisfaction &OutSatisfaction) {
429  if (ConstraintExprs.empty()) {
430  OutSatisfaction.IsSatisfied = true;
431  return false;
432  }
433  if (!Template) {
435  *this, nullptr, ConstraintExprs, ConvertedConstraints,
436  TemplateArgsLists, TemplateIDRange, OutSatisfaction);
437  }
438 
439  // A list of the template argument list flattened in a predictible manner for
440  // the purposes of caching. The ConstraintSatisfaction type is in AST so it
441  // has no access to the MultiLevelTemplateArgumentList, so this has to happen
442  // here.
444  for (auto List : TemplateArgsLists)
445  FlattenedArgs.insert(FlattenedArgs.end(), List.Args.begin(),
446  List.Args.end());
447 
448  llvm::FoldingSetNodeID ID;
449  ConstraintSatisfaction::Profile(ID, Context, Template, FlattenedArgs);
450  void *InsertPos;
451  if (auto *Cached = SatisfactionCache.FindNodeOrInsertPos(ID, InsertPos)) {
452  OutSatisfaction = *Cached;
453  return false;
454  }
455 
456  auto Satisfaction =
457  std::make_unique<ConstraintSatisfaction>(Template, FlattenedArgs);
458  if (::CheckConstraintSatisfaction(*this, Template, ConstraintExprs,
459  ConvertedConstraints, TemplateArgsLists,
460  TemplateIDRange, *Satisfaction)) {
461  OutSatisfaction = *Satisfaction;
462  return true;
463  }
464 
465  if (auto *Cached = SatisfactionCache.FindNodeOrInsertPos(ID, InsertPos)) {
466  // The evaluation of this constraint resulted in us trying to re-evaluate it
467  // recursively. This isn't really possible, except we try to form a
468  // RecoveryExpr as a part of the evaluation. If this is the case, just
469  // return the 'cached' version (which will have the same result), and save
470  // ourselves the extra-insert. If it ever becomes possible to legitimately
471  // recursively check a constraint, we should skip checking the 'inner' one
472  // above, and replace the cached version with this one, as it would be more
473  // specific.
474  OutSatisfaction = *Cached;
475  return false;
476  }
477 
478  // Else we can simply add this satisfaction to the list.
479  OutSatisfaction = *Satisfaction;
480  // We cannot use InsertPos here because CheckConstraintSatisfaction might have
481  // invalidated it.
482  // Note that entries of SatisfactionCache are deleted in Sema's destructor.
483  SatisfactionCache.InsertNode(Satisfaction.release());
484  return false;
485 }
486 
487 bool Sema::CheckConstraintSatisfaction(const Expr *ConstraintExpr,
488  ConstraintSatisfaction &Satisfaction) {
490  *this, ConstraintExpr, Satisfaction,
491  [this](const Expr *AtomicExpr) -> ExprResult {
492  // We only do this to immitate lvalue-to-rvalue conversion.
493  return PerformContextuallyConvertToBool(
494  const_cast<Expr *>(AtomicExpr));
495  })
496  .isInvalid();
497 }
498 
499 bool Sema::SetupConstraintScope(
502  if (FD->isTemplateInstantiation() && FD->getPrimaryTemplate()) {
503  FunctionTemplateDecl *PrimaryTemplate = FD->getPrimaryTemplate();
504  InstantiatingTemplate Inst(
505  *this, FD->getPointOfInstantiation(),
507  TemplateArgs ? *TemplateArgs : ArrayRef<TemplateArgument>{},
508  SourceRange());
509  if (Inst.isInvalid())
510  return true;
511 
512  // addInstantiatedParametersToScope creates a map of 'uninstantiated' to
513  // 'instantiated' parameters and adds it to the context. For the case where
514  // this function is a template being instantiated NOW, we also need to add
515  // the list of current template arguments to the list so that they also can
516  // be picked out of the map.
517  if (auto *SpecArgs = FD->getTemplateSpecializationArgs()) {
518  MultiLevelTemplateArgumentList JustTemplArgs(FD, SpecArgs->asArray(),
519  /*Final=*/false);
520  if (addInstantiatedParametersToScope(
521  FD, PrimaryTemplate->getTemplatedDecl(), Scope, JustTemplArgs))
522  return true;
523  }
524 
525  // If this is a member function, make sure we get the parameters that
526  // reference the original primary template.
527  if (const auto *FromMemTempl =
528  PrimaryTemplate->getInstantiatedFromMemberTemplate()) {
529  if (addInstantiatedParametersToScope(FD, FromMemTempl->getTemplatedDecl(),
530  Scope, MLTAL))
531  return true;
532  }
533 
534  return false;
535  }
536 
539  FunctionDecl *InstantiatedFrom =
542  : FD->getInstantiatedFromDecl();
543 
544  InstantiatingTemplate Inst(
545  *this, FD->getPointOfInstantiation(),
547  TemplateArgs ? *TemplateArgs : ArrayRef<TemplateArgument>{},
548  SourceRange());
549  if (Inst.isInvalid())
550  return true;
551 
552  // Case where this was not a template, but instantiated as a
553  // child-function.
554  if (addInstantiatedParametersToScope(FD, InstantiatedFrom, Scope, MLTAL))
555  return true;
556  }
557 
558  return false;
559 }
560 
561 // This function collects all of the template arguments for the purposes of
562 // constraint-instantiation and checking.
564 Sema::SetupConstraintCheckingTemplateArgumentsAndScope(
568 
569  // Collect the list of template arguments relative to the 'primary' template.
570  // We need the entire list, since the constraint is completely uninstantiated
571  // at this point.
572  MLTAL =
573  getTemplateInstantiationArgs(FD, /*Final=*/false, /*Innermost=*/nullptr,
574  /*RelativeToPrimary=*/true,
575  /*Pattern=*/nullptr,
576  /*ForConstraintInstantiation=*/true);
577  if (SetupConstraintScope(FD, TemplateArgs, MLTAL, Scope))
578  return std::nullopt;
579 
580  return MLTAL;
581 }
582 
584  ConstraintSatisfaction &Satisfaction,
585  SourceLocation UsageLoc,
586  bool ForOverloadResolution) {
587  // Don't check constraints if the function is dependent. Also don't check if
588  // this is a function template specialization, as the call to
589  // CheckinstantiatedFunctionTemplateConstraints after this will check it
590  // better.
591  if (FD->isDependentContext() ||
592  FD->getTemplatedKind() ==
594  Satisfaction.IsSatisfied = true;
595  return false;
596  }
597 
598  DeclContext *CtxToSave = const_cast<FunctionDecl *>(FD);
599 
600  while (isLambdaCallOperator(CtxToSave) || FD->isTransparentContext()) {
601  if (isLambdaCallOperator(CtxToSave))
602  CtxToSave = CtxToSave->getParent()->getParent();
603  else
604  CtxToSave = CtxToSave->getNonTransparentContext();
605  }
606 
607  ContextRAII SavedContext{*this, CtxToSave};
608  LocalInstantiationScope Scope(*this, !ForOverloadResolution ||
611  SetupConstraintCheckingTemplateArgumentsAndScope(
612  const_cast<FunctionDecl *>(FD), {}, Scope);
613 
614  if (!MLTAL)
615  return true;
616 
617  Qualifiers ThisQuals;
618  CXXRecordDecl *Record = nullptr;
619  if (auto *Method = dyn_cast<CXXMethodDecl>(FD)) {
620  ThisQuals = Method->getMethodQualifiers();
621  Record = const_cast<CXXRecordDecl *>(Method->getParent());
622  }
623  CXXThisScopeRAII ThisScope(*this, Record, ThisQuals, Record != nullptr);
624  // We substitute with empty arguments in order to rebuild the atomic
625  // constraint in a constant-evaluated context.
626  // FIXME: Should this be a dedicated TreeTransform?
627  const Expr *RC = FD->getTrailingRequiresClause();
629 
631  FD, {RC}, Converted, *MLTAL,
632  SourceRange(UsageLoc.isValid() ? UsageLoc : FD->getLocation()),
633  Satisfaction))
634  return true;
635 
636  // FIXME: we need to do this for the function constraints for
637  // comparison of constraints to work, but do we also need to do it for
638  // CheckInstantiatedFunctionConstraints? That one is more difficult, but we
639  // seem to always just pick up the constraints from the primary template.
640  assert(Converted.size() <= 1 && "Got more expressions converted?");
641  if (!Converted.empty() && Converted[0] != nullptr)
642  const_cast<FunctionDecl *>(FD)->setTrailingRequiresClause(Converted[0]);
643  return false;
644 }
645 
646 
647 // Figure out the to-translation-unit depth for this function declaration for
648 // the purpose of seeing if they differ by constraints. This isn't the same as
649 // getTemplateDepth, because it includes already instantiated parents.
650 static unsigned
652  bool SkipForSpecialization = false) {
654  ND, /*Final=*/false, /*Innermost=*/nullptr, /*RelativeToPrimary=*/true,
655  /*Pattern=*/nullptr,
656  /*ForConstraintInstantiation=*/true, SkipForSpecialization);
657  return MLTAL.getNumSubstitutedLevels();
658 }
659 
660 namespace {
661  class AdjustConstraintDepth : public TreeTransform<AdjustConstraintDepth> {
662  unsigned TemplateDepth = 0;
663  public:
664  using inherited = TreeTransform<AdjustConstraintDepth>;
665  AdjustConstraintDepth(Sema &SemaRef, unsigned TemplateDepth)
666  : inherited(SemaRef), TemplateDepth(TemplateDepth) {}
667 
668  using inherited::TransformTemplateTypeParmType;
669  QualType TransformTemplateTypeParmType(TypeLocBuilder &TLB,
670  TemplateTypeParmTypeLoc TL, bool) {
671  const TemplateTypeParmType *T = TL.getTypePtr();
672 
673  TemplateTypeParmDecl *NewTTPDecl = nullptr;
674  if (TemplateTypeParmDecl *OldTTPDecl = T->getDecl())
675  NewTTPDecl = cast_or_null<TemplateTypeParmDecl>(
676  TransformDecl(TL.getNameLoc(), OldTTPDecl));
677 
678  QualType Result = getSema().Context.getTemplateTypeParmType(
679  T->getDepth() + TemplateDepth, T->getIndex(), T->isParameterPack(),
680  NewTTPDecl);
682  NewTL.setNameLoc(TL.getNameLoc());
683  return Result;
684  }
685  };
686 } // namespace
687 
689  const Expr *OldConstr,
690  const NamedDecl *New,
691  const Expr *NewConstr) {
692  if (Old && New && Old != New) {
693  unsigned Depth1 = CalculateTemplateDepthForConstraints(
694  *this, Old);
695  unsigned Depth2 = CalculateTemplateDepthForConstraints(
696  *this, New);
697 
698  // Adjust the 'shallowest' verison of this to increase the depth to match
699  // the 'other'.
700  if (Depth2 > Depth1) {
701  OldConstr = AdjustConstraintDepth(*this, Depth2 - Depth1)
702  .TransformExpr(const_cast<Expr *>(OldConstr))
703  .get();
704  } else if (Depth1 > Depth2) {
705  NewConstr = AdjustConstraintDepth(*this, Depth1 - Depth2)
706  .TransformExpr(const_cast<Expr *>(NewConstr))
707  .get();
708  }
709  }
710 
711  llvm::FoldingSetNodeID ID1, ID2;
712  OldConstr->Profile(ID1, Context, /*Canonical=*/true);
713  NewConstr->Profile(ID2, Context, /*Canonical=*/true);
714  return ID1 == ID2;
715 }
716 
718  assert(FD->getFriendObjectKind() && "Must be a friend!");
719 
720  // The logic for non-templates is handled in ASTContext::isSameEntity, so we
721  // don't have to bother checking 'DependsOnEnclosingTemplate' for a
722  // non-function-template.
723  assert(FD->getDescribedFunctionTemplate() &&
724  "Non-function templates don't need to be checked");
725 
728 
729  unsigned OldTemplateDepth = CalculateTemplateDepthForConstraints(*this, FD);
730  for (const Expr *Constraint : ACs)
731  if (ConstraintExpressionDependsOnEnclosingTemplate(FD, OldTemplateDepth,
732  Constraint))
733  return true;
734 
735  return false;
736 }
737 
739  TemplateDecl *TD, const MultiLevelTemplateArgumentList &TemplateArgsLists,
740  SourceRange TemplateIDRange) {
741  ConstraintSatisfaction Satisfaction;
742  llvm::SmallVector<const Expr *, 3> AssociatedConstraints;
743  TD->getAssociatedConstraints(AssociatedConstraints);
744  if (CheckConstraintSatisfaction(TD, AssociatedConstraints, TemplateArgsLists,
745  TemplateIDRange, Satisfaction))
746  return true;
747 
748  if (!Satisfaction.IsSatisfied) {
749  SmallString<128> TemplateArgString;
750  TemplateArgString = " ";
751  TemplateArgString += getTemplateArgumentBindingsText(
752  TD->getTemplateParameters(), TemplateArgsLists.getInnermost().data(),
753  TemplateArgsLists.getInnermost().size());
754 
755  Diag(TemplateIDRange.getBegin(),
756  diag::err_template_arg_list_constraints_not_satisfied)
757  << (int)getTemplateNameKindForDiagnostics(TemplateName(TD)) << TD
758  << TemplateArgString << TemplateIDRange;
759  DiagnoseUnsatisfiedConstraint(Satisfaction);
760  return true;
761  }
762  return false;
763 }
764 
766  SourceLocation PointOfInstantiation, FunctionDecl *Decl,
767  ArrayRef<TemplateArgument> TemplateArgs,
768  ConstraintSatisfaction &Satisfaction) {
769  // In most cases we're not going to have constraints, so check for that first.
770  FunctionTemplateDecl *Template = Decl->getPrimaryTemplate();
771  // Note - code synthesis context for the constraints check is created
772  // inside CheckConstraintsSatisfaction.
773  SmallVector<const Expr *, 3> TemplateAC;
774  Template->getAssociatedConstraints(TemplateAC);
775  if (TemplateAC.empty()) {
776  Satisfaction.IsSatisfied = true;
777  return false;
778  }
779 
780  // Enter the scope of this instantiation. We don't use
781  // PushDeclContext because we don't have a scope.
782  Sema::ContextRAII savedContext(*this, Decl);
784 
786  SetupConstraintCheckingTemplateArgumentsAndScope(Decl, TemplateArgs,
787  Scope);
788 
789  if (!MLTAL)
790  return true;
791 
792  Qualifiers ThisQuals;
793  CXXRecordDecl *Record = nullptr;
794  if (auto *Method = dyn_cast<CXXMethodDecl>(Decl)) {
795  ThisQuals = Method->getMethodQualifiers();
796  Record = Method->getParent();
797  }
798  CXXThisScopeRAII ThisScope(*this, Record, ThisQuals, Record != nullptr);
799  FunctionScopeRAII FuncScope(*this);
801  PushLambdaScope();
802  else
803  FuncScope.disable();
804 
806  return CheckConstraintSatisfaction(Template, TemplateAC, Converted, *MLTAL,
807  PointOfInstantiation, Satisfaction);
808 }
809 
812  bool First) {
813  assert(!Req->isSatisfied()
814  && "Diagnose() can only be used on an unsatisfied requirement");
815  switch (Req->getSatisfactionStatus()) {
817  llvm_unreachable("Diagnosing a dependent requirement");
818  break;
820  auto *SubstDiag = Req->getExprSubstitutionDiagnostic();
821  if (!SubstDiag->DiagMessage.empty())
822  S.Diag(SubstDiag->DiagLoc,
823  diag::note_expr_requirement_expr_substitution_error)
824  << (int)First << SubstDiag->SubstitutedEntity
825  << SubstDiag->DiagMessage;
826  else
827  S.Diag(SubstDiag->DiagLoc,
828  diag::note_expr_requirement_expr_unknown_substitution_error)
829  << (int)First << SubstDiag->SubstitutedEntity;
830  break;
831  }
833  S.Diag(Req->getNoexceptLoc(),
834  diag::note_expr_requirement_noexcept_not_met)
835  << (int)First << Req->getExpr();
836  break;
838  auto *SubstDiag =
840  if (!SubstDiag->DiagMessage.empty())
841  S.Diag(SubstDiag->DiagLoc,
842  diag::note_expr_requirement_type_requirement_substitution_error)
843  << (int)First << SubstDiag->SubstitutedEntity
844  << SubstDiag->DiagMessage;
845  else
846  S.Diag(SubstDiag->DiagLoc,
847  diag::note_expr_requirement_type_requirement_unknown_substitution_error)
848  << (int)First << SubstDiag->SubstitutedEntity;
849  break;
850  }
852  ConceptSpecializationExpr *ConstraintExpr =
854  if (ConstraintExpr->getTemplateArgsAsWritten()->NumTemplateArgs == 1) {
855  // A simple case - expr type is the type being constrained and the concept
856  // was not provided arguments.
857  Expr *e = Req->getExpr();
858  S.Diag(e->getBeginLoc(),
859  diag::note_expr_requirement_constraints_not_satisfied_simple)
860  << (int)First << S.Context.getReferenceQualifiedType(e)
861  << ConstraintExpr->getNamedConcept();
862  } else {
863  S.Diag(ConstraintExpr->getBeginLoc(),
864  diag::note_expr_requirement_constraints_not_satisfied)
865  << (int)First << ConstraintExpr;
866  }
867  S.DiagnoseUnsatisfiedConstraint(ConstraintExpr->getSatisfaction());
868  break;
869  }
871  llvm_unreachable("We checked this above");
872  }
873 }
874 
877  bool First) {
878  assert(!Req->isSatisfied()
879  && "Diagnose() can only be used on an unsatisfied requirement");
880  switch (Req->getSatisfactionStatus()) {
882  llvm_unreachable("Diagnosing a dependent requirement");
883  return;
885  auto *SubstDiag = Req->getSubstitutionDiagnostic();
886  if (!SubstDiag->DiagMessage.empty())
887  S.Diag(SubstDiag->DiagLoc,
888  diag::note_type_requirement_substitution_error) << (int)First
889  << SubstDiag->SubstitutedEntity << SubstDiag->DiagMessage;
890  else
891  S.Diag(SubstDiag->DiagLoc,
892  diag::note_type_requirement_unknown_substitution_error)
893  << (int)First << SubstDiag->SubstitutedEntity;
894  return;
895  }
896  default:
897  llvm_unreachable("Unknown satisfaction status");
898  return;
899  }
900 }
901 
904  bool First) {
905  if (Req->isSubstitutionFailure()) {
908  if (!SubstDiag->DiagMessage.empty())
909  S.Diag(SubstDiag->DiagLoc,
910  diag::note_nested_requirement_substitution_error)
911  << (int)First << SubstDiag->SubstitutedEntity
912  << SubstDiag->DiagMessage;
913  else
914  S.Diag(SubstDiag->DiagLoc,
915  diag::note_nested_requirement_unknown_substitution_error)
916  << (int)First << SubstDiag->SubstitutedEntity;
917  return;
918  }
920 }
921 
922 
924  Expr *SubstExpr,
925  bool First = true) {
926  SubstExpr = SubstExpr->IgnoreParenImpCasts();
927  if (BinaryOperator *BO = dyn_cast<BinaryOperator>(SubstExpr)) {
928  switch (BO->getOpcode()) {
929  // These two cases will in practice only be reached when using fold
930  // expressions with || and &&, since otherwise the || and && will have been
931  // broken down into atomic constraints during satisfaction checking.
932  case BO_LOr:
933  // Or evaluated to false - meaning both RHS and LHS evaluated to false.
936  /*First=*/false);
937  return;
938  case BO_LAnd: {
939  bool LHSSatisfied =
940  BO->getLHS()->EvaluateKnownConstInt(S.Context).getBoolValue();
941  if (LHSSatisfied) {
942  // LHS is true, so RHS must be false.
944  return;
945  }
946  // LHS is false
948 
949  // RHS might also be false
950  bool RHSSatisfied =
951  BO->getRHS()->EvaluateKnownConstInt(S.Context).getBoolValue();
952  if (!RHSSatisfied)
954  /*First=*/false);
955  return;
956  }
957  case BO_GE:
958  case BO_LE:
959  case BO_GT:
960  case BO_LT:
961  case BO_EQ:
962  case BO_NE:
963  if (BO->getLHS()->getType()->isIntegerType() &&
964  BO->getRHS()->getType()->isIntegerType()) {
965  Expr::EvalResult SimplifiedLHS;
966  Expr::EvalResult SimplifiedRHS;
967  BO->getLHS()->EvaluateAsInt(SimplifiedLHS, S.Context,
969  /*InConstantContext=*/true);
970  BO->getRHS()->EvaluateAsInt(SimplifiedRHS, S.Context,
972  /*InConstantContext=*/true);
973  if (!SimplifiedLHS.Diag && ! SimplifiedRHS.Diag) {
974  S.Diag(SubstExpr->getBeginLoc(),
975  diag::note_atomic_constraint_evaluated_to_false_elaborated)
976  << (int)First << SubstExpr
977  << toString(SimplifiedLHS.Val.getInt(), 10)
978  << BinaryOperator::getOpcodeStr(BO->getOpcode())
979  << toString(SimplifiedRHS.Val.getInt(), 10);
980  return;
981  }
982  }
983  break;
984 
985  default:
986  break;
987  }
988  } else if (auto *CSE = dyn_cast<ConceptSpecializationExpr>(SubstExpr)) {
989  if (CSE->getTemplateArgsAsWritten()->NumTemplateArgs == 1) {
990  S.Diag(
991  CSE->getSourceRange().getBegin(),
992  diag::
993  note_single_arg_concept_specialization_constraint_evaluated_to_false)
994  << (int)First
995  << CSE->getTemplateArgsAsWritten()->arguments()[0].getArgument()
996  << CSE->getNamedConcept();
997  } else {
998  S.Diag(SubstExpr->getSourceRange().getBegin(),
999  diag::note_concept_specialization_constraint_evaluated_to_false)
1000  << (int)First << CSE;
1001  }
1002  S.DiagnoseUnsatisfiedConstraint(CSE->getSatisfaction());
1003  return;
1004  } else if (auto *RE = dyn_cast<RequiresExpr>(SubstExpr)) {
1005  for (concepts::Requirement *Req : RE->getRequirements())
1006  if (!Req->isDependent() && !Req->isSatisfied()) {
1007  if (auto *E = dyn_cast<concepts::ExprRequirement>(Req))
1009  else if (auto *T = dyn_cast<concepts::TypeRequirement>(Req))
1011  else
1013  S, cast<concepts::NestedRequirement>(Req), First);
1014  break;
1015  }
1016  return;
1017  }
1018 
1019  S.Diag(SubstExpr->getSourceRange().getBegin(),
1020  diag::note_atomic_constraint_evaluated_to_false)
1021  << (int)First << SubstExpr;
1022 }
1023 
1024 template<typename SubstitutionDiagnostic>
1026  Sema &S, const Expr *E,
1027  const llvm::PointerUnion<Expr *, SubstitutionDiagnostic *> &Record,
1028  bool First = true) {
1029  if (auto *Diag = Record.template dyn_cast<SubstitutionDiagnostic *>()){
1030  S.Diag(Diag->first, diag::note_substituted_constraint_expr_is_ill_formed)
1031  << Diag->second;
1032  return;
1033  }
1034 
1036  Record.template get<Expr *>(), First);
1037 }
1038 
1039 void
1041  bool First) {
1042  assert(!Satisfaction.IsSatisfied &&
1043  "Attempted to diagnose a satisfied constraint");
1044  for (auto &Pair : Satisfaction.Details) {
1045  diagnoseUnsatisfiedConstraintExpr(*this, Pair.first, Pair.second, First);
1046  First = false;
1047  }
1048 }
1049 
1051  const ASTConstraintSatisfaction &Satisfaction,
1052  bool First) {
1053  assert(!Satisfaction.IsSatisfied &&
1054  "Attempted to diagnose a satisfied constraint");
1055  for (auto &Pair : Satisfaction) {
1056  diagnoseUnsatisfiedConstraintExpr(*this, Pair.first, Pair.second, First);
1057  First = false;
1058  }
1059 }
1060 
1061 const NormalizedConstraint *
1063  NamedDecl *ConstrainedDecl, ArrayRef<const Expr *> AssociatedConstraints) {
1064  auto CacheEntry = NormalizationCache.find(ConstrainedDecl);
1065  if (CacheEntry == NormalizationCache.end()) {
1066  auto Normalized =
1067  NormalizedConstraint::fromConstraintExprs(*this, ConstrainedDecl,
1068  AssociatedConstraints);
1069  CacheEntry =
1070  NormalizationCache
1071  .try_emplace(ConstrainedDecl,
1072  Normalized
1073  ? new (Context) NormalizedConstraint(
1074  std::move(*Normalized))
1075  : nullptr)
1076  .first;
1077  }
1078  return CacheEntry->second;
1079 }
1080 
1081 static bool
1083  ConceptDecl *Concept,
1084  const MultiLevelTemplateArgumentList &MLTAL,
1085  const ASTTemplateArgumentListInfo *ArgsAsWritten) {
1086  if (!N.isAtomic()) {
1087  if (substituteParameterMappings(S, N.getLHS(), Concept, MLTAL,
1088  ArgsAsWritten))
1089  return true;
1090  return substituteParameterMappings(S, N.getRHS(), Concept, MLTAL,
1091  ArgsAsWritten);
1092  }
1093  TemplateParameterList *TemplateParams = Concept->getTemplateParameters();
1094 
1095  AtomicConstraint &Atomic = *N.getAtomicConstraint();
1096  TemplateArgumentListInfo SubstArgs;
1097  if (!Atomic.ParameterMapping) {
1098  llvm::SmallBitVector OccurringIndices(TemplateParams->size());
1099  S.MarkUsedTemplateParameters(Atomic.ConstraintExpr, /*OnlyDeduced=*/false,
1100  /*Depth=*/0, OccurringIndices);
1101  TemplateArgumentLoc *TempArgs =
1102  new (S.Context) TemplateArgumentLoc[OccurringIndices.count()];
1103  for (unsigned I = 0, J = 0, C = TemplateParams->size(); I != C; ++I)
1104  if (OccurringIndices[I])
1105  new (&(TempArgs)[J++])
1107  TemplateParams->begin()[I],
1108  // Here we assume we do not support things like
1109  // template<typename A, typename B>
1110  // concept C = ...;
1111  //
1112  // template<typename... Ts> requires C<Ts...>
1113  // struct S { };
1114  // The above currently yields a diagnostic.
1115  // We still might have default arguments for concept parameters.
1116  ArgsAsWritten->NumTemplateArgs > I
1117  ? ArgsAsWritten->arguments()[I].getLocation()
1118  : SourceLocation()));
1119  Atomic.ParameterMapping.emplace(TempArgs, OccurringIndices.count());
1120  }
1122  S, ArgsAsWritten->arguments().front().getSourceRange().getBegin(),
1124  SourceRange(ArgsAsWritten->arguments()[0].getSourceRange().getBegin(),
1125  ArgsAsWritten->arguments().back().getSourceRange().getEnd()));
1126  if (S.SubstTemplateArguments(*Atomic.ParameterMapping, MLTAL, SubstArgs))
1127  return true;
1128 
1129  TemplateArgumentLoc *TempArgs =
1130  new (S.Context) TemplateArgumentLoc[SubstArgs.size()];
1131  std::copy(SubstArgs.arguments().begin(), SubstArgs.arguments().end(),
1132  TempArgs);
1133  Atomic.ParameterMapping.emplace(TempArgs, SubstArgs.size());
1134  return false;
1135 }
1136 
1138  const ConceptSpecializationExpr *CSE) {
1140  CSE->getTemplateArguments()};
1142  CSE->getNamedConcept(), /*Final=*/true, &TAL,
1143  /*RelativeToPrimary=*/true,
1144  /*Pattern=*/nullptr,
1145  /*ForConstraintInstantiation=*/true);
1146 
1147  return substituteParameterMappings(S, N, CSE->getNamedConcept(), MLTAL,
1148  CSE->getTemplateArgsAsWritten());
1149 }
1150 
1152 NormalizedConstraint::fromConstraintExprs(Sema &S, NamedDecl *D,
1154  assert(E.size() != 0);
1155  auto Conjunction = fromConstraintExpr(S, D, E[0]);
1156  if (!Conjunction)
1157  return std::nullopt;
1158  for (unsigned I = 1; I < E.size(); ++I) {
1159  auto Next = fromConstraintExpr(S, D, E[I]);
1160  if (!Next)
1161  return std::nullopt;
1162  *Conjunction = NormalizedConstraint(S.Context, std::move(*Conjunction),
1163  std::move(*Next), CCK_Conjunction);
1164  }
1165  return Conjunction;
1166 }
1167 
1169 NormalizedConstraint::fromConstraintExpr(Sema &S, NamedDecl *D, const Expr *E) {
1170  assert(E != nullptr);
1171 
1172  // C++ [temp.constr.normal]p1.1
1173  // [...]
1174  // - The normal form of an expression (E) is the normal form of E.
1175  // [...]
1176  E = E->IgnoreParenImpCasts();
1177 
1178  // C++2a [temp.param]p4:
1179  // [...] If T is not a pack, then E is E', otherwise E is (E' && ...).
1180  // Fold expression is considered atomic constraints per current wording.
1181  // See http://cplusplus.github.io/concepts-ts/ts-active.html#28
1182 
1183  if (LogicalBinOp BO = E) {
1184  auto LHS = fromConstraintExpr(S, D, BO.getLHS());
1185  if (!LHS)
1186  return std::nullopt;
1187  auto RHS = fromConstraintExpr(S, D, BO.getRHS());
1188  if (!RHS)
1189  return std::nullopt;
1190 
1191  return NormalizedConstraint(S.Context, std::move(*LHS), std::move(*RHS),
1192  BO.isAnd() ? CCK_Conjunction : CCK_Disjunction);
1193  } else if (auto *CSE = dyn_cast<const ConceptSpecializationExpr>(E)) {
1194  const NormalizedConstraint *SubNF;
1195  {
1197  S, CSE->getExprLoc(),
1199  CSE->getSourceRange());
1200  // C++ [temp.constr.normal]p1.1
1201  // [...]
1202  // The normal form of an id-expression of the form C<A1, A2, ..., AN>,
1203  // where C names a concept, is the normal form of the
1204  // constraint-expression of C, after substituting A1, A2, ..., AN for C’s
1205  // respective template parameters in the parameter mappings in each atomic
1206  // constraint. If any such substitution results in an invalid type or
1207  // expression, the program is ill-formed; no diagnostic is required.
1208  // [...]
1209  ConceptDecl *CD = CSE->getNamedConcept();
1211  {CD->getConstraintExpr()});
1212  if (!SubNF)
1213  return std::nullopt;
1214  }
1215 
1217  New.emplace(S.Context, *SubNF);
1218 
1219  if (substituteParameterMappings(S, *New, CSE))
1220  return std::nullopt;
1221 
1222  return New;
1223  }
1224  return NormalizedConstraint{new (S.Context) AtomicConstraint(S, E)};
1225 }
1226 
1227 using NormalForm =
1229 
1230 static NormalForm makeCNF(const NormalizedConstraint &Normalized) {
1231  if (Normalized.isAtomic())
1232  return {{Normalized.getAtomicConstraint()}};
1233 
1234  NormalForm LCNF = makeCNF(Normalized.getLHS());
1235  NormalForm RCNF = makeCNF(Normalized.getRHS());
1237  LCNF.reserve(LCNF.size() + RCNF.size());
1238  while (!RCNF.empty())
1239  LCNF.push_back(RCNF.pop_back_val());
1240  return LCNF;
1241  }
1242 
1243  // Disjunction
1244  NormalForm Res;
1245  Res.reserve(LCNF.size() * RCNF.size());
1246  for (auto &LDisjunction : LCNF)
1247  for (auto &RDisjunction : RCNF) {
1248  NormalForm::value_type Combined;
1249  Combined.reserve(LDisjunction.size() + RDisjunction.size());
1250  std::copy(LDisjunction.begin(), LDisjunction.end(),
1251  std::back_inserter(Combined));
1252  std::copy(RDisjunction.begin(), RDisjunction.end(),
1253  std::back_inserter(Combined));
1254  Res.emplace_back(Combined);
1255  }
1256  return Res;
1257 }
1258 
1259 static NormalForm makeDNF(const NormalizedConstraint &Normalized) {
1260  if (Normalized.isAtomic())
1261  return {{Normalized.getAtomicConstraint()}};
1262 
1263  NormalForm LDNF = makeDNF(Normalized.getLHS());
1264  NormalForm RDNF = makeDNF(Normalized.getRHS());
1266  LDNF.reserve(LDNF.size() + RDNF.size());
1267  while (!RDNF.empty())
1268  LDNF.push_back(RDNF.pop_back_val());
1269  return LDNF;
1270  }
1271 
1272  // Conjunction
1273  NormalForm Res;
1274  Res.reserve(LDNF.size() * RDNF.size());
1275  for (auto &LConjunction : LDNF) {
1276  for (auto &RConjunction : RDNF) {
1277  NormalForm::value_type Combined;
1278  Combined.reserve(LConjunction.size() + RConjunction.size());
1279  std::copy(LConjunction.begin(), LConjunction.end(),
1280  std::back_inserter(Combined));
1281  std::copy(RConjunction.begin(), RConjunction.end(),
1282  std::back_inserter(Combined));
1283  Res.emplace_back(Combined);
1284  }
1285  }
1286  return Res;
1287 }
1288 
1289 template<typename AtomicSubsumptionEvaluator>
1290 static bool subsumes(NormalForm PDNF, NormalForm QCNF,
1291  AtomicSubsumptionEvaluator E) {
1292  // C++ [temp.constr.order] p2
1293  // Then, P subsumes Q if and only if, for every disjunctive clause Pi in the
1294  // disjunctive normal form of P, Pi subsumes every conjunctive clause Qj in
1295  // the conjuctive normal form of Q, where [...]
1296  for (const auto &Pi : PDNF) {
1297  for (const auto &Qj : QCNF) {
1298  // C++ [temp.constr.order] p2
1299  // - [...] a disjunctive clause Pi subsumes a conjunctive clause Qj if
1300  // and only if there exists an atomic constraint Pia in Pi for which
1301  // there exists an atomic constraint, Qjb, in Qj such that Pia
1302  // subsumes Qjb.
1303  bool Found = false;
1304  for (const AtomicConstraint *Pia : Pi) {
1305  for (const AtomicConstraint *Qjb : Qj) {
1306  if (E(*Pia, *Qjb)) {
1307  Found = true;
1308  break;
1309  }
1310  }
1311  if (Found)
1312  break;
1313  }
1314  if (!Found)
1315  return false;
1316  }
1317  }
1318  return true;
1319 }
1320 
1321 template<typename AtomicSubsumptionEvaluator>
1323  NamedDecl *DQ, ArrayRef<const Expr *> Q, bool &Subsumes,
1324  AtomicSubsumptionEvaluator E) {
1325  // C++ [temp.constr.order] p2
1326  // In order to determine if a constraint P subsumes a constraint Q, P is
1327  // transformed into disjunctive normal form, and Q is transformed into
1328  // conjunctive normal form. [...]
1329  auto *PNormalized = S.getNormalizedAssociatedConstraints(DP, P);
1330  if (!PNormalized)
1331  return true;
1332  const NormalForm PDNF = makeDNF(*PNormalized);
1333 
1334  auto *QNormalized = S.getNormalizedAssociatedConstraints(DQ, Q);
1335  if (!QNormalized)
1336  return true;
1337  const NormalForm QCNF = makeCNF(*QNormalized);
1338 
1339  Subsumes = subsumes(PDNF, QCNF, E);
1340  return false;
1341 }
1342 
1345  NamedDecl *D2,
1347  bool &Result) {
1348  if (const auto *FD1 = dyn_cast<FunctionDecl>(D1)) {
1349  auto IsExpectedEntity = [](const FunctionDecl *FD) {
1351  return Kind == FunctionDecl::TK_NonTemplate ||
1353  };
1354  const auto *FD2 = dyn_cast<FunctionDecl>(D2);
1355  (void)IsExpectedEntity;
1356  (void)FD2;
1357  assert(IsExpectedEntity(FD1) && FD2 && IsExpectedEntity(FD2) &&
1358  "use non-instantiated function declaration for constraints partial "
1359  "ordering");
1360  }
1361 
1362  if (AC1.empty()) {
1363  Result = AC2.empty();
1364  return false;
1365  }
1366  if (AC2.empty()) {
1367  // TD1 has associated constraints and TD2 does not.
1368  Result = true;
1369  return false;
1370  }
1371 
1372  std::pair<NamedDecl *, NamedDecl *> Key{D1, D2};
1373  auto CacheEntry = SubsumptionCache.find(Key);
1374  if (CacheEntry != SubsumptionCache.end()) {
1375  Result = CacheEntry->second;
1376  return false;
1377  }
1378 
1379  unsigned Depth1 = CalculateTemplateDepthForConstraints(*this, D1, true);
1380  unsigned Depth2 = CalculateTemplateDepthForConstraints(*this, D2, true);
1381 
1382  for (size_t I = 0; I != AC1.size() && I != AC2.size(); ++I) {
1383  if (Depth2 > Depth1) {
1384  AC1[I] = AdjustConstraintDepth(*this, Depth2 - Depth1)
1385  .TransformExpr(const_cast<Expr *>(AC1[I]))
1386  .get();
1387  } else if (Depth1 > Depth2) {
1388  AC2[I] = AdjustConstraintDepth(*this, Depth1 - Depth2)
1389  .TransformExpr(const_cast<Expr *>(AC2[I]))
1390  .get();
1391  }
1392  }
1393 
1394  if (subsumes(*this, D1, AC1, D2, AC2, Result,
1395  [this] (const AtomicConstraint &A, const AtomicConstraint &B) {
1396  return A.subsumes(Context, B);
1397  }))
1398  return true;
1399  SubsumptionCache.try_emplace(Key, Result);
1400  return false;
1401 }
1402 
1405  if (isSFINAEContext())
1406  // No need to work here because our notes would be discarded.
1407  return false;
1408 
1409  if (AC1.empty() || AC2.empty())
1410  return false;
1411 
1412  auto NormalExprEvaluator =
1413  [this] (const AtomicConstraint &A, const AtomicConstraint &B) {
1414  return A.subsumes(Context, B);
1415  };
1416 
1417  const Expr *AmbiguousAtomic1 = nullptr, *AmbiguousAtomic2 = nullptr;
1418  auto IdenticalExprEvaluator =
1419  [&] (const AtomicConstraint &A, const AtomicConstraint &B) {
1420  if (!A.hasMatchingParameterMapping(Context, B))
1421  return false;
1422  const Expr *EA = A.ConstraintExpr, *EB = B.ConstraintExpr;
1423  if (EA == EB)
1424  return true;
1425 
1426  // Not the same source level expression - are the expressions
1427  // identical?
1428  llvm::FoldingSetNodeID IDA, IDB;
1429  EA->Profile(IDA, Context, /*Canonical=*/true);
1430  EB->Profile(IDB, Context, /*Canonical=*/true);
1431  if (IDA != IDB)
1432  return false;
1433 
1434  AmbiguousAtomic1 = EA;
1435  AmbiguousAtomic2 = EB;
1436  return true;
1437  };
1438 
1439  {
1440  // The subsumption checks might cause diagnostics
1441  SFINAETrap Trap(*this);
1442  auto *Normalized1 = getNormalizedAssociatedConstraints(D1, AC1);
1443  if (!Normalized1)
1444  return false;
1445  const NormalForm DNF1 = makeDNF(*Normalized1);
1446  const NormalForm CNF1 = makeCNF(*Normalized1);
1447 
1448  auto *Normalized2 = getNormalizedAssociatedConstraints(D2, AC2);
1449  if (!Normalized2)
1450  return false;
1451  const NormalForm DNF2 = makeDNF(*Normalized2);
1452  const NormalForm CNF2 = makeCNF(*Normalized2);
1453 
1454  bool Is1AtLeastAs2Normally = subsumes(DNF1, CNF2, NormalExprEvaluator);
1455  bool Is2AtLeastAs1Normally = subsumes(DNF2, CNF1, NormalExprEvaluator);
1456  bool Is1AtLeastAs2 = subsumes(DNF1, CNF2, IdenticalExprEvaluator);
1457  bool Is2AtLeastAs1 = subsumes(DNF2, CNF1, IdenticalExprEvaluator);
1458  if (Is1AtLeastAs2 == Is1AtLeastAs2Normally &&
1459  Is2AtLeastAs1 == Is2AtLeastAs1Normally)
1460  // Same result - no ambiguity was caused by identical atomic expressions.
1461  return false;
1462  }
1463 
1464  // A different result! Some ambiguous atomic constraint(s) caused a difference
1465  assert(AmbiguousAtomic1 && AmbiguousAtomic2);
1466 
1467  Diag(AmbiguousAtomic1->getBeginLoc(), diag::note_ambiguous_atomic_constraints)
1468  << AmbiguousAtomic1->getSourceRange();
1469  Diag(AmbiguousAtomic2->getBeginLoc(),
1470  diag::note_ambiguous_atomic_constraints_similar_expression)
1471  << AmbiguousAtomic2->getSourceRange();
1472  return true;
1473 }
1474 
1476  Expr *E, bool IsSimple, SourceLocation NoexceptLoc,
1478  ConceptSpecializationExpr *SubstitutedConstraintExpr) :
1479  Requirement(IsSimple ? RK_Simple : RK_Compound, Status == SS_Dependent,
1480  Status == SS_Dependent &&
1481  (E->containsUnexpandedParameterPack() ||
1482  Req.containsUnexpandedParameterPack()),
1483  Status == SS_Satisfied), Value(E), NoexceptLoc(NoexceptLoc),
1484  TypeReq(Req), SubstitutedConstraintExpr(SubstitutedConstraintExpr),
1485  Status(Status) {
1486  assert((!IsSimple || (Req.isEmpty() && NoexceptLoc.isInvalid())) &&
1487  "Simple requirement must not have a return type requirement or a "
1488  "noexcept specification");
1489  assert((Status > SS_TypeRequirementSubstitutionFailure && Req.isTypeConstraint()) ==
1490  (SubstitutedConstraintExpr != nullptr));
1491 }
1492 
1494  SubstitutionDiagnostic *ExprSubstDiag, bool IsSimple,
1495  SourceLocation NoexceptLoc, ReturnTypeRequirement Req) :
1496  Requirement(IsSimple ? RK_Simple : RK_Compound, Req.isDependent(),
1497  Req.containsUnexpandedParameterPack(), /*IsSatisfied=*/false),
1498  Value(ExprSubstDiag), NoexceptLoc(NoexceptLoc), TypeReq(Req),
1499  Status(SS_ExprSubstitutionFailure) {
1500  assert((!IsSimple || (Req.isEmpty() && NoexceptLoc.isInvalid())) &&
1501  "Simple requirement must not have a return type requirement or a "
1502  "noexcept specification");
1503 }
1504 
1507  TypeConstraintInfo(TPL, false) {
1508  assert(TPL->size() == 1);
1509  const TypeConstraint *TC =
1510  cast<TemplateTypeParmDecl>(TPL->getParam(0))->getTypeConstraint();
1511  assert(TC &&
1512  "TPL must have a template type parameter with a type constraint");
1513  auto *Constraint =
1514  cast<ConceptSpecializationExpr>(TC->getImmediatelyDeclaredConstraint());
1515  bool Dependent =
1516  Constraint->getTemplateArgsAsWritten() &&
1518  Constraint->getTemplateArgsAsWritten()->arguments().drop_front(1));
1519  TypeConstraintInfo.setInt(Dependent ? true : false);
1520 }
1521 
1523  Requirement(RK_Type, T->getType()->isInstantiationDependentType(),
1524  T->getType()->containsUnexpandedParameterPack(),
1525  // We reach this ctor with either dependent types (in which
1526  // IsSatisfied doesn't matter) or with non-dependent type in
1527  // which the existence of the type indicates satisfaction.
1528  /*IsSatisfied=*/true),
1529  Value(T),
1530  Status(T->getType()->isInstantiationDependentType() ? SS_Dependent
1531  : SS_Satisfied) {}
clang::concepts::TypeRequirement::TypeRequirement
TypeRequirement(TypeSourceInfo *T)
Construct a type requirement from a type.
Definition: SemaConcept.cpp:1522
clang::NormalizedConstraint
A normalized constraint, as defined in C++ [temp.constr.normal], is either an atomic constraint,...
Definition: SemaConcept.h:81
clang::AtomicExpr
AtomicExpr - Variadic atomic builtins: __atomic_exchange, __atomic_fetch_*, __atomic_load,...
Definition: Expr.h:6240
clang::ConceptDecl::getConstraintExpr
Expr * getConstraintExpr() const
Definition: DeclTemplate.h:3274
clang::concepts::ExprRequirement::getExprSubstitutionDiagnostic
SubstitutionDiagnostic * getExprSubstitutionDiagnostic() const
Definition: ExprConcepts.h:382
diagnoseWellFormedUnsatisfiedConstraintExpr
static void diagnoseWellFormedUnsatisfiedConstraintExpr(Sema &S, Expr *SubstExpr, bool First=true)
Definition: SemaConcept.cpp:923
clang::isLambdaCallOperator
bool isLambdaCallOperator(const CXXMethodDecl *MD)
Definition: ASTLambda.h:27
clang::ASTConstraintSatisfaction
The result of a constraint satisfaction check, containing the necessary information to diagnose an un...
Definition: ASTConcept.h:77
DiagRecursiveConstraintEval
static bool DiagRecursiveConstraintEval(Sema &S, llvm::FoldingSetNodeID &ID, const Expr *E, const MultiLevelTemplateArgumentList &MLTAL)
Definition: SemaConcept.cpp:273
clang::Sema::InstantiatingTemplate::ParameterMappingSubstitution
Definition: Sema.h:9526
clang::concepts::Requirement::SubstitutionDiagnostic::DiagLoc
SourceLocation DiagLoc
Definition: ExprConcepts.h:162
clang::prec::LogicalAnd
@ LogicalAnd
Definition: OperatorPrecedence.h:32
clang::Sema::SubstConstraintExpr
ExprResult SubstConstraintExpr(Expr *E, const MultiLevelTemplateArgumentList &TemplateArgs)
Definition: SemaTemplateInstantiate.cpp:3916
TreeTransform.h
clang::OK_Ordinary
@ OK_Ordinary
An ordinary object is located at an address in memory.
Definition: Specifiers.h:139
calculateConstraintSatisfaction
static ExprResult calculateConstraintSatisfaction(Sema &S, const Expr *ConstraintExpr, ConstraintSatisfaction &Satisfaction, AtomicEvaluator &&Evaluator)
Definition: SemaConcept.cpp:162
clang::concepts::TypeRequirement::getSubstitutionDiagnostic
SubstitutionDiagnostic * getSubstitutionDiagnostic() const
Definition: ExprConcepts.h:234
clang::TemplateTypeParmType::getDecl
TemplateTypeParmDecl * getDecl() const
Definition: Type.h:5047
clang::Sema::CheckInstantiatedFunctionTemplateConstraints
bool CheckInstantiatedFunctionTemplateConstraints(SourceLocation PointOfInstantiation, FunctionDecl *Decl, ArrayRef< TemplateArgument > TemplateArgs, ConstraintSatisfaction &Satisfaction)
Definition: SemaConcept.cpp:765
clang::Sema::CXXThisScopeRAII
RAII object used to temporarily allow the C++ 'this' expression to be used, with the given qualifiers...
Definition: Sema.h:6594
clang::FunctionDecl::TK_MemberSpecialization
@ TK_MemberSpecialization
Definition: Decl.h:1918
clang::SourceRange
A trivial tuple used to represent a source range.
Definition: SourceLocation.h:210
clang::NormalizedConstraint::getCompoundKind
CompoundConstraintKind getCompoundKind() const
Definition: SemaConcept.h:123
clang::DeclContext
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition: DeclBase.h:1389
clang::FunctionDecl::TK_FunctionTemplate
@ TK_FunctionTemplate
Definition: Decl.h:1915
clang::PartialDiagnostic::NullDiagnostic
Definition: PartialDiagnostic.h:40
clang::Sema::getIdentityTemplateArgumentLoc
TemplateArgumentLoc getIdentityTemplateArgumentLoc(NamedDecl *Param, SourceLocation Location)
Get a template argument mapping the given template parameter to itself, e.g.
Definition: SemaTemplateDeduction.cpp:2606
clang::AtomicConstraint
Definition: SemaConcept.h:29
clang::Sema::AreConstraintExpressionsEqual
bool AreConstraintExpressionsEqual(const NamedDecl *Old, const Expr *OldConstr, const NamedDecl *New, const Expr *NewConstr)
Definition: SemaConcept.cpp:688
Diag
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
Definition: LiteralSupport.cpp:79
SemaInternal.h
clang::concepts::TypeRequirement::SS_SubstitutionFailure
@ SS_SubstitutionFailure
Definition: ExprConcepts.h:203
llvm::SmallVector
Definition: LLVM.h:38
clang::APValue::getInt
APSInt & getInt()
Definition: APValue.h:415
clang::SourceLocation
Encodes a location in the source.
Definition: SourceLocation.h:86
clang::NamedDecl
This represents a decl that may have a name.
Definition: Decl.h:247
clang::SourceRange::getBegin
SourceLocation getBegin() const
Definition: SourceLocation.h:219
clang::TreeTransform
A semantic tree transformation that allows one to transform one abstract syntax tree into another.
Definition: TreeTransform.h:101
clang::Stmt::getSourceRange
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
Definition: Stmt.cpp:324
clang::ConceptReference::getNamedConcept
ConceptDecl * getNamedConcept() const
Definition: ASTConcept.h:154
clang::QualType
A (possibly-)qualified type.
Definition: Type.h:737
clang::concepts::ExprRequirement::ReturnTypeRequirement::isEmpty
bool isEmpty() const
Definition: ExprConcepts.h:300
clang::TemplateDecl::getAssociatedConstraints
void getAssociatedConstraints(llvm::SmallVectorImpl< const Expr * > &AC) const
Get the total constraint-expression associated with this template, including constraint-expressions d...
Definition: DeclTemplate.cpp:238
clang::TypeConstraint::getImmediatelyDeclaredConstraint
Expr * getImmediatelyDeclaredConstraint() const
Get the immediately-declared constraint expression introduced by this type-constraint,...
Definition: ASTConcept.h:187
clang::Sema::getNormalizedAssociatedConstraints
const NormalizedConstraint * getNormalizedAssociatedConstraints(NamedDecl *ConstrainedDecl, ArrayRef< const Expr * > AssociatedConstraints)
Definition: SemaConcept.cpp:1062
clang::concepts::Requirement::SubstitutionDiagnostic
Definition: ExprConcepts.h:157
clang::Qualifiers
The collection of all-type qualifiers we support.
Definition: Type.h:147
clang::Sema::Diag
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID, bool DeferHint=false)
Emit a diagnostic.
Definition: Sema.cpp:1887
memcpy
__DEVICE__ void * memcpy(void *__a, const void *__b, size_t __c)
Definition: __clang_cuda_device_functions.h:1549
int
__device__ int
Definition: __clang_hip_libdevice_declares.h:63
clang::concepts::NestedRequirement::getSubstitutionDiagnostic
SubstitutionDiagnostic * getSubstitutionDiagnostic() const
Definition: ExprConcepts.h:437
clang::FunctionDecl::TK_FunctionTemplateSpecialization
@ TK_FunctionTemplateSpecialization
Definition: Decl.h:1922
subsumes
static bool subsumes(NormalForm PDNF, NormalForm QCNF, AtomicSubsumptionEvaluator E)
Definition: SemaConcept.cpp:1290
clang::BinaryOperator::getOpcodeStr
StringRef getOpcodeStr() const
Definition: Expr.h:3878
clang::Expr::EvalStatus::Diag
SmallVectorImpl< PartialDiagnosticAt > * Diag
Diag - If this is non-null, it will be filled in with a stack of notes indicating why evaluation fail...
Definition: Expr.h:609
diagnoseUnsatisfiedRequirement
static void diagnoseUnsatisfiedRequirement(Sema &S, concepts::ExprRequirement *Req, bool First)
Definition: SemaConcept.cpp:810
clang::FunctionDecl::TK_DependentNonTemplate
@ TK_DependentNonTemplate
Definition: Decl.h:1927
clang::FunctionDecl::getPrimaryTemplate
FunctionTemplateDecl * getPrimaryTemplate() const
Retrieve the primary template that this function template specialization either specializes or was in...
Definition: Decl.cpp:3916
clang::concepts::ExprRequirement::getExpr
Expr * getExpr() const
Definition: ExprConcepts.h:389
llvm::Optional
Definition: LLVM.h:40
clang::ComparisonCategoryType::First
@ First
clang::TypeSpecTypeLoc::getNameLoc
SourceLocation getNameLoc() const
Definition: TypeLoc.h:523
clang::FunctionDecl::getTemplateSpecializationArgs
const TemplateArgumentList * getTemplateSpecializationArgs() const
Retrieve the template arguments used to produce this function template specialization from the primar...
Definition: Decl.cpp:3932
clang::concepts::ExprRequirement::ReturnTypeRequirement::isTypeConstraint
bool isTypeConstraint() const
Definition: ExprConcepts.h:309
clang::MultiLevelTemplateArgumentList::getOutermost
const ArgList & getOutermost() const
Retrieve the outermost template argument list.
Definition: Template.h:254
clang::Sema::CheckFunctionConstraints
bool CheckFunctionConstraints(const FunctionDecl *FD, ConstraintSatisfaction &Satisfaction, SourceLocation UsageLoc=SourceLocation(), bool ForOverloadResolution=false)
Check whether the given function decl's trailing requires clause is satisfied, if any.
Definition: SemaConcept.cpp:583
ASTLambda.h
clang::concepts::Requirement::isSatisfied
bool isSatisfied() const
Definition: ExprConcepts.h:174
clang::ASTTemplateArgumentListInfo::NumTemplateArgs
unsigned NumTemplateArgs
The number of template arguments in TemplateArgs.
Definition: TemplateBase.h:634
clang::concepts::TypeRequirement::getSatisfactionStatus
SatisfactionStatus getSatisfactionStatus() const
Definition: ExprConcepts.h:225
clang::Token
Token - This structure provides full information about a lexed token.
Definition: Token.h:35
clang::concepts::ExprRequirement::getReturnTypeRequirementSubstitutedConstraintExpr
ConceptSpecializationExpr * getReturnTypeRequirementSubstitutedConstraintExpr() const
Definition: ExprConcepts.h:377
substituteParameterMappings
static bool substituteParameterMappings(Sema &S, NormalizedConstraint &N, ConceptDecl *Concept, const MultiLevelTemplateArgumentList &MLTAL, const ASTTemplateArgumentListInfo *ArgsAsWritten)
Definition: SemaConcept.cpp:1082
clang::Expr::EvalResult::Val
APValue Val
Val - This is the value the expression can be folded to.
Definition: Expr.h:624
clang::concepts::Requirement::containsUnexpandedParameterPack
bool containsUnexpandedParameterPack() const
Definition: ExprConcepts.h:192
clang::concepts::TypeRequirement::SS_Dependent
@ SS_Dependent
Definition: ExprConcepts.h:202
clang::AtomicExpr::getBeginLoc
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: Expr.h:6335
clang::ASTTemplateArgumentListInfo::arguments
llvm::ArrayRef< TemplateArgumentLoc > arguments() const
Definition: TemplateBase.h:645
clang::AtomicConstraint::ParameterMapping
Optional< ArrayRef< TemplateArgumentLoc > > ParameterMapping
Definition: SemaConcept.h:31
clang::DeclaratorContext::TemplateArg
@ TemplateArg
clang::Sema::Context
ASTContext & Context
Definition: Sema.h:409
clang::Type
The base class of the type hierarchy.
Definition: Type.h:1565
Overload.h
clang::DeclContext::getNonTransparentContext
DeclContext * getNonTransparentContext()
Definition: DeclBase.cpp:1255
clang::ExprError
ExprResult ExprError()
Definition: Ownership.h:278
clang::Expr::SE_NoSideEffects
@ SE_NoSideEffects
Strictly evaluate the expression.
Definition: Expr.h:648
clang::concepts::ExprRequirement::ReturnTypeRequirement::ReturnTypeRequirement
ReturnTypeRequirement()
No return type requirement was specified.
Definition: ExprConcepts.h:274
clang::Sema::SFINAETrap
RAII class used to determine whether SFINAE has trapped any errors that occur during template argumen...
Definition: Sema.h:9632
clang::ConstraintSatisfaction::Details
llvm::SmallVector< std::pair< const Expr *, Detail >, 4 > Details
Pairs of unsatisfied atomic constraint expressions along with the substituted constraint expr,...
Definition: ASTConcept.h:53
clang::Sema::InstantiatingTemplate::ConstraintsCheck
Definition: Sema.h:9502
clang::concepts::NestedRequirement::getConstraintSatisfaction
const ASTConstraintSatisfaction & getConstraintSatisfaction() const
Definition: ExprConcepts.h:451
clang::Sema::FunctionScopeRAII::disable
void disable()
Definition: Sema.h:5007
clang::concepts::Requirement::SubstitutionDiagnostic::SubstitutedEntity
StringRef SubstitutedEntity
Definition: ExprConcepts.h:158
ExprConcepts.h
clang::ExprEmpty
ExprResult ExprEmpty()
Definition: Ownership.h:289
clang::ASTContext::getReferenceQualifiedType
QualType getReferenceQualifiedType(const Expr *e) const
getReferenceQualifiedType - Given an expr, will return the type for that expression,...
Definition: ASTContext.cpp:5702
clang::FunctionTemplateDecl
Declaration of a template function.
Definition: DeclTemplate.h:1006
llvm::MutableArrayRef
Definition: LLVM.h:35
clang::TypeLocBuilder::push
TyLocType push(QualType T)
Pushes space for a new TypeLoc of the given type.
Definition: TypeLocBuilder.h:99
Template.h
clang::ConceptReference::getTemplateArgsAsWritten
const ASTTemplateArgumentListInfo * getTemplateArgsAsWritten() const
Definition: ASTConcept.h:158
makeCNF
static NormalForm makeCNF(const NormalizedConstraint &Normalized)
Definition: SemaConcept.cpp:1230
clang::Expr::isTypeDependent
bool isTypeDependent() const
Determines whether the type of this expression depends on.
Definition: Expr.h:185
clang::TemplateParameterList::getParam
NamedDecl * getParam(unsigned Idx)
Definition: DeclTemplate.h:139
clang::PartialDiagnosticAt
std::pair< SourceLocation, PartialDiagnostic > PartialDiagnosticAt
A partial diagnostic along with the source location where this diagnostic occurs.
Definition: PartialDiagnostic.h:205
clang::Sema::getDiagnostics
DiagnosticsEngine & getDiagnostics() const
Definition: Sema.h:1634
clang::TemplateArgumentListInfo
A convenient class for passing around template argument information.
Definition: TemplateBase.h:565
clang::NormalizedConstraint::getLHS
NormalizedConstraint & getLHS() const
Definition: SemaConcept.h:130
clang::BinaryOperator
A builtin binary operation expression such as "x + y" or "x <= y".
Definition: Expr.h:3813
clang::TemplateTypeParmType::getIndex
unsigned getIndex() const
Definition: Type.h:5044
clang::FunctionDecl::getTemplatedKind
TemplatedKind getTemplatedKind() const
What kind of templated function this is.
Definition: Decl.cpp:3753
clang::concepts::ExprRequirement::SS_TypeRequirementSubstitutionFailure
@ SS_TypeRequirementSubstitutionFailure
Definition: ExprConcepts.h:260
clang::ConceptDecl
Declaration of a C++20 concept.
Definition: DeclTemplate.h:3259
clang::Scope
Scope - A scope is a transient data structure that is used while parsing the program.
Definition: Scope.h:40
clang::threadSafety::sx::toString
std::string toString(const til::SExpr *E)
Definition: ThreadSafetyCommon.h:91
clang::TemplateSpecializationType::anyInstantiationDependentTemplateArguments
static bool anyInstantiationDependentTemplateArguments(ArrayRef< TemplateArgumentLoc > Args)
Definition: Type.cpp:3731
clang::ConceptSpecializationExpr
Represents the specialization of a concept - evaluates to a prvalue of type bool.
Definition: ExprConcepts.h:40
clang::FPOptionsOverride
Represents difference between two FPOptions values.
Definition: LangOptions.h:803
clang::Token::getKind
tok::TokenKind getKind() const
Definition: Token.h:93
clang::Sema::InstantiatingTemplate::ConstraintSubstitution
Definition: Sema.h:9511
diagnoseUnsatisfiedConstraintExpr
static void diagnoseUnsatisfiedConstraintExpr(Sema &S, const Expr *E, const llvm::PointerUnion< Expr *, SubstitutionDiagnostic * > &Record, bool First=true)
Definition: SemaConcept.cpp:1025
clang::concepts::NestedRequirement
A requires-expression requirement which is satisfied when a general constraint expression is satisfie...
Definition: ExprConcepts.h:403
clang::Sema::SFINAETrap::hasErrorOccurred
bool hasErrorOccurred() const
Determine whether any SFINAE errors have been trapped.
Definition: Sema.h:9663
clang::DeclContext::isTransparentContext
bool isTransparentContext() const
isTransparentContext - Determines whether this context is a "transparent" context,...
Definition: DeclBase.cpp:1208
clang::Sema::SubstTemplateArguments
bool SubstTemplateArguments(ArrayRef< TemplateArgumentLoc > Args, const MultiLevelTemplateArgumentList &TemplateArgs, TemplateArgumentListInfo &Outputs)
Definition: SemaTemplateInstantiate.cpp:3895
clang::concepts::Requirement
A static requirement that can be used in a requires-expression to check properties of types and expre...
Definition: ExprConcepts.h:145
clang::NormalizedConstraint::getAtomicConstraint
AtomicConstraint * getAtomicConstraint() const
Definition: SemaConcept.h:140
clang::MultiLevelTemplateArgumentList
Data structure that captures multiple levels of template argument lists for use in template instantia...
Definition: Template.h:75
clang::Sema::PerformContextuallyConvertToBool
ExprResult PerformContextuallyConvertToBool(Expr *From)
PerformContextuallyConvertToBool - Perform a contextual conversion of the expression From to bool (C+...
Definition: SemaOverload.cpp:5696
clang::Expr::containsErrors
bool containsErrors() const
Whether this expression contains subexpressions which had errors, e.g.
Definition: Expr.h:238
clang::Token::is
bool is(tok::TokenKind K) const
is/isNot - Predicates to check if this token is a specific kind, as in "if (Tok.is(tok::l_brace)) {....
Definition: Token.h:98
clang::Expr::EvaluateAsConstantExpr
bool EvaluateAsConstantExpr(EvalResult &Result, const ASTContext &Ctx, ConstantExprKind Kind=ConstantExprKind::Normal) const
Evaluate an expression that is required to be a constant expression.
Definition: ExprConstant.cpp:15242
clang::Sema::PDiag
PartialDiagnostic PDiag(unsigned DiagID=0)
Build a partial diagnostic.
Definition: SemaInternal.h:24
clang::Sema::InstantiatingTemplate::isInvalid
bool isInvalid() const
Determines whether we have exceeded the maximum recursive template instantiations.
Definition: Sema.h:9558
clang::Type::isFunctionType
bool isFunctionType() const
Definition: Type.h:6879
clang::TemplateArgumentLoc
Location wrapper for a TemplateArgument.
Definition: TemplateBase.h:459
clang::FunctionDecl::getPointOfInstantiation
SourceLocation getPointOfInstantiation() const
Retrieve the (first) point of instantiation of a function template specialization or a member of a cl...
Definition: Decl.cpp:4096
llvm::SmallString< 128 >
clang::Expr::EvalResult
EvalResult is a struct with detailed info about an evaluated expression.
Definition: Expr.h:622
bool
#define bool
Definition: stdbool.h:20
clang::concepts::ExprRequirement::SS_Dependent
@ SS_Dependent
Definition: ExprConcepts.h:257
clang::TemplateParameterList
Stores a list of template parameters for a TemplateDecl and its derived classes.
Definition: DeclTemplate.h:70
isInvalid
static bool isInvalid(LocType Loc, bool *Invalid)
Definition: SourceManager.cpp:1233
clang::Sema::MaybeEmitAmbiguousAtomicConstraintsDiagnostic
bool MaybeEmitAmbiguousAtomicConstraintsDiagnostic(NamedDecl *D1, ArrayRef< const Expr * > AC1, NamedDecl *D2, ArrayRef< const Expr * > AC2)
If D1 was not at least as constrained as D2, but would've been if a pair of atomic constraints involv...
Definition: SemaConcept.cpp:1403
clang::DeclaratorDecl::getTrailingRequiresClause
Expr * getTrailingRequiresClause()
Get the constraint-expression introduced by the trailing requires-clause in the function/member decla...
Definition: Decl.h:834
clang::Stmt::Profile
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, bool Canonical) const
Produce a unique representation of the given statement.
Definition: StmtProfile.cpp:2369
clang::Sema::InstantiatingTemplate::ConstraintNormalization
Definition: Sema.h:9520
clang::APValue::isInt
bool isInt() const
Definition: APValue.h:393
clang::TemplateTypeParmDecl
Declaration of a template type parameter.
Definition: DeclTemplate.h:1205
Sema.h
clang::TypeLocBuilder
Definition: TypeLocBuilder.h:22
clang::OverloadedOperatorKind
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
Definition: OperatorKinds.h:21
clang::ConstraintSatisfaction::IsSatisfied
bool IsSatisfied
Definition: ASTConcept.h:46
clang::TemplateDecl::getTemplateParameters
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
Definition: DeclTemplate.h:427
clang::TemplateTypeParmType
Definition: Type.h:5002
clang::Sema::EnsureTemplateArgumentListConstraints
bool EnsureTemplateArgumentListConstraints(TemplateDecl *Template, const MultiLevelTemplateArgumentList &TemplateArgs, SourceRange TemplateIDRange)
Ensure that the given template arguments satisfy the constraints associated with the given template,...
Definition: SemaConcept.cpp:738
clang::NormalizedConstraint::CCK_Disjunction
@ CCK_Disjunction
Definition: SemaConcept.h:84
clang::Sema::getTemplateInstantiationArgs
MultiLevelTemplateArgumentList getTemplateInstantiationArgs(const NamedDecl *D, bool Final=false, const TemplateArgumentList *Innermost=nullptr, bool RelativeToPrimary=false, const FunctionDecl *Pattern=nullptr, bool ForConstraintInstantiation=false, bool SkipForSpecialization=false)
Retrieve the template argument list(s) that should be used to instantiate the definition of the given...
Definition: SemaTemplateInstantiate.cpp:284
clang::MultiLevelTemplateArgumentList::isAnyArgInstantiationDependent
bool isAnyArgInstantiationDependent() const
Definition: Template.h:187
clang::FunctionDecl::getInstantiatedFromDecl
FunctionDecl * getInstantiatedFromDecl() const
Definition: Decl.cpp:3820
clang::concepts::ExprRequirement::getSatisfactionStatus
SatisfactionStatus getSatisfactionStatus() const
Definition: ExprConcepts.h:366
clang::concepts::ExprRequirement::ExprRequirement
ExprRequirement(Expr *E, bool IsSimple, SourceLocation NoexceptLoc, ReturnTypeRequirement Req, SatisfactionStatus Status, ConceptSpecializationExpr *SubstitutedConstraintExpr=nullptr)
Construct a compound requirement.
Definition: SemaConcept.cpp:1475
clang::TemplateArgumentListInfo::arguments
llvm::ArrayRef< TemplateArgumentLoc > arguments() const
Definition: TemplateBase.h:593
clang::concepts::ExprRequirement::ReturnTypeRequirement::getSubstitutionDiagnostic
SubstitutionDiagnostic * getSubstitutionDiagnostic() const
Definition: ExprConcepts.h:314
clang::CXXRecordDecl
Represents a C++ struct/union/class.
Definition: DeclCXX.h:254
clang::BinaryOperator::Create
static BinaryOperator * Create(const ASTContext &C, Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy, ExprValueKind VK, ExprObjectKind OK, SourceLocation opLoc, FPOptionsOverride FPFeatures)
Definition: Expr.cpp:4627
clang::OO_None
@ OO_None
Not an overloaded operator.
Definition: OperatorKinds.h:22
P
StringRef P
Definition: ASTMatchersInternal.cpp:564
clang::Type::isDependentType
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
Definition: Type.h:2304
clang::VK_PRValue
@ VK_PRValue
A pr-value expression (in the C++11 taxonomy) produces a temporary value.
Definition: Specifiers.h:123
clang::ConstraintSatisfaction::Profile
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &C)
Definition: ASTConcept.h:55
clang::Decl::getFriendObjectKind
FriendObjectKind getFriendObjectKind() const
Determines whether this declaration is the object of a friend declaration and, if so,...
Definition: DeclBase.h:1185
clang::ConceptSpecializationExpr::getBeginLoc
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: ExprConcepts.h:118
clang::concepts::ExprRequirement::SS_Satisfied
@ SS_Satisfied
Definition: ExprConcepts.h:262
clang::PartialDiagnostic::EmitToString
void EmitToString(DiagnosticsEngine &Diags, SmallVectorImpl< char > &Buf) const
Definition: PartialDiagnostic.h:167
false
#define false
Definition: stdbool.h:22
clang::concepts::TypeRequirement
A requires-expression requirement which queries the existence of a type name or type template special...
Definition: ExprConcepts.h:199
clang::ActionResult::get
PtrTy get() const
Definition: Ownership.h:169
SemaDiagnostic.h
makeDNF
static NormalForm makeDNF(const NormalizedConstraint &Normalized)
Definition: SemaConcept.cpp:1259
clang::TemplateName
Represents a C++ template name within the type system.
Definition: TemplateName.h:201
clang::TemplateArgumentListInfo::size
unsigned size() const
Definition: TemplateBase.h:587
clang::DeclContext::getParent
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition: DeclBase.h:1923
clang::Expr::getExprLoc
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
Definition: Expr.cpp:329
TemplateDeduction.h
clang::TemplateDecl
The base class of all kinds of template declarations (e.g., class, function, etc.).
Definition: DeclTemplate.h:408
clang::ASTConstraintSatisfaction::IsSatisfied
bool IsSatisfied
Definition: ASTConcept.h:81
llvm::ArrayRef
Definition: LLVM.h:34
Value
Value
Definition: UninitializedValues.cpp:103
clang::Decl
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:83
clang::EnterExpressionEvaluationContext
RAII object that enters a new expression evaluation context.
Definition: Sema.h:13805
clang::Expr::IgnoreParenImpCasts
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
Definition: Expr.cpp:3035
clang::MultiLevelTemplateArgumentList::getInnermost
const ArgList & getInnermost() const
Retrieve the innermost template argument list.
Definition: Template.h:250
clang::FunctionDecl::TemplatedKind
TemplatedKind
The kind of templated function a FunctionDecl can be.
Definition: Decl.h:1911
clang::Sema::SatisfactionStackContains
bool SatisfactionStackContains(const llvm::FoldingSetNodeID &ID) const
Definition: Sema.h:7248
clang::Sema
Sema - This implements semantic analysis and AST building for C.
Definition: Sema.h:358
clang::FunctionDecl::TK_NonTemplate
@ TK_NonTemplate
Definition: Decl.h:1913
clang::ActionResult::isInvalid
bool isInvalid() const
Definition: Ownership.h:165
clang::concepts::ExprRequirement::SatisfactionStatus
SatisfactionStatus
Definition: ExprConcepts.h:256
clang::concepts::ExprRequirement::SS_NoexceptNotMet
@ SS_NoexceptNotMet
Definition: ExprConcepts.h:259
clang::TemplateTypeParmTypeLoc
Wrapper for template type parameters.
Definition: TypeLoc.h:743
clang::concepts::ExprRequirement::SS_ExprSubstitutionFailure
@ SS_ExprSubstitutionFailure
Definition: ExprConcepts.h:258
clang::TemplateArgumentList
A template argument list.
Definition: DeclTemplate.h:238
clang::Sema::ContextRAII
A RAII object to temporarily push a declaration context.
Definition: Sema.h:994
clang::Sema::FunctionScopeRAII
An RAII helper that pops function a function scope on exit.
Definition: Sema.h:4999
clang::TemplateParameterList::size
unsigned size() const
Definition: DeclTemplate.h:130
clang::sema::TemplateDeductionInfo
Provides information about an attempted template argument deduction, whose success or failure was des...
Definition: TemplateDeduction.h:42
clang::Sema::IsAtLeastAsConstrained
bool IsAtLeastAsConstrained(NamedDecl *D1, MutableArrayRef< const Expr * > AC1, NamedDecl *D2, MutableArrayRef< const Expr * > AC2, bool &Result)
Check whether the given declaration's associated constraints are at least as constrained than another...
Definition: SemaConcept.cpp:1343
clang::AtomicConstraint::ConstraintExpr
const Expr * ConstraintExpr
Definition: SemaConcept.h:30
clang::BinaryOperator::getOverloadedOpcode
static Opcode getOverloadedOpcode(OverloadedOperatorKind OO)
Retrieve the binary opcode that corresponds to the given overloaded operator.
Definition: Expr.cpp:2131
clang::PartialDiagnostic
Definition: PartialDiagnostic.h:31
clang::Sema::InstantiatingTemplate
A stack object to be created when performing template instantiation.
Definition: Sema.h:9414
clang::NormalizedConstraint::CCK_Conjunction
@ CCK_Conjunction
Definition: SemaConcept.h:84
clang::Sema::PushSatisfactionStackEntry
void PushSatisfactionStackEntry(const llvm::FoldingSetNodeID &ID)
Definition: Sema.h:7242
clang::ObjCPropertyAttribute::Kind
Kind
Definition: DeclObjCCommon.h:22
clang::TemplateArgumentList::OnStack
@ OnStack
Definition: DeclTemplate.h:259
clang::ActionResult< Expr * >
clang::FunctionTemplateDecl::getTemplatedDecl
FunctionDecl * getTemplatedDecl() const
Get the underlying function declaration of the template.
Definition: DeclTemplate.h:1052
clang::Sema::ReuseLambdaContextDecl
@ ReuseLambdaContextDecl
Definition: Sema.h:5347
clang::Sema::ExpressionEvaluationContext::ConstantEvaluated
@ ConstantEvaluated
The current context is "potentially evaluated" in C++11 terms, but the expression is evaluated at com...
clang::concepts::ExprRequirement::ReturnTypeRequirement
Definition: ExprConcepts.h:264
clang::MultiLevelTemplateArgumentList::getNumSubstitutedLevels
unsigned getNumSubstitutedLevels() const
Determine the number of substituted levels in this template argument list.
Definition: Template.h:128
clang::Builtin::ID
ID
Definition: Builtins.h:52
clang::SourceLocation::isInvalid
bool isInvalid() const
Definition: SourceLocation.h:111
clang::TemplateTypeParmType::getDepth
unsigned getDepth() const
Definition: Type.h:5043
clang::ConceptSpecializationExpr::getTemplateArguments
ArrayRef< TemplateArgument > getTemplateArguments() const
Definition: ExprConcepts.h:87
clang
Definition: CalledOnceCheck.h:17
clang::concepts::Requirement::SubstitutionDiagnostic::DiagMessage
StringRef DiagMessage
Definition: ExprConcepts.h:163
RecursiveASTVisitor.h
clang::Sema::FriendConstraintsDependOnEnclosingTemplate
bool FriendConstraintsDependOnEnclosingTemplate(const FunctionDecl *FD)
Definition: SemaConcept.cpp:717
clang::ConstraintSatisfaction::ContainsErrors
bool ContainsErrors
Definition: ASTConcept.h:47
clang::sema::TemplateDeductionInfo::takeSFINAEDiagnostic
void takeSFINAEDiagnostic(PartialDiagnosticAt &PD)
Take ownership of the SFINAE diagnostic.
Definition: TemplateDeduction.h:107
clang::ConceptSpecializationExpr::getSatisfaction
const ASTConstraintSatisfaction & getSatisfaction() const
Get elaborated satisfaction info about the template arguments' satisfaction of the named concept.
Definition: ExprConcepts.h:108
clang::FunctionTemplateDecl::getInstantiatedFromMemberTemplate
FunctionTemplateDecl * getInstantiatedFromMemberTemplate() const
Definition: DeclTemplate.h:1096
clang::Sema::PopSatisfactionStackEntry
void PopSatisfactionStackEntry()
Definition: Sema.h:7246
clang::Sema::MarkUsedTemplateParameters
void MarkUsedTemplateParameters(const Expr *E, bool OnlyDeduced, unsigned Depth, llvm::SmallBitVector &Used)
Mark which template parameters are used in a given expression.
Definition: SemaTemplateDeduction.cpp:6256
clang::Expr::getType
QualType getType() const
Definition: Expr.h:141
clang::SourceLocation::isValid
bool isValid() const
Return true if this is a valid SourceLocation object.
Definition: SourceLocation.h:110
CheckConstraintSatisfaction
static bool CheckConstraintSatisfaction(Sema &S, const NamedDecl *Template, ArrayRef< const Expr * > ConstraintExprs, llvm::SmallVectorImpl< Expr * > &Converted, const MultiLevelTemplateArgumentList &TemplateArgsLists, SourceRange TemplateIDRange, ConstraintSatisfaction &Satisfaction)
Definition: SemaConcept.cpp:376
clang::TypeSourceInfo
A container of type source information.
Definition: Type.h:6593
clang::LocalInstantiationScope
A stack-allocated class that identifies which local variable declaration instantiations are present i...
Definition: Template.h:333
clang::BinaryOperator::getOverloadedOperator
static OverloadedOperatorKind getOverloadedOperator(Opcode Opc)
Retrieve the overloaded operator kind that corresponds to the given binary opcode.
Definition: Expr.cpp:2169
clang::TemplateParameterList::begin
iterator begin()
Definition: DeclTemplate.h:125
clang::getBinOpPrecedence
prec::Level getBinOpPrecedence(tok::TokenKind Kind, bool GreaterThanIsOperator, bool CPlusPlus11)
Return the precedence of the specified binary operator token.
Definition: OperatorPrecedence.cpp:17
clang::Sema::CheckConstraintSatisfaction
bool CheckConstraintSatisfaction(const NamedDecl *Template, ArrayRef< const Expr * > ConstraintExprs, const MultiLevelTemplateArgumentList &TemplateArgLists, SourceRange TemplateIDRange, ConstraintSatisfaction &Satisfaction)
Check whether the given list of constraint expressions are satisfied (as if in a 'conjunction') given...
Definition: Sema.h:7312
clang::DeclContext::isDependentContext
bool isDependentContext() const
Determines whether this context is dependent on a template parameter.
Definition: DeclBase.cpp:1174
clang::Stmt::getBeginLoc
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: Stmt.cpp:336
clang::concepts::ExprRequirement::getNoexceptLoc
SourceLocation getNoexceptLoc() const
Definition: ExprConcepts.h:364
clang::ConstraintSatisfaction::SubstitutionDiagnostic
std::pair< SourceLocation, StringRef > SubstitutionDiagnostic
Definition: ASTConcept.h:43
clang::TypeSpecTypeLoc::setNameLoc
void setNameLoc(SourceLocation Loc)
Definition: TypeLoc.h:527
clang::ConstraintSatisfaction
The result of a constraint satisfaction check, containing the necessary information to diagnose an un...
Definition: ASTConcept.h:28
clang::CPlusPlus11
@ CPlusPlus11
Definition: LangStandard.h:54
clang::InheritingConcreteTypeLoc::getTypePtr
const TypeClass * getTypePtr() const
Definition: TypeLoc.h:502
clang::Sema::DiagnoseUnsatisfiedConstraint
void DiagnoseUnsatisfiedConstraint(const ConstraintSatisfaction &Satisfaction, bool First=true)
Emit diagnostics explaining why a constraint expression was deemed unsatisfied.
Definition: SemaConcept.cpp:1040
OperatorPrecedence.h
clang::ASTTemplateArgumentListInfo
Represents an explicit template argument list in C++, e.g., the "<int>" in "sort<int>".
Definition: TemplateBase.h:614
llvm::SmallVectorImpl
Definition: Randstruct.h:18
clang::FunctionDecl::isTemplateInstantiation
bool isTemplateInstantiation() const
Determines if the given function was instantiated from a function template.
Definition: Decl.cpp:3860
true
#define true
Definition: stdbool.h:21
clang::ASTContext::hasSameUnqualifiedType
bool hasSameUnqualifiedType(QualType T1, QualType T2) const
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
Definition: ASTContext.h:2544
clang::AtomicConstraint::subsumes
bool subsumes(ASTContext &C, const AtomicConstraint &Other) const
Definition: SemaConcept.h:57
clang::Expr
This represents one expression.
Definition: Expr.h:109
clang::FunctionDecl::getDescribedFunctionTemplate
FunctionTemplateDecl * getDescribedFunctionTemplate() const
Retrieves the function template that is described by this function declaration.
Definition: Decl.cpp:3802
clang::Type::isSpecificBuiltinType
bool isSpecificBuiltinType(unsigned K) const
Test for a particular builtin type.
Definition: Type.h:7149
clang::TemplateTypeParmType::isParameterPack
bool isParameterPack() const
Definition: Type.h:5045
clang::concepts::ExprRequirement
A requires-expression requirement which queries the validity and properties of an expression ('simple...
Definition: ExprConcepts.h:254
clang::concepts::NestedRequirement::isSubstitutionFailure
bool isSubstitutionFailure() const
Definition: ExprConcepts.h:433
clang::concepts::Requirement::RK_Type
@ RK_Type
Definition: ExprConcepts.h:149
clang::NormalizedConstraint::isAtomic
bool isAtomic() const
Definition: SemaConcept.h:128
clang::Decl::getLocation
SourceLocation getLocation() const
Definition: DeclBase.h:432
clang::ASTContext::BoolTy
CanQualType BoolTy
Definition: ASTContext.h:1081
clang::FunctionDecl
Represents a function declaration or definition.
Definition: Decl.h:1904
clang::NormalizedConstraint::getRHS
NormalizedConstraint & getRHS() const
Definition: SemaConcept.h:135
clang::AtomicConstraint::hasMatchingParameterMapping
bool hasMatchingParameterMapping(ASTContext &C, const AtomicConstraint &Other) const
Definition: SemaConcept.h:36
clang::Sema::CheckConstraintExpression
bool CheckConstraintExpression(const Expr *CE, Token NextToken=Token(), bool *PossibleNonPrimary=nullptr, bool IsTrailingRequiresClause=false)
Check whether the given expression is a valid constraint expression.
Definition: SemaConcept.cpp:87
CalculateTemplateDepthForConstraints
static unsigned CalculateTemplateDepthForConstraints(Sema &S, const NamedDecl *ND, bool SkipForSpecialization=false)
Definition: SemaConcept.cpp:651
SemaConcept.h
clang::TypeConstraint
Definition: ASTConcept.h:169
clang::ActionResult::isUsable
bool isUsable() const
Definition: Ownership.h:166
clang::FunctionDecl::getInstantiatedFromMemberFunction
FunctionDecl * getInstantiatedFromMemberFunction() const
If this function is an instantiation of a member function of a class template specialization,...
Definition: Decl.cpp:3774
clang::concepts::ExprRequirement::SS_ConstraintsNotSatisfied
@ SS_ConstraintsNotSatisfied
Definition: ExprConcepts.h:261
clang::concepts::ExprRequirement::getReturnTypeRequirement
const ReturnTypeRequirement & getReturnTypeRequirement() const
Definition: ExprConcepts.h:372
Initialization.h