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,
230 return inherited::RebuildPackExpansion(Pattern, EllipsisLoc, NumExpansions);
233 TemplateArgumentLoc RebuildPackExpansion(TemplateArgumentLoc Pattern,
234 SourceLocation EllipsisLoc,
236 if (!RemoveNonPackExpansionPacks)
237 return inherited::RebuildPackExpansion(Pattern, EllipsisLoc,
243 TemplateArgumentLoc &Out, UnexpandedInfo &Info) {
244 if (!RemoveNonPackExpansionPacks)
245 return inherited::PreparePackForExpansion(In, Uneval, Out, Info);
246 assert(
In.getArgument().isPackExpansion());
252 using inherited::TransformTemplateTypeParmType;
253 QualType TransformTemplateTypeParmType(TypeLocBuilder &TLB,
254 TemplateTypeParmTypeLoc TL,
bool) {
255 const TemplateTypeParmType *T = TL.
getTypePtr();
257 TemplateTypeParmDecl *NewTTPDecl =
nullptr;
258 if (TemplateTypeParmDecl *OldTTPDecl = T->getDecl())
259 NewTTPDecl = cast_or_null<TemplateTypeParmDecl>(
262 QualType
Result = getSema().Context.getTemplateTypeParmType(
263 T->getDepth() + TemplateDepth, T->getIndex(),
264 RemoveNonPackExpansionPacks ?
false : T->isParameterPack(), NewTTPDecl);
265 TemplateTypeParmTypeLoc NewTL = TLB.
push<TemplateTypeParmTypeLoc>(
Result);
270 bool AlreadyTransformed(QualType T) {
280 ExprResult TransformDeclRefExpr(DeclRefExpr *E) {
281 NonTypeTemplateParmDecl *NTTP =
282 dyn_cast<NonTypeTemplateParmDecl>(E->
getDecl());
284 return inherited::TransformDeclRefExpr(E);
287 "Template arguments for NTTP decl?");
311 using inherited = RecursiveASTVisitor<HashParameterMapping>;
315 const MultiLevelTemplateArgumentList &TemplateArgs;
316 llvm::FoldingSetNodeID &
ID;
317 llvm::SmallVector<TemplateArgument, 10> UsedTemplateArgs;
321 bool shouldVisitTemplateInstantiations()
const {
return true; }
324 HashParameterMapping(Sema &SemaRef,
325 const MultiLevelTemplateArgumentList &TemplateArgs,
326 llvm::FoldingSetNodeID &ID,
328 : SemaRef(SemaRef), TemplateArgs(TemplateArgs),
ID(
ID),
329 OuterPackSubstIndex(OuterPackSubstIndex) {}
331 bool VisitTemplateTypeParmType(TemplateTypeParmType *T) {
342 TemplateArgument Arg = TemplateArgs(T->getDepth(), T->getIndex());
348 if ((T->isParameterPack() ||
349 (T->getDecl() && T->getDecl()->isTemplateParameterPack())) &&
352 "Missing argument pack");
357 UsedTemplateArgs.push_back(
362 bool VisitDeclRefExpr(DeclRefExpr *E) {
364 NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(D);
366 return TraverseDecl(D);
377 "Missing argument pack");
381 UsedTemplateArgs.push_back(
386 bool VisitTypedefType(TypedefType *TT) {
387 return inherited::TraverseType(TT->
desugar());
390 bool TraverseDecl(Decl *D) {
391 if (
auto *VD = dyn_cast<ValueDecl>(D)) {
392 if (
auto *Var = dyn_cast<VarDecl>(VD))
393 TraverseStmt(Var->getInit());
394 return TraverseType(VD->getType());
397 return inherited::TraverseDecl(D);
400 bool TraverseCallExpr(CallExpr *CE) {
401 inherited::TraverseStmt(CE->
getCallee());
404 inherited::TraverseStmt(Arg);
409 bool TraverseCXXThisExpr(CXXThisExpr *E) {
410 return inherited::TraverseType(E->
getType());
413 bool TraverseTypeLoc(TypeLoc TL,
bool TraverseQualifier =
true) {
418 bool TraverseDependentNameType(
const DependentNameType *T,
420 return TraverseNestedNameSpecifier(T->getQualifier());
423 bool TraverseTagType(
const TagType *T,
bool TraverseQualifier) {
431 bool TraverseUnresolvedUsingType(UnresolvedUsingType *T,
432 bool TraverseQualifier) {
436 TraverseQualifier && NNS)
437 return inherited::TraverseNestedNameSpecifier(NNS);
438 return inherited::TraverseUnresolvedUsingType(T, TraverseQualifier);
441 bool TraverseInjectedClassNameType(InjectedClassNameType *T,
442 bool TraverseQualifier) {
443 return TraverseTemplateArguments(T->getTemplateArgs(SemaRef.
Context));
446 bool TraverseTemplateArgument(
const TemplateArgument &Arg) {
449 Sema::ArgPackSubstIndexRAII _1(SemaRef, std::nullopt);
450 llvm::SaveAndRestore<UnsignedOrNone>
_2(OuterPackSubstIndex,
452 return inherited::TraverseTemplateArgument(Arg);
455 Sema::ArgPackSubstIndexRAII _1(SemaRef, OuterPackSubstIndex);
456 return inherited::TraverseTemplateArgument(Arg);
459 bool TraverseSizeOfPackExpr(SizeOfPackExpr *SOPE) {
460 return TraverseDecl(SOPE->
getPack());
463 bool VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *E) {
468 if (
auto *TTP = dyn_cast_if_present<TemplateTemplateParmDecl>(
475 TemplateArgument Arg = TemplateArgs(TTP->getDepth(), TTP->getPosition());
478 "Missing argument pack");
482 "Null template template argument");
483 UsedTemplateArgs.push_back(
486 return inherited::TraverseTemplateName(
Template);
489 void VisitConstraint(
const NormalizedConstraintWithParamMapping &Constraint) {
491 for (
const auto &List : TemplateArgs)
492 for (
const TemplateArgument &Arg : List.Args)
498 llvm::ArrayRef<TemplateArgumentLoc> Mapping =
500 for (
auto &ArgLoc : Mapping) {
501 TemplateArgument Canonical =
504 UsedTemplateArgs.push_back(Canonical);
505 TraverseTemplateArgument(Canonical);
508 for (
auto &
Used : UsedTemplateArgs) {
509 llvm::FoldingSetNodeID
R;
516class ConstraintSatisfactionChecker {
519 const ConceptReference *TopLevelConceptId;
520 SourceLocation TemplateNameLoc;
522 ConstraintSatisfaction &Satisfaction;
523 bool BuildExpression;
526 ConceptDecl *ParentConcept =
nullptr;
530 llvm::DenseMap<llvm::FoldingSetNodeID, TemplateArgumentLoc>
534 template <
class Constra
int>
536 return C.getPackSubstitutionIndex() ?
C.getPackSubstitutionIndex()
537 : PackSubstitutionIndex;
541 EvaluateAtomicConstraint(
const Expr *AtomicExpr,
542 const MultiLevelTemplateArgumentList &MLTAL);
545 const FoldExpandedConstraint &FE,
546 const MultiLevelTemplateArgumentList &MLTAL);
549 std::optional<MultiLevelTemplateArgumentList> SubstitutionInTemplateArguments(
550 const NormalizedConstraintWithParamMapping &Constraint,
551 const MultiLevelTemplateArgumentList &MLTAL,
552 llvm::SmallVector<TemplateArgument> &SubstitutedOuterMost);
554 ExprResult EvaluateSlow(
const AtomicConstraint &Constraint,
555 const MultiLevelTemplateArgumentList &MLTAL);
558 const MultiLevelTemplateArgumentList &MLTAL);
560 ExprResult EvaluateSlow(
const FoldExpandedConstraint &Constraint,
561 const MultiLevelTemplateArgumentList &MLTAL);
564 const MultiLevelTemplateArgumentList &MLTAL);
566 ExprResult EvaluateSlow(
const ConceptIdConstraint &Constraint,
567 const MultiLevelTemplateArgumentList &MLTAL,
571 const MultiLevelTemplateArgumentList &MLTAL);
574 const MultiLevelTemplateArgumentList &MLTAL);
577 ConstraintSatisfactionChecker(Sema &SemaRef,
const NamedDecl *
Template,
578 const ConceptReference *TopLevelConceptId,
579 SourceLocation TemplateNameLoc,
581 ConstraintSatisfaction &Satisfaction,
582 bool BuildExpression)
584 TemplateNameLoc(TemplateNameLoc),
585 PackSubstitutionIndex(PackSubstitutionIndex),
586 Satisfaction(Satisfaction), BuildExpression(BuildExpression) {}
589 const MultiLevelTemplateArgumentList &MLTAL);
592StringRef allocateStringFromConceptDiagnostic(
const Sema &S,
602ExprResult ConstraintSatisfactionChecker::EvaluateAtomicConstraint(
604 llvm::FoldingSetNodeID
ID;
611 SatisfactionStackRAII StackRAII(S,
Template, ID);
622 if (Inst.isInvalid())
627 SubstitutedExpression =
630 if (SubstitutedExpression.
isInvalid() || Trap.hasErrorOccurred()) {
634 if (!Trap.hasErrorOccurred())
641 Info.takeSFINAEDiagnostic(SubstDiag);
648 Satisfaction.
Details.emplace_back(
651 allocateStringFromConceptDiagnostic(S, SubstDiag.second)});
673 SubstitutedExpression.
get(),
676 return SubstitutedExpression;
679std::optional<MultiLevelTemplateArgumentList>
680ConstraintSatisfactionChecker::SubstitutionInTemplateArguments(
703 if (Inst.isInvalid())
710 &CachedTemplateArgs);
725 TD->getLocation(), SubstArgs,
734 SubstitutedOutermost =
735 llvm::to_vector_of<TemplateArgument>(MLTAL.
getOutermost());
737 for (
unsigned I = 0, MappedIndex = 0; I <
Used.size(); I++) {
742 if (I < SubstitutedOutermost.size()) {
743 SubstitutedOutermost[I] = Arg;
746 SubstitutedOutermost.push_back(Arg);
747 Offset = SubstitutedOutermost.size();
750 if (Offset < SubstitutedOutermost.size())
751 SubstitutedOutermost.erase(SubstitutedOutermost.begin() + Offset);
756 return std::move(SubstitutedTemplateArgs);
759ExprResult ConstraintSatisfactionChecker::EvaluateSlow(
762 std::optional<EnterExpressionEvaluationContext> EvaluationContext;
766 EvaluationContext.emplace(
769 EvaluationContext.emplace(
774 std::optional<MultiLevelTemplateArgumentList> SubstitutedArgs =
775 SubstitutionInTemplateArguments(Constraint, MLTAL, SubstitutedOutermost);
776 if (!SubstitutedArgs) {
784 std::optional<Sema::ContextRAII> ConceptContext;
789 ExprResult SubstitutedAtomicExpr = EvaluateAtomicConstraint(
795 if (SubstitutedAtomicExpr.
isUnset())
809 Satisfaction.
Details.emplace_back(
811 SubstitutedAtomicExpr.get()->getBeginLoc(),
812 allocateStringFromConceptDiagnostic(S, Msg)});
813 return SubstitutedAtomicExpr;
819 return SubstitutedAtomicExpr;
824 EvalResult.
Diag = &EvaluationDiags;
827 !EvaluationDiags.empty()) {
831 diag::err_non_constant_constraint_expression)
834 S.
Diag(PDiag.first, PDiag.second);
839 "evaluating bool expression didn't produce int");
842 Satisfaction.
Details.emplace_back(SubstitutedAtomicExpr.
get());
844 return SubstitutedAtomicExpr;
847ExprResult ConstraintSatisfactionChecker::Evaluate(
852 llvm::FoldingSetNodeID
ID;
853 UnsignedOrNone OuterPackSubstIndex = getOuterPackIndex(Constraint);
857 HashParameterMapping(S, MLTAL, ID, OuterPackSubstIndex)
858 .VisitConstraint(Constraint);
862 auto &Cached = Iter->second.Satisfaction;
866 Cached.Details.begin(), Cached.Details.end());
867 return Iter->second.SubstExpr;
870 ExprResult E = EvaluateSlow(Constraint, MLTAL);
875 Cache.Satisfaction.Details.insert(
Cache.Satisfaction.Details.end(),
876 Satisfaction.
Details.begin() + Size,
885ConstraintSatisfactionChecker::EvaluateFoldExpandedConstraintSize(
893 assert(!Unexpanded.empty() &&
"Pack expansion without parameter packs?");
895 bool RetainExpansion =
false;
899 false, Expand, RetainExpansion,
900 NumExpansions,
false) ||
901 !Expand || RetainExpansion)
904 if (NumExpansions && S.
getLangOpts().BracketDepth < *NumExpansions)
906 return NumExpansions;
909ExprResult ConstraintSatisfactionChecker::EvaluateSlow(
915 unsigned EffectiveDetailEndIndex = Satisfaction.
Details.size();
920 std::optional<MultiLevelTemplateArgumentList> SubstitutedArgs =
921 SubstitutionInTemplateArguments(
923 MLTAL, SubstitutedOutermost);
924 if (!SubstitutedArgs) {
931 EvaluateFoldExpandedConstraintSize(Constraint, *SubstitutedArgs);
935 if (*NumExpansions == 0) {
940 for (
unsigned I = 0; I < *NumExpansions; I++) {
945 ConstraintSatisfactionChecker(S,
Template, TopLevelConceptId,
950 if (BuildExpression) {
951 if (
Out.isUnset() || !
Expr.isUsable())
955 Conjunction ? BinaryOperatorKind::BO_LAnd
956 : BinaryOperatorKind::BO_LOr,
963 EffectiveDetailEndIndex,
974ExprResult ConstraintSatisfactionChecker::Evaluate(
978 llvm::FoldingSetNodeID
ID;
980 HashParameterMapping(S, MLTAL, ID, std::nullopt).VisitConstraint(Constraint);
985 auto &Cached = Iter->second.Satisfaction;
989 Cached.Details.begin(), Cached.Details.end());
990 return Iter->second.SubstExpr;
995 ExprResult E = EvaluateSlow(Constraint, MLTAL);
999 Cache.Satisfaction.Details.insert(
Cache.Satisfaction.Details.end(),
1000 Satisfaction.
Details.begin() + Size,
1002 Cache.SubstExpr = E;
1007ExprResult ConstraintSatisfactionChecker::EvaluateSlow(
1013 std::optional<MultiLevelTemplateArgumentList> SubstitutedArgs =
1014 SubstitutionInTemplateArguments(Constraint, MLTAL, SubstitutedOutermost);
1016 if (!SubstitutedArgs) {
1036 if (TopLevelConceptId &&
1039 OutArgs.addArgument(A);
1042 Trap.hasErrorOccurred()) {
1044 if (!Trap.hasErrorOccurred())
1049 Info.takeSFINAEDiagnostic(SubstDiag);
1057 Satisfaction.
Details.begin() + Size,
1060 allocateStringFromConceptDiagnostic(S, SubstDiag.second)});
1072 if (SubstitutedConceptId.
isInvalid() || Trap.hasErrorOccurred())
1075 if (Size != Satisfaction.
Details.size()) {
1077 Satisfaction.
Details.begin() + Size,
1082 return SubstitutedConceptId;
1085ExprResult ConstraintSatisfactionChecker::Evaluate(
1102 if (InstTemplate.isInvalid())
1113 Satisfaction.
Details.insert(Satisfaction.
Details.begin() + Size, ConceptId);
1123 UnsignedOrNone OuterPackSubstIndex = getOuterPackIndex(Constraint);
1124 llvm::FoldingSetNodeID
ID;
1127 HashParameterMapping(S, MLTAL, ID, OuterPackSubstIndex)
1128 .VisitConstraint(Constraint);
1133 auto &Cached = Iter->second.Satisfaction;
1137 Cached.Details.begin(), Cached.Details.end());
1138 return Iter->second.SubstExpr;
1141 ExprResult CE = EvaluateSlow(Constraint, MLTAL, Size);
1147 Cache.Satisfaction.Details.insert(
Cache.Satisfaction.Details.end(),
1148 Satisfaction.
Details.begin() + Size,
1150 Cache.SubstExpr = CE;
1155ExprResult ConstraintSatisfactionChecker::Evaluate(
1159 unsigned EffectiveDetailEndIndex = Satisfaction.
Details.size();
1181 EffectiveDetailEndIndex,
1184 if (!BuildExpression)
1194 Conjunction ? BinaryOperatorKind::BO_LAnd
1195 : BinaryOperatorKind::BO_LOr,
1200ExprResult ConstraintSatisfactionChecker::Evaluate(
1203 switch (Constraint.
getKind()) {
1218 llvm_unreachable(
"Unknown ConstraintKind enum");
1229 *ConvertedExpr =
nullptr;
1231 if (AssociatedConstraints.empty()) {
1251 struct SynthesisContextPair {
1257 : Inst(S, InstantiationRange.
getBegin(),
1259 TemplateArgs, InstantiationRange),
1262 std::optional<SynthesisContextPair> SynthesisContext;
1263 if (!TopLevelConceptId)
1274 if (TopLevelConceptId)
1281 ConstraintSatisfactionChecker(
1284 ConvertedExpr !=
nullptr)
1285 .Evaluate(*
C, TemplateArgsLists);
1290 if (Res.
isUsable() && ConvertedExpr)
1291 *ConvertedExpr = Res.
get();
1302 llvm::TimeTraceScope TimeScope(
1303 "CheckConstraintSatisfaction", [TemplateIDRange,
this] {
1306 if (AssociatedConstraints.empty()) {
1312 return ::CheckConstraintSatisfaction(
1313 *
this,
nullptr, AssociatedConstraints, TemplateArgsLists,
1314 TemplateIDRange, OutSatisfaction, ConvertedExpr, TopLevelConceptId);
1328 for (
auto List : TemplateArgsLists)
1330 FlattenedArgs.emplace_back(
Context.getCanonicalTemplateArgument(Arg));
1333 if (TopLevelConceptId)
1336 llvm::FoldingSetNodeID ID;
1339 if (
auto *Cached = SatisfactionCache.FindNodeOrInsertPos(ID, InsertPos)) {
1340 OutSatisfaction = *Cached;
1345 std::make_unique<ConstraintSatisfaction>(Owner, FlattenedArgs);
1347 *
this,
Template, AssociatedConstraints, TemplateArgsLists,
1348 TemplateIDRange, *Satisfaction, ConvertedExpr, TopLevelConceptId)) {
1349 OutSatisfaction = std::move(*Satisfaction);
1353 if (
auto *Cached = SatisfactionCache.FindNodeOrInsertPos(ID, InsertPos)) {
1362 OutSatisfaction = *Cached;
1367 OutSatisfaction = *Satisfaction;
1371 SatisfactionCache.InsertNode(Satisfaction.release());
1393 return !ArgLoc.getArgument().isDependent() &&
1394 ArgLoc.getArgument().isConceptOrConceptTemplateParameter();
1396 return Concept->getConstraintExpr();
1409bool Sema::SetupConstraintScope(
1414 "Use LambdaScopeForCallOperatorInstantiationRAII to handle lambda "
1420 Sema::InstantiatingTemplate::ConstraintsCheck{}, PrimaryTemplate,
1421 TemplateArgs ? *TemplateArgs : ArrayRef<TemplateArgument>{},
1423 if (Inst.isInvalid())
1432 MultiLevelTemplateArgumentList JustTemplArgs(FD, SpecArgs->asArray(),
1434 if (addInstantiatedParametersToScope(
1441 if (FunctionTemplateDecl *FromMemTempl =
1443 if (addInstantiatedParametersToScope(FD, FromMemTempl->getTemplatedDecl(),
1453 FunctionDecl *InstantiatedFrom =
1460 Sema::InstantiatingTemplate::ConstraintsCheck{}, InstantiatedFrom,
1461 TemplateArgs ? *TemplateArgs : ArrayRef<TemplateArgument>{},
1463 if (Inst.isInvalid())
1468 if (addInstantiatedParametersToScope(FD, InstantiatedFrom, Scope, MLTAL))
1477std::optional<MultiLevelTemplateArgumentList>
1478Sema::SetupConstraintCheckingTemplateArgumentsAndScope(
1481 MultiLevelTemplateArgumentList MLTAL;
1488 false, std::nullopt,
1495 if (SetupConstraintScope(FD, TemplateArgs, MLTAL, Scope))
1496 return std::nullopt;
1504 bool ForOverloadResolution) {
1523 if (
const auto *MD = dyn_cast<CXXConversionDecl>(FD);
1526 Satisfaction, UsageLoc,
1540 std::optional<MultiLevelTemplateArgumentList> MLTAL =
1541 SetupConstraintCheckingTemplateArgumentsAndScope(
1549 if (
auto *
Method = dyn_cast<CXXMethodDecl>(FD)) {
1550 ThisQuals =
Method->getMethodQualifiers();
1557 ForOverloadResolution);
1567 const Expr *ConstrExpr) {
1582 std::optional<LocalInstantiationScope> ScopeForParameters;
1585 ScopeForParameters.emplace(S,
true);
1589 FD =
Template->getInstantiatedFromMemberTemplate()->getTemplatedDecl();
1591 if (ScopeForParameters->getInstantiationOfIfExists(PVD))
1593 if (!PVD->isParameterPack()) {
1594 ScopeForParameters->InstantiatedLocal(PVD, PVD);
1613 ScopeForParameters->MakeInstantiatedLocalArgPack(PVD);
1614 ScopeForParameters->InstantiatedLocalPackArg(PVD, PVD);
1618 std::optional<Sema::CXXThisScopeRAII> ThisScope;
1627 std::optional<Sema::ContextRAII> ContextScope;
1635 if (
auto *RD = dyn_cast<CXXRecordDecl>(DC)) {
1647 return SubstConstr.
get();
1651 const Expr *OldConstr,
1653 const Expr *NewConstr) {
1654 if (OldConstr == NewConstr)
1657 if (Old && !
New.isInvalid() && !
New.ContainsDecl(Old) &&
1660 if (
const Expr *SubstConstr =
1663 OldConstr = SubstConstr;
1666 if (
const Expr *SubstConstr =
1669 NewConstr = SubstConstr;
1674 llvm::FoldingSetNodeID ID1, ID2;
1687 "Non-function templates don't need to be checked");
1708 TemplateIDRange, Satisfaction))
1713 TemplateArgString =
" ";
1719 diag::err_template_arg_list_constraints_not_satisfied)
1721 << TemplateArgString << TemplateIDRange;
1733 Template->getAssociatedConstraints(TemplateAC);
1734 if (TemplateAC.empty()) {
1753 SemaRef, PointOfInstantiation,
1755 PointOfInstantiation);
1756 if (Inst.isInvalid())
1766 Template, TemplateAC, MLTAL, PointOfInstantiation, Satisfaction);
1777 return ::CheckFunctionConstraintsWithoutInstantiation(
1778 *
this, PointOfInstantiation,
Decl->getDescribedFunctionTemplate(),
1779 TemplateArgs, Satisfaction);
1784 Template->getAssociatedConstraints(TemplateAC);
1785 if (TemplateAC.empty()) {
1795 std::optional<MultiLevelTemplateArgumentList> MLTAL =
1796 SetupConstraintCheckingTemplateArgumentsAndScope(
Decl, TemplateArgs,
1804 if (
auto *
Method = dyn_cast<CXXMethodDecl>(
Decl)) {
1805 ThisQuals =
Method->getMethodQualifiers();
1814 PointOfInstantiation, Satisfaction);
1821 "Diagnose() can only be used on an unsatisfied requirement");
1824 llvm_unreachable(
"Diagnosing a dependent requirement");
1828 if (!SubstDiag->DiagMessage.empty())
1829 S.
Diag(SubstDiag->DiagLoc,
1830 diag::note_expr_requirement_expr_substitution_error)
1831 << (
int)
First << SubstDiag->SubstitutedEntity
1832 << SubstDiag->DiagMessage;
1834 S.
Diag(SubstDiag->DiagLoc,
1835 diag::note_expr_requirement_expr_unknown_substitution_error)
1836 << (
int)
First << SubstDiag->SubstitutedEntity;
1846 if (!SubstDiag->DiagMessage.empty())
1847 S.
Diag(SubstDiag->DiagLoc,
1848 diag::note_expr_requirement_type_requirement_substitution_error)
1849 << (
int)
First << SubstDiag->SubstitutedEntity
1850 << SubstDiag->DiagMessage;
1855 note_expr_requirement_type_requirement_unknown_substitution_error)
1856 << (
int)
First << SubstDiag->SubstitutedEntity;
1866 llvm_unreachable(
"We checked this above");
1874 "Diagnose() can only be used on an unsatisfied requirement");
1877 llvm_unreachable(
"Diagnosing a dependent requirement");
1881 if (!SubstDiag->DiagMessage.empty())
1882 S.
Diag(SubstDiag->DiagLoc, diag::note_type_requirement_substitution_error)
1883 << (
int)
First << SubstDiag->SubstitutedEntity
1884 << SubstDiag->DiagMessage;
1886 S.
Diag(SubstDiag->DiagLoc,
1887 diag::note_type_requirement_unknown_substitution_error)
1888 << (
int)
First << SubstDiag->SubstitutedEntity;
1892 llvm_unreachable(
"Unknown satisfaction status");
1900 if (
Concept->getTemplateArgsAsWritten()->NumTemplateArgs == 1) {
1904 note_single_arg_concept_specialization_constraint_evaluated_to_false)
1906 <<
Concept->getTemplateArgsAsWritten()->arguments()[0].getArgument()
1907 <<
Concept->getNamedConcept();
1909 S.
Diag(Loc, diag::note_concept_specialization_constraint_evaluated_to_false)
1939 const Expr *SubstExpr,
1942 if (
const BinaryOperator *BO = dyn_cast<BinaryOperator>(SubstExpr)) {
1943 switch (BO->getOpcode()) {
1955 BO->getLHS()->EvaluateKnownConstInt(S.
Context).getBoolValue();
1966 BO->getRHS()->EvaluateKnownConstInt(S.
Context).getBoolValue();
1978 if (BO->getLHS()->getType()->isIntegerType() &&
1979 BO->getRHS()->getType()->isIntegerType()) {
1982 BO->getLHS()->EvaluateAsInt(SimplifiedLHS, S.
Context,
1985 BO->getRHS()->EvaluateAsInt(SimplifiedRHS, S.
Context,
1988 if (!SimplifiedLHS.
Diag && !SimplifiedRHS.
Diag) {
1990 diag::note_atomic_constraint_evaluated_to_false_elaborated)
2003 }
else if (
auto *RE = dyn_cast<RequiresExpr>(SubstExpr)) {
2006 if (!Req->isDependent() && !Req->isSatisfied()) {
2007 if (
auto *E = dyn_cast<concepts::ExprRequirement>(Req))
2009 else if (
auto *T = dyn_cast<concepts::TypeRequirement>(Req))
2017 }
else if (
auto *CSE = dyn_cast<ConceptSpecializationExpr>(SubstExpr)) {
2021 }
else if (
auto *TTE = dyn_cast<TypeTraitExpr>(SubstExpr);
2022 TTE && TTE->getTrait() == clang::TypeTrait::BTT_IsDeducible) {
2023 assert(TTE->getNumArgs() == 2);
2025 diag::note_is_deducible_constraint_evaluated_to_false)
2026 << TTE->getArg(0)->getType() << TTE->getArg(1)->getType();
2031 diag::note_atomic_constraint_evaluated_to_false)
2041 .
template dyn_cast<const ConstraintSubstitutionDiagnostic *>()) {
2043 S.
Diag(
Diag->first, diag::note_nested_requirement_substitution_error)
2046 S.
Diag(
Diag->first, diag::note_substituted_constraint_expr_is_ill_formed)
2050 if (
const auto *
Concept = dyn_cast<const ConceptReference *>(
Record)) {
2065 "Attempted to diagnose a satisfied constraint");
2076 "Attempted to diagnose a satisfied constraint");
2084class SubstituteParameterMappings {
2096 bool RemovePacksForFoldExpr;
2098 SubstituteParameterMappings(
Sema &SemaRef,
2101 bool RemovePacksForFoldExpr)
2102 : SemaRef(SemaRef), MLTAL(MLTAL), ArgsAsWritten(ArgsAsWritten),
2103 RemovePacksForFoldExpr(RemovePacksForFoldExpr) {}
2112 SubstituteParameterMappings(
Sema &SemaRef,
2113 bool RemovePacksForFoldExpr =
false)
2115 RemovePacksForFoldExpr(RemovePacksForFoldExpr) {}
2117 bool substitute(NormalizedConstraint &N);
2120void SubstituteParameterMappings::buildParameterMapping(
2125 llvm::SmallBitVector OccurringIndices(TemplateParams->
size());
2126 llvm::SmallBitVector OccurringIndicesForSubsumption(TemplateParams->
size());
2132 0, OccurringIndices);
2136 0, OccurringIndicesForSubsumption);
2143 0, OccurringIndices);
2147 ->getTemplateArgsAsWritten();
2150 0, OccurringIndices);
2158 I < TemplateParams->size(); ++I) {
2164 assert(Arg &&
"expected a default argument");
2165 DefaultArgs.emplace_back(std::move(*Arg));
2170 OccurringIndicesForSubsumption);
2173 unsigned Size = OccurringIndices.count();
2181 for (
unsigned I = 0, J = 0,
C = TemplateParams->
size(); I !=
C; ++I) {
2183 ? ArgsAsWritten->arguments()[I].getLocation()
2187 if (OccurringIndices[I]) {
2191 UsedParams.push_back(Param);
2201 std::move(OccurringIndices), std::move(OccurringIndicesForSubsumption),
2205bool SubstituteParameterMappings::substitute(
2208 buildParameterMapping(N);
2217 InstLocBegin = ArgsAsWritten->getLAngleLoc();
2218 InstLocEnd = ArgsAsWritten->getRAngleLoc();
2220 auto SR =
Arguments[0].getSourceRange();
2221 InstLocBegin = SR.getBegin();
2222 InstLocEnd = SR.getEnd();
2226 SemaRef, InstLocBegin,
2229 {InstLocBegin, InstLocEnd});
2230 if (Inst.isInvalid())
2247 TD->getLocation(), SubstArgs,
2258 if (I < SubstArgs.
size())
2259 Loc = SubstArgs.
arguments()[I].getLocation();
2286 InstLocBegin = ArgsAsWritten->getLAngleLoc();
2287 InstLocEnd = ArgsAsWritten->getRAngleLoc();
2289 auto SR =
Arguments[0].getSourceRange();
2290 InstLocBegin = SR.getBegin();
2291 InstLocEnd = SR.getEnd();
2296 SemaRef, InstLocBegin,
2299 {InstLocBegin, InstLocEnd});
2300 if (Inst.isInvalid())
2311 CSE->getTemplateArgsAsWritten();
2317 CSE->getConceptNameInfo().getLoc(), Out,
2322 auto TemplateArgs = *MLTAL;
2325 return SubstituteParameterMappings(SemaRef, &TemplateArgs, ArgsAsWritten,
2326 RemovePacksForFoldExpr)
2334 assert(!ArgsAsWritten);
2343 assert(!ArgsAsWritten);
2348 return SubstituteParameterMappings(SemaRef,
true)
2354 assert(ArgsAsWritten);
2355 return substitute(CC);
2357 assert(!ArgsAsWritten);
2369 if (RemovePacksForFoldExpr) {
2373 if (AdjustConstraints(SemaRef, 0,
2375 .TransformTemplateArguments(InputArgLoc.begin(),
2376 InputArgLoc.end(), OutArgs))
2397 return SubstituteParameterMappings(SemaRef, &MLTAL,
2399 RemovePacksForFoldExpr)
2404 if (substitute(Compound.getLHS()))
2406 return substitute(Compound.getRHS());
2409 llvm_unreachable(
"Unknown ConstraintKind enum");
2416 assert(ACs.size() != 0);
2418 fromConstraintExpr(S, D, ACs[0].ConstraintExpr, ACs[0].ArgPackSubstIndex);
2421 for (
unsigned I = 1; I < ACs.size(); ++I) {
2422 auto *
Next = fromConstraintExpr(S, D, ACs[I].ConstraintExpr,
2423 ACs[I].ArgPackSubstIndex);
2434 assert(E !=
nullptr);
2442 llvm::FoldingSetNodeID
ID;
2446 SatisfactionStackRAII StackRAII(S, D, ID);
2453 if (LogicalBinOp BO = E) {
2454 auto *LHS = fromConstraintExpr(S, D, BO.getLHS(), SubstIndex);
2457 auto *RHS = fromConstraintExpr(S, D, BO.getRHS(), SubstIndex);
2464 if (
auto *CSE = dyn_cast<const ConceptSpecializationExpr>(E)) {
2480 SubNF = NormalizedConstraint::fromAssociatedConstraints(
2482 AssociatedConstraint(Res.get(), SubstIndex));
2489 if (
auto *FE = dyn_cast<const CXXFoldExpr>(E);
2491 (FE->getOperator() == BinaryOperatorKind::BO_LAnd ||
2492 FE->getOperator() == BinaryOperatorKind::BO_LOr)) {
2497 FE->getOperator() == BinaryOperatorKind::BO_LAnd
2501 if (FE->getInit()) {
2502 auto *LHS = fromConstraintExpr(S, D, FE->getLHS(), SubstIndex);
2503 auto *RHS = fromConstraintExpr(S, D, FE->getRHS(), SubstIndex);
2507 if (FE->isRightFold())
2520 auto *
Sub = fromConstraintExpr(S, D, FE->
getPattern(), SubstIndex);
2532 if (!ConstrainedDeclOrNestedReq) {
2533 auto *Normalized = NormalizedConstraint::fromAssociatedConstraints(
2534 *
this,
nullptr, AssociatedConstraints);
2536 SubstituteParameterMappings(*this).substitute(*Normalized))
2544 ConstrainedDeclOrNestedReq.dyn_cast<
const NamedDecl *>();
2545 auto CacheEntry = NormalizationCache.find(ConstrainedDeclOrNestedReq);
2546 if (CacheEntry == NormalizationCache.end()) {
2547 auto *Normalized = NormalizedConstraint::fromAssociatedConstraints(
2548 *
this, ND, AssociatedConstraints);
2550 NormalizationCache.try_emplace(ConstrainedDeclOrNestedReq,
nullptr);
2554 bool Failed = SubstituteParameterMappings(*this).substitute(*Normalized);
2556 NormalizationCache.try_emplace(ConstrainedDeclOrNestedReq, Normalized)
2561 return CacheEntry->second;
2584 if (It != BPacks.end())
2596 if (
const auto *FD1 = dyn_cast<FunctionDecl>(D1)) {
2602 const auto *FD2 = dyn_cast<FunctionDecl>(D2);
2603 assert(IsExpectedEntity(FD1) && FD2 && IsExpectedEntity(FD2) &&
2604 "use non-instantiated function declaration for constraints partial "
2619 std::pair<const NamedDecl *, const NamedDecl *> Key{D1, D2};
2620 auto CacheEntry = SubsumptionCache.find(Key);
2621 if (CacheEntry != SubsumptionCache.end()) {
2622 Result = CacheEntry->second;
2629 for (
size_t I = 0; I != AC1.size() && I != AC2.size(); ++I) {
2630 if (Depth2 > Depth1) {
2631 AC1[I].ConstraintExpr =
2632 AdjustConstraints(*
this, Depth2 - Depth1)
2633 .TransformExpr(
const_cast<Expr *
>(AC1[I].ConstraintExpr))
2635 }
else if (Depth1 > Depth2) {
2636 AC2[I].ConstraintExpr =
2637 AdjustConstraints(*
this, Depth1 - Depth2)
2638 .TransformExpr(
const_cast<Expr *
>(AC2[I].ConstraintExpr))
2647 const NamedDecl *DeclAC1 = D1, *DeclAC2 = D2;
2648 if (Depth2 > Depth1)
2650 else if (Depth1 > Depth2)
2652 std::optional<bool> Subsumes = SC.
Subsumes(DeclAC1, AC1, DeclAC2, AC2);
2658 SubsumptionCache.try_emplace(Key, *Subsumes);
2669 if (AC1.empty() || AC2.empty())
2672 const Expr *AmbiguousAtomic1 =
nullptr, *AmbiguousAtomic2 =
nullptr;
2683 llvm::FoldingSetNodeID IDA, IDB;
2685 EB->Profile(IDB,
Context,
true);
2689 AmbiguousAtomic1 = EA;
2690 AmbiguousAtomic2 = EB;
2705 bool Is1AtLeastAs2Normally = SC.
Subsumes(Normalized1, Normalized2);
2706 bool Is2AtLeastAs1Normally = SC.
Subsumes(Normalized2, Normalized1);
2709 bool Is1AtLeastAs2 = SC2.
Subsumes(Normalized1, Normalized2);
2710 bool Is2AtLeastAs1 = SC2.
Subsumes(Normalized2, Normalized1);
2712 if (Is1AtLeastAs2 == Is1AtLeastAs2Normally &&
2713 Is2AtLeastAs1 == Is2AtLeastAs1Normally)
2718 assert(AmbiguousAtomic1 && AmbiguousAtomic2);
2720 Diag(AmbiguousAtomic1->
getBeginLoc(), diag::note_ambiguous_atomic_constraints)
2722 Diag(AmbiguousAtomic2->getBeginLoc(),
2723 diag::note_ambiguous_atomic_constraints_similar_expression)
2724 << AmbiguousAtomic2->getSourceRange();
2735 : SemaRef(SemaRef), Callable(Callable), NextID(1) {}
2737uint16_t SubsumptionChecker::getNewLiteralId() {
2738 assert((
unsigned(NextID) + 1 < std::numeric_limits<uint16_t>::max()) &&
2739 "too many constraints!");
2744 auto &Elems = AtomicMap[Ori->getConstraintExpr()];
2759 llvm::FoldingSetNodeID ID;
2760 ID.AddBoolean(Ori->hasParameterMapping());
2761 if (Ori->hasParameterMapping()) {
2762 const auto &Mapping = Ori->getParameterMapping();
2764 Ori->mappingOccurenceListForSubsumption();
2765 for (
auto [Idx, TAL] : llvm::enumerate(Mapping)) {
2772 auto It = Elems.find(ID);
2773 if (It == Elems.end()) {
2776 MappedAtomicConstraint{
2777 Ori, {getNewLiteralId(), Literal::Atomic}}})
2779 ReverseMap[It->second.ID.Value] = Ori;
2781 return It->getSecond().ID;
2785 auto &Elems = FoldMap[Ori->getPattern()];
2787 FoldExpendedConstraintKey K;
2788 K.Kind = Ori->getFoldOperator();
2790 auto It = llvm::find_if(Elems, [&K](
const FoldExpendedConstraintKey &
Other) {
2791 return K.Kind ==
Other.Kind;
2793 if (It == Elems.end()) {
2794 K.ID = {getNewLiteralId(), Literal::FoldExpanded};
2795 It = Elems.insert(Elems.end(), std::move(K));
2796 ReverseMap[It->ID.Value] = Ori;
2802 return SubsumptionChecker::Normalize<CNFFormula>(
C);
2805 return SubsumptionChecker::Normalize<DNFFormula>(
C);
2821template <
typename FormulaType>
2825 auto Add = [&,
this](Clause
C) {
2828 C.erase(llvm::unique(
C),
C.end());
2829 AddUniqueClauseToFormula(Res, std::move(
C));
2834 return {{find(&
static_cast<const AtomicConstraint &
>(NC))}};
2837 return {{find(&
static_cast<const FoldExpandedConstraint &
>(NC))}};
2840 return Normalize<FormulaType>(
2841 static_cast<const ConceptIdConstraint &
>(NC).getNormalizedConstraint());
2844 const auto &Compound =
static_cast<const CompoundConstraint &
>(NC);
2846 SemaRef.runWithSufficientStackSpace(SourceLocation(), [&] {
2847 Left = Normalize<FormulaType>(Compound.getLHS());
2848 Right = Normalize<FormulaType>(Compound.getRHS());
2851 if (Compound.getCompoundKind() == FormulaType::Kind) {
2852 unsigned SizeLeft =
Left.size();
2853 Res = std::move(Left);
2854 Res.reserve(SizeLeft +
Right.size());
2855 std::for_each(std::make_move_iterator(
Right.begin()),
2856 std::make_move_iterator(
Right.end()), Add);
2860 Res.reserve(
Left.size() *
Right.size());
2861 for (
const auto <ransform : Left) {
2862 for (
const auto &RTransform : Right) {
2864 Combined.reserve(LTransform.size() + RTransform.size());
2865 llvm::copy(LTransform, std::back_inserter(Combined));
2866 llvm::copy(RTransform, std::back_inserter(Combined));
2867 Add(std::move(Combined));
2873 llvm_unreachable(
"Unknown ConstraintKind enum");
2876void SubsumptionChecker::AddUniqueClauseToFormula(Formula &F, Clause
C) {
2877 for (
auto &
Other : F) {
2878 if (llvm::equal(
C,
Other))
2888 SemaRef.getNormalizedAssociatedConstraints(DP, P);
2890 return std::nullopt;
2893 SemaRef.getNormalizedAssociatedConstraints(DQ, Q);
2895 return std::nullopt;
2897 return Subsumes(PNormalized, QNormalized);
2903 DNFFormula DNFP = DNF(*P);
2904 CNFFormula CNFQ = CNF(*Q);
2909 const CNFFormula &QCNF) {
2910 for (
const auto &Pi : PDNF) {
2911 for (
const auto &Qj : QCNF) {
2917 if (!DNFSubsumes(Pi, Qj))
2924bool SubsumptionChecker::DNFSubsumes(
const Clause &P,
const Clause &Q) {
2926 return llvm::any_of(P, [&](Literal LP) {
2927 return llvm::any_of(Q, [
this, LP](Literal LQ) {
return Subsumes(LP, LQ); });
2933 std::pair<const FoldExpandedConstraint *, const FoldExpandedConstraint *> Key{
2936 auto It = FoldSubsumptionCache.find(Key);
2937 if (It == FoldSubsumptionCache.end()) {
2946 It = FoldSubsumptionCache.try_emplace(std::move(Key), DoesSubsume).first;
2952 if (A.Kind != B.Kind)
2955 case Literal::Atomic:
2957 return A.Value == B.Value;
2959 *
static_cast<const AtomicConstraint *
>(ReverseMap[A.Value]),
2960 *
static_cast<const AtomicConstraint *
>(ReverseMap[B.Value]));
2961 case Literal::FoldExpanded:
2963 static_cast<const FoldExpandedConstraint *
>(ReverseMap[A.Value]),
2964 static_cast<const FoldExpandedConstraint *
>(ReverseMap[B.Value]));
2966 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)
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)
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
TemplateDecl * 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
ConceptReference * getConceptReference() const
const ImplicitConceptSpecializationDecl * getSpecializationDecl() 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()
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.
const NamedDecl * getConstraintDecl() const
bool hasMatchingParameterMapping(ASTContext &C, const NormalizedConstraint &Other) const
const OccurenceList & mappingOccurenceList() const
const OccurenceList & mappingOccurenceListForSubsumption() const
TemplateParameterList * getUsedTemplateParamList() const
llvm::MutableArrayRef< TemplateArgumentLoc > getParameterMapping() const
bool hasParameterMapping() const
void updateParameterMapping(OccurenceList Indexes, OccurenceList IndexesForSubsumption, llvm::MutableArrayRef< TemplateArgumentLoc > Args, TemplateParameterList *ParamList)
A (possibly-)qualified type.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
QualType getCanonicalType() const
The collection of all-type qualifiers we support.
A class that does preorder or postorder depth-first traversal on the entire Clang AST and visits each...
Scope - A scope is a transient data structure that is used while parsing the program.
PartialDiagnostic PDiag(unsigned DiagID=0)
Build a partial diagnostic.
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
Emit a diagnostic.
RAII object used to change the argument pack substitution index within a Sema object.
RAII object used to temporarily allow the C++ 'this' expression to be used, with the given qualifiers...
RAII class used to determine whether SFINAE has trapped any errors that occur during template argumen...
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
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.
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
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
UnresolvedUsingTypenameDecl * getDecl() const
NestedNameSpecifier getQualifier() const
Retrieve the nested-name-specifier that qualifies the name.
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.
OptionalUnsigned< unsigned > UnsignedOrNone
@ 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
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.