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) {
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 TraverseTagType(
const TagType *
T,
bool TraverseQualifier) {
397 bool TraverseInjectedClassNameType(InjectedClassNameType *
T,
398 bool TraverseQualifier) {
399 return TraverseTemplateArguments(
T->getTemplateArgs(SemaRef.
Context));
402 bool TraverseTemplateArgument(
const TemplateArgument &Arg) {
405 Sema::ArgPackSubstIndexRAII _1(SemaRef, std::nullopt);
406 llvm::SaveAndRestore<UnsignedOrNone>
_2(OuterPackSubstIndex,
408 return inherited::TraverseTemplateArgument(Arg);
411 Sema::ArgPackSubstIndexRAII _1(SemaRef, OuterPackSubstIndex);
412 return inherited::TraverseTemplateArgument(Arg);
415 bool TraverseSizeOfPackExpr(SizeOfPackExpr *SOPE) {
416 return TraverseDecl(SOPE->
getPack());
419 bool VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *E) {
424 if (
auto *TTP = dyn_cast_if_present<TemplateTemplateParmDecl>(
431 TemplateArgument Arg = TemplateArgs(TTP->getDepth(), TTP->getPosition());
434 "Missing argument pack");
438 "Null template template argument");
439 UsedTemplateArgs.push_back(
442 return inherited::TraverseTemplateName(
Template);
445 void VisitConstraint(
const NormalizedConstraintWithParamMapping &Constraint) {
447 for (
const auto &List : TemplateArgs)
448 for (
const TemplateArgument &Arg : List.Args)
454 llvm::ArrayRef<TemplateArgumentLoc> Mapping =
456 for (
auto &ArgLoc : Mapping) {
457 TemplateArgument Canonical =
460 UsedTemplateArgs.push_back(Canonical);
461 TraverseTemplateArgument(Canonical);
464 for (
auto &
Used : UsedTemplateArgs) {
465 llvm::FoldingSetNodeID R;
472class ConstraintSatisfactionChecker {
475 SourceLocation TemplateNameLoc;
476 UnsignedOrNone PackSubstitutionIndex;
477 ConstraintSatisfaction &Satisfaction;
478 bool BuildExpression;
482 EvaluateAtomicConstraint(
const Expr *AtomicExpr,
483 const MultiLevelTemplateArgumentList &MLTAL);
485 UnsignedOrNone EvaluateFoldExpandedConstraintSize(
486 const FoldExpandedConstraint &FE,
487 const MultiLevelTemplateArgumentList &MLTAL);
490 std::optional<MultiLevelTemplateArgumentList> SubstitutionInTemplateArguments(
491 const NormalizedConstraintWithParamMapping &Constraint,
492 const MultiLevelTemplateArgumentList &MLTAL,
493 llvm::SmallVector<TemplateArgument> &SubstitutedOuterMost);
495 ExprResult EvaluateSlow(
const AtomicConstraint &Constraint,
496 const MultiLevelTemplateArgumentList &MLTAL);
499 const MultiLevelTemplateArgumentList &MLTAL);
501 ExprResult EvaluateSlow(
const FoldExpandedConstraint &Constraint,
502 const MultiLevelTemplateArgumentList &MLTAL);
505 const MultiLevelTemplateArgumentList &MLTAL);
507 ExprResult EvaluateSlow(
const ConceptIdConstraint &Constraint,
508 const MultiLevelTemplateArgumentList &MLTAL,
512 const MultiLevelTemplateArgumentList &MLTAL);
515 const MultiLevelTemplateArgumentList &MLTAL);
518 ConstraintSatisfactionChecker(Sema &SemaRef,
const NamedDecl *
Template,
519 SourceLocation TemplateNameLoc,
520 UnsignedOrNone PackSubstitutionIndex,
521 ConstraintSatisfaction &Satisfaction,
522 bool BuildExpression)
524 PackSubstitutionIndex(PackSubstitutionIndex),
525 Satisfaction(Satisfaction), BuildExpression(BuildExpression) {}
528 const MultiLevelTemplateArgumentList &MLTAL);
531StringRef allocateStringFromConceptDiagnostic(
const Sema &S,
541ExprResult ConstraintSatisfactionChecker::EvaluateAtomicConstraint(
543 llvm::FoldingSetNodeID
ID;
546 Satisfaction.IsSatisfied =
false;
547 Satisfaction.ContainsErrors =
true;
550 SatisfactionStackRAII StackRAII(S,
Template, ID);
561 if (Inst.isInvalid())
566 SubstitutedExpression =
569 if (SubstitutedExpression.
isInvalid() || Trap.hasErrorOccurred()) {
573 if (!Trap.hasErrorOccurred())
580 Info.takeSFINAEDiagnostic(SubstDiag);
587 Satisfaction.Details.emplace_back(
590 allocateStringFromConceptDiagnostic(S, SubstDiag.second)});
591 Satisfaction.IsSatisfied =
false;
612 SubstitutedExpression.
get(),
615 return SubstitutedExpression;
618std::optional<MultiLevelTemplateArgumentList>
619ConstraintSatisfactionChecker::SubstitutionInTemplateArguments(
625 return std::move(MLTAL);
639 if (Inst.isInvalid())
646 : PackSubstitutionIndex);
651 Satisfaction.IsSatisfied =
false;
659 TD->getLocation(), SubstArgs,
668 SubstitutedOutermost =
669 llvm::to_vector_of<TemplateArgument>(MLTAL.
getOutermost());
671 for (
unsigned I = 0, MappedIndex = 0; I <
Used.size(); I++) {
676 if (I < SubstitutedOutermost.size()) {
677 SubstitutedOutermost[I] = Arg;
680 SubstitutedOutermost.push_back(Arg);
681 Offset = SubstitutedOutermost.size();
684 if (Offset < SubstitutedOutermost.size())
685 SubstitutedOutermost.erase(SubstitutedOutermost.begin() + Offset);
690 return std::move(SubstitutedTemplateArgs);
693ExprResult ConstraintSatisfactionChecker::EvaluateSlow(
701 std::optional<MultiLevelTemplateArgumentList> SubstitutedArgs =
702 SubstitutionInTemplateArguments(Constraint, MLTAL, SubstitutedOutermost);
703 if (!SubstitutedArgs) {
704 Satisfaction.IsSatisfied =
false;
709 ExprResult SubstitutedAtomicExpr = EvaluateAtomicConstraint(
715 if (SubstitutedAtomicExpr.
isUnset())
725 Satisfaction.IsSatisfied =
false;
726 Satisfaction.ContainsErrors =
true;
729 Satisfaction.Details.emplace_back(
731 SubstitutedAtomicExpr.get()->getBeginLoc(),
732 allocateStringFromConceptDiagnostic(S, Msg)});
733 return SubstitutedAtomicExpr;
737 Satisfaction.IsSatisfied =
true;
738 Satisfaction.ContainsErrors =
false;
739 return SubstitutedAtomicExpr;
744 EvalResult.
Diag = &EvaluationDiags;
747 !EvaluationDiags.empty()) {
751 diag::err_non_constant_constraint_expression)
754 S.
Diag(PDiag.first, PDiag.second);
759 "evaluating bool expression didn't produce int");
760 Satisfaction.IsSatisfied = EvalResult.
Val.
getInt().getBoolValue();
761 if (!Satisfaction.IsSatisfied)
762 Satisfaction.Details.emplace_back(SubstitutedAtomicExpr.
get());
764 return SubstitutedAtomicExpr;
767ExprResult ConstraintSatisfactionChecker::Evaluate(
771 unsigned Size = Satisfaction.Details.size();
772 llvm::FoldingSetNodeID
ID;
776 : PackSubstitutionIndex;
780 HashParameterMapping(S, MLTAL, ID, OuterPackSubstIndex)
781 .VisitConstraint(Constraint);
785 auto &Cached = Iter->second.Satisfaction;
786 Satisfaction.ContainsErrors = Cached.ContainsErrors;
787 Satisfaction.IsSatisfied = Cached.IsSatisfied;
788 Satisfaction.Details.insert(Satisfaction.Details.begin() + Size,
789 Cached.Details.begin(), Cached.Details.end());
790 return Iter->second.SubstExpr;
793 ExprResult E = EvaluateSlow(Constraint, MLTAL);
796 Cache.Satisfaction.ContainsErrors = Satisfaction.ContainsErrors;
797 Cache.Satisfaction.IsSatisfied = Satisfaction.IsSatisfied;
798 Cache.Satisfaction.Details.insert(
Cache.Satisfaction.Details.end(),
799 Satisfaction.Details.begin() + Size,
800 Satisfaction.Details.end());
808ConstraintSatisfactionChecker::EvaluateFoldExpandedConstraintSize(
816 assert(!Unexpanded.empty() &&
"Pack expansion without parameter packs?");
818 bool RetainExpansion =
false;
822 false, Expand, RetainExpansion,
823 NumExpansions,
false) ||
824 !Expand || RetainExpansion)
827 if (NumExpansions && S.
getLangOpts().BracketDepth < *NumExpansions)
829 return NumExpansions;
832ExprResult ConstraintSatisfactionChecker::EvaluateSlow(
838 unsigned EffectiveDetailEndIndex = Satisfaction.Details.size();
843 std::optional<MultiLevelTemplateArgumentList> SubstitutedArgs =
844 SubstitutionInTemplateArguments(
846 MLTAL, SubstitutedOutermost);
847 if (!SubstitutedArgs) {
848 Satisfaction.IsSatisfied =
false;
854 EvaluateFoldExpandedConstraintSize(Constraint, *SubstitutedArgs);
858 if (*NumExpansions == 0) {
859 Satisfaction.IsSatisfied = Conjunction;
863 for (
unsigned I = 0; I < *NumExpansions; I++) {
865 Satisfaction.IsSatisfied =
false;
866 Satisfaction.ContainsErrors =
false;
868 ConstraintSatisfactionChecker(S,
Template, TemplateNameLoc,
872 if (BuildExpression &&
Expr.isUsable()) {
877 Conjunction ? BinaryOperatorKind::BO_LAnd
878 : BinaryOperatorKind::BO_LOr,
883 assert(!BuildExpression || !Satisfaction.IsSatisfied);
885 if (!Conjunction && Satisfaction.IsSatisfied) {
886 Satisfaction.Details.erase(Satisfaction.Details.begin() +
887 EffectiveDetailEndIndex,
888 Satisfaction.Details.end());
891 if (Satisfaction.IsSatisfied != Conjunction)
898ExprResult ConstraintSatisfactionChecker::Evaluate(
902 llvm::FoldingSetNodeID
ID;
904 HashParameterMapping(S, MLTAL, ID, std::nullopt).VisitConstraint(Constraint);
909 auto &Cached = Iter->second.Satisfaction;
910 Satisfaction.ContainsErrors = Cached.ContainsErrors;
911 Satisfaction.IsSatisfied = Cached.IsSatisfied;
912 Satisfaction.Details.insert(Satisfaction.Details.end(),
913 Cached.Details.begin(), Cached.Details.end());
914 return Iter->second.SubstExpr;
917 unsigned Size = Satisfaction.Details.size();
919 ExprResult E = EvaluateSlow(Constraint, MLTAL);
921 Cache.Satisfaction.ContainsErrors = Satisfaction.ContainsErrors;
922 Cache.Satisfaction.IsSatisfied = Satisfaction.IsSatisfied;
923 Cache.Satisfaction.Details.insert(
Cache.Satisfaction.Details.end(),
924 Satisfaction.Details.begin() + Size,
925 Satisfaction.Details.end());
931ExprResult ConstraintSatisfactionChecker::EvaluateSlow(
937 std::optional<MultiLevelTemplateArgumentList> SubstitutedArgs =
938 SubstitutionInTemplateArguments(Constraint, MLTAL, SubstitutedOutermost);
940 if (!SubstitutedArgs) {
941 Satisfaction.IsSatisfied =
false;
949 : PackSubstitutionIndex);
961 Trap.hasErrorOccurred()) {
962 Satisfaction.IsSatisfied =
false;
963 if (!Trap.hasErrorOccurred())
968 Info.takeSFINAEDiagnostic(SubstDiag);
975 Satisfaction.Details.insert(
976 Satisfaction.Details.begin() + Size,
979 allocateStringFromConceptDiagnostic(S, SubstDiag.second)});
991 if (SubstitutedConceptId.
isInvalid() || Trap.hasErrorOccurred())
994 if (Size != Satisfaction.Details.size()) {
995 Satisfaction.Details.insert(
996 Satisfaction.Details.begin() + Size,
1001 return SubstitutedConceptId;
1004ExprResult ConstraintSatisfactionChecker::Evaluate(
1013 : PackSubstitutionIndex;
1027 if (InstTemplate.isInvalid())
1030 unsigned Size = Satisfaction.Details.size();
1035 Satisfaction.Details.insert(Satisfaction.Details.begin() + Size, ConceptId);
1042 if (Satisfaction.IsSatisfied)
1045 llvm::FoldingSetNodeID
ID;
1048 HashParameterMapping(S, MLTAL, ID, OuterPackSubstIndex)
1049 .VisitConstraint(Constraint);
1054 auto &Cached = Iter->second.Satisfaction;
1055 Satisfaction.ContainsErrors = Cached.ContainsErrors;
1056 Satisfaction.IsSatisfied = Cached.IsSatisfied;
1057 Satisfaction.Details.insert(Satisfaction.Details.begin() + Size,
1058 Cached.Details.begin(), Cached.Details.end());
1059 return Iter->second.SubstExpr;
1062 ExprResult CE = EvaluateSlow(Constraint, MLTAL, Size);
1066 Cache.Satisfaction.ContainsErrors = Satisfaction.ContainsErrors;
1067 Cache.Satisfaction.IsSatisfied = Satisfaction.IsSatisfied;
1068 Cache.Satisfaction.Details.insert(
Cache.Satisfaction.Details.end(),
1069 Satisfaction.Details.begin() + Size,
1070 Satisfaction.Details.end());
1071 Cache.SubstExpr = CE;
1076ExprResult ConstraintSatisfactionChecker::Evaluate(
1080 unsigned EffectiveDetailEndIndex = Satisfaction.Details.size();
1087 if (Conjunction && (!Satisfaction.IsSatisfied || Satisfaction.ContainsErrors))
1090 if (!Conjunction && !LHS.
isInvalid() && Satisfaction.IsSatisfied &&
1091 !Satisfaction.ContainsErrors)
1094 Satisfaction.ContainsErrors =
false;
1095 Satisfaction.IsSatisfied =
false;
1099 if (!Conjunction && !RHS.
isInvalid() && Satisfaction.IsSatisfied &&
1100 !Satisfaction.ContainsErrors)
1101 Satisfaction.Details.erase(Satisfaction.Details.begin() +
1102 EffectiveDetailEndIndex,
1103 Satisfaction.Details.end());
1105 if (!BuildExpression)
1115 Conjunction ? BinaryOperatorKind::BO_LAnd
1116 : BinaryOperatorKind::BO_LOr,
1121ExprResult ConstraintSatisfactionChecker::Evaluate(
1124 switch (Constraint.
getKind()) {
1139 llvm_unreachable(
"Unknown ConstraintKind enum");
1150 *ConvertedExpr =
nullptr;
1152 if (AssociatedConstraints.empty()) {
1167 struct SynthesisContextPair {
1173 : Inst(S, InstantiationRange.
getBegin(),
1175 TemplateArgs, InstantiationRange),
1178 std::optional<SynthesisContextPair> SynthesisContext;
1179 if (!TopLevelConceptId)
1190 if (TopLevelConceptId)
1196 ExprResult Res = ConstraintSatisfactionChecker(
1199 ConvertedExpr !=
nullptr)
1200 .Evaluate(*
C, TemplateArgsLists);
1205 if (Res.
isUsable() && ConvertedExpr)
1206 *ConvertedExpr = Res.
get();
1217 llvm::TimeTraceScope TimeScope(
1218 "CheckConstraintSatisfaction", [TemplateIDRange,
this] {
1221 if (AssociatedConstraints.empty()) {
1227 return ::CheckConstraintSatisfaction(
1228 *
this,
nullptr, AssociatedConstraints, TemplateArgsLists,
1229 TemplateIDRange, OutSatisfaction, ConvertedExpr, TopLevelConceptId);
1243 for (
auto List : TemplateArgsLists)
1245 FlattenedArgs.emplace_back(
Context.getCanonicalTemplateArgument(Arg));
1248 if (TopLevelConceptId)
1251 llvm::FoldingSetNodeID ID;
1254 if (
auto *Cached = SatisfactionCache.FindNodeOrInsertPos(ID, InsertPos)) {
1255 OutSatisfaction = *Cached;
1260 std::make_unique<ConstraintSatisfaction>(Owner, FlattenedArgs);
1262 *
this,
Template, AssociatedConstraints, TemplateArgsLists,
1263 TemplateIDRange, *Satisfaction, ConvertedExpr, TopLevelConceptId)) {
1264 OutSatisfaction = std::move(*Satisfaction);
1268 if (
auto *Cached = SatisfactionCache.FindNodeOrInsertPos(ID, InsertPos)) {
1277 OutSatisfaction = *Cached;
1282 OutSatisfaction = *Satisfaction;
1286 SatisfactionCache.InsertNode(Satisfaction.release());
1308 return !ArgLoc.getArgument().isDependent() &&
1309 ArgLoc.getArgument().isConceptOrConceptTemplateParameter();
1311 return Concept->getConstraintExpr();
1324bool Sema::SetupConstraintScope(
1329 "Use LambdaScopeForCallOperatorInstantiationRAII to handle lambda "
1335 Sema::InstantiatingTemplate::ConstraintsCheck{}, PrimaryTemplate,
1336 TemplateArgs ? *TemplateArgs : ArrayRef<TemplateArgument>{},
1338 if (Inst.isInvalid())
1347 MultiLevelTemplateArgumentList JustTemplArgs(FD, SpecArgs->asArray(),
1349 if (addInstantiatedParametersToScope(
1356 if (FunctionTemplateDecl *FromMemTempl =
1358 if (addInstantiatedParametersToScope(FD, FromMemTempl->getTemplatedDecl(),
1368 FunctionDecl *InstantiatedFrom =
1375 Sema::InstantiatingTemplate::ConstraintsCheck{}, InstantiatedFrom,
1376 TemplateArgs ? *TemplateArgs : ArrayRef<TemplateArgument>{},
1378 if (Inst.isInvalid())
1383 if (addInstantiatedParametersToScope(FD, InstantiatedFrom, Scope, MLTAL))
1392std::optional<MultiLevelTemplateArgumentList>
1393Sema::SetupConstraintCheckingTemplateArgumentsAndScope(
1396 MultiLevelTemplateArgumentList MLTAL;
1403 false, std::nullopt,
1410 if (SetupConstraintScope(FD, TemplateArgs, MLTAL, Scope))
1411 return std::nullopt;
1419 bool ForOverloadResolution) {
1438 if (
const auto *MD = dyn_cast<CXXConversionDecl>(FD);
1441 Satisfaction, UsageLoc,
1455 std::optional<MultiLevelTemplateArgumentList> MLTAL =
1456 SetupConstraintCheckingTemplateArgumentsAndScope(
1464 if (
auto *
Method = dyn_cast<CXXMethodDecl>(FD)) {
1465 ThisQuals =
Method->getMethodQualifiers();
1472 ForOverloadResolution);
1482 const Expr *ConstrExpr) {
1505 std::optional<LocalInstantiationScope> ScopeForParameters;
1508 ScopeForParameters.emplace(S,
true);
1512 FD =
Template->getInstantiatedFromMemberTemplate()->getTemplatedDecl();
1514 if (ScopeForParameters->getInstantiationOfIfExists(PVD))
1516 if (!PVD->isParameterPack()) {
1517 ScopeForParameters->InstantiatedLocal(PVD, PVD);
1536 ScopeForParameters->MakeInstantiatedLocalArgPack(PVD);
1537 ScopeForParameters->InstantiatedLocalPackArg(PVD, PVD);
1541 std::optional<Sema::CXXThisScopeRAII> ThisScope;
1550 std::optional<Sema::ContextRAII> ContextScope;
1558 if (
auto *RD = dyn_cast<CXXRecordDecl>(DC)) {
1570 return SubstConstr.
get();
1574 const Expr *OldConstr,
1576 const Expr *NewConstr) {
1577 if (OldConstr == NewConstr)
1580 if (Old && !
New.isInvalid() && !
New.ContainsDecl(Old) &&
1582 if (
const Expr *SubstConstr =
1585 OldConstr = SubstConstr;
1588 if (
const Expr *SubstConstr =
1591 NewConstr = SubstConstr;
1596 llvm::FoldingSetNodeID ID1, ID2;
1609 "Non-function templates don't need to be checked");
1630 TemplateIDRange, Satisfaction))
1635 TemplateArgString =
" ";
1641 diag::err_template_arg_list_constraints_not_satisfied)
1643 << TemplateArgString << TemplateIDRange;
1655 Template->getAssociatedConstraints(TemplateAC);
1656 if (TemplateAC.empty()) {
1675 SemaRef, PointOfInstantiation,
1677 PointOfInstantiation);
1678 if (Inst.isInvalid())
1688 Template, TemplateAC, MLTAL, PointOfInstantiation, Satisfaction);
1699 return ::CheckFunctionConstraintsWithoutInstantiation(
1700 *
this, PointOfInstantiation,
Decl->getDescribedFunctionTemplate(),
1701 TemplateArgs, Satisfaction);
1706 Template->getAssociatedConstraints(TemplateAC);
1707 if (TemplateAC.empty()) {
1717 std::optional<MultiLevelTemplateArgumentList> MLTAL =
1718 SetupConstraintCheckingTemplateArgumentsAndScope(
Decl, TemplateArgs,
1726 if (
auto *
Method = dyn_cast<CXXMethodDecl>(
Decl)) {
1727 ThisQuals =
Method->getMethodQualifiers();
1736 PointOfInstantiation, Satisfaction);
1743 "Diagnose() can only be used on an unsatisfied requirement");
1746 llvm_unreachable(
"Diagnosing a dependent requirement");
1750 if (!SubstDiag->DiagMessage.empty())
1751 S.
Diag(SubstDiag->DiagLoc,
1752 diag::note_expr_requirement_expr_substitution_error)
1753 << (
int)
First << SubstDiag->SubstitutedEntity
1754 << SubstDiag->DiagMessage;
1756 S.
Diag(SubstDiag->DiagLoc,
1757 diag::note_expr_requirement_expr_unknown_substitution_error)
1758 << (
int)
First << SubstDiag->SubstitutedEntity;
1768 if (!SubstDiag->DiagMessage.empty())
1769 S.
Diag(SubstDiag->DiagLoc,
1770 diag::note_expr_requirement_type_requirement_substitution_error)
1771 << (
int)
First << SubstDiag->SubstitutedEntity
1772 << SubstDiag->DiagMessage;
1777 note_expr_requirement_type_requirement_unknown_substitution_error)
1778 << (
int)
First << SubstDiag->SubstitutedEntity;
1788 llvm_unreachable(
"We checked this above");
1796 "Diagnose() can only be used on an unsatisfied requirement");
1799 llvm_unreachable(
"Diagnosing a dependent requirement");
1803 if (!SubstDiag->DiagMessage.empty())
1804 S.
Diag(SubstDiag->DiagLoc, diag::note_type_requirement_substitution_error)
1805 << (
int)
First << SubstDiag->SubstitutedEntity
1806 << SubstDiag->DiagMessage;
1808 S.
Diag(SubstDiag->DiagLoc,
1809 diag::note_type_requirement_unknown_substitution_error)
1810 << (
int)
First << SubstDiag->SubstitutedEntity;
1814 llvm_unreachable(
"Unknown satisfaction status");
1822 if (
Concept->getTemplateArgsAsWritten()->NumTemplateArgs == 1) {
1826 note_single_arg_concept_specialization_constraint_evaluated_to_false)
1828 <<
Concept->getTemplateArgsAsWritten()->arguments()[0].getArgument()
1829 <<
Concept->getNamedConcept();
1831 S.
Diag(Loc, diag::note_concept_specialization_constraint_evaluated_to_false)
1861 const Expr *SubstExpr,
1864 if (
const BinaryOperator *BO = dyn_cast<BinaryOperator>(SubstExpr)) {
1865 switch (BO->getOpcode()) {
1877 BO->getLHS()->EvaluateKnownConstInt(S.
Context).getBoolValue();
1888 BO->getRHS()->EvaluateKnownConstInt(S.
Context).getBoolValue();
1900 if (BO->getLHS()->getType()->isIntegerType() &&
1901 BO->getRHS()->getType()->isIntegerType()) {
1904 BO->getLHS()->EvaluateAsInt(SimplifiedLHS, S.
Context,
1907 BO->getRHS()->EvaluateAsInt(SimplifiedRHS, S.
Context,
1910 if (!SimplifiedLHS.
Diag && !SimplifiedRHS.
Diag) {
1912 diag::note_atomic_constraint_evaluated_to_false_elaborated)
1925 }
else if (
auto *RE = dyn_cast<RequiresExpr>(SubstExpr)) {
1928 if (!Req->isDependent() && !Req->isSatisfied()) {
1929 if (
auto *E = dyn_cast<concepts::ExprRequirement>(Req))
1931 else if (
auto *
T = dyn_cast<concepts::TypeRequirement>(Req))
1939 }
else if (
auto *CSE = dyn_cast<ConceptSpecializationExpr>(SubstExpr)) {
1943 }
else if (
auto *TTE = dyn_cast<TypeTraitExpr>(SubstExpr);
1944 TTE && TTE->getTrait() == clang::TypeTrait::BTT_IsDeducible) {
1945 assert(TTE->getNumArgs() == 2);
1947 diag::note_is_deducible_constraint_evaluated_to_false)
1948 << TTE->getArg(0)->getType() << TTE->getArg(1)->getType();
1953 diag::note_atomic_constraint_evaluated_to_false)
1963 .
template dyn_cast<const ConstraintSubstitutionDiagnostic *>()) {
1965 S.
Diag(
Diag->first, diag::note_nested_requirement_substitution_error)
1968 S.
Diag(
Diag->first, diag::note_substituted_constraint_expr_is_ill_formed)
1972 if (
const auto *
Concept = dyn_cast<const ConceptReference *>(
Record)) {
1987 "Attempted to diagnose a satisfied constraint");
1998 "Attempted to diagnose a satisfied constraint");
2006class SubstituteParameterMappings {
2018 bool RemovePacksForFoldExpr;
2020 SubstituteParameterMappings(
Sema &SemaRef,
2023 bool RemovePacksForFoldExpr)
2024 : SemaRef(SemaRef), MLTAL(MLTAL), ArgsAsWritten(ArgsAsWritten),
2025 RemovePacksForFoldExpr(RemovePacksForFoldExpr) {}
2034 SubstituteParameterMappings(
Sema &SemaRef,
2035 bool RemovePacksForFoldExpr =
false)
2037 RemovePacksForFoldExpr(RemovePacksForFoldExpr) {}
2039 bool substitute(NormalizedConstraint &N);
2042void SubstituteParameterMappings::buildParameterMapping(
2047 llvm::SmallBitVector OccurringIndices(TemplateParams->
size());
2048 llvm::SmallBitVector OccurringIndicesForSubsumption(TemplateParams->
size());
2054 0, OccurringIndices);
2058 0, OccurringIndicesForSubsumption);
2065 0, OccurringIndices);
2069 ->getTemplateArgsAsWritten();
2072 0, OccurringIndices);
2074 unsigned Size = OccurringIndices.count();
2082 for (
unsigned I = 0, J = 0,
C = TemplateParams->
size(); I !=
C; ++I) {
2084 ? ArgsAsWritten->arguments()[I].getLocation()
2088 if (OccurringIndices[I]) {
2092 UsedParams.push_back(Param);
2102 std::move(OccurringIndices), std::move(OccurringIndicesForSubsumption),
2106bool SubstituteParameterMappings::substitute(
2109 buildParameterMapping(N);
2118 InstLocBegin = ArgsAsWritten->getLAngleLoc();
2119 InstLocEnd = ArgsAsWritten->getRAngleLoc();
2121 auto SR =
Arguments[0].getSourceRange();
2122 InstLocBegin = SR.getBegin();
2123 InstLocEnd = SR.getEnd();
2127 SemaRef, InstLocBegin,
2130 {InstLocBegin, InstLocEnd});
2131 if (Inst.isInvalid())
2146 TD->getLocation(), SubstArgs,
2157 if (I < SubstArgs.
size())
2158 Loc = SubstArgs.
arguments()[I].getLocation();
2185 InstLocBegin = ArgsAsWritten->getLAngleLoc();
2186 InstLocEnd = ArgsAsWritten->getRAngleLoc();
2188 auto SR =
Arguments[0].getSourceRange();
2189 InstLocBegin = SR.getBegin();
2190 InstLocEnd = SR.getEnd();
2195 SemaRef, InstLocBegin,
2198 {InstLocBegin, InstLocEnd});
2199 if (Inst.isInvalid())
2208 CSE->getTemplateArgsAsWritten();
2214 CSE->getConceptNameInfo().getLoc(), Out,
2219 auto TemplateArgs = *MLTAL;
2222 return SubstituteParameterMappings(SemaRef, &TemplateArgs, ArgsAsWritten,
2223 RemovePacksForFoldExpr)
2231 assert(!ArgsAsWritten);
2240 assert(!ArgsAsWritten);
2245 return SubstituteParameterMappings(SemaRef,
true)
2251 assert(ArgsAsWritten);
2252 return substitute(CC);
2254 assert(!ArgsAsWritten);
2258 if (RemovePacksForFoldExpr) {
2262 if (AdjustConstraints(SemaRef, 0,
2264 .TransformTemplateArguments(InputArgLoc.begin(),
2265 InputArgLoc.end(), OutArgs))
2285 return SubstituteParameterMappings(SemaRef, &MLTAL,
2287 RemovePacksForFoldExpr)
2292 if (substitute(Compound.getLHS()))
2294 return substitute(Compound.getRHS());
2297 llvm_unreachable(
"Unknown ConstraintKind enum");
2304 assert(ACs.size() != 0);
2306 fromConstraintExpr(S, D, ACs[0].ConstraintExpr, ACs[0].ArgPackSubstIndex);
2309 for (
unsigned I = 1; I < ACs.size(); ++I) {
2310 auto *
Next = fromConstraintExpr(S, D, ACs[I].ConstraintExpr,
2311 ACs[I].ArgPackSubstIndex);
2322 assert(E !=
nullptr);
2330 llvm::FoldingSetNodeID
ID;
2334 SatisfactionStackRAII StackRAII(S, D, ID);
2341 if (LogicalBinOp BO = E) {
2342 auto *LHS = fromConstraintExpr(S, D, BO.getLHS(), SubstIndex);
2345 auto *RHS = fromConstraintExpr(S, D, BO.getRHS(), SubstIndex);
2351 }
else if (
auto *CSE = dyn_cast<const ConceptSpecializationExpr>(E)) {
2354 Sema::NonSFINAEContext _(S);
2355 Sema::InstantiatingTemplate Inst(
2357 Sema::InstantiatingTemplate::ConstraintNormalization{},
2360 if (Inst.isInvalid())
2381 SubNF = NormalizedConstraint::fromAssociatedConstraints(
2382 S, CD, AssociatedConstraint(Res.
get(), SubstIndex));
2392 }
else if (
auto *FE = dyn_cast<const CXXFoldExpr>(E);
2394 (FE->getOperator() == BinaryOperatorKind::BO_LAnd ||
2395 FE->getOperator() == BinaryOperatorKind::BO_LOr)) {
2400 FE->getOperator() == BinaryOperatorKind::BO_LAnd
2404 if (FE->getInit()) {
2405 auto *LHS = fromConstraintExpr(S, D, FE->getLHS(), SubstIndex);
2406 auto *RHS = fromConstraintExpr(S, D, FE->getRHS(), SubstIndex);
2410 if (FE->isRightFold())
2423 auto *
Sub = fromConstraintExpr(S, D, FE->
getPattern(), SubstIndex);
2435 if (!ConstrainedDeclOrNestedReq) {
2436 auto *Normalized = NormalizedConstraint::fromAssociatedConstraints(
2437 *
this,
nullptr, AssociatedConstraints);
2439 SubstituteParameterMappings(*this).substitute(*Normalized))
2447 ConstrainedDeclOrNestedReq.dyn_cast<
const NamedDecl *>();
2448 auto CacheEntry = NormalizationCache.find(ConstrainedDeclOrNestedReq);
2449 if (CacheEntry == NormalizationCache.end()) {
2450 auto *Normalized = NormalizedConstraint::fromAssociatedConstraints(
2451 *
this, ND, AssociatedConstraints);
2453 NormalizationCache.try_emplace(ConstrainedDeclOrNestedReq,
nullptr);
2457 bool Failed = SubstituteParameterMappings(*this).substitute(*Normalized);
2459 NormalizationCache.try_emplace(ConstrainedDeclOrNestedReq, Normalized)
2464 return CacheEntry->second;
2487 if (It != BPacks.end())
2499 if (
const auto *FD1 = dyn_cast<FunctionDecl>(D1)) {
2505 const auto *FD2 = dyn_cast<FunctionDecl>(D2);
2506 assert(IsExpectedEntity(FD1) && FD2 && IsExpectedEntity(FD2) &&
2507 "use non-instantiated function declaration for constraints partial "
2522 std::pair<const NamedDecl *, const NamedDecl *> Key{D1, D2};
2523 auto CacheEntry = SubsumptionCache.find(Key);
2524 if (CacheEntry != SubsumptionCache.end()) {
2525 Result = CacheEntry->second;
2532 for (
size_t I = 0; I != AC1.size() && I != AC2.size(); ++I) {
2533 if (Depth2 > Depth1) {
2534 AC1[I].ConstraintExpr =
2535 AdjustConstraints(*
this, Depth2 - Depth1)
2536 .TransformExpr(
const_cast<Expr *
>(AC1[I].ConstraintExpr))
2538 }
else if (Depth1 > Depth2) {
2539 AC2[I].ConstraintExpr =
2540 AdjustConstraints(*
this, Depth1 - Depth2)
2541 .TransformExpr(
const_cast<Expr *
>(AC2[I].ConstraintExpr))
2547 std::optional<bool> Subsumes = SC.
Subsumes(D1, AC1, D2, AC2);
2553 SubsumptionCache.try_emplace(Key, *Subsumes);
2564 if (AC1.empty() || AC2.empty())
2567 const Expr *AmbiguousAtomic1 =
nullptr, *AmbiguousAtomic2 =
nullptr;
2578 llvm::FoldingSetNodeID IDA, IDB;
2580 EB->Profile(IDB,
Context,
true);
2584 AmbiguousAtomic1 = EA;
2585 AmbiguousAtomic2 = EB;
2600 bool Is1AtLeastAs2Normally = SC.
Subsumes(Normalized1, Normalized2);
2601 bool Is2AtLeastAs1Normally = SC.
Subsumes(Normalized2, Normalized1);
2604 bool Is1AtLeastAs2 = SC2.
Subsumes(Normalized1, Normalized2);
2605 bool Is2AtLeastAs1 = SC2.
Subsumes(Normalized2, Normalized1);
2607 if (Is1AtLeastAs2 == Is1AtLeastAs2Normally &&
2608 Is2AtLeastAs1 == Is2AtLeastAs1Normally)
2613 assert(AmbiguousAtomic1 && AmbiguousAtomic2);
2615 Diag(AmbiguousAtomic1->
getBeginLoc(), diag::note_ambiguous_atomic_constraints)
2617 Diag(AmbiguousAtomic2->getBeginLoc(),
2618 diag::note_ambiguous_atomic_constraints_similar_expression)
2619 << AmbiguousAtomic2->getSourceRange();
2630 : SemaRef(SemaRef), Callable(Callable), NextID(1) {}
2632uint16_t SubsumptionChecker::getNewLiteralId() {
2633 assert((
unsigned(NextID) + 1 < std::numeric_limits<uint16_t>::max()) &&
2634 "too many constraints!");
2639 auto &Elems = AtomicMap[Ori->getConstraintExpr()];
2654 llvm::FoldingSetNodeID ID;
2655 ID.AddBoolean(Ori->hasParameterMapping());
2656 if (Ori->hasParameterMapping()) {
2657 const auto &Mapping = Ori->getParameterMapping();
2659 Ori->mappingOccurenceListForSubsumption();
2660 for (
auto [Idx, TAL] : llvm::enumerate(Mapping)) {
2667 auto It = Elems.find(ID);
2668 if (It == Elems.end()) {
2671 MappedAtomicConstraint{
2672 Ori, {getNewLiteralId(), Literal::Atomic}}})
2674 ReverseMap[It->second.ID.Value] = Ori;
2676 return It->getSecond().ID;
2680 auto &Elems = FoldMap[Ori->getPattern()];
2682 FoldExpendedConstraintKey K;
2683 K.Kind = Ori->getFoldOperator();
2685 auto It = llvm::find_if(Elems, [&K](
const FoldExpendedConstraintKey &
Other) {
2686 return K.Kind ==
Other.Kind;
2688 if (It == Elems.end()) {
2689 K.ID = {getNewLiteralId(), Literal::FoldExpanded};
2690 It = Elems.insert(Elems.end(), std::move(K));
2691 ReverseMap[It->ID.Value] = Ori;
2697 return SubsumptionChecker::Normalize<CNFFormula>(
C);
2700 return SubsumptionChecker::Normalize<DNFFormula>(
C);
2716template <
typename FormulaType>
2720 auto Add = [&,
this](Clause
C) {
2723 C.erase(llvm::unique(
C),
C.end());
2724 AddUniqueClauseToFormula(Res, std::move(
C));
2729 return {{find(&
static_cast<const AtomicConstraint &
>(NC))}};
2732 return {{find(&
static_cast<const FoldExpandedConstraint &
>(NC))}};
2735 return Normalize<FormulaType>(
2736 static_cast<const ConceptIdConstraint &
>(NC).getNormalizedConstraint());
2739 const auto &Compound =
static_cast<const CompoundConstraint &
>(NC);
2741 SemaRef.runWithSufficientStackSpace(SourceLocation(), [&] {
2742 Left = Normalize<FormulaType>(Compound.getLHS());
2743 Right = Normalize<FormulaType>(Compound.getRHS());
2746 if (Compound.getCompoundKind() == FormulaType::Kind) {
2747 unsigned SizeLeft =
Left.size();
2748 Res = std::move(Left);
2749 Res.reserve(SizeLeft +
Right.size());
2750 std::for_each(std::make_move_iterator(
Right.begin()),
2751 std::make_move_iterator(
Right.end()), Add);
2755 Res.reserve(
Left.size() *
Right.size());
2756 for (
const auto <ransform : Left) {
2757 for (
const auto &RTransform : Right) {
2759 Combined.reserve(LTransform.size() + RTransform.size());
2760 llvm::copy(LTransform, std::back_inserter(Combined));
2761 llvm::copy(RTransform, std::back_inserter(Combined));
2762 Add(std::move(Combined));
2768 llvm_unreachable(
"Unknown ConstraintKind enum");
2771void SubsumptionChecker::AddUniqueClauseToFormula(Formula &F, Clause
C) {
2772 for (
auto &
Other : F) {
2773 if (llvm::equal(
C,
Other))
2783 SemaRef.getNormalizedAssociatedConstraints(DP, P);
2785 return std::nullopt;
2788 SemaRef.getNormalizedAssociatedConstraints(DQ, Q);
2790 return std::nullopt;
2792 return Subsumes(PNormalized, QNormalized);
2798 DNFFormula DNFP = DNF(*P);
2799 CNFFormula CNFQ = CNF(*Q);
2804 const CNFFormula &QCNF) {
2805 for (
const auto &Pi : PDNF) {
2806 for (
const auto &Qj : QCNF) {
2812 if (!DNFSubsumes(Pi, Qj))
2819bool SubsumptionChecker::DNFSubsumes(
const Clause &P,
const Clause &Q) {
2821 return llvm::any_of(P, [&](Literal LP) {
2822 return llvm::any_of(Q, [
this, LP](Literal LQ) {
return Subsumes(LP, LQ); });
2828 std::pair<const FoldExpandedConstraint *, const FoldExpandedConstraint *> Key{
2831 auto It = FoldSubsumptionCache.find(Key);
2832 if (It == FoldSubsumptionCache.end()) {
2841 It = FoldSubsumptionCache.try_emplace(std::move(Key), DoesSubsume).first;
2847 if (A.Kind != B.Kind)
2850 case Literal::Atomic:
2852 return A.Value == B.Value;
2854 *
static_cast<const AtomicConstraint *
>(ReverseMap[A.Value]),
2855 *
static_cast<const AtomicConstraint *
>(ReverseMap[B.Value]));
2856 case Literal::FoldExpanded:
2858 static_cast<const FoldExpandedConstraint *
>(ReverseMap[A.Value]),
2859 static_cast<const FoldExpandedConstraint *
>(ReverseMap[B.Value]));
2861 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)
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.
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.
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