clang 20.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
14#include "TreeTransform.h"
15#include "clang/AST/ASTLambda.h"
16#include "clang/AST/DeclCXX.h"
21#include "clang/Sema/Overload.h"
23#include "clang/Sema/Sema.h"
25#include "clang/Sema/Template.h"
27#include "llvm/ADT/DenseMap.h"
28#include "llvm/ADT/PointerUnion.h"
29#include "llvm/ADT/StringExtras.h"
30#include <optional>
31
32using namespace clang;
33using namespace sema;
34
35namespace {
36class LogicalBinOp {
39 const Expr *LHS = nullptr;
40 const Expr *RHS = nullptr;
41
42public:
43 LogicalBinOp(const Expr *E) {
44 if (auto *BO = dyn_cast<BinaryOperator>(E)) {
45 Op = BinaryOperator::getOverloadedOperator(BO->getOpcode());
46 LHS = BO->getLHS();
47 RHS = BO->getRHS();
48 Loc = BO->getExprLoc();
49 } else if (auto *OO = dyn_cast<CXXOperatorCallExpr>(E)) {
50 // If OO is not || or && it might not have exactly 2 arguments.
51 if (OO->getNumArgs() == 2) {
52 Op = OO->getOperator();
53 LHS = OO->getArg(0);
54 RHS = OO->getArg(1);
55 Loc = OO->getOperatorLoc();
56 }
57 }
58 }
59
60 bool isAnd() const { return Op == OO_AmpAmp; }
61 bool isOr() const { return Op == OO_PipePipe; }
62 explicit operator bool() const { return isAnd() || isOr(); }
63
64 const Expr *getLHS() const { return LHS; }
65 const Expr *getRHS() const { return RHS; }
66 OverloadedOperatorKind getOp() const { return Op; }
67
68 ExprResult recreateBinOp(Sema &SemaRef, ExprResult LHS) const {
69 return recreateBinOp(SemaRef, LHS, const_cast<Expr *>(getRHS()));
70 }
71
72 ExprResult recreateBinOp(Sema &SemaRef, ExprResult LHS,
73 ExprResult RHS) const {
74 assert((isAnd() || isOr()) && "Not the right kind of op?");
75 assert((!LHS.isInvalid() && !RHS.isInvalid()) && "not good expressions?");
76
77 if (!LHS.isUsable() || !RHS.isUsable())
78 return ExprEmpty();
79
80 // We should just be able to 'normalize' these to the builtin Binary
81 // Operator, since that is how they are evaluated in constriant checks.
82 return BinaryOperator::Create(SemaRef.Context, LHS.get(), RHS.get(),
84 SemaRef.Context.BoolTy, VK_PRValue,
86 }
87};
88}
89
90bool Sema::CheckConstraintExpression(const Expr *ConstraintExpression,
91 Token NextToken, bool *PossibleNonPrimary,
92 bool IsTrailingRequiresClause) {
93 // C++2a [temp.constr.atomic]p1
94 // ..E shall be a constant expression of type bool.
95
96 ConstraintExpression = ConstraintExpression->IgnoreParenImpCasts();
97
98 if (LogicalBinOp BO = ConstraintExpression) {
99 return CheckConstraintExpression(BO.getLHS(), NextToken,
100 PossibleNonPrimary) &&
101 CheckConstraintExpression(BO.getRHS(), NextToken,
102 PossibleNonPrimary);
103 } else if (auto *C = dyn_cast<ExprWithCleanups>(ConstraintExpression))
104 return CheckConstraintExpression(C->getSubExpr(), NextToken,
105 PossibleNonPrimary);
106
107 QualType Type = ConstraintExpression->getType();
108
109 auto CheckForNonPrimary = [&] {
110 if (!PossibleNonPrimary)
111 return;
112
113 *PossibleNonPrimary =
114 // We have the following case:
115 // template<typename> requires func(0) struct S { };
116 // The user probably isn't aware of the parentheses required around
117 // the function call, and we're only going to parse 'func' as the
118 // primary-expression, and complain that it is of non-bool type.
119 //
120 // However, if we're in a lambda, this might also be:
121 // []<typename> requires var () {};
122 // Which also looks like a function call due to the lambda parentheses,
123 // but unlike the first case, isn't an error, so this check is skipped.
124 (NextToken.is(tok::l_paren) &&
125 (IsTrailingRequiresClause ||
126 (Type->isDependentType() &&
127 isa<UnresolvedLookupExpr>(ConstraintExpression) &&
128 !dyn_cast_if_present<LambdaScopeInfo>(getCurFunction())) ||
129 Type->isFunctionType() ||
130 Type->isSpecificBuiltinType(BuiltinType::Overload))) ||
131 // We have the following case:
132 // template<typename T> requires size_<T> == 0 struct S { };
133 // The user probably isn't aware of the parentheses required around
134 // the binary operator, and we're only going to parse 'func' as the
135 // first operand, and complain that it is of non-bool type.
136 getBinOpPrecedence(NextToken.getKind(),
137 /*GreaterThanIsOperator=*/true,
139 };
140
141 // An atomic constraint!
142 if (ConstraintExpression->isTypeDependent()) {
143 CheckForNonPrimary();
144 return true;
145 }
146
148 Diag(ConstraintExpression->getExprLoc(),
149 diag::err_non_bool_atomic_constraint) << Type
150 << ConstraintExpression->getSourceRange();
151 CheckForNonPrimary();
152 return false;
153 }
154
155 if (PossibleNonPrimary)
156 *PossibleNonPrimary = false;
157 return true;
158}
159
160namespace {
161struct SatisfactionStackRAII {
162 Sema &SemaRef;
163 bool Inserted = false;
164 SatisfactionStackRAII(Sema &SemaRef, const NamedDecl *ND,
165 const llvm::FoldingSetNodeID &FSNID)
166 : SemaRef(SemaRef) {
167 if (ND) {
168 SemaRef.PushSatisfactionStackEntry(ND, FSNID);
169 Inserted = true;
170 }
171 }
172 ~SatisfactionStackRAII() {
173 if (Inserted)
175 }
176};
177} // namespace
178
179template <typename ConstraintEvaluator>
180static ExprResult
181calculateConstraintSatisfaction(Sema &S, const Expr *ConstraintExpr,
182 ConstraintSatisfaction &Satisfaction,
183 const ConstraintEvaluator &Evaluator);
184
185template <typename ConstraintEvaluator>
186static ExprResult
188 OverloadedOperatorKind Op, const Expr *RHS,
189 ConstraintSatisfaction &Satisfaction,
190 const ConstraintEvaluator &Evaluator) {
191 size_t EffectiveDetailEndIndex = Satisfaction.Details.size();
192
193 ExprResult LHSRes =
194 calculateConstraintSatisfaction(S, LHS, Satisfaction, Evaluator);
195
196 if (LHSRes.isInvalid())
197 return ExprError();
198
199 bool IsLHSSatisfied = Satisfaction.IsSatisfied;
200
201 if (Op == clang::OO_PipePipe && IsLHSSatisfied)
202 // [temp.constr.op] p3
203 // A disjunction is a constraint taking two operands. To determine if
204 // a disjunction is satisfied, the satisfaction of the first operand
205 // is checked. If that is satisfied, the disjunction is satisfied.
206 // Otherwise, the disjunction is satisfied if and only if the second
207 // operand is satisfied.
208 // LHS is instantiated while RHS is not. Skip creating invalid BinaryOp.
209 return LHSRes;
210
211 if (Op == clang::OO_AmpAmp && !IsLHSSatisfied)
212 // [temp.constr.op] p2
213 // A conjunction is a constraint taking two operands. To determine if
214 // a conjunction is satisfied, the satisfaction of the first operand
215 // is checked. If that is not satisfied, the conjunction is not
216 // satisfied. Otherwise, the conjunction is satisfied if and only if
217 // the second operand is satisfied.
218 // LHS is instantiated while RHS is not. Skip creating invalid BinaryOp.
219 return LHSRes;
220
221 ExprResult RHSRes =
222 calculateConstraintSatisfaction(S, RHS, Satisfaction, Evaluator);
223 if (RHSRes.isInvalid())
224 return ExprError();
225
226 bool IsRHSSatisfied = Satisfaction.IsSatisfied;
227 // Current implementation adds diagnostic information about the falsity
228 // of each false atomic constraint expression when it evaluates them.
229 // When the evaluation results to `false || true`, the information
230 // generated during the evaluation of left-hand side is meaningless
231 // because the whole expression evaluates to true.
232 // The following code removes the irrelevant diagnostic information.
233 // FIXME: We should probably delay the addition of diagnostic information
234 // until we know the entire expression is false.
235 if (Op == clang::OO_PipePipe && IsRHSSatisfied) {
236 auto EffectiveDetailEnd = Satisfaction.Details.begin();
237 std::advance(EffectiveDetailEnd, EffectiveDetailEndIndex);
238 Satisfaction.Details.erase(EffectiveDetailEnd, Satisfaction.Details.end());
239 }
240
241 if (!LHSRes.isUsable() || !RHSRes.isUsable())
242 return ExprEmpty();
243
244 return BinaryOperator::Create(S.Context, LHSRes.get(), RHSRes.get(),
248}
249
250template <typename ConstraintEvaluator>
251static ExprResult
253 ConstraintSatisfaction &Satisfaction,
254 const ConstraintEvaluator &Evaluator) {
255 bool Conjunction = FE->getOperator() == BinaryOperatorKind::BO_LAnd;
256 size_t EffectiveDetailEndIndex = Satisfaction.Details.size();
257
258 ExprResult Out;
259 if (FE->isLeftFold() && FE->getInit()) {
260 Out = calculateConstraintSatisfaction(S, FE->getInit(), Satisfaction,
261 Evaluator);
262 if (Out.isInvalid())
263 return ExprError();
264
265 // If the first clause of a conjunction is not satisfied,
266 // or if the first clause of a disjection is satisfied,
267 // we have established satisfaction of the whole constraint
268 // and we should not continue further.
269 if (Conjunction != Satisfaction.IsSatisfied)
270 return Out;
271 }
272 std::optional<unsigned> NumExpansions =
273 Evaluator.EvaluateFoldExpandedConstraintSize(FE);
274 if (!NumExpansions)
275 return ExprError();
276 for (unsigned I = 0; I < *NumExpansions; I++) {
279 Satisfaction, Evaluator);
280 if (Res.isInvalid())
281 return ExprError();
282 bool IsRHSSatisfied = Satisfaction.IsSatisfied;
283 if (!Conjunction && IsRHSSatisfied) {
284 auto EffectiveDetailEnd = Satisfaction.Details.begin();
285 std::advance(EffectiveDetailEnd, EffectiveDetailEndIndex);
286 Satisfaction.Details.erase(EffectiveDetailEnd,
287 Satisfaction.Details.end());
288 }
289 if (Out.isUnset())
290 Out = Res;
291 else if (!Res.isUnset()) {
293 S.Context, Out.get(), Res.get(), FE->getOperator(), S.Context.BoolTy,
295 }
296 if (Conjunction != IsRHSSatisfied)
297 return Out;
298 }
299
300 if (FE->isRightFold() && FE->getInit()) {
302 Satisfaction, Evaluator);
303 if (Out.isInvalid())
304 return ExprError();
305
306 if (Out.isUnset())
307 Out = Res;
308 else if (!Res.isUnset()) {
310 S.Context, Out.get(), Res.get(), FE->getOperator(), S.Context.BoolTy,
312 }
313 }
314
315 if (Out.isUnset()) {
316 Satisfaction.IsSatisfied = Conjunction;
317 Out = S.BuildEmptyCXXFoldExpr(FE->getBeginLoc(), FE->getOperator());
318 }
319 return Out;
320}
321
322template <typename ConstraintEvaluator>
323static ExprResult
324calculateConstraintSatisfaction(Sema &S, const Expr *ConstraintExpr,
325 ConstraintSatisfaction &Satisfaction,
326 const ConstraintEvaluator &Evaluator) {
327 ConstraintExpr = ConstraintExpr->IgnoreParenImpCasts();
328
329 if (LogicalBinOp BO = ConstraintExpr)
331 S, BO.getLHS(), BO.getOp(), BO.getRHS(), Satisfaction, Evaluator);
332
333 if (auto *C = dyn_cast<ExprWithCleanups>(ConstraintExpr)) {
334 // These aren't evaluated, so we don't care about cleanups, so we can just
335 // evaluate these as if the cleanups didn't exist.
336 return calculateConstraintSatisfaction(S, C->getSubExpr(), Satisfaction,
337 Evaluator);
338 }
339
340 if (auto *FE = dyn_cast<CXXFoldExpr>(ConstraintExpr);
341 FE && S.getLangOpts().CPlusPlus26 &&
342 (FE->getOperator() == BinaryOperatorKind::BO_LAnd ||
343 FE->getOperator() == BinaryOperatorKind::BO_LOr)) {
344 return calculateConstraintSatisfaction(S, FE, Satisfaction, Evaluator);
345 }
346
347 // An atomic constraint expression
348 ExprResult SubstitutedAtomicExpr =
349 Evaluator.EvaluateAtomicConstraint(ConstraintExpr);
350
351 if (SubstitutedAtomicExpr.isInvalid())
352 return ExprError();
353
354 if (!SubstitutedAtomicExpr.isUsable())
355 // Evaluator has decided satisfaction without yielding an expression.
356 return ExprEmpty();
357
358 // We don't have the ability to evaluate this, since it contains a
359 // RecoveryExpr, so we want to fail overload resolution. Otherwise,
360 // we'd potentially pick up a different overload, and cause confusing
361 // diagnostics. SO, add a failure detail that will cause us to make this
362 // overload set not viable.
363 if (SubstitutedAtomicExpr.get()->containsErrors()) {
364 Satisfaction.IsSatisfied = false;
365 Satisfaction.ContainsErrors = true;
366
367 PartialDiagnostic Msg = S.PDiag(diag::note_constraint_references_error);
368 SmallString<128> DiagString;
369 DiagString = ": ";
370 Msg.EmitToString(S.getDiagnostics(), DiagString);
371 unsigned MessageSize = DiagString.size();
372 char *Mem = new (S.Context) char[MessageSize];
373 memcpy(Mem, DiagString.c_str(), MessageSize);
374 Satisfaction.Details.emplace_back(
376 SubstitutedAtomicExpr.get()->getBeginLoc(),
377 StringRef(Mem, MessageSize)});
378 return SubstitutedAtomicExpr;
379 }
380
381 EnterExpressionEvaluationContext ConstantEvaluated(
384 Expr::EvalResult EvalResult;
385 EvalResult.Diag = &EvaluationDiags;
386 if (!SubstitutedAtomicExpr.get()->EvaluateAsConstantExpr(EvalResult,
387 S.Context) ||
388 !EvaluationDiags.empty()) {
389 // C++2a [temp.constr.atomic]p1
390 // ...E shall be a constant expression of type bool.
391 S.Diag(SubstitutedAtomicExpr.get()->getBeginLoc(),
392 diag::err_non_constant_constraint_expression)
393 << SubstitutedAtomicExpr.get()->getSourceRange();
394 for (const PartialDiagnosticAt &PDiag : EvaluationDiags)
395 S.Diag(PDiag.first, PDiag.second);
396 return ExprError();
397 }
398
399 assert(EvalResult.Val.isInt() &&
400 "evaluating bool expression didn't produce int");
401 Satisfaction.IsSatisfied = EvalResult.Val.getInt().getBoolValue();
402 if (!Satisfaction.IsSatisfied)
403 Satisfaction.Details.emplace_back(SubstitutedAtomicExpr.get());
404
405 return SubstitutedAtomicExpr;
406}
407
408static bool
409DiagRecursiveConstraintEval(Sema &S, llvm::FoldingSetNodeID &ID,
410 const NamedDecl *Templ, const Expr *E,
411 const MultiLevelTemplateArgumentList &MLTAL) {
412 E->Profile(ID, S.Context, /*Canonical=*/true);
413 for (const auto &List : MLTAL)
414 for (const auto &TemplateArg : List.Args)
415 TemplateArg.Profile(ID, S.Context);
416
417 // Note that we have to do this with our own collection, because there are
418 // times where a constraint-expression check can cause us to need to evaluate
419 // other constriants that are unrelated, such as when evaluating a recovery
420 // expression, or when trying to determine the constexpr-ness of special
421 // members. Otherwise we could just use the
422 // Sema::InstantiatingTemplate::isAlreadyBeingInstantiated function.
423 if (S.SatisfactionStackContains(Templ, ID)) {
424 S.Diag(E->getExprLoc(), diag::err_constraint_depends_on_self)
425 << const_cast<Expr *>(E) << E->getSourceRange();
426 return true;
427 }
428
429 return false;
430}
431
433 Sema &S, const NamedDecl *Template, SourceLocation TemplateNameLoc,
434 const MultiLevelTemplateArgumentList &MLTAL, const Expr *ConstraintExpr,
435 ConstraintSatisfaction &Satisfaction) {
436
437 struct ConstraintEvaluator {
438 Sema &S;
439 const NamedDecl *Template;
440 SourceLocation TemplateNameLoc;
442 ConstraintSatisfaction &Satisfaction;
443
444 ExprResult EvaluateAtomicConstraint(const Expr *AtomicExpr) const {
445 EnterExpressionEvaluationContext ConstantEvaluated(
446 S, Sema::ExpressionEvaluationContext::ConstantEvaluated,
448
449 // Atomic constraint - substitute arguments and check satisfaction.
450 ExprResult SubstitutedExpression;
451 {
452 TemplateDeductionInfo Info(TemplateNameLoc);
456 const_cast<NamedDecl *>(Template), Info,
458 if (Inst.isInvalid())
459 return ExprError();
460
461 llvm::FoldingSetNodeID ID;
462 if (Template &&
463 DiagRecursiveConstraintEval(S, ID, Template, AtomicExpr, MLTAL)) {
464 Satisfaction.IsSatisfied = false;
465 Satisfaction.ContainsErrors = true;
466 return ExprEmpty();
467 }
468
469 SatisfactionStackRAII StackRAII(S, Template, ID);
470
471 // We do not want error diagnostics escaping here.
472 Sema::SFINAETrap Trap(S);
473 SubstitutedExpression =
474 S.SubstConstraintExpr(const_cast<Expr *>(AtomicExpr), MLTAL);
475
476 if (SubstitutedExpression.isInvalid() || Trap.hasErrorOccurred()) {
477 // C++2a [temp.constr.atomic]p1
478 // ...If substitution results in an invalid type or expression, the
479 // constraint is not satisfied.
480 if (!Trap.hasErrorOccurred())
481 // A non-SFINAE error has occurred as a result of this
482 // substitution.
483 return ExprError();
484
487 Info.takeSFINAEDiagnostic(SubstDiag);
488 // FIXME: Concepts: This is an unfortunate consequence of there
489 // being no serialization code for PartialDiagnostics and the fact
490 // that serializing them would likely take a lot more storage than
491 // just storing them as strings. We would still like, in the
492 // future, to serialize the proper PartialDiagnostic as serializing
493 // it as a string defeats the purpose of the diagnostic mechanism.
494 SmallString<128> DiagString;
495 DiagString = ": ";
496 SubstDiag.second.EmitToString(S.getDiagnostics(), DiagString);
497 unsigned MessageSize = DiagString.size();
498 char *Mem = new (S.Context) char[MessageSize];
499 memcpy(Mem, DiagString.c_str(), MessageSize);
500 Satisfaction.Details.emplace_back(
502 SubstDiag.first, StringRef(Mem, MessageSize)});
503 Satisfaction.IsSatisfied = false;
504 return ExprEmpty();
505 }
506 }
507
508 if (!S.CheckConstraintExpression(SubstitutedExpression.get()))
509 return ExprError();
510
511 // [temp.constr.atomic]p3: To determine if an atomic constraint is
512 // satisfied, the parameter mapping and template arguments are first
513 // substituted into its expression. If substitution results in an
514 // invalid type or expression, the constraint is not satisfied.
515 // Otherwise, the lvalue-to-rvalue conversion is performed if necessary,
516 // and E shall be a constant expression of type bool.
517 //
518 // Perform the L to R Value conversion if necessary. We do so for all
519 // non-PRValue categories, else we fail to extend the lifetime of
520 // temporaries, and that fails the constant expression check.
521 if (!SubstitutedExpression.get()->isPRValue())
522 SubstitutedExpression = ImplicitCastExpr::Create(
523 S.Context, SubstitutedExpression.get()->getType(),
524 CK_LValueToRValue, SubstitutedExpression.get(),
525 /*BasePath=*/nullptr, VK_PRValue, FPOptionsOverride());
526
527 return SubstitutedExpression;
528 }
529
530 std::optional<unsigned>
531 EvaluateFoldExpandedConstraintSize(const CXXFoldExpr *FE) const {
532
533 // We should ignore errors in the presence of packs of different size.
534 Sema::SFINAETrap Trap(S);
535
536 Expr *Pattern = FE->getPattern();
537
539 S.collectUnexpandedParameterPacks(Pattern, Unexpanded);
540 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
541 bool Expand = true;
542 bool RetainExpansion = false;
543 std::optional<unsigned> OrigNumExpansions = FE->getNumExpansions(),
544 NumExpansions = OrigNumExpansions;
546 FE->getEllipsisLoc(), Pattern->getSourceRange(), Unexpanded,
547 MLTAL, Expand, RetainExpansion, NumExpansions) ||
548 !Expand || RetainExpansion)
549 return std::nullopt;
550
551 if (NumExpansions && S.getLangOpts().BracketDepth < NumExpansions) {
552 S.Diag(FE->getEllipsisLoc(),
553 clang::diag::err_fold_expression_limit_exceeded)
554 << *NumExpansions << S.getLangOpts().BracketDepth
555 << FE->getSourceRange();
556 S.Diag(FE->getEllipsisLoc(), diag::note_bracket_depth);
557 return std::nullopt;
558 }
559 return NumExpansions;
560 }
561 };
562
564 S, ConstraintExpr, Satisfaction,
565 ConstraintEvaluator{S, Template, TemplateNameLoc, MLTAL, Satisfaction});
566}
567
569 Sema &S, const NamedDecl *Template, ArrayRef<const Expr *> ConstraintExprs,
571 const MultiLevelTemplateArgumentList &TemplateArgsLists,
572 SourceRange TemplateIDRange, ConstraintSatisfaction &Satisfaction) {
573 if (ConstraintExprs.empty()) {
574 Satisfaction.IsSatisfied = true;
575 return false;
576 }
577
578 if (TemplateArgsLists.isAnyArgInstantiationDependent()) {
579 // No need to check satisfaction for dependent constraint expressions.
580 Satisfaction.IsSatisfied = true;
581 return false;
582 }
583
584 ArrayRef<TemplateArgument> TemplateArgs =
585 TemplateArgsLists.getNumSubstitutedLevels() > 0
586 ? TemplateArgsLists.getOutermost()
588 Sema::InstantiatingTemplate Inst(S, TemplateIDRange.getBegin(),
590 const_cast<NamedDecl *>(Template), TemplateArgs, TemplateIDRange);
591 if (Inst.isInvalid())
592 return true;
593
594 for (const Expr *ConstraintExpr : ConstraintExprs) {
596 S, Template, TemplateIDRange.getBegin(), TemplateArgsLists,
597 ConstraintExpr, Satisfaction);
598 if (Res.isInvalid())
599 return true;
600
601 Converted.push_back(Res.get());
602 if (!Satisfaction.IsSatisfied) {
603 // Backfill the 'converted' list with nulls so we can keep the Converted
604 // and unconverted lists in sync.
605 Converted.append(ConstraintExprs.size() - Converted.size(), nullptr);
606 // [temp.constr.op] p2
607 // [...] To determine if a conjunction is satisfied, the satisfaction
608 // of the first operand is checked. If that is not satisfied, the
609 // conjunction is not satisfied. [...]
610 return false;
611 }
612 }
613 return false;
614}
615
617 const NamedDecl *Template, ArrayRef<const Expr *> ConstraintExprs,
618 llvm::SmallVectorImpl<Expr *> &ConvertedConstraints,
619 const MultiLevelTemplateArgumentList &TemplateArgsLists,
620 SourceRange TemplateIDRange, ConstraintSatisfaction &OutSatisfaction) {
621 if (ConstraintExprs.empty()) {
622 OutSatisfaction.IsSatisfied = true;
623 return false;
624 }
625 if (!Template) {
626 return ::CheckConstraintSatisfaction(
627 *this, nullptr, ConstraintExprs, ConvertedConstraints,
628 TemplateArgsLists, TemplateIDRange, OutSatisfaction);
629 }
630 // Invalid templates could make their way here. Substituting them could result
631 // in dependent expressions.
632 if (Template->isInvalidDecl()) {
633 OutSatisfaction.IsSatisfied = false;
634 return true;
635 }
636
637 // A list of the template argument list flattened in a predictible manner for
638 // the purposes of caching. The ConstraintSatisfaction type is in AST so it
639 // has no access to the MultiLevelTemplateArgumentList, so this has to happen
640 // here.
642 for (auto List : TemplateArgsLists)
643 FlattenedArgs.insert(FlattenedArgs.end(), List.Args.begin(),
644 List.Args.end());
645
646 llvm::FoldingSetNodeID ID;
647 ConstraintSatisfaction::Profile(ID, Context, Template, FlattenedArgs);
648 void *InsertPos;
649 if (auto *Cached = SatisfactionCache.FindNodeOrInsertPos(ID, InsertPos)) {
650 OutSatisfaction = *Cached;
651 return false;
652 }
653
654 auto Satisfaction =
655 std::make_unique<ConstraintSatisfaction>(Template, FlattenedArgs);
656 if (::CheckConstraintSatisfaction(*this, Template, ConstraintExprs,
657 ConvertedConstraints, TemplateArgsLists,
658 TemplateIDRange, *Satisfaction)) {
659 OutSatisfaction = *Satisfaction;
660 return true;
661 }
662
663 if (auto *Cached = SatisfactionCache.FindNodeOrInsertPos(ID, InsertPos)) {
664 // The evaluation of this constraint resulted in us trying to re-evaluate it
665 // recursively. This isn't really possible, except we try to form a
666 // RecoveryExpr as a part of the evaluation. If this is the case, just
667 // return the 'cached' version (which will have the same result), and save
668 // ourselves the extra-insert. If it ever becomes possible to legitimately
669 // recursively check a constraint, we should skip checking the 'inner' one
670 // above, and replace the cached version with this one, as it would be more
671 // specific.
672 OutSatisfaction = *Cached;
673 return false;
674 }
675
676 // Else we can simply add this satisfaction to the list.
677 OutSatisfaction = *Satisfaction;
678 // We cannot use InsertPos here because CheckConstraintSatisfaction might have
679 // invalidated it.
680 // Note that entries of SatisfactionCache are deleted in Sema's destructor.
681 SatisfactionCache.InsertNode(Satisfaction.release());
682 return false;
683}
684
685bool Sema::CheckConstraintSatisfaction(const Expr *ConstraintExpr,
686 ConstraintSatisfaction &Satisfaction) {
687
688 struct ConstraintEvaluator {
689 Sema &S;
690 ExprResult EvaluateAtomicConstraint(const Expr *AtomicExpr) const {
691 return S.PerformContextuallyConvertToBool(const_cast<Expr *>(AtomicExpr));
692 }
693
694 std::optional<unsigned>
695 EvaluateFoldExpandedConstraintSize(const CXXFoldExpr *FE) const {
696 return 0;
697 }
698 };
699
700 return calculateConstraintSatisfaction(*this, ConstraintExpr, Satisfaction,
701 ConstraintEvaluator{*this})
702 .isInvalid();
703}
704
705bool Sema::addInstantiatedCapturesToScope(
706 FunctionDecl *Function, const FunctionDecl *PatternDecl,
708 const MultiLevelTemplateArgumentList &TemplateArgs) {
709 const auto *LambdaClass = cast<CXXMethodDecl>(Function)->getParent();
710 const auto *LambdaPattern = cast<CXXMethodDecl>(PatternDecl)->getParent();
711
712 unsigned Instantiated = 0;
713
714 auto AddSingleCapture = [&](const ValueDecl *CapturedPattern,
715 unsigned Index) {
716 ValueDecl *CapturedVar = LambdaClass->getCapture(Index)->getCapturedVar();
717 assert(CapturedVar->isInitCapture());
718 Scope.InstantiatedLocal(CapturedPattern, CapturedVar);
719 };
720
721 for (const LambdaCapture &CapturePattern : LambdaPattern->captures()) {
722 if (!CapturePattern.capturesVariable()) {
723 Instantiated++;
724 continue;
725 }
726 ValueDecl *CapturedPattern = CapturePattern.getCapturedVar();
727
728 if (!CapturedPattern->isInitCapture()) {
729 Instantiated++;
730 continue;
731 }
732
733 if (!CapturedPattern->isParameterPack()) {
734 AddSingleCapture(CapturedPattern, Instantiated++);
735 } else {
736 Scope.MakeInstantiatedLocalArgPack(CapturedPattern);
739 dyn_cast<VarDecl>(CapturedPattern)->getInit(), Unexpanded);
740 auto NumArgumentsInExpansion =
741 getNumArgumentsInExpansionFromUnexpanded(Unexpanded, TemplateArgs);
742 if (!NumArgumentsInExpansion)
743 continue;
744 for (unsigned Arg = 0; Arg < *NumArgumentsInExpansion; ++Arg)
745 AddSingleCapture(CapturedPattern, Instantiated++);
746 }
747 }
748 return false;
749}
750
751bool Sema::SetupConstraintScope(
752 FunctionDecl *FD, std::optional<ArrayRef<TemplateArgument>> TemplateArgs,
755 if (FD->isTemplateInstantiation() && FD->getPrimaryTemplate()) {
756 FunctionTemplateDecl *PrimaryTemplate = FD->getPrimaryTemplate();
757 InstantiatingTemplate Inst(
758 *this, FD->getPointOfInstantiation(),
760 TemplateArgs ? *TemplateArgs : ArrayRef<TemplateArgument>{},
761 SourceRange());
762 if (Inst.isInvalid())
763 return true;
764
765 // addInstantiatedParametersToScope creates a map of 'uninstantiated' to
766 // 'instantiated' parameters and adds it to the context. For the case where
767 // this function is a template being instantiated NOW, we also need to add
768 // the list of current template arguments to the list so that they also can
769 // be picked out of the map.
770 if (auto *SpecArgs = FD->getTemplateSpecializationArgs()) {
771 MultiLevelTemplateArgumentList JustTemplArgs(FD, SpecArgs->asArray(),
772 /*Final=*/false);
773 if (addInstantiatedParametersToScope(
774 FD, PrimaryTemplate->getTemplatedDecl(), Scope, JustTemplArgs))
775 return true;
776 }
777
778 // If this is a member function, make sure we get the parameters that
779 // reference the original primary template.
780 // We walk up the instantiated template chain so that nested lambdas get
781 // handled properly.
782 // We should only collect instantiated parameters from the primary template.
783 // Otherwise, we may have mismatched template parameter depth!
784 if (FunctionTemplateDecl *FromMemTempl =
785 PrimaryTemplate->getInstantiatedFromMemberTemplate()) {
786 while (FromMemTempl->getInstantiatedFromMemberTemplate())
787 FromMemTempl = FromMemTempl->getInstantiatedFromMemberTemplate();
788 if (addInstantiatedParametersToScope(FD, FromMemTempl->getTemplatedDecl(),
789 Scope, MLTAL))
790 return true;
791 }
792
793 return false;
794 }
795
798 FunctionDecl *InstantiatedFrom =
802
803 InstantiatingTemplate Inst(
804 *this, FD->getPointOfInstantiation(),
806 TemplateArgs ? *TemplateArgs : ArrayRef<TemplateArgument>{},
807 SourceRange());
808 if (Inst.isInvalid())
809 return true;
810
811 // Case where this was not a template, but instantiated as a
812 // child-function.
813 if (addInstantiatedParametersToScope(FD, InstantiatedFrom, Scope, MLTAL))
814 return true;
815 }
816
817 return false;
818}
819
820// This function collects all of the template arguments for the purposes of
821// constraint-instantiation and checking.
822std::optional<MultiLevelTemplateArgumentList>
823Sema::SetupConstraintCheckingTemplateArgumentsAndScope(
824 FunctionDecl *FD, std::optional<ArrayRef<TemplateArgument>> TemplateArgs,
827
828 // Collect the list of template arguments relative to the 'primary' template.
829 // We need the entire list, since the constraint is completely uninstantiated
830 // at this point.
831 MLTAL =
833 /*Final=*/false, /*Innermost=*/std::nullopt,
834 /*RelativeToPrimary=*/true,
835 /*Pattern=*/nullptr,
836 /*ForConstraintInstantiation=*/true);
837 if (SetupConstraintScope(FD, TemplateArgs, MLTAL, Scope))
838 return std::nullopt;
839
840 return MLTAL;
841}
842
844 ConstraintSatisfaction &Satisfaction,
845 SourceLocation UsageLoc,
846 bool ForOverloadResolution) {
847 // Don't check constraints if the function is dependent. Also don't check if
848 // this is a function template specialization, as the call to
849 // CheckFunctionTemplateConstraints after this will check it
850 // better.
851 if (FD->isDependentContext() ||
852 FD->getTemplatedKind() ==
854 Satisfaction.IsSatisfied = true;
855 return false;
856 }
857
858 // A lambda conversion operator has the same constraints as the call operator
859 // and constraints checking relies on whether we are in a lambda call operator
860 // (and may refer to its parameters), so check the call operator instead.
861 // Note that the declarations outside of the lambda should also be
862 // considered. Turning on the 'ForOverloadResolution' flag results in the
863 // LocalInstantiationScope not looking into its parents, but we can still
864 // access Decls from the parents while building a lambda RAII scope later.
865 if (const auto *MD = dyn_cast<CXXConversionDecl>(FD);
866 MD && isLambdaConversionOperator(const_cast<CXXConversionDecl *>(MD)))
867 return CheckFunctionConstraints(MD->getParent()->getLambdaCallOperator(),
868 Satisfaction, UsageLoc,
869 /*ShouldAddDeclsFromParentScope=*/true);
870
871 DeclContext *CtxToSave = const_cast<FunctionDecl *>(FD);
872
873 while (isLambdaCallOperator(CtxToSave) || FD->isTransparentContext()) {
874 if (isLambdaCallOperator(CtxToSave))
875 CtxToSave = CtxToSave->getParent()->getParent();
876 else
877 CtxToSave = CtxToSave->getNonTransparentContext();
878 }
879
880 ContextRAII SavedContext{*this, CtxToSave};
881 LocalInstantiationScope Scope(*this, !ForOverloadResolution);
882 std::optional<MultiLevelTemplateArgumentList> MLTAL =
883 SetupConstraintCheckingTemplateArgumentsAndScope(
884 const_cast<FunctionDecl *>(FD), {}, Scope);
885
886 if (!MLTAL)
887 return true;
888
889 Qualifiers ThisQuals;
890 CXXRecordDecl *Record = nullptr;
891 if (auto *Method = dyn_cast<CXXMethodDecl>(FD)) {
892 ThisQuals = Method->getMethodQualifiers();
893 Record = const_cast<CXXRecordDecl *>(Method->getParent());
894 }
895 CXXThisScopeRAII ThisScope(*this, Record, ThisQuals, Record != nullptr);
896
898 *this, const_cast<FunctionDecl *>(FD), *MLTAL, Scope,
899 ForOverloadResolution);
900
902 FD, {FD->getTrailingRequiresClause()}, *MLTAL,
903 SourceRange(UsageLoc.isValid() ? UsageLoc : FD->getLocation()),
904 Satisfaction);
905}
906
907
908// Figure out the to-translation-unit depth for this function declaration for
909// the purpose of seeing if they differ by constraints. This isn't the same as
910// getTemplateDepth, because it includes already instantiated parents.
911static unsigned
913 bool SkipForSpecialization = false) {
915 ND, ND->getLexicalDeclContext(), /*Final=*/false,
916 /*Innermost=*/std::nullopt,
917 /*RelativeToPrimary=*/true,
918 /*Pattern=*/nullptr,
919 /*ForConstraintInstantiation=*/true, SkipForSpecialization);
920 return MLTAL.getNumLevels();
921}
922
923namespace {
924 class AdjustConstraintDepth : public TreeTransform<AdjustConstraintDepth> {
925 unsigned TemplateDepth = 0;
926 public:
927 using inherited = TreeTransform<AdjustConstraintDepth>;
928 AdjustConstraintDepth(Sema &SemaRef, unsigned TemplateDepth)
929 : inherited(SemaRef), TemplateDepth(TemplateDepth) {}
930
931 using inherited::TransformTemplateTypeParmType;
932 QualType TransformTemplateTypeParmType(TypeLocBuilder &TLB,
933 TemplateTypeParmTypeLoc TL, bool) {
934 const TemplateTypeParmType *T = TL.getTypePtr();
935
936 TemplateTypeParmDecl *NewTTPDecl = nullptr;
937 if (TemplateTypeParmDecl *OldTTPDecl = T->getDecl())
938 NewTTPDecl = cast_or_null<TemplateTypeParmDecl>(
939 TransformDecl(TL.getNameLoc(), OldTTPDecl));
940
941 QualType Result = getSema().Context.getTemplateTypeParmType(
942 T->getDepth() + TemplateDepth, T->getIndex(), T->isParameterPack(),
943 NewTTPDecl);
945 NewTL.setNameLoc(TL.getNameLoc());
946 return Result;
947 }
948 };
949} // namespace
950
952 Sema &S, const Sema::TemplateCompareNewDeclInfo &DeclInfo,
953 const Expr *ConstrExpr) {
955 DeclInfo.getDecl(), DeclInfo.getLexicalDeclContext(), /*Final=*/false,
956 /*Innermost=*/std::nullopt,
957 /*RelativeToPrimary=*/true,
958 /*Pattern=*/nullptr, /*ForConstraintInstantiation=*/true,
959 /*SkipForSpecialization*/ false);
960
961 if (MLTAL.getNumSubstitutedLevels() == 0)
962 return ConstrExpr;
963
964 Sema::SFINAETrap SFINAE(S, /*AccessCheckingSFINAE=*/false);
965
967 S, DeclInfo.getLocation(),
969 const_cast<NamedDecl *>(DeclInfo.getDecl()), SourceRange{});
970 if (Inst.isInvalid())
971 return nullptr;
972
973 // Set up a dummy 'instantiation' scope in the case of reference to function
974 // parameters that the surrounding function hasn't been instantiated yet. Note
975 // this may happen while we're comparing two templates' constraint
976 // equivalence.
977 std::optional<LocalInstantiationScope> ScopeForParameters;
978 if (const NamedDecl *ND = DeclInfo.getDecl();
979 ND && ND->isFunctionOrFunctionTemplate()) {
980 ScopeForParameters.emplace(S, /*CombineWithOuterScope=*/true);
981 const FunctionDecl *FD = ND->getAsFunction();
982 for (auto *PVD : FD->parameters()) {
983 if (!PVD->isParameterPack()) {
984 ScopeForParameters->InstantiatedLocal(PVD, PVD);
985 continue;
986 }
987 // This is hacky: we're mapping the parameter pack to a size-of-1 argument
988 // to avoid building SubstTemplateTypeParmPackTypes for
989 // PackExpansionTypes. The SubstTemplateTypeParmPackType node would
990 // otherwise reference the AssociatedDecl of the template arguments, which
991 // is, in this case, the template declaration.
992 //
993 // However, as we are in the process of comparing potential
994 // re-declarations, the canonical declaration is the declaration itself at
995 // this point. So if we didn't expand these packs, we would end up with an
996 // incorrect profile difference because we will be profiling the
997 // canonical types!
998 //
999 // FIXME: Improve the "no-transform" machinery in FindInstantiatedDecl so
1000 // that we can eliminate the Scope in the cases where the declarations are
1001 // not necessarily instantiated. It would also benefit the noexcept
1002 // specifier comparison.
1003 ScopeForParameters->MakeInstantiatedLocalArgPack(PVD);
1004 ScopeForParameters->InstantiatedLocalPackArg(PVD, PVD);
1005 }
1006 }
1007
1008 std::optional<Sema::CXXThisScopeRAII> ThisScope;
1009
1010 // See TreeTransform::RebuildTemplateSpecializationType. A context scope is
1011 // essential for having an injected class as the canonical type for a template
1012 // specialization type at the rebuilding stage. This guarantees that, for
1013 // out-of-line definitions, injected class name types and their equivalent
1014 // template specializations can be profiled to the same value, which makes it
1015 // possible that e.g. constraints involving C<Class<T>> and C<Class> are
1016 // perceived identical.
1017 std::optional<Sema::ContextRAII> ContextScope;
1018 const DeclContext *DC = [&] {
1019 if (!DeclInfo.getDecl())
1020 return DeclInfo.getDeclContext();
1021 return DeclInfo.getDecl()->getFriendObjectKind()
1022 ? DeclInfo.getLexicalDeclContext()
1023 : DeclInfo.getDeclContext();
1024 }();
1025 if (auto *RD = dyn_cast<CXXRecordDecl>(DC)) {
1026 ThisScope.emplace(S, const_cast<CXXRecordDecl *>(RD), Qualifiers());
1027 ContextScope.emplace(S, const_cast<DeclContext *>(cast<DeclContext>(RD)),
1028 /*NewThisContext=*/false);
1029 }
1031 const_cast<clang::Expr *>(ConstrExpr), MLTAL);
1032 if (SFINAE.hasErrorOccurred() || !SubstConstr.isUsable())
1033 return nullptr;
1034 return SubstConstr.get();
1035}
1036
1038 const Expr *OldConstr,
1039 const TemplateCompareNewDeclInfo &New,
1040 const Expr *NewConstr) {
1041 if (OldConstr == NewConstr)
1042 return true;
1043 // C++ [temp.constr.decl]p4
1044 if (Old && !New.isInvalid() && !New.ContainsDecl(Old) &&
1046 if (const Expr *SubstConstr =
1048 OldConstr))
1049 OldConstr = SubstConstr;
1050 else
1051 return false;
1052 if (const Expr *SubstConstr =
1054 NewConstr))
1055 NewConstr = SubstConstr;
1056 else
1057 return false;
1058 }
1059
1060 llvm::FoldingSetNodeID ID1, ID2;
1061 OldConstr->Profile(ID1, Context, /*Canonical=*/true);
1062 NewConstr->Profile(ID2, Context, /*Canonical=*/true);
1063 return ID1 == ID2;
1064}
1065
1067 assert(FD->getFriendObjectKind() && "Must be a friend!");
1068
1069 // The logic for non-templates is handled in ASTContext::isSameEntity, so we
1070 // don't have to bother checking 'DependsOnEnclosingTemplate' for a
1071 // non-function-template.
1072 assert(FD->getDescribedFunctionTemplate() &&
1073 "Non-function templates don't need to be checked");
1074
1077
1078 unsigned OldTemplateDepth = CalculateTemplateDepthForConstraints(*this, FD);
1079 for (const Expr *Constraint : ACs)
1080 if (ConstraintExpressionDependsOnEnclosingTemplate(FD, OldTemplateDepth,
1081 Constraint))
1082 return true;
1083
1084 return false;
1085}
1086
1088 TemplateDecl *TD, const MultiLevelTemplateArgumentList &TemplateArgsLists,
1089 SourceRange TemplateIDRange) {
1090 ConstraintSatisfaction Satisfaction;
1091 llvm::SmallVector<const Expr *, 3> AssociatedConstraints;
1092 TD->getAssociatedConstraints(AssociatedConstraints);
1093 if (CheckConstraintSatisfaction(TD, AssociatedConstraints, TemplateArgsLists,
1094 TemplateIDRange, Satisfaction))
1095 return true;
1096
1097 if (!Satisfaction.IsSatisfied) {
1098 SmallString<128> TemplateArgString;
1099 TemplateArgString = " ";
1100 TemplateArgString += getTemplateArgumentBindingsText(
1101 TD->getTemplateParameters(), TemplateArgsLists.getInnermost().data(),
1102 TemplateArgsLists.getInnermost().size());
1103
1104 Diag(TemplateIDRange.getBegin(),
1105 diag::err_template_arg_list_constraints_not_satisfied)
1107 << TemplateArgString << TemplateIDRange;
1108 DiagnoseUnsatisfiedConstraint(Satisfaction);
1109 return true;
1110 }
1111 return false;
1112}
1113
1115 Sema &SemaRef, SourceLocation PointOfInstantiation,
1116 FunctionTemplateDecl *Template, ArrayRef<TemplateArgument> TemplateArgs,
1117 ConstraintSatisfaction &Satisfaction) {
1119 Template->getAssociatedConstraints(TemplateAC);
1120 if (TemplateAC.empty()) {
1121 Satisfaction.IsSatisfied = true;
1122 return false;
1123 }
1124
1126
1127 FunctionDecl *FD = Template->getTemplatedDecl();
1128 // Collect the list of template arguments relative to the 'primary'
1129 // template. We need the entire list, since the constraint is completely
1130 // uninstantiated at this point.
1131
1132 // FIXME: Add TemplateArgs through the 'Innermost' parameter once
1133 // the refactoring of getTemplateInstantiationArgs() relands.
1135 MLTAL.addOuterTemplateArguments(Template, std::nullopt, /*Final=*/false);
1137 MLTAL, /*D=*/FD, FD,
1138 /*Final=*/false, /*Innermost=*/std::nullopt, /*RelativeToPrimary=*/true,
1139 /*Pattern=*/nullptr, /*ForConstraintInstantiation=*/true);
1140 MLTAL.replaceInnermostTemplateArguments(Template, TemplateArgs);
1141
1142 Sema::ContextRAII SavedContext(SemaRef, FD);
1143 std::optional<Sema::CXXThisScopeRAII> ThisScope;
1144 if (auto *Method = dyn_cast<CXXMethodDecl>(FD))
1145 ThisScope.emplace(SemaRef, /*Record=*/Method->getParent(),
1146 /*ThisQuals=*/Method->getMethodQualifiers());
1147 return SemaRef.CheckConstraintSatisfaction(
1148 Template, TemplateAC, MLTAL, PointOfInstantiation, Satisfaction);
1149}
1150
1152 SourceLocation PointOfInstantiation, FunctionDecl *Decl,
1153 ArrayRef<TemplateArgument> TemplateArgs,
1154 ConstraintSatisfaction &Satisfaction) {
1155 // In most cases we're not going to have constraints, so check for that first.
1156 FunctionTemplateDecl *Template = Decl->getPrimaryTemplate();
1157
1158 if (!Template)
1159 return ::CheckFunctionConstraintsWithoutInstantiation(
1160 *this, PointOfInstantiation, Decl->getDescribedFunctionTemplate(),
1161 TemplateArgs, Satisfaction);
1162
1163 // Note - code synthesis context for the constraints check is created
1164 // inside CheckConstraintsSatisfaction.
1166 Template->getAssociatedConstraints(TemplateAC);
1167 if (TemplateAC.empty()) {
1168 Satisfaction.IsSatisfied = true;
1169 return false;
1170 }
1171
1172 // Enter the scope of this instantiation. We don't use
1173 // PushDeclContext because we don't have a scope.
1174 Sema::ContextRAII savedContext(*this, Decl);
1176
1177 std::optional<MultiLevelTemplateArgumentList> MLTAL =
1178 SetupConstraintCheckingTemplateArgumentsAndScope(Decl, TemplateArgs,
1179 Scope);
1180
1181 if (!MLTAL)
1182 return true;
1183
1184 Qualifiers ThisQuals;
1185 CXXRecordDecl *Record = nullptr;
1186 if (auto *Method = dyn_cast<CXXMethodDecl>(Decl)) {
1187 ThisQuals = Method->getMethodQualifiers();
1188 Record = Method->getParent();
1189 }
1190
1191 CXXThisScopeRAII ThisScope(*this, Record, ThisQuals, Record != nullptr);
1193 *this, const_cast<FunctionDecl *>(Decl), *MLTAL, Scope);
1194
1196 return CheckConstraintSatisfaction(Template, TemplateAC, Converted, *MLTAL,
1197 PointOfInstantiation, Satisfaction);
1198}
1199
1202 bool First) {
1203 assert(!Req->isSatisfied()
1204 && "Diagnose() can only be used on an unsatisfied requirement");
1205 switch (Req->getSatisfactionStatus()) {
1207 llvm_unreachable("Diagnosing a dependent requirement");
1208 break;
1210 auto *SubstDiag = Req->getExprSubstitutionDiagnostic();
1211 if (!SubstDiag->DiagMessage.empty())
1212 S.Diag(SubstDiag->DiagLoc,
1213 diag::note_expr_requirement_expr_substitution_error)
1214 << (int)First << SubstDiag->SubstitutedEntity
1215 << SubstDiag->DiagMessage;
1216 else
1217 S.Diag(SubstDiag->DiagLoc,
1218 diag::note_expr_requirement_expr_unknown_substitution_error)
1219 << (int)First << SubstDiag->SubstitutedEntity;
1220 break;
1221 }
1223 S.Diag(Req->getNoexceptLoc(),
1224 diag::note_expr_requirement_noexcept_not_met)
1225 << (int)First << Req->getExpr();
1226 break;
1228 auto *SubstDiag =
1230 if (!SubstDiag->DiagMessage.empty())
1231 S.Diag(SubstDiag->DiagLoc,
1232 diag::note_expr_requirement_type_requirement_substitution_error)
1233 << (int)First << SubstDiag->SubstitutedEntity
1234 << SubstDiag->DiagMessage;
1235 else
1236 S.Diag(SubstDiag->DiagLoc,
1237 diag::note_expr_requirement_type_requirement_unknown_substitution_error)
1238 << (int)First << SubstDiag->SubstitutedEntity;
1239 break;
1240 }
1242 ConceptSpecializationExpr *ConstraintExpr =
1244 if (ConstraintExpr->getTemplateArgsAsWritten()->NumTemplateArgs == 1) {
1245 // A simple case - expr type is the type being constrained and the concept
1246 // was not provided arguments.
1247 Expr *e = Req->getExpr();
1248 S.Diag(e->getBeginLoc(),
1249 diag::note_expr_requirement_constraints_not_satisfied_simple)
1251 << ConstraintExpr->getNamedConcept();
1252 } else {
1253 S.Diag(ConstraintExpr->getBeginLoc(),
1254 diag::note_expr_requirement_constraints_not_satisfied)
1255 << (int)First << ConstraintExpr;
1256 }
1258 break;
1259 }
1261 llvm_unreachable("We checked this above");
1262 }
1263}
1264
1267 bool First) {
1268 assert(!Req->isSatisfied()
1269 && "Diagnose() can only be used on an unsatisfied requirement");
1270 switch (Req->getSatisfactionStatus()) {
1272 llvm_unreachable("Diagnosing a dependent requirement");
1273 return;
1275 auto *SubstDiag = Req->getSubstitutionDiagnostic();
1276 if (!SubstDiag->DiagMessage.empty())
1277 S.Diag(SubstDiag->DiagLoc,
1278 diag::note_type_requirement_substitution_error) << (int)First
1279 << SubstDiag->SubstitutedEntity << SubstDiag->DiagMessage;
1280 else
1281 S.Diag(SubstDiag->DiagLoc,
1282 diag::note_type_requirement_unknown_substitution_error)
1283 << (int)First << SubstDiag->SubstitutedEntity;
1284 return;
1285 }
1286 default:
1287 llvm_unreachable("Unknown satisfaction status");
1288 return;
1289 }
1290}
1292 Expr *SubstExpr,
1293 bool First = true);
1294
1297 bool First) {
1298 using SubstitutionDiagnostic = std::pair<SourceLocation, StringRef>;
1299 for (auto &Record : Req->getConstraintSatisfaction()) {
1300 if (auto *SubstDiag = Record.dyn_cast<SubstitutionDiagnostic *>())
1301 S.Diag(SubstDiag->first, diag::note_nested_requirement_substitution_error)
1303 << SubstDiag->second;
1304 else
1306 First);
1307 First = false;
1308 }
1309}
1310
1312 Expr *SubstExpr,
1313 bool First) {
1314 SubstExpr = SubstExpr->IgnoreParenImpCasts();
1315 if (BinaryOperator *BO = dyn_cast<BinaryOperator>(SubstExpr)) {
1316 switch (BO->getOpcode()) {
1317 // These two cases will in practice only be reached when using fold
1318 // expressions with || and &&, since otherwise the || and && will have been
1319 // broken down into atomic constraints during satisfaction checking.
1320 case BO_LOr:
1321 // Or evaluated to false - meaning both RHS and LHS evaluated to false.
1324 /*First=*/false);
1325 return;
1326 case BO_LAnd: {
1327 bool LHSSatisfied =
1328 BO->getLHS()->EvaluateKnownConstInt(S.Context).getBoolValue();
1329 if (LHSSatisfied) {
1330 // LHS is true, so RHS must be false.
1332 return;
1333 }
1334 // LHS is false
1336
1337 // RHS might also be false
1338 bool RHSSatisfied =
1339 BO->getRHS()->EvaluateKnownConstInt(S.Context).getBoolValue();
1340 if (!RHSSatisfied)
1342 /*First=*/false);
1343 return;
1344 }
1345 case BO_GE:
1346 case BO_LE:
1347 case BO_GT:
1348 case BO_LT:
1349 case BO_EQ:
1350 case BO_NE:
1351 if (BO->getLHS()->getType()->isIntegerType() &&
1352 BO->getRHS()->getType()->isIntegerType()) {
1353 Expr::EvalResult SimplifiedLHS;
1354 Expr::EvalResult SimplifiedRHS;
1355 BO->getLHS()->EvaluateAsInt(SimplifiedLHS, S.Context,
1357 /*InConstantContext=*/true);
1358 BO->getRHS()->EvaluateAsInt(SimplifiedRHS, S.Context,
1360 /*InConstantContext=*/true);
1361 if (!SimplifiedLHS.Diag && ! SimplifiedRHS.Diag) {
1362 S.Diag(SubstExpr->getBeginLoc(),
1363 diag::note_atomic_constraint_evaluated_to_false_elaborated)
1364 << (int)First << SubstExpr
1365 << toString(SimplifiedLHS.Val.getInt(), 10)
1366 << BinaryOperator::getOpcodeStr(BO->getOpcode())
1367 << toString(SimplifiedRHS.Val.getInt(), 10);
1368 return;
1369 }
1370 }
1371 break;
1372
1373 default:
1374 break;
1375 }
1376 } else if (auto *CSE = dyn_cast<ConceptSpecializationExpr>(SubstExpr)) {
1377 if (CSE->getTemplateArgsAsWritten()->NumTemplateArgs == 1) {
1378 S.Diag(
1379 CSE->getSourceRange().getBegin(),
1380 diag::
1381 note_single_arg_concept_specialization_constraint_evaluated_to_false)
1382 << (int)First
1383 << CSE->getTemplateArgsAsWritten()->arguments()[0].getArgument()
1384 << CSE->getNamedConcept();
1385 } else {
1386 S.Diag(SubstExpr->getSourceRange().getBegin(),
1387 diag::note_concept_specialization_constraint_evaluated_to_false)
1388 << (int)First << CSE;
1389 }
1390 S.DiagnoseUnsatisfiedConstraint(CSE->getSatisfaction());
1391 return;
1392 } else if (auto *RE = dyn_cast<RequiresExpr>(SubstExpr)) {
1393 // FIXME: RequiresExpr should store dependent diagnostics.
1394 for (concepts::Requirement *Req : RE->getRequirements())
1395 if (!Req->isDependent() && !Req->isSatisfied()) {
1396 if (auto *E = dyn_cast<concepts::ExprRequirement>(Req))
1398 else if (auto *T = dyn_cast<concepts::TypeRequirement>(Req))
1400 else
1402 S, cast<concepts::NestedRequirement>(Req), First);
1403 break;
1404 }
1405 return;
1406 } else if (auto *TTE = dyn_cast<TypeTraitExpr>(SubstExpr);
1407 TTE && TTE->getTrait() == clang::TypeTrait::BTT_IsDeducible) {
1408 assert(TTE->getNumArgs() == 2);
1409 S.Diag(SubstExpr->getSourceRange().getBegin(),
1410 diag::note_is_deducible_constraint_evaluated_to_false)
1411 << TTE->getArg(0)->getType() << TTE->getArg(1)->getType();
1412 return;
1413 }
1414
1415 S.Diag(SubstExpr->getSourceRange().getBegin(),
1416 diag::note_atomic_constraint_evaluated_to_false)
1417 << (int)First << SubstExpr;
1418}
1419
1420template <typename SubstitutionDiagnostic>
1422 Sema &S, const llvm::PointerUnion<Expr *, SubstitutionDiagnostic *> &Record,
1423 bool First = true) {
1424 if (auto *Diag = Record.template dyn_cast<SubstitutionDiagnostic *>()) {
1425 S.Diag(Diag->first, diag::note_substituted_constraint_expr_is_ill_formed)
1426 << Diag->second;
1427 return;
1428 }
1429
1431}
1432
1433void
1435 bool First) {
1436 assert(!Satisfaction.IsSatisfied &&
1437 "Attempted to diagnose a satisfied constraint");
1438 for (auto &Record : Satisfaction.Details) {
1440 First = false;
1441 }
1442}
1443
1445 const ASTConstraintSatisfaction &Satisfaction,
1446 bool First) {
1447 assert(!Satisfaction.IsSatisfied &&
1448 "Attempted to diagnose a satisfied constraint");
1449 for (auto &Record : Satisfaction) {
1451 First = false;
1452 }
1453}
1454
1457 NamedDecl *ConstrainedDecl, ArrayRef<const Expr *> AssociatedConstraints) {
1458 // In case the ConstrainedDecl comes from modules, it is necessary to use
1459 // the canonical decl to avoid different atomic constraints with the 'same'
1460 // declarations.
1461 ConstrainedDecl = cast<NamedDecl>(ConstrainedDecl->getCanonicalDecl());
1462
1463 auto CacheEntry = NormalizationCache.find(ConstrainedDecl);
1464 if (CacheEntry == NormalizationCache.end()) {
1465 auto Normalized =
1466 NormalizedConstraint::fromConstraintExprs(*this, ConstrainedDecl,
1467 AssociatedConstraints);
1468 CacheEntry =
1469 NormalizationCache
1470 .try_emplace(ConstrainedDecl,
1471 Normalized
1473 std::move(*Normalized))
1474 : nullptr)
1475 .first;
1476 }
1477 return CacheEntry->second;
1478}
1479
1481 Sema &S, NamedDecl *ConstrainedDecl,
1482 ArrayRef<const Expr *> AssociatedConstraints) {
1483 return S.getNormalizedAssociatedConstraints(ConstrainedDecl,
1484 AssociatedConstraints);
1485}
1486
1487static bool
1489 ConceptDecl *Concept,
1490 const MultiLevelTemplateArgumentList &MLTAL,
1491 const ASTTemplateArgumentListInfo *ArgsAsWritten) {
1492
1493 if (N.isCompound()) {
1494 if (substituteParameterMappings(S, N.getLHS(), Concept, MLTAL,
1495 ArgsAsWritten))
1496 return true;
1497 return substituteParameterMappings(S, N.getRHS(), Concept, MLTAL,
1498 ArgsAsWritten);
1499 }
1500
1501 if (N.isFoldExpanded()) {
1504 S, N.getFoldExpandedConstraint()->Constraint, Concept, MLTAL,
1505 ArgsAsWritten);
1506 }
1507
1508 TemplateParameterList *TemplateParams = Concept->getTemplateParameters();
1509
1511 TemplateArgumentListInfo SubstArgs;
1512 if (!Atomic.ParameterMapping) {
1513 llvm::SmallBitVector OccurringIndices(TemplateParams->size());
1514 S.MarkUsedTemplateParameters(Atomic.ConstraintExpr, /*OnlyDeduced=*/false,
1515 /*Depth=*/0, OccurringIndices);
1516 TemplateArgumentLoc *TempArgs =
1517 new (S.Context) TemplateArgumentLoc[OccurringIndices.count()];
1518 for (unsigned I = 0, J = 0, C = TemplateParams->size(); I != C; ++I)
1519 if (OccurringIndices[I])
1520 new (&(TempArgs)[J++])
1522 TemplateParams->begin()[I],
1523 // Here we assume we do not support things like
1524 // template<typename A, typename B>
1525 // concept C = ...;
1526 //
1527 // template<typename... Ts> requires C<Ts...>
1528 // struct S { };
1529 // The above currently yields a diagnostic.
1530 // We still might have default arguments for concept parameters.
1531 ArgsAsWritten->NumTemplateArgs > I
1532 ? ArgsAsWritten->arguments()[I].getLocation()
1533 : SourceLocation()));
1534 Atomic.ParameterMapping.emplace(TempArgs, OccurringIndices.count());
1535 }
1536 SourceLocation InstLocBegin =
1537 ArgsAsWritten->arguments().empty()
1538 ? ArgsAsWritten->getLAngleLoc()
1539 : ArgsAsWritten->arguments().front().getSourceRange().getBegin();
1540 SourceLocation InstLocEnd =
1541 ArgsAsWritten->arguments().empty()
1542 ? ArgsAsWritten->getRAngleLoc()
1543 : ArgsAsWritten->arguments().front().getSourceRange().getEnd();
1545 S, InstLocBegin,
1547 Atomic.ConstraintDecl, {InstLocBegin, InstLocEnd});
1548 if (Inst.isInvalid())
1549 return true;
1550 if (S.SubstTemplateArguments(*Atomic.ParameterMapping, MLTAL, SubstArgs))
1551 return true;
1552
1553 TemplateArgumentLoc *TempArgs =
1554 new (S.Context) TemplateArgumentLoc[SubstArgs.size()];
1555 std::copy(SubstArgs.arguments().begin(), SubstArgs.arguments().end(),
1556 TempArgs);
1557 Atomic.ParameterMapping.emplace(TempArgs, SubstArgs.size());
1558 return false;
1559}
1560
1562 const ConceptSpecializationExpr *CSE) {
1565 /*Final=*/false, CSE->getTemplateArguments(),
1566 /*RelativeToPrimary=*/true,
1567 /*Pattern=*/nullptr,
1568 /*ForConstraintInstantiation=*/true);
1569
1570 return substituteParameterMappings(S, N, CSE->getNamedConcept(), MLTAL,
1572}
1573
1578 : Constraint{CompoundConstraint{
1579 new(C) NormalizedConstraintPair{std::move(LHS), std::move(RHS)},
1580 Kind}} {}
1581
1583 const NormalizedConstraint &Other) {
1584 if (Other.isAtomic()) {
1585 Constraint = new (C) AtomicConstraint(*Other.getAtomicConstraint());
1586 } else if (Other.isFoldExpanded()) {
1588 Other.getFoldExpandedConstraint()->Kind,
1589 NormalizedConstraint(C, Other.getFoldExpandedConstraint()->Constraint),
1590 Other.getFoldExpandedConstraint()->Pattern);
1591 } else {
1593 new (C)
1595 NormalizedConstraint(C, Other.getRHS())},
1596 Other.getCompoundKind());
1597 }
1598}
1599
1601 assert(isCompound() && "getLHS called on a non-compound constraint.");
1602 return cast<CompoundConstraint>(Constraint).getPointer()->LHS;
1603}
1604
1606 assert(isCompound() && "getRHS called on a non-compound constraint.");
1607 return cast<CompoundConstraint>(Constraint).getPointer()->RHS;
1608}
1609
1610std::optional<NormalizedConstraint>
1611NormalizedConstraint::fromConstraintExprs(Sema &S, NamedDecl *D,
1613 assert(E.size() != 0);
1614 auto Conjunction = fromConstraintExpr(S, D, E[0]);
1615 if (!Conjunction)
1616 return std::nullopt;
1617 for (unsigned I = 1; I < E.size(); ++I) {
1618 auto Next = fromConstraintExpr(S, D, E[I]);
1619 if (!Next)
1620 return std::nullopt;
1621 *Conjunction = NormalizedConstraint(S.Context, std::move(*Conjunction),
1622 std::move(*Next), CCK_Conjunction);
1623 }
1624 return Conjunction;
1625}
1626
1627std::optional<NormalizedConstraint>
1628NormalizedConstraint::fromConstraintExpr(Sema &S, NamedDecl *D, const Expr *E) {
1629 assert(E != nullptr);
1630
1631 // C++ [temp.constr.normal]p1.1
1632 // [...]
1633 // - The normal form of an expression (E) is the normal form of E.
1634 // [...]
1635 E = E->IgnoreParenImpCasts();
1636
1637 // C++2a [temp.param]p4:
1638 // [...] If T is not a pack, then E is E', otherwise E is (E' && ...).
1639 // Fold expression is considered atomic constraints per current wording.
1640 // See http://cplusplus.github.io/concepts-ts/ts-active.html#28
1641
1642 if (LogicalBinOp BO = E) {
1643 auto LHS = fromConstraintExpr(S, D, BO.getLHS());
1644 if (!LHS)
1645 return std::nullopt;
1646 auto RHS = fromConstraintExpr(S, D, BO.getRHS());
1647 if (!RHS)
1648 return std::nullopt;
1649
1650 return NormalizedConstraint(S.Context, std::move(*LHS), std::move(*RHS),
1651 BO.isAnd() ? CCK_Conjunction : CCK_Disjunction);
1652 } else if (auto *CSE = dyn_cast<const ConceptSpecializationExpr>(E)) {
1653 const NormalizedConstraint *SubNF;
1654 {
1656 S, CSE->getExprLoc(),
1658 CSE->getSourceRange());
1659 if (Inst.isInvalid())
1660 return std::nullopt;
1661 // C++ [temp.constr.normal]p1.1
1662 // [...]
1663 // The normal form of an id-expression of the form C<A1, A2, ..., AN>,
1664 // where C names a concept, is the normal form of the
1665 // constraint-expression of C, after substituting A1, A2, ..., AN for C’s
1666 // respective template parameters in the parameter mappings in each atomic
1667 // constraint. If any such substitution results in an invalid type or
1668 // expression, the program is ill-formed; no diagnostic is required.
1669 // [...]
1670 ConceptDecl *CD = CSE->getNamedConcept();
1672 {CD->getConstraintExpr()});
1673 if (!SubNF)
1674 return std::nullopt;
1675 }
1676
1677 std::optional<NormalizedConstraint> New;
1678 New.emplace(S.Context, *SubNF);
1679
1680 if (substituteParameterMappings(S, *New, CSE))
1681 return std::nullopt;
1682
1683 return New;
1684 } else if (auto *FE = dyn_cast<const CXXFoldExpr>(E);
1685 FE && S.getLangOpts().CPlusPlus26 &&
1686 (FE->getOperator() == BinaryOperatorKind::BO_LAnd ||
1687 FE->getOperator() == BinaryOperatorKind::BO_LOr)) {
1688
1689 // Normalize fold expressions in C++26.
1690
1692 FE->getOperator() == BinaryOperatorKind::BO_LAnd
1695
1696 if (FE->getInit()) {
1697 auto LHS = fromConstraintExpr(S, D, FE->getLHS());
1698 auto RHS = fromConstraintExpr(S, D, FE->getRHS());
1699 if (!LHS || !RHS)
1700 return std::nullopt;
1701
1702 if (FE->isRightFold())
1704 Kind, std::move(*RHS), FE->getPattern()}};
1705 else
1707 Kind, std::move(*LHS), FE->getPattern()}};
1708
1709 return NormalizedConstraint(
1710 S.Context, std::move(*LHS), std::move(*RHS),
1711 FE->getOperator() == BinaryOperatorKind::BO_LAnd ? CCK_Conjunction
1712 : CCK_Disjunction);
1713 }
1714 auto Sub = fromConstraintExpr(S, D, FE->getPattern());
1715 if (!Sub)
1716 return std::nullopt;
1718 Kind, std::move(*Sub), FE->getPattern()}};
1719 }
1720
1722}
1723
1726
1727 // [C++26] [temp.constr.fold]
1728 // Two fold expanded constraints are compatible for subsumption
1729 // if their respective constraints both contain an equivalent unexpanded pack.
1730
1732 Sema::collectUnexpandedParameterPacks(const_cast<Expr *>(A.Pattern), APacks);
1733 Sema::collectUnexpandedParameterPacks(const_cast<Expr *>(B.Pattern), BPacks);
1734
1735 for (const UnexpandedParameterPack &APack : APacks) {
1736 std::pair<unsigned, unsigned> DepthAndIndex = getDepthAndIndex(APack);
1737 auto it = llvm::find_if(BPacks, [&](const UnexpandedParameterPack &BPack) {
1738 return getDepthAndIndex(BPack) == DepthAndIndex;
1739 });
1740 if (it != BPacks.end())
1741 return true;
1742 }
1743 return false;
1744}
1745
1747 if (Normalized.isAtomic())
1748 return {{Normalized.getAtomicConstraint()}};
1749
1750 else if (Normalized.isFoldExpanded())
1751 return {{Normalized.getFoldExpandedConstraint()}};
1752
1753 NormalForm LCNF = makeCNF(Normalized.getLHS());
1754 NormalForm RCNF = makeCNF(Normalized.getRHS());
1756 LCNF.reserve(LCNF.size() + RCNF.size());
1757 while (!RCNF.empty())
1758 LCNF.push_back(RCNF.pop_back_val());
1759 return LCNF;
1760 }
1761
1762 // Disjunction
1763 NormalForm Res;
1764 Res.reserve(LCNF.size() * RCNF.size());
1765 for (auto &LDisjunction : LCNF)
1766 for (auto &RDisjunction : RCNF) {
1767 NormalForm::value_type Combined;
1768 Combined.reserve(LDisjunction.size() + RDisjunction.size());
1769 std::copy(LDisjunction.begin(), LDisjunction.end(),
1770 std::back_inserter(Combined));
1771 std::copy(RDisjunction.begin(), RDisjunction.end(),
1772 std::back_inserter(Combined));
1773 Res.emplace_back(Combined);
1774 }
1775 return Res;
1776}
1777
1779 if (Normalized.isAtomic())
1780 return {{Normalized.getAtomicConstraint()}};
1781
1782 else if (Normalized.isFoldExpanded())
1783 return {{Normalized.getFoldExpandedConstraint()}};
1784
1785 NormalForm LDNF = makeDNF(Normalized.getLHS());
1786 NormalForm RDNF = makeDNF(Normalized.getRHS());
1788 LDNF.reserve(LDNF.size() + RDNF.size());
1789 while (!RDNF.empty())
1790 LDNF.push_back(RDNF.pop_back_val());
1791 return LDNF;
1792 }
1793
1794 // Conjunction
1795 NormalForm Res;
1796 Res.reserve(LDNF.size() * RDNF.size());
1797 for (auto &LConjunction : LDNF) {
1798 for (auto &RConjunction : RDNF) {
1799 NormalForm::value_type Combined;
1800 Combined.reserve(LConjunction.size() + RConjunction.size());
1801 std::copy(LConjunction.begin(), LConjunction.end(),
1802 std::back_inserter(Combined));
1803 std::copy(RConjunction.begin(), RConjunction.end(),
1804 std::back_inserter(Combined));
1805 Res.emplace_back(Combined);
1806 }
1807 }
1808 return Res;
1809}
1810
1813 NamedDecl *D2,
1815 bool &Result) {
1816 if (const auto *FD1 = dyn_cast<FunctionDecl>(D1)) {
1817 auto IsExpectedEntity = [](const FunctionDecl *FD) {
1819 return Kind == FunctionDecl::TK_NonTemplate ||
1821 };
1822 const auto *FD2 = dyn_cast<FunctionDecl>(D2);
1823 (void)IsExpectedEntity;
1824 (void)FD1;
1825 (void)FD2;
1826 assert(IsExpectedEntity(FD1) && FD2 && IsExpectedEntity(FD2) &&
1827 "use non-instantiated function declaration for constraints partial "
1828 "ordering");
1829 }
1830
1831 if (AC1.empty()) {
1832 Result = AC2.empty();
1833 return false;
1834 }
1835 if (AC2.empty()) {
1836 // TD1 has associated constraints and TD2 does not.
1837 Result = true;
1838 return false;
1839 }
1840
1841 std::pair<NamedDecl *, NamedDecl *> Key{D1, D2};
1842 auto CacheEntry = SubsumptionCache.find(Key);
1843 if (CacheEntry != SubsumptionCache.end()) {
1844 Result = CacheEntry->second;
1845 return false;
1846 }
1847
1848 unsigned Depth1 = CalculateTemplateDepthForConstraints(*this, D1, true);
1849 unsigned Depth2 = CalculateTemplateDepthForConstraints(*this, D2, true);
1850
1851 for (size_t I = 0; I != AC1.size() && I != AC2.size(); ++I) {
1852 if (Depth2 > Depth1) {
1853 AC1[I] = AdjustConstraintDepth(*this, Depth2 - Depth1)
1854 .TransformExpr(const_cast<Expr *>(AC1[I]))
1855 .get();
1856 } else if (Depth1 > Depth2) {
1857 AC2[I] = AdjustConstraintDepth(*this, Depth1 - Depth2)
1858 .TransformExpr(const_cast<Expr *>(AC2[I]))
1859 .get();
1860 }
1861 }
1862
1863 if (clang::subsumes(
1864 *this, D1, AC1, D2, AC2, Result,
1865 [this](const AtomicConstraint &A, const AtomicConstraint &B) {
1866 return A.subsumes(Context, B);
1867 }))
1868 return true;
1869 SubsumptionCache.try_emplace(Key, Result);
1870 return false;
1871}
1872
1875 if (isSFINAEContext())
1876 // No need to work here because our notes would be discarded.
1877 return false;
1878
1879 if (AC1.empty() || AC2.empty())
1880 return false;
1881
1882 auto NormalExprEvaluator =
1883 [this] (const AtomicConstraint &A, const AtomicConstraint &B) {
1884 return A.subsumes(Context, B);
1885 };
1886
1887 const Expr *AmbiguousAtomic1 = nullptr, *AmbiguousAtomic2 = nullptr;
1888 auto IdenticalExprEvaluator =
1889 [&] (const AtomicConstraint &A, const AtomicConstraint &B) {
1891 return false;
1892 const Expr *EA = A.ConstraintExpr, *EB = B.ConstraintExpr;
1893 if (EA == EB)
1894 return true;
1895
1896 // Not the same source level expression - are the expressions
1897 // identical?
1898 llvm::FoldingSetNodeID IDA, IDB;
1899 EA->Profile(IDA, Context, /*Canonical=*/true);
1900 EB->Profile(IDB, Context, /*Canonical=*/true);
1901 if (IDA != IDB)
1902 return false;
1903
1904 AmbiguousAtomic1 = EA;
1905 AmbiguousAtomic2 = EB;
1906 return true;
1907 };
1908
1909 {
1910 // The subsumption checks might cause diagnostics
1911 SFINAETrap Trap(*this);
1912 auto *Normalized1 = getNormalizedAssociatedConstraints(D1, AC1);
1913 if (!Normalized1)
1914 return false;
1915 const NormalForm DNF1 = makeDNF(*Normalized1);
1916 const NormalForm CNF1 = makeCNF(*Normalized1);
1917
1918 auto *Normalized2 = getNormalizedAssociatedConstraints(D2, AC2);
1919 if (!Normalized2)
1920 return false;
1921 const NormalForm DNF2 = makeDNF(*Normalized2);
1922 const NormalForm CNF2 = makeCNF(*Normalized2);
1923
1924 bool Is1AtLeastAs2Normally =
1925 clang::subsumes(DNF1, CNF2, NormalExprEvaluator);
1926 bool Is2AtLeastAs1Normally =
1927 clang::subsumes(DNF2, CNF1, NormalExprEvaluator);
1928 bool Is1AtLeastAs2 = clang::subsumes(DNF1, CNF2, IdenticalExprEvaluator);
1929 bool Is2AtLeastAs1 = clang::subsumes(DNF2, CNF1, IdenticalExprEvaluator);
1930 if (Is1AtLeastAs2 == Is1AtLeastAs2Normally &&
1931 Is2AtLeastAs1 == Is2AtLeastAs1Normally)
1932 // Same result - no ambiguity was caused by identical atomic expressions.
1933 return false;
1934 }
1935
1936 // A different result! Some ambiguous atomic constraint(s) caused a difference
1937 assert(AmbiguousAtomic1 && AmbiguousAtomic2);
1938
1939 Diag(AmbiguousAtomic1->getBeginLoc(), diag::note_ambiguous_atomic_constraints)
1940 << AmbiguousAtomic1->getSourceRange();
1941 Diag(AmbiguousAtomic2->getBeginLoc(),
1942 diag::note_ambiguous_atomic_constraints_similar_expression)
1943 << AmbiguousAtomic2->getSourceRange();
1944 return true;
1945}
1946
1948 Expr *E, bool IsSimple, SourceLocation NoexceptLoc,
1950 ConceptSpecializationExpr *SubstitutedConstraintExpr) :
1951 Requirement(IsSimple ? RK_Simple : RK_Compound, Status == SS_Dependent,
1952 Status == SS_Dependent &&
1953 (E->containsUnexpandedParameterPack() ||
1954 Req.containsUnexpandedParameterPack()),
1955 Status == SS_Satisfied), Value(E), NoexceptLoc(NoexceptLoc),
1956 TypeReq(Req), SubstitutedConstraintExpr(SubstitutedConstraintExpr),
1957 Status(Status) {
1958 assert((!IsSimple || (Req.isEmpty() && NoexceptLoc.isInvalid())) &&
1959 "Simple requirement must not have a return type requirement or a "
1960 "noexcept specification");
1961 assert((Status > SS_TypeRequirementSubstitutionFailure && Req.isTypeConstraint()) ==
1962 (SubstitutedConstraintExpr != nullptr));
1963}
1964
1966 SubstitutionDiagnostic *ExprSubstDiag, bool IsSimple,
1967 SourceLocation NoexceptLoc, ReturnTypeRequirement Req) :
1968 Requirement(IsSimple ? RK_Simple : RK_Compound, Req.isDependent(),
1969 Req.containsUnexpandedParameterPack(), /*IsSatisfied=*/false),
1970 Value(ExprSubstDiag), NoexceptLoc(NoexceptLoc), TypeReq(Req),
1971 Status(SS_ExprSubstitutionFailure) {
1972 assert((!IsSimple || (Req.isEmpty() && NoexceptLoc.isInvalid())) &&
1973 "Simple requirement must not have a return type requirement or a "
1974 "noexcept specification");
1975}
1976
1979 TypeConstraintInfo(TPL, false) {
1980 assert(TPL->size() == 1);
1981 const TypeConstraint *TC =
1982 cast<TemplateTypeParmDecl>(TPL->getParam(0))->getTypeConstraint();
1983 assert(TC &&
1984 "TPL must have a template type parameter with a type constraint");
1985 auto *Constraint =
1986 cast<ConceptSpecializationExpr>(TC->getImmediatelyDeclaredConstraint());
1987 bool Dependent =
1988 Constraint->getTemplateArgsAsWritten() &&
1990 Constraint->getTemplateArgsAsWritten()->arguments().drop_front(1));
1991 TypeConstraintInfo.setInt(Dependent ? true : false);
1992}
1993
1995 Requirement(RK_Type, T->getType()->isInstantiationDependentType(),
1996 T->getType()->containsUnexpandedParameterPack(),
1997 // We reach this ctor with either dependent types (in which
1998 // IsSatisfied doesn't matter) or with non-dependent type in
1999 // which the existence of the type indicates satisfaction.
2000 /*IsSatisfied=*/true),
2001 Value(T),
2002 Status(T->getType()->isInstantiationDependentType() ? SS_Dependent
2003 : SS_Satisfied) {}
2004
2007 assert(isCompound() && "getCompoundKind on a non-compound constraint..");
2008 return cast<CompoundConstraint>(Constraint).getInt();
2009}
2010
2012 assert(isAtomic() && "getAtomicConstraint called on non-atomic constraint.");
2013 return cast<AtomicConstraint *>(Constraint);
2014}
2015
2018 assert(isFoldExpanded() &&
2019 "getFoldExpandedConstraint called on non-fold-expanded constraint.");
2020 return cast<FoldExpandedConstraint *>(Constraint);
2021}
This file provides some common utility functions for processing Lambda related AST Constructs.
static char ID
Definition: Arena.cpp:183
const Decl * D
Expr * E
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines Expressions and AST nodes for C++2a concepts.
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.
llvm::MachO::Record Record
Definition: MachO.h:31
Defines and computes precedence levels for binary/ternary operators.
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
static bool CheckConstraintSatisfaction(Sema &S, const NamedDecl *Template, ArrayRef< const Expr * > ConstraintExprs, llvm::SmallVectorImpl< Expr * > &Converted, const MultiLevelTemplateArgumentList &TemplateArgsLists, SourceRange TemplateIDRange, ConstraintSatisfaction &Satisfaction)
static const Expr * SubstituteConstraintExpressionWithoutSatisfaction(Sema &S, const Sema::TemplateCompareNewDeclInfo &DeclInfo, const Expr *ConstrExpr)
static ExprResult calculateConstraintSatisfaction(Sema &S, const Expr *ConstraintExpr, ConstraintSatisfaction &Satisfaction, const ConstraintEvaluator &Evaluator)
static bool DiagRecursiveConstraintEval(Sema &S, llvm::FoldingSetNodeID &ID, const NamedDecl *Templ, const Expr *E, const MultiLevelTemplateArgumentList &MLTAL)
static void diagnoseWellFormedUnsatisfiedConstraintExpr(Sema &S, Expr *SubstExpr, bool First=true)
static void diagnoseUnsatisfiedRequirement(Sema &S, concepts::ExprRequirement *Req, bool First)
static bool CheckFunctionConstraintsWithoutInstantiation(Sema &SemaRef, SourceLocation PointOfInstantiation, FunctionTemplateDecl *Template, ArrayRef< TemplateArgument > TemplateArgs, ConstraintSatisfaction &Satisfaction)
static bool substituteParameterMappings(Sema &S, NormalizedConstraint &N, ConceptDecl *Concept, const MultiLevelTemplateArgumentList &MLTAL, const ASTTemplateArgumentListInfo *ArgsAsWritten)
static void diagnoseUnsatisfiedConstraintExpr(Sema &S, const llvm::PointerUnion< Expr *, SubstitutionDiagnostic * > &Record, bool First=true)
static unsigned CalculateTemplateDepthForConstraints(Sema &S, const NamedDecl *ND, bool SkipForSpecialization=false)
SourceLocation Loc
Definition: SemaObjC.cpp:759
static bool isInvalid(LocType Loc, bool *Invalid)
__DEVICE__ void * memcpy(void *__a, const void *__b, size_t __c)
__device__ int
#define bool
Definition: amdgpuintrin.h:20
APSInt & getInt()
Definition: APValue.h:465
bool isInt() const
Definition: APValue.h:443
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:188
QualType getReferenceQualifiedType(const Expr *e) const
getReferenceQualifiedType - Given an expr, will return the type for that expression,...
CanQualType BoolTy
Definition: ASTContext.h:1161
bool hasSameUnqualifiedType(QualType T1, QualType T2) const
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
Definition: ASTContext.h:2763
bool isUnset() const
Definition: Ownership.h:167
PtrTy get() const
Definition: Ownership.h:170
bool isInvalid() const
Definition: Ownership.h:166
bool isUsable() const
Definition: Ownership.h:168
AtomicExpr - Variadic atomic builtins: __atomic_exchange, __atomic_fetch_*, __atomic_load,...
Definition: Expr.h:6678
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: Expr.h:6796
A builtin binary operation expression such as "x + y" or "x <= y".
Definition: Expr.h:3909
static OverloadedOperatorKind getOverloadedOperator(Opcode Opc)
Retrieve the overloaded operator kind that corresponds to the given binary opcode.
Definition: Expr.cpp:2189
StringRef getOpcodeStr() const
Definition: Expr.h:3975
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:4895
static Opcode getOverloadedOpcode(OverloadedOperatorKind OO)
Retrieve the binary opcode that corresponds to the given overloaded operator.
Definition: Expr.cpp:2151
Represents a C++ conversion function within a class.
Definition: DeclCXX.h:2880
Represents a folding of a pack over an operator.
Definition: ExprCXX.h:4846
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: ExprCXX.h:4900
Expr * getInit() const
Get the operand that doesn't contain a pack, for a binary fold.
Definition: ExprCXX.h:4887
std::optional< unsigned > getNumExpansions() const
Definition: ExprCXX.h:4894
SourceLocation getEllipsisLoc() const
Definition: ExprCXX.h:4891
bool isLeftFold() const
Does this produce a left-associated sequence of operators?
Definition: ExprCXX.h:4881
bool isRightFold() const
Does this produce a right-associated sequence of operators?
Definition: ExprCXX.h:4876
Expr * getPattern() const
Get the pattern, that is, the operand that contains an unexpanded pack.
Definition: ExprCXX.h:4884
BinaryOperatorKind getOperator() const
Definition: ExprCXX.h:4892
Represents a C++ struct/union/class.
Definition: DeclCXX.h:258
Declaration of a C++20 concept.
Expr * getConstraintExpr() const
Represents the specialization of a concept - evaluates to a prvalue of type bool.
Definition: ExprConcepts.h:42
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: ExprConcepts.h:143
ArrayRef< TemplateArgument > getTemplateArguments() const
Definition: ExprConcepts.h:81
const ASTTemplateArgumentListInfo * getTemplateArgsAsWritten() const
Definition: ExprConcepts.h:98
const ASTConstraintSatisfaction & getSatisfaction() const
Get elaborated satisfaction info about the template arguments' satisfaction of the named concept.
Definition: ExprConcepts.h:133
ConceptDecl * getNamedConcept() const
Definition: ExprConcepts.h:87
The result of a constraint satisfaction check, containing the necessary information to diagnose an un...
Definition: ASTConcept.h:35
std::pair< SourceLocation, StringRef > SubstitutionDiagnostic
Definition: ASTConcept.h:49
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &C)
Definition: ASTConcept.h:60
llvm::SmallVector< Detail, 4 > Details
The substituted constraint expr, if the template arguments could be substituted into them,...
Definition: ASTConcept.h:58
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition: DeclBase.h:1435
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition: DeclBase.h:2089
bool isTransparentContext() const
isTransparentContext - Determines whether this context is a "transparent" context,...
Definition: DeclBase.cpp:1368
bool isDependentContext() const
Determines whether this context is dependent on a template parameter.
Definition: DeclBase.cpp:1334
DeclContext * getNonTransparentContext()
Definition: DeclBase.cpp:1415
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:86
FriendObjectKind getFriendObjectKind() const
Determines whether this declaration is the object of a friend declaration and, if so,...
Definition: DeclBase.h:1215
bool isFunctionOrFunctionTemplate() const
Whether this declaration is a function or function template.
Definition: DeclBase.h:1108
bool isParameterPack() const
Whether this declaration is a parameter pack.
Definition: DeclBase.cpp:239
FunctionDecl * getAsFunction() LLVM_READONLY
Returns the function itself, or the templated function if this is a function template.
Definition: DeclBase.cpp:246
bool isInvalidDecl() const
Definition: DeclBase.h:591
SourceLocation getLocation() const
Definition: DeclBase.h:442
DeclContext * getLexicalDeclContext()
getLexicalDeclContext - The declaration context where this Decl was lexically declared (LexicalDC).
Definition: DeclBase.h:907
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
Definition: DeclBase.h:967
virtual SourceRange getSourceRange() const LLVM_READONLY
Source range that this declaration covers.
Definition: DeclBase.h:430
Expr * getTrailingRequiresClause()
Get the constraint-expression introduced by the trailing requires-clause in the function/member decla...
Definition: Decl.h:810
RAII object that enters a new expression evaluation context.
This represents one expression.
Definition: Expr.h:110
@ SE_NoSideEffects
Strictly evaluate the expression.
Definition: Expr.h:668
bool isTypeDependent() const
Determines whether the type of this expression depends on.
Definition: Expr.h:192
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
Definition: Expr.cpp:3090
bool containsErrors() const
Whether this expression contains subexpressions which had errors, e.g.
Definition: Expr.h:245
bool isPRValue() const
Definition: Expr.h:278
bool EvaluateAsConstantExpr(EvalResult &Result, const ASTContext &Ctx, ConstantExprKind Kind=ConstantExprKind::Normal) const
Evaluate an expression that is required to be a constant expression.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
Definition: Expr.cpp:277
QualType getType() const
Definition: Expr.h:142
Represents difference between two FPOptions values.
Definition: LangOptions.h:978
Represents a function declaration or definition.
Definition: Decl.h:1935
FunctionTemplateDecl * getDescribedFunctionTemplate() const
Retrieves the function template that is described by this function declaration.
Definition: Decl.cpp:4052
SourceLocation getPointOfInstantiation() const
Retrieve the (first) point of instantiation of a function template specialization or a member of a cl...
Definition: Decl.cpp:4370
ArrayRef< ParmVarDecl * > parameters() const
Definition: Decl.h:2649
FunctionTemplateDecl * getPrimaryTemplate() const
Retrieve the primary template that this function template specialization either specializes or was in...
Definition: Decl.cpp:4172
const TemplateArgumentList * getTemplateSpecializationArgs() const
Retrieve the template arguments used to produce this function template specialization from the primar...
Definition: Decl.cpp:4188
bool isTemplateInstantiation() const
Determines if the given function was instantiated from a function template.
Definition: Decl.cpp:4116
TemplatedKind
The kind of templated function a FunctionDecl can be.
Definition: Decl.h:1940
@ TK_MemberSpecialization
Definition: Decl.h:1947
@ TK_DependentNonTemplate
Definition: Decl.h:1956
@ TK_FunctionTemplateSpecialization
Definition: Decl.h:1951
TemplatedKind getTemplatedKind() const
What kind of templated function this is.
Definition: Decl.cpp:4003
FunctionDecl * getInstantiatedFromDecl() const
Definition: Decl.cpp:4076
FunctionDecl * getInstantiatedFromMemberFunction() const
If this function is an instantiation of a member function of a class template specialization,...
Definition: Decl.cpp:4024
Declaration of a template function.
Definition: DeclTemplate.h:959
FunctionDecl * getTemplatedDecl() const
Get the underlying function declaration of the template.
FunctionTemplateDecl * getInstantiatedFromMemberTemplate() const
static ImplicitCastExpr * Create(const ASTContext &Context, QualType T, CastKind Kind, Expr *Operand, const CXXCastPath *BasePath, ExprValueKind Cat, FPOptionsOverride FPO)
Definition: Expr.cpp:2082
const TypeClass * getTypePtr() const
Definition: TypeLoc.h:514
Describes the capture of a variable or of this, or of a C++1y init-capture.
Definition: LambdaCapture.h:25
A stack-allocated class that identifies which local variable declaration instantiations are present i...
Definition: Template.h:365
Data structure that captures multiple levels of template argument lists for use in template instantia...
Definition: Template.h:76
const ArgList & getInnermost() const
Retrieve the innermost template argument list.
Definition: Template.h:265
void addOuterTemplateArguments(Decl *AssociatedDecl, ArgList Args, bool Final)
Add a new outmost level to the multi-level template argument list.
Definition: Template.h:210
unsigned getNumLevels() const
Determine the number of levels in this template argument list.
Definition: Template.h:123
void replaceInnermostTemplateArguments(Decl *AssociatedDecl, ArgList Args)
Replaces the current 'innermost' level with the provided argument list.
Definition: Template.h:237
unsigned getNumSubstitutedLevels() const
Determine the number of substituted levels in this template argument list.
Definition: Template.h:129
const ArgList & getOutermost() const
Retrieve the outermost template argument list.
Definition: Template.h:269
This represents a decl that may have a name.
Definition: Decl.h:253
void EmitToString(DiagnosticsEngine &Diags, SmallVectorImpl< char > &Buf) const
A (possibly-)qualified type.
Definition: Type.h:929
The collection of all-type qualifiers we support.
Definition: Type.h:324
Scope - A scope is a transient data structure that is used while parsing the program.
Definition: Scope.h:41
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID, bool DeferHint=false)
Emit a diagnostic.
Definition: SemaBase.cpp:60
PartialDiagnostic PDiag(unsigned DiagID=0)
Build a partial diagnostic.
Definition: SemaBase.cpp:32
Sema & SemaRef
Definition: SemaBase.h:40
RAII object used to change the argument pack substitution index within a Sema object.
Definition: Sema.h:13212
RAII object used to temporarily allow the C++ 'this' expression to be used, with the given qualifiers...
Definition: Sema.h:8048
A RAII object to temporarily push a declaration context.
Definition: Sema.h:3010
RAII class used to determine whether SFINAE has trapped any errors that occur during template argumen...
Definition: Sema.h:12086
bool hasErrorOccurred() const
Determine whether any SFINAE errors have been trapped.
Definition: Sema.h:12116
SourceLocation getLocation() const
Definition: Sema.h:11860
bool ContainsDecl(const NamedDecl *ND) const
Definition: Sema.h:11850
const DeclContext * getDeclContext() const
Definition: Sema.h:11856
const NamedDecl * getDecl() const
Definition: Sema.h:11848
const DeclContext * getLexicalDeclContext() const
Definition: Sema.h:11852
Sema - This implements semantic analysis and AST building for C.
Definition: Sema.h:464
bool CheckParameterPacksForExpansion(SourceLocation EllipsisLoc, SourceRange PatternRange, ArrayRef< UnexpandedParameterPack > Unexpanded, const MultiLevelTemplateArgumentList &TemplateArgs, bool &ShouldExpand, bool &RetainExpansion, std::optional< unsigned > &NumExpansions)
Determine whether we could expand a pack expansion with the given set of parameter packs into separat...
ASTContext & Context
Definition: Sema.h:909
bool ConstraintExpressionDependsOnEnclosingTemplate(const FunctionDecl *Friend, unsigned TemplateDepth, const Expr *Constraint)
DiagnosticsEngine & getDiagnostics() const
Definition: Sema.h:529
ExprResult SubstConstraintExprWithoutSatisfaction(Expr *E, const MultiLevelTemplateArgumentList &TemplateArgs)
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:90
bool SubstTemplateArguments(ArrayRef< TemplateArgumentLoc > Args, const MultiLevelTemplateArgumentList &TemplateArgs, TemplateArgumentListInfo &Outputs)
std::optional< unsigned > getNumArgumentsInExpansionFromUnexpanded(llvm::ArrayRef< UnexpandedParameterPack > Unexpanded, const MultiLevelTemplateArgumentList &TemplateArgs)
bool FriendConstraintsDependOnEnclosingTemplate(const FunctionDecl *FD)
bool EnsureTemplateArgumentListConstraints(TemplateDecl *Template, const MultiLevelTemplateArgumentList &TemplateArgs, SourceRange TemplateIDRange)
Ensure that the given template arguments satisfy the constraints associated with the given template,...
const LangOptions & getLangOpts() const
Definition: Sema.h:525
@ ReuseLambdaContextDecl
Definition: Sema.h:6531
void collectUnexpandedParameterPacks(TemplateArgument Arg, SmallVectorImpl< UnexpandedParameterPack > &Unexpanded)
Collect the set of unexpanded parameter packs within the given template argument.
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:14387
bool AreConstraintExpressionsEqual(const NamedDecl *Old, const Expr *OldConstr, const TemplateCompareNewDeclInfo &New, const Expr *NewConstr)
sema::FunctionScopeInfo * getCurFunction() const
Definition: Sema.h:940
std::optional< sema::TemplateDeductionInfo * > isSFINAEContext() const
Determines whether we are currently in a context where template argument substitution failures are no...
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...
MultiLevelTemplateArgumentList getTemplateInstantiationArgs(const NamedDecl *D, const DeclContext *DC=nullptr, bool Final=false, std::optional< ArrayRef< TemplateArgument > > Innermost=std::nullopt, bool RelativeToPrimary=false, const FunctionDecl *Pattern=nullptr, bool ForConstraintInstantiation=false, bool SkipForSpecialization=false, bool ForDefaultArgumentSubstitution=false)
Retrieve the template argument list(s) that should be used to instantiate the definition of the given...
ExprResult PerformContextuallyConvertToBool(Expr *From)
PerformContextuallyConvertToBool - Perform a contextual conversion of the expression From to bool (C+...
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.
TemplateNameKindForDiagnostics getTemplateNameKindForDiagnostics(TemplateName Name)
Definition: SemaDecl.cpp:1289
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...
void PushSatisfactionStackEntry(const NamedDecl *D, const llvm::FoldingSetNodeID &ID)
Definition: Sema.h:14324
void PopSatisfactionStackEntry()
Definition: Sema.h:14330
ExprResult SubstConstraintExpr(Expr *E, const MultiLevelTemplateArgumentList &TemplateArgs)
void MarkUsedTemplateParameters(const Expr *E, bool OnlyDeduced, unsigned Depth, llvm::SmallBitVector &Used)
Mark which template parameters are used in a given expression.
@ ConstantEvaluated
The current context is "potentially evaluated" in C++11 terms, but the expression is evaluated at com...
bool SatisfactionStackContains(const NamedDecl *D, const llvm::FoldingSetNodeID &ID) const
Definition: Sema.h:14332
ExprResult BuildEmptyCXXFoldExpr(SourceLocation EllipsisLoc, BinaryOperatorKind Operator)
TemplateArgumentLoc getIdentityTemplateArgumentLoc(NamedDecl *Param, SourceLocation Location)
Get a template argument mapping the given template parameter to itself, e.g.
bool CheckFunctionTemplateConstraints(SourceLocation PointOfInstantiation, FunctionDecl *Decl, ArrayRef< TemplateArgument > TemplateArgs, ConstraintSatisfaction &Satisfaction)
std::string getTemplateArgumentBindingsText(const TemplateParameterList *Params, const TemplateArgumentList &Args)
Produces a formatted string that describes the binding of template parameters to template arguments.
void DiagnoseUnsatisfiedConstraint(const ConstraintSatisfaction &Satisfaction, bool First=true)
Emit diagnostics explaining why a constraint expression was deemed unsatisfied.
const NormalizedConstraint * getNormalizedAssociatedConstraints(NamedDecl *ConstrainedDecl, ArrayRef< const Expr * > AssociatedConstraints)
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
A trivial tuple used to represent a source range.
SourceLocation getBegin() const
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
Definition: Stmt.cpp:333
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, bool Canonical, bool ProfileLambdaExpr=false) const
Produce a unique representation of the given statement.
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: Stmt.cpp:345
A convenient class for passing around template argument information.
Definition: TemplateBase.h:632
llvm::ArrayRef< TemplateArgumentLoc > arguments() const
Definition: TemplateBase.h:659
Location wrapper for a TemplateArgument.
Definition: TemplateBase.h:524
The base class of all kinds of template declarations (e.g., class, function, etc.).
Definition: DeclTemplate.h:399
void getAssociatedConstraints(llvm::SmallVectorImpl< const Expr * > &AC) const
Get the total constraint-expression associated with this template, including constraint-expressions d...
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
Definition: DeclTemplate.h:418
Represents a C++ template name within the type system.
Definition: TemplateName.h:220
Stores a list of template parameters for a TemplateDecl and its derived classes.
Definition: DeclTemplate.h:73
NamedDecl * getParam(unsigned Idx)
Definition: DeclTemplate.h:147
static bool anyInstantiationDependentTemplateArguments(ArrayRef< TemplateArgumentLoc > Args)
Definition: Type.cpp:4340
Declaration of a template type parameter.
Wrapper for template type parameters.
Definition: TypeLoc.h:758
Token - This structure provides full information about a lexed token.
Definition: Token.h:36
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:99
tok::TokenKind getKind() const
Definition: Token.h:94
A semantic tree transformation that allows one to transform one abstract syntax tree into another.
Models the abbreviated syntax to constrain a template type parameter: template <convertible_to<string...
Definition: ASTConcept.h:227
Expr * getImmediatelyDeclaredConstraint() const
Get the immediately-declared constraint expression introduced by this type-constraint,...
Definition: ASTConcept.h:242
TyLocType push(QualType T)
Pushes space for a new TypeLoc of the given type.
A container of type source information.
Definition: Type.h:7902
SourceLocation getNameLoc() const
Definition: TypeLoc.h:535
void setNameLoc(SourceLocation Loc)
Definition: TypeLoc.h:539
The base class of the type hierarchy.
Definition: Type.h:1828
bool isSpecificBuiltinType(unsigned K) const
Test for a particular builtin type.
Definition: Type.h:8479
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
Definition: Type.h:2706
bool isFunctionType() const
Definition: Type.h:8182
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Definition: Decl.h:671
bool isInitCapture() const
Whether this variable is the implicit variable for a lambda init-capture.
Definition: Decl.cpp:5394
ReturnTypeRequirement()
No return type requirement was specified.
Definition: ExprConcepts.h:300
SubstitutionDiagnostic * getSubstitutionDiagnostic() const
Definition: ExprConcepts.h:340
A requires-expression requirement which queries the validity and properties of an expression ('simple...
Definition: ExprConcepts.h:280
SubstitutionDiagnostic * getExprSubstitutionDiagnostic() const
Definition: ExprConcepts.h:408
ConceptSpecializationExpr * getReturnTypeRequirementSubstitutedConstraintExpr() const
Definition: ExprConcepts.h:403
const ReturnTypeRequirement & getReturnTypeRequirement() const
Definition: ExprConcepts.h:398
SatisfactionStatus getSatisfactionStatus() const
Definition: ExprConcepts.h:392
SourceLocation getNoexceptLoc() const
Definition: ExprConcepts.h:390
ExprRequirement(Expr *E, bool IsSimple, SourceLocation NoexceptLoc, ReturnTypeRequirement Req, SatisfactionStatus Status, ConceptSpecializationExpr *SubstitutedConstraintExpr=nullptr)
Construct a compound requirement.
A requires-expression requirement which is satisfied when a general constraint expression is satisfie...
Definition: ExprConcepts.h:429
const ASTConstraintSatisfaction & getConstraintSatisfaction() const
Definition: ExprConcepts.h:484
A static requirement that can be used in a requires-expression to check properties of types and expre...
Definition: ExprConcepts.h:168
bool containsUnexpandedParameterPack() const
Definition: ExprConcepts.h:218
A requires-expression requirement which queries the existence of a type name or type template special...
Definition: ExprConcepts.h:225
SubstitutionDiagnostic * getSubstitutionDiagnostic() const
Definition: ExprConcepts.h:260
SatisfactionStatus getSatisfactionStatus() const
Definition: ExprConcepts.h:251
TypeRequirement(TypeSourceInfo *T)
Construct a type requirement from a type.
Provides information about an attempted template argument deduction, whose success or failure was des...
void takeSFINAEDiagnostic(PartialDiagnosticAt &PD)
Take ownership of the SFINAE diagnostic.
bool Sub(InterpState &S, CodePtr OpPC)
Definition: Interp.h:428
The JSON file list parser is used to communicate input to InstallAPI.
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
Definition: OperatorKinds.h:21
@ OO_None
Not an overloaded operator.
Definition: OperatorKinds.h:22
NormalForm makeCNF(const NormalizedConstraint &Normalized)
@ CPlusPlus11
Definition: LangStandard.h:56
@ CPlusPlus26
Definition: LangStandard.h:61
NormalForm makeDNF(const NormalizedConstraint &Normalized)
@ OK_Ordinary
An ordinary object is located at an address in memory.
Definition: Specifiers.h:151
bool subsumes(const NormalForm &PDNF, const NormalForm &QCNF, const AtomicSubsumptionEvaluator &E)
Definition: SemaConcept.h:186
ExprResult ExprEmpty()
Definition: Ownership.h:271
bool isLambdaCallOperator(const CXXMethodDecl *MD)
Definition: ASTLambda.h:27
@ Result
The result type of a method or function.
std::pair< unsigned, unsigned > getDepthAndIndex(const NamedDecl *ND)
Retrieve the depth and index of a template parameter.
Definition: SemaInternal.h:61
const NormalizedConstraint * getNormalizedAssociatedConstraints(Sema &S, NamedDecl *ConstrainedDecl, ArrayRef< const Expr * > AssociatedConstraints)
ExprResult ExprError()
Definition: Ownership.h:264
prec::Level getBinOpPrecedence(tok::TokenKind Kind, bool GreaterThanIsOperator, bool CPlusPlus11)
Return the precedence of the specified binary operator token.
bool isLambdaConversionOperator(CXXConversionDecl *C)
Definition: ASTLambda.h:62
@ VK_PRValue
A pr-value expression (in the C++11 taxonomy) produces a temporary value.
Definition: Specifiers.h:135
const FunctionProtoType * T
std::pair< llvm::PointerUnion< const TemplateTypeParmType *, NamedDecl * >, SourceLocation > UnexpandedParameterPack
Definition: Sema.h:236
std::pair< SourceLocation, PartialDiagnostic > PartialDiagnosticAt
A partial diagnostic along with the source location where this diagnostic occurs.
@ Other
Other implicit parameter.
#define true
Definition: stdbool.h:25
#define false
Definition: stdbool.h:26
The result of a constraint satisfaction check, containing the necessary information to diagnose an un...
Definition: ASTConcept.h:89
Represents an explicit template argument list in C++, e.g., the "<int>" in "sort<int>".
Definition: TemplateBase.h:676
SourceLocation getLAngleLoc() const
Definition: TemplateBase.h:696
llvm::ArrayRef< TemplateArgumentLoc > arguments() const
Definition: TemplateBase.h:705
unsigned NumTemplateArgs
The number of template arguments in TemplateArgs.
Definition: TemplateBase.h:694
SourceLocation getRAngleLoc() const
Definition: TemplateBase.h:697
bool subsumes(ASTContext &C, const AtomicConstraint &Other) const
Definition: SemaConcept.h:60
bool hasMatchingParameterMapping(ASTContext &C, const AtomicConstraint &Other) const
Definition: SemaConcept.h:39
const Expr * ConstraintExpr
Definition: SemaConcept.h:32
EvalResult is a struct with detailed info about an evaluated expression.
Definition: Expr.h:642
APValue Val
Val - This is the value the expression can be folded to.
Definition: Expr.h:644
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:630
NormalizedConstraint Constraint
Definition: SemaConcept.h:166
static bool AreCompatibleForSubsumption(const FoldExpandedConstraint &A, const FoldExpandedConstraint &B)
A normalized constraint, as defined in C++ [temp.constr.normal], is either an atomic constraint,...
Definition: SemaConcept.h:106
llvm::PointerUnion< AtomicConstraint *, FoldExpandedConstraint *, CompoundConstraint > Constraint
Definition: SemaConcept.h:116
NormalizedConstraint & getRHS() const
llvm::PointerIntPair< NormalizedConstraintPair *, 1, CompoundConstraintKind > CompoundConstraint
Definition: SemaConcept.h:112
CompoundConstraintKind getCompoundKind() const
NormalizedConstraint(AtomicConstraint *C)
Definition: SemaConcept.h:118
AtomicConstraint * getAtomicConstraint() const
FoldExpandedConstraint * getFoldExpandedConstraint() const
NormalizedConstraint & getLHS() const
A stack object to be created when performing template instantiation.
Definition: Sema.h:12845
bool isInvalid() const
Determines whether we have exceeded the maximum recursive template instantiations.
Definition: Sema.h:12999