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 AdjustConstraints :
public TreeTransform<AdjustConstraints> {
217 unsigned TemplateDepth = 0;
219 bool RemoveNonPackExpansionPacks =
false;
222 using inherited = TreeTransform<AdjustConstraints>;
223 AdjustConstraints(Sema &SemaRef,
unsigned TemplateDepth,
224 bool RemoveNonPackExpansionPacks =
false)
225 : inherited(SemaRef), TemplateDepth(TemplateDepth),
226 RemoveNonPackExpansionPacks(RemoveNonPackExpansionPacks) {}
228 ExprResult RebuildPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc,
229 UnsignedOrNone NumExpansions) {
230 return inherited::RebuildPackExpansion(Pattern, EllipsisLoc, NumExpansions);
233 TemplateArgumentLoc RebuildPackExpansion(TemplateArgumentLoc Pattern,
234 SourceLocation EllipsisLoc,
235 UnsignedOrNone NumExpansions) {
236 if (!RemoveNonPackExpansionPacks)
237 return inherited::RebuildPackExpansion(Pattern, EllipsisLoc,
243 TemplateArgumentLoc &Out, UnexpandedInfo &Info) {
244 if (!RemoveNonPackExpansionPacks)
245 return inherited::PreparePackForExpansion(In, Uneval, Out, Info);
246 assert(
In.getArgument().isPackExpansion());
252 using inherited::TransformTemplateTypeParmType;
253 QualType TransformTemplateTypeParmType(TypeLocBuilder &TLB,
254 TemplateTypeParmTypeLoc TL,
bool) {
255 const TemplateTypeParmType *T = TL.
getTypePtr();
257 TemplateTypeParmDecl *NewTTPDecl =
nullptr;
258 if (TemplateTypeParmDecl *OldTTPDecl = T->getDecl())
259 NewTTPDecl = cast_or_null<TemplateTypeParmDecl>(
262 QualType
Result = getSema().Context.getTemplateTypeParmType(
263 T->getDepth() + TemplateDepth, T->getIndex(),
264 RemoveNonPackExpansionPacks ?
false : T->isParameterPack(), NewTTPDecl);
265 TemplateTypeParmTypeLoc NewTL = TLB.
push<TemplateTypeParmTypeLoc>(
Result);
270 bool AlreadyTransformed(QualType T) {
286 using inherited = RecursiveASTVisitor<HashParameterMapping>;
290 const MultiLevelTemplateArgumentList &TemplateArgs;
291 llvm::FoldingSetNodeID &
ID;
292 llvm::SmallVector<TemplateArgument, 10> UsedTemplateArgs;
294 UnsignedOrNone OuterPackSubstIndex;
296 bool shouldVisitTemplateInstantiations()
const {
return true; }
299 HashParameterMapping(Sema &SemaRef,
300 const MultiLevelTemplateArgumentList &TemplateArgs,
301 llvm::FoldingSetNodeID &ID,
302 UnsignedOrNone OuterPackSubstIndex)
303 : SemaRef(SemaRef), TemplateArgs(TemplateArgs),
ID(
ID),
304 OuterPackSubstIndex(OuterPackSubstIndex) {}
306 bool VisitTemplateTypeParmType(TemplateTypeParmType *T) {
317 TemplateArgument Arg = TemplateArgs(T->getDepth(), T->getIndex());
323 if ((T->isParameterPack() ||
324 (T->getDecl() && T->getDecl()->isTemplateParameterPack())) &&
327 "Missing argument pack");
332 UsedTemplateArgs.push_back(
337 bool VisitDeclRefExpr(DeclRefExpr *E) {
339 NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(D);
341 return TraverseDecl(D);
352 "Missing argument pack");
356 UsedTemplateArgs.push_back(
361 bool VisitTypedefType(TypedefType *TT) {
362 return inherited::TraverseType(TT->
desugar());
365 bool TraverseDecl(Decl *D) {
366 if (
auto *VD = dyn_cast<ValueDecl>(D)) {
367 if (
auto *Var = dyn_cast<VarDecl>(VD))
368 TraverseStmt(Var->getInit());
369 return TraverseType(VD->getType());
372 return inherited::TraverseDecl(D);
375 bool TraverseCallExpr(CallExpr *CE) {
376 inherited::TraverseStmt(CE->
getCallee());
379 inherited::TraverseStmt(Arg);
384 bool TraverseTypeLoc(TypeLoc TL,
bool TraverseQualifier =
true) {
389 bool TraverseDependentNameType(
const DependentNameType *T,
391 return TraverseNestedNameSpecifier(T->getQualifier());
394 bool TraverseTagType(
const TagType *T,
bool TraverseQualifier) {
402 bool TraverseInjectedClassNameType(InjectedClassNameType *T,
403 bool TraverseQualifier) {
404 return TraverseTemplateArguments(T->getTemplateArgs(SemaRef.
Context));
407 bool TraverseTemplateArgument(
const TemplateArgument &Arg) {
410 Sema::ArgPackSubstIndexRAII _1(SemaRef, std::nullopt);
411 llvm::SaveAndRestore<UnsignedOrNone>
_2(OuterPackSubstIndex,
413 return inherited::TraverseTemplateArgument(Arg);
416 Sema::ArgPackSubstIndexRAII _1(SemaRef, OuterPackSubstIndex);
417 return inherited::TraverseTemplateArgument(Arg);
420 bool TraverseSizeOfPackExpr(SizeOfPackExpr *SOPE) {
421 return TraverseDecl(SOPE->
getPack());
424 bool VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *E) {
429 if (
auto *TTP = dyn_cast_if_present<TemplateTemplateParmDecl>(
436 TemplateArgument Arg = TemplateArgs(TTP->getDepth(), TTP->getPosition());
439 "Missing argument pack");
443 "Null template template argument");
444 UsedTemplateArgs.push_back(
447 return inherited::TraverseTemplateName(
Template);
450 void VisitConstraint(
const NormalizedConstraintWithParamMapping &Constraint) {
452 for (
const auto &List : TemplateArgs)
453 for (
const TemplateArgument &Arg : List.Args)
459 llvm::ArrayRef<TemplateArgumentLoc> Mapping =
461 for (
auto &ArgLoc : Mapping) {
462 TemplateArgument Canonical =
465 UsedTemplateArgs.push_back(Canonical);
466 TraverseTemplateArgument(Canonical);
469 for (
auto &
Used : UsedTemplateArgs) {
470 llvm::FoldingSetNodeID
R;
477class ConstraintSatisfactionChecker {
480 SourceLocation TemplateNameLoc;
481 UnsignedOrNone PackSubstitutionIndex;
482 ConstraintSatisfaction &Satisfaction;
483 bool BuildExpression;
488 ConceptDecl *ParentConcept =
nullptr;
492 EvaluateAtomicConstraint(
const Expr *AtomicExpr,
493 const MultiLevelTemplateArgumentList &MLTAL);
495 UnsignedOrNone EvaluateFoldExpandedConstraintSize(
496 const FoldExpandedConstraint &FE,
497 const MultiLevelTemplateArgumentList &MLTAL);
500 std::optional<MultiLevelTemplateArgumentList> SubstitutionInTemplateArguments(
501 const NormalizedConstraintWithParamMapping &Constraint,
502 const MultiLevelTemplateArgumentList &MLTAL,
503 llvm::SmallVector<TemplateArgument> &SubstitutedOuterMost);
505 ExprResult EvaluateSlow(
const AtomicConstraint &Constraint,
506 const MultiLevelTemplateArgumentList &MLTAL);
509 const MultiLevelTemplateArgumentList &MLTAL);
511 ExprResult EvaluateSlow(
const FoldExpandedConstraint &Constraint,
512 const MultiLevelTemplateArgumentList &MLTAL);
515 const MultiLevelTemplateArgumentList &MLTAL);
517 ExprResult EvaluateSlow(
const ConceptIdConstraint &Constraint,
518 const MultiLevelTemplateArgumentList &MLTAL,
522 const MultiLevelTemplateArgumentList &MLTAL);
525 const MultiLevelTemplateArgumentList &MLTAL);
528 ConstraintSatisfactionChecker(Sema &SemaRef,
const NamedDecl *
Template,
529 SourceLocation TemplateNameLoc,
530 UnsignedOrNone PackSubstitutionIndex,
531 ConstraintSatisfaction &Satisfaction,
532 bool BuildExpression)
534 PackSubstitutionIndex(PackSubstitutionIndex),
535 Satisfaction(Satisfaction), BuildExpression(BuildExpression) {}
538 const MultiLevelTemplateArgumentList &MLTAL);
541StringRef allocateStringFromConceptDiagnostic(
const Sema &S,
551ExprResult ConstraintSatisfactionChecker::EvaluateAtomicConstraint(
553 llvm::FoldingSetNodeID
ID;
556 Satisfaction.IsSatisfied =
false;
557 Satisfaction.ContainsErrors =
true;
560 SatisfactionStackRAII StackRAII(S,
Template, ID);
571 if (Inst.isInvalid())
576 SubstitutedExpression =
579 if (SubstitutedExpression.
isInvalid() || Trap.hasErrorOccurred()) {
583 if (!Trap.hasErrorOccurred())
590 Info.takeSFINAEDiagnostic(SubstDiag);
597 Satisfaction.Details.emplace_back(
600 allocateStringFromConceptDiagnostic(S, SubstDiag.second)});
601 Satisfaction.IsSatisfied =
false;
622 SubstitutedExpression.
get(),
625 return SubstitutedExpression;
628std::optional<MultiLevelTemplateArgumentList>
629ConstraintSatisfactionChecker::SubstitutionInTemplateArguments(
652 if (Inst.isInvalid())
659 : PackSubstitutionIndex);
664 Satisfaction.IsSatisfied =
false;
672 TD->getLocation(), SubstArgs,
681 SubstitutedOutermost =
682 llvm::to_vector_of<TemplateArgument>(MLTAL.
getOutermost());
684 for (
unsigned I = 0, MappedIndex = 0; I <
Used.size(); I++) {
689 if (I < SubstitutedOutermost.size()) {
690 SubstitutedOutermost[I] = Arg;
693 SubstitutedOutermost.push_back(Arg);
694 Offset = SubstitutedOutermost.size();
697 if (Offset < SubstitutedOutermost.size())
698 SubstitutedOutermost.erase(SubstitutedOutermost.begin() + Offset);
703 return std::move(SubstitutedTemplateArgs);
706ExprResult ConstraintSatisfactionChecker::EvaluateSlow(
709 std::optional<EnterExpressionEvaluationContext> EvaluationContext;
710 EvaluationContext.emplace(
715 std::optional<MultiLevelTemplateArgumentList> SubstitutedArgs =
716 SubstitutionInTemplateArguments(Constraint, MLTAL, SubstitutedOutermost);
717 if (!SubstitutedArgs) {
718 Satisfaction.IsSatisfied =
false;
728 EvaluationContext.emplace(
732 S.
Context, ParentConcept->getDeclContext(),
733 ParentConcept->getBeginLoc(), SubstitutedOutermost));
737 ExprResult SubstitutedAtomicExpr = EvaluateAtomicConstraint(
743 if (SubstitutedAtomicExpr.
isUnset())
753 Satisfaction.IsSatisfied =
false;
754 Satisfaction.ContainsErrors =
true;
757 Satisfaction.Details.emplace_back(
759 SubstitutedAtomicExpr.get()->getBeginLoc(),
760 allocateStringFromConceptDiagnostic(S, Msg)});
761 return SubstitutedAtomicExpr;
765 Satisfaction.IsSatisfied =
true;
766 Satisfaction.ContainsErrors =
false;
767 return SubstitutedAtomicExpr;
772 EvalResult.
Diag = &EvaluationDiags;
775 !EvaluationDiags.empty()) {
779 diag::err_non_constant_constraint_expression)
782 S.
Diag(PDiag.first, PDiag.second);
787 "evaluating bool expression didn't produce int");
788 Satisfaction.IsSatisfied = EvalResult.
Val.
getInt().getBoolValue();
789 if (!Satisfaction.IsSatisfied)
790 Satisfaction.Details.emplace_back(SubstitutedAtomicExpr.
get());
792 return SubstitutedAtomicExpr;
795ExprResult ConstraintSatisfactionChecker::Evaluate(
799 unsigned Size = Satisfaction.Details.size();
800 llvm::FoldingSetNodeID
ID;
804 : PackSubstitutionIndex;
808 HashParameterMapping(S, MLTAL, ID, OuterPackSubstIndex)
809 .VisitConstraint(Constraint);
813 auto &Cached = Iter->second.Satisfaction;
814 Satisfaction.ContainsErrors = Cached.ContainsErrors;
815 Satisfaction.IsSatisfied = Cached.IsSatisfied;
816 Satisfaction.Details.insert(Satisfaction.Details.begin() + Size,
817 Cached.Details.begin(), Cached.Details.end());
818 return Iter->second.SubstExpr;
821 ExprResult E = EvaluateSlow(Constraint, MLTAL);
824 Cache.Satisfaction.ContainsErrors = Satisfaction.ContainsErrors;
825 Cache.Satisfaction.IsSatisfied = Satisfaction.IsSatisfied;
826 Cache.Satisfaction.Details.insert(
Cache.Satisfaction.Details.end(),
827 Satisfaction.Details.begin() + Size,
828 Satisfaction.Details.end());
836ConstraintSatisfactionChecker::EvaluateFoldExpandedConstraintSize(
844 assert(!Unexpanded.empty() &&
"Pack expansion without parameter packs?");
846 bool RetainExpansion =
false;
850 false, Expand, RetainExpansion,
851 NumExpansions,
false) ||
852 !Expand || RetainExpansion)
855 if (NumExpansions && S.
getLangOpts().BracketDepth < *NumExpansions)
857 return NumExpansions;
860ExprResult ConstraintSatisfactionChecker::EvaluateSlow(
866 unsigned EffectiveDetailEndIndex = Satisfaction.Details.size();
871 std::optional<MultiLevelTemplateArgumentList> SubstitutedArgs =
872 SubstitutionInTemplateArguments(
874 MLTAL, SubstitutedOutermost);
875 if (!SubstitutedArgs) {
876 Satisfaction.IsSatisfied =
false;
882 EvaluateFoldExpandedConstraintSize(Constraint, *SubstitutedArgs);
886 if (*NumExpansions == 0) {
887 Satisfaction.IsSatisfied = Conjunction;
891 for (
unsigned I = 0; I < *NumExpansions; I++) {
893 Satisfaction.IsSatisfied =
false;
894 Satisfaction.ContainsErrors =
false;
896 ConstraintSatisfactionChecker(S,
Template, TemplateNameLoc,
900 if (BuildExpression &&
Expr.isUsable()) {
905 Conjunction ? BinaryOperatorKind::BO_LAnd
906 : BinaryOperatorKind::BO_LOr,
911 assert(!BuildExpression || !Satisfaction.IsSatisfied);
913 if (!Conjunction && Satisfaction.IsSatisfied) {
914 Satisfaction.Details.erase(Satisfaction.Details.begin() +
915 EffectiveDetailEndIndex,
916 Satisfaction.Details.end());
919 if (Satisfaction.IsSatisfied != Conjunction)
926ExprResult ConstraintSatisfactionChecker::Evaluate(
930 llvm::FoldingSetNodeID
ID;
932 HashParameterMapping(S, MLTAL, ID, std::nullopt).VisitConstraint(Constraint);
937 auto &Cached = Iter->second.Satisfaction;
938 Satisfaction.ContainsErrors = Cached.ContainsErrors;
939 Satisfaction.IsSatisfied = Cached.IsSatisfied;
940 Satisfaction.Details.insert(Satisfaction.Details.end(),
941 Cached.Details.begin(), Cached.Details.end());
942 return Iter->second.SubstExpr;
945 unsigned Size = Satisfaction.Details.size();
947 ExprResult E = EvaluateSlow(Constraint, MLTAL);
949 Cache.Satisfaction.ContainsErrors = Satisfaction.ContainsErrors;
950 Cache.Satisfaction.IsSatisfied = Satisfaction.IsSatisfied;
951 Cache.Satisfaction.Details.insert(
Cache.Satisfaction.Details.end(),
952 Satisfaction.Details.begin() + Size,
953 Satisfaction.Details.end());
959ExprResult ConstraintSatisfactionChecker::EvaluateSlow(
965 std::optional<MultiLevelTemplateArgumentList> SubstitutedArgs =
966 SubstitutionInTemplateArguments(Constraint, MLTAL, SubstitutedOutermost);
968 if (!SubstitutedArgs) {
969 Satisfaction.IsSatisfied =
false;
977 : PackSubstitutionIndex);
989 Trap.hasErrorOccurred()) {
990 Satisfaction.IsSatisfied =
false;
991 if (!Trap.hasErrorOccurred())
996 Info.takeSFINAEDiagnostic(SubstDiag);
1003 Satisfaction.Details.insert(
1004 Satisfaction.Details.begin() + Size,
1007 allocateStringFromConceptDiagnostic(S, SubstDiag.second)});
1019 if (SubstitutedConceptId.
isInvalid() || Trap.hasErrorOccurred())
1022 if (Size != Satisfaction.Details.size()) {
1023 Satisfaction.Details.insert(
1024 Satisfaction.Details.begin() + Size,
1029 return SubstitutedConceptId;
1032ExprResult ConstraintSatisfactionChecker::Evaluate(
1041 : PackSubstitutionIndex;
1055 if (InstTemplate.isInvalid())
1061 unsigned Size = Satisfaction.Details.size();
1066 Satisfaction.Details.insert(Satisfaction.Details.begin() + Size, ConceptId);
1073 if (Satisfaction.IsSatisfied)
1076 llvm::FoldingSetNodeID
ID;
1079 HashParameterMapping(S, MLTAL, ID, OuterPackSubstIndex)
1080 .VisitConstraint(Constraint);
1085 auto &Cached = Iter->second.Satisfaction;
1086 Satisfaction.ContainsErrors = Cached.ContainsErrors;
1087 Satisfaction.IsSatisfied = Cached.IsSatisfied;
1088 Satisfaction.Details.insert(Satisfaction.Details.begin() + Size,
1089 Cached.Details.begin(), Cached.Details.end());
1090 return Iter->second.SubstExpr;
1093 ExprResult CE = EvaluateSlow(Constraint, MLTAL, Size);
1097 Cache.Satisfaction.ContainsErrors = Satisfaction.ContainsErrors;
1098 Cache.Satisfaction.IsSatisfied = Satisfaction.IsSatisfied;
1099 Cache.Satisfaction.Details.insert(
Cache.Satisfaction.Details.end(),
1100 Satisfaction.Details.begin() + Size,
1101 Satisfaction.Details.end());
1102 Cache.SubstExpr = CE;
1107ExprResult ConstraintSatisfactionChecker::Evaluate(
1111 unsigned EffectiveDetailEndIndex = Satisfaction.Details.size();
1118 if (Conjunction && (!Satisfaction.IsSatisfied || Satisfaction.ContainsErrors))
1121 if (!Conjunction && !LHS.
isInvalid() && Satisfaction.IsSatisfied &&
1122 !Satisfaction.ContainsErrors)
1125 Satisfaction.ContainsErrors =
false;
1126 Satisfaction.IsSatisfied =
false;
1130 if (!Conjunction && !RHS.
isInvalid() && Satisfaction.IsSatisfied &&
1131 !Satisfaction.ContainsErrors)
1132 Satisfaction.Details.erase(Satisfaction.Details.begin() +
1133 EffectiveDetailEndIndex,
1134 Satisfaction.Details.end());
1136 if (!BuildExpression)
1146 Conjunction ? BinaryOperatorKind::BO_LAnd
1147 : BinaryOperatorKind::BO_LOr,
1152ExprResult ConstraintSatisfactionChecker::Evaluate(
1155 switch (Constraint.
getKind()) {
1170 llvm_unreachable(
"Unknown ConstraintKind enum");
1181 *ConvertedExpr =
nullptr;
1183 if (AssociatedConstraints.empty()) {
1203 struct SynthesisContextPair {
1209 : Inst(S, InstantiationRange.
getBegin(),
1211 TemplateArgs, InstantiationRange),
1214 std::optional<SynthesisContextPair> SynthesisContext;
1215 if (!TopLevelConceptId)
1226 if (TopLevelConceptId)
1232 ExprResult Res = ConstraintSatisfactionChecker(
1235 ConvertedExpr !=
nullptr)
1236 .Evaluate(*
C, TemplateArgsLists);
1241 if (Res.
isUsable() && ConvertedExpr)
1242 *ConvertedExpr = Res.
get();
1253 llvm::TimeTraceScope TimeScope(
1254 "CheckConstraintSatisfaction", [TemplateIDRange,
this] {
1257 if (AssociatedConstraints.empty()) {
1263 return ::CheckConstraintSatisfaction(
1264 *
this,
nullptr, AssociatedConstraints, TemplateArgsLists,
1265 TemplateIDRange, OutSatisfaction, ConvertedExpr, TopLevelConceptId);
1279 for (
auto List : TemplateArgsLists)
1281 FlattenedArgs.emplace_back(
Context.getCanonicalTemplateArgument(Arg));
1284 if (TopLevelConceptId)
1287 llvm::FoldingSetNodeID ID;
1290 if (
auto *Cached = SatisfactionCache.FindNodeOrInsertPos(ID, InsertPos)) {
1291 OutSatisfaction = *Cached;
1296 std::make_unique<ConstraintSatisfaction>(Owner, FlattenedArgs);
1298 *
this,
Template, AssociatedConstraints, TemplateArgsLists,
1299 TemplateIDRange, *Satisfaction, ConvertedExpr, TopLevelConceptId)) {
1300 OutSatisfaction = std::move(*Satisfaction);
1304 if (
auto *Cached = SatisfactionCache.FindNodeOrInsertPos(ID, InsertPos)) {
1313 OutSatisfaction = *Cached;
1318 OutSatisfaction = *Satisfaction;
1322 SatisfactionCache.InsertNode(Satisfaction.release());
1344 return !ArgLoc.getArgument().isDependent() &&
1345 ArgLoc.getArgument().isConceptOrConceptTemplateParameter();
1347 return Concept->getConstraintExpr();
1360bool Sema::SetupConstraintScope(
1365 "Use LambdaScopeForCallOperatorInstantiationRAII to handle lambda "
1371 Sema::InstantiatingTemplate::ConstraintsCheck{}, PrimaryTemplate,
1372 TemplateArgs ? *TemplateArgs : ArrayRef<TemplateArgument>{},
1374 if (Inst.isInvalid())
1383 MultiLevelTemplateArgumentList JustTemplArgs(FD, SpecArgs->asArray(),
1385 if (addInstantiatedParametersToScope(
1392 if (FunctionTemplateDecl *FromMemTempl =
1394 if (addInstantiatedParametersToScope(FD, FromMemTempl->getTemplatedDecl(),
1404 FunctionDecl *InstantiatedFrom =
1411 Sema::InstantiatingTemplate::ConstraintsCheck{}, InstantiatedFrom,
1412 TemplateArgs ? *TemplateArgs : ArrayRef<TemplateArgument>{},
1414 if (Inst.isInvalid())
1419 if (addInstantiatedParametersToScope(FD, InstantiatedFrom, Scope, MLTAL))
1428std::optional<MultiLevelTemplateArgumentList>
1429Sema::SetupConstraintCheckingTemplateArgumentsAndScope(
1432 MultiLevelTemplateArgumentList MLTAL;
1439 false, std::nullopt,
1446 if (SetupConstraintScope(FD, TemplateArgs, MLTAL, Scope))
1447 return std::nullopt;
1455 bool ForOverloadResolution) {
1474 if (
const auto *MD = dyn_cast<CXXConversionDecl>(FD);
1477 Satisfaction, UsageLoc,
1491 std::optional<MultiLevelTemplateArgumentList> MLTAL =
1492 SetupConstraintCheckingTemplateArgumentsAndScope(
1500 if (
auto *
Method = dyn_cast<CXXMethodDecl>(FD)) {
1501 ThisQuals =
Method->getMethodQualifiers();
1508 ForOverloadResolution);
1518 const Expr *ConstrExpr) {
1541 std::optional<LocalInstantiationScope> ScopeForParameters;
1544 ScopeForParameters.emplace(S,
true);
1548 FD =
Template->getInstantiatedFromMemberTemplate()->getTemplatedDecl();
1550 if (ScopeForParameters->getInstantiationOfIfExists(PVD))
1552 if (!PVD->isParameterPack()) {
1553 ScopeForParameters->InstantiatedLocal(PVD, PVD);
1572 ScopeForParameters->MakeInstantiatedLocalArgPack(PVD);
1573 ScopeForParameters->InstantiatedLocalPackArg(PVD, PVD);
1577 std::optional<Sema::CXXThisScopeRAII> ThisScope;
1586 std::optional<Sema::ContextRAII> ContextScope;
1594 if (
auto *RD = dyn_cast<CXXRecordDecl>(DC)) {
1606 return SubstConstr.
get();
1610 const Expr *OldConstr,
1612 const Expr *NewConstr) {
1613 if (OldConstr == NewConstr)
1616 if (Old && !
New.isInvalid() && !
New.ContainsDecl(Old) &&
1618 if (
const Expr *SubstConstr =
1621 OldConstr = SubstConstr;
1624 if (
const Expr *SubstConstr =
1627 NewConstr = SubstConstr;
1632 llvm::FoldingSetNodeID ID1, ID2;
1645 "Non-function templates don't need to be checked");
1666 TemplateIDRange, Satisfaction))
1671 TemplateArgString =
" ";
1677 diag::err_template_arg_list_constraints_not_satisfied)
1679 << TemplateArgString << TemplateIDRange;
1691 Template->getAssociatedConstraints(TemplateAC);
1692 if (TemplateAC.empty()) {
1711 SemaRef, PointOfInstantiation,
1713 PointOfInstantiation);
1714 if (Inst.isInvalid())
1724 Template, TemplateAC, MLTAL, PointOfInstantiation, Satisfaction);
1735 return ::CheckFunctionConstraintsWithoutInstantiation(
1736 *
this, PointOfInstantiation,
Decl->getDescribedFunctionTemplate(),
1737 TemplateArgs, Satisfaction);
1742 Template->getAssociatedConstraints(TemplateAC);
1743 if (TemplateAC.empty()) {
1753 std::optional<MultiLevelTemplateArgumentList> MLTAL =
1754 SetupConstraintCheckingTemplateArgumentsAndScope(
Decl, TemplateArgs,
1762 if (
auto *
Method = dyn_cast<CXXMethodDecl>(
Decl)) {
1763 ThisQuals =
Method->getMethodQualifiers();
1772 PointOfInstantiation, Satisfaction);
1779 "Diagnose() can only be used on an unsatisfied requirement");
1782 llvm_unreachable(
"Diagnosing a dependent requirement");
1786 if (!SubstDiag->DiagMessage.empty())
1787 S.
Diag(SubstDiag->DiagLoc,
1788 diag::note_expr_requirement_expr_substitution_error)
1789 << (
int)
First << SubstDiag->SubstitutedEntity
1790 << SubstDiag->DiagMessage;
1792 S.
Diag(SubstDiag->DiagLoc,
1793 diag::note_expr_requirement_expr_unknown_substitution_error)
1794 << (
int)
First << SubstDiag->SubstitutedEntity;
1804 if (!SubstDiag->DiagMessage.empty())
1805 S.
Diag(SubstDiag->DiagLoc,
1806 diag::note_expr_requirement_type_requirement_substitution_error)
1807 << (
int)
First << SubstDiag->SubstitutedEntity
1808 << SubstDiag->DiagMessage;
1813 note_expr_requirement_type_requirement_unknown_substitution_error)
1814 << (
int)
First << SubstDiag->SubstitutedEntity;
1824 llvm_unreachable(
"We checked this above");
1832 "Diagnose() can only be used on an unsatisfied requirement");
1835 llvm_unreachable(
"Diagnosing a dependent requirement");
1839 if (!SubstDiag->DiagMessage.empty())
1840 S.
Diag(SubstDiag->DiagLoc, diag::note_type_requirement_substitution_error)
1841 << (
int)
First << SubstDiag->SubstitutedEntity
1842 << SubstDiag->DiagMessage;
1844 S.
Diag(SubstDiag->DiagLoc,
1845 diag::note_type_requirement_unknown_substitution_error)
1846 << (
int)
First << SubstDiag->SubstitutedEntity;
1850 llvm_unreachable(
"Unknown satisfaction status");
1858 if (
Concept->getTemplateArgsAsWritten()->NumTemplateArgs == 1) {
1862 note_single_arg_concept_specialization_constraint_evaluated_to_false)
1864 <<
Concept->getTemplateArgsAsWritten()->arguments()[0].getArgument()
1865 <<
Concept->getNamedConcept();
1867 S.
Diag(Loc, diag::note_concept_specialization_constraint_evaluated_to_false)
1897 const Expr *SubstExpr,
1900 if (
const BinaryOperator *BO = dyn_cast<BinaryOperator>(SubstExpr)) {
1901 switch (BO->getOpcode()) {
1913 BO->getLHS()->EvaluateKnownConstInt(S.
Context).getBoolValue();
1924 BO->getRHS()->EvaluateKnownConstInt(S.
Context).getBoolValue();
1936 if (BO->getLHS()->getType()->isIntegerType() &&
1937 BO->getRHS()->getType()->isIntegerType()) {
1940 BO->getLHS()->EvaluateAsInt(SimplifiedLHS, S.
Context,
1943 BO->getRHS()->EvaluateAsInt(SimplifiedRHS, S.
Context,
1946 if (!SimplifiedLHS.
Diag && !SimplifiedRHS.
Diag) {
1948 diag::note_atomic_constraint_evaluated_to_false_elaborated)
1961 }
else if (
auto *RE = dyn_cast<RequiresExpr>(SubstExpr)) {
1964 if (!Req->isDependent() && !Req->isSatisfied()) {
1965 if (
auto *E = dyn_cast<concepts::ExprRequirement>(Req))
1967 else if (
auto *T = dyn_cast<concepts::TypeRequirement>(Req))
1975 }
else if (
auto *CSE = dyn_cast<ConceptSpecializationExpr>(SubstExpr)) {
1979 }
else if (
auto *TTE = dyn_cast<TypeTraitExpr>(SubstExpr);
1980 TTE && TTE->getTrait() == clang::TypeTrait::BTT_IsDeducible) {
1981 assert(TTE->getNumArgs() == 2);
1983 diag::note_is_deducible_constraint_evaluated_to_false)
1984 << TTE->getArg(0)->getType() << TTE->getArg(1)->getType();
1989 diag::note_atomic_constraint_evaluated_to_false)
1999 .
template dyn_cast<const ConstraintSubstitutionDiagnostic *>()) {
2001 S.
Diag(
Diag->first, diag::note_nested_requirement_substitution_error)
2004 S.
Diag(
Diag->first, diag::note_substituted_constraint_expr_is_ill_formed)
2008 if (
const auto *
Concept = dyn_cast<const ConceptReference *>(
Record)) {
2023 "Attempted to diagnose a satisfied constraint");
2034 "Attempted to diagnose a satisfied constraint");
2042class SubstituteParameterMappings {
2054 bool RemovePacksForFoldExpr;
2056 SubstituteParameterMappings(
Sema &SemaRef,
2059 bool RemovePacksForFoldExpr)
2060 : SemaRef(SemaRef), MLTAL(MLTAL), ArgsAsWritten(ArgsAsWritten),
2061 RemovePacksForFoldExpr(RemovePacksForFoldExpr) {}
2070 SubstituteParameterMappings(
Sema &SemaRef,
2071 bool RemovePacksForFoldExpr =
false)
2073 RemovePacksForFoldExpr(RemovePacksForFoldExpr) {}
2075 bool substitute(NormalizedConstraint &N);
2078void SubstituteParameterMappings::buildParameterMapping(
2083 llvm::SmallBitVector OccurringIndices(TemplateParams->
size());
2084 llvm::SmallBitVector OccurringIndicesForSubsumption(TemplateParams->
size());
2090 0, OccurringIndices);
2094 0, OccurringIndicesForSubsumption);
2101 0, OccurringIndices);
2105 ->getTemplateArgsAsWritten();
2108 0, OccurringIndices);
2110 unsigned Size = OccurringIndices.count();
2118 for (
unsigned I = 0, J = 0,
C = TemplateParams->
size(); I !=
C; ++I) {
2120 ? ArgsAsWritten->arguments()[I].getLocation()
2124 if (OccurringIndices[I]) {
2128 UsedParams.push_back(Param);
2138 std::move(OccurringIndices), std::move(OccurringIndicesForSubsumption),
2142bool SubstituteParameterMappings::substitute(
2145 buildParameterMapping(N);
2154 InstLocBegin = ArgsAsWritten->getLAngleLoc();
2155 InstLocEnd = ArgsAsWritten->getRAngleLoc();
2157 auto SR =
Arguments[0].getSourceRange();
2158 InstLocBegin = SR.getBegin();
2159 InstLocEnd = SR.getEnd();
2163 SemaRef, InstLocBegin,
2166 {InstLocBegin, InstLocEnd});
2167 if (Inst.isInvalid())
2182 TD->getLocation(), SubstArgs,
2193 if (I < SubstArgs.
size())
2194 Loc = SubstArgs.
arguments()[I].getLocation();
2221 InstLocBegin = ArgsAsWritten->getLAngleLoc();
2222 InstLocEnd = ArgsAsWritten->getRAngleLoc();
2224 auto SR =
Arguments[0].getSourceRange();
2225 InstLocBegin = SR.getBegin();
2226 InstLocEnd = SR.getEnd();
2231 SemaRef, InstLocBegin,
2234 {InstLocBegin, InstLocEnd});
2235 if (Inst.isInvalid())
2244 CSE->getTemplateArgsAsWritten();
2250 CSE->getConceptNameInfo().getLoc(), Out,
2255 auto TemplateArgs = *MLTAL;
2258 return SubstituteParameterMappings(SemaRef, &TemplateArgs, ArgsAsWritten,
2259 RemovePacksForFoldExpr)
2267 assert(!ArgsAsWritten);
2276 assert(!ArgsAsWritten);
2281 return SubstituteParameterMappings(SemaRef,
true)
2287 assert(ArgsAsWritten);
2288 return substitute(CC);
2290 assert(!ArgsAsWritten);
2294 if (RemovePacksForFoldExpr) {
2298 if (AdjustConstraints(SemaRef, 0,
2300 .TransformTemplateArguments(InputArgLoc.begin(),
2301 InputArgLoc.end(), OutArgs))
2321 return SubstituteParameterMappings(SemaRef, &MLTAL,
2323 RemovePacksForFoldExpr)
2328 if (substitute(Compound.getLHS()))
2330 return substitute(Compound.getRHS());
2333 llvm_unreachable(
"Unknown ConstraintKind enum");
2340 assert(ACs.size() != 0);
2342 fromConstraintExpr(S, D, ACs[0].ConstraintExpr, ACs[0].ArgPackSubstIndex);
2345 for (
unsigned I = 1; I < ACs.size(); ++I) {
2346 auto *
Next = fromConstraintExpr(S, D, ACs[I].ConstraintExpr,
2347 ACs[I].ArgPackSubstIndex);
2358 assert(E !=
nullptr);
2366 llvm::FoldingSetNodeID
ID;
2370 SatisfactionStackRAII StackRAII(S, D, ID);
2377 if (LogicalBinOp BO = E) {
2378 auto *LHS = fromConstraintExpr(S, D, BO.getLHS(), SubstIndex);
2381 auto *RHS = fromConstraintExpr(S, D, BO.getRHS(), SubstIndex);
2387 }
else if (
auto *CSE = dyn_cast<const ConceptSpecializationExpr>(E)) {
2390 Sema::NonSFINAEContext _(S);
2391 Sema::InstantiatingTemplate Inst(
2393 Sema::InstantiatingTemplate::ConstraintNormalization{},
2396 if (Inst.isInvalid())
2417 SubNF = NormalizedConstraint::fromAssociatedConstraints(
2418 S, CD, AssociatedConstraint(Res.
get(), SubstIndex));
2428 }
else if (
auto *FE = dyn_cast<const CXXFoldExpr>(E);
2430 (FE->getOperator() == BinaryOperatorKind::BO_LAnd ||
2431 FE->getOperator() == BinaryOperatorKind::BO_LOr)) {
2436 FE->getOperator() == BinaryOperatorKind::BO_LAnd
2440 if (FE->getInit()) {
2441 auto *LHS = fromConstraintExpr(S, D, FE->getLHS(), SubstIndex);
2442 auto *RHS = fromConstraintExpr(S, D, FE->getRHS(), SubstIndex);
2446 if (FE->isRightFold())
2459 auto *
Sub = fromConstraintExpr(S, D, FE->
getPattern(), SubstIndex);
2471 if (!ConstrainedDeclOrNestedReq) {
2472 auto *Normalized = NormalizedConstraint::fromAssociatedConstraints(
2473 *
this,
nullptr, AssociatedConstraints);
2475 SubstituteParameterMappings(*this).substitute(*Normalized))
2483 ConstrainedDeclOrNestedReq.dyn_cast<
const NamedDecl *>();
2484 auto CacheEntry = NormalizationCache.find(ConstrainedDeclOrNestedReq);
2485 if (CacheEntry == NormalizationCache.end()) {
2486 auto *Normalized = NormalizedConstraint::fromAssociatedConstraints(
2487 *
this, ND, AssociatedConstraints);
2489 NormalizationCache.try_emplace(ConstrainedDeclOrNestedReq,
nullptr);
2493 bool Failed = SubstituteParameterMappings(*this).substitute(*Normalized);
2495 NormalizationCache.try_emplace(ConstrainedDeclOrNestedReq, Normalized)
2500 return CacheEntry->second;
2523 if (It != BPacks.end())
2535 if (
const auto *FD1 = dyn_cast<FunctionDecl>(D1)) {
2541 const auto *FD2 = dyn_cast<FunctionDecl>(D2);
2542 assert(IsExpectedEntity(FD1) && FD2 && IsExpectedEntity(FD2) &&
2543 "use non-instantiated function declaration for constraints partial "
2558 std::pair<const NamedDecl *, const NamedDecl *> Key{D1, D2};
2559 auto CacheEntry = SubsumptionCache.find(Key);
2560 if (CacheEntry != SubsumptionCache.end()) {
2561 Result = CacheEntry->second;
2568 for (
size_t I = 0; I != AC1.size() && I != AC2.size(); ++I) {
2569 if (Depth2 > Depth1) {
2570 AC1[I].ConstraintExpr =
2571 AdjustConstraints(*
this, Depth2 - Depth1)
2572 .TransformExpr(
const_cast<Expr *
>(AC1[I].ConstraintExpr))
2574 }
else if (Depth1 > Depth2) {
2575 AC2[I].ConstraintExpr =
2576 AdjustConstraints(*
this, Depth1 - Depth2)
2577 .TransformExpr(
const_cast<Expr *
>(AC2[I].ConstraintExpr))
2586 const NamedDecl *DeclAC1 = D1, *DeclAC2 = D2;
2587 if (Depth2 > Depth1)
2589 else if (Depth1 > Depth2)
2591 std::optional<bool> Subsumes = SC.
Subsumes(DeclAC1, AC1, DeclAC2, AC2);
2597 SubsumptionCache.try_emplace(Key, *Subsumes);
2608 if (AC1.empty() || AC2.empty())
2611 const Expr *AmbiguousAtomic1 =
nullptr, *AmbiguousAtomic2 =
nullptr;
2622 llvm::FoldingSetNodeID IDA, IDB;
2624 EB->Profile(IDB,
Context,
true);
2628 AmbiguousAtomic1 = EA;
2629 AmbiguousAtomic2 = EB;
2644 bool Is1AtLeastAs2Normally = SC.
Subsumes(Normalized1, Normalized2);
2645 bool Is2AtLeastAs1Normally = SC.
Subsumes(Normalized2, Normalized1);
2648 bool Is1AtLeastAs2 = SC2.
Subsumes(Normalized1, Normalized2);
2649 bool Is2AtLeastAs1 = SC2.
Subsumes(Normalized2, Normalized1);
2651 if (Is1AtLeastAs2 == Is1AtLeastAs2Normally &&
2652 Is2AtLeastAs1 == Is2AtLeastAs1Normally)
2657 assert(AmbiguousAtomic1 && AmbiguousAtomic2);
2659 Diag(AmbiguousAtomic1->
getBeginLoc(), diag::note_ambiguous_atomic_constraints)
2661 Diag(AmbiguousAtomic2->getBeginLoc(),
2662 diag::note_ambiguous_atomic_constraints_similar_expression)
2663 << AmbiguousAtomic2->getSourceRange();
2674 : SemaRef(SemaRef), Callable(Callable), NextID(1) {}
2676uint16_t SubsumptionChecker::getNewLiteralId() {
2677 assert((
unsigned(NextID) + 1 < std::numeric_limits<uint16_t>::max()) &&
2678 "too many constraints!");
2683 auto &Elems = AtomicMap[Ori->getConstraintExpr()];
2698 llvm::FoldingSetNodeID ID;
2699 ID.AddBoolean(Ori->hasParameterMapping());
2700 if (Ori->hasParameterMapping()) {
2701 const auto &Mapping = Ori->getParameterMapping();
2703 Ori->mappingOccurenceListForSubsumption();
2704 for (
auto [Idx, TAL] : llvm::enumerate(Mapping)) {
2711 auto It = Elems.find(ID);
2712 if (It == Elems.end()) {
2715 MappedAtomicConstraint{
2716 Ori, {getNewLiteralId(), Literal::Atomic}}})
2718 ReverseMap[It->second.ID.Value] = Ori;
2720 return It->getSecond().ID;
2724 auto &Elems = FoldMap[Ori->getPattern()];
2726 FoldExpendedConstraintKey K;
2727 K.Kind = Ori->getFoldOperator();
2729 auto It = llvm::find_if(Elems, [&K](
const FoldExpendedConstraintKey &
Other) {
2730 return K.Kind ==
Other.Kind;
2732 if (It == Elems.end()) {
2733 K.ID = {getNewLiteralId(), Literal::FoldExpanded};
2734 It = Elems.insert(Elems.end(), std::move(K));
2735 ReverseMap[It->ID.Value] = Ori;
2741 return SubsumptionChecker::Normalize<CNFFormula>(
C);
2744 return SubsumptionChecker::Normalize<DNFFormula>(
C);
2760template <
typename FormulaType>
2764 auto Add = [&,
this](Clause
C) {
2767 C.erase(llvm::unique(
C),
C.end());
2768 AddUniqueClauseToFormula(Res, std::move(
C));
2773 return {{find(&
static_cast<const AtomicConstraint &
>(NC))}};
2776 return {{find(&
static_cast<const FoldExpandedConstraint &
>(NC))}};
2779 return Normalize<FormulaType>(
2780 static_cast<const ConceptIdConstraint &
>(NC).getNormalizedConstraint());
2783 const auto &Compound =
static_cast<const CompoundConstraint &
>(NC);
2785 SemaRef.runWithSufficientStackSpace(SourceLocation(), [&] {
2786 Left = Normalize<FormulaType>(Compound.getLHS());
2787 Right = Normalize<FormulaType>(Compound.getRHS());
2790 if (Compound.getCompoundKind() == FormulaType::Kind) {
2791 unsigned SizeLeft =
Left.size();
2792 Res = std::move(Left);
2793 Res.reserve(SizeLeft +
Right.size());
2794 std::for_each(std::make_move_iterator(
Right.begin()),
2795 std::make_move_iterator(
Right.end()), Add);
2799 Res.reserve(
Left.size() *
Right.size());
2800 for (
const auto <ransform : Left) {
2801 for (
const auto &RTransform : Right) {
2803 Combined.reserve(LTransform.size() + RTransform.size());
2804 llvm::copy(LTransform, std::back_inserter(Combined));
2805 llvm::copy(RTransform, std::back_inserter(Combined));
2806 Add(std::move(Combined));
2812 llvm_unreachable(
"Unknown ConstraintKind enum");
2815void SubsumptionChecker::AddUniqueClauseToFormula(Formula &F, Clause
C) {
2816 for (
auto &
Other : F) {
2817 if (llvm::equal(
C,
Other))
2827 SemaRef.getNormalizedAssociatedConstraints(DP, P);
2829 return std::nullopt;
2832 SemaRef.getNormalizedAssociatedConstraints(DQ, Q);
2834 return std::nullopt;
2836 return Subsumes(PNormalized, QNormalized);
2842 DNFFormula DNFP = DNF(*P);
2843 CNFFormula CNFQ = CNF(*Q);
2848 const CNFFormula &QCNF) {
2849 for (
const auto &Pi : PDNF) {
2850 for (
const auto &Qj : QCNF) {
2856 if (!DNFSubsumes(Pi, Qj))
2863bool SubsumptionChecker::DNFSubsumes(
const Clause &P,
const Clause &Q) {
2865 return llvm::any_of(P, [&](Literal LP) {
2866 return llvm::any_of(Q, [
this, LP](Literal LQ) {
return Subsumes(LP, LQ); });
2872 std::pair<const FoldExpandedConstraint *, const FoldExpandedConstraint *> Key{
2875 auto It = FoldSubsumptionCache.find(Key);
2876 if (It == FoldSubsumptionCache.end()) {
2885 It = FoldSubsumptionCache.try_emplace(std::move(Key), DoesSubsume).first;
2891 if (A.Kind != B.Kind)
2894 case Literal::Atomic:
2896 return A.Value == B.Value;
2898 *
static_cast<const AtomicConstraint *
>(ReverseMap[A.Value]),
2899 *
static_cast<const AtomicConstraint *
>(ReverseMap[B.Value]));
2900 case Literal::FoldExpanded:
2902 static_cast<const FoldExpandedConstraint *
>(ReverseMap[A.Value]),
2903 static_cast<const FoldExpandedConstraint *
>(ReverseMap[B.Value]));
2905 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)
static bool PreparePackForExpansion(Sema &S, const CXXBaseSpecifier &Base, const MultiLevelTemplateArgumentList &TemplateArgs, TypeSourceInfo *&Out, UnexpandedInfo &Info)
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)
static ImplicitConceptSpecializationDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation SL, ArrayRef< TemplateArgument > ConvertedArgs)
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.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
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.
bool SubstTemplateArgumentsInParameterMapping(ArrayRef< TemplateArgumentLoc > Args, SourceLocation BaseLoc, const MultiLevelTemplateArgumentList &TemplateArgs, TemplateArgumentListInfo &Out)
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)
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.
@ 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