clang 19.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"
22#include "clang/Sema/Overload.h"
24#include "clang/Sema/Sema.h"
27#include "clang/Sema/Template.h"
29#include "llvm/ADT/DenseMap.h"
30#include "llvm/ADT/PointerUnion.h"
31#include "llvm/ADT/StringExtras.h"
32#include <optional>
33
34using namespace clang;
35using namespace sema;
36
37namespace {
38class LogicalBinOp {
41 const Expr *LHS = nullptr;
42 const Expr *RHS = nullptr;
43
44public:
45 LogicalBinOp(const Expr *E) {
46 if (auto *BO = dyn_cast<BinaryOperator>(E)) {
47 Op = BinaryOperator::getOverloadedOperator(BO->getOpcode());
48 LHS = BO->getLHS();
49 RHS = BO->getRHS();
50 Loc = BO->getExprLoc();
51 } else if (auto *OO = dyn_cast<CXXOperatorCallExpr>(E)) {
52 // If OO is not || or && it might not have exactly 2 arguments.
53 if (OO->getNumArgs() == 2) {
54 Op = OO->getOperator();
55 LHS = OO->getArg(0);
56 RHS = OO->getArg(1);
57 Loc = OO->getOperatorLoc();
58 }
59 }
60 }
61
62 bool isAnd() const { return Op == OO_AmpAmp; }
63 bool isOr() const { return Op == OO_PipePipe; }
64 explicit operator bool() const { return isAnd() || isOr(); }
65
66 const Expr *getLHS() const { return LHS; }
67 const Expr *getRHS() const { return RHS; }
68 OverloadedOperatorKind getOp() const { return Op; }
69
70 ExprResult recreateBinOp(Sema &SemaRef, ExprResult LHS) const {
71 return recreateBinOp(SemaRef, LHS, const_cast<Expr *>(getRHS()));
72 }
73
74 ExprResult recreateBinOp(Sema &SemaRef, ExprResult LHS,
75 ExprResult RHS) const {
76 assert((isAnd() || isOr()) && "Not the right kind of op?");
77 assert((!LHS.isInvalid() && !RHS.isInvalid()) && "not good expressions?");
78
79 if (!LHS.isUsable() || !RHS.isUsable())
80 return ExprEmpty();
81
82 // We should just be able to 'normalize' these to the builtin Binary
83 // Operator, since that is how they are evaluated in constriant checks.
84 return BinaryOperator::Create(SemaRef.Context, LHS.get(), RHS.get(),
86 SemaRef.Context.BoolTy, VK_PRValue,
88 }
89};
90}
91
92bool Sema::CheckConstraintExpression(const Expr *ConstraintExpression,
93 Token NextToken, bool *PossibleNonPrimary,
94 bool IsTrailingRequiresClause) {
95 // C++2a [temp.constr.atomic]p1
96 // ..E shall be a constant expression of type bool.
97
98 ConstraintExpression = ConstraintExpression->IgnoreParenImpCasts();
99
100 if (LogicalBinOp BO = ConstraintExpression) {
101 return CheckConstraintExpression(BO.getLHS(), NextToken,
102 PossibleNonPrimary) &&
103 CheckConstraintExpression(BO.getRHS(), NextToken,
104 PossibleNonPrimary);
105 } else if (auto *C = dyn_cast<ExprWithCleanups>(ConstraintExpression))
106 return CheckConstraintExpression(C->getSubExpr(), NextToken,
107 PossibleNonPrimary);
108
109 QualType Type = ConstraintExpression->getType();
110
111 auto CheckForNonPrimary = [&] {
112 if (!PossibleNonPrimary)
113 return;
114
115 *PossibleNonPrimary =
116 // We have the following case:
117 // template<typename> requires func(0) struct S { };
118 // The user probably isn't aware of the parentheses required around
119 // the function call, and we're only going to parse 'func' as the
120 // primary-expression, and complain that it is of non-bool type.
121 //
122 // However, if we're in a lambda, this might also be:
123 // []<typename> requires var () {};
124 // Which also looks like a function call due to the lambda parentheses,
125 // but unlike the first case, isn't an error, so this check is skipped.
126 (NextToken.is(tok::l_paren) &&
127 (IsTrailingRequiresClause ||
128 (Type->isDependentType() &&
129 isa<UnresolvedLookupExpr>(ConstraintExpression) &&
130 !dyn_cast_if_present<LambdaScopeInfo>(getCurFunction())) ||
131 Type->isFunctionType() ||
132 Type->isSpecificBuiltinType(BuiltinType::Overload))) ||
133 // We have the following case:
134 // template<typename T> requires size_<T> == 0 struct S { };
135 // The user probably isn't aware of the parentheses required around
136 // the binary operator, and we're only going to parse 'func' as the
137 // first operand, and complain that it is of non-bool type.
138 getBinOpPrecedence(NextToken.getKind(),
139 /*GreaterThanIsOperator=*/true,
141 };
142
143 // An atomic constraint!
144 if (ConstraintExpression->isTypeDependent()) {
145 CheckForNonPrimary();
146 return true;
147 }
148
150 Diag(ConstraintExpression->getExprLoc(),
151 diag::err_non_bool_atomic_constraint) << Type
152 << ConstraintExpression->getSourceRange();
153 CheckForNonPrimary();
154 return false;
155 }
156
157 if (PossibleNonPrimary)
158 *PossibleNonPrimary = false;
159 return true;
160}
161
162namespace {
163struct SatisfactionStackRAII {
164 Sema &SemaRef;
165 bool Inserted = false;
166 SatisfactionStackRAII(Sema &SemaRef, const NamedDecl *ND,
167 const llvm::FoldingSetNodeID &FSNID)
168 : SemaRef(SemaRef) {
169 if (ND) {
170 SemaRef.PushSatisfactionStackEntry(ND, FSNID);
171 Inserted = true;
172 }
173 }
174 ~SatisfactionStackRAII() {
175 if (Inserted)
177 }
178};
179} // namespace
180
181template <typename ConstraintEvaluator>
182static ExprResult
183calculateConstraintSatisfaction(Sema &S, const Expr *ConstraintExpr,
184 ConstraintSatisfaction &Satisfaction,
185 const ConstraintEvaluator &Evaluator);
186
187template <typename ConstraintEvaluator>
188static ExprResult
190 OverloadedOperatorKind Op, const Expr *RHS,
191 ConstraintSatisfaction &Satisfaction,
192 const ConstraintEvaluator &Evaluator) {
193 size_t EffectiveDetailEndIndex = Satisfaction.Details.size();
194
195 ExprResult LHSRes =
196 calculateConstraintSatisfaction(S, LHS, Satisfaction, Evaluator);
197
198 if (LHSRes.isInvalid())
199 return ExprError();
200
201 bool IsLHSSatisfied = Satisfaction.IsSatisfied;
202
203 if (Op == clang::OO_PipePipe && IsLHSSatisfied)
204 // [temp.constr.op] p3
205 // A disjunction is a constraint taking two operands. To determine if
206 // a disjunction is satisfied, the satisfaction of the first operand
207 // is checked. If that is satisfied, the disjunction is satisfied.
208 // Otherwise, the disjunction is satisfied if and only if the second
209 // operand is satisfied.
210 // LHS is instantiated while RHS is not. Skip creating invalid BinaryOp.
211 return LHSRes;
212
213 if (Op == clang::OO_AmpAmp && !IsLHSSatisfied)
214 // [temp.constr.op] p2
215 // A conjunction is a constraint taking two operands. To determine if
216 // a conjunction is satisfied, the satisfaction of the first operand
217 // is checked. If that is not satisfied, the conjunction is not
218 // satisfied. Otherwise, the conjunction is satisfied if and only if
219 // the second operand is satisfied.
220 // LHS is instantiated while RHS is not. Skip creating invalid BinaryOp.
221 return LHSRes;
222
223 ExprResult RHSRes =
224 calculateConstraintSatisfaction(S, RHS, Satisfaction, Evaluator);
225 if (RHSRes.isInvalid())
226 return ExprError();
227
228 bool IsRHSSatisfied = Satisfaction.IsSatisfied;
229 // Current implementation adds diagnostic information about the falsity
230 // of each false atomic constraint expression when it evaluates them.
231 // When the evaluation results to `false || true`, the information
232 // generated during the evaluation of left-hand side is meaningless
233 // because the whole expression evaluates to true.
234 // The following code removes the irrelevant diagnostic information.
235 // FIXME: We should probably delay the addition of diagnostic information
236 // until we know the entire expression is false.
237 if (Op == clang::OO_PipePipe && IsRHSSatisfied) {
238 auto EffectiveDetailEnd = Satisfaction.Details.begin();
239 std::advance(EffectiveDetailEnd, EffectiveDetailEndIndex);
240 Satisfaction.Details.erase(EffectiveDetailEnd, Satisfaction.Details.end());
241 }
242
243 if (!LHSRes.isUsable() || !RHSRes.isUsable())
244 return ExprEmpty();
245
246 return BinaryOperator::Create(S.Context, LHSRes.get(), RHSRes.get(),
250}
251
252template <typename ConstraintEvaluator>
253static ExprResult
255 ConstraintSatisfaction &Satisfaction,
256 const ConstraintEvaluator &Evaluator) {
257 bool Conjunction = FE->getOperator() == BinaryOperatorKind::BO_LAnd;
258 size_t EffectiveDetailEndIndex = Satisfaction.Details.size();
259
260 ExprResult Out;
261 if (FE->isLeftFold() && FE->getInit()) {
262 Out = calculateConstraintSatisfaction(S, FE->getInit(), Satisfaction,
263 Evaluator);
264 if (Out.isInvalid())
265 return ExprError();
266
267 // If the first clause of a conjunction is not satisfied,
268 // or if the first clause of a disjection is satisfied,
269 // we have established satisfaction of the whole constraint
270 // and we should not continue further.
271 if (Conjunction != Satisfaction.IsSatisfied)
272 return Out;
273 }
274 std::optional<unsigned> NumExpansions =
275 Evaluator.EvaluateFoldExpandedConstraintSize(FE);
276 if (!NumExpansions)
277 return ExprError();
278 for (unsigned I = 0; I < *NumExpansions; I++) {
281 Satisfaction, Evaluator);
282 if (Res.isInvalid())
283 return ExprError();
284 bool IsRHSSatisfied = Satisfaction.IsSatisfied;
285 if (!Conjunction && IsRHSSatisfied) {
286 auto EffectiveDetailEnd = Satisfaction.Details.begin();
287 std::advance(EffectiveDetailEnd, EffectiveDetailEndIndex);
288 Satisfaction.Details.erase(EffectiveDetailEnd,
289 Satisfaction.Details.end());
290 }
291 if (Out.isUnset())
292 Out = Res;
293 else if (!Res.isUnset()) {
295 S.Context, Out.get(), Res.get(), FE->getOperator(), S.Context.BoolTy,
297 }
298 if (Conjunction != IsRHSSatisfied)
299 return Out;
300 }
301
302 if (FE->isRightFold() && FE->getInit()) {
304 Satisfaction, Evaluator);
305 if (Out.isInvalid())
306 return ExprError();
307
308 if (Out.isUnset())
309 Out = Res;
310 else if (!Res.isUnset()) {
312 S.Context, Out.get(), Res.get(), FE->getOperator(), S.Context.BoolTy,
314 }
315 }
316
317 if (Out.isUnset()) {
318 Satisfaction.IsSatisfied = Conjunction;
319 Out = S.BuildEmptyCXXFoldExpr(FE->getBeginLoc(), FE->getOperator());
320 }
321 return Out;
322}
323
324template <typename ConstraintEvaluator>
325static ExprResult
326calculateConstraintSatisfaction(Sema &S, const Expr *ConstraintExpr,
327 ConstraintSatisfaction &Satisfaction,
328 const ConstraintEvaluator &Evaluator) {
329 ConstraintExpr = ConstraintExpr->IgnoreParenImpCasts();
330
331 if (LogicalBinOp BO = ConstraintExpr)
333 S, BO.getLHS(), BO.getOp(), BO.getRHS(), Satisfaction, Evaluator);
334
335 if (auto *C = dyn_cast<ExprWithCleanups>(ConstraintExpr)) {
336 // These aren't evaluated, so we don't care about cleanups, so we can just
337 // evaluate these as if the cleanups didn't exist.
338 return calculateConstraintSatisfaction(S, C->getSubExpr(), Satisfaction,
339 Evaluator);
340 }
341
342 if (auto *FE = dyn_cast<CXXFoldExpr>(ConstraintExpr);
343 FE && S.getLangOpts().CPlusPlus26 &&
344 (FE->getOperator() == BinaryOperatorKind::BO_LAnd ||
345 FE->getOperator() == BinaryOperatorKind::BO_LOr)) {
346 return calculateConstraintSatisfaction(S, FE, Satisfaction, Evaluator);
347 }
348
349 // An atomic constraint expression
350 ExprResult SubstitutedAtomicExpr =
351 Evaluator.EvaluateAtomicConstraint(ConstraintExpr);
352
353 if (SubstitutedAtomicExpr.isInvalid())
354 return ExprError();
355
356 if (!SubstitutedAtomicExpr.isUsable())
357 // Evaluator has decided satisfaction without yielding an expression.
358 return ExprEmpty();
359
360 // We don't have the ability to evaluate this, since it contains a
361 // RecoveryExpr, so we want to fail overload resolution. Otherwise,
362 // we'd potentially pick up a different overload, and cause confusing
363 // diagnostics. SO, add a failure detail that will cause us to make this
364 // overload set not viable.
365 if (SubstitutedAtomicExpr.get()->containsErrors()) {
366 Satisfaction.IsSatisfied = false;
367 Satisfaction.ContainsErrors = true;
368
369 PartialDiagnostic Msg = S.PDiag(diag::note_constraint_references_error);
370 SmallString<128> DiagString;
371 DiagString = ": ";
372 Msg.EmitToString(S.getDiagnostics(), DiagString);
373 unsigned MessageSize = DiagString.size();
374 char *Mem = new (S.Context) char[MessageSize];
375 memcpy(Mem, DiagString.c_str(), MessageSize);
376 Satisfaction.Details.emplace_back(
378 SubstitutedAtomicExpr.get()->getBeginLoc(),
379 StringRef(Mem, MessageSize)});
380 return SubstitutedAtomicExpr;
381 }
382
383 EnterExpressionEvaluationContext ConstantEvaluated(
386 Expr::EvalResult EvalResult;
387 EvalResult.Diag = &EvaluationDiags;
388 if (!SubstitutedAtomicExpr.get()->EvaluateAsConstantExpr(EvalResult,
389 S.Context) ||
390 !EvaluationDiags.empty()) {
391 // C++2a [temp.constr.atomic]p1
392 // ...E shall be a constant expression of type bool.
393 S.Diag(SubstitutedAtomicExpr.get()->getBeginLoc(),
394 diag::err_non_constant_constraint_expression)
395 << SubstitutedAtomicExpr.get()->getSourceRange();
396 for (const PartialDiagnosticAt &PDiag : EvaluationDiags)
397 S.Diag(PDiag.first, PDiag.second);
398 return ExprError();
399 }
400
401 assert(EvalResult.Val.isInt() &&
402 "evaluating bool expression didn't produce int");
403 Satisfaction.IsSatisfied = EvalResult.Val.getInt().getBoolValue();
404 if (!Satisfaction.IsSatisfied)
405 Satisfaction.Details.emplace_back(SubstitutedAtomicExpr.get());
406
407 return SubstitutedAtomicExpr;
408}
409
410static bool
411DiagRecursiveConstraintEval(Sema &S, llvm::FoldingSetNodeID &ID,
412 const NamedDecl *Templ, const Expr *E,
413 const MultiLevelTemplateArgumentList &MLTAL) {
414 E->Profile(ID, S.Context, /*Canonical=*/true);
415 for (const auto &List : MLTAL)
416 for (const auto &TemplateArg : List.Args)
417 TemplateArg.Profile(ID, S.Context);
418
419 // Note that we have to do this with our own collection, because there are
420 // times where a constraint-expression check can cause us to need to evaluate
421 // other constriants that are unrelated, such as when evaluating a recovery
422 // expression, or when trying to determine the constexpr-ness of special
423 // members. Otherwise we could just use the
424 // Sema::InstantiatingTemplate::isAlreadyBeingInstantiated function.
425 if (S.SatisfactionStackContains(Templ, ID)) {
426 S.Diag(E->getExprLoc(), diag::err_constraint_depends_on_self)
427 << const_cast<Expr *>(E) << E->getSourceRange();
428 return true;
429 }
430
431 return false;
432}
433
435 Sema &S, const NamedDecl *Template, SourceLocation TemplateNameLoc,
436 const MultiLevelTemplateArgumentList &MLTAL, const Expr *ConstraintExpr,
437 ConstraintSatisfaction &Satisfaction) {
438
439 struct ConstraintEvaluator {
440 Sema &S;
441 const NamedDecl *Template;
442 SourceLocation TemplateNameLoc;
444 ConstraintSatisfaction &Satisfaction;
445
446 ExprResult EvaluateAtomicConstraint(const Expr *AtomicExpr) const {
447 EnterExpressionEvaluationContext ConstantEvaluated(
448 S, Sema::ExpressionEvaluationContext::ConstantEvaluated,
450
451 // Atomic constraint - substitute arguments and check satisfaction.
452 ExprResult SubstitutedExpression;
453 {
454 TemplateDeductionInfo Info(TemplateNameLoc);
458 const_cast<NamedDecl *>(Template), Info,
460 if (Inst.isInvalid())
461 return ExprError();
462
463 llvm::FoldingSetNodeID ID;
464 if (Template &&
465 DiagRecursiveConstraintEval(S, ID, Template, AtomicExpr, MLTAL)) {
466 Satisfaction.IsSatisfied = false;
467 Satisfaction.ContainsErrors = true;
468 return ExprEmpty();
469 }
470
471 SatisfactionStackRAII StackRAII(S, Template, ID);
472
473 // We do not want error diagnostics escaping here.
474 Sema::SFINAETrap Trap(S);
475 SubstitutedExpression =
476 S.SubstConstraintExpr(const_cast<Expr *>(AtomicExpr), MLTAL);
477
478 if (SubstitutedExpression.isInvalid() || Trap.hasErrorOccurred()) {
479 // C++2a [temp.constr.atomic]p1
480 // ...If substitution results in an invalid type or expression, the
481 // constraint is not satisfied.
482 if (!Trap.hasErrorOccurred())
483 // A non-SFINAE error has occurred as a result of this
484 // substitution.
485 return ExprError();
486
489 Info.takeSFINAEDiagnostic(SubstDiag);
490 // FIXME: Concepts: This is an unfortunate consequence of there
491 // being no serialization code for PartialDiagnostics and the fact
492 // that serializing them would likely take a lot more storage than
493 // just storing them as strings. We would still like, in the
494 // future, to serialize the proper PartialDiagnostic as serializing
495 // it as a string defeats the purpose of the diagnostic mechanism.
496 SmallString<128> DiagString;
497 DiagString = ": ";
498 SubstDiag.second.EmitToString(S.getDiagnostics(), DiagString);
499 unsigned MessageSize = DiagString.size();
500 char *Mem = new (S.Context) char[MessageSize];
501 memcpy(Mem, DiagString.c_str(), MessageSize);
502 Satisfaction.Details.emplace_back(
504 SubstDiag.first, StringRef(Mem, MessageSize)});
505 Satisfaction.IsSatisfied = false;
506 return ExprEmpty();
507 }
508 }
509
510 if (!S.CheckConstraintExpression(SubstitutedExpression.get()))
511 return ExprError();
512
513 // [temp.constr.atomic]p3: To determine if an atomic constraint is
514 // satisfied, the parameter mapping and template arguments are first
515 // substituted into its expression. If substitution results in an
516 // invalid type or expression, the constraint is not satisfied.
517 // Otherwise, the lvalue-to-rvalue conversion is performed if necessary,
518 // and E shall be a constant expression of type bool.
519 //
520 // Perform the L to R Value conversion if necessary. We do so for all
521 // non-PRValue categories, else we fail to extend the lifetime of
522 // temporaries, and that fails the constant expression check.
523 if (!SubstitutedExpression.get()->isPRValue())
524 SubstitutedExpression = ImplicitCastExpr::Create(
525 S.Context, SubstitutedExpression.get()->getType(),
526 CK_LValueToRValue, SubstitutedExpression.get(),
527 /*BasePath=*/nullptr, VK_PRValue, FPOptionsOverride());
528
529 return SubstitutedExpression;
530 }
531
532 std::optional<unsigned>
533 EvaluateFoldExpandedConstraintSize(const CXXFoldExpr *FE) const {
534 Expr *Pattern = FE->getPattern();
535
537 S.collectUnexpandedParameterPacks(Pattern, Unexpanded);
538 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
539 bool Expand = true;
540 bool RetainExpansion = false;
541 std::optional<unsigned> OrigNumExpansions = FE->getNumExpansions(),
542 NumExpansions = OrigNumExpansions;
544 FE->getEllipsisLoc(), Pattern->getSourceRange(), Unexpanded,
545 MLTAL, Expand, RetainExpansion, NumExpansions) ||
546 !Expand || RetainExpansion)
547 return std::nullopt;
548
549 if (NumExpansions && S.getLangOpts().BracketDepth < NumExpansions) {
550 S.Diag(FE->getEllipsisLoc(),
551 clang::diag::err_fold_expression_limit_exceeded)
552 << *NumExpansions << S.getLangOpts().BracketDepth
553 << FE->getSourceRange();
554 S.Diag(FE->getEllipsisLoc(), diag::note_bracket_depth);
555 return std::nullopt;
556 }
557 return NumExpansions;
558 }
559 };
560
562 S, ConstraintExpr, Satisfaction,
563 ConstraintEvaluator{S, Template, TemplateNameLoc, MLTAL, Satisfaction});
564}
565
567 Sema &S, const NamedDecl *Template, ArrayRef<const Expr *> ConstraintExprs,
569 const MultiLevelTemplateArgumentList &TemplateArgsLists,
570 SourceRange TemplateIDRange, ConstraintSatisfaction &Satisfaction) {
571 if (ConstraintExprs.empty()) {
572 Satisfaction.IsSatisfied = true;
573 return false;
574 }
575
576 if (TemplateArgsLists.isAnyArgInstantiationDependent()) {
577 // No need to check satisfaction for dependent constraint expressions.
578 Satisfaction.IsSatisfied = true;
579 return false;
580 }
581
582 ArrayRef<TemplateArgument> TemplateArgs =
583 TemplateArgsLists.getNumSubstitutedLevels() > 0
584 ? TemplateArgsLists.getOutermost()
586 Sema::InstantiatingTemplate Inst(S, TemplateIDRange.getBegin(),
588 const_cast<NamedDecl *>(Template), TemplateArgs, TemplateIDRange);
589 if (Inst.isInvalid())
590 return true;
591
592 for (const Expr *ConstraintExpr : ConstraintExprs) {
594 S, Template, TemplateIDRange.getBegin(), TemplateArgsLists,
595 ConstraintExpr, Satisfaction);
596 if (Res.isInvalid())
597 return true;
598
599 Converted.push_back(Res.get());
600 if (!Satisfaction.IsSatisfied) {
601 // Backfill the 'converted' list with nulls so we can keep the Converted
602 // and unconverted lists in sync.
603 Converted.append(ConstraintExprs.size() - Converted.size(), nullptr);
604 // [temp.constr.op] p2
605 // [...] To determine if a conjunction is satisfied, the satisfaction
606 // of the first operand is checked. If that is not satisfied, the
607 // conjunction is not satisfied. [...]
608 return false;
609 }
610 }
611 return false;
612}
613
615 const NamedDecl *Template, ArrayRef<const Expr *> ConstraintExprs,
616 llvm::SmallVectorImpl<Expr *> &ConvertedConstraints,
617 const MultiLevelTemplateArgumentList &TemplateArgsLists,
618 SourceRange TemplateIDRange, ConstraintSatisfaction &OutSatisfaction) {
619 if (ConstraintExprs.empty()) {
620 OutSatisfaction.IsSatisfied = true;
621 return false;
622 }
623 if (!Template) {
624 return ::CheckConstraintSatisfaction(
625 *this, nullptr, ConstraintExprs, ConvertedConstraints,
626 TemplateArgsLists, TemplateIDRange, OutSatisfaction);
627 }
628 // Invalid templates could make their way here. Substituting them could result
629 // in dependent expressions.
630 if (Template->isInvalidDecl()) {
631 OutSatisfaction.IsSatisfied = false;
632 return true;
633 }
634
635 // A list of the template argument list flattened in a predictible manner for
636 // the purposes of caching. The ConstraintSatisfaction type is in AST so it
637 // has no access to the MultiLevelTemplateArgumentList, so this has to happen
638 // here.
640 for (auto List : TemplateArgsLists)
641 FlattenedArgs.insert(FlattenedArgs.end(), List.Args.begin(),
642 List.Args.end());
643
644 llvm::FoldingSetNodeID ID;
645 ConstraintSatisfaction::Profile(ID, Context, Template, FlattenedArgs);
646 void *InsertPos;
647 if (auto *Cached = SatisfactionCache.FindNodeOrInsertPos(ID, InsertPos)) {
648 OutSatisfaction = *Cached;
649 return false;
650 }
651
652 auto Satisfaction =
653 std::make_unique<ConstraintSatisfaction>(Template, FlattenedArgs);
654 if (::CheckConstraintSatisfaction(*this, Template, ConstraintExprs,
655 ConvertedConstraints, TemplateArgsLists,
656 TemplateIDRange, *Satisfaction)) {
657 OutSatisfaction = *Satisfaction;
658 return true;
659 }
660
661 if (auto *Cached = SatisfactionCache.FindNodeOrInsertPos(ID, InsertPos)) {
662 // The evaluation of this constraint resulted in us trying to re-evaluate it
663 // recursively. This isn't really possible, except we try to form a
664 // RecoveryExpr as a part of the evaluation. If this is the case, just
665 // return the 'cached' version (which will have the same result), and save
666 // ourselves the extra-insert. If it ever becomes possible to legitimately
667 // recursively check a constraint, we should skip checking the 'inner' one
668 // above, and replace the cached version with this one, as it would be more
669 // specific.
670 OutSatisfaction = *Cached;
671 return false;
672 }
673
674 // Else we can simply add this satisfaction to the list.
675 OutSatisfaction = *Satisfaction;
676 // We cannot use InsertPos here because CheckConstraintSatisfaction might have
677 // invalidated it.
678 // Note that entries of SatisfactionCache are deleted in Sema's destructor.
679 SatisfactionCache.InsertNode(Satisfaction.release());
680 return false;
681}
682
683bool Sema::CheckConstraintSatisfaction(const Expr *ConstraintExpr,
684 ConstraintSatisfaction &Satisfaction) {
685
686 struct ConstraintEvaluator {
687 Sema &S;
688 ExprResult EvaluateAtomicConstraint(const Expr *AtomicExpr) const {
689 return S.PerformContextuallyConvertToBool(const_cast<Expr *>(AtomicExpr));
690 }
691
692 std::optional<unsigned>
693 EvaluateFoldExpandedConstraintSize(const CXXFoldExpr *FE) const {
694 return 0;
695 }
696 };
697
698 return calculateConstraintSatisfaction(*this, ConstraintExpr, Satisfaction,
699 ConstraintEvaluator{*this})
700 .isInvalid();
701}
702
703bool Sema::addInstantiatedCapturesToScope(
704 FunctionDecl *Function, const FunctionDecl *PatternDecl,
706 const MultiLevelTemplateArgumentList &TemplateArgs) {
707 const auto *LambdaClass = cast<CXXMethodDecl>(Function)->getParent();
708 const auto *LambdaPattern = cast<CXXMethodDecl>(PatternDecl)->getParent();
709
710 unsigned Instantiated = 0;
711
712 auto AddSingleCapture = [&](const ValueDecl *CapturedPattern,
713 unsigned Index) {
714 ValueDecl *CapturedVar = LambdaClass->getCapture(Index)->getCapturedVar();
715 if (CapturedVar->isInitCapture())
716 Scope.InstantiatedLocal(CapturedPattern, CapturedVar);
717 };
718
719 for (const LambdaCapture &CapturePattern : LambdaPattern->captures()) {
720 if (!CapturePattern.capturesVariable()) {
721 Instantiated++;
722 continue;
723 }
724 const ValueDecl *CapturedPattern = CapturePattern.getCapturedVar();
725 if (!CapturedPattern->isParameterPack()) {
726 AddSingleCapture(CapturedPattern, Instantiated++);
727 } else {
728 Scope.MakeInstantiatedLocalArgPack(CapturedPattern);
729 std::optional<unsigned> NumArgumentsInExpansion =
730 getNumArgumentsInExpansion(CapturedPattern->getType(), TemplateArgs);
731 if (!NumArgumentsInExpansion)
732 continue;
733 for (unsigned Arg = 0; Arg < *NumArgumentsInExpansion; ++Arg)
734 AddSingleCapture(CapturedPattern, Instantiated++);
735 }
736 }
737 return false;
738}
739
740bool Sema::SetupConstraintScope(
741 FunctionDecl *FD, std::optional<ArrayRef<TemplateArgument>> TemplateArgs,
744 if (FD->isTemplateInstantiation() && FD->getPrimaryTemplate()) {
745 FunctionTemplateDecl *PrimaryTemplate = FD->getPrimaryTemplate();
746 InstantiatingTemplate Inst(
747 *this, FD->getPointOfInstantiation(),
749 TemplateArgs ? *TemplateArgs : ArrayRef<TemplateArgument>{},
750 SourceRange());
751 if (Inst.isInvalid())
752 return true;
753
754 // addInstantiatedParametersToScope creates a map of 'uninstantiated' to
755 // 'instantiated' parameters and adds it to the context. For the case where
756 // this function is a template being instantiated NOW, we also need to add
757 // the list of current template arguments to the list so that they also can
758 // be picked out of the map.
759 if (auto *SpecArgs = FD->getTemplateSpecializationArgs()) {
760 MultiLevelTemplateArgumentList JustTemplArgs(FD, SpecArgs->asArray(),
761 /*Final=*/false);
762 if (addInstantiatedParametersToScope(
763 FD, PrimaryTemplate->getTemplatedDecl(), Scope, JustTemplArgs))
764 return true;
765 }
766
767 // If this is a member function, make sure we get the parameters that
768 // reference the original primary template.
769 // We walk up the instantiated template chain so that nested lambdas get
770 // handled properly.
771 // We should only collect instantiated parameters from the primary template.
772 // Otherwise, we may have mismatched template parameter depth!
773 if (FunctionTemplateDecl *FromMemTempl =
774 PrimaryTemplate->getInstantiatedFromMemberTemplate()) {
775 while (FromMemTempl->getInstantiatedFromMemberTemplate())
776 FromMemTempl = FromMemTempl->getInstantiatedFromMemberTemplate();
777 if (addInstantiatedParametersToScope(FD, FromMemTempl->getTemplatedDecl(),
778 Scope, MLTAL))
779 return true;
780 }
781
782 return false;
783 }
784
787 FunctionDecl *InstantiatedFrom =
791
792 InstantiatingTemplate Inst(
793 *this, FD->getPointOfInstantiation(),
795 TemplateArgs ? *TemplateArgs : ArrayRef<TemplateArgument>{},
796 SourceRange());
797 if (Inst.isInvalid())
798 return true;
799
800 // Case where this was not a template, but instantiated as a
801 // child-function.
802 if (addInstantiatedParametersToScope(FD, InstantiatedFrom, Scope, MLTAL))
803 return true;
804 }
805
806 return false;
807}
808
809// This function collects all of the template arguments for the purposes of
810// constraint-instantiation and checking.
811std::optional<MultiLevelTemplateArgumentList>
812Sema::SetupConstraintCheckingTemplateArgumentsAndScope(
813 FunctionDecl *FD, std::optional<ArrayRef<TemplateArgument>> TemplateArgs,
816
817 // Collect the list of template arguments relative to the 'primary' template.
818 // We need the entire list, since the constraint is completely uninstantiated
819 // at this point.
820 MLTAL =
822 /*Final=*/false, /*Innermost=*/std::nullopt,
823 /*RelativeToPrimary=*/true,
824 /*Pattern=*/nullptr,
825 /*ForConstraintInstantiation=*/true);
826 if (SetupConstraintScope(FD, TemplateArgs, MLTAL, Scope))
827 return std::nullopt;
828
829 return MLTAL;
830}
831
833 ConstraintSatisfaction &Satisfaction,
834 SourceLocation UsageLoc,
835 bool ForOverloadResolution) {
836 // Don't check constraints if the function is dependent. Also don't check if
837 // this is a function template specialization, as the call to
838 // CheckinstantiatedFunctionTemplateConstraints after this will check it
839 // better.
840 if (FD->isDependentContext() ||
841 FD->getTemplatedKind() ==
843 Satisfaction.IsSatisfied = true;
844 return false;
845 }
846
847 // A lambda conversion operator has the same constraints as the call operator
848 // and constraints checking relies on whether we are in a lambda call operator
849 // (and may refer to its parameters), so check the call operator instead.
850 // Note that the declarations outside of the lambda should also be
851 // considered. Turning on the 'ForOverloadResolution' flag results in the
852 // LocalInstantiationScope not looking into its parents, but we can still
853 // access Decls from the parents while building a lambda RAII scope later.
854 if (const auto *MD = dyn_cast<CXXConversionDecl>(FD);
855 MD && isLambdaConversionOperator(const_cast<CXXConversionDecl *>(MD)))
856 return CheckFunctionConstraints(MD->getParent()->getLambdaCallOperator(),
857 Satisfaction, UsageLoc,
858 /*ShouldAddDeclsFromParentScope=*/true);
859
860 DeclContext *CtxToSave = const_cast<FunctionDecl *>(FD);
861
862 while (isLambdaCallOperator(CtxToSave) || FD->isTransparentContext()) {
863 if (isLambdaCallOperator(CtxToSave))
864 CtxToSave = CtxToSave->getParent()->getParent();
865 else
866 CtxToSave = CtxToSave->getNonTransparentContext();
867 }
868
869 ContextRAII SavedContext{*this, CtxToSave};
870 LocalInstantiationScope Scope(*this, !ForOverloadResolution);
871 std::optional<MultiLevelTemplateArgumentList> MLTAL =
872 SetupConstraintCheckingTemplateArgumentsAndScope(
873 const_cast<FunctionDecl *>(FD), {}, Scope);
874
875 if (!MLTAL)
876 return true;
877
878 Qualifiers ThisQuals;
879 CXXRecordDecl *Record = nullptr;
880 if (auto *Method = dyn_cast<CXXMethodDecl>(FD)) {
881 ThisQuals = Method->getMethodQualifiers();
882 Record = const_cast<CXXRecordDecl *>(Method->getParent());
883 }
884 CXXThisScopeRAII ThisScope(*this, Record, ThisQuals, Record != nullptr);
885
887 *this, const_cast<FunctionDecl *>(FD), *MLTAL, Scope,
888 ForOverloadResolution);
889
891 FD, {FD->getTrailingRequiresClause()}, *MLTAL,
892 SourceRange(UsageLoc.isValid() ? UsageLoc : FD->getLocation()),
893 Satisfaction);
894}
895
896
897// Figure out the to-translation-unit depth for this function declaration for
898// the purpose of seeing if they differ by constraints. This isn't the same as
899// getTemplateDepth, because it includes already instantiated parents.
900static unsigned
902 bool SkipForSpecialization = false) {
904 ND, ND->getLexicalDeclContext(), /*Final=*/false,
905 /*Innermost=*/std::nullopt,
906 /*RelativeToPrimary=*/true,
907 /*Pattern=*/nullptr,
908 /*ForConstraintInstantiation=*/true, SkipForSpecialization);
909 return MLTAL.getNumLevels();
910}
911
912namespace {
913 class AdjustConstraintDepth : public TreeTransform<AdjustConstraintDepth> {
914 unsigned TemplateDepth = 0;
915 public:
916 using inherited = TreeTransform<AdjustConstraintDepth>;
917 AdjustConstraintDepth(Sema &SemaRef, unsigned TemplateDepth)
918 : inherited(SemaRef), TemplateDepth(TemplateDepth) {}
919
920 using inherited::TransformTemplateTypeParmType;
921 QualType TransformTemplateTypeParmType(TypeLocBuilder &TLB,
922 TemplateTypeParmTypeLoc TL, bool) {
923 const TemplateTypeParmType *T = TL.getTypePtr();
924
925 TemplateTypeParmDecl *NewTTPDecl = nullptr;
926 if (TemplateTypeParmDecl *OldTTPDecl = T->getDecl())
927 NewTTPDecl = cast_or_null<TemplateTypeParmDecl>(
928 TransformDecl(TL.getNameLoc(), OldTTPDecl));
929
930 QualType Result = getSema().Context.getTemplateTypeParmType(
931 T->getDepth() + TemplateDepth, T->getIndex(), T->isParameterPack(),
932 NewTTPDecl);
934 NewTL.setNameLoc(TL.getNameLoc());
935 return Result;
936 }
937 };
938} // namespace
939
941 Sema &S, const Sema::TemplateCompareNewDeclInfo &DeclInfo,
942 const Expr *ConstrExpr) {
944 DeclInfo.getDecl(), DeclInfo.getLexicalDeclContext(), /*Final=*/false,
945 /*Innermost=*/std::nullopt,
946 /*RelativeToPrimary=*/true,
947 /*Pattern=*/nullptr, /*ForConstraintInstantiation=*/true,
948 /*SkipForSpecialization*/ false);
949
950 if (MLTAL.getNumSubstitutedLevels() == 0)
951 return ConstrExpr;
952
953 Sema::SFINAETrap SFINAE(S, /*AccessCheckingSFINAE=*/false);
954
956 S, DeclInfo.getLocation(),
958 const_cast<NamedDecl *>(DeclInfo.getDecl()), SourceRange{});
959 if (Inst.isInvalid())
960 return nullptr;
961
962 // Set up a dummy 'instantiation' scope in the case of reference to function
963 // parameters that the surrounding function hasn't been instantiated yet. Note
964 // this may happen while we're comparing two templates' constraint
965 // equivalence.
966 LocalInstantiationScope ScopeForParameters(S);
967 if (auto *FD = DeclInfo.getDecl()->getAsFunction())
968 for (auto *PVD : FD->parameters())
969 ScopeForParameters.InstantiatedLocal(PVD, PVD);
970
971 std::optional<Sema::CXXThisScopeRAII> ThisScope;
972
973 // See TreeTransform::RebuildTemplateSpecializationType. A context scope is
974 // essential for having an injected class as the canonical type for a template
975 // specialization type at the rebuilding stage. This guarantees that, for
976 // out-of-line definitions, injected class name types and their equivalent
977 // template specializations can be profiled to the same value, which makes it
978 // possible that e.g. constraints involving C<Class<T>> and C<Class> are
979 // perceived identical.
980 std::optional<Sema::ContextRAII> ContextScope;
981 if (auto *RD = dyn_cast<CXXRecordDecl>(DeclInfo.getDeclContext())) {
982 ThisScope.emplace(S, const_cast<CXXRecordDecl *>(RD), Qualifiers());
983 ContextScope.emplace(S, const_cast<DeclContext *>(cast<DeclContext>(RD)),
984 /*NewThisContext=*/false);
985 }
987 const_cast<clang::Expr *>(ConstrExpr), MLTAL);
988 if (SFINAE.hasErrorOccurred() || !SubstConstr.isUsable())
989 return nullptr;
990 return SubstConstr.get();
991}
992
994 const Expr *OldConstr,
996 const Expr *NewConstr) {
997 if (OldConstr == NewConstr)
998 return true;
999 // C++ [temp.constr.decl]p4
1000 if (Old && !New.isInvalid() && !New.ContainsDecl(Old) &&
1002 if (const Expr *SubstConstr =
1004 OldConstr))
1005 OldConstr = SubstConstr;
1006 else
1007 return false;
1008 if (const Expr *SubstConstr =
1010 NewConstr))
1011 NewConstr = SubstConstr;
1012 else
1013 return false;
1014 }
1015
1016 llvm::FoldingSetNodeID ID1, ID2;
1017 OldConstr->Profile(ID1, Context, /*Canonical=*/true);
1018 NewConstr->Profile(ID2, Context, /*Canonical=*/true);
1019 return ID1 == ID2;
1020}
1021
1023 assert(FD->getFriendObjectKind() && "Must be a friend!");
1024
1025 // The logic for non-templates is handled in ASTContext::isSameEntity, so we
1026 // don't have to bother checking 'DependsOnEnclosingTemplate' for a
1027 // non-function-template.
1028 assert(FD->getDescribedFunctionTemplate() &&
1029 "Non-function templates don't need to be checked");
1030
1033
1034 unsigned OldTemplateDepth = CalculateTemplateDepthForConstraints(*this, FD);
1035 for (const Expr *Constraint : ACs)
1036 if (ConstraintExpressionDependsOnEnclosingTemplate(FD, OldTemplateDepth,
1037 Constraint))
1038 return true;
1039
1040 return false;
1041}
1042
1044 TemplateDecl *TD, const MultiLevelTemplateArgumentList &TemplateArgsLists,
1045 SourceRange TemplateIDRange) {
1046 ConstraintSatisfaction Satisfaction;
1047 llvm::SmallVector<const Expr *, 3> AssociatedConstraints;
1048 TD->getAssociatedConstraints(AssociatedConstraints);
1049 if (CheckConstraintSatisfaction(TD, AssociatedConstraints, TemplateArgsLists,
1050 TemplateIDRange, Satisfaction))
1051 return true;
1052
1053 if (!Satisfaction.IsSatisfied) {
1054 SmallString<128> TemplateArgString;
1055 TemplateArgString = " ";
1056 TemplateArgString += getTemplateArgumentBindingsText(
1057 TD->getTemplateParameters(), TemplateArgsLists.getInnermost().data(),
1058 TemplateArgsLists.getInnermost().size());
1059
1060 Diag(TemplateIDRange.getBegin(),
1061 diag::err_template_arg_list_constraints_not_satisfied)
1063 << TemplateArgString << TemplateIDRange;
1064 DiagnoseUnsatisfiedConstraint(Satisfaction);
1065 return true;
1066 }
1067 return false;
1068}
1069
1071 SourceLocation PointOfInstantiation, FunctionDecl *Decl,
1072 ArrayRef<TemplateArgument> TemplateArgs,
1073 ConstraintSatisfaction &Satisfaction) {
1074 // In most cases we're not going to have constraints, so check for that first.
1075 FunctionTemplateDecl *Template = Decl->getPrimaryTemplate();
1076 // Note - code synthesis context for the constraints check is created
1077 // inside CheckConstraintsSatisfaction.
1079 Template->getAssociatedConstraints(TemplateAC);
1080 if (TemplateAC.empty()) {
1081 Satisfaction.IsSatisfied = true;
1082 return false;
1083 }
1084
1085 // Enter the scope of this instantiation. We don't use
1086 // PushDeclContext because we don't have a scope.
1087 Sema::ContextRAII savedContext(*this, Decl);
1089
1090 std::optional<MultiLevelTemplateArgumentList> MLTAL =
1091 SetupConstraintCheckingTemplateArgumentsAndScope(Decl, TemplateArgs,
1092 Scope);
1093
1094 if (!MLTAL)
1095 return true;
1096
1097 Qualifiers ThisQuals;
1098 CXXRecordDecl *Record = nullptr;
1099 if (auto *Method = dyn_cast<CXXMethodDecl>(Decl)) {
1100 ThisQuals = Method->getMethodQualifiers();
1101 Record = Method->getParent();
1102 }
1103
1104 CXXThisScopeRAII ThisScope(*this, Record, ThisQuals, Record != nullptr);
1106 *this, const_cast<FunctionDecl *>(Decl), *MLTAL, Scope);
1107
1109 return CheckConstraintSatisfaction(Template, TemplateAC, Converted, *MLTAL,
1110 PointOfInstantiation, Satisfaction);
1111}
1112
1115 bool First) {
1116 assert(!Req->isSatisfied()
1117 && "Diagnose() can only be used on an unsatisfied requirement");
1118 switch (Req->getSatisfactionStatus()) {
1120 llvm_unreachable("Diagnosing a dependent requirement");
1121 break;
1123 auto *SubstDiag = Req->getExprSubstitutionDiagnostic();
1124 if (!SubstDiag->DiagMessage.empty())
1125 S.Diag(SubstDiag->DiagLoc,
1126 diag::note_expr_requirement_expr_substitution_error)
1127 << (int)First << SubstDiag->SubstitutedEntity
1128 << SubstDiag->DiagMessage;
1129 else
1130 S.Diag(SubstDiag->DiagLoc,
1131 diag::note_expr_requirement_expr_unknown_substitution_error)
1132 << (int)First << SubstDiag->SubstitutedEntity;
1133 break;
1134 }
1136 S.Diag(Req->getNoexceptLoc(),
1137 diag::note_expr_requirement_noexcept_not_met)
1138 << (int)First << Req->getExpr();
1139 break;
1141 auto *SubstDiag =
1143 if (!SubstDiag->DiagMessage.empty())
1144 S.Diag(SubstDiag->DiagLoc,
1145 diag::note_expr_requirement_type_requirement_substitution_error)
1146 << (int)First << SubstDiag->SubstitutedEntity
1147 << SubstDiag->DiagMessage;
1148 else
1149 S.Diag(SubstDiag->DiagLoc,
1150 diag::note_expr_requirement_type_requirement_unknown_substitution_error)
1151 << (int)First << SubstDiag->SubstitutedEntity;
1152 break;
1153 }
1155 ConceptSpecializationExpr *ConstraintExpr =
1157 if (ConstraintExpr->getTemplateArgsAsWritten()->NumTemplateArgs == 1) {
1158 // A simple case - expr type is the type being constrained and the concept
1159 // was not provided arguments.
1160 Expr *e = Req->getExpr();
1161 S.Diag(e->getBeginLoc(),
1162 diag::note_expr_requirement_constraints_not_satisfied_simple)
1164 << ConstraintExpr->getNamedConcept();
1165 } else {
1166 S.Diag(ConstraintExpr->getBeginLoc(),
1167 diag::note_expr_requirement_constraints_not_satisfied)
1168 << (int)First << ConstraintExpr;
1169 }
1171 break;
1172 }
1174 llvm_unreachable("We checked this above");
1175 }
1176}
1177
1180 bool First) {
1181 assert(!Req->isSatisfied()
1182 && "Diagnose() can only be used on an unsatisfied requirement");
1183 switch (Req->getSatisfactionStatus()) {
1185 llvm_unreachable("Diagnosing a dependent requirement");
1186 return;
1188 auto *SubstDiag = Req->getSubstitutionDiagnostic();
1189 if (!SubstDiag->DiagMessage.empty())
1190 S.Diag(SubstDiag->DiagLoc,
1191 diag::note_type_requirement_substitution_error) << (int)First
1192 << SubstDiag->SubstitutedEntity << SubstDiag->DiagMessage;
1193 else
1194 S.Diag(SubstDiag->DiagLoc,
1195 diag::note_type_requirement_unknown_substitution_error)
1196 << (int)First << SubstDiag->SubstitutedEntity;
1197 return;
1198 }
1199 default:
1200 llvm_unreachable("Unknown satisfaction status");
1201 return;
1202 }
1203}
1205 Expr *SubstExpr,
1206 bool First = true);
1207
1210 bool First) {
1211 using SubstitutionDiagnostic = std::pair<SourceLocation, StringRef>;
1212 for (auto &Record : Req->getConstraintSatisfaction()) {
1213 if (auto *SubstDiag = Record.dyn_cast<SubstitutionDiagnostic *>())
1214 S.Diag(SubstDiag->first, diag::note_nested_requirement_substitution_error)
1216 << SubstDiag->second;
1217 else
1219 First);
1220 First = false;
1221 }
1222}
1223
1225 Expr *SubstExpr,
1226 bool First) {
1227 SubstExpr = SubstExpr->IgnoreParenImpCasts();
1228 if (BinaryOperator *BO = dyn_cast<BinaryOperator>(SubstExpr)) {
1229 switch (BO->getOpcode()) {
1230 // These two cases will in practice only be reached when using fold
1231 // expressions with || and &&, since otherwise the || and && will have been
1232 // broken down into atomic constraints during satisfaction checking.
1233 case BO_LOr:
1234 // Or evaluated to false - meaning both RHS and LHS evaluated to false.
1237 /*First=*/false);
1238 return;
1239 case BO_LAnd: {
1240 bool LHSSatisfied =
1241 BO->getLHS()->EvaluateKnownConstInt(S.Context).getBoolValue();
1242 if (LHSSatisfied) {
1243 // LHS is true, so RHS must be false.
1245 return;
1246 }
1247 // LHS is false
1249
1250 // RHS might also be false
1251 bool RHSSatisfied =
1252 BO->getRHS()->EvaluateKnownConstInt(S.Context).getBoolValue();
1253 if (!RHSSatisfied)
1255 /*First=*/false);
1256 return;
1257 }
1258 case BO_GE:
1259 case BO_LE:
1260 case BO_GT:
1261 case BO_LT:
1262 case BO_EQ:
1263 case BO_NE:
1264 if (BO->getLHS()->getType()->isIntegerType() &&
1265 BO->getRHS()->getType()->isIntegerType()) {
1266 Expr::EvalResult SimplifiedLHS;
1267 Expr::EvalResult SimplifiedRHS;
1268 BO->getLHS()->EvaluateAsInt(SimplifiedLHS, S.Context,
1270 /*InConstantContext=*/true);
1271 BO->getRHS()->EvaluateAsInt(SimplifiedRHS, S.Context,
1273 /*InConstantContext=*/true);
1274 if (!SimplifiedLHS.Diag && ! SimplifiedRHS.Diag) {
1275 S.Diag(SubstExpr->getBeginLoc(),
1276 diag::note_atomic_constraint_evaluated_to_false_elaborated)
1277 << (int)First << SubstExpr
1278 << toString(SimplifiedLHS.Val.getInt(), 10)
1279 << BinaryOperator::getOpcodeStr(BO->getOpcode())
1280 << toString(SimplifiedRHS.Val.getInt(), 10);
1281 return;
1282 }
1283 }
1284 break;
1285
1286 default:
1287 break;
1288 }
1289 } else if (auto *CSE = dyn_cast<ConceptSpecializationExpr>(SubstExpr)) {
1290 if (CSE->getTemplateArgsAsWritten()->NumTemplateArgs == 1) {
1291 S.Diag(
1292 CSE->getSourceRange().getBegin(),
1293 diag::
1294 note_single_arg_concept_specialization_constraint_evaluated_to_false)
1295 << (int)First
1296 << CSE->getTemplateArgsAsWritten()->arguments()[0].getArgument()
1297 << CSE->getNamedConcept();
1298 } else {
1299 S.Diag(SubstExpr->getSourceRange().getBegin(),
1300 diag::note_concept_specialization_constraint_evaluated_to_false)
1301 << (int)First << CSE;
1302 }
1303 S.DiagnoseUnsatisfiedConstraint(CSE->getSatisfaction());
1304 return;
1305 } else if (auto *RE = dyn_cast<RequiresExpr>(SubstExpr)) {
1306 // FIXME: RequiresExpr should store dependent diagnostics.
1307 for (concepts::Requirement *Req : RE->getRequirements())
1308 if (!Req->isDependent() && !Req->isSatisfied()) {
1309 if (auto *E = dyn_cast<concepts::ExprRequirement>(Req))
1311 else if (auto *T = dyn_cast<concepts::TypeRequirement>(Req))
1313 else
1315 S, cast<concepts::NestedRequirement>(Req), First);
1316 break;
1317 }
1318 return;
1319 } else if (auto *TTE = dyn_cast<TypeTraitExpr>(SubstExpr);
1320 TTE && TTE->getTrait() == clang::TypeTrait::BTT_IsDeducible) {
1321 assert(TTE->getNumArgs() == 2);
1322 S.Diag(SubstExpr->getSourceRange().getBegin(),
1323 diag::note_is_deducible_constraint_evaluated_to_false)
1324 << TTE->getArg(0)->getType() << TTE->getArg(1)->getType();
1325 return;
1326 }
1327
1328 S.Diag(SubstExpr->getSourceRange().getBegin(),
1329 diag::note_atomic_constraint_evaluated_to_false)
1330 << (int)First << SubstExpr;
1331}
1332
1333template <typename SubstitutionDiagnostic>
1335 Sema &S, const llvm::PointerUnion<Expr *, SubstitutionDiagnostic *> &Record,
1336 bool First = true) {
1337 if (auto *Diag = Record.template dyn_cast<SubstitutionDiagnostic *>()) {
1338 S.Diag(Diag->first, diag::note_substituted_constraint_expr_is_ill_formed)
1339 << Diag->second;
1340 return;
1341 }
1342
1344 Record.template get<Expr *>(), First);
1345}
1346
1347void
1349 bool First) {
1350 assert(!Satisfaction.IsSatisfied &&
1351 "Attempted to diagnose a satisfied constraint");
1352 for (auto &Record : Satisfaction.Details) {
1354 First = false;
1355 }
1356}
1357
1359 const ASTConstraintSatisfaction &Satisfaction,
1360 bool First) {
1361 assert(!Satisfaction.IsSatisfied &&
1362 "Attempted to diagnose a satisfied constraint");
1363 for (auto &Record : Satisfaction) {
1365 First = false;
1366 }
1367}
1368
1371 NamedDecl *ConstrainedDecl, ArrayRef<const Expr *> AssociatedConstraints) {
1372 // In case the ConstrainedDecl comes from modules, it is necessary to use
1373 // the canonical decl to avoid different atomic constraints with the 'same'
1374 // declarations.
1375 ConstrainedDecl = cast<NamedDecl>(ConstrainedDecl->getCanonicalDecl());
1376
1377 auto CacheEntry = NormalizationCache.find(ConstrainedDecl);
1378 if (CacheEntry == NormalizationCache.end()) {
1379 auto Normalized =
1380 NormalizedConstraint::fromConstraintExprs(*this, ConstrainedDecl,
1381 AssociatedConstraints);
1382 CacheEntry =
1383 NormalizationCache
1384 .try_emplace(ConstrainedDecl,
1385 Normalized
1387 std::move(*Normalized))
1388 : nullptr)
1389 .first;
1390 }
1391 return CacheEntry->second;
1392}
1393
1395 Sema &S, NamedDecl *ConstrainedDecl,
1396 ArrayRef<const Expr *> AssociatedConstraints) {
1397 return S.getNormalizedAssociatedConstraints(ConstrainedDecl,
1398 AssociatedConstraints);
1399}
1400
1401static bool
1403 ConceptDecl *Concept,
1404 const MultiLevelTemplateArgumentList &MLTAL,
1405 const ASTTemplateArgumentListInfo *ArgsAsWritten) {
1406
1407 if (N.isCompound()) {
1408 if (substituteParameterMappings(S, N.getLHS(), Concept, MLTAL,
1409 ArgsAsWritten))
1410 return true;
1411 return substituteParameterMappings(S, N.getRHS(), Concept, MLTAL,
1412 ArgsAsWritten);
1413 }
1414
1415 if (N.isFoldExpanded()) {
1418 S, N.getFoldExpandedConstraint()->Constraint, Concept, MLTAL,
1419 ArgsAsWritten);
1420 }
1421
1422 TemplateParameterList *TemplateParams = Concept->getTemplateParameters();
1423
1425 TemplateArgumentListInfo SubstArgs;
1426 if (!Atomic.ParameterMapping) {
1427 llvm::SmallBitVector OccurringIndices(TemplateParams->size());
1428 S.MarkUsedTemplateParameters(Atomic.ConstraintExpr, /*OnlyDeduced=*/false,
1429 /*Depth=*/0, OccurringIndices);
1430 TemplateArgumentLoc *TempArgs =
1431 new (S.Context) TemplateArgumentLoc[OccurringIndices.count()];
1432 for (unsigned I = 0, J = 0, C = TemplateParams->size(); I != C; ++I)
1433 if (OccurringIndices[I])
1434 new (&(TempArgs)[J++])
1436 TemplateParams->begin()[I],
1437 // Here we assume we do not support things like
1438 // template<typename A, typename B>
1439 // concept C = ...;
1440 //
1441 // template<typename... Ts> requires C<Ts...>
1442 // struct S { };
1443 // The above currently yields a diagnostic.
1444 // We still might have default arguments for concept parameters.
1445 ArgsAsWritten->NumTemplateArgs > I
1446 ? ArgsAsWritten->arguments()[I].getLocation()
1447 : SourceLocation()));
1448 Atomic.ParameterMapping.emplace(TempArgs, OccurringIndices.count());
1449 }
1450 SourceLocation InstLocBegin =
1451 ArgsAsWritten->arguments().empty()
1452 ? ArgsAsWritten->getLAngleLoc()
1453 : ArgsAsWritten->arguments().front().getSourceRange().getBegin();
1454 SourceLocation InstLocEnd =
1455 ArgsAsWritten->arguments().empty()
1456 ? ArgsAsWritten->getRAngleLoc()
1457 : ArgsAsWritten->arguments().front().getSourceRange().getEnd();
1459 S, InstLocBegin,
1461 {InstLocBegin, InstLocEnd});
1462 if (Inst.isInvalid())
1463 return true;
1464 if (S.SubstTemplateArguments(*Atomic.ParameterMapping, MLTAL, SubstArgs))
1465 return true;
1466
1467 TemplateArgumentLoc *TempArgs =
1468 new (S.Context) TemplateArgumentLoc[SubstArgs.size()];
1469 std::copy(SubstArgs.arguments().begin(), SubstArgs.arguments().end(),
1470 TempArgs);
1471 Atomic.ParameterMapping.emplace(TempArgs, SubstArgs.size());
1472 return false;
1473}
1474
1476 const ConceptSpecializationExpr *CSE) {
1479 /*Final=*/false, CSE->getTemplateArguments(),
1480 /*RelativeToPrimary=*/true,
1481 /*Pattern=*/nullptr,
1482 /*ForConstraintInstantiation=*/true);
1483
1484 return substituteParameterMappings(S, N, CSE->getNamedConcept(), MLTAL,
1486}
1487
1492 : Constraint{CompoundConstraint{
1493 new(C) NormalizedConstraintPair{std::move(LHS), std::move(RHS)},
1494 Kind}} {}
1495
1497 const NormalizedConstraint &Other) {
1498 if (Other.isAtomic()) {
1499 Constraint = new (C) AtomicConstraint(*Other.getAtomicConstraint());
1500 } else if (Other.isFoldExpanded()) {
1502 Other.getFoldExpandedConstraint()->Kind,
1503 NormalizedConstraint(C, Other.getFoldExpandedConstraint()->Constraint),
1504 Other.getFoldExpandedConstraint()->Pattern);
1505 } else {
1507 new (C)
1509 NormalizedConstraint(C, Other.getRHS())},
1510 Other.getCompoundKind());
1511 }
1512}
1513
1515 assert(isCompound() && "getLHS called on a non-compound constraint.");
1516 return Constraint.get<CompoundConstraint>().getPointer()->LHS;
1517}
1518
1520 assert(isCompound() && "getRHS called on a non-compound constraint.");
1521 return Constraint.get<CompoundConstraint>().getPointer()->RHS;
1522}
1523
1524std::optional<NormalizedConstraint>
1525NormalizedConstraint::fromConstraintExprs(Sema &S, NamedDecl *D,
1527 assert(E.size() != 0);
1528 auto Conjunction = fromConstraintExpr(S, D, E[0]);
1529 if (!Conjunction)
1530 return std::nullopt;
1531 for (unsigned I = 1; I < E.size(); ++I) {
1532 auto Next = fromConstraintExpr(S, D, E[I]);
1533 if (!Next)
1534 return std::nullopt;
1535 *Conjunction = NormalizedConstraint(S.Context, std::move(*Conjunction),
1536 std::move(*Next), CCK_Conjunction);
1537 }
1538 return Conjunction;
1539}
1540
1541std::optional<NormalizedConstraint>
1542NormalizedConstraint::fromConstraintExpr(Sema &S, NamedDecl *D, const Expr *E) {
1543 assert(E != nullptr);
1544
1545 // C++ [temp.constr.normal]p1.1
1546 // [...]
1547 // - The normal form of an expression (E) is the normal form of E.
1548 // [...]
1549 E = E->IgnoreParenImpCasts();
1550
1551 // C++2a [temp.param]p4:
1552 // [...] If T is not a pack, then E is E', otherwise E is (E' && ...).
1553 // Fold expression is considered atomic constraints per current wording.
1554 // See http://cplusplus.github.io/concepts-ts/ts-active.html#28
1555
1556 if (LogicalBinOp BO = E) {
1557 auto LHS = fromConstraintExpr(S, D, BO.getLHS());
1558 if (!LHS)
1559 return std::nullopt;
1560 auto RHS = fromConstraintExpr(S, D, BO.getRHS());
1561 if (!RHS)
1562 return std::nullopt;
1563
1564 return NormalizedConstraint(S.Context, std::move(*LHS), std::move(*RHS),
1565 BO.isAnd() ? CCK_Conjunction : CCK_Disjunction);
1566 } else if (auto *CSE = dyn_cast<const ConceptSpecializationExpr>(E)) {
1567 const NormalizedConstraint *SubNF;
1568 {
1570 S, CSE->getExprLoc(),
1572 CSE->getSourceRange());
1573 if (Inst.isInvalid())
1574 return std::nullopt;
1575 // C++ [temp.constr.normal]p1.1
1576 // [...]
1577 // The normal form of an id-expression of the form C<A1, A2, ..., AN>,
1578 // where C names a concept, is the normal form of the
1579 // constraint-expression of C, after substituting A1, A2, ..., AN for C’s
1580 // respective template parameters in the parameter mappings in each atomic
1581 // constraint. If any such substitution results in an invalid type or
1582 // expression, the program is ill-formed; no diagnostic is required.
1583 // [...]
1584 ConceptDecl *CD = CSE->getNamedConcept();
1586 {CD->getConstraintExpr()});
1587 if (!SubNF)
1588 return std::nullopt;
1589 }
1590
1591 std::optional<NormalizedConstraint> New;
1592 New.emplace(S.Context, *SubNF);
1593
1594 if (substituteParameterMappings(S, *New, CSE))
1595 return std::nullopt;
1596
1597 return New;
1598 } else if (auto *FE = dyn_cast<const CXXFoldExpr>(E);
1599 FE && S.getLangOpts().CPlusPlus26 &&
1600 (FE->getOperator() == BinaryOperatorKind::BO_LAnd ||
1601 FE->getOperator() == BinaryOperatorKind::BO_LOr)) {
1602
1603 // Normalize fold expressions in C++26.
1604
1606 FE->getOperator() == BinaryOperatorKind::BO_LAnd
1609
1610 if (FE->getInit()) {
1611 auto LHS = fromConstraintExpr(S, D, FE->getLHS());
1612 auto RHS = fromConstraintExpr(S, D, FE->getRHS());
1613 if (!LHS || !RHS)
1614 return std::nullopt;
1615
1616 if (FE->isRightFold())
1618 Kind, std::move(*RHS), FE->getPattern()}};
1619 else
1621 Kind, std::move(*LHS), FE->getPattern()}};
1622
1623 return NormalizedConstraint(
1624 S.Context, std::move(*LHS), std::move(*RHS),
1625 FE->getOperator() == BinaryOperatorKind::BO_LAnd ? CCK_Conjunction
1626 : CCK_Disjunction);
1627 }
1628 auto Sub = fromConstraintExpr(S, D, FE->getPattern());
1629 if (!Sub)
1630 return std::nullopt;
1632 Kind, std::move(*Sub), FE->getPattern()}};
1633 }
1634
1635 return NormalizedConstraint{new (S.Context) AtomicConstraint(S, E)};
1636}
1637
1640
1641 // [C++26] [temp.constr.fold]
1642 // Two fold expanded constraints are compatible for subsumption
1643 // if their respective constraints both contain an equivalent unexpanded pack.
1644
1646 Sema::collectUnexpandedParameterPacks(const_cast<Expr *>(A.Pattern), APacks);
1647 Sema::collectUnexpandedParameterPacks(const_cast<Expr *>(B.Pattern), BPacks);
1648
1649 for (const UnexpandedParameterPack &APack : APacks) {
1650 std::pair<unsigned, unsigned> DepthAndIndex = getDepthAndIndex(APack);
1651 auto it = llvm::find_if(BPacks, [&](const UnexpandedParameterPack &BPack) {
1652 return getDepthAndIndex(BPack) == DepthAndIndex;
1653 });
1654 if (it != BPacks.end())
1655 return true;
1656 }
1657 return false;
1658}
1659
1661 if (Normalized.isAtomic())
1662 return {{Normalized.getAtomicConstraint()}};
1663
1664 else if (Normalized.isFoldExpanded())
1665 return {{Normalized.getFoldExpandedConstraint()}};
1666
1667 NormalForm LCNF = makeCNF(Normalized.getLHS());
1668 NormalForm RCNF = makeCNF(Normalized.getRHS());
1670 LCNF.reserve(LCNF.size() + RCNF.size());
1671 while (!RCNF.empty())
1672 LCNF.push_back(RCNF.pop_back_val());
1673 return LCNF;
1674 }
1675
1676 // Disjunction
1677 NormalForm Res;
1678 Res.reserve(LCNF.size() * RCNF.size());
1679 for (auto &LDisjunction : LCNF)
1680 for (auto &RDisjunction : RCNF) {
1681 NormalForm::value_type Combined;
1682 Combined.reserve(LDisjunction.size() + RDisjunction.size());
1683 std::copy(LDisjunction.begin(), LDisjunction.end(),
1684 std::back_inserter(Combined));
1685 std::copy(RDisjunction.begin(), RDisjunction.end(),
1686 std::back_inserter(Combined));
1687 Res.emplace_back(Combined);
1688 }
1689 return Res;
1690}
1691
1693 if (Normalized.isAtomic())
1694 return {{Normalized.getAtomicConstraint()}};
1695
1696 else if (Normalized.isFoldExpanded())
1697 return {{Normalized.getFoldExpandedConstraint()}};
1698
1699 NormalForm LDNF = makeDNF(Normalized.getLHS());
1700 NormalForm RDNF = makeDNF(Normalized.getRHS());
1702 LDNF.reserve(LDNF.size() + RDNF.size());
1703 while (!RDNF.empty())
1704 LDNF.push_back(RDNF.pop_back_val());
1705 return LDNF;
1706 }
1707
1708 // Conjunction
1709 NormalForm Res;
1710 Res.reserve(LDNF.size() * RDNF.size());
1711 for (auto &LConjunction : LDNF) {
1712 for (auto &RConjunction : RDNF) {
1713 NormalForm::value_type Combined;
1714 Combined.reserve(LConjunction.size() + RConjunction.size());
1715 std::copy(LConjunction.begin(), LConjunction.end(),
1716 std::back_inserter(Combined));
1717 std::copy(RConjunction.begin(), RConjunction.end(),
1718 std::back_inserter(Combined));
1719 Res.emplace_back(Combined);
1720 }
1721 }
1722 return Res;
1723}
1724
1727 NamedDecl *D2,
1729 bool &Result) {
1730 if (const auto *FD1 = dyn_cast<FunctionDecl>(D1)) {
1731 auto IsExpectedEntity = [](const FunctionDecl *FD) {
1733 return Kind == FunctionDecl::TK_NonTemplate ||
1735 };
1736 const auto *FD2 = dyn_cast<FunctionDecl>(D2);
1737 (void)IsExpectedEntity;
1738 (void)FD1;
1739 (void)FD2;
1740 assert(IsExpectedEntity(FD1) && FD2 && IsExpectedEntity(FD2) &&
1741 "use non-instantiated function declaration for constraints partial "
1742 "ordering");
1743 }
1744
1745 if (AC1.empty()) {
1746 Result = AC2.empty();
1747 return false;
1748 }
1749 if (AC2.empty()) {
1750 // TD1 has associated constraints and TD2 does not.
1751 Result = true;
1752 return false;
1753 }
1754
1755 std::pair<NamedDecl *, NamedDecl *> Key{D1, D2};
1756 auto CacheEntry = SubsumptionCache.find(Key);
1757 if (CacheEntry != SubsumptionCache.end()) {
1758 Result = CacheEntry->second;
1759 return false;
1760 }
1761
1762 unsigned Depth1 = CalculateTemplateDepthForConstraints(*this, D1, true);
1763 unsigned Depth2 = CalculateTemplateDepthForConstraints(*this, D2, true);
1764
1765 for (size_t I = 0; I != AC1.size() && I != AC2.size(); ++I) {
1766 if (Depth2 > Depth1) {
1767 AC1[I] = AdjustConstraintDepth(*this, Depth2 - Depth1)
1768 .TransformExpr(const_cast<Expr *>(AC1[I]))
1769 .get();
1770 } else if (Depth1 > Depth2) {
1771 AC2[I] = AdjustConstraintDepth(*this, Depth1 - Depth2)
1772 .TransformExpr(const_cast<Expr *>(AC2[I]))
1773 .get();
1774 }
1775 }
1776
1777 if (clang::subsumes(
1778 *this, D1, AC1, D2, AC2, Result,
1779 [this](const AtomicConstraint &A, const AtomicConstraint &B) {
1780 return A.subsumes(Context, B);
1781 }))
1782 return true;
1783 SubsumptionCache.try_emplace(Key, Result);
1784 return false;
1785}
1786
1789 if (isSFINAEContext())
1790 // No need to work here because our notes would be discarded.
1791 return false;
1792
1793 if (AC1.empty() || AC2.empty())
1794 return false;
1795
1796 auto NormalExprEvaluator =
1797 [this] (const AtomicConstraint &A, const AtomicConstraint &B) {
1798 return A.subsumes(Context, B);
1799 };
1800
1801 const Expr *AmbiguousAtomic1 = nullptr, *AmbiguousAtomic2 = nullptr;
1802 auto IdenticalExprEvaluator =
1803 [&] (const AtomicConstraint &A, const AtomicConstraint &B) {
1805 return false;
1806 const Expr *EA = A.ConstraintExpr, *EB = B.ConstraintExpr;
1807 if (EA == EB)
1808 return true;
1809
1810 // Not the same source level expression - are the expressions
1811 // identical?
1812 llvm::FoldingSetNodeID IDA, IDB;
1813 EA->Profile(IDA, Context, /*Canonical=*/true);
1814 EB->Profile(IDB, Context, /*Canonical=*/true);
1815 if (IDA != IDB)
1816 return false;
1817
1818 AmbiguousAtomic1 = EA;
1819 AmbiguousAtomic2 = EB;
1820 return true;
1821 };
1822
1823 {
1824 // The subsumption checks might cause diagnostics
1825 SFINAETrap Trap(*this);
1826 auto *Normalized1 = getNormalizedAssociatedConstraints(D1, AC1);
1827 if (!Normalized1)
1828 return false;
1829 const NormalForm DNF1 = makeDNF(*Normalized1);
1830 const NormalForm CNF1 = makeCNF(*Normalized1);
1831
1832 auto *Normalized2 = getNormalizedAssociatedConstraints(D2, AC2);
1833 if (!Normalized2)
1834 return false;
1835 const NormalForm DNF2 = makeDNF(*Normalized2);
1836 const NormalForm CNF2 = makeCNF(*Normalized2);
1837
1838 bool Is1AtLeastAs2Normally =
1839 clang::subsumes(DNF1, CNF2, NormalExprEvaluator);
1840 bool Is2AtLeastAs1Normally =
1841 clang::subsumes(DNF2, CNF1, NormalExprEvaluator);
1842 bool Is1AtLeastAs2 = clang::subsumes(DNF1, CNF2, IdenticalExprEvaluator);
1843 bool Is2AtLeastAs1 = clang::subsumes(DNF2, CNF1, IdenticalExprEvaluator);
1844 if (Is1AtLeastAs2 == Is1AtLeastAs2Normally &&
1845 Is2AtLeastAs1 == Is2AtLeastAs1Normally)
1846 // Same result - no ambiguity was caused by identical atomic expressions.
1847 return false;
1848 }
1849
1850 // A different result! Some ambiguous atomic constraint(s) caused a difference
1851 assert(AmbiguousAtomic1 && AmbiguousAtomic2);
1852
1853 Diag(AmbiguousAtomic1->getBeginLoc(), diag::note_ambiguous_atomic_constraints)
1854 << AmbiguousAtomic1->getSourceRange();
1855 Diag(AmbiguousAtomic2->getBeginLoc(),
1856 diag::note_ambiguous_atomic_constraints_similar_expression)
1857 << AmbiguousAtomic2->getSourceRange();
1858 return true;
1859}
1860
1862 Expr *E, bool IsSimple, SourceLocation NoexceptLoc,
1864 ConceptSpecializationExpr *SubstitutedConstraintExpr) :
1865 Requirement(IsSimple ? RK_Simple : RK_Compound, Status == SS_Dependent,
1866 Status == SS_Dependent &&
1867 (E->containsUnexpandedParameterPack() ||
1868 Req.containsUnexpandedParameterPack()),
1869 Status == SS_Satisfied), Value(E), NoexceptLoc(NoexceptLoc),
1870 TypeReq(Req), SubstitutedConstraintExpr(SubstitutedConstraintExpr),
1871 Status(Status) {
1872 assert((!IsSimple || (Req.isEmpty() && NoexceptLoc.isInvalid())) &&
1873 "Simple requirement must not have a return type requirement or a "
1874 "noexcept specification");
1875 assert((Status > SS_TypeRequirementSubstitutionFailure && Req.isTypeConstraint()) ==
1876 (SubstitutedConstraintExpr != nullptr));
1877}
1878
1880 SubstitutionDiagnostic *ExprSubstDiag, bool IsSimple,
1881 SourceLocation NoexceptLoc, ReturnTypeRequirement Req) :
1882 Requirement(IsSimple ? RK_Simple : RK_Compound, Req.isDependent(),
1883 Req.containsUnexpandedParameterPack(), /*IsSatisfied=*/false),
1884 Value(ExprSubstDiag), NoexceptLoc(NoexceptLoc), TypeReq(Req),
1885 Status(SS_ExprSubstitutionFailure) {
1886 assert((!IsSimple || (Req.isEmpty() && NoexceptLoc.isInvalid())) &&
1887 "Simple requirement must not have a return type requirement or a "
1888 "noexcept specification");
1889}
1890
1893 TypeConstraintInfo(TPL, false) {
1894 assert(TPL->size() == 1);
1895 const TypeConstraint *TC =
1896 cast<TemplateTypeParmDecl>(TPL->getParam(0))->getTypeConstraint();
1897 assert(TC &&
1898 "TPL must have a template type parameter with a type constraint");
1899 auto *Constraint =
1900 cast<ConceptSpecializationExpr>(TC->getImmediatelyDeclaredConstraint());
1901 bool Dependent =
1902 Constraint->getTemplateArgsAsWritten() &&
1904 Constraint->getTemplateArgsAsWritten()->arguments().drop_front(1));
1905 TypeConstraintInfo.setInt(Dependent ? true : false);
1906}
1907
1909 Requirement(RK_Type, T->getType()->isInstantiationDependentType(),
1910 T->getType()->containsUnexpandedParameterPack(),
1911 // We reach this ctor with either dependent types (in which
1912 // IsSatisfied doesn't matter) or with non-dependent type in
1913 // which the existence of the type indicates satisfaction.
1914 /*IsSatisfied=*/true),
1915 Value(T),
1916 Status(T->getType()->isInstantiationDependentType() ? SS_Dependent
1917 : SS_Satisfied) {}
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 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:758
static bool isInvalid(LocType Loc, bool *Invalid)
__DEVICE__ void * memcpy(void *__a, const void *__b, size_t __c)
__device__ int
APSInt & getInt()
Definition: APValue.h:423
bool isInt() const
Definition: APValue.h:401
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:186
QualType getReferenceQualifiedType(const Expr *e) const
getReferenceQualifiedType - Given an expr, will return the type for that expression,...
CanQualType BoolTy
Definition: ASTContext.h:1113
bool hasSameUnqualifiedType(QualType T1, QualType T2) const
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
Definition: ASTContext.h:2666
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:6619
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: Expr.h:6726
A builtin binary operation expression such as "x + y" or "x <= y".
Definition: Expr.h:3860
static OverloadedOperatorKind getOverloadedOperator(Opcode Opc)
Retrieve the overloaded operator kind that corresponds to the given binary opcode.
Definition: Expr.cpp:2181
StringRef getOpcodeStr() const
Definition: Expr.h:3925
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:4804
static Opcode getOverloadedOpcode(OverloadedOperatorKind OO)
Retrieve the binary opcode that corresponds to the given overloaded operator.
Definition: Expr.cpp:2143
Represents a C++ conversion function within a class.
Definition: DeclCXX.h:2862
Represents a folding of a pack over an operator.
Definition: ExprCXX.h:4838
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:50
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &C)
Definition: ASTConcept.h:61
llvm::SmallVector< Detail, 4 > Details
The substituted constraint expr, if the template arguments could be substituted into them,...
Definition: ASTConcept.h:59
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition: DeclBase.h:1425
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition: DeclBase.h:2079
bool isTransparentContext() const
isTransparentContext - Determines whether this context is a "transparent" context,...
Definition: DeclBase.cpp:1343
bool isDependentContext() const
Determines whether this context is dependent on a template parameter.
Definition: DeclBase.cpp:1309
DeclContext * getNonTransparentContext()
Definition: DeclBase.cpp:1390
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:1205
bool isParameterPack() const
Whether this declaration is a parameter pack.
Definition: DeclBase.cpp:242
FunctionDecl * getAsFunction() LLVM_READONLY
Returns the function itself, or the templated function if this is a function template.
Definition: DeclBase.cpp:249
bool isInvalidDecl() const
Definition: DeclBase.h:594
SourceLocation getLocation() const
Definition: DeclBase.h:445
DeclContext * getLexicalDeclContext()
getLexicalDeclContext - The declaration context where this Decl was lexically declared (LexicalDC).
Definition: DeclBase.h:897
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
Definition: DeclBase.h:957
virtual SourceRange getSourceRange() const LLVM_READONLY
Source range that this declaration covers.
Definition: DeclBase.h:433
Expr * getTrailingRequiresClause()
Get the constraint-expression introduced by the trailing requires-clause in the function/member decla...
Definition: Decl.h:807
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:3070
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:919
Represents a function declaration or definition.
Definition: Decl.h:1932
FunctionTemplateDecl * getDescribedFunctionTemplate() const
Retrieves the function template that is described by this function declaration.
Definition: Decl.cpp:4030
SourceLocation getPointOfInstantiation() const
Retrieve the (first) point of instantiation of a function template specialization or a member of a cl...
Definition: Decl.cpp:4348
ArrayRef< ParmVarDecl * > parameters() const
Definition: Decl.h:2646
FunctionTemplateDecl * getPrimaryTemplate() const
Retrieve the primary template that this function template specialization either specializes or was in...
Definition: Decl.cpp:4150
const TemplateArgumentList * getTemplateSpecializationArgs() const
Retrieve the template arguments used to produce this function template specialization from the primar...
Definition: Decl.cpp:4166
bool isTemplateInstantiation() const
Determines if the given function was instantiated from a function template.
Definition: Decl.cpp:4094
TemplatedKind
The kind of templated function a FunctionDecl can be.
Definition: Decl.h:1937
@ TK_MemberSpecialization
Definition: Decl.h:1944
@ TK_DependentNonTemplate
Definition: Decl.h:1953
@ TK_FunctionTemplateSpecialization
Definition: Decl.h:1948
TemplatedKind getTemplatedKind() const
What kind of templated function this is.
Definition: Decl.cpp:3981
FunctionDecl * getInstantiatedFromDecl() const
Definition: Decl.cpp:4054
FunctionDecl * getInstantiatedFromMemberFunction() const
If this function is an instantiation of a member function of a class template specialization,...
Definition: Decl.cpp:4002
Declaration of a template function.
Definition: DeclTemplate.h:957
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:2074
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
void InstantiatedLocal(const Decl *D, Decl *Inst)
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
unsigned getNumLevels() const
Determine the number of levels in this template argument list.
Definition: Template.h:123
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:249
void EmitToString(DiagnosticsEngine &Diags, SmallVectorImpl< char > &Buf) const
A (possibly-)qualified type.
Definition: Type.h:941
The collection of all-type qualifiers we support.
Definition: Type.h:319
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
RAII object used to change the argument pack substitution index within a Sema object.
Definition: Sema.h:13184
RAII object used to temporarily allow the C++ 'this' expression to be used, with the given qualifiers...
Definition: Sema.h:8055
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:12078
bool hasErrorOccurred() const
Determine whether any SFINAE errors have been trapped.
Definition: Sema.h:12108
SourceLocation getLocation() const
Definition: Sema.h:11855
bool ContainsDecl(const NamedDecl *ND) const
Definition: Sema.h:11845
const DeclContext * getDeclContext() const
Definition: Sema.h:11851
const NamedDecl * getDecl() const
Definition: Sema.h:11843
const DeclContext * getLexicalDeclContext() const
Definition: Sema.h:11847
Sema - This implements semantic analysis and AST building for C.
Definition: Sema.h:535
bool CheckInstantiatedFunctionTemplateConstraints(SourceLocation PointOfInstantiation, FunctionDecl *Decl, ArrayRef< TemplateArgument > TemplateArgs, ConstraintSatisfaction &Satisfaction)
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:1002
bool ConstraintExpressionDependsOnEnclosingTemplate(const FunctionDecl *Friend, unsigned TemplateDepth, const Expr *Constraint)
DiagnosticsEngine & getDiagnostics() const
Definition: Sema.h:597
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:92
bool SubstTemplateArguments(ArrayRef< TemplateArgumentLoc > Args, const MultiLevelTemplateArgumentList &TemplateArgs, TemplateArgumentListInfo &Outputs)
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:593
@ ReuseLambdaContextDecl
Definition: Sema.h:6533
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:14343
bool AreConstraintExpressionsEqual(const NamedDecl *Old, const Expr *OldConstr, const TemplateCompareNewDeclInfo &New, const Expr *NewConstr)
sema::FunctionScopeInfo * getCurFunction() const
Definition: Sema.h:1033
std::optional< unsigned > getNumArgumentsInExpansion(QualType T, const MultiLevelTemplateArgumentList &TemplateArgs)
Determine the number of arguments in the given pack expansion type.
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...
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:1287
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:14280
void PopSatisfactionStackEntry()
Definition: Sema.h:14286
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:14288
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.
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)
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)
Retrieve the template argument list(s) that should be used to instantiate the definition of the given...
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:326
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:338
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:394
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:413
Represents a C++ template name within the type system.
Definition: TemplateName.h:203
Stores a list of template parameters for a TemplateDecl and its derived classes.
Definition: DeclTemplate.h:73
NamedDecl * getParam(unsigned Idx)
Definition: DeclTemplate.h:144
static bool anyInstantiationDependentTemplateArguments(ArrayRef< TemplateArgumentLoc > Args)
Definition: Type.cpp:4270
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:228
Expr * getImmediatelyDeclaredConstraint() const
Get the immediately-declared constraint expression introduced by this type-constraint,...
Definition: ASTConcept.h:243
TyLocType push(QualType T)
Pushes space for a new TypeLoc of the given type.
A container of type source information.
Definition: Type.h:7714
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:1829
bool isSpecificBuiltinType(unsigned K) const
Test for a particular builtin type.
Definition: Type.h:8264
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
Definition: Type.h:2672
bool isFunctionType() const
Definition: Type.h:7992
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Definition: Decl.h:667
QualType getType() const
Definition: Decl.h:678
bool isInitCapture() const
Whether this variable is the implicit variable for a lambda init-capture.
Definition: Decl.cpp:5359
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:376
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:57
@ CPlusPlus26
Definition: LangStandard.h:62
NormalForm makeDNF(const NormalizedConstraint &Normalized)
@ OK_Ordinary
An ordinary object is located at an address in memory.
Definition: Specifiers.h:148
bool subsumes(const NormalForm &PDNF, const NormalForm &QCNF, const AtomicSubsumptionEvaluator &E)
Definition: SemaConcept.h:196
ExprResult ExprEmpty()
Definition: Ownership.h:271
bool isLambdaCallOperator(const CXXMethodDecl *MD)
Definition: ASTLambda.h:27
@ Result
The result type of a method or function.
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.
std::pair< unsigned, unsigned > getDepthAndIndex(NamedDecl *ND)
Retrieve the depth and index of a template parameter.
Definition: SemaInternal.h:61
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:132
const FunctionProtoType * T
std::pair< llvm::PointerUnion< const TemplateTypeParmType *, NamedDecl * >, SourceLocation > UnexpandedParameterPack
Definition: Sema.h:258
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
#define bool
Definition: stdbool.h:24
The result of a constraint satisfaction check, containing the necessary information to diagnose an un...
Definition: ASTConcept.h:90
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:59
bool hasMatchingParameterMapping(ASTContext &C, const AtomicConstraint &Other) const
Definition: SemaConcept.h:38
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:176
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:105
llvm::PointerUnion< AtomicConstraint *, FoldExpandedConstraint *, CompoundConstraint > Constraint
Definition: SemaConcept.h:115
NormalizedConstraint & getRHS() const
llvm::PointerIntPair< NormalizedConstraintPair *, 1, CompoundConstraintKind > CompoundConstraint
Definition: SemaConcept.h:111
AtomicConstraint * getAtomicConstraint() const
Definition: SemaConcept.h:151
NormalizedConstraint(AtomicConstraint *C)
Definition: SemaConcept.h:117
CompoundConstraintKind getCompoundKind() const
Definition: SemaConcept.h:143
NormalizedConstraint & getLHS() const
FoldExpandedConstraint * getFoldExpandedConstraint() const
Definition: SemaConcept.h:157
A stack object to be created when performing template instantiation.
Definition: Sema.h:12837
bool isInvalid() const
Determines whether we have exceeded the maximum recursive template instantiations.
Definition: Sema.h:12991