30#include "llvm/ADT/DenseMap.h"
31#include "llvm/ADT/PointerUnion.h"
32#include "llvm/ADT/StringExtras.h"
33#include "llvm/Support/SaveAndRestore.h"
34#include "llvm/Support/ScopedPrinter.h"
35#include "llvm/Support/TimeProfiler.h"
44 const Expr *LHS =
nullptr;
45 const Expr *RHS =
nullptr;
48 LogicalBinOp(
const Expr *E) {
49 if (
auto *BO = dyn_cast<BinaryOperator>(E)) {
53 Loc = BO->getExprLoc();
54 }
else if (
auto *OO = dyn_cast<CXXOperatorCallExpr>(E)) {
56 if (OO->getNumArgs() == 2) {
57 Op = OO->getOperator();
60 Loc = OO->getOperatorLoc();
65 bool isAnd()
const {
return Op == OO_AmpAmp; }
66 bool isOr()
const {
return Op == OO_PipePipe; }
67 explicit operator bool()
const {
return isAnd() || isOr(); }
69 const Expr *getLHS()
const {
return LHS; }
70 const Expr *getRHS()
const {
return RHS; }
74 return recreateBinOp(SemaRef, LHS,
const_cast<Expr *
>(getRHS()));
79 assert((isAnd() || isOr()) &&
"Not the right kind of op?");
80 assert((!LHS.isInvalid() && !RHS.isInvalid()) &&
"not good expressions?");
82 if (!LHS.isUsable() || !RHS.isUsable())
96 Token NextToken,
bool *PossibleNonPrimary,
97 bool IsTrailingRequiresClause) {
103 if (LogicalBinOp BO = ConstraintExpression) {
105 PossibleNonPrimary) &&
108 }
else if (
auto *
C = dyn_cast<ExprWithCleanups>(ConstraintExpression))
114 auto CheckForNonPrimary = [&] {
115 if (!PossibleNonPrimary)
118 *PossibleNonPrimary =
129 (NextToken.
is(tok::l_paren) &&
130 (IsTrailingRequiresClause ||
148 CheckForNonPrimary();
154 diag::err_non_bool_atomic_constraint)
156 CheckForNonPrimary();
160 if (PossibleNonPrimary)
161 *PossibleNonPrimary =
false;
166struct SatisfactionStackRAII {
168 bool Inserted =
false;
170 const llvm::FoldingSetNodeID &FSNID)
177 ~SatisfactionStackRAII() {
189 for (
const auto &List : *MLTAL)
207 bool SkipForSpecialization =
false) {
213 true, SkipForSpecialization);
218class AdjustConstraints :
public TreeTransform<AdjustConstraints> {
219 unsigned TemplateDepth = 0;
221 bool RemoveNonPackExpansionPacks =
false;
224 using inherited = TreeTransform<AdjustConstraints>;
225 AdjustConstraints(Sema &SemaRef,
unsigned TemplateDepth,
226 bool RemoveNonPackExpansionPacks =
false)
227 : inherited(SemaRef), TemplateDepth(TemplateDepth),
228 RemoveNonPackExpansionPacks(RemoveNonPackExpansionPacks) {}
230 ExprResult RebuildPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc,
232 return inherited::RebuildPackExpansion(Pattern, EllipsisLoc, NumExpansions);
235 TemplateArgumentLoc RebuildPackExpansion(TemplateArgumentLoc Pattern,
236 SourceLocation EllipsisLoc,
238 if (!RemoveNonPackExpansionPacks)
239 return inherited::RebuildPackExpansion(Pattern, EllipsisLoc,
245 TemplateArgumentLoc &Out, UnexpandedInfo &Info) {
246 if (!RemoveNonPackExpansionPacks)
247 return inherited::PreparePackForExpansion(In, Uneval, Out, Info);
248 assert(
In.getArgument().isPackExpansion());
254 using inherited::TransformTemplateTypeParmType;
255 QualType TransformTemplateTypeParmType(TypeLocBuilder &TLB,
256 TemplateTypeParmTypeLoc TL,
bool) {
259 TemplateTypeParmDecl *NewTTPDecl =
nullptr;
260 if (TemplateTypeParmDecl *OldTTPDecl =
T->getDecl())
261 NewTTPDecl = cast_or_null<TemplateTypeParmDecl>(
264 QualType
Result = getSema().Context.getTemplateTypeParmType(
265 T->getDepth() + TemplateDepth,
T->getIndex(),
266 RemoveNonPackExpansionPacks ?
false :
T->isParameterPack(), NewTTPDecl);
267 TemplateTypeParmTypeLoc NewTL = TLB.
push<TemplateTypeParmTypeLoc>(
Result);
272 bool AlreadyTransformed(QualType
T) {
282 ExprResult TransformDeclRefExpr(DeclRefExpr *E) {
283 NonTypeTemplateParmDecl *NTTP =
284 dyn_cast<NonTypeTemplateParmDecl>(E->
getDecl());
286 return inherited::TransformDeclRefExpr(E);
289 "Template arguments for NTTP decl?");
305 RemoveNonPackExpansionPacks ? NTTP : D,
315 using inherited = RecursiveASTVisitor<HashParameterMapping>;
319 const MultiLevelTemplateArgumentList &TemplateArgs;
320 llvm::FoldingSetNodeID &
ID;
321 llvm::SmallVector<TemplateArgument, 10> UsedTemplateArgs;
325 bool shouldVisitTemplateInstantiations()
const {
return true; }
328 HashParameterMapping(Sema &SemaRef,
329 const MultiLevelTemplateArgumentList &TemplateArgs,
330 llvm::FoldingSetNodeID &ID,
332 : SemaRef(SemaRef), TemplateArgs(TemplateArgs),
ID(
ID),
333 OuterPackSubstIndex(OuterPackSubstIndex) {}
335 bool VisitTemplateTypeParmType(TemplateTypeParmType *
T) {
346 TemplateArgument Arg = TemplateArgs(
T->getDepth(),
T->getIndex());
352 if ((
T->isParameterPack() ||
353 (
T->getDecl() &&
T->getDecl()->isTemplateParameterPack())) &&
356 "Missing argument pack");
361 UsedTemplateArgs.push_back(
366 bool VisitDeclRefExpr(DeclRefExpr *E) {
368 NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(D);
370 return TraverseDecl(D);
388 "Missing argument pack");
392 UsedTemplateArgs.push_back(
397 bool VisitTypedefType(TypedefType *TT) {
398 return inherited::TraverseType(TT->
desugar());
401 bool TraverseDecl(Decl *D) {
402 if (
auto *VD = dyn_cast<ValueDecl>(D)) {
403 if (
auto *Var = dyn_cast<VarDecl>(VD))
404 TraverseStmt(Var->getInit());
405 return TraverseType(VD->getType());
408 return inherited::TraverseDecl(D);
411 bool TraverseCallExpr(CallExpr *CE) {
412 inherited::TraverseStmt(CE->
getCallee());
415 inherited::TraverseStmt(Arg);
420 bool TraverseCXXThisExpr(CXXThisExpr *E) {
421 return inherited::TraverseType(E->
getType());
424 bool TraverseTypeLoc(TypeLoc TL,
bool TraverseQualifier =
true) {
429 bool TraverseDependentNameType(
const DependentNameType *
T,
431 return TraverseNestedNameSpecifier(
T->getQualifier());
434 bool TraverseTagType(
const TagType *
T,
bool TraverseQualifier) {
442 bool TraverseUnresolvedUsingType(UnresolvedUsingType *
T,
443 bool TraverseQualifier) {
446 if (NestedNameSpecifier NNS =
T->getDecl()->getQualifier();
447 TraverseQualifier && NNS)
448 return inherited::TraverseNestedNameSpecifier(NNS);
449 return inherited::TraverseUnresolvedUsingType(
T, TraverseQualifier);
452 bool TraverseInjectedClassNameType(InjectedClassNameType *
T,
453 bool TraverseQualifier) {
454 return TraverseTemplateArguments(
T->getTemplateArgs(SemaRef.
Context));
457 bool TraverseTemplateArgument(
const TemplateArgument &Arg) {
460 Sema::ArgPackSubstIndexRAII _1(SemaRef, std::nullopt);
461 llvm::SaveAndRestore<UnsignedOrNone>
_2(OuterPackSubstIndex,
463 return inherited::TraverseTemplateArgument(Arg);
466 Sema::ArgPackSubstIndexRAII _1(SemaRef, OuterPackSubstIndex);
467 return inherited::TraverseTemplateArgument(Arg);
470 bool TraverseSizeOfPackExpr(SizeOfPackExpr *SOPE) {
471 return TraverseDecl(SOPE->
getPack());
474 bool VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *E) {
479 if (
auto *TTP = dyn_cast_if_present<TemplateTemplateParmDecl>(
486 TemplateArgument Arg = TemplateArgs(TTP->getDepth(), TTP->getPosition());
489 "Missing argument pack");
493 "Null template template argument");
494 UsedTemplateArgs.push_back(
497 return inherited::TraverseTemplateName(
Template);
500 void VisitConstraint(
const NormalizedConstraintWithParamMapping &Constraint) {
502 for (
const auto &List : TemplateArgs)
503 for (
const TemplateArgument &Arg : List.Args)
509 llvm::ArrayRef<TemplateArgumentLoc> Mapping =
511 for (
auto &ArgLoc : Mapping) {
512 TemplateArgument Canonical =
515 UsedTemplateArgs.push_back(Canonical);
516 TraverseTemplateArgument(Canonical);
519 for (
auto &
Used : UsedTemplateArgs) {
520 llvm::FoldingSetNodeID
R;
527class ConstraintSatisfactionChecker {
530 const ConceptReference *TopLevelConceptId;
531 SourceLocation TemplateNameLoc;
533 ConstraintSatisfaction &Satisfaction;
534 bool BuildExpression;
537 ConceptDecl *ParentConcept =
nullptr;
541 llvm::DenseMap<llvm::FoldingSetNodeID, TemplateArgumentLoc>
545 template <
class Constra
int>
547 return C.getPackSubstitutionIndex() ?
C.getPackSubstitutionIndex()
548 : PackSubstitutionIndex;
552 EvaluateAtomicConstraint(
const Expr *AtomicExpr,
553 const MultiLevelTemplateArgumentList &MLTAL);
556 const FoldExpandedConstraint &FE,
557 const MultiLevelTemplateArgumentList &MLTAL);
560 std::optional<MultiLevelTemplateArgumentList> SubstitutionInTemplateArguments(
561 const NormalizedConstraintWithParamMapping &Constraint,
562 const MultiLevelTemplateArgumentList &MLTAL,
563 llvm::SmallVector<TemplateArgument> &SubstitutedOuterMost);
565 ExprResult EvaluateSlow(
const AtomicConstraint &Constraint,
566 const MultiLevelTemplateArgumentList &MLTAL);
569 const MultiLevelTemplateArgumentList &MLTAL);
571 ExprResult EvaluateSlow(
const FoldExpandedConstraint &Constraint,
572 const MultiLevelTemplateArgumentList &MLTAL);
575 const MultiLevelTemplateArgumentList &MLTAL);
577 ExprResult EvaluateSlow(
const ConceptIdConstraint &Constraint,
578 const MultiLevelTemplateArgumentList &MLTAL,
582 const MultiLevelTemplateArgumentList &MLTAL);
585 const MultiLevelTemplateArgumentList &MLTAL);
588 ConstraintSatisfactionChecker(Sema &SemaRef,
const NamedDecl *
Template,
589 const ConceptReference *TopLevelConceptId,
590 SourceLocation TemplateNameLoc,
592 ConstraintSatisfaction &Satisfaction,
593 bool BuildExpression)
595 TemplateNameLoc(TemplateNameLoc),
596 PackSubstitutionIndex(PackSubstitutionIndex),
597 Satisfaction(Satisfaction), BuildExpression(BuildExpression) {}
600 const MultiLevelTemplateArgumentList &MLTAL);
603StringRef allocateStringFromConceptDiagnostic(
const Sema &S,
613ExprResult ConstraintSatisfactionChecker::EvaluateAtomicConstraint(
615 llvm::FoldingSetNodeID
ID;
622 SatisfactionStackRAII StackRAII(S,
Template, ID);
633 if (Inst.isInvalid())
638 SubstitutedExpression =
641 if (SubstitutedExpression.
isInvalid() || Trap.hasErrorOccurred()) {
645 if (!Trap.hasErrorOccurred())
652 Info.takeSFINAEDiagnostic(SubstDiag);
659 Satisfaction.
Details.emplace_back(
662 allocateStringFromConceptDiagnostic(S, SubstDiag.second)});
684 SubstitutedExpression.
get(),
687 return SubstitutedExpression;
690std::optional<MultiLevelTemplateArgumentList>
691ConstraintSatisfactionChecker::SubstitutionInTemplateArguments(
714 if (Inst.isInvalid())
721 &CachedTemplateArgs);
736 TD->getLocation(), SubstArgs,
745 SubstitutedOutermost =
746 llvm::to_vector_of<TemplateArgument>(MLTAL.
getOutermost());
748 for (
unsigned I = 0, MappedIndex = 0; I <
Used.size(); I++) {
753 if (I < SubstitutedOutermost.size()) {
754 SubstitutedOutermost[I] = Arg;
757 SubstitutedOutermost.push_back(Arg);
758 Offset = SubstitutedOutermost.size();
761 if (Offset < SubstitutedOutermost.size())
762 SubstitutedOutermost.erase(SubstitutedOutermost.begin() + Offset);
767 return std::move(SubstitutedTemplateArgs);
770ExprResult ConstraintSatisfactionChecker::EvaluateSlow(
773 std::optional<EnterExpressionEvaluationContext> EvaluationContext;
777 EvaluationContext.emplace(
780 EvaluationContext.emplace(
785 std::optional<MultiLevelTemplateArgumentList> SubstitutedArgs =
786 SubstitutionInTemplateArguments(Constraint, MLTAL, SubstitutedOutermost);
787 if (!SubstitutedArgs) {
795 std::optional<Sema::ContextRAII> ConceptContext;
800 ExprResult SubstitutedAtomicExpr = EvaluateAtomicConstraint(
806 if (SubstitutedAtomicExpr.
isUnset())
820 Satisfaction.
Details.emplace_back(
822 SubstitutedAtomicExpr.get()->getBeginLoc(),
823 allocateStringFromConceptDiagnostic(S, Msg)});
824 return SubstitutedAtomicExpr;
830 return SubstitutedAtomicExpr;
835 EvalResult.
Diag = &EvaluationDiags;
838 !EvaluationDiags.empty()) {
842 diag::err_non_constant_constraint_expression)
845 S.
Diag(PDiag.first, PDiag.second);
850 "evaluating bool expression didn't produce int");
853 Satisfaction.
Details.emplace_back(SubstitutedAtomicExpr.
get());
855 return SubstitutedAtomicExpr;
858ExprResult ConstraintSatisfactionChecker::Evaluate(
863 llvm::FoldingSetNodeID
ID;
864 UnsignedOrNone OuterPackSubstIndex = getOuterPackIndex(Constraint);
868 HashParameterMapping(S, MLTAL, ID, OuterPackSubstIndex)
869 .VisitConstraint(Constraint);
873 auto &Cached = Iter->second.Satisfaction;
877 Cached.Details.begin(), Cached.Details.end());
878 return Iter->second.SubstExpr;
881 ExprResult E = EvaluateSlow(Constraint, MLTAL);
886 Cache.Satisfaction.Details.insert(
Cache.Satisfaction.Details.end(),
887 Satisfaction.
Details.begin() + Size,
896ConstraintSatisfactionChecker::EvaluateFoldExpandedConstraintSize(
904 assert(!Unexpanded.empty() &&
"Pack expansion without parameter packs?");
906 bool RetainExpansion =
false;
910 false, Expand, RetainExpansion,
911 NumExpansions,
false) ||
912 !Expand || RetainExpansion)
915 if (NumExpansions && S.
getLangOpts().BracketDepth < *NumExpansions)
917 return NumExpansions;
920ExprResult ConstraintSatisfactionChecker::EvaluateSlow(
926 unsigned EffectiveDetailEndIndex = Satisfaction.
Details.size();
931 std::optional<MultiLevelTemplateArgumentList> SubstitutedArgs =
932 SubstitutionInTemplateArguments(
934 MLTAL, SubstitutedOutermost);
935 if (!SubstitutedArgs) {
942 EvaluateFoldExpandedConstraintSize(Constraint, *SubstitutedArgs);
946 if (*NumExpansions == 0) {
951 for (
unsigned I = 0; I < *NumExpansions; I++) {
956 ConstraintSatisfactionChecker(S,
Template, TopLevelConceptId,
961 if (BuildExpression) {
962 if (
Out.isUnset() || !
Expr.isUsable())
966 Conjunction ? BinaryOperatorKind::BO_LAnd
967 : BinaryOperatorKind::BO_LOr,
974 EffectiveDetailEndIndex,
985ExprResult ConstraintSatisfactionChecker::Evaluate(
989 llvm::FoldingSetNodeID
ID;
991 HashParameterMapping(S, MLTAL, ID, std::nullopt).VisitConstraint(Constraint);
996 auto &Cached = Iter->second.Satisfaction;
1000 Cached.Details.begin(), Cached.Details.end());
1001 return Iter->second.SubstExpr;
1006 ExprResult E = EvaluateSlow(Constraint, MLTAL);
1010 Cache.Satisfaction.Details.insert(
Cache.Satisfaction.Details.end(),
1011 Satisfaction.
Details.begin() + Size,
1013 Cache.SubstExpr = E;
1018ExprResult ConstraintSatisfactionChecker::EvaluateSlow(
1024 std::optional<MultiLevelTemplateArgumentList> SubstitutedArgs =
1025 SubstitutionInTemplateArguments(Constraint, MLTAL, SubstitutedOutermost);
1027 if (!SubstitutedArgs) {
1047 if (TopLevelConceptId &&
1051 OutArgs.addArgument(A);
1054 Trap.hasErrorOccurred()) {
1056 if (!Trap.hasErrorOccurred())
1061 Info.takeSFINAEDiagnostic(SubstDiag);
1069 Satisfaction.
Details.begin() + Size,
1072 allocateStringFromConceptDiagnostic(S, SubstDiag.second)});
1085 if (SubstitutedConceptId.
isInvalid() || Trap.hasErrorOccurred())
1088 if (Size != Satisfaction.
Details.size()) {
1090 Satisfaction.
Details.begin() + Size,
1095 return SubstitutedConceptId;
1098ExprResult ConstraintSatisfactionChecker::Evaluate(
1115 if (InstTemplate.isInvalid())
1127 Satisfaction.
Details.insert(Satisfaction.
Details.begin() + Size, ConceptId);
1137 UnsignedOrNone OuterPackSubstIndex = getOuterPackIndex(Constraint);
1138 llvm::FoldingSetNodeID
ID;
1141 HashParameterMapping(S, MLTAL, ID, OuterPackSubstIndex)
1142 .VisitConstraint(Constraint);
1147 auto &Cached = Iter->second.Satisfaction;
1151 Cached.Details.begin(), Cached.Details.end());
1152 return Iter->second.SubstExpr;
1155 ExprResult CE = EvaluateSlow(Constraint, MLTAL, Size);
1161 Cache.Satisfaction.Details.insert(
Cache.Satisfaction.Details.end(),
1162 Satisfaction.
Details.begin() + Size,
1164 Cache.SubstExpr = CE;
1169ExprResult ConstraintSatisfactionChecker::Evaluate(
1173 unsigned EffectiveDetailEndIndex = Satisfaction.
Details.size();
1195 EffectiveDetailEndIndex,
1198 if (!BuildExpression)
1208 Conjunction ? BinaryOperatorKind::BO_LAnd
1209 : BinaryOperatorKind::BO_LOr,
1214ExprResult ConstraintSatisfactionChecker::Evaluate(
1217 switch (Constraint.
getKind()) {
1232 llvm_unreachable(
"Unknown ConstraintKind enum");
1243 *ConvertedExpr =
nullptr;
1245 if (AssociatedConstraints.empty()) {
1265 struct SynthesisContextPair {
1271 : Inst(S, InstantiationRange.
getBegin(),
1273 TemplateArgs, InstantiationRange),
1276 std::optional<SynthesisContextPair> SynthesisContext;
1277 if (!TopLevelConceptId)
1288 if (TopLevelConceptId)
1295 ConstraintSatisfactionChecker(
1298 ConvertedExpr !=
nullptr)
1299 .Evaluate(*
C, TemplateArgsLists);
1304 if (Res.
isUsable() && ConvertedExpr)
1305 *ConvertedExpr = Res.
get();
1316 llvm::TimeTraceScope TimeScope(
1317 "CheckConstraintSatisfaction", [TemplateIDRange,
this] {
1320 if (AssociatedConstraints.empty()) {
1326 return ::CheckConstraintSatisfaction(
1327 *
this,
nullptr, AssociatedConstraints, TemplateArgsLists,
1328 TemplateIDRange, OutSatisfaction, ConvertedExpr, TopLevelConceptId);
1342 for (
auto List : TemplateArgsLists)
1344 FlattenedArgs.emplace_back(
Context.getCanonicalTemplateArgument(Arg));
1347 if (TopLevelConceptId)
1350 llvm::FoldingSetNodeID ID;
1353 if (
auto *Cached = SatisfactionCache.FindNodeOrInsertPos(ID, InsertPos)) {
1354 OutSatisfaction = *Cached;
1359 std::make_unique<ConstraintSatisfaction>(Owner, FlattenedArgs);
1361 *
this,
Template, AssociatedConstraints, TemplateArgsLists,
1362 TemplateIDRange, *Satisfaction, ConvertedExpr, TopLevelConceptId)) {
1363 OutSatisfaction = std::move(*Satisfaction);
1367 if (
auto *Cached = SatisfactionCache.FindNodeOrInsertPos(ID, InsertPos)) {
1376 OutSatisfaction = *Cached;
1381 OutSatisfaction = *Satisfaction;
1385 SatisfactionCache.InsertNode(Satisfaction.release());
1407 return !ArgLoc.getArgument().isDependent() &&
1408 ArgLoc.getArgument().isConceptOrConceptTemplateParameter();
1410 return Concept->getConstraintExpr();
1423bool Sema::SetupConstraintScope(
1428 "Use LambdaScopeForCallOperatorInstantiationRAII to handle lambda "
1434 Sema::InstantiatingTemplate::ConstraintsCheck{}, PrimaryTemplate,
1435 TemplateArgs ? *TemplateArgs : ArrayRef<TemplateArgument>{},
1437 if (Inst.isInvalid())
1446 MultiLevelTemplateArgumentList JustTemplArgs(FD, SpecArgs->asArray(),
1448 if (addInstantiatedParametersToScope(
1455 if (FunctionTemplateDecl *FromMemTempl =
1457 if (addInstantiatedParametersToScope(FD, FromMemTempl->getTemplatedDecl(),
1467 FunctionDecl *InstantiatedFrom =
1474 Sema::InstantiatingTemplate::ConstraintsCheck{}, InstantiatedFrom,
1475 TemplateArgs ? *TemplateArgs : ArrayRef<TemplateArgument>{},
1477 if (Inst.isInvalid())
1482 if (addInstantiatedParametersToScope(FD, InstantiatedFrom, Scope, MLTAL))
1491std::optional<MultiLevelTemplateArgumentList>
1492Sema::SetupConstraintCheckingTemplateArgumentsAndScope(
1495 MultiLevelTemplateArgumentList MLTAL;
1502 false, std::nullopt,
1509 if (SetupConstraintScope(FD, TemplateArgs, MLTAL, Scope))
1510 return std::nullopt;
1518 bool ForOverloadResolution) {
1537 if (
const auto *MD = dyn_cast<CXXConversionDecl>(FD);
1540 Satisfaction, UsageLoc,
1554 std::optional<MultiLevelTemplateArgumentList> MLTAL =
1555 SetupConstraintCheckingTemplateArgumentsAndScope(
1563 if (
auto *
Method = dyn_cast<CXXMethodDecl>(FD)) {
1564 ThisQuals =
Method->getMethodQualifiers();
1571 ForOverloadResolution);
1581 const Expr *ConstrExpr) {
1596 std::optional<LocalInstantiationScope> ScopeForParameters;
1599 ScopeForParameters.emplace(S,
true);
1603 FD =
Template->getInstantiatedFromMemberTemplate()->getTemplatedDecl();
1605 if (ScopeForParameters->getInstantiationOfIfExists(PVD))
1607 if (!PVD->isParameterPack()) {
1608 ScopeForParameters->InstantiatedLocal(PVD, PVD);
1627 ScopeForParameters->MakeInstantiatedLocalArgPack(PVD);
1628 ScopeForParameters->InstantiatedLocalPackArg(PVD, PVD);
1632 std::optional<Sema::CXXThisScopeRAII> ThisScope;
1641 std::optional<Sema::ContextRAII> ContextScope;
1649 if (
auto *RD = dyn_cast<CXXRecordDecl>(DC)) {
1661 return SubstConstr.
get();
1665 const Expr *OldConstr,
1667 const Expr *NewConstr) {
1668 if (OldConstr == NewConstr)
1671 if (Old && !
New.isInvalid() && !
New.ContainsDecl(Old) &&
1674 if (
const Expr *SubstConstr =
1677 OldConstr = SubstConstr;
1680 if (
const Expr *SubstConstr =
1683 NewConstr = SubstConstr;
1688 llvm::FoldingSetNodeID ID1, ID2;
1701 "Non-function templates don't need to be checked");
1722 TemplateIDRange, Satisfaction))
1727 TemplateArgString =
" ";
1733 diag::err_template_arg_list_constraints_not_satisfied)
1735 << TemplateArgString << TemplateIDRange;
1747 Template->getAssociatedConstraints(TemplateAC);
1748 if (TemplateAC.empty()) {
1767 SemaRef, PointOfInstantiation,
1769 PointOfInstantiation);
1770 if (Inst.isInvalid())
1780 Template, TemplateAC, MLTAL, PointOfInstantiation, Satisfaction);
1791 return ::CheckFunctionConstraintsWithoutInstantiation(
1792 *
this, PointOfInstantiation,
Decl->getDescribedFunctionTemplate(),
1793 TemplateArgs, Satisfaction);
1798 Template->getAssociatedConstraints(TemplateAC);
1799 if (TemplateAC.empty()) {
1809 std::optional<MultiLevelTemplateArgumentList> MLTAL =
1810 SetupConstraintCheckingTemplateArgumentsAndScope(
Decl, TemplateArgs,
1818 if (
auto *
Method = dyn_cast<CXXMethodDecl>(
Decl)) {
1819 ThisQuals =
Method->getMethodQualifiers();
1828 PointOfInstantiation, Satisfaction);
1835 "Diagnose() can only be used on an unsatisfied requirement");
1838 llvm_unreachable(
"Diagnosing a dependent requirement");
1842 if (!SubstDiag->DiagMessage.empty())
1843 S.
Diag(SubstDiag->DiagLoc,
1844 diag::note_expr_requirement_expr_substitution_error)
1845 << (
int)
First << SubstDiag->SubstitutedEntity
1846 << SubstDiag->DiagMessage;
1848 S.
Diag(SubstDiag->DiagLoc,
1849 diag::note_expr_requirement_expr_unknown_substitution_error)
1850 << (
int)
First << SubstDiag->SubstitutedEntity;
1860 if (!SubstDiag->DiagMessage.empty())
1861 S.
Diag(SubstDiag->DiagLoc,
1862 diag::note_expr_requirement_type_requirement_substitution_error)
1863 << (
int)
First << SubstDiag->SubstitutedEntity
1864 << SubstDiag->DiagMessage;
1869 note_expr_requirement_type_requirement_unknown_substitution_error)
1870 << (
int)
First << SubstDiag->SubstitutedEntity;
1880 llvm_unreachable(
"We checked this above");
1888 "Diagnose() can only be used on an unsatisfied requirement");
1891 llvm_unreachable(
"Diagnosing a dependent requirement");
1895 if (!SubstDiag->DiagMessage.empty())
1896 S.
Diag(SubstDiag->DiagLoc, diag::note_type_requirement_substitution_error)
1897 << (
int)
First << SubstDiag->SubstitutedEntity
1898 << SubstDiag->DiagMessage;
1900 S.
Diag(SubstDiag->DiagLoc,
1901 diag::note_type_requirement_unknown_substitution_error)
1902 << (
int)
First << SubstDiag->SubstitutedEntity;
1906 llvm_unreachable(
"Unknown satisfaction status");
1914 if (
Concept->getTemplateArgsAsWritten()->NumTemplateArgs == 1) {
1918 note_single_arg_concept_specialization_constraint_evaluated_to_false)
1920 <<
Concept->getTemplateArgsAsWritten()->arguments()[0].getArgument()
1921 <<
Concept->getNamedConcept().getAsTemplateDecl();
1923 S.
Diag(Loc, diag::note_concept_specialization_constraint_evaluated_to_false)
1953 const Expr *SubstExpr,
1956 if (
const BinaryOperator *BO = dyn_cast<BinaryOperator>(SubstExpr)) {
1957 switch (BO->getOpcode()) {
1969 BO->getLHS()->EvaluateKnownConstInt(S.
Context).getBoolValue();
1980 BO->getRHS()->EvaluateKnownConstInt(S.
Context).getBoolValue();
1992 if (BO->getLHS()->getType()->isIntegerType() &&
1993 BO->getRHS()->getType()->isIntegerType()) {
1996 BO->getLHS()->EvaluateAsInt(SimplifiedLHS, S.
Context,
1999 BO->getRHS()->EvaluateAsInt(SimplifiedRHS, S.
Context,
2002 if (!SimplifiedLHS.
Diag && !SimplifiedRHS.
Diag) {
2004 diag::note_atomic_constraint_evaluated_to_false_elaborated)
2017 }
else if (
auto *RE = dyn_cast<RequiresExpr>(SubstExpr)) {
2020 if (!Req->isDependent() && !Req->isSatisfied()) {
2021 if (
auto *E = dyn_cast<concepts::ExprRequirement>(Req))
2023 else if (
auto *
T = dyn_cast<concepts::TypeRequirement>(Req))
2031 }
else if (
auto *CSE = dyn_cast<ConceptSpecializationExpr>(SubstExpr)) {
2035 }
else if (
auto *TTE = dyn_cast<TypeTraitExpr>(SubstExpr);
2036 TTE && TTE->getTrait() == clang::TypeTrait::BTT_IsDeducible) {
2037 assert(TTE->getNumArgs() == 2);
2039 diag::note_is_deducible_constraint_evaluated_to_false)
2040 << TTE->getArg(0)->getType() << TTE->getArg(1)->getType();
2045 diag::note_atomic_constraint_evaluated_to_false)
2055 .
template dyn_cast<const ConstraintSubstitutionDiagnostic *>()) {
2057 S.
Diag(
Diag->first, diag::note_nested_requirement_substitution_error)
2060 S.
Diag(
Diag->first, diag::note_substituted_constraint_expr_is_ill_formed)
2064 if (
const auto *
Concept = dyn_cast<const ConceptReference *>(
Record)) {
2079 "Attempted to diagnose a satisfied constraint");
2090 "Attempted to diagnose a satisfied constraint");
2098class SubstituteParameterMappings {
2110 bool RemovePacksForFoldExpr;
2112 SubstituteParameterMappings(
Sema &SemaRef,
2115 bool RemovePacksForFoldExpr)
2116 : SemaRef(SemaRef), MLTAL(MLTAL), ArgsAsWritten(ArgsAsWritten),
2117 RemovePacksForFoldExpr(RemovePacksForFoldExpr) {}
2126 SubstituteParameterMappings(
Sema &SemaRef,
2127 bool RemovePacksForFoldExpr =
false)
2129 RemovePacksForFoldExpr(RemovePacksForFoldExpr) {}
2131 bool substitute(NormalizedConstraint &N);
2134void SubstituteParameterMappings::buildParameterMapping(
2139 llvm::SmallBitVector OccurringIndices(TemplateParams->
size());
2140 llvm::SmallBitVector OccurringIndicesForSubsumption(TemplateParams->
size());
2146 0, OccurringIndices);
2150 0, OccurringIndicesForSubsumption);
2157 0, OccurringIndices);
2161 ->getTemplateArgsAsWritten();
2164 0, OccurringIndices);
2172 I < TemplateParams->size(); ++I) {
2178 assert(Arg &&
"expected a default argument");
2179 DefaultArgs.emplace_back(std::move(*Arg));
2182 0, OccurringIndices);
2185 OccurringIndicesForSubsumption);
2188 unsigned Size = OccurringIndices.count();
2196 for (
unsigned I = 0, J = 0,
C = TemplateParams->
size(); I !=
C; ++I) {
2198 ? ArgsAsWritten->arguments()[I].getLocation()
2202 if (OccurringIndices[I]) {
2206 UsedParams.push_back(Param);
2216 std::move(OccurringIndices), std::move(OccurringIndicesForSubsumption),
2220bool SubstituteParameterMappings::substitute(
2223 buildParameterMapping(N);
2232 InstLocBegin = ArgsAsWritten->getLAngleLoc();
2233 InstLocEnd = ArgsAsWritten->getRAngleLoc();
2235 auto SR =
Arguments[0].getSourceRange();
2236 InstLocBegin = SR.getBegin();
2237 InstLocEnd = SR.getEnd();
2241 SemaRef, InstLocBegin,
2244 {InstLocBegin, InstLocEnd});
2245 if (Inst.isInvalid())
2262 TD->getLocation(), SubstArgs,
2273 if (I < SubstArgs.
size())
2274 Loc = SubstArgs.
arguments()[I].getLocation();
2301 InstLocBegin = ArgsAsWritten->getLAngleLoc();
2302 InstLocEnd = ArgsAsWritten->getRAngleLoc();
2304 auto SR =
Arguments[0].getSourceRange();
2305 InstLocBegin = SR.getBegin();
2306 InstLocEnd = SR.getEnd();
2311 SemaRef, InstLocBegin,
2314 {InstLocBegin, InstLocEnd});
2315 if (Inst.isInvalid())
2326 CSE->getTemplateArgsAsWritten();
2332 CSE->getConceptNameInfo().getLoc(), Out,
2337 auto TemplateArgs = *MLTAL;
2340 return SubstituteParameterMappings(SemaRef, &TemplateArgs, ArgsAsWritten,
2341 RemovePacksForFoldExpr)
2349 assert(!ArgsAsWritten);
2358 assert(!ArgsAsWritten);
2363 return SubstituteParameterMappings(SemaRef,
true)
2369 assert(ArgsAsWritten);
2370 return substitute(CC);
2372 assert(!ArgsAsWritten);
2384 if (RemovePacksForFoldExpr) {
2388 if (AdjustConstraints(SemaRef, 0,
2390 .TransformTemplateArguments(InputArgLoc.begin(),
2391 InputArgLoc.end(), OutArgs))
2412 return SubstituteParameterMappings(SemaRef, &MLTAL,
2414 RemovePacksForFoldExpr)
2419 if (substitute(Compound.getLHS()))
2421 return substitute(Compound.getRHS());
2424 llvm_unreachable(
"Unknown ConstraintKind enum");
2431 assert(ACs.size() != 0);
2433 fromConstraintExpr(S, D, ACs[0].ConstraintExpr, ACs[0].ArgPackSubstIndex);
2436 for (
unsigned I = 1; I < ACs.size(); ++I) {
2437 auto *
Next = fromConstraintExpr(S, D, ACs[I].ConstraintExpr,
2438 ACs[I].ArgPackSubstIndex);
2449 assert(E !=
nullptr);
2457 llvm::FoldingSetNodeID
ID;
2461 SatisfactionStackRAII StackRAII(S, D, ID);
2468 if (LogicalBinOp BO = E) {
2469 auto *LHS = fromConstraintExpr(S, D, BO.getLHS(), SubstIndex);
2472 auto *RHS = fromConstraintExpr(S, D, BO.getRHS(), SubstIndex);
2479 if (
auto *CSE = dyn_cast<const ConceptSpecializationExpr>(E)) {
2495 SubNF = NormalizedConstraint::fromAssociatedConstraints(
2497 AssociatedConstraint(Res.get(), SubstIndex));
2504 if (
auto *FE = dyn_cast<const CXXFoldExpr>(E);
2506 (FE->getOperator() == BinaryOperatorKind::BO_LAnd ||
2507 FE->getOperator() == BinaryOperatorKind::BO_LOr)) {
2512 FE->getOperator() == BinaryOperatorKind::BO_LAnd
2516 if (FE->getInit()) {
2517 auto *LHS = fromConstraintExpr(S, D, FE->getLHS(), SubstIndex);
2518 auto *RHS = fromConstraintExpr(S, D, FE->getRHS(), SubstIndex);
2522 if (FE->isRightFold())
2535 auto *
Sub = fromConstraintExpr(S, D, FE->
getPattern(), SubstIndex);
2547 if (!ConstrainedDeclOrNestedReq) {
2548 auto *Normalized = NormalizedConstraint::fromAssociatedConstraints(
2549 *
this,
nullptr, AssociatedConstraints);
2551 SubstituteParameterMappings(*this).substitute(*Normalized))
2559 ConstrainedDeclOrNestedReq.dyn_cast<
const NamedDecl *>();
2560 auto CacheEntry = NormalizationCache.find(ConstrainedDeclOrNestedReq);
2561 if (CacheEntry == NormalizationCache.end()) {
2562 auto *Normalized = NormalizedConstraint::fromAssociatedConstraints(
2563 *
this, ND, AssociatedConstraints);
2565 NormalizationCache.try_emplace(ConstrainedDeclOrNestedReq,
nullptr);
2569 bool Failed = SubstituteParameterMappings(*this).substitute(*Normalized);
2571 NormalizationCache.try_emplace(ConstrainedDeclOrNestedReq, Normalized)
2576 return CacheEntry->second;
2599 if (It != BPacks.end())
2611 if (
const auto *FD1 = dyn_cast<FunctionDecl>(D1)) {
2617 const auto *FD2 = dyn_cast<FunctionDecl>(D2);
2618 assert(IsExpectedEntity(FD1) && FD2 && IsExpectedEntity(FD2) &&
2619 "use non-instantiated function declaration for constraints partial "
2634 std::pair<const NamedDecl *, const NamedDecl *> Key{D1, D2};
2635 auto CacheEntry = SubsumptionCache.find(Key);
2636 if (CacheEntry != SubsumptionCache.end()) {
2637 Result = CacheEntry->second;
2644 for (
size_t I = 0; I != AC1.size() && I != AC2.size(); ++I) {
2645 if (Depth2 > Depth1) {
2646 AC1[I].ConstraintExpr =
2647 AdjustConstraints(*
this, Depth2 - Depth1)
2648 .TransformExpr(
const_cast<Expr *
>(AC1[I].ConstraintExpr))
2650 }
else if (Depth1 > Depth2) {
2651 AC2[I].ConstraintExpr =
2652 AdjustConstraints(*
this, Depth1 - Depth2)
2653 .TransformExpr(
const_cast<Expr *
>(AC2[I].ConstraintExpr))
2662 const NamedDecl *DeclAC1 = D1, *DeclAC2 = D2;
2663 if (Depth2 > Depth1)
2665 else if (Depth1 > Depth2)
2667 std::optional<bool> Subsumes = SC.
Subsumes(DeclAC1, AC1, DeclAC2, AC2);
2673 SubsumptionCache.try_emplace(Key, *Subsumes);
2684 if (AC1.empty() || AC2.empty())
2687 const Expr *AmbiguousAtomic1 =
nullptr, *AmbiguousAtomic2 =
nullptr;
2698 llvm::FoldingSetNodeID IDA, IDB;
2700 EB->Profile(IDB,
Context,
true);
2704 AmbiguousAtomic1 = EA;
2705 AmbiguousAtomic2 = EB;
2720 bool Is1AtLeastAs2Normally = SC.
Subsumes(Normalized1, Normalized2);
2721 bool Is2AtLeastAs1Normally = SC.
Subsumes(Normalized2, Normalized1);
2724 bool Is1AtLeastAs2 = SC2.
Subsumes(Normalized1, Normalized2);
2725 bool Is2AtLeastAs1 = SC2.
Subsumes(Normalized2, Normalized1);
2727 if (Is1AtLeastAs2 == Is1AtLeastAs2Normally &&
2728 Is2AtLeastAs1 == Is2AtLeastAs1Normally)
2733 assert(AmbiguousAtomic1 && AmbiguousAtomic2);
2735 Diag(AmbiguousAtomic1->
getBeginLoc(), diag::note_ambiguous_atomic_constraints)
2737 Diag(AmbiguousAtomic2->getBeginLoc(),
2738 diag::note_ambiguous_atomic_constraints_similar_expression)
2739 << AmbiguousAtomic2->getSourceRange();
2750 : SemaRef(SemaRef), Callable(Callable), NextID(1) {}
2752uint16_t SubsumptionChecker::getNewLiteralId() {
2753 assert((
unsigned(NextID) + 1 < std::numeric_limits<uint16_t>::max()) &&
2754 "too many constraints!");
2759 auto &Elems = AtomicMap[Ori->getConstraintExpr()];
2774 llvm::FoldingSetNodeID ID;
2775 ID.AddBoolean(Ori->hasParameterMapping());
2776 if (Ori->hasParameterMapping()) {
2777 const auto &Mapping = Ori->getParameterMapping();
2779 Ori->mappingOccurenceListForSubsumption();
2780 for (
auto [Idx, TAL] : llvm::enumerate(Mapping)) {
2787 auto It = Elems.find(ID);
2788 if (It == Elems.end()) {
2791 MappedAtomicConstraint{
2792 Ori, {getNewLiteralId(), Literal::Atomic}}})
2794 ReverseMap[It->second.ID.Value] = Ori;
2796 return It->getSecond().ID;
2800 auto &Elems = FoldMap[Ori->getPattern()];
2802 FoldExpendedConstraintKey K;
2803 K.Kind = Ori->getFoldOperator();
2805 auto It = llvm::find_if(Elems, [&K](
const FoldExpendedConstraintKey &
Other) {
2806 return K.Kind ==
Other.Kind;
2808 if (It == Elems.end()) {
2809 K.ID = {getNewLiteralId(), Literal::FoldExpanded};
2810 It = Elems.insert(Elems.end(), std::move(K));
2811 ReverseMap[It->ID.Value] = Ori;
2817 return SubsumptionChecker::Normalize<CNFFormula>(
C);
2820 return SubsumptionChecker::Normalize<DNFFormula>(
C);
2836template <
typename FormulaType>
2840 auto Add = [&,
this](Clause
C) {
2843 C.erase(llvm::unique(
C),
C.end());
2844 AddUniqueClauseToFormula(Res, std::move(
C));
2849 return {{find(&
static_cast<const AtomicConstraint &
>(NC))}};
2852 return {{find(&
static_cast<const FoldExpandedConstraint &
>(NC))}};
2855 return Normalize<FormulaType>(
2856 static_cast<const ConceptIdConstraint &
>(NC).getNormalizedConstraint());
2859 const auto &Compound =
static_cast<const CompoundConstraint &
>(NC);
2861 SemaRef.runWithSufficientStackSpace(SourceLocation(), [&] {
2862 Left = Normalize<FormulaType>(Compound.getLHS());
2863 Right = Normalize<FormulaType>(Compound.getRHS());
2866 if (Compound.getCompoundKind() == FormulaType::Kind) {
2867 unsigned SizeLeft =
Left.size();
2868 Res = std::move(Left);
2869 Res.reserve(SizeLeft +
Right.size());
2870 std::for_each(std::make_move_iterator(
Right.begin()),
2871 std::make_move_iterator(
Right.end()), Add);
2875 Res.reserve(
Left.size() *
Right.size());
2876 for (
const auto <ransform : Left) {
2877 for (
const auto &RTransform : Right) {
2879 Combined.reserve(LTransform.size() + RTransform.size());
2880 llvm::copy(LTransform, std::back_inserter(Combined));
2881 llvm::copy(RTransform, std::back_inserter(Combined));
2882 Add(std::move(Combined));
2888 llvm_unreachable(
"Unknown ConstraintKind enum");
2891void SubsumptionChecker::AddUniqueClauseToFormula(Formula &F, Clause
C) {
2892 for (
auto &
Other : F) {
2893 if (llvm::equal(
C,
Other))
2903 SemaRef.getNormalizedAssociatedConstraints(DP, P);
2905 return std::nullopt;
2908 SemaRef.getNormalizedAssociatedConstraints(DQ, Q);
2910 return std::nullopt;
2912 return Subsumes(PNormalized, QNormalized);
2918 DNFFormula DNFP = DNF(*P);
2919 CNFFormula CNFQ = CNF(*Q);
2924 const CNFFormula &QCNF) {
2925 for (
const auto &Pi : PDNF) {
2926 for (
const auto &Qj : QCNF) {
2932 if (!DNFSubsumes(Pi, Qj))
2939bool SubsumptionChecker::DNFSubsumes(
const Clause &P,
const Clause &Q) {
2941 return llvm::any_of(P, [&](Literal LP) {
2942 return llvm::any_of(Q, [
this, LP](Literal LQ) {
return Subsumes(LP, LQ); });
2948 std::pair<const FoldExpandedConstraint *, const FoldExpandedConstraint *> Key{
2951 auto It = FoldSubsumptionCache.find(Key);
2952 if (It == FoldSubsumptionCache.end()) {
2961 It = FoldSubsumptionCache.try_emplace(std::move(Key), DoesSubsume).first;
2967 if (A.Kind != B.Kind)
2970 case Literal::Atomic:
2972 return A.Value == B.Value;
2974 *
static_cast<const AtomicConstraint *
>(ReverseMap[A.Value]),
2975 *
static_cast<const AtomicConstraint *
>(ReverseMap[B.Value]));
2976 case Literal::FoldExpanded:
2978 static_cast<const FoldExpandedConstraint *
>(ReverseMap[A.Value]),
2979 static_cast<const FoldExpandedConstraint *
>(ReverseMap[B.Value]));
2981 llvm_unreachable(
"unknown literal kind");
2986class DumpNormalizedConstraint {
2988 const PrintingPolicy &PP;
2992 DumpNormalizedConstraint(raw_ostream &OS, ASTContext &Context)
2993 :
OS(
OS), PP(Context.getPrintingPolicy()),
2996 void dump(
const NormalizedConstraint &N) {
3001 void Traverse(
const NormalizedConstraint &N) {
3003 case NormalizedConstraint::ConstraintKind::Compound:
3004 VisitCompound(
static_cast<const CompoundConstraint &
>(N));
3006 case NormalizedConstraint::ConstraintKind::Atomic:
3007 VisitAtomic(
static_cast<const AtomicConstraint &
>(N));
3009 case NormalizedConstraint::ConstraintKind::ConceptId:
3010 VisitConceptId(
static_cast<const ConceptIdConstraint &
>(N));
3012 case NormalizedConstraint::ConstraintKind::FoldExpanded:
3013 VisitFoldExpanded(
static_cast<const FoldExpandedConstraint &
>(N));
3018 void WriteNodeHeader(
const NormalizedConstraint &N, StringRef Kind) {
3024 void WritePackIndex(
const NormalizedConstraintWithParamMapping &N) {
3026 OS <<
" SubstIndex=" << *Idx;
3029 void VisitCompound(
const CompoundConstraint &
C) {
3030 WriteNodeHeader(
C,
"CompoundConstraint");
3035 TD.
AddChild([&] { Traverse(
C.getLHS()); });
3036 TD.
AddChild([&] { Traverse(
C.getRHS()); });
3039 void VisitAtomic(
const AtomicConstraint &A) {
3040 WriteNodeHeader(A,
"AtomicConstraint");
3044 WriteParameterMapping(A);
3047 void VisitConceptId(
const ConceptIdConstraint &
C) {
3048 WriteNodeHeader(
C,
"ConceptIdConstraint");
3051 if (
auto *CSE =
C.getConceptSpecializationExpr()) {
3054 C.getConceptId()->print(OS, PP);
3056 WriteParameterMapping(
C);
3057 TD.
AddChild([&] { Traverse(
C.getNormalizedConstraint()); });
3060 void VisitFoldExpanded(
const FoldExpandedConstraint &F) {
3061 WriteNodeHeader(F,
"FoldExpandedConstraint");
3063 << (F.
getFoldOperator() == FoldExpandedConstraint::FoldOperatorKind::And
3069 WriteParameterMapping(F);
3073 void WriteParameterMapping(
const NormalizedConstraintWithParamMapping &N) {
3080 OS <<
"ParameterMapping";
3081 WriteOccurenceList(
"Indexes", Indexes);
3082 WriteOccurenceList(
"IndexesForSubsumption", IndexesForSub);
3084 for (unsigned ParamIndex : Indexes.set_bits()) {
3085 TD.AddChild([this, Slot, ParamIndex, Mapping, TPL] {
3086 assert(TPL && Slot < TPL->size());
3087 const NamedDecl *Param = TPL->getParam(Slot);
3088 OS <<
"#" << ParamIndex <<
": <";
3089 Param->print(OS, PP);
3091 Mapping[Slot].getArgument().print(PP, OS,
3093 TD.AddChild([this, Slot, Mapping] {
3094 const TemplateArgument &TA = Mapping[Slot].getArgument();
3095 OS <<
"TemplateArgument " << TA.getKindName();
3096 TD.dumpPointer(&TA);
3104 void WriteOccurenceList(StringRef Label,
3108 OS <<
" " << Label <<
"={"
3111 llvm::make_range(BV.set_bits_begin(), BV.set_bits_end()),
3112 [](
unsigned I) { return llvm::to_string(I); }),
3121 dump(llvm::errs(), Context);
3126 return DumpNormalizedConstraint(OS, Context).dump(*
this);
This file provides AST data structures related to concepts.
This file provides some common utility functions for processing Lambda related AST Constructs.
static void dump(llvm::raw_ostream &OS, StringRef FunctionName, ArrayRef< CounterExpression > Expressions, ArrayRef< CounterMappingRegion > Regions)
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)
Result
Implement __builtin_bit_cast and related operations.
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)
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
TemplateArgument getCanonicalTemplateArgument(const TemplateArgument &Arg) const
Retrieve the "canonical" template argument.
const TemplateArgument * getDefaultTemplateArgumentOrNone(const NamedDecl *P) const
Return the default argument of a template parameter, if one exists.
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
TemplateName getNamedConcept() const
SourceLocation getTemplateKWLoc() const
Represents the specialization of a concept - evaluates to a prvalue of type bool.
SourceLocation getBeginLoc() const LLVM_READONLY
ArrayRef< TemplateArgument > getTemplateArguments() const
const ASTTemplateArgumentListInfo * getTemplateArgsAsWritten() const
ConceptDecl * getConceptDecl() const
ConceptReference * getConceptReference() const
const ImplicitConceptSpecializationDecl * getSpecializationDecl() const
const ASTConstraintSatisfaction & getSatisfaction() const
Get elaborated satisfaction info about the template arguments' satisfaction of the named concept.
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()
NamedDecl * getFoundDecl()
Get the NamedDecl through which this reference occurred.
bool refersToEnclosingVariableOrCapture() const
Does this DeclRefExpr refer to an enclosing local or a captured variable?
DeclarationNameInfo getNameInfo() const
SourceLocation getTemplateKeywordLoc() const
Retrieve the location of the template keyword preceding this name, if any.
static DeclRefExpr * Create(const ASTContext &Context, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, ValueDecl *D, bool RefersToEnclosingVariableOrCapture, SourceLocation NameLoc, QualType T, ExprValueKind VK, NamedDecl *FoundD=nullptr, const TemplateArgumentListInfo *TemplateArgs=nullptr, NonOdrUseReason NOUR=NOUR_None)
NestedNameSpecifierLoc getQualifierLoc() const
If the name was qualified, retrieves the nested-name-specifier that precedes the name,...
const TemplateArgumentLoc * getTemplateArgs() const
Retrieve the template arguments provided as part of this template-id.
NonOdrUseReason isNonOdrUse() const
Is this expression a non-odr-use reference, and if so, why?
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.
bool isParameterPack() const
Whether this declaration is a parameter pack.
FunctionDecl * getAsFunction() LLVM_READONLY
Returns the function itself, or the templated function if this is a function template.
SourceLocation getLocation() const
DeclContext * getDeclContext()
DeclContext * getLexicalDeclContext()
getLexicalDeclContext - The declaration context where this Decl was lexically declared (LexicalDC).
SourceLocation getInnerLocStart() const
Return start of source range ignoring outer template declarations.
const AssociatedConstraint & getTrailingRequiresClause() const
Get the constraint-expression introduced by the trailing requires-clause in the function/member decla...
TypeSourceInfo * getTypeSourceInfo() const
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.
ExprValueKind getValueKind() const
getValueKind - The value kind that this expression produces.
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
void setRetainInnerDepths()
This represents a decl that may have a name.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
static NonTypeTemplateParmDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, int D, int P, const IdentifierInfo *Id, QualType T, bool ParameterPack, TypeSourceInfo *TInfo)
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...
const DeclContext * getDeclContext() const
const NamedDecl * getDecl() const
const DeclContext * getLexicalDeclContext() const
Sema - This implements semantic analysis and AST building for C.
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
llvm::DenseMap< llvm::FoldingSetNodeID, TemplateArgumentLoc > * CurrentCachedTemplateArgs
Cache the instantiation results of template parameter mappings within concepts.
TemplateArgumentLoc getTrivialTemplateArgumentLoc(const TemplateArgument &Arg, QualType NTTPType, SourceLocation Loc)
Allocate a TemplateArgumentLoc where all locations have been initialized to the given location.
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
void printPretty(raw_ostream &OS, PrinterHelper *Helper, const PrintingPolicy &Policy, unsigned Indentation=0, StringRef NewlineSymbol="\n", const ASTContext *Context=nullptr) 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.
TemplateDecl * getAsTemplateDecl(bool IgnoreDeduced=false) const
Retrieve the underlying template declaration that this template name refers to, if known.
bool isNull() const
Determine whether this template name is NULL.
Stores a list of template parameters for a TemplateDecl and its derived classes.
NamedDecl * getParam(unsigned Idx)
unsigned getMinRequiredArguments() const
Returns the minimum number of arguments needed to form a template specialization.
static TemplateParameterList * Create(const ASTContext &C, SourceLocation TemplateLoc, SourceLocation LAngleLoc, ArrayRef< NamedDecl * > Params, SourceLocation RAngleLoc, Expr *RequiresClause)
SourceLocation getLAngleLoc() const
SourceLocation getTemplateLoc() const
void dumpPointer(const void *Ptr)
void dumpSourceRange(SourceRange R)
void AddChild(Fn DoAddChild)
Add a child of the current node. Calls DoAddChild without arguments.
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.
@ OS
Indicates that the tracking object is a descendant of a referenced-counted OSObject,...
bool Sub(InterpState &S, CodePtr OpPC)
bool Add(InterpState &S, CodePtr OpPC)
Top level wrappers for InstallAPI frontend operations.
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.
OptionalUnsigned< unsigned > UnsignedOrNone
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
void dump(ASTContext &Context) const
SourceLocation getBeginLoc() const
llvm::SmallBitVector OccurenceList
constexpr underlying_type toInternalRepresentation() const
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.