27#include "llvm/ADT/DenseMap.h"
28#include "llvm/ADT/PointerUnion.h"
29#include "llvm/ADT/StringExtras.h"
39 const Expr *LHS =
nullptr;
40 const Expr *RHS =
nullptr;
43 LogicalBinOp(
const Expr *
E) {
44 if (
auto *BO = dyn_cast<BinaryOperator>(
E)) {
48 Loc = BO->getExprLoc();
49 }
else if (
auto *OO = dyn_cast<CXXOperatorCallExpr>(
E)) {
51 if (OO->getNumArgs() == 2) {
52 Op = OO->getOperator();
55 Loc = OO->getOperatorLoc();
60 bool isAnd()
const {
return Op == OO_AmpAmp; }
61 bool isOr()
const {
return Op == OO_PipePipe; }
62 explicit operator bool()
const {
return isAnd() || isOr(); }
64 const Expr *getLHS()
const {
return LHS; }
65 const Expr *getRHS()
const {
return RHS; }
69 return recreateBinOp(SemaRef, LHS,
const_cast<Expr *
>(getRHS()));
74 assert((isAnd() || isOr()) &&
"Not the right kind of op?");
91 Token NextToken,
bool *PossibleNonPrimary,
92 bool IsTrailingRequiresClause) {
98 if (LogicalBinOp BO = ConstraintExpression) {
100 PossibleNonPrimary) &&
103 }
else if (
auto *
C = dyn_cast<ExprWithCleanups>(ConstraintExpression))
109 auto CheckForNonPrimary = [&] {
110 if (!PossibleNonPrimary)
113 *PossibleNonPrimary =
124 (NextToken.
is(tok::l_paren) &&
125 (IsTrailingRequiresClause ||
127 isa<UnresolvedLookupExpr>(ConstraintExpression) &&
143 CheckForNonPrimary();
149 diag::err_non_bool_atomic_constraint) <<
Type
151 CheckForNonPrimary();
155 if (PossibleNonPrimary)
156 *PossibleNonPrimary =
false;
161struct SatisfactionStackRAII {
163 bool Inserted =
false;
165 const llvm::FoldingSetNodeID &FSNID)
172 ~SatisfactionStackRAII() {
184 for (
const auto &List : MLTAL)
223 llvm::FoldingSetNodeID ID;
231 SatisfactionStackRAII StackRAII(S,
Template, ID);
235 SubstitutedExpression =
259 unsigned MessageSize = DiagString.size();
260 char *Mem =
new (S.
Context)
char[MessageSize];
261 memcpy(Mem, DiagString.c_str(), MessageSize);
262 Satisfaction.
Details.emplace_back(
264 SubstDiag.first, StringRef(Mem, MessageSize)});
286 SubstitutedExpression.
get(),
289 return SubstitutedExpression;
304 assert(!Unexpanded.empty() &&
"Pack expansion without parameter packs?");
306 bool RetainExpansion =
false;
310 true, Expand, RetainExpansion,
312 !Expand || RetainExpansion)
315 if (NumExpansions && S.
getLangOpts().BracketDepth < *NumExpansions) {
317 clang::diag::err_fold_expression_limit_exceeded)
323 return NumExpansions;
336 size_t EffectiveDetailEndIndex = Satisfaction.
Details.size();
339 S, LHS,
Template, TemplateNameLoc, MLTAL, Satisfaction);
346 if (Op == clang::OO_PipePipe && IsLHSSatisfied)
356 if (Op == clang::OO_AmpAmp && !IsLHSSatisfied)
367 S, RHS,
Template, TemplateNameLoc, MLTAL, Satisfaction);
380 if (Op == clang::OO_PipePipe && IsRHSSatisfied) {
381 auto EffectiveDetailEnd = Satisfaction.
Details.begin();
382 std::advance(EffectiveDetailEnd, EffectiveDetailEndIndex);
383 Satisfaction.
Details.erase(EffectiveDetailEnd, Satisfaction.
Details.end());
399 bool Conjunction = FE->
getOperator() == BinaryOperatorKind::BO_LAnd;
400 size_t EffectiveDetailEndIndex = Satisfaction.
Details.size();
405 TemplateNameLoc, MLTAL, Satisfaction);
417 S, FE,
Template, TemplateNameLoc, MLTAL, Satisfaction);
420 for (
unsigned I = 0; I < *NumExpansions; I++) {
427 if (!Conjunction && IsRHSSatisfied) {
428 auto EffectiveDetailEnd = Satisfaction.
Details.begin();
429 std::advance(EffectiveDetailEnd, EffectiveDetailEndIndex);
430 Satisfaction.
Details.erase(EffectiveDetailEnd,
440 if (Conjunction != IsRHSSatisfied)
472 if (LogicalBinOp BO = ConstraintExpr)
474 S, BO.getLHS(), BO.getOp(), BO.getRHS(),
Template, TemplateNameLoc,
475 MLTAL, Satisfaction);
477 if (
auto *
C = dyn_cast<ExprWithCleanups>(ConstraintExpr)) {
481 S,
C->getSubExpr(),
Template, TemplateNameLoc, MLTAL, Satisfaction);
484 if (
auto *FE = dyn_cast<CXXFoldExpr>(ConstraintExpr);
486 (FE->getOperator() == BinaryOperatorKind::BO_LAnd ||
487 FE->getOperator() == BinaryOperatorKind::BO_LOr)) {
489 MLTAL, Satisfaction);
496 S, ConstraintExpr,
Template, TemplateNameLoc, MLTAL, Satisfaction);
501 if (!SubstitutedAtomicExpr.
isUsable())
518 unsigned MessageSize = DiagString.size();
519 char *Mem =
new (S.
Context)
char[MessageSize];
520 memcpy(Mem, DiagString.c_str(), MessageSize);
521 Satisfaction.
Details.emplace_back(
523 SubstitutedAtomicExpr.get()->getBeginLoc(),
524 StringRef(Mem, MessageSize)});
525 return SubstitutedAtomicExpr;
532 EvalResult.
Diag = &EvaluationDiags;
535 !EvaluationDiags.empty()) {
539 diag::err_non_constant_constraint_expression)
542 S.
Diag(PDiag.first, PDiag.second);
547 "evaluating bool expression didn't produce int");
550 Satisfaction.
Details.emplace_back(SubstitutedAtomicExpr.
get());
552 return SubstitutedAtomicExpr;
561 TemplateNameLoc, MLTAL, Satisfaction);
570 if (AssociatedConstraints.empty()) {
598 AC.ConstraintExpr, Satisfaction);
602 Converted.push_back(Res.
get());
606 Converted.append(AssociatedConstraints.size() - Converted.size(),
624 if (AssociatedConstraints.empty()) {
629 return ::CheckConstraintSatisfaction(
630 *
this,
nullptr, AssociatedConstraints, ConvertedConstraints,
631 TemplateArgsLists, TemplateIDRange, OutSatisfaction);
645 for (
auto List : TemplateArgsLists)
646 llvm::append_range(FlattenedArgs, List.Args);
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());
701bool Sema::SetupConstraintScope(
706 "Use LambdaScopeForCallOperatorInstantiationRAII to handle lambda "
710 InstantiatingTemplate Inst(
715 if (Inst.isInvalid())
726 if (addInstantiatedParametersToScope(
735 if (addInstantiatedParametersToScope(FD, FromMemTempl->getTemplatedDecl(),
750 InstantiatingTemplate Inst(
755 if (Inst.isInvalid())
760 if (addInstantiatedParametersToScope(FD, InstantiatedFrom,
Scope, MLTAL))
769std::optional<MultiLevelTemplateArgumentList>
770Sema::SetupConstraintCheckingTemplateArgumentsAndScope(
787 if (SetupConstraintScope(FD, TemplateArgs, MLTAL,
Scope))
796 bool ForOverloadResolution) {
815 if (
const auto *MD = dyn_cast<CXXConversionDecl>(FD);
818 Satisfaction, UsageLoc,
832 std::optional<MultiLevelTemplateArgumentList> MLTAL =
833 SetupConstraintCheckingTemplateArgumentsAndScope(
841 if (
auto *
Method = dyn_cast<CXXMethodDecl>(FD)) {
842 ThisQuals =
Method->getMethodQualifiers();
849 ForOverloadResolution);
863 bool SkipForSpecialization =
false) {
869 true, SkipForSpecialization);
874 class AdjustConstraintDepth :
public TreeTransform<AdjustConstraintDepth> {
875 unsigned TemplateDepth = 0;
878 AdjustConstraintDepth(
Sema &SemaRef,
unsigned TemplateDepth)
879 : inherited(SemaRef), TemplateDepth(TemplateDepth) {}
881 using inherited::TransformTemplateTypeParmType;
888 NewTTPDecl = cast_or_null<TemplateTypeParmDecl>(
891 QualType Result = getSema().Context.getTemplateTypeParmType(
892 T->getDepth() + TemplateDepth,
T->getIndex(),
T->isParameterPack(),
903 const Expr *ConstrExpr) {
927 std::optional<LocalInstantiationScope> ScopeForParameters;
930 ScopeForParameters.emplace(S,
true);
934 FD =
Template->getInstantiatedFromMemberTemplate()->getTemplatedDecl();
936 if (ScopeForParameters->getInstantiationOfIfExists(PVD))
938 if (!PVD->isParameterPack()) {
939 ScopeForParameters->InstantiatedLocal(PVD, PVD);
958 ScopeForParameters->MakeInstantiatedLocalArgPack(PVD);
959 ScopeForParameters->InstantiatedLocalPackArg(PVD, PVD);
963 std::optional<Sema::CXXThisScopeRAII> ThisScope;
972 std::optional<Sema::ContextRAII> ContextScope;
980 if (
auto *RD = dyn_cast<CXXRecordDecl>(DC)) {
982 ContextScope.emplace(S,
const_cast<DeclContext *
>(cast<DeclContext>(RD)),
992 return SubstConstr.
get();
996 const Expr *OldConstr,
998 const Expr *NewConstr) {
999 if (OldConstr == NewConstr)
1002 if (Old && !
New.isInvalid() && !
New.ContainsDecl(Old) &&
1004 if (
const Expr *SubstConstr =
1007 OldConstr = SubstConstr;
1010 if (
const Expr *SubstConstr =
1013 NewConstr = SubstConstr;
1018 llvm::FoldingSetNodeID ID1, ID2;
1031 "Non-function templates don't need to be checked");
1052 TemplateIDRange, Satisfaction))
1057 TemplateArgString =
" ";
1063 diag::err_template_arg_list_constraints_not_satisfied)
1065 << TemplateArgString << TemplateIDRange;
1077 Template->getAssociatedConstraints(TemplateAC);
1078 if (TemplateAC.empty()) {
1097 SemaRef, PointOfInstantiation,
1099 PointOfInstantiation);
1100 if (Inst.isInvalid())
1110 Template, TemplateAC, MLTAL, PointOfInstantiation, Satisfaction);
1121 return ::CheckFunctionConstraintsWithoutInstantiation(
1122 *
this, PointOfInstantiation,
Decl->getDescribedFunctionTemplate(),
1123 TemplateArgs, Satisfaction);
1128 Template->getAssociatedConstraints(TemplateAC);
1129 if (TemplateAC.empty()) {
1139 std::optional<MultiLevelTemplateArgumentList> MLTAL =
1140 SetupConstraintCheckingTemplateArgumentsAndScope(
Decl, TemplateArgs,
1148 if (
auto *
Method = dyn_cast<CXXMethodDecl>(
Decl)) {
1149 ThisQuals =
Method->getMethodQualifiers();
1158 PointOfInstantiation, Satisfaction);
1165 &&
"Diagnose() can only be used on an unsatisfied requirement");
1168 llvm_unreachable(
"Diagnosing a dependent requirement");
1172 if (!SubstDiag->DiagMessage.empty())
1173 S.
Diag(SubstDiag->DiagLoc,
1174 diag::note_expr_requirement_expr_substitution_error)
1175 << (
int)
First << SubstDiag->SubstitutedEntity
1176 << SubstDiag->DiagMessage;
1178 S.
Diag(SubstDiag->DiagLoc,
1179 diag::note_expr_requirement_expr_unknown_substitution_error)
1180 << (
int)
First << SubstDiag->SubstitutedEntity;
1185 diag::note_expr_requirement_noexcept_not_met)
1191 if (!SubstDiag->DiagMessage.empty())
1192 S.
Diag(SubstDiag->DiagLoc,
1193 diag::note_expr_requirement_type_requirement_substitution_error)
1194 << (
int)
First << SubstDiag->SubstitutedEntity
1195 << SubstDiag->DiagMessage;
1197 S.
Diag(SubstDiag->DiagLoc,
1198 diag::note_expr_requirement_type_requirement_unknown_substitution_error)
1199 << (
int)
First << SubstDiag->SubstitutedEntity;
1210 diag::note_expr_requirement_constraints_not_satisfied_simple)
1215 diag::note_expr_requirement_constraints_not_satisfied)
1216 << (
int)
First << ConstraintExpr;
1222 llvm_unreachable(
"We checked this above");
1230 &&
"Diagnose() can only be used on an unsatisfied requirement");
1233 llvm_unreachable(
"Diagnosing a dependent requirement");
1237 if (!SubstDiag->DiagMessage.empty())
1238 S.
Diag(SubstDiag->DiagLoc,
1239 diag::note_type_requirement_substitution_error) << (
int)
First
1240 << SubstDiag->SubstitutedEntity << SubstDiag->DiagMessage;
1242 S.
Diag(SubstDiag->DiagLoc,
1243 diag::note_type_requirement_unknown_substitution_error)
1244 << (
int)
First << SubstDiag->SubstitutedEntity;
1248 llvm_unreachable(
"Unknown satisfaction status");
1259 using SubstitutionDiagnostic = std::pair<SourceLocation, StringRef>;
1261 if (
auto *SubstDiag =
Record.dyn_cast<SubstitutionDiagnostic *>())
1262 S.
Diag(SubstDiag->first, diag::note_nested_requirement_substitution_error)
1264 << SubstDiag->second;
1277 switch (BO->getOpcode()) {
1289 BO->getLHS()->EvaluateKnownConstInt(S.
Context).getBoolValue();
1300 BO->getRHS()->EvaluateKnownConstInt(S.
Context).getBoolValue();
1312 if (BO->getLHS()->getType()->isIntegerType() &&
1313 BO->getRHS()->getType()->isIntegerType()) {
1316 BO->getLHS()->EvaluateAsInt(SimplifiedLHS, S.
Context,
1319 BO->getRHS()->EvaluateAsInt(SimplifiedRHS, S.
Context,
1322 if (!SimplifiedLHS.
Diag && ! SimplifiedRHS.
Diag) {
1324 diag::note_atomic_constraint_evaluated_to_false_elaborated)
1337 }
else if (
auto *CSE = dyn_cast<ConceptSpecializationExpr>(SubstExpr)) {
1338 if (CSE->getTemplateArgsAsWritten()->NumTemplateArgs == 1) {
1340 CSE->getSourceRange().getBegin(),
1342 note_single_arg_concept_specialization_constraint_evaluated_to_false)
1344 << CSE->getTemplateArgsAsWritten()->arguments()[0].getArgument()
1345 << CSE->getNamedConcept();
1348 diag::note_concept_specialization_constraint_evaluated_to_false)
1349 << (
int)
First << CSE;
1353 }
else if (
auto *RE = dyn_cast<RequiresExpr>(SubstExpr)) {
1356 if (!Req->isDependent() && !Req->isSatisfied()) {
1357 if (
auto *
E = dyn_cast<concepts::ExprRequirement>(Req))
1359 else if (
auto *
T = dyn_cast<concepts::TypeRequirement>(Req))
1363 S, cast<concepts::NestedRequirement>(Req),
First);
1367 }
else if (
auto *TTE = dyn_cast<TypeTraitExpr>(SubstExpr);
1368 TTE && TTE->getTrait() == clang::TypeTrait::BTT_IsDeducible) {
1369 assert(TTE->getNumArgs() == 2);
1371 diag::note_is_deducible_constraint_evaluated_to_false)
1372 << TTE->getArg(0)->getType() << TTE->getArg(1)->getType();
1377 diag::note_atomic_constraint_evaluated_to_false)
1382template <
typename SubstitutionDiagnostic>
1384 Sema &S,
const llvm::PointerUnion<Expr *, SubstitutionDiagnostic *> &
Record,
1385 bool First =
true) {
1386 if (
auto *
Diag =
Record.template dyn_cast<SubstitutionDiagnostic *>()) {
1387 S.
Diag(
Diag->first, diag::note_substituted_constraint_expr_is_ill_formed)
1399 "Attempted to diagnose a satisfied constraint");
1410 "Attempted to diagnose a satisfied constraint");
1411 for (
auto &
Record : Satisfaction) {
1425 auto CacheEntry = NormalizationCache.find(ConstrainedDecl);
1426 if (CacheEntry == NormalizationCache.end()) {
1427 auto Normalized = NormalizedConstraint::fromAssociatedConstraints(
1428 *
this, ConstrainedDecl, AssociatedConstraints);
1431 .try_emplace(ConstrainedDecl,
1434 std::move(*Normalized))
1438 return CacheEntry->second;
1445 AssociatedConstraints);
1473 if (!
Atomic.ParameterMapping) {
1474 llvm::SmallBitVector OccurringIndices(TemplateParams->
size());
1476 0, OccurringIndices);
1479 for (
unsigned I = 0, J = 0,
C = TemplateParams->
size(); I !=
C; ++I)
1480 if (OccurringIndices[I])
1481 new (&(TempArgs)[J++])
1483 TemplateParams->
begin()[I],
1493 ? ArgsAsWritten->
arguments()[I].getLocation()
1495 Atomic.ParameterMapping.emplace(TempArgs, OccurringIndices.count());
1500 : ArgsAsWritten->
arguments().front().getSourceRange().getBegin();
1504 : ArgsAsWritten->
arguments().front().getSourceRange().getEnd();
1509 {InstLocBegin, InstLocEnd});
1510 if (Inst.isInvalid())
1519 Atomic.ParameterMapping.emplace(TempArgs, SubstArgs.
size());
1546 if (
Other.isAtomic()) {
1548 }
else if (
Other.isFoldExpanded()) {
1550 Other.getFoldExpandedConstraint()->Kind,
1552 Other.getFoldExpandedConstraint()->Pattern);
1558 Other.getCompoundKind());
1563 assert(
isCompound() &&
"getLHS called on a non-compound constraint.");
1564 return cast<CompoundConstraint>(
Constraint).getPointer()->LHS;
1568 assert(
isCompound() &&
"getRHS called on a non-compound constraint.");
1569 return cast<CompoundConstraint>(
Constraint).getPointer()->RHS;
1572std::optional<NormalizedConstraint>
1573NormalizedConstraint::fromAssociatedConstraints(
1575 assert(ACs.size() != 0);
1576 auto Conjunction = fromConstraintExpr(S,
D, ACs[0].ConstraintExpr);
1578 return std::nullopt;
1579 for (
unsigned I = 1; I < ACs.size(); ++I) {
1580 auto Next = fromConstraintExpr(S,
D, ACs[I].ConstraintExpr);
1582 return std::nullopt;
1589std::optional<NormalizedConstraint>
1590NormalizedConstraint::fromConstraintExpr(
Sema &S,
const NamedDecl *
D,
1592 assert(
E !=
nullptr);
1605 if (LogicalBinOp BO =
E) {
1606 auto LHS = fromConstraintExpr(S,
D, BO.getLHS());
1608 return std::nullopt;
1609 auto RHS = fromConstraintExpr(S,
D, BO.getRHS());
1611 return std::nullopt;
1615 }
else if (
auto *CSE = dyn_cast<const ConceptSpecializationExpr>(
E)) {
1619 S, CSE->getExprLoc(),
1623 if (Inst.isInvalid())
1624 return std::nullopt;
1638 return std::nullopt;
1641 std::optional<NormalizedConstraint>
New;
1645 return std::nullopt;
1648 }
else if (
auto *FE = dyn_cast<const CXXFoldExpr>(
E);
1650 (FE->getOperator() == BinaryOperatorKind::BO_LAnd ||
1651 FE->getOperator() == BinaryOperatorKind::BO_LOr)) {
1656 FE->getOperator() == BinaryOperatorKind::BO_LAnd
1660 if (FE->getInit()) {
1661 auto LHS = fromConstraintExpr(S,
D, FE->getLHS());
1662 auto RHS = fromConstraintExpr(S,
D, FE->getRHS());
1664 return std::nullopt;
1666 if (FE->isRightFold())
1668 Kind, std::move(*RHS), FE->getPattern()}};
1671 Kind, std::move(*LHS), FE->getPattern()}};
1674 S.
Context, std::move(*LHS), std::move(*RHS),
1678 auto Sub = fromConstraintExpr(S,
D, FE->getPattern());
1680 return std::nullopt;
1682 Kind, std::move(*Sub), FE->getPattern()}};
1706 if (It != BPacks.end())
1718 if (
const auto *FD1 = dyn_cast<FunctionDecl>(D1)) {
1724 const auto *FD2 = dyn_cast<FunctionDecl>(D2);
1725 assert(IsExpectedEntity(FD1) && FD2 && IsExpectedEntity(FD2) &&
1726 "use non-instantiated function declaration for constraints partial "
1741 std::pair<const NamedDecl *, const NamedDecl *> Key{D1, D2};
1742 auto CacheEntry = SubsumptionCache.find(Key);
1743 if (CacheEntry != SubsumptionCache.end()) {
1744 Result = CacheEntry->second;
1751 for (
size_t I = 0; I != AC1.size() && I != AC2.size(); ++I) {
1752 if (Depth2 > Depth1) {
1753 AC1[I].ConstraintExpr =
1754 AdjustConstraintDepth(*
this, Depth2 - Depth1)
1755 .TransformExpr(
const_cast<Expr *
>(AC1[I].ConstraintExpr))
1757 }
else if (Depth1 > Depth2) {
1758 AC2[I].ConstraintExpr =
1759 AdjustConstraintDepth(*
this, Depth1 - Depth2)
1760 .TransformExpr(
const_cast<Expr *
>(AC2[I].ConstraintExpr))
1766 std::optional<bool> Subsumes = SC.
Subsumes(D1, AC1, D2, AC2);
1772 SubsumptionCache.try_emplace(Key, *Subsumes);
1783 if (AC1.empty() || AC2.empty())
1786 const Expr *AmbiguousAtomic1 =
nullptr, *AmbiguousAtomic2 =
nullptr;
1797 llvm::FoldingSetNodeID IDA, IDB;
1799 EB->Profile(IDB,
Context,
true);
1803 AmbiguousAtomic1 = EA;
1804 AmbiguousAtomic2 = EB;
1821 bool Is1AtLeastAs2Normally = SC.
Subsumes(Normalized1, Normalized2);
1822 bool Is2AtLeastAs1Normally = SC.
Subsumes(Normalized2, Normalized1);
1825 bool Is1AtLeastAs2 = SC2.
Subsumes(Normalized1, Normalized2);
1826 bool Is2AtLeastAs1 = SC2.
Subsumes(Normalized2, Normalized1);
1828 if (Is1AtLeastAs2 == Is1AtLeastAs2Normally &&
1829 Is2AtLeastAs1 == Is2AtLeastAs1Normally)
1834 assert(AmbiguousAtomic1 && AmbiguousAtomic2);
1836 Diag(AmbiguousAtomic1->
getBeginLoc(), diag::note_ambiguous_atomic_constraints)
1838 Diag(AmbiguousAtomic2->getBeginLoc(),
1839 diag::note_ambiguous_atomic_constraints_similar_expression)
1840 << AmbiguousAtomic2->getSourceRange();
1846 assert(
isCompound() &&
"getCompoundKind on a non-compound constraint..");
1847 return cast<CompoundConstraint>(
Constraint).getInt();
1851 assert(
isAtomic() &&
"getAtomicConstraint called on non-atomic constraint.");
1858 "getFoldExpandedConstraint called on non-fold-expanded constraint.");
1859 return cast<FoldExpandedConstraint *>(
Constraint);
1868template <>
struct llvm::DenseMapInfo<
llvm::FoldingSetNodeID> {
1871 FoldingSetNodeID ID;
1872 ID.AddInteger(std::numeric_limits<unsigned>::max());
1877 FoldingSetNodeID ID;
1878 for (
unsigned I = 0; I <
sizeof(ID) /
sizeof(
unsigned); ++I) {
1879 ID.AddInteger(std::numeric_limits<unsigned>::max());
1885 return Val.ComputeHash();
1889 const FoldingSetNodeID &RHS) {
1898uint16_t SubsumptionChecker::getNewLiteralId() {
1899 assert((
unsigned(NextID) + 1 < std::numeric_limits<uint16_t>::max()) &&
1900 "too many constraints!");
1905 auto &Elems = AtomicMap[Ori->ConstraintExpr];
1920 llvm::FoldingSetNodeID ID;
1921 const auto &Mapping = Ori->ParameterMapping;
1922 ID.AddBoolean(Mapping.has_value());
1930 auto It = Elems.find(ID);
1931 if (It == Elems.end()) {
1934 MappedAtomicConstraint{
1935 Ori, {getNewLiteralId(), Literal::Atomic}}})
1937 ReverseMap[It->second.ID.Value] = Ori;
1939 return It->getSecond().ID;
1943 auto &Elems = FoldMap[Ori->Pattern];
1945 FoldExpendedConstraintKey K;
1948 auto It = llvm::find_if(Elems, [&K](
const FoldExpendedConstraintKey &
Other) {
1949 return K.Kind ==
Other.Kind;
1951 if (It == Elems.end()) {
1952 K.ID = {getNewLiteralId(), Literal::FoldExpanded};
1953 It = Elems.insert(Elems.end(), std::move(K));
1954 ReverseMap[It->ID.Value] = Ori;
1960 return SubsumptionChecker::Normalize<CNFFormula>(
C);
1963 return SubsumptionChecker::Normalize<DNFFormula>(
C);
1979template <
typename FormulaType>
1983 auto Add = [&,
this](Clause
C) {
1986 C.erase(llvm::unique(
C),
C.end());
1987 AddUniqueClauseToFormula(Res, std::move(
C));
2003 auto SizeLeft =
Left.size();
2004 Res = std::move(Left);
2005 Res.reserve(SizeLeft +
Right.size());
2006 std::for_each(std::make_move_iterator(
Right.begin()),
2007 std::make_move_iterator(
Right.end()), Add);
2011 Res.reserve(
Left.size() *
Right.size());
2012 for (
const auto <ransform : Left) {
2013 for (
const auto &RTransform : Right) {
2015 Combined.reserve(LTransform.size() + RTransform.size());
2016 llvm::append_range(Combined, LTransform);
2017 llvm::append_range(Combined, RTransform);
2018 Add(std::move(Combined));
2024void SubsumptionChecker::AddUniqueClauseToFormula(Formula &F, Clause
C) {
2025 for (
auto &
Other : F) {
2026 if (llvm::equal(
C,
Other))
2038 return std::nullopt;
2043 return std::nullopt;
2045 return Subsumes(PNormalized, QNormalized);
2051 DNFFormula DNFP = DNF(*
P);
2052 CNFFormula CNFQ = CNF(*Q);
2057 const CNFFormula &QCNF) {
2058 for (
const auto &Pi : PDNF) {
2059 for (
const auto &Qj : QCNF) {
2065 if (!DNFSubsumes(Pi, Qj))
2072bool SubsumptionChecker::DNFSubsumes(
const Clause &
P,
const Clause &Q) {
2074 return llvm::any_of(
P, [&](Literal LP) {
2075 return llvm::any_of(Q, [
this, LP](Literal LQ) {
return Subsumes(LP, LQ); });
2081 std::pair<const FoldExpandedConstraint *, const FoldExpandedConstraint *> Key{
2084 auto It = FoldSubsumptionCache.find(Key);
2085 if (It == FoldSubsumptionCache.end()) {
2094 It = FoldSubsumptionCache.try_emplace(std::move(Key), DoesSubsume).first;
2100 if (A.Kind != B.Kind)
2103 case Literal::Atomic:
2105 return A.Value == B.Value;
2109 case Literal::FoldExpanded:
2114 llvm_unreachable(
"unknown literal kind");
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 UnsignedOrNone EvaluateFoldExpandedConstraintSize(Sema &S, const CXXFoldExpr *FE, const NamedDecl *Template, SourceLocation TemplateNameLoc, const MultiLevelTemplateArgumentList &MLTAL, ConstraintSatisfaction &Satisfaction)
static ExprResult calculateConstraintSatisfaction(Sema &S, const Expr *ConstraintExpr, const NamedDecl *Template, SourceLocation TemplateNameLoc, const MultiLevelTemplateArgumentList &MLTAL, ConstraintSatisfaction &Satisfaction)
static const Expr * SubstituteConstraintExpressionWithoutSatisfaction(Sema &S, const Sema::TemplateCompareNewDeclInfo &DeclInfo, const Expr *ConstrExpr)
static bool DiagRecursiveConstraintEval(Sema &S, llvm::FoldingSetNodeID &ID, const NamedDecl *Templ, const Expr *E, const MultiLevelTemplateArgumentList &MLTAL)
static bool CheckConstraintSatisfaction(Sema &S, const NamedDecl *Template, ArrayRef< AssociatedConstraint > AssociatedConstraints, llvm::SmallVectorImpl< Expr * > &Converted, const MultiLevelTemplateArgumentList &TemplateArgsLists, SourceRange TemplateIDRange, ConstraintSatisfaction &Satisfaction)
static void diagnoseWellFormedUnsatisfiedConstraintExpr(Sema &S, Expr *SubstExpr, bool First=true)
static ExprResult EvaluateAtomicConstraint(Sema &S, const Expr *AtomicExpr, const NamedDecl *Template, SourceLocation TemplateNameLoc, const MultiLevelTemplateArgumentList &MLTAL, ConstraintSatisfaction &Satisfaction)
static void diagnoseUnsatisfiedRequirement(Sema &S, concepts::ExprRequirement *Req, bool First)
static bool CheckFunctionConstraintsWithoutInstantiation(Sema &SemaRef, SourceLocation PointOfInstantiation, FunctionTemplateDecl *Template, ArrayRef< TemplateArgument > TemplateArgs, ConstraintSatisfaction &Satisfaction)
static bool substituteParameterMappings(Sema &S, NormalizedConstraint &N, ConceptDecl *Concept, const MultiLevelTemplateArgumentList &MLTAL, const ASTTemplateArgumentListInfo *ArgsAsWritten)
static void diagnoseUnsatisfiedConstraintExpr(Sema &S, const llvm::PointerUnion< Expr *, SubstitutionDiagnostic * > &Record, bool First=true)
static unsigned CalculateTemplateDepthForConstraints(Sema &S, const NamedDecl *ND, bool SkipForSpecialization=false)
__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 ...
TemplateArgument getCanonicalTemplateArgument(const TemplateArgument &Arg) const
Retrieve the "canonical" template argument.
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.
SourceLocation getEllipsisLoc() const
bool isLeftFold() const
Does this produce a left-associated sequence of operators?
UnsignedOrNone getNumExpansions() const
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
SourceLocation getConceptNameLoc() 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 isFunctionOrFunctionTemplate() const
Whether this declaration is a function or function template.
FunctionDecl * getAsFunction() LLVM_READONLY
Returns the function itself, or the templated function if this is a function template.
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.
const AssociatedConstraint & getTrailingRequiresClause() const
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.
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
A stack-allocated class that identifies which local variable declaration instantiations are present i...
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
const DeclContext * getDeclContext() const
const NamedDecl * getDecl() const
const DeclContext * getLexicalDeclContext() const
Sema - This implements semantic analysis and AST building for C.
bool ConstraintExpressionDependsOnEnclosingTemplate(const FunctionDecl *Friend, unsigned TemplateDepth, const Expr *Constraint)
DiagnosticsEngine & getDiagnostics() const
void DiagnoseTypeTraitDetails(const Expr *E)
If E represents a built-in type trait, or a known standard type trait, try to print more information ...
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.
ASTContext & getASTContext() const
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
bool CheckConstraintSatisfaction(const NamedDecl *Template, ArrayRef< AssociatedConstraint > AssociatedConstraints, const MultiLevelTemplateArgumentList &TemplateArgLists, SourceRange TemplateIDRange, ConstraintSatisfaction &Satisfaction)
Check whether the given list of constraint expressions are satisfied (as if in a 'conjunction') given...
void collectUnexpandedParameterPacks(TemplateArgument Arg, SmallVectorImpl< UnexpandedParameterPack > &Unexpanded)
Collect the set of unexpanded parameter packs within the given template argument.
const NormalizedConstraint * getNormalizedAssociatedConstraints(const NamedDecl *ConstrainedDecl, ArrayRef< AssociatedConstraint > AssociatedConstraints)
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...
MultiLevelTemplateArgumentList getTemplateInstantiationArgs(const NamedDecl *D, const DeclContext *DC=nullptr, bool Final=false, std::optional< ArrayRef< TemplateArgument > > Innermost=std::nullopt, bool RelativeToPrimary=false, const FunctionDecl *Pattern=nullptr, bool ForConstraintInstantiation=false, bool SkipForSpecialization=false, bool ForDefaultArgumentSubstitution=false)
Retrieve the template argument list(s) that should be used to instantiate the definition of the given...
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)
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...
@ Unevaluated
The current expression and its subexpressions occur within an unevaluated operand (C++11 [expr]p7),...
bool SatisfactionStackContains(const NamedDecl *D, const llvm::FoldingSetNodeID &ID) const
bool CheckParameterPacksForExpansion(SourceLocation EllipsisLoc, SourceRange PatternRange, ArrayRef< UnexpandedParameterPack > Unexpanded, const MultiLevelTemplateArgumentList &TemplateArgs, bool FailOnPackProducingTemplates, bool &ShouldExpand, bool &RetainExpansion, UnsignedOrNone &NumExpansions)
Determine whether we could expand a pack expansion with the given set of parameter packs into separat...
ExprResult BuildEmptyCXXFoldExpr(SourceLocation EllipsisLoc, BinaryOperatorKind Operator)
bool IsAtLeastAsConstrained(const NamedDecl *D1, MutableArrayRef< AssociatedConstraint > AC1, const NamedDecl *D2, MutableArrayRef< AssociatedConstraint > AC2, bool &Result)
Check whether the given declaration's associated constraints are at least as constrained than another...
TemplateArgumentLoc getIdentityTemplateArgumentLoc(NamedDecl *Param, SourceLocation Location)
Get a template argument mapping the given template parameter to itself, e.g.
bool CheckFunctionTemplateConstraints(SourceLocation PointOfInstantiation, FunctionDecl *Decl, ArrayRef< TemplateArgument > TemplateArgs, ConstraintSatisfaction &Satisfaction)
void runWithSufficientStackSpace(SourceLocation Loc, llvm::function_ref< void()> Fn)
Run some code with "sufficient" stack space.
std::string getTemplateArgumentBindingsText(const TemplateParameterList *Params, const TemplateArgumentList &Args)
Produces a formatted string that describes the binding of template parameters to template arguments.
bool MaybeEmitAmbiguousAtomicConstraintsDiagnostic(const NamedDecl *D1, ArrayRef< AssociatedConstraint > AC1, const NamedDecl *D2, ArrayRef< AssociatedConstraint > AC2)
If D1 was not at least as constrained as D2, but would've been if a pair of atomic constraints involv...
void DiagnoseUnsatisfiedConstraint(const ConstraintSatisfaction &Satisfaction, bool First=true)
Emit diagnostics explaining why a constraint expression was deemed unsatisfied.
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
SubsumptionChecker establishes subsumption between two set of constraints.
llvm::function_ref< bool(const AtomicConstraint &, const AtomicConstraint &)> SubsumptionCallable
std::optional< bool > Subsumes(const NamedDecl *DP, ArrayRef< AssociatedConstraint > P, const NamedDecl *DQ, ArrayRef< AssociatedConstraint > Q)
SubsumptionChecker(Sema &SemaRef, SubsumptionCallable Callable={})
A convenient class for passing around template argument information.
ArrayRef< TemplateArgumentLoc > arguments() const
Location wrapper for a TemplateArgument.
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) const
Used to insert TemplateArguments into FoldingSets.
The base class of all kinds of template declarations (e.g., class, function, etc.).
void getAssociatedConstraints(llvm::SmallVectorImpl< AssociatedConstraint > &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.
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
TyLocType push(QualType T)
Pushes space for a new TypeLoc of the given type.
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
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
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...
A requires-expression requirement which queries the existence of a type name or type template special...
SubstitutionDiagnostic * getSubstitutionDiagnostic() const
SatisfactionStatus getSatisfactionStatus() const
Provides information about an attempted template argument deduction, whose success or failure was des...
void takeSFINAEDiagnostic(PartialDiagnosticAt &PD)
Take ownership of the SFINAE diagnostic.
uint32_t Literal
Literals are represented as positive integers.
bool Sub(InterpState &S, CodePtr OpPC)
bool Add(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.
@ OK_Ordinary
An ordinary object is located at an address in memory.
std::pair< llvm::PointerUnion< const TemplateTypeParmType *, NamedDecl *, const TemplateSpecializationType *, const SubstBuiltinTemplatePackType * >, SourceLocation > UnexpandedParameterPack
bool isLambdaCallOperator(const CXXMethodDecl *MD)
@ Result
The result type of a method or function.
std::pair< unsigned, unsigned > getDepthAndIndex(const NamedDecl *ND)
Retrieve the depth and index of a template parameter.
@ Template
We are parsing a template declaration.
@ Concept
The name was classified as a concept name.
prec::Level getBinOpPrecedence(tok::TokenKind Kind, bool GreaterThanIsOperator, bool CPlusPlus11)
Return the precedence of the specified binary operator token.
bool isLambdaConversionOperator(CXXConversionDecl *C)
const NormalizedConstraint * getNormalizedAssociatedConstraints(Sema &S, const NamedDecl *ConstrainedDecl, ArrayRef< AssociatedConstraint > AssociatedConstraints)
@ VK_PRValue
A pr-value expression (in the C++11 taxonomy) produces a temporary value.
const FunctionProtoType * T
std::pair< SourceLocation, PartialDiagnostic > PartialDiagnosticAt
A partial diagnostic along with the source location where this diagnostic occurs.
@ Other
Other implicit parameter.
Diagnostic wrappers for TextAPI types for error reporting.
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
ArrayRef< TemplateArgumentLoc > arguments() const
unsigned NumTemplateArgs
The number of template arguments in TemplateArgs.
SourceLocation getRAngleLoc() 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)
enum clang::FoldExpandedConstraint::FoldOperatorKind Kind
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
CompoundConstraintKind getCompoundKind() const
NormalizedConstraint(AtomicConstraint *C)
AtomicConstraint * getAtomicConstraint() const
FoldExpandedConstraint * getFoldExpandedConstraint() const
NormalizedConstraint & getLHS() const
A stack object to be created when performing template instantiation.
bool isInvalid() const
Determines whether we have exceeded the maximum recursive template instantiations.
static bool isEqual(const FoldingSetNodeID &LHS, const FoldingSetNodeID &RHS)
static FoldingSetNodeID getTombstoneKey()
static FoldingSetNodeID getEmptyKey()
static unsigned getHashValue(const FoldingSetNodeID &Val)