29#include "llvm/ADT/DenseMap.h"
30#include "llvm/ADT/PointerUnion.h"
31#include "llvm/ADT/StringExtras.h"
41 const Expr *LHS =
nullptr;
42 const Expr *RHS =
nullptr;
45 LogicalBinOp(
const Expr *
E) {
46 if (
auto *BO = dyn_cast<BinaryOperator>(
E)) {
50 Loc = BO->getExprLoc();
51 }
else if (
auto *OO = dyn_cast<CXXOperatorCallExpr>(
E)) {
53 if (OO->getNumArgs() == 2) {
54 Op = OO->getOperator();
57 Loc = OO->getOperatorLoc();
62 bool isAnd()
const {
return Op == OO_AmpAmp; }
63 bool isOr()
const {
return Op == OO_PipePipe; }
64 explicit operator bool()
const {
return isAnd() || isOr(); }
66 const Expr *getLHS()
const {
return LHS; }
67 const Expr *getRHS()
const {
return RHS; }
71 return recreateBinOp(SemaRef, LHS,
const_cast<Expr *
>(getRHS()));
76 assert((isAnd() || isOr()) &&
"Not the right kind of op?");
93 Token NextToken,
bool *PossibleNonPrimary,
94 bool IsTrailingRequiresClause) {
100 if (LogicalBinOp BO = ConstraintExpression) {
102 PossibleNonPrimary) &&
105 }
else if (
auto *
C = dyn_cast<ExprWithCleanups>(ConstraintExpression))
111 auto CheckForNonPrimary = [&] {
112 if (!PossibleNonPrimary)
115 *PossibleNonPrimary =
126 (NextToken.
is(tok::l_paren) &&
127 (IsTrailingRequiresClause ||
129 isa<UnresolvedLookupExpr>(ConstraintExpression) &&
145 CheckForNonPrimary();
151 diag::err_non_bool_atomic_constraint) <<
Type
153 CheckForNonPrimary();
157 if (PossibleNonPrimary)
158 *PossibleNonPrimary =
false;
163struct SatisfactionStackRAII {
165 bool Inserted =
false;
167 const llvm::FoldingSetNodeID &FSNID)
174 ~SatisfactionStackRAII() {
181template <
typename Constra
intEvaluator>
185 const ConstraintEvaluator &Evaluator);
187template <
typename Constra
intEvaluator>
192 const ConstraintEvaluator &Evaluator) {
193 size_t EffectiveDetailEndIndex = Satisfaction.
Details.size();
203 if (Op == clang::OO_PipePipe && IsLHSSatisfied)
213 if (Op == clang::OO_AmpAmp && !IsLHSSatisfied)
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());
252template <
typename Constra
intEvaluator>
256 const ConstraintEvaluator &Evaluator) {
257 bool Conjunction = FE->
getOperator() == BinaryOperatorKind::BO_LAnd;
258 size_t EffectiveDetailEndIndex = Satisfaction.
Details.size();
274 std::optional<unsigned> NumExpansions =
275 Evaluator.EvaluateFoldExpandedConstraintSize(FE);
278 for (
unsigned I = 0; I < *NumExpansions; I++) {
281 Satisfaction, Evaluator);
285 if (!Conjunction && IsRHSSatisfied) {
286 auto EffectiveDetailEnd = Satisfaction.
Details.begin();
287 std::advance(EffectiveDetailEnd, EffectiveDetailEndIndex);
288 Satisfaction.
Details.erase(EffectiveDetailEnd,
298 if (Conjunction != IsRHSSatisfied)
304 Satisfaction, Evaluator);
324template <
typename Constra
intEvaluator>
328 const ConstraintEvaluator &Evaluator) {
331 if (LogicalBinOp BO = ConstraintExpr)
333 S, BO.getLHS(), BO.getOp(), BO.getRHS(), Satisfaction, Evaluator);
335 if (
auto *
C = dyn_cast<ExprWithCleanups>(ConstraintExpr)) {
342 if (
auto *FE = dyn_cast<CXXFoldExpr>(ConstraintExpr);
344 (FE->getOperator() == BinaryOperatorKind::BO_LAnd ||
345 FE->getOperator() == BinaryOperatorKind::BO_LOr)) {
351 Evaluator.EvaluateAtomicConstraint(ConstraintExpr);
356 if (!SubstitutedAtomicExpr.
isUsable())
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;
387 EvalResult.
Diag = &EvaluationDiags;
390 !EvaluationDiags.empty()) {
394 diag::err_non_constant_constraint_expression)
397 S.
Diag(PDiag.first, PDiag.second);
402 "evaluating bool expression didn't produce int");
405 Satisfaction.
Details.emplace_back(SubstitutedAtomicExpr.
get());
407 return SubstitutedAtomicExpr;
415 for (
const auto &List : MLTAL)
439 struct ConstraintEvaluator {
448 S, Sema::ExpressionEvaluationContext::ConstantEvaluated,
463 llvm::FoldingSetNodeID
ID;
471 SatisfactionStackRAII StackRAII(S, Template,
ID);
475 SubstitutedExpression =
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)});
526 CK_LValueToRValue, SubstitutedExpression.
get(),
529 return SubstitutedExpression;
532 std::optional<unsigned>
533 EvaluateFoldExpandedConstraintSize(
const CXXFoldExpr *FE)
const {
542 assert(!Unexpanded.empty() &&
"Pack expansion without parameter packs?");
544 bool RetainExpansion =
false;
546 NumExpansions = OrigNumExpansions;
549 MLTAL, Expand, RetainExpansion, NumExpansions) ||
550 !Expand || RetainExpansion)
553 if (NumExpansions && S.
getLangOpts().BracketDepth < NumExpansions) {
555 clang::diag::err_fold_expression_limit_exceeded)
561 return NumExpansions;
566 S, ConstraintExpr, Satisfaction,
567 ConstraintEvaluator{S, Template, TemplateNameLoc, MLTAL, Satisfaction});
575 if (ConstraintExprs.empty()) {
592 const_cast<NamedDecl *
>(Template), TemplateArgs, TemplateIDRange);
596 for (
const Expr *ConstraintExpr : ConstraintExprs) {
598 S, Template, TemplateIDRange.
getBegin(), TemplateArgsLists,
599 ConstraintExpr, Satisfaction);
603 Converted.push_back(Res.
get());
607 Converted.append(ConstraintExprs.size() - Converted.size(),
nullptr);
623 if (ConstraintExprs.empty()) {
628 return ::CheckConstraintSatisfaction(
629 *
this,
nullptr, ConstraintExprs, ConvertedConstraints,
630 TemplateArgsLists, TemplateIDRange, OutSatisfaction);
644 for (
auto List : TemplateArgsLists)
645 FlattenedArgs.insert(FlattenedArgs.end(), List.Args.begin(),
648 llvm::FoldingSetNodeID ID;
651 if (
auto *Cached = SatisfactionCache.FindNodeOrInsertPos(ID, InsertPos)) {
652 OutSatisfaction = *Cached;
657 std::make_unique<ConstraintSatisfaction>(Template, FlattenedArgs);
659 ConvertedConstraints, TemplateArgsLists,
660 TemplateIDRange, *Satisfaction)) {
661 OutSatisfaction = *Satisfaction;
665 if (
auto *Cached = SatisfactionCache.FindNodeOrInsertPos(ID, InsertPos)) {
674 OutSatisfaction = *Cached;
679 OutSatisfaction = *Satisfaction;
683 SatisfactionCache.InsertNode(Satisfaction.release());
690 struct ConstraintEvaluator {
696 std::optional<unsigned>
697 EvaluateFoldExpandedConstraintSize(
const CXXFoldExpr *FE)
const {
703 ConstraintEvaluator{*
this})
707bool Sema::addInstantiatedCapturesToScope(
711 const auto *LambdaClass = cast<CXXMethodDecl>(
Function)->getParent();
712 const auto *LambdaPattern = cast<CXXMethodDecl>(PatternDecl)->getParent();
714 unsigned Instantiated = 0;
716 auto AddSingleCapture = [&](
const ValueDecl *CapturedPattern,
718 ValueDecl *CapturedVar = LambdaClass->getCapture(Index)->getCapturedVar();
720 Scope.InstantiatedLocal(CapturedPattern, CapturedVar);
723 for (
const LambdaCapture &CapturePattern : LambdaPattern->captures()) {
724 if (!CapturePattern.capturesVariable()) {
728 ValueDecl *CapturedPattern = CapturePattern.getCapturedVar();
735 AddSingleCapture(CapturedPattern, Instantiated++);
737 Scope.MakeInstantiatedLocalArgPack(CapturedPattern);
740 dyn_cast<VarDecl>(CapturedPattern)->getInit(), Unexpanded);
741 auto NumArgumentsInExpansion =
743 if (!NumArgumentsInExpansion)
745 for (
unsigned Arg = 0; Arg < *NumArgumentsInExpansion; ++Arg)
746 AddSingleCapture(CapturedPattern, Instantiated++);
752bool Sema::SetupConstraintScope(
758 InstantiatingTemplate Inst(
763 if (Inst.isInvalid())
774 if (addInstantiatedParametersToScope(
787 while (FromMemTempl->getInstantiatedFromMemberTemplate())
788 FromMemTempl = FromMemTempl->getInstantiatedFromMemberTemplate();
789 if (addInstantiatedParametersToScope(FD, FromMemTempl->getTemplatedDecl(),
804 InstantiatingTemplate Inst(
809 if (Inst.isInvalid())
814 if (addInstantiatedParametersToScope(FD, InstantiatedFrom,
Scope, MLTAL))
823std::optional<MultiLevelTemplateArgumentList>
824Sema::SetupConstraintCheckingTemplateArgumentsAndScope(
838 if (SetupConstraintScope(FD, TemplateArgs, MLTAL,
Scope))
847 bool ForOverloadResolution) {
866 if (
const auto *MD = dyn_cast<CXXConversionDecl>(FD);
869 Satisfaction, UsageLoc,
883 std::optional<MultiLevelTemplateArgumentList> MLTAL =
884 SetupConstraintCheckingTemplateArgumentsAndScope(
892 if (
auto *Method = dyn_cast<CXXMethodDecl>(FD)) {
893 ThisQuals = Method->getMethodQualifiers();
900 ForOverloadResolution);
914 bool SkipForSpecialization =
false) {
920 true, SkipForSpecialization);
925 class AdjustConstraintDepth :
public TreeTransform<AdjustConstraintDepth> {
926 unsigned TemplateDepth = 0;
929 AdjustConstraintDepth(
Sema &SemaRef,
unsigned TemplateDepth)
930 : inherited(SemaRef), TemplateDepth(TemplateDepth) {}
932 using inherited::TransformTemplateTypeParmType;
939 NewTTPDecl = cast_or_null<TemplateTypeParmDecl>(
942 QualType Result = getSema().Context.getTemplateTypeParmType(
943 T->getDepth() + TemplateDepth,
T->getIndex(),
T->isParameterPack(),
954 const Expr *ConstrExpr) {
983 std::optional<Sema::CXXThisScopeRAII> ThisScope;
992 std::optional<Sema::ContextRAII> ContextScope;
993 if (
auto *RD = dyn_cast<CXXRecordDecl>(DeclInfo.
getDeclContext())) {
995 ContextScope.emplace(S,
const_cast<DeclContext *
>(cast<DeclContext>(RD)),
1002 return SubstConstr.
get();
1006 const Expr *OldConstr,
1008 const Expr *NewConstr) {
1009 if (OldConstr == NewConstr)
1014 if (
const Expr *SubstConstr =
1017 OldConstr = SubstConstr;
1020 if (
const Expr *SubstConstr =
1023 NewConstr = SubstConstr;
1028 llvm::FoldingSetNodeID ID1, ID2;
1041 "Non-function templates don't need to be checked");
1047 for (
const Expr *Constraint : ACs)
1062 TemplateIDRange, Satisfaction))
1067 TemplateArgString =
" ";
1073 diag::err_template_arg_list_constraints_not_satisfied)
1075 << TemplateArgString << TemplateIDRange;
1092 if (TemplateAC.empty()) {
1102 std::optional<MultiLevelTemplateArgumentList> MLTAL =
1103 SetupConstraintCheckingTemplateArgumentsAndScope(
Decl, TemplateArgs,
1111 if (
auto *Method = dyn_cast<CXXMethodDecl>(
Decl)) {
1112 ThisQuals = Method->getMethodQualifiers();
1113 Record = Method->getParent();
1122 PointOfInstantiation, Satisfaction);
1129 &&
"Diagnose() can only be used on an unsatisfied requirement");
1132 llvm_unreachable(
"Diagnosing a dependent requirement");
1136 if (!SubstDiag->DiagMessage.empty())
1137 S.
Diag(SubstDiag->DiagLoc,
1138 diag::note_expr_requirement_expr_substitution_error)
1139 << (
int)
First << SubstDiag->SubstitutedEntity
1140 << SubstDiag->DiagMessage;
1142 S.
Diag(SubstDiag->DiagLoc,
1143 diag::note_expr_requirement_expr_unknown_substitution_error)
1144 << (
int)
First << SubstDiag->SubstitutedEntity;
1149 diag::note_expr_requirement_noexcept_not_met)
1155 if (!SubstDiag->DiagMessage.empty())
1156 S.
Diag(SubstDiag->DiagLoc,
1157 diag::note_expr_requirement_type_requirement_substitution_error)
1158 << (
int)
First << SubstDiag->SubstitutedEntity
1159 << SubstDiag->DiagMessage;
1161 S.
Diag(SubstDiag->DiagLoc,
1162 diag::note_expr_requirement_type_requirement_unknown_substitution_error)
1163 << (
int)
First << SubstDiag->SubstitutedEntity;
1174 diag::note_expr_requirement_constraints_not_satisfied_simple)
1179 diag::note_expr_requirement_constraints_not_satisfied)
1180 << (
int)
First << ConstraintExpr;
1186 llvm_unreachable(
"We checked this above");
1194 &&
"Diagnose() can only be used on an unsatisfied requirement");
1197 llvm_unreachable(
"Diagnosing a dependent requirement");
1201 if (!SubstDiag->DiagMessage.empty())
1202 S.
Diag(SubstDiag->DiagLoc,
1203 diag::note_type_requirement_substitution_error) << (
int)
First
1204 << SubstDiag->SubstitutedEntity << SubstDiag->DiagMessage;
1206 S.
Diag(SubstDiag->DiagLoc,
1207 diag::note_type_requirement_unknown_substitution_error)
1208 << (
int)
First << SubstDiag->SubstitutedEntity;
1212 llvm_unreachable(
"Unknown satisfaction status");
1223 using SubstitutionDiagnostic = std::pair<SourceLocation, StringRef>;
1225 if (
auto *SubstDiag =
Record.dyn_cast<SubstitutionDiagnostic *>())
1226 S.
Diag(SubstDiag->first, diag::note_nested_requirement_substitution_error)
1228 << SubstDiag->second;
1241 switch (BO->getOpcode()) {
1253 BO->getLHS()->EvaluateKnownConstInt(S.
Context).getBoolValue();
1264 BO->getRHS()->EvaluateKnownConstInt(S.
Context).getBoolValue();
1276 if (BO->getLHS()->getType()->isIntegerType() &&
1277 BO->getRHS()->getType()->isIntegerType()) {
1280 BO->getLHS()->EvaluateAsInt(SimplifiedLHS, S.
Context,
1283 BO->getRHS()->EvaluateAsInt(SimplifiedRHS, S.
Context,
1286 if (!SimplifiedLHS.
Diag && ! SimplifiedRHS.
Diag) {
1288 diag::note_atomic_constraint_evaluated_to_false_elaborated)
1301 }
else if (
auto *CSE = dyn_cast<ConceptSpecializationExpr>(SubstExpr)) {
1302 if (CSE->getTemplateArgsAsWritten()->NumTemplateArgs == 1) {
1304 CSE->getSourceRange().getBegin(),
1306 note_single_arg_concept_specialization_constraint_evaluated_to_false)
1308 << CSE->getTemplateArgsAsWritten()->arguments()[0].getArgument()
1309 << CSE->getNamedConcept();
1312 diag::note_concept_specialization_constraint_evaluated_to_false)
1313 << (
int)
First << CSE;
1317 }
else if (
auto *RE = dyn_cast<RequiresExpr>(SubstExpr)) {
1320 if (!Req->isDependent() && !Req->isSatisfied()) {
1321 if (
auto *
E = dyn_cast<concepts::ExprRequirement>(Req))
1323 else if (
auto *
T = dyn_cast<concepts::TypeRequirement>(Req))
1327 S, cast<concepts::NestedRequirement>(Req),
First);
1331 }
else if (
auto *TTE = dyn_cast<TypeTraitExpr>(SubstExpr);
1332 TTE && TTE->getTrait() == clang::TypeTrait::BTT_IsDeducible) {
1333 assert(TTE->getNumArgs() == 2);
1335 diag::note_is_deducible_constraint_evaluated_to_false)
1336 << TTE->getArg(0)->getType() << TTE->getArg(1)->getType();
1341 diag::note_atomic_constraint_evaluated_to_false)
1345template <
typename SubstitutionDiagnostic>
1347 Sema &S,
const llvm::PointerUnion<Expr *, SubstitutionDiagnostic *> &
Record,
1348 bool First =
true) {
1349 if (
auto *
Diag =
Record.template dyn_cast<SubstitutionDiagnostic *>()) {
1350 S.
Diag(
Diag->first, diag::note_substituted_constraint_expr_is_ill_formed)
1363 "Attempted to diagnose a satisfied constraint");
1374 "Attempted to diagnose a satisfied constraint");
1375 for (
auto &
Record : Satisfaction) {
1389 auto CacheEntry = NormalizationCache.find(ConstrainedDecl);
1390 if (CacheEntry == NormalizationCache.end()) {
1392 NormalizedConstraint::fromConstraintExprs(*
this, ConstrainedDecl,
1393 AssociatedConstraints);
1396 .try_emplace(ConstrainedDecl,
1399 std::move(*Normalized))
1403 return CacheEntry->second;
1410 AssociatedConstraints);
1438 if (!
Atomic.ParameterMapping) {
1439 llvm::SmallBitVector OccurringIndices(TemplateParams->
size());
1441 0, OccurringIndices);
1444 for (
unsigned I = 0, J = 0,
C = TemplateParams->
size(); I !=
C; ++I)
1445 if (OccurringIndices[I])
1446 new (&(TempArgs)[J++])
1448 TemplateParams->
begin()[I],
1458 ? ArgsAsWritten->
arguments()[I].getLocation()
1460 Atomic.ParameterMapping.emplace(TempArgs, OccurringIndices.count());
1465 : ArgsAsWritten->
arguments().front().getSourceRange().getBegin();
1469 : ArgsAsWritten->
arguments().front().getSourceRange().getEnd();
1473 Atomic.ConstraintDecl, {InstLocBegin, InstLocEnd});
1474 if (Inst.isInvalid())
1483 Atomic.ParameterMapping.emplace(TempArgs, SubstArgs.
size());
1510 if (
Other.isAtomic()) {
1512 }
else if (
Other.isFoldExpanded()) {
1514 Other.getFoldExpandedConstraint()->Kind,
1516 Other.getFoldExpandedConstraint()->Pattern);
1522 Other.getCompoundKind());
1527 assert(
isCompound() &&
"getLHS called on a non-compound constraint.");
1532 assert(
isCompound() &&
"getRHS called on a non-compound constraint.");
1536std::optional<NormalizedConstraint>
1539 assert(
E.size() != 0);
1540 auto Conjunction = fromConstraintExpr(S,
D,
E[0]);
1542 return std::nullopt;
1543 for (
unsigned I = 1; I <
E.size(); ++I) {
1544 auto Next = fromConstraintExpr(S,
D,
E[I]);
1546 return std::nullopt;
1553std::optional<NormalizedConstraint>
1555 assert(
E !=
nullptr);
1568 if (LogicalBinOp BO =
E) {
1569 auto LHS = fromConstraintExpr(S,
D, BO.getLHS());
1571 return std::nullopt;
1572 auto RHS = fromConstraintExpr(S,
D, BO.getRHS());
1574 return std::nullopt;
1578 }
else if (
auto *CSE = dyn_cast<const ConceptSpecializationExpr>(
E)) {
1582 S, CSE->getExprLoc(),
1585 if (Inst.isInvalid())
1586 return std::nullopt;
1600 return std::nullopt;
1603 std::optional<NormalizedConstraint> New;
1604 New.emplace(S.
Context, *SubNF);
1607 return std::nullopt;
1610 }
else if (
auto *FE = dyn_cast<const CXXFoldExpr>(
E);
1612 (FE->getOperator() == BinaryOperatorKind::BO_LAnd ||
1613 FE->getOperator() == BinaryOperatorKind::BO_LOr)) {
1618 FE->getOperator() == BinaryOperatorKind::BO_LAnd
1622 if (FE->getInit()) {
1623 auto LHS = fromConstraintExpr(S,
D, FE->getLHS());
1624 auto RHS = fromConstraintExpr(S,
D, FE->getRHS());
1626 return std::nullopt;
1628 if (FE->isRightFold())
1630 Kind, std::move(*RHS), FE->getPattern()}};
1633 Kind, std::move(*LHS), FE->getPattern()}};
1636 S.
Context, std::move(*LHS), std::move(*RHS),
1640 auto Sub = fromConstraintExpr(S,
D, FE->getPattern());
1642 return std::nullopt;
1644 Kind, std::move(*Sub), FE->getPattern()}};
1666 if (it != BPacks.end())
1682 LCNF.reserve(LCNF.size() + RCNF.size());
1683 while (!RCNF.empty())
1684 LCNF.push_back(RCNF.pop_back_val());
1690 Res.reserve(LCNF.size() * RCNF.size());
1691 for (
auto &LDisjunction : LCNF)
1692 for (
auto &RDisjunction : RCNF) {
1693 NormalForm::value_type Combined;
1694 Combined.reserve(LDisjunction.size() + RDisjunction.size());
1695 std::copy(LDisjunction.begin(), LDisjunction.end(),
1696 std::back_inserter(Combined));
1697 std::copy(RDisjunction.begin(), RDisjunction.end(),
1698 std::back_inserter(Combined));
1699 Res.emplace_back(Combined);
1714 LDNF.reserve(LDNF.size() + RDNF.size());
1715 while (!RDNF.empty())
1716 LDNF.push_back(RDNF.pop_back_val());
1722 Res.reserve(LDNF.size() * RDNF.size());
1723 for (
auto &LConjunction : LDNF) {
1724 for (
auto &RConjunction : RDNF) {
1725 NormalForm::value_type Combined;
1726 Combined.reserve(LConjunction.size() + RConjunction.size());
1727 std::copy(LConjunction.begin(), LConjunction.end(),
1728 std::back_inserter(Combined));
1729 std::copy(RConjunction.begin(), RConjunction.end(),
1730 std::back_inserter(Combined));
1731 Res.emplace_back(Combined);
1742 if (
const auto *FD1 = dyn_cast<FunctionDecl>(D1)) {
1748 const auto *FD2 = dyn_cast<FunctionDecl>(D2);
1749 (void)IsExpectedEntity;
1752 assert(IsExpectedEntity(FD1) && FD2 && IsExpectedEntity(FD2) &&
1753 "use non-instantiated function declaration for constraints partial "
1767 std::pair<NamedDecl *, NamedDecl *> Key{D1, D2};
1768 auto CacheEntry = SubsumptionCache.find(Key);
1769 if (CacheEntry != SubsumptionCache.end()) {
1770 Result = CacheEntry->second;
1777 for (
size_t I = 0; I != AC1.size() && I != AC2.size(); ++I) {
1778 if (Depth2 > Depth1) {
1779 AC1[I] = AdjustConstraintDepth(*
this, Depth2 - Depth1)
1780 .TransformExpr(
const_cast<Expr *
>(AC1[I]))
1782 }
else if (Depth1 > Depth2) {
1783 AC2[I] = AdjustConstraintDepth(*
this, Depth1 - Depth2)
1784 .TransformExpr(
const_cast<Expr *
>(AC2[I]))
1790 *
this, D1, AC1, D2, AC2,
Result,
1795 SubsumptionCache.try_emplace(Key,
Result);
1805 if (AC1.empty() || AC2.empty())
1808 auto NormalExprEvaluator =
1813 const Expr *AmbiguousAtomic1 =
nullptr, *AmbiguousAtomic2 =
nullptr;
1814 auto IdenticalExprEvaluator =
1824 llvm::FoldingSetNodeID IDA, IDB;
1826 EB->Profile(IDB,
Context,
true);
1830 AmbiguousAtomic1 = EA;
1831 AmbiguousAtomic2 = EB;
1850 bool Is1AtLeastAs2Normally =
1852 bool Is2AtLeastAs1Normally =
1854 bool Is1AtLeastAs2 =
clang::subsumes(DNF1, CNF2, IdenticalExprEvaluator);
1855 bool Is2AtLeastAs1 =
clang::subsumes(DNF2, CNF1, IdenticalExprEvaluator);
1856 if (Is1AtLeastAs2 == Is1AtLeastAs2Normally &&
1857 Is2AtLeastAs1 == Is2AtLeastAs1Normally)
1863 assert(AmbiguousAtomic1 && AmbiguousAtomic2);
1865 Diag(AmbiguousAtomic1->
getBeginLoc(), diag::note_ambiguous_atomic_constraints)
1867 Diag(AmbiguousAtomic2->getBeginLoc(),
1868 diag::note_ambiguous_atomic_constraints_similar_expression)
1869 << AmbiguousAtomic2->getSourceRange();
1877 Requirement(IsSimple ? RK_Simple : RK_Compound, Status == SS_Dependent,
1878 Status == SS_Dependent &&
1879 (
E->containsUnexpandedParameterPack() ||
1880 Req.containsUnexpandedParameterPack()),
1881 Status == SS_Satisfied),
Value(
E), NoexceptLoc(NoexceptLoc),
1882 TypeReq(Req), SubstitutedConstraintExpr(SubstitutedConstraintExpr),
1885 "Simple requirement must not have a return type requirement or a "
1886 "noexcept specification");
1888 (SubstitutedConstraintExpr !=
nullptr));
1894 Requirement(IsSimple ? RK_Simple : RK_Compound, Req.isDependent(),
1895 Req.containsUnexpandedParameterPack(),
false),
1896 Value(ExprSubstDiag), NoexceptLoc(NoexceptLoc), TypeReq(Req),
1897 Status(SS_ExprSubstitutionFailure) {
1899 "Simple requirement must not have a return type requirement or a "
1900 "noexcept specification");
1905 TypeConstraintInfo(TPL,
false) {
1906 assert(TPL->
size() == 1);
1908 cast<TemplateTypeParmDecl>(TPL->
getParam(0))->getTypeConstraint();
1910 "TPL must have a template type parameter with a type constraint");
1914 Constraint->getTemplateArgsAsWritten() &&
1916 Constraint->getTemplateArgsAsWritten()->arguments().drop_front(1));
1917 TypeConstraintInfo.setInt(
Dependent ?
true :
false);
1928 Status(
T->getType()->isInstantiationDependentType() ?
SS_Dependent
This file provides some common utility functions for processing Lambda related AST Constructs.
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
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)
static bool isInvalid(LocType Loc, bool *Invalid)
__DEVICE__ void * memcpy(void *__a, const void *__b, size_t __c)
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
QualType getReferenceQualifiedType(const Expr *e) const
getReferenceQualifiedType - Given an expr, will return the type for that expression,...
bool hasSameUnqualifiedType(QualType T1, QualType T2) const
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
AtomicExpr - Variadic atomic builtins: __atomic_exchange, __atomic_fetch_*, __atomic_load,...
SourceLocation getBeginLoc() const LLVM_READONLY
A builtin binary operation expression such as "x + y" or "x <= y".
static OverloadedOperatorKind getOverloadedOperator(Opcode Opc)
Retrieve the overloaded operator kind that corresponds to the given binary opcode.
StringRef getOpcodeStr() const
static BinaryOperator * Create(const ASTContext &C, Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy, ExprValueKind VK, ExprObjectKind OK, SourceLocation opLoc, FPOptionsOverride FPFeatures)
static Opcode getOverloadedOpcode(OverloadedOperatorKind OO)
Retrieve the binary opcode that corresponds to the given overloaded operator.
Represents a C++ conversion function within a class.
Represents a folding of a pack over an operator.
SourceLocation getBeginLoc() const LLVM_READONLY
Expr * getInit() const
Get the operand that doesn't contain a pack, for a binary fold.
std::optional< unsigned > getNumExpansions() const
SourceLocation getEllipsisLoc() const
bool isLeftFold() const
Does this produce a left-associated sequence of operators?
bool isRightFold() const
Does this produce a right-associated sequence of operators?
Expr * getPattern() const
Get the pattern, that is, the operand that contains an unexpanded pack.
BinaryOperatorKind getOperator() const
Represents a C++ struct/union/class.
Declaration of a C++20 concept.
Expr * getConstraintExpr() const
Represents the specialization of a concept - evaluates to a prvalue of type bool.
SourceLocation getBeginLoc() const LLVM_READONLY
ArrayRef< TemplateArgument > getTemplateArguments() const
const ASTTemplateArgumentListInfo * getTemplateArgsAsWritten() const
const ASTConstraintSatisfaction & getSatisfaction() const
Get elaborated satisfaction info about the template arguments' satisfaction of the named concept.
ConceptDecl * getNamedConcept() const
The result of a constraint satisfaction check, containing the necessary information to diagnose an un...
std::pair< SourceLocation, StringRef > SubstitutionDiagnostic
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &C)
llvm::SmallVector< Detail, 4 > Details
The substituted constraint expr, if the template arguments could be substituted into them,...
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
DeclContext * getParent()
getParent - Returns the containing DeclContext.
bool isTransparentContext() const
isTransparentContext - Determines whether this context is a "transparent" context,...
bool isDependentContext() const
Determines whether this context is dependent on a template parameter.
DeclContext * getNonTransparentContext()
Decl - This represents one declaration (or definition), e.g.
FriendObjectKind getFriendObjectKind() const
Determines whether this declaration is the object of a friend declaration and, if so,...
bool isParameterPack() const
Whether this declaration is a parameter pack.
FunctionDecl * getAsFunction() LLVM_READONLY
Returns the function itself, or the templated function if this is a function template.
bool isInvalidDecl() const
SourceLocation getLocation() const
DeclContext * getLexicalDeclContext()
getLexicalDeclContext - The declaration context where this Decl was lexically declared (LexicalDC).
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
virtual SourceRange getSourceRange() const LLVM_READONLY
Source range that this declaration covers.
Expr * getTrailingRequiresClause()
Get the constraint-expression introduced by the trailing requires-clause in the function/member decla...
RAII object that enters a new expression evaluation context.
This represents one expression.
@ SE_NoSideEffects
Strictly evaluate the expression.
bool isTypeDependent() const
Determines whether the type of this expression depends on.
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
bool containsErrors() const
Whether this expression contains subexpressions which had errors, e.g.
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...
Represents difference between two FPOptions values.
Represents a function declaration or definition.
FunctionTemplateDecl * getDescribedFunctionTemplate() const
Retrieves the function template that is described by this function declaration.
SourceLocation getPointOfInstantiation() const
Retrieve the (first) point of instantiation of a function template specialization or a member of a cl...
ArrayRef< ParmVarDecl * > parameters() const
FunctionTemplateDecl * getPrimaryTemplate() const
Retrieve the primary template that this function template specialization either specializes or was in...
const TemplateArgumentList * getTemplateSpecializationArgs() const
Retrieve the template arguments used to produce this function template specialization from the primar...
bool isTemplateInstantiation() const
Determines if the given function was instantiated from a function template.
TemplatedKind
The kind of templated function a FunctionDecl can be.
@ TK_MemberSpecialization
@ TK_DependentNonTemplate
@ TK_FunctionTemplateSpecialization
TemplatedKind getTemplatedKind() const
What kind of templated function this is.
FunctionDecl * getInstantiatedFromDecl() const
FunctionDecl * getInstantiatedFromMemberFunction() const
If this function is an instantiation of a member function of a class template specialization,...
Declaration of a template function.
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)
const TypeClass * getTypePtr() const
Describes the capture of a variable or of this, or of a C++1y init-capture.
A stack-allocated class that identifies which local variable declaration instantiations are present i...
void InstantiatedLocal(const Decl *D, Decl *Inst)
Data structure that captures multiple levels of template argument lists for use in template instantia...
const ArgList & getInnermost() const
Retrieve the innermost template argument list.
unsigned getNumLevels() const
Determine the number of levels in this template argument list.
unsigned getNumSubstitutedLevels() const
Determine the number of substituted levels in this template argument list.
const ArgList & getOutermost() const
Retrieve the outermost template argument list.
bool isAnyArgInstantiationDependent() const
This represents a decl that may have a name.
void EmitToString(DiagnosticsEngine &Diags, SmallVectorImpl< char > &Buf) const
A (possibly-)qualified type.
The collection of all-type qualifiers we support.
Scope - A scope is a transient data structure that is used while parsing the program.
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID, bool DeferHint=false)
Emit a diagnostic.
PartialDiagnostic PDiag(unsigned DiagID=0)
Build a partial diagnostic.
RAII object used to change the argument pack substitution index within a Sema object.
RAII object used to temporarily allow the C++ 'this' expression to be used, with the given qualifiers...
RAII class used to determine whether SFINAE has trapped any errors that occur during template argumen...
bool hasErrorOccurred() const
Determine whether any SFINAE errors have been trapped.
SourceLocation getLocation() const
bool ContainsDecl(const NamedDecl *ND) const
const DeclContext * getDeclContext() const
const NamedDecl * getDecl() const
const DeclContext * getLexicalDeclContext() const
Sema - This implements semantic analysis and AST building for C.
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...
bool ConstraintExpressionDependsOnEnclosingTemplate(const FunctionDecl *Friend, unsigned TemplateDepth, const Expr *Constraint)
DiagnosticsEngine & getDiagnostics() const
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.
bool SubstTemplateArguments(ArrayRef< TemplateArgumentLoc > Args, const MultiLevelTemplateArgumentList &TemplateArgs, TemplateArgumentListInfo &Outputs)
std::optional< unsigned > getNumArgumentsInExpansionFromUnexpanded(llvm::ArrayRef< UnexpandedParameterPack > Unexpanded, const MultiLevelTemplateArgumentList &TemplateArgs)
bool FriendConstraintsDependOnEnclosingTemplate(const FunctionDecl *FD)
bool EnsureTemplateArgumentListConstraints(TemplateDecl *Template, const MultiLevelTemplateArgumentList &TemplateArgs, SourceRange TemplateIDRange)
Ensure that the given template arguments satisfy the constraints associated with the given template,...
const LangOptions & getLangOpts() const
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...
bool AreConstraintExpressionsEqual(const NamedDecl *Old, const Expr *OldConstr, const TemplateCompareNewDeclInfo &New, const Expr *NewConstr)
sema::FunctionScopeInfo * getCurFunction() const
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)
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)
void PopSatisfactionStackEntry()
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
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...
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
A convenient class for passing around template argument information.
llvm::ArrayRef< TemplateArgumentLoc > arguments() const
Location wrapper for a TemplateArgument.
The base class of all kinds of template declarations (e.g., class, function, etc.).
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.
Represents a C++ template name within the type system.
Stores a list of template parameters for a TemplateDecl and its derived classes.
NamedDecl * getParam(unsigned Idx)
static bool anyInstantiationDependentTemplateArguments(ArrayRef< TemplateArgumentLoc > Args)
Declaration of a template type parameter.
Wrapper for template type parameters.
Token - This structure provides full information about a lexed token.
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)) {....
tok::TokenKind getKind() const
Models the abbreviated syntax to constrain a template type parameter: template <convertible_to<string...
Expr * getImmediatelyDeclaredConstraint() const
Get the immediately-declared constraint expression introduced by this type-constraint,...
TyLocType push(QualType T)
Pushes space for a new TypeLoc of the given type.
A container of type source information.
SourceLocation getNameLoc() const
void setNameLoc(SourceLocation Loc)
The base class of the type hierarchy.
bool isSpecificBuiltinType(unsigned K) const
Test for a particular builtin type.
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
bool isFunctionType() const
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
bool isInitCapture() const
Whether this variable is the implicit variable for a lambda init-capture.
ReturnTypeRequirement()
No return type requirement was specified.
bool isTypeConstraint() const
SubstitutionDiagnostic * getSubstitutionDiagnostic() const
A requires-expression requirement which queries the validity and properties of an expression ('simple...
SubstitutionDiagnostic * getExprSubstitutionDiagnostic() const
ConceptSpecializationExpr * getReturnTypeRequirementSubstitutedConstraintExpr() const
@ SS_ConstraintsNotSatisfied
@ SS_TypeRequirementSubstitutionFailure
@ SS_ExprSubstitutionFailure
const ReturnTypeRequirement & getReturnTypeRequirement() const
SatisfactionStatus getSatisfactionStatus() const
SourceLocation getNoexceptLoc() const
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...
const ASTConstraintSatisfaction & getConstraintSatisfaction() const
StringRef getInvalidConstraintEntity()
A static requirement that can be used in a requires-expression to check properties of types and expre...
bool containsUnexpandedParameterPack() const
A requires-expression requirement which queries the existence of a type name or type template special...
SubstitutionDiagnostic * getSubstitutionDiagnostic() const
SatisfactionStatus getSatisfactionStatus() const
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)
The JSON file list parser is used to communicate input to InstallAPI.
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
@ OO_None
Not an overloaded operator.
NormalForm makeCNF(const NormalizedConstraint &Normalized)
NormalForm makeDNF(const NormalizedConstraint &Normalized)
@ OK_Ordinary
An ordinary object is located at an address in memory.
bool subsumes(const NormalForm &PDNF, const NormalForm &QCNF, const AtomicSubsumptionEvaluator &E)
bool isLambdaCallOperator(const CXXMethodDecl *MD)
@ Result
The result type of a method or function.
const NormalizedConstraint * getNormalizedAssociatedConstraints(Sema &S, NamedDecl *ConstrainedDecl, ArrayRef< const Expr * > AssociatedConstraints)
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.
bool isLambdaConversionOperator(CXXConversionDecl *C)
@ VK_PRValue
A pr-value expression (in the C++11 taxonomy) produces a temporary value.
const FunctionProtoType * T
std::pair< llvm::PointerUnion< const TemplateTypeParmType *, NamedDecl * >, SourceLocation > UnexpandedParameterPack
std::pair< SourceLocation, PartialDiagnostic > PartialDiagnosticAt
A partial diagnostic along with the source location where this diagnostic occurs.
@ Other
Other implicit parameter.
The result of a constraint satisfaction check, containing the necessary information to diagnose an un...
Represents an explicit template argument list in C++, e.g., the "<int>" in "sort<int>".
SourceLocation getLAngleLoc() const
llvm::ArrayRef< TemplateArgumentLoc > arguments() const
unsigned NumTemplateArgs
The number of template arguments in TemplateArgs.
SourceLocation getRAngleLoc() const
bool subsumes(ASTContext &C, const AtomicConstraint &Other) const
bool hasMatchingParameterMapping(ASTContext &C, const AtomicConstraint &Other) const
const Expr * ConstraintExpr
EvalResult is a struct with detailed info about an evaluated expression.
APValue Val
Val - This is the value the expression can be folded to.
SmallVectorImpl< PartialDiagnosticAt > * Diag
Diag - If this is non-null, it will be filled in with a stack of notes indicating why evaluation fail...
NormalizedConstraint Constraint
static bool AreCompatibleForSubsumption(const FoldExpandedConstraint &A, const FoldExpandedConstraint &B)
A normalized constraint, as defined in C++ [temp.constr.normal], is either an atomic constraint,...
llvm::PointerUnion< AtomicConstraint *, FoldExpandedConstraint *, CompoundConstraint > Constraint
bool isFoldExpanded() const
NormalizedConstraint & getRHS() const
llvm::PointerIntPair< NormalizedConstraintPair *, 1, CompoundConstraintKind > CompoundConstraint
AtomicConstraint * getAtomicConstraint() const
NormalizedConstraint(AtomicConstraint *C)
CompoundConstraintKind getCompoundKind() const
NormalizedConstraint & getLHS() const
FoldExpandedConstraint * getFoldExpandedConstraint() const
A stack object to be created when performing template instantiation.
bool isInvalid() const
Determines whether we have exceeded the maximum recursive template instantiations.