29#include "llvm/ADT/DenseMap.h"
30#include "llvm/ADT/PointerUnion.h"
31#include "llvm/ADT/StringExtras.h"
32#include "llvm/Support/SaveAndRestore.h"
33#include "llvm/Support/TimeProfiler.h"
42 const Expr *LHS =
nullptr;
43 const Expr *RHS =
nullptr;
46 LogicalBinOp(
const Expr *E) {
47 if (
auto *BO = dyn_cast<BinaryOperator>(E)) {
51 Loc = BO->getExprLoc();
52 }
else if (
auto *OO = dyn_cast<CXXOperatorCallExpr>(E)) {
54 if (OO->getNumArgs() == 2) {
55 Op = OO->getOperator();
58 Loc = OO->getOperatorLoc();
63 bool isAnd()
const {
return Op == OO_AmpAmp; }
64 bool isOr()
const {
return Op == OO_PipePipe; }
65 explicit operator bool()
const {
return isAnd() || isOr(); }
67 const Expr *getLHS()
const {
return LHS; }
68 const Expr *getRHS()
const {
return RHS; }
72 return recreateBinOp(SemaRef, LHS,
const_cast<Expr *
>(getRHS()));
77 assert((isAnd() || isOr()) &&
"Not the right kind of op?");
78 assert((!LHS.isInvalid() && !RHS.isInvalid()) &&
"not good expressions?");
80 if (!LHS.isUsable() || !RHS.isUsable())
94 Token NextToken,
bool *PossibleNonPrimary,
95 bool IsTrailingRequiresClause) {
101 if (LogicalBinOp BO = ConstraintExpression) {
103 PossibleNonPrimary) &&
106 }
else if (
auto *
C = dyn_cast<ExprWithCleanups>(ConstraintExpression))
112 auto CheckForNonPrimary = [&] {
113 if (!PossibleNonPrimary)
116 *PossibleNonPrimary =
127 (NextToken.
is(tok::l_paren) &&
128 (IsTrailingRequiresClause ||
146 CheckForNonPrimary();
152 diag::err_non_bool_atomic_constraint)
154 CheckForNonPrimary();
158 if (PossibleNonPrimary)
159 *PossibleNonPrimary =
false;
164struct SatisfactionStackRAII {
166 bool Inserted =
false;
168 const llvm::FoldingSetNodeID &FSNID)
175 ~SatisfactionStackRAII() {
187 for (
const auto &List : *MLTAL)
205 bool SkipForSpecialization =
false) {
211 true, SkipForSpecialization);
216class AdjustConstraintDepth :
public TreeTransform<AdjustConstraintDepth> {
217 unsigned TemplateDepth = 0;
220 using inherited = TreeTransform<AdjustConstraintDepth>;
221 AdjustConstraintDepth(Sema &SemaRef,
unsigned TemplateDepth)
222 : inherited(SemaRef), TemplateDepth(TemplateDepth) {}
224 using inherited::TransformTemplateTypeParmType;
225 QualType TransformTemplateTypeParmType(TypeLocBuilder &TLB,
226 TemplateTypeParmTypeLoc TL,
bool) {
229 TemplateTypeParmDecl *NewTTPDecl =
nullptr;
230 if (TemplateTypeParmDecl *OldTTPDecl =
T->getDecl())
231 NewTTPDecl = cast_or_null<TemplateTypeParmDecl>(
234 QualType
Result = getSema().Context.getTemplateTypeParmType(
235 T->getDepth() + TemplateDepth,
T->getIndex(),
T->isParameterPack(),
237 TemplateTypeParmTypeLoc NewTL = TLB.
push<TemplateTypeParmTypeLoc>(
Result);
242 bool AlreadyTransformed(QualType
T) {
258 using inherited = RecursiveASTVisitor<HashParameterMapping>;
262 const MultiLevelTemplateArgumentList &TemplateArgs;
263 llvm::FoldingSetNodeID &
ID;
264 llvm::SmallVector<TemplateArgument, 10> UsedTemplateArgs;
266 UnsignedOrNone OuterPackSubstIndex;
268 bool shouldVisitTemplateInstantiations()
const {
return true; }
271 HashParameterMapping(Sema &SemaRef,
272 const MultiLevelTemplateArgumentList &TemplateArgs,
273 llvm::FoldingSetNodeID &ID,
274 UnsignedOrNone OuterPackSubstIndex)
275 : SemaRef(SemaRef), TemplateArgs(TemplateArgs),
ID(
ID),
276 OuterPackSubstIndex(OuterPackSubstIndex) {}
278 bool VisitTemplateTypeParmType(TemplateTypeParmType *
T) {
289 TemplateArgument Arg = TemplateArgs(
T->getDepth(),
T->getIndex());
293 "Missing argument pack");
298 UsedTemplateArgs.push_back(
303 bool VisitDeclRefExpr(DeclRefExpr *E) {
305 NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(D);
307 return TraverseDecl(D);
318 "Missing argument pack");
322 UsedTemplateArgs.push_back(
327 bool VisitTypedefType(TypedefType *TT) {
328 return inherited::TraverseType(TT->
desugar());
331 bool TraverseDecl(Decl *D) {
332 if (
auto *VD = dyn_cast<ValueDecl>(D)) {
333 if (
auto *Var = dyn_cast<VarDecl>(VD))
334 TraverseStmt(Var->getInit());
335 return TraverseType(VD->getType());
338 return inherited::TraverseDecl(D);
341 bool TraverseCallExpr(CallExpr *CE) {
342 inherited::TraverseStmt(CE->
getCallee());
345 inherited::TraverseStmt(Arg);
350 bool TraverseTypeLoc(TypeLoc TL,
bool TraverseQualifier =
true) {
355 bool TraverseTagType(
const TagType *
T,
bool TraverseQualifier) {
363 bool TraverseInjectedClassNameType(InjectedClassNameType *
T,
364 bool TraverseQualifier) {
365 return TraverseTemplateArguments(
T->getTemplateArgs(SemaRef.
Context));
368 bool TraverseTemplateArgument(
const TemplateArgument &Arg) {
371 Sema::ArgPackSubstIndexRAII _1(SemaRef, std::nullopt);
372 llvm::SaveAndRestore<UnsignedOrNone>
_2(OuterPackSubstIndex,
374 return inherited::TraverseTemplateArgument(Arg);
377 Sema::ArgPackSubstIndexRAII _1(SemaRef, OuterPackSubstIndex);
378 return inherited::TraverseTemplateArgument(Arg);
381 bool TraverseSizeOfPackExpr(SizeOfPackExpr *SOPE) {
382 return TraverseDecl(SOPE->
getPack());
385 bool VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *E) {
390 if (
auto *TTP = dyn_cast_if_present<TemplateTemplateParmDecl>(
397 TemplateArgument Arg = TemplateArgs(TTP->getDepth(), TTP->getPosition());
400 "Missing argument pack");
404 "Null template template argument");
405 UsedTemplateArgs.push_back(
408 return inherited::TraverseTemplateName(
Template);
411 void VisitConstraint(
const NormalizedConstraintWithParamMapping &Constraint) {
413 for (
const auto &List : TemplateArgs)
414 for (
const TemplateArgument &Arg : List.Args)
420 llvm::ArrayRef<TemplateArgumentLoc> Mapping =
422 for (
auto &ArgLoc : Mapping) {
423 TemplateArgument Canonical =
426 UsedTemplateArgs.push_back(Canonical);
427 TraverseTemplateArgument(Canonical);
430 for (
auto &
Used : UsedTemplateArgs) {
431 llvm::FoldingSetNodeID R;
438class ConstraintSatisfactionChecker {
441 SourceLocation TemplateNameLoc;
442 UnsignedOrNone PackSubstitutionIndex;
443 ConstraintSatisfaction &Satisfaction;
444 bool BuildExpression;
448 EvaluateAtomicConstraint(
const Expr *AtomicExpr,
449 const MultiLevelTemplateArgumentList &MLTAL);
451 UnsignedOrNone EvaluateFoldExpandedConstraintSize(
452 const FoldExpandedConstraint &FE,
453 const MultiLevelTemplateArgumentList &MLTAL);
456 std::optional<MultiLevelTemplateArgumentList> SubstitutionInTemplateArguments(
457 const NormalizedConstraintWithParamMapping &Constraint,
458 const MultiLevelTemplateArgumentList &MLTAL,
459 llvm::SmallVector<TemplateArgument> &SubstitutedOuterMost);
461 ExprResult EvaluateSlow(
const AtomicConstraint &Constraint,
462 const MultiLevelTemplateArgumentList &MLTAL);
465 const MultiLevelTemplateArgumentList &MLTAL);
467 ExprResult EvaluateSlow(
const FoldExpandedConstraint &Constraint,
468 const MultiLevelTemplateArgumentList &MLTAL);
471 const MultiLevelTemplateArgumentList &MLTAL);
473 ExprResult EvaluateSlow(
const ConceptIdConstraint &Constraint,
474 const MultiLevelTemplateArgumentList &MLTAL,
478 const MultiLevelTemplateArgumentList &MLTAL);
481 const MultiLevelTemplateArgumentList &MLTAL);
484 ConstraintSatisfactionChecker(Sema &SemaRef,
const NamedDecl *
Template,
485 SourceLocation TemplateNameLoc,
486 UnsignedOrNone PackSubstitutionIndex,
487 ConstraintSatisfaction &Satisfaction,
488 bool BuildExpression)
490 PackSubstitutionIndex(PackSubstitutionIndex),
491 Satisfaction(Satisfaction), BuildExpression(BuildExpression) {}
494 const MultiLevelTemplateArgumentList &MLTAL);
497StringRef allocateStringFromConceptDiagnostic(
const Sema &S,
507ExprResult ConstraintSatisfactionChecker::EvaluateAtomicConstraint(
513 llvm::FoldingSetNodeID
ID;
516 Satisfaction.IsSatisfied =
false;
517 Satisfaction.ContainsErrors =
true;
520 SatisfactionStackRAII StackRAII(S,
Template, ID);
531 if (Inst.isInvalid())
536 SubstitutedExpression =
539 if (SubstitutedExpression.
isInvalid() || Trap.hasErrorOccurred()) {
543 if (!Trap.hasErrorOccurred())
550 Info.takeSFINAEDiagnostic(SubstDiag);
557 Satisfaction.Details.emplace_back(
560 allocateStringFromConceptDiagnostic(S, SubstDiag.second)});
561 Satisfaction.IsSatisfied =
false;
582 SubstitutedExpression.
get(),
585 return SubstitutedExpression;
588std::optional<MultiLevelTemplateArgumentList>
589ConstraintSatisfactionChecker::SubstitutionInTemplateArguments(
595 return std::move(MLTAL);
609 if (Inst.isInvalid())
616 : PackSubstitutionIndex);
621 Satisfaction.IsSatisfied =
false;
629 TD->getLocation(), SubstArgs,
638 SubstitutedOutermost =
639 llvm::to_vector_of<TemplateArgument>(MLTAL.
getOutermost());
641 for (
unsigned I = 0, MappedIndex = 0; I <
Used.size(); I++) {
646 if (I < SubstitutedOutermost.size()) {
647 SubstitutedOutermost[I] = Arg;
650 SubstitutedOutermost.push_back(Arg);
651 Offset = SubstitutedOutermost.size();
654 if (Offset < SubstitutedOutermost.size())
655 SubstitutedOutermost.erase(SubstitutedOutermost.begin() + Offset);
660 return std::move(SubstitutedTemplateArgs);
663ExprResult ConstraintSatisfactionChecker::EvaluateSlow(
668 std::optional<MultiLevelTemplateArgumentList> SubstitutedArgs =
669 SubstitutionInTemplateArguments(Constraint, MLTAL, SubstitutedOutermost);
670 if (!SubstitutedArgs) {
671 Satisfaction.IsSatisfied =
false;
676 ExprResult SubstitutedAtomicExpr = EvaluateAtomicConstraint(
682 if (SubstitutedAtomicExpr.
isUnset())
692 Satisfaction.IsSatisfied =
false;
693 Satisfaction.ContainsErrors =
true;
696 Satisfaction.Details.emplace_back(
698 SubstitutedAtomicExpr.get()->getBeginLoc(),
699 allocateStringFromConceptDiagnostic(S, Msg)});
700 return SubstitutedAtomicExpr;
704 Satisfaction.IsSatisfied =
true;
705 Satisfaction.ContainsErrors =
false;
706 return SubstitutedAtomicExpr;
713 EvalResult.
Diag = &EvaluationDiags;
716 !EvaluationDiags.empty()) {
720 diag::err_non_constant_constraint_expression)
723 S.
Diag(PDiag.first, PDiag.second);
728 "evaluating bool expression didn't produce int");
729 Satisfaction.IsSatisfied = EvalResult.
Val.
getInt().getBoolValue();
730 if (!Satisfaction.IsSatisfied)
731 Satisfaction.Details.emplace_back(SubstitutedAtomicExpr.
get());
733 return SubstitutedAtomicExpr;
736ExprResult ConstraintSatisfactionChecker::Evaluate(
740 unsigned Size = Satisfaction.Details.size();
741 llvm::FoldingSetNodeID
ID;
745 : PackSubstitutionIndex;
749 HashParameterMapping(S, MLTAL, ID, OuterPackSubstIndex)
750 .VisitConstraint(Constraint);
754 auto &Cached = Iter->second.Satisfaction;
755 Satisfaction.ContainsErrors = Cached.ContainsErrors;
756 Satisfaction.IsSatisfied = Cached.IsSatisfied;
757 Satisfaction.Details.insert(Satisfaction.Details.begin() + Size,
758 Cached.Details.begin(), Cached.Details.end());
759 return Iter->second.SubstExpr;
762 ExprResult E = EvaluateSlow(Constraint, MLTAL);
765 Cache.Satisfaction.ContainsErrors = Satisfaction.ContainsErrors;
766 Cache.Satisfaction.IsSatisfied = Satisfaction.IsSatisfied;
767 Cache.Satisfaction.Details.insert(
Cache.Satisfaction.Details.end(),
768 Satisfaction.Details.begin() + Size,
769 Satisfaction.Details.end());
777ConstraintSatisfactionChecker::EvaluateFoldExpandedConstraintSize(
785 assert(!Unexpanded.empty() &&
"Pack expansion without parameter packs?");
787 bool RetainExpansion =
false;
791 false, Expand, RetainExpansion,
792 NumExpansions,
false) ||
793 !Expand || RetainExpansion)
796 if (NumExpansions && S.
getLangOpts().BracketDepth < *NumExpansions)
798 return NumExpansions;
801ExprResult ConstraintSatisfactionChecker::EvaluateSlow(
807 unsigned EffectiveDetailEndIndex = Satisfaction.Details.size();
812 std::optional<MultiLevelTemplateArgumentList> SubstitutedArgs =
813 SubstitutionInTemplateArguments(
815 MLTAL, SubstitutedOutermost);
816 if (!SubstitutedArgs) {
817 Satisfaction.IsSatisfied =
false;
823 EvaluateFoldExpandedConstraintSize(Constraint, *SubstitutedArgs);
827 if (*NumExpansions == 0) {
828 Satisfaction.IsSatisfied = Conjunction;
832 for (
unsigned I = 0; I < *NumExpansions; I++) {
834 Satisfaction.IsSatisfied =
false;
835 Satisfaction.ContainsErrors =
false;
837 ConstraintSatisfactionChecker(S,
Template, TemplateNameLoc,
841 if (BuildExpression &&
Expr.isUsable()) {
846 Conjunction ? BinaryOperatorKind::BO_LAnd
847 : BinaryOperatorKind::BO_LOr,
852 assert(!BuildExpression || !Satisfaction.IsSatisfied);
854 if (!Conjunction && Satisfaction.IsSatisfied) {
855 Satisfaction.Details.erase(Satisfaction.Details.begin() +
856 EffectiveDetailEndIndex,
857 Satisfaction.Details.end());
860 if (Satisfaction.IsSatisfied != Conjunction)
867ExprResult ConstraintSatisfactionChecker::Evaluate(
871 llvm::FoldingSetNodeID
ID;
873 HashParameterMapping(S, MLTAL, ID, std::nullopt).VisitConstraint(Constraint);
878 auto &Cached = Iter->second.Satisfaction;
879 Satisfaction.ContainsErrors = Cached.ContainsErrors;
880 Satisfaction.IsSatisfied = Cached.IsSatisfied;
881 Satisfaction.Details.insert(Satisfaction.Details.end(),
882 Cached.Details.begin(), Cached.Details.end());
883 return Iter->second.SubstExpr;
886 unsigned Size = Satisfaction.Details.size();
888 ExprResult E = EvaluateSlow(Constraint, MLTAL);
890 Cache.Satisfaction.ContainsErrors = Satisfaction.ContainsErrors;
891 Cache.Satisfaction.IsSatisfied = Satisfaction.IsSatisfied;
892 Cache.Satisfaction.Details.insert(
Cache.Satisfaction.Details.end(),
893 Satisfaction.Details.begin() + Size,
894 Satisfaction.Details.end());
900ExprResult ConstraintSatisfactionChecker::EvaluateSlow(
906 std::optional<MultiLevelTemplateArgumentList> SubstitutedArgs =
907 SubstitutionInTemplateArguments(Constraint, MLTAL, SubstitutedOutermost);
909 if (!SubstitutedArgs) {
910 Satisfaction.IsSatisfied =
false;
918 : PackSubstitutionIndex);
930 Trap.hasErrorOccurred()) {
931 Satisfaction.IsSatisfied =
false;
932 if (!Trap.hasErrorOccurred())
937 Info.takeSFINAEDiagnostic(SubstDiag);
944 Satisfaction.Details.insert(
945 Satisfaction.Details.begin() + Size,
948 allocateStringFromConceptDiagnostic(S, SubstDiag.second)});
960 if (SubstitutedConceptId.
isInvalid() || Trap.hasErrorOccurred())
963 if (Size != Satisfaction.Details.size()) {
964 Satisfaction.Details.insert(
965 Satisfaction.Details.begin() + Size,
970 return SubstitutedConceptId;
973ExprResult ConstraintSatisfactionChecker::Evaluate(
982 : PackSubstitutionIndex;
996 if (InstTemplate.isInvalid())
999 unsigned Size = Satisfaction.Details.size();
1004 Satisfaction.Details.insert(Satisfaction.Details.begin() + Size, ConceptId);
1011 if (Satisfaction.IsSatisfied)
1014 llvm::FoldingSetNodeID
ID;
1017 HashParameterMapping(S, MLTAL, ID, OuterPackSubstIndex)
1018 .VisitConstraint(Constraint);
1023 auto &Cached = Iter->second.Satisfaction;
1024 Satisfaction.ContainsErrors = Cached.ContainsErrors;
1025 Satisfaction.IsSatisfied = Cached.IsSatisfied;
1026 Satisfaction.Details.insert(Satisfaction.Details.begin() + Size,
1027 Cached.Details.begin(), Cached.Details.end());
1028 return Iter->second.SubstExpr;
1031 ExprResult CE = EvaluateSlow(Constraint, MLTAL, Size);
1035 Cache.Satisfaction.ContainsErrors = Satisfaction.ContainsErrors;
1036 Cache.Satisfaction.IsSatisfied = Satisfaction.IsSatisfied;
1037 Cache.Satisfaction.Details.insert(
Cache.Satisfaction.Details.end(),
1038 Satisfaction.Details.begin() + Size,
1039 Satisfaction.Details.end());
1040 Cache.SubstExpr = CE;
1045ExprResult ConstraintSatisfactionChecker::Evaluate(
1049 unsigned EffectiveDetailEndIndex = Satisfaction.Details.size();
1056 if (Conjunction && (!Satisfaction.IsSatisfied || Satisfaction.ContainsErrors))
1059 if (!Conjunction && !LHS.
isInvalid() && Satisfaction.IsSatisfied &&
1060 !Satisfaction.ContainsErrors)
1063 Satisfaction.ContainsErrors =
false;
1064 Satisfaction.IsSatisfied =
false;
1068 if (!Conjunction && !RHS.
isInvalid() && Satisfaction.IsSatisfied &&
1069 !Satisfaction.ContainsErrors)
1070 Satisfaction.Details.erase(Satisfaction.Details.begin() +
1071 EffectiveDetailEndIndex,
1072 Satisfaction.Details.end());
1074 if (!BuildExpression)
1084 Conjunction ? BinaryOperatorKind::BO_LAnd
1085 : BinaryOperatorKind::BO_LOr,
1090ExprResult ConstraintSatisfactionChecker::Evaluate(
1093 switch (Constraint.
getKind()) {
1108 llvm_unreachable(
"Unknown ConstraintKind enum");
1119 *ConvertedExpr =
nullptr;
1121 if (AssociatedConstraints.empty()) {
1136 struct SynthesisContextPair {
1142 : Inst(S, InstantiationRange.
getBegin(),
1144 TemplateArgs, InstantiationRange),
1147 std::optional<SynthesisContextPair> SynthesisContext;
1148 if (!TopLevelConceptId)
1159 if (TopLevelConceptId)
1165 ExprResult Res = ConstraintSatisfactionChecker(
1168 ConvertedExpr !=
nullptr)
1169 .Evaluate(*
C, TemplateArgsLists);
1174 if (Res.
isUsable() && ConvertedExpr)
1175 *ConvertedExpr = Res.
get();
1186 llvm::TimeTraceScope TimeScope(
1187 "CheckConstraintSatisfaction", [TemplateIDRange,
this] {
1190 if (AssociatedConstraints.empty()) {
1196 return ::CheckConstraintSatisfaction(
1197 *
this,
nullptr, AssociatedConstraints, TemplateArgsLists,
1198 TemplateIDRange, OutSatisfaction, ConvertedExpr, TopLevelConceptId);
1212 for (
auto List : TemplateArgsLists)
1214 FlattenedArgs.emplace_back(
Context.getCanonicalTemplateArgument(Arg));
1217 if (TopLevelConceptId)
1220 llvm::FoldingSetNodeID ID;
1223 if (
auto *Cached = SatisfactionCache.FindNodeOrInsertPos(ID, InsertPos)) {
1224 OutSatisfaction = *Cached;
1229 std::make_unique<ConstraintSatisfaction>(Owner, FlattenedArgs);
1231 *
this,
Template, AssociatedConstraints, TemplateArgsLists,
1232 TemplateIDRange, *Satisfaction, ConvertedExpr, TopLevelConceptId)) {
1233 OutSatisfaction = std::move(*Satisfaction);
1237 if (
auto *Cached = SatisfactionCache.FindNodeOrInsertPos(ID, InsertPos)) {
1246 OutSatisfaction = *Cached;
1251 OutSatisfaction = *Satisfaction;
1255 SatisfactionCache.InsertNode(Satisfaction.release());
1277 return !ArgLoc.getArgument().isDependent() &&
1278 ArgLoc.getArgument().isConceptOrConceptTemplateParameter();
1280 return Concept->getConstraintExpr();
1303 Constraints.emplace_back(Res.
get());
1315bool Sema::SetupConstraintScope(
1320 "Use LambdaScopeForCallOperatorInstantiationRAII to handle lambda "
1324 InstantiatingTemplate Inst(
1329 if (Inst.isInvalid())
1340 if (addInstantiatedParametersToScope(
1349 if (addInstantiatedParametersToScope(FD, FromMemTempl->getTemplatedDecl(),
1359 FunctionDecl *InstantiatedFrom =
1366 Sema::InstantiatingTemplate::ConstraintsCheck{}, InstantiatedFrom,
1367 TemplateArgs ? *TemplateArgs : ArrayRef<TemplateArgument>{},
1369 if (Inst.isInvalid())
1374 if (addInstantiatedParametersToScope(FD, InstantiatedFrom, Scope, MLTAL))
1383std::optional<MultiLevelTemplateArgumentList>
1384Sema::SetupConstraintCheckingTemplateArgumentsAndScope(
1387 MultiLevelTemplateArgumentList MLTAL;
1394 false, std::nullopt,
1401 if (SetupConstraintScope(FD, TemplateArgs, MLTAL, Scope))
1402 return std::nullopt;
1410 bool ForOverloadResolution) {
1429 if (
const auto *MD = dyn_cast<CXXConversionDecl>(FD);
1432 Satisfaction, UsageLoc,
1446 std::optional<MultiLevelTemplateArgumentList> MLTAL =
1447 SetupConstraintCheckingTemplateArgumentsAndScope(
1455 if (
auto *
Method = dyn_cast<CXXMethodDecl>(FD)) {
1456 ThisQuals =
Method->getMethodQualifiers();
1463 ForOverloadResolution);
1473 const Expr *ConstrExpr) {
1496 std::optional<LocalInstantiationScope> ScopeForParameters;
1499 ScopeForParameters.emplace(S,
true);
1503 FD =
Template->getInstantiatedFromMemberTemplate()->getTemplatedDecl();
1505 if (ScopeForParameters->getInstantiationOfIfExists(PVD))
1507 if (!PVD->isParameterPack()) {
1508 ScopeForParameters->InstantiatedLocal(PVD, PVD);
1527 ScopeForParameters->MakeInstantiatedLocalArgPack(PVD);
1528 ScopeForParameters->InstantiatedLocalPackArg(PVD, PVD);
1532 std::optional<Sema::CXXThisScopeRAII> ThisScope;
1541 std::optional<Sema::ContextRAII> ContextScope;
1549 if (
auto *RD = dyn_cast<CXXRecordDecl>(DC)) {
1561 return SubstConstr.
get();
1565 const Expr *OldConstr,
1567 const Expr *NewConstr) {
1568 if (OldConstr == NewConstr)
1571 if (Old && !
New.isInvalid() && !
New.ContainsDecl(Old) &&
1573 if (
const Expr *SubstConstr =
1576 OldConstr = SubstConstr;
1579 if (
const Expr *SubstConstr =
1582 NewConstr = SubstConstr;
1587 llvm::FoldingSetNodeID ID1, ID2;
1600 "Non-function templates don't need to be checked");
1621 TemplateIDRange, Satisfaction))
1626 TemplateArgString =
" ";
1632 diag::err_template_arg_list_constraints_not_satisfied)
1634 << TemplateArgString << TemplateIDRange;
1646 Template->getAssociatedConstraints(TemplateAC);
1647 if (TemplateAC.empty()) {
1666 SemaRef, PointOfInstantiation,
1668 PointOfInstantiation);
1669 if (Inst.isInvalid())
1679 Template, TemplateAC, MLTAL, PointOfInstantiation, Satisfaction);
1690 return ::CheckFunctionConstraintsWithoutInstantiation(
1691 *
this, PointOfInstantiation,
Decl->getDescribedFunctionTemplate(),
1692 TemplateArgs, Satisfaction);
1697 Template->getAssociatedConstraints(TemplateAC);
1698 if (TemplateAC.empty()) {
1708 std::optional<MultiLevelTemplateArgumentList> MLTAL =
1709 SetupConstraintCheckingTemplateArgumentsAndScope(
Decl, TemplateArgs,
1717 if (
auto *
Method = dyn_cast<CXXMethodDecl>(
Decl)) {
1718 ThisQuals =
Method->getMethodQualifiers();
1727 PointOfInstantiation, Satisfaction);
1734 "Diagnose() can only be used on an unsatisfied requirement");
1737 llvm_unreachable(
"Diagnosing a dependent requirement");
1741 if (!SubstDiag->DiagMessage.empty())
1742 S.
Diag(SubstDiag->DiagLoc,
1743 diag::note_expr_requirement_expr_substitution_error)
1744 << (
int)
First << SubstDiag->SubstitutedEntity
1745 << SubstDiag->DiagMessage;
1747 S.
Diag(SubstDiag->DiagLoc,
1748 diag::note_expr_requirement_expr_unknown_substitution_error)
1749 << (
int)
First << SubstDiag->SubstitutedEntity;
1759 if (!SubstDiag->DiagMessage.empty())
1760 S.
Diag(SubstDiag->DiagLoc,
1761 diag::note_expr_requirement_type_requirement_substitution_error)
1762 << (
int)
First << SubstDiag->SubstitutedEntity
1763 << SubstDiag->DiagMessage;
1768 note_expr_requirement_type_requirement_unknown_substitution_error)
1769 << (
int)
First << SubstDiag->SubstitutedEntity;
1779 llvm_unreachable(
"We checked this above");
1787 "Diagnose() can only be used on an unsatisfied requirement");
1790 llvm_unreachable(
"Diagnosing a dependent requirement");
1794 if (!SubstDiag->DiagMessage.empty())
1795 S.
Diag(SubstDiag->DiagLoc, diag::note_type_requirement_substitution_error)
1796 << (
int)
First << SubstDiag->SubstitutedEntity
1797 << SubstDiag->DiagMessage;
1799 S.
Diag(SubstDiag->DiagLoc,
1800 diag::note_type_requirement_unknown_substitution_error)
1801 << (
int)
First << SubstDiag->SubstitutedEntity;
1805 llvm_unreachable(
"Unknown satisfaction status");
1813 if (
Concept->getTemplateArgsAsWritten()->NumTemplateArgs == 1) {
1817 note_single_arg_concept_specialization_constraint_evaluated_to_false)
1819 <<
Concept->getTemplateArgsAsWritten()->arguments()[0].getArgument()
1820 <<
Concept->getNamedConcept();
1822 S.
Diag(Loc, diag::note_concept_specialization_constraint_evaluated_to_false)
1852 const Expr *SubstExpr,
1855 if (
const BinaryOperator *BO = dyn_cast<BinaryOperator>(SubstExpr)) {
1856 switch (BO->getOpcode()) {
1868 BO->getLHS()->EvaluateKnownConstInt(S.
Context).getBoolValue();
1879 BO->getRHS()->EvaluateKnownConstInt(S.
Context).getBoolValue();
1891 if (BO->getLHS()->getType()->isIntegerType() &&
1892 BO->getRHS()->getType()->isIntegerType()) {
1895 BO->getLHS()->EvaluateAsInt(SimplifiedLHS, S.
Context,
1898 BO->getRHS()->EvaluateAsInt(SimplifiedRHS, S.
Context,
1901 if (!SimplifiedLHS.
Diag && !SimplifiedRHS.
Diag) {
1903 diag::note_atomic_constraint_evaluated_to_false_elaborated)
1916 }
else if (
auto *RE = dyn_cast<RequiresExpr>(SubstExpr)) {
1919 if (!Req->isDependent() && !Req->isSatisfied()) {
1920 if (
auto *E = dyn_cast<concepts::ExprRequirement>(Req))
1922 else if (
auto *
T = dyn_cast<concepts::TypeRequirement>(Req))
1930 }
else if (
auto *CSE = dyn_cast<ConceptSpecializationExpr>(SubstExpr)) {
1934 }
else if (
auto *TTE = dyn_cast<TypeTraitExpr>(SubstExpr);
1935 TTE && TTE->getTrait() == clang::TypeTrait::BTT_IsDeducible) {
1936 assert(TTE->getNumArgs() == 2);
1938 diag::note_is_deducible_constraint_evaluated_to_false)
1939 << TTE->getArg(0)->getType() << TTE->getArg(1)->getType();
1944 diag::note_atomic_constraint_evaluated_to_false)
1954 .
template dyn_cast<const ConstraintSubstitutionDiagnostic *>()) {
1956 S.
Diag(
Diag->first, diag::note_nested_requirement_substitution_error)
1959 S.
Diag(
Diag->first, diag::note_substituted_constraint_expr_is_ill_formed)
1963 if (
const auto *
Concept = dyn_cast<const ConceptReference *>(
Record)) {
1978 "Attempted to diagnose a satisfied constraint");
1989 "Attempted to diagnose a satisfied constraint");
1997class SubstituteParameterMappings {
2005 SubstituteParameterMappings(
Sema &SemaRef,
2009 : SemaRef(SemaRef), MLTAL(MLTAL), ArgsAsWritten(ArgsAsWritten),
2010 InFoldExpr(InFoldExpr) {}
2019 SubstituteParameterMappings(
Sema &SemaRef,
bool InFoldExpr =
false)
2021 InFoldExpr(InFoldExpr) {}
2023 bool substitute(NormalizedConstraint &N);
2026void SubstituteParameterMappings::buildParameterMapping(
2031 llvm::SmallBitVector OccurringIndices(TemplateParams->
size());
2032 llvm::SmallBitVector OccurringIndicesForSubsumption(TemplateParams->
size());
2038 0, OccurringIndices);
2042 0, OccurringIndicesForSubsumption);
2049 0, OccurringIndices);
2053 ->getTemplateArgsAsWritten();
2056 0, OccurringIndices);
2058 unsigned Size = OccurringIndices.count();
2066 for (
unsigned I = 0, J = 0,
C = TemplateParams->
size(); I !=
C; ++I) {
2068 ? ArgsAsWritten->arguments()[I].getLocation()
2072 if (OccurringIndices[I]) {
2076 UsedParams.push_back(Param);
2086 std::move(OccurringIndices), std::move(OccurringIndicesForSubsumption),
2090bool SubstituteParameterMappings::substitute(
2093 buildParameterMapping(N);
2102 InstLocBegin = ArgsAsWritten->getLAngleLoc();
2103 InstLocEnd = ArgsAsWritten->getRAngleLoc();
2105 auto SR =
Arguments[0].getSourceRange();
2106 InstLocBegin = SR.getBegin();
2107 InstLocEnd = SR.getEnd();
2111 SemaRef, InstLocBegin,
2114 {InstLocBegin, InstLocEnd});
2115 if (Inst.isInvalid())
2131 TD->getLocation(), SubstArgs,
2142 if (I < SubstArgs.
size())
2143 Loc = SubstArgs.
arguments()[I].getLocation();
2170 InstLocBegin = ArgsAsWritten->getLAngleLoc();
2171 InstLocEnd = ArgsAsWritten->getRAngleLoc();
2173 auto SR =
Arguments[0].getSourceRange();
2174 InstLocBegin = SR.getBegin();
2175 InstLocEnd = SR.getEnd();
2180 SemaRef, InstLocBegin,
2183 {InstLocBegin, InstLocEnd});
2184 if (Inst.isInvalid())
2193 CSE->getTemplateArgsAsWritten();
2200 CSE->getConceptNameInfo().getLoc(), Out,
2205 auto TemplateArgs = *MLTAL;
2208 return SubstituteParameterMappings(SemaRef, &TemplateArgs, ArgsAsWritten,
2217 assert(!ArgsAsWritten);
2226 assert(!ArgsAsWritten);
2231 return SubstituteParameterMappings(SemaRef,
true)
2237 assert(ArgsAsWritten);
2238 return substitute(CC);
2240 assert(!ArgsAsWritten);
2250 return SubstituteParameterMappings(
2256 if (substitute(Compound.getLHS()))
2258 return substitute(Compound.getRHS());
2261 llvm_unreachable(
"Unknown ConstraintKind enum");
2268 assert(ACs.size() != 0);
2270 fromConstraintExpr(S, D, ACs[0].ConstraintExpr, ACs[0].ArgPackSubstIndex);
2273 for (
unsigned I = 1; I < ACs.size(); ++I) {
2274 auto *
Next = fromConstraintExpr(S, D, ACs[I].ConstraintExpr,
2275 ACs[I].ArgPackSubstIndex);
2286 assert(E !=
nullptr);
2294 llvm::FoldingSetNodeID
ID;
2298 SatisfactionStackRAII StackRAII(S, D, ID);
2305 if (LogicalBinOp BO = E) {
2306 auto *LHS = fromConstraintExpr(S, D, BO.getLHS(), SubstIndex);
2309 auto *RHS = fromConstraintExpr(S, D, BO.getRHS(), SubstIndex);
2315 }
else if (
auto *CSE = dyn_cast<const ConceptSpecializationExpr>(E)) {
2318 Sema::NonSFINAEContext _(S);
2319 Sema::InstantiatingTemplate Inst(
2321 Sema::InstantiatingTemplate::ConstraintNormalization{},
2324 if (Inst.isInvalid())
2345 SubNF = NormalizedConstraint::fromAssociatedConstraints(
2346 S, CD, AssociatedConstraint(Res.
get(), SubstIndex));
2356 }
else if (
auto *FE = dyn_cast<const CXXFoldExpr>(E);
2358 (FE->getOperator() == BinaryOperatorKind::BO_LAnd ||
2359 FE->getOperator() == BinaryOperatorKind::BO_LOr)) {
2364 FE->getOperator() == BinaryOperatorKind::BO_LAnd
2368 if (FE->getInit()) {
2369 auto *LHS = fromConstraintExpr(S, D, FE->getLHS(), SubstIndex);
2370 auto *RHS = fromConstraintExpr(S, D, FE->getRHS(), SubstIndex);
2374 if (FE->isRightFold())
2387 auto *
Sub = fromConstraintExpr(S, D, FE->
getPattern(), SubstIndex);
2399 if (!ConstrainedDeclOrNestedReq) {
2400 auto *Normalized = NormalizedConstraint::fromAssociatedConstraints(
2401 *
this,
nullptr, AssociatedConstraints);
2403 SubstituteParameterMappings(*this).substitute(*Normalized))
2411 ConstrainedDeclOrNestedReq.dyn_cast<
const NamedDecl *>();
2412 auto CacheEntry = NormalizationCache.find(ConstrainedDeclOrNestedReq);
2413 if (CacheEntry == NormalizationCache.end()) {
2414 auto *Normalized = NormalizedConstraint::fromAssociatedConstraints(
2415 *
this, ND, AssociatedConstraints);
2417 NormalizationCache.try_emplace(ConstrainedDeclOrNestedReq,
nullptr);
2421 bool Failed = SubstituteParameterMappings(*this).substitute(*Normalized);
2423 NormalizationCache.try_emplace(ConstrainedDeclOrNestedReq, Normalized)
2428 return CacheEntry->second;
2451 if (It != BPacks.end())
2463 if (
const auto *FD1 = dyn_cast<FunctionDecl>(D1)) {
2469 const auto *FD2 = dyn_cast<FunctionDecl>(D2);
2470 assert(IsExpectedEntity(FD1) && FD2 && IsExpectedEntity(FD2) &&
2471 "use non-instantiated function declaration for constraints partial "
2486 std::pair<const NamedDecl *, const NamedDecl *> Key{D1, D2};
2487 auto CacheEntry = SubsumptionCache.find(Key);
2488 if (CacheEntry != SubsumptionCache.end()) {
2489 Result = CacheEntry->second;
2496 for (
size_t I = 0; I != AC1.size() && I != AC2.size(); ++I) {
2497 if (Depth2 > Depth1) {
2498 AC1[I].ConstraintExpr =
2499 AdjustConstraintDepth(*
this, Depth2 - Depth1)
2500 .TransformExpr(
const_cast<Expr *
>(AC1[I].ConstraintExpr))
2502 }
else if (Depth1 > Depth2) {
2503 AC2[I].ConstraintExpr =
2504 AdjustConstraintDepth(*
this, Depth1 - Depth2)
2505 .TransformExpr(
const_cast<Expr *
>(AC2[I].ConstraintExpr))
2511 std::optional<bool> Subsumes = SC.
Subsumes(D1, AC1, D2, AC2);
2517 SubsumptionCache.try_emplace(Key, *Subsumes);
2528 if (AC1.empty() || AC2.empty())
2531 const Expr *AmbiguousAtomic1 =
nullptr, *AmbiguousAtomic2 =
nullptr;
2542 llvm::FoldingSetNodeID IDA, IDB;
2544 EB->Profile(IDB,
Context,
true);
2548 AmbiguousAtomic1 = EA;
2549 AmbiguousAtomic2 = EB;
2564 bool Is1AtLeastAs2Normally = SC.
Subsumes(Normalized1, Normalized2);
2565 bool Is2AtLeastAs1Normally = SC.
Subsumes(Normalized2, Normalized1);
2568 bool Is1AtLeastAs2 = SC2.
Subsumes(Normalized1, Normalized2);
2569 bool Is2AtLeastAs1 = SC2.
Subsumes(Normalized2, Normalized1);
2571 if (Is1AtLeastAs2 == Is1AtLeastAs2Normally &&
2572 Is2AtLeastAs1 == Is2AtLeastAs1Normally)
2577 assert(AmbiguousAtomic1 && AmbiguousAtomic2);
2579 Diag(AmbiguousAtomic1->
getBeginLoc(), diag::note_ambiguous_atomic_constraints)
2581 Diag(AmbiguousAtomic2->getBeginLoc(),
2582 diag::note_ambiguous_atomic_constraints_similar_expression)
2583 << AmbiguousAtomic2->getSourceRange();
2594 : SemaRef(SemaRef), Callable(Callable), NextID(1) {}
2596uint16_t SubsumptionChecker::getNewLiteralId() {
2597 assert((
unsigned(NextID) + 1 < std::numeric_limits<uint16_t>::max()) &&
2598 "too many constraints!");
2603 auto &Elems = AtomicMap[Ori->getConstraintExpr()];
2618 llvm::FoldingSetNodeID ID;
2619 ID.AddBoolean(Ori->hasParameterMapping());
2620 if (Ori->hasParameterMapping()) {
2621 const auto &Mapping = Ori->getParameterMapping();
2623 Ori->mappingOccurenceListForSubsumption();
2624 for (
auto [Idx, TAL] : llvm::enumerate(Mapping)) {
2631 auto It = Elems.find(ID);
2632 if (It == Elems.end()) {
2635 MappedAtomicConstraint{
2636 Ori, {getNewLiteralId(), Literal::Atomic}}})
2638 ReverseMap[It->second.ID.Value] = Ori;
2640 return It->getSecond().ID;
2644 auto &Elems = FoldMap[Ori->getPattern()];
2646 FoldExpendedConstraintKey K;
2647 K.Kind = Ori->getFoldOperator();
2649 auto It = llvm::find_if(Elems, [&K](
const FoldExpendedConstraintKey &
Other) {
2650 return K.Kind ==
Other.Kind;
2652 if (It == Elems.end()) {
2653 K.ID = {getNewLiteralId(), Literal::FoldExpanded};
2654 It = Elems.insert(Elems.end(), std::move(K));
2655 ReverseMap[It->ID.Value] = Ori;
2661 return SubsumptionChecker::Normalize<CNFFormula>(
C);
2664 return SubsumptionChecker::Normalize<DNFFormula>(
C);
2680template <
typename FormulaType>
2684 auto Add = [&,
this](Clause
C) {
2687 C.erase(llvm::unique(
C),
C.end());
2688 AddUniqueClauseToFormula(Res, std::move(
C));
2693 return {{find(&
static_cast<const AtomicConstraint &
>(NC))}};
2696 return {{find(&
static_cast<const FoldExpandedConstraint &
>(NC))}};
2699 return Normalize<FormulaType>(
2700 static_cast<const ConceptIdConstraint &
>(NC).getNormalizedConstraint());
2703 const auto &Compound =
static_cast<const CompoundConstraint &
>(NC);
2705 SemaRef.runWithSufficientStackSpace(SourceLocation(), [&] {
2706 Left = Normalize<FormulaType>(Compound.getLHS());
2707 Right = Normalize<FormulaType>(Compound.getRHS());
2710 if (Compound.getCompoundKind() == FormulaType::Kind) {
2711 unsigned SizeLeft =
Left.size();
2712 Res = std::move(Left);
2713 Res.reserve(SizeLeft +
Right.size());
2714 std::for_each(std::make_move_iterator(
Right.begin()),
2715 std::make_move_iterator(
Right.end()), Add);
2719 Res.reserve(
Left.size() *
Right.size());
2720 for (
const auto <ransform : Left) {
2721 for (
const auto &RTransform : Right) {
2723 Combined.reserve(LTransform.size() + RTransform.size());
2724 llvm::copy(LTransform, std::back_inserter(Combined));
2725 llvm::copy(RTransform, std::back_inserter(Combined));
2726 Add(std::move(Combined));
2732 llvm_unreachable(
"Unknown ConstraintKind enum");
2735void SubsumptionChecker::AddUniqueClauseToFormula(Formula &F, Clause
C) {
2736 for (
auto &
Other : F) {
2737 if (llvm::equal(
C,
Other))
2747 SemaRef.getNormalizedAssociatedConstraints(DP, P);
2749 return std::nullopt;
2752 SemaRef.getNormalizedAssociatedConstraints(DQ, Q);
2754 return std::nullopt;
2756 return Subsumes(PNormalized, QNormalized);
2762 DNFFormula DNFP = DNF(*P);
2763 CNFFormula CNFQ = CNF(*Q);
2768 const CNFFormula &QCNF) {
2769 for (
const auto &Pi : PDNF) {
2770 for (
const auto &Qj : QCNF) {
2776 if (!DNFSubsumes(Pi, Qj))
2783bool SubsumptionChecker::DNFSubsumes(
const Clause &P,
const Clause &Q) {
2785 return llvm::any_of(P, [&](Literal LP) {
2786 return llvm::any_of(Q, [
this, LP](Literal LQ) {
return Subsumes(LP, LQ); });
2792 std::pair<const FoldExpandedConstraint *, const FoldExpandedConstraint *> Key{
2795 auto It = FoldSubsumptionCache.find(Key);
2796 if (It == FoldSubsumptionCache.end()) {
2805 It = FoldSubsumptionCache.try_emplace(std::move(Key), DoesSubsume).first;
2811 if (A.Kind != B.Kind)
2814 case Literal::Atomic:
2816 return A.Value == B.Value;
2818 *
static_cast<const AtomicConstraint *
>(ReverseMap[A.Value]),
2819 *
static_cast<const AtomicConstraint *
>(ReverseMap[B.Value]));
2820 case Literal::FoldExpanded:
2822 static_cast<const FoldExpandedConstraint *
>(ReverseMap[A.Value]),
2823 static_cast<const FoldExpandedConstraint *
>(ReverseMap[B.Value]));
2825 llvm_unreachable(
"unknown literal kind");
This file provides AST data structures related to concepts.
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 bool Evaluate(APValue &Result, EvalInfo &Info, const Expr *E)
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::Records Records
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 void diagnoseUnsatisfiedConstraintExpr(Sema &S, const UnsatisfiedConstraintRecord &Record, SourceLocation Loc, bool First, concepts::NestedRequirement *Req=nullptr)
static ExprResult SubstituteConceptsInConstraintExpression(Sema &S, const NamedDecl *D, const ConceptSpecializationExpr *CSE, UnsignedOrNone SubstIndex)
static void DiagnoseUnsatisfiedConstraint(Sema &S, ArrayRef< UnsatisfiedConstraintRecord > Records, SourceLocation Loc, bool First=true, concepts::NestedRequirement *Req=nullptr)
static const Expr * SubstituteConstraintExpressionWithoutSatisfaction(Sema &S, const Sema::TemplateCompareNewDeclInfo &DeclInfo, const Expr *ConstrExpr)
static void diagnoseWellFormedUnsatisfiedConstraintExpr(Sema &S, const Expr *SubstExpr, bool First)
static bool DiagRecursiveConstraintEval(Sema &S, llvm::FoldingSetNodeID &ID, const NamedDecl *Templ, const Expr *E, const MultiLevelTemplateArgumentList *MLTAL=nullptr)
static bool CheckConstraintSatisfaction(Sema &S, const NamedDecl *Template, ArrayRef< AssociatedConstraint > AssociatedConstraints, const MultiLevelTemplateArgumentList &TemplateArgsLists, SourceRange TemplateIDRange, ConstraintSatisfaction &Satisfaction, Expr **ConvertedExpr, const ConceptReference *TopLevelConceptId=nullptr)
static void diagnoseUnsatisfiedRequirement(Sema &S, concepts::ExprRequirement *Req, bool First)
static void diagnoseUnsatisfiedConceptIdExpr(Sema &S, const ConceptReference *Concept, SourceLocation Loc, bool First)
static bool CheckFunctionConstraintsWithoutInstantiation(Sema &SemaRef, SourceLocation PointOfInstantiation, FunctionTemplateDecl *Template, ArrayRef< TemplateArgument > TemplateArgs, ConstraintSatisfaction &Satisfaction)
static unsigned CalculateTemplateDepthForConstraints(Sema &S, const NamedDecl *ND, bool SkipForSpecialization=false)
TemplateArgument getCanonicalTemplateArgument(const TemplateArgument &Arg) const
Retrieve the "canonical" template argument.
llvm::StringRef backupStr(llvm::StringRef S) const
const Expr * getConstraintExpr() const
static AtomicConstraint * Create(ASTContext &Ctx, const Expr *ConstraintExpr, const NamedDecl *ConstraintDecl, UnsignedOrNone PackIndex)
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 C++ struct/union/class.
Represents a C++ nested-name-specifier or a global scope specifier.
void Adopt(NestedNameSpecifierLoc Other)
Adopt an existing nested-name-specifier (with source-range information).
const NormalizedConstraint & getLHS() const
static CompoundConstraint * CreateConjunction(ASTContext &Ctx, NormalizedConstraint *LHS, NormalizedConstraint *RHS)
CompoundConstraintKind getCompoundKind() const
const NormalizedConstraint & getRHS() const
static CompoundConstraint * Create(ASTContext &Ctx, NormalizedConstraint *LHS, CompoundConstraintKind CCK, NormalizedConstraint *RHS)
Declaration of a C++20 concept.
ConceptDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
const NormalizedConstraint & getNormalizedConstraint() const
const ConceptSpecializationExpr * getConceptSpecializationExpr() const
static ConceptIdConstraint * Create(ASTContext &Ctx, const ConceptReference *ConceptId, NormalizedConstraint *SubConstraint, const NamedDecl *ConstraintDecl, const ConceptSpecializationExpr *CSE, UnsignedOrNone PackIndex)
const ConceptReference * getConceptId() const
A reference to a concept and its template args, as it appears in the code.
const NestedNameSpecifierLoc & getNestedNameSpecifierLoc() const
NamedDecl * getFoundDecl() const
const DeclarationNameInfo & getConceptNameInfo() const
SourceLocation getBeginLoc() const LLVM_READONLY
const ASTTemplateArgumentListInfo * getTemplateArgsAsWritten() const
TemplateDecl * getNamedConcept() const
SourceLocation getTemplateKWLoc() const
Represents the specialization of a concept - evaluates to a prvalue of type bool.
SourceLocation getBeginLoc() const LLVM_READONLY
SourceLocation getExprLoc() const LLVM_READONLY
ArrayRef< TemplateArgument > getTemplateArguments() const
const ASTTemplateArgumentListInfo * getTemplateArgsAsWritten() const
ConceptReference * getConceptReference() 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...
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &C)
llvm::SmallVector< UnsatisfiedConstraintRecord, 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).
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 isValueDependent() const
Determines whether the value of this expression depends on.
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.
static bool AreCompatibleForSubsumption(const FoldExpandedConstraint &A, const FoldExpandedConstraint &B)
FoldOperatorKind getFoldOperator() const
const Expr * getPattern() const
static FoldExpandedConstraint * Create(ASTContext &Ctx, const Expr *Pattern, const NamedDecl *ConstraintDecl, FoldOperatorKind OpKind, NormalizedConstraint *Constraint)
const NormalizedConstraint & getNormalizedPattern() const
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...
bool hasTemplateArgument(unsigned Depth, unsigned Index) const
Determine whether there is a non-NULL template argument at the given depth and index.
const ArgList & getInnermost() const
Retrieve the innermost template argument list.
void addOuterTemplateArguments(Decl *AssociatedDecl, ArgList Args, bool Final)
Add a new outmost level to the multi-level 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.
void replaceOutermostTemplateArguments(Decl *AssociatedDecl, ArgList Args)
const ArgList & getOutermost() const
Retrieve the outermost template argument list.
bool isAnyArgInstantiationDependent() const
This represents a decl that may have a name.
unsigned getPosition() const
Get the position of the template parameter within its parameter list.
bool isParameterPack() const
Whether this parameter is a non-type template parameter pack.
unsigned getIndex() const
Get the index of the template parameter within its parameter list.
unsigned getDepth() const
Get the nesting depth of the template parameter.
UnsignedOrNone getPackSubstitutionIndex() const
const NamedDecl * getConstraintDecl() const
bool hasMatchingParameterMapping(ASTContext &C, const NormalizedConstraint &Other) const
const OccurenceList & mappingOccurenceList() const
const OccurenceList & mappingOccurenceListForSubsumption() const
TemplateParameterList * getUsedTemplateParamList() const
llvm::MutableArrayRef< TemplateArgumentLoc > getParameterMapping() const
bool hasParameterMapping() const
void updateParameterMapping(OccurenceList Indexes, OccurenceList IndexesForSubsumption, llvm::MutableArrayRef< TemplateArgumentLoc > Args, TemplateParameterList *ParamList)
A (possibly-)qualified type.
QualType getCanonicalType() const
The collection of all-type qualifiers we support.
A class that does preorder or postorder depth-first traversal on the entire Clang AST and visits each...
Scope - A scope is a transient data structure that is used while parsing the program.
PartialDiagnostic PDiag(unsigned DiagID=0)
Build a partial diagnostic.
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
Emit a 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...
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.
TemplateArgumentLoc getTrivialTemplateArgumentLoc(const TemplateArgument &Arg, QualType NTTPType, SourceLocation Loc, NamedDecl *TemplateParam=nullptr)
Allocate a TemplateArgumentLoc where all locations have been initialized to the given location.
ExprResult SubstConceptTemplateArguments(const ConceptSpecializationExpr *CSE, const Expr *ConstraintExpr, const MultiLevelTemplateArgumentList &MLTAL)
Substitute concept template arguments in the constraint expression of a concept-id.
llvm::DenseMap< llvm::FoldingSetNodeID, UnsubstitutedConstraintSatisfactionCacheResult > UnsubstitutedConstraintSatisfactionCache
Cache the satisfaction of an atomic constraint.
bool ConstraintExpressionDependsOnEnclosingTemplate(const FunctionDecl *Friend, unsigned TemplateDepth, const Expr *Constraint)
void MarkUsedTemplateParametersForSubsumptionParameterMapping(const Expr *E, unsigned Depth, llvm::SmallBitVector &Used)
Mark which template parameters are named in a given expression.
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 ...
bool CheckParameterPacksForExpansion(SourceLocation EllipsisLoc, SourceRange PatternRange, ArrayRef< UnexpandedParameterPack > Unexpanded, const MultiLevelTemplateArgumentList &TemplateArgs, bool FailOnPackProducingTemplates, bool &ShouldExpand, bool &RetainExpansion, UnsignedOrNone &NumExpansions, bool Diagnose=true)
Determine whether we could expand a pack expansion with the given set of parameter packs into separat...
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
ExprResult CheckConceptTemplateId(const CXXScopeSpec &SS, SourceLocation TemplateKWLoc, const DeclarationNameInfo &ConceptNameInfo, NamedDecl *FoundDecl, TemplateDecl *NamedConcept, const TemplateArgumentListInfo *TemplateArgs, bool DoCheckConstraintSatisfaction=true)
llvm::PointerUnion< const NamedDecl *, const concepts::NestedRequirement * > ConstrainedDeclOrNestedRequirement
bool SubstTemplateArguments(ArrayRef< TemplateArgumentLoc > Args, const MultiLevelTemplateArgumentList &TemplateArgs, TemplateArgumentListInfo &Outputs)
bool CheckConstraintSatisfaction(ConstrainedDeclOrNestedRequirement Entity, ArrayRef< AssociatedConstraint > AssociatedConstraints, const MultiLevelTemplateArgumentList &TemplateArgLists, SourceRange TemplateIDRange, ConstraintSatisfaction &Satisfaction, const ConceptReference *TopLevelConceptId=nullptr, Expr **ConvertedExpr=nullptr)
Check whether the given list of constraint expressions are satisfied (as if in a 'conjunction') given...
const NormalizedConstraint * getNormalizedAssociatedConstraints(ConstrainedDeclOrNestedRequirement Entity, ArrayRef< AssociatedConstraint > AssociatedConstraints)
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.
TemplateArgument getPackSubstitutedTemplateArgument(TemplateArgument Arg) const
bool AreConstraintExpressionsEqual(const NamedDecl *Old, const Expr *OldConstr, const TemplateCompareNewDeclInfo &New, const Expr *NewConstr)
sema::FunctionScopeInfo * getCurFunction() const
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...
void DiagnoseUnsatisfiedConstraint(const ConstraintSatisfaction &Satisfaction, SourceLocation Loc={}, bool First=true)
Emit diagnostics explaining why a constraint expression was deemed unsatisfied.
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)
SourceManager & getSourceManager() const
bool isSFINAEContext() const
UnsignedOrNone ArgPackSubstIndex
The current index into pack expansion arguments that will be used for substitution of parameter packs...
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 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)
bool SubstTemplateArgumentsInParameterMapping(ArrayRef< TemplateArgumentLoc > Args, SourceLocation BaseLoc, const MultiLevelTemplateArgumentList &TemplateArgs, TemplateArgumentListInfo &Out, bool BuildPackExpansionTypes)
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...
bool CheckTemplateArgumentList(TemplateDecl *Template, SourceLocation TemplateLoc, TemplateArgumentListInfo &TemplateArgs, const DefaultArguments &DefaultArgs, bool PartialTemplateArgs, CheckTemplateArgumentInfo &CTAI, bool UpdateArgsWithConversions=true, bool *ConstraintsNotSatisfied=nullptr)
Check that the given template arguments can be provided to the given template, converting the argumen...
NamedDecl * getPack() const
Retrieve the parameter pack.
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
std::string printToString(const SourceManager &SM) 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
Expr * getReplacement() const
SubsumptionChecker establishes subsumption between two set of constraints.
std::optional< bool > Subsumes(const NamedDecl *DP, ArrayRef< AssociatedConstraint > P, const NamedDecl *DQ, ArrayRef< AssociatedConstraint > Q)
SubsumptionChecker(Sema &SemaRef, SubsumptionCallable Callable={})
llvm::function_ref< bool( const AtomicConstraint &, const AtomicConstraint &)> SubsumptionCallable
A convenient class for passing around template argument information.
ArrayRef< TemplateArgumentLoc > arguments() const
Location wrapper for a TemplateArgument.
Represents a template argument.
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) const
Used to insert TemplateArguments into FoldingSets.
TemplateName getAsTemplate() const
Retrieve the template name for a template name argument.
bool containsUnexpandedParameterPack() const
Whether this template argument contains an unexpanded parameter pack.
@ Pack
The template argument is actually a parameter pack.
ArgKind getKind() const
Return the kind of stored template argument.
bool isPackExpansion() const
Determine whether this template argument is a pack expansion.
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.
bool isNull() const
Determine whether this template name is NULL.
Stores a list of template parameters for a TemplateDecl and its derived classes.
static TemplateParameterList * Create(const ASTContext &C, SourceLocation TemplateLoc, SourceLocation LAngleLoc, ArrayRef< NamedDecl * > Params, SourceLocation RAngleLoc, Expr *RequiresClause)
SourceLocation getLAngleLoc() const
SourceLocation getTemplateLoc() const
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.
QualType getType() const
Get the type for which this source info wrapper provides information.
SourceLocation getNameLoc() const
void setNameLoc(SourceLocation Loc)
The base class of the type hierarchy.
bool isInstantiationDependentType() const
Determine whether this type is an instantiation-dependent type, meaning that the type involves a temp...
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 containsUnexpandedParameterPack() const
Whether this type is or contains an unexpanded parameter pack, used to support C++0x variadic templat...
bool isVariablyModifiedType() const
Whether this type is a variably-modified type (C99 6.7.5).
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
bool hasInvalidConstraint() const
Expr * getConstraintExpr() 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...
__inline void unsigned int _2
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.
bool isa(CodeGen::Address addr)
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
@ TemplateName
The identifier is a template name. FIXME: Add an annotation for that.
@ OK_Ordinary
An ordinary object is located at an address in memory.
llvm::PointerUnion< const Expr *, const ConceptReference *, const ConstraintSubstitutionDiagnostic * > UnsatisfiedConstraintRecord
std::pair< llvm::PointerUnion< const TemplateTypeParmType *, NamedDecl *, const TemplateSpecializationType *, const SubstBuiltinTemplatePackType * >, SourceLocation > UnexpandedParameterPack
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
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.
const FunctionProtoType * T
@ Template
We are parsing a template declaration.
@ Concept
The name was classified as a concept name.
std::pair< SourceLocation, StringRef > ConstraintSubstitutionDiagnostic
Unsatisfied constraint expressions if the template arguments could be substituted into them,...
prec::Level getBinOpPrecedence(tok::TokenKind Kind, bool GreaterThanIsOperator, bool CPlusPlus11)
Return the precedence of the specified binary operator token.
bool isLambdaConversionOperator(CXXConversionDecl *C)
std::pair< SourceLocation, PartialDiagnostic > PartialDiagnosticAt
A partial diagnostic along with the source location where this diagnostic occurs.
@ VK_PRValue
A pr-value expression (in the C++11 taxonomy) produces a temporary value.
U cast(CodeGen::Address addr)
ActionResult< Expr * > ExprResult
@ Other
Other implicit parameter.
The result of a constraint satisfaction check, containing the necessary information to diagnose an un...
ArrayRef< UnsatisfiedConstraintRecord > records() const
Represents an explicit template argument list in C++, e.g., the "<int>" in "sort<int>".
SourceLocation RAngleLoc
The source location of the right angle bracket ('>').
SourceLocation LAngleLoc
The source location of the left angle bracket ('<').
ArrayRef< TemplateArgumentLoc > arguments() const
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...
A normalized constraint, as defined in C++ [temp.constr.normal], is either an atomic constraint,...
NormalizedConstraint(const Expr *ConstraintExpr, const NamedDecl *ConstraintDecl, UnsignedOrNone PackIndex)
SourceRange getSourceRange() const
ConstraintKind getKind() const
SourceLocation getBeginLoc() const
llvm::SmallBitVector OccurenceList
SmallVector< TemplateArgument, 4 > SugaredConverted
The checked, converted argument will be added to the end of these vectors.
A stack object to be created when performing template instantiation.
bool isInvalid() const
Determines whether we have exceeded the maximum recursive template instantiations.
constexpr unsigned toInternalRepresentation() const