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) {
286 using inherited = RecursiveASTVisitor<HashParameterMapping>;
290 const MultiLevelTemplateArgumentList &TemplateArgs;
291 llvm::FoldingSetNodeID &
ID;
292 llvm::SmallVector<TemplateArgument, 10> UsedTemplateArgs;
296 bool shouldVisitTemplateInstantiations()
const {
return true; }
299 HashParameterMapping(Sema &SemaRef,
300 const MultiLevelTemplateArgumentList &TemplateArgs,
301 llvm::FoldingSetNodeID &ID,
303 : SemaRef(SemaRef), TemplateArgs(TemplateArgs),
ID(
ID),
304 OuterPackSubstIndex(OuterPackSubstIndex) {}
306 bool VisitTemplateTypeParmType(TemplateTypeParmType *T) {
317 TemplateArgument Arg = TemplateArgs(T->getDepth(), T->getIndex());
323 if ((T->isParameterPack() ||
324 (T->getDecl() && T->getDecl()->isTemplateParameterPack())) &&
327 "Missing argument pack");
332 UsedTemplateArgs.push_back(
337 bool VisitDeclRefExpr(DeclRefExpr *E) {
339 NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(D);
341 return TraverseDecl(D);
352 "Missing argument pack");
356 UsedTemplateArgs.push_back(
361 bool VisitTypedefType(TypedefType *TT) {
362 return inherited::TraverseType(TT->
desugar());
365 bool TraverseDecl(Decl *D) {
366 if (
auto *VD = dyn_cast<ValueDecl>(D)) {
367 if (
auto *Var = dyn_cast<VarDecl>(VD))
368 TraverseStmt(Var->getInit());
369 return TraverseType(VD->getType());
372 return inherited::TraverseDecl(D);
375 bool TraverseCallExpr(CallExpr *CE) {
376 inherited::TraverseStmt(CE->
getCallee());
379 inherited::TraverseStmt(Arg);
384 bool TraverseCXXThisExpr(CXXThisExpr *E) {
385 return inherited::TraverseType(E->
getType());
388 bool TraverseTypeLoc(TypeLoc TL,
bool TraverseQualifier =
true) {
393 bool TraverseDependentNameType(
const DependentNameType *T,
395 return TraverseNestedNameSpecifier(T->getQualifier());
398 bool TraverseTagType(
const TagType *T,
bool TraverseQualifier) {
406 bool TraverseUnresolvedUsingType(UnresolvedUsingType *T,
407 bool TraverseQualifier) {
411 TraverseQualifier && NNS)
412 return inherited::TraverseNestedNameSpecifier(NNS);
413 return inherited::TraverseUnresolvedUsingType(T, TraverseQualifier);
416 bool TraverseInjectedClassNameType(InjectedClassNameType *T,
417 bool TraverseQualifier) {
418 return TraverseTemplateArguments(T->getTemplateArgs(SemaRef.
Context));
421 bool TraverseTemplateArgument(
const TemplateArgument &Arg) {
424 Sema::ArgPackSubstIndexRAII _1(SemaRef, std::nullopt);
425 llvm::SaveAndRestore<UnsignedOrNone>
_2(OuterPackSubstIndex,
427 return inherited::TraverseTemplateArgument(Arg);
430 Sema::ArgPackSubstIndexRAII _1(SemaRef, OuterPackSubstIndex);
431 return inherited::TraverseTemplateArgument(Arg);
434 bool TraverseSizeOfPackExpr(SizeOfPackExpr *SOPE) {
435 return TraverseDecl(SOPE->
getPack());
438 bool VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *E) {
443 if (
auto *TTP = dyn_cast_if_present<TemplateTemplateParmDecl>(
450 TemplateArgument Arg = TemplateArgs(TTP->getDepth(), TTP->getPosition());
453 "Missing argument pack");
457 "Null template template argument");
458 UsedTemplateArgs.push_back(
461 return inherited::TraverseTemplateName(
Template);
464 void VisitConstraint(
const NormalizedConstraintWithParamMapping &Constraint) {
466 for (
const auto &List : TemplateArgs)
467 for (
const TemplateArgument &Arg : List.Args)
473 llvm::ArrayRef<TemplateArgumentLoc> Mapping =
475 for (
auto &ArgLoc : Mapping) {
476 TemplateArgument Canonical =
479 UsedTemplateArgs.push_back(Canonical);
480 TraverseTemplateArgument(Canonical);
483 for (
auto &
Used : UsedTemplateArgs) {
484 llvm::FoldingSetNodeID
R;
491class ConstraintSatisfactionChecker {
494 SourceLocation TemplateNameLoc;
496 ConstraintSatisfaction &Satisfaction;
497 bool BuildExpression;
500 ConceptDecl *ParentConcept =
nullptr;
504 llvm::DenseMap<llvm::FoldingSetNodeID, TemplateArgumentLoc>
508 template <
class Constra
int>
510 return C.getPackSubstitutionIndex() ?
C.getPackSubstitutionIndex()
511 : PackSubstitutionIndex;
515 EvaluateAtomicConstraint(
const Expr *AtomicExpr,
516 const MultiLevelTemplateArgumentList &MLTAL);
519 const FoldExpandedConstraint &FE,
520 const MultiLevelTemplateArgumentList &MLTAL);
523 std::optional<MultiLevelTemplateArgumentList> SubstitutionInTemplateArguments(
524 const NormalizedConstraintWithParamMapping &Constraint,
525 const MultiLevelTemplateArgumentList &MLTAL,
526 llvm::SmallVector<TemplateArgument> &SubstitutedOuterMost);
528 ExprResult EvaluateSlow(
const AtomicConstraint &Constraint,
529 const MultiLevelTemplateArgumentList &MLTAL);
532 const MultiLevelTemplateArgumentList &MLTAL);
534 ExprResult EvaluateSlow(
const FoldExpandedConstraint &Constraint,
535 const MultiLevelTemplateArgumentList &MLTAL);
538 const MultiLevelTemplateArgumentList &MLTAL);
540 ExprResult EvaluateSlow(
const ConceptIdConstraint &Constraint,
541 const MultiLevelTemplateArgumentList &MLTAL,
545 const MultiLevelTemplateArgumentList &MLTAL);
548 const MultiLevelTemplateArgumentList &MLTAL);
551 ConstraintSatisfactionChecker(Sema &SemaRef,
const NamedDecl *
Template,
552 SourceLocation TemplateNameLoc,
554 ConstraintSatisfaction &Satisfaction,
555 bool BuildExpression)
557 PackSubstitutionIndex(PackSubstitutionIndex),
558 Satisfaction(Satisfaction), BuildExpression(BuildExpression) {}
561 const MultiLevelTemplateArgumentList &MLTAL);
564StringRef allocateStringFromConceptDiagnostic(
const Sema &S,
574ExprResult ConstraintSatisfactionChecker::EvaluateAtomicConstraint(
576 llvm::FoldingSetNodeID
ID;
583 SatisfactionStackRAII StackRAII(S,
Template, ID);
594 if (Inst.isInvalid())
599 SubstitutedExpression =
602 if (SubstitutedExpression.
isInvalid() || Trap.hasErrorOccurred()) {
606 if (!Trap.hasErrorOccurred())
613 Info.takeSFINAEDiagnostic(SubstDiag);
620 Satisfaction.
Details.emplace_back(
623 allocateStringFromConceptDiagnostic(S, SubstDiag.second)});
645 SubstitutedExpression.
get(),
648 return SubstitutedExpression;
651std::optional<MultiLevelTemplateArgumentList>
652ConstraintSatisfactionChecker::SubstitutionInTemplateArguments(
675 if (Inst.isInvalid())
682 &CachedTemplateArgs);
695 TD->getLocation(), SubstArgs,
704 SubstitutedOutermost =
705 llvm::to_vector_of<TemplateArgument>(MLTAL.
getOutermost());
707 for (
unsigned I = 0, MappedIndex = 0; I <
Used.size(); I++) {
712 if (I < SubstitutedOutermost.size()) {
713 SubstitutedOutermost[I] = Arg;
716 SubstitutedOutermost.push_back(Arg);
717 Offset = SubstitutedOutermost.size();
720 if (Offset < SubstitutedOutermost.size())
721 SubstitutedOutermost.erase(SubstitutedOutermost.begin() + Offset);
726 return std::move(SubstitutedTemplateArgs);
729ExprResult ConstraintSatisfactionChecker::EvaluateSlow(
732 std::optional<EnterExpressionEvaluationContext> EvaluationContext;
733 EvaluationContext.emplace(
738 std::optional<MultiLevelTemplateArgumentList> SubstitutedArgs =
739 SubstitutionInTemplateArguments(Constraint, MLTAL, SubstitutedOutermost);
740 if (!SubstitutedArgs) {
748 std::optional<Sema::ContextRAII> ConceptContext;
753 EvaluationContext.emplace(
758 ParentConcept->
getBeginLoc(), SubstitutedOutermost));
762 ExprResult SubstitutedAtomicExpr = EvaluateAtomicConstraint(
768 if (SubstitutedAtomicExpr.
isUnset())
782 Satisfaction.
Details.emplace_back(
784 SubstitutedAtomicExpr.get()->getBeginLoc(),
785 allocateStringFromConceptDiagnostic(S, Msg)});
786 return SubstitutedAtomicExpr;
792 return SubstitutedAtomicExpr;
797 EvalResult.
Diag = &EvaluationDiags;
800 !EvaluationDiags.empty()) {
804 diag::err_non_constant_constraint_expression)
807 S.
Diag(PDiag.first, PDiag.second);
812 "evaluating bool expression didn't produce int");
815 Satisfaction.
Details.emplace_back(SubstitutedAtomicExpr.
get());
817 return SubstitutedAtomicExpr;
820ExprResult ConstraintSatisfactionChecker::Evaluate(
825 llvm::FoldingSetNodeID
ID;
826 UnsignedOrNone OuterPackSubstIndex = getOuterPackIndex(Constraint);
830 HashParameterMapping(S, MLTAL, ID, OuterPackSubstIndex)
831 .VisitConstraint(Constraint);
835 auto &Cached = Iter->second.Satisfaction;
839 Cached.Details.begin(), Cached.Details.end());
840 return Iter->second.SubstExpr;
843 ExprResult E = EvaluateSlow(Constraint, MLTAL);
848 Cache.Satisfaction.Details.insert(
Cache.Satisfaction.Details.end(),
849 Satisfaction.
Details.begin() + Size,
858ConstraintSatisfactionChecker::EvaluateFoldExpandedConstraintSize(
866 assert(!Unexpanded.empty() &&
"Pack expansion without parameter packs?");
868 bool RetainExpansion =
false;
872 false, Expand, RetainExpansion,
873 NumExpansions,
false) ||
874 !Expand || RetainExpansion)
877 if (NumExpansions && S.
getLangOpts().BracketDepth < *NumExpansions)
879 return NumExpansions;
882ExprResult ConstraintSatisfactionChecker::EvaluateSlow(
888 unsigned EffectiveDetailEndIndex = Satisfaction.
Details.size();
893 std::optional<MultiLevelTemplateArgumentList> SubstitutedArgs =
894 SubstitutionInTemplateArguments(
896 MLTAL, SubstitutedOutermost);
897 if (!SubstitutedArgs) {
904 EvaluateFoldExpandedConstraintSize(Constraint, *SubstitutedArgs);
908 if (*NumExpansions == 0) {
913 for (
unsigned I = 0; I < *NumExpansions; I++) {
918 ConstraintSatisfactionChecker(S,
Template, TemplateNameLoc,
922 if (BuildExpression) {
923 if (
Out.isUnset() || !
Expr.isUsable())
927 Conjunction ? BinaryOperatorKind::BO_LAnd
928 : BinaryOperatorKind::BO_LOr,
935 EffectiveDetailEndIndex,
946ExprResult ConstraintSatisfactionChecker::Evaluate(
950 llvm::FoldingSetNodeID
ID;
952 HashParameterMapping(S, MLTAL, ID, std::nullopt).VisitConstraint(Constraint);
957 auto &Cached = Iter->second.Satisfaction;
961 Cached.Details.begin(), Cached.Details.end());
962 return Iter->second.SubstExpr;
967 ExprResult E = EvaluateSlow(Constraint, MLTAL);
971 Cache.Satisfaction.Details.insert(
Cache.Satisfaction.Details.end(),
972 Satisfaction.
Details.begin() + Size,
979ExprResult ConstraintSatisfactionChecker::EvaluateSlow(
985 std::optional<MultiLevelTemplateArgumentList> SubstitutedArgs =
986 SubstitutionInTemplateArguments(Constraint, MLTAL, SubstitutedOutermost);
988 if (!SubstitutedArgs) {
1006 Trap.hasErrorOccurred()) {
1008 if (!Trap.hasErrorOccurred())
1013 Info.takeSFINAEDiagnostic(SubstDiag);
1021 Satisfaction.
Details.begin() + Size,
1024 allocateStringFromConceptDiagnostic(S, SubstDiag.second)});
1036 if (SubstitutedConceptId.
isInvalid() || Trap.hasErrorOccurred())
1039 if (Size != Satisfaction.
Details.size()) {
1041 Satisfaction.
Details.begin() + Size,
1046 return SubstitutedConceptId;
1049ExprResult ConstraintSatisfactionChecker::Evaluate(
1066 if (InstTemplate.isInvalid())
1077 Satisfaction.
Details.insert(Satisfaction.
Details.begin() + Size, ConceptId);
1087 UnsignedOrNone OuterPackSubstIndex = getOuterPackIndex(Constraint);
1088 llvm::FoldingSetNodeID
ID;
1091 HashParameterMapping(S, MLTAL, ID, OuterPackSubstIndex)
1092 .VisitConstraint(Constraint);
1097 auto &Cached = Iter->second.Satisfaction;
1101 Cached.Details.begin(), Cached.Details.end());
1102 return Iter->second.SubstExpr;
1105 ExprResult CE = EvaluateSlow(Constraint, MLTAL, Size);
1111 Cache.Satisfaction.Details.insert(
Cache.Satisfaction.Details.end(),
1112 Satisfaction.
Details.begin() + Size,
1114 Cache.SubstExpr = CE;
1119ExprResult ConstraintSatisfactionChecker::Evaluate(
1123 unsigned EffectiveDetailEndIndex = Satisfaction.
Details.size();
1145 EffectiveDetailEndIndex,
1148 if (!BuildExpression)
1158 Conjunction ? BinaryOperatorKind::BO_LAnd
1159 : BinaryOperatorKind::BO_LOr,
1164ExprResult ConstraintSatisfactionChecker::Evaluate(
1167 switch (Constraint.
getKind()) {
1182 llvm_unreachable(
"Unknown ConstraintKind enum");
1193 *ConvertedExpr =
nullptr;
1195 if (AssociatedConstraints.empty()) {
1215 struct SynthesisContextPair {
1221 : Inst(S, InstantiationRange.
getBegin(),
1223 TemplateArgs, InstantiationRange),
1226 std::optional<SynthesisContextPair> SynthesisContext;
1227 if (!TopLevelConceptId)
1238 if (TopLevelConceptId)
1244 ExprResult Res = ConstraintSatisfactionChecker(
1247 ConvertedExpr !=
nullptr)
1248 .Evaluate(*
C, TemplateArgsLists);
1253 if (Res.
isUsable() && ConvertedExpr)
1254 *ConvertedExpr = Res.
get();
1265 llvm::TimeTraceScope TimeScope(
1266 "CheckConstraintSatisfaction", [TemplateIDRange,
this] {
1269 if (AssociatedConstraints.empty()) {
1275 return ::CheckConstraintSatisfaction(
1276 *
this,
nullptr, AssociatedConstraints, TemplateArgsLists,
1277 TemplateIDRange, OutSatisfaction, ConvertedExpr, TopLevelConceptId);
1291 for (
auto List : TemplateArgsLists)
1293 FlattenedArgs.emplace_back(
Context.getCanonicalTemplateArgument(Arg));
1296 if (TopLevelConceptId)
1299 llvm::FoldingSetNodeID ID;
1302 if (
auto *Cached = SatisfactionCache.FindNodeOrInsertPos(ID, InsertPos)) {
1303 OutSatisfaction = *Cached;
1308 std::make_unique<ConstraintSatisfaction>(Owner, FlattenedArgs);
1310 *
this,
Template, AssociatedConstraints, TemplateArgsLists,
1311 TemplateIDRange, *Satisfaction, ConvertedExpr, TopLevelConceptId)) {
1312 OutSatisfaction = std::move(*Satisfaction);
1316 if (
auto *Cached = SatisfactionCache.FindNodeOrInsertPos(ID, InsertPos)) {
1325 OutSatisfaction = *Cached;
1330 OutSatisfaction = *Satisfaction;
1334 SatisfactionCache.InsertNode(Satisfaction.release());
1356 return !ArgLoc.getArgument().isDependent() &&
1357 ArgLoc.getArgument().isConceptOrConceptTemplateParameter();
1359 return Concept->getConstraintExpr();
1372bool Sema::SetupConstraintScope(
1377 "Use LambdaScopeForCallOperatorInstantiationRAII to handle lambda "
1383 Sema::InstantiatingTemplate::ConstraintsCheck{}, PrimaryTemplate,
1384 TemplateArgs ? *TemplateArgs : ArrayRef<TemplateArgument>{},
1386 if (Inst.isInvalid())
1395 MultiLevelTemplateArgumentList JustTemplArgs(FD, SpecArgs->asArray(),
1397 if (addInstantiatedParametersToScope(
1404 if (FunctionTemplateDecl *FromMemTempl =
1406 if (addInstantiatedParametersToScope(FD, FromMemTempl->getTemplatedDecl(),
1416 FunctionDecl *InstantiatedFrom =
1423 Sema::InstantiatingTemplate::ConstraintsCheck{}, InstantiatedFrom,
1424 TemplateArgs ? *TemplateArgs : ArrayRef<TemplateArgument>{},
1426 if (Inst.isInvalid())
1431 if (addInstantiatedParametersToScope(FD, InstantiatedFrom, Scope, MLTAL))
1440std::optional<MultiLevelTemplateArgumentList>
1441Sema::SetupConstraintCheckingTemplateArgumentsAndScope(
1444 MultiLevelTemplateArgumentList MLTAL;
1451 false, std::nullopt,
1458 if (SetupConstraintScope(FD, TemplateArgs, MLTAL, Scope))
1459 return std::nullopt;
1467 bool ForOverloadResolution) {
1486 if (
const auto *MD = dyn_cast<CXXConversionDecl>(FD);
1489 Satisfaction, UsageLoc,
1503 std::optional<MultiLevelTemplateArgumentList> MLTAL =
1504 SetupConstraintCheckingTemplateArgumentsAndScope(
1512 if (
auto *
Method = dyn_cast<CXXMethodDecl>(FD)) {
1513 ThisQuals =
Method->getMethodQualifiers();
1520 ForOverloadResolution);
1530 const Expr *ConstrExpr) {
1545 std::optional<LocalInstantiationScope> ScopeForParameters;
1548 ScopeForParameters.emplace(S,
true);
1552 FD =
Template->getInstantiatedFromMemberTemplate()->getTemplatedDecl();
1554 if (ScopeForParameters->getInstantiationOfIfExists(PVD))
1556 if (!PVD->isParameterPack()) {
1557 ScopeForParameters->InstantiatedLocal(PVD, PVD);
1576 ScopeForParameters->MakeInstantiatedLocalArgPack(PVD);
1577 ScopeForParameters->InstantiatedLocalPackArg(PVD, PVD);
1581 std::optional<Sema::CXXThisScopeRAII> ThisScope;
1590 std::optional<Sema::ContextRAII> ContextScope;
1598 if (
auto *RD = dyn_cast<CXXRecordDecl>(DC)) {
1610 return SubstConstr.
get();
1614 const Expr *OldConstr,
1616 const Expr *NewConstr) {
1617 if (OldConstr == NewConstr)
1620 if (Old && !
New.isInvalid() && !
New.ContainsDecl(Old) &&
1623 if (
const Expr *SubstConstr =
1626 OldConstr = SubstConstr;
1629 if (
const Expr *SubstConstr =
1632 NewConstr = SubstConstr;
1637 llvm::FoldingSetNodeID ID1, ID2;
1650 "Non-function templates don't need to be checked");
1671 TemplateIDRange, Satisfaction))
1676 TemplateArgString =
" ";
1682 diag::err_template_arg_list_constraints_not_satisfied)
1684 << TemplateArgString << TemplateIDRange;
1696 Template->getAssociatedConstraints(TemplateAC);
1697 if (TemplateAC.empty()) {
1716 SemaRef, PointOfInstantiation,
1718 PointOfInstantiation);
1719 if (Inst.isInvalid())
1729 Template, TemplateAC, MLTAL, PointOfInstantiation, Satisfaction);
1740 return ::CheckFunctionConstraintsWithoutInstantiation(
1741 *
this, PointOfInstantiation,
Decl->getDescribedFunctionTemplate(),
1742 TemplateArgs, Satisfaction);
1747 Template->getAssociatedConstraints(TemplateAC);
1748 if (TemplateAC.empty()) {
1758 std::optional<MultiLevelTemplateArgumentList> MLTAL =
1759 SetupConstraintCheckingTemplateArgumentsAndScope(
Decl, TemplateArgs,
1767 if (
auto *
Method = dyn_cast<CXXMethodDecl>(
Decl)) {
1768 ThisQuals =
Method->getMethodQualifiers();
1777 PointOfInstantiation, Satisfaction);
1784 "Diagnose() can only be used on an unsatisfied requirement");
1787 llvm_unreachable(
"Diagnosing a dependent requirement");
1791 if (!SubstDiag->DiagMessage.empty())
1792 S.
Diag(SubstDiag->DiagLoc,
1793 diag::note_expr_requirement_expr_substitution_error)
1794 << (
int)
First << SubstDiag->SubstitutedEntity
1795 << SubstDiag->DiagMessage;
1797 S.
Diag(SubstDiag->DiagLoc,
1798 diag::note_expr_requirement_expr_unknown_substitution_error)
1799 << (
int)
First << SubstDiag->SubstitutedEntity;
1809 if (!SubstDiag->DiagMessage.empty())
1810 S.
Diag(SubstDiag->DiagLoc,
1811 diag::note_expr_requirement_type_requirement_substitution_error)
1812 << (
int)
First << SubstDiag->SubstitutedEntity
1813 << SubstDiag->DiagMessage;
1818 note_expr_requirement_type_requirement_unknown_substitution_error)
1819 << (
int)
First << SubstDiag->SubstitutedEntity;
1829 llvm_unreachable(
"We checked this above");
1837 "Diagnose() can only be used on an unsatisfied requirement");
1840 llvm_unreachable(
"Diagnosing a dependent requirement");
1844 if (!SubstDiag->DiagMessage.empty())
1845 S.
Diag(SubstDiag->DiagLoc, diag::note_type_requirement_substitution_error)
1846 << (
int)
First << SubstDiag->SubstitutedEntity
1847 << SubstDiag->DiagMessage;
1849 S.
Diag(SubstDiag->DiagLoc,
1850 diag::note_type_requirement_unknown_substitution_error)
1851 << (
int)
First << SubstDiag->SubstitutedEntity;
1855 llvm_unreachable(
"Unknown satisfaction status");
1863 if (
Concept->getTemplateArgsAsWritten()->NumTemplateArgs == 1) {
1867 note_single_arg_concept_specialization_constraint_evaluated_to_false)
1869 <<
Concept->getTemplateArgsAsWritten()->arguments()[0].getArgument()
1870 <<
Concept->getNamedConcept();
1872 S.
Diag(Loc, diag::note_concept_specialization_constraint_evaluated_to_false)
1902 const Expr *SubstExpr,
1905 if (
const BinaryOperator *BO = dyn_cast<BinaryOperator>(SubstExpr)) {
1906 switch (BO->getOpcode()) {
1918 BO->getLHS()->EvaluateKnownConstInt(S.
Context).getBoolValue();
1929 BO->getRHS()->EvaluateKnownConstInt(S.
Context).getBoolValue();
1941 if (BO->getLHS()->getType()->isIntegerType() &&
1942 BO->getRHS()->getType()->isIntegerType()) {
1945 BO->getLHS()->EvaluateAsInt(SimplifiedLHS, S.
Context,
1948 BO->getRHS()->EvaluateAsInt(SimplifiedRHS, S.
Context,
1951 if (!SimplifiedLHS.
Diag && !SimplifiedRHS.
Diag) {
1953 diag::note_atomic_constraint_evaluated_to_false_elaborated)
1966 }
else if (
auto *RE = dyn_cast<RequiresExpr>(SubstExpr)) {
1969 if (!Req->isDependent() && !Req->isSatisfied()) {
1970 if (
auto *E = dyn_cast<concepts::ExprRequirement>(Req))
1972 else if (
auto *T = dyn_cast<concepts::TypeRequirement>(Req))
1980 }
else if (
auto *CSE = dyn_cast<ConceptSpecializationExpr>(SubstExpr)) {
1984 }
else if (
auto *TTE = dyn_cast<TypeTraitExpr>(SubstExpr);
1985 TTE && TTE->getTrait() == clang::TypeTrait::BTT_IsDeducible) {
1986 assert(TTE->getNumArgs() == 2);
1988 diag::note_is_deducible_constraint_evaluated_to_false)
1989 << TTE->getArg(0)->getType() << TTE->getArg(1)->getType();
1994 diag::note_atomic_constraint_evaluated_to_false)
2004 .
template dyn_cast<const ConstraintSubstitutionDiagnostic *>()) {
2006 S.
Diag(
Diag->first, diag::note_nested_requirement_substitution_error)
2009 S.
Diag(
Diag->first, diag::note_substituted_constraint_expr_is_ill_formed)
2013 if (
const auto *
Concept = dyn_cast<const ConceptReference *>(
Record)) {
2028 "Attempted to diagnose a satisfied constraint");
2039 "Attempted to diagnose a satisfied constraint");
2047class SubstituteParameterMappings {
2059 bool RemovePacksForFoldExpr;
2061 SubstituteParameterMappings(
Sema &SemaRef,
2064 bool RemovePacksForFoldExpr)
2065 : SemaRef(SemaRef), MLTAL(MLTAL), ArgsAsWritten(ArgsAsWritten),
2066 RemovePacksForFoldExpr(RemovePacksForFoldExpr) {}
2075 SubstituteParameterMappings(
Sema &SemaRef,
2076 bool RemovePacksForFoldExpr =
false)
2078 RemovePacksForFoldExpr(RemovePacksForFoldExpr) {}
2080 bool substitute(NormalizedConstraint &N);
2083void SubstituteParameterMappings::buildParameterMapping(
2088 llvm::SmallBitVector OccurringIndices(TemplateParams->
size());
2089 llvm::SmallBitVector OccurringIndicesForSubsumption(TemplateParams->
size());
2095 0, OccurringIndices);
2099 0, OccurringIndicesForSubsumption);
2106 0, OccurringIndices);
2110 ->getTemplateArgsAsWritten();
2113 0, OccurringIndices);
2121 I < TemplateParams->size(); ++I) {
2127 assert(Arg &&
"expected a default argument");
2128 DefaultArgs.emplace_back(std::move(*Arg));
2133 OccurringIndicesForSubsumption);
2136 unsigned Size = OccurringIndices.count();
2144 for (
unsigned I = 0, J = 0,
C = TemplateParams->
size(); I !=
C; ++I) {
2146 ? ArgsAsWritten->arguments()[I].getLocation()
2150 if (OccurringIndices[I]) {
2154 UsedParams.push_back(Param);
2164 std::move(OccurringIndices), std::move(OccurringIndicesForSubsumption),
2168bool SubstituteParameterMappings::substitute(
2171 buildParameterMapping(N);
2180 InstLocBegin = ArgsAsWritten->getLAngleLoc();
2181 InstLocEnd = ArgsAsWritten->getRAngleLoc();
2183 auto SR =
Arguments[0].getSourceRange();
2184 InstLocBegin = SR.getBegin();
2185 InstLocEnd = SR.getEnd();
2189 SemaRef, InstLocBegin,
2192 {InstLocBegin, InstLocEnd});
2193 if (Inst.isInvalid())
2210 TD->getLocation(), SubstArgs,
2221 if (I < SubstArgs.
size())
2222 Loc = SubstArgs.
arguments()[I].getLocation();
2249 InstLocBegin = ArgsAsWritten->getLAngleLoc();
2250 InstLocEnd = ArgsAsWritten->getRAngleLoc();
2252 auto SR =
Arguments[0].getSourceRange();
2253 InstLocBegin = SR.getBegin();
2254 InstLocEnd = SR.getEnd();
2259 SemaRef, InstLocBegin,
2262 {InstLocBegin, InstLocEnd});
2263 if (Inst.isInvalid())
2274 CSE->getTemplateArgsAsWritten();
2280 CSE->getConceptNameInfo().getLoc(), Out,
2285 auto TemplateArgs = *MLTAL;
2288 return SubstituteParameterMappings(SemaRef, &TemplateArgs, ArgsAsWritten,
2289 RemovePacksForFoldExpr)
2297 assert(!ArgsAsWritten);
2306 assert(!ArgsAsWritten);
2311 return SubstituteParameterMappings(SemaRef,
true)
2317 assert(ArgsAsWritten);
2318 return substitute(CC);
2320 assert(!ArgsAsWritten);
2324 if (RemovePacksForFoldExpr) {
2328 if (AdjustConstraints(SemaRef, 0,
2330 .TransformTemplateArguments(InputArgLoc.begin(),
2331 InputArgLoc.end(), OutArgs))
2351 return SubstituteParameterMappings(SemaRef, &MLTAL,
2353 RemovePacksForFoldExpr)
2358 if (substitute(Compound.getLHS()))
2360 return substitute(Compound.getRHS());
2363 llvm_unreachable(
"Unknown ConstraintKind enum");
2370 assert(ACs.size() != 0);
2372 fromConstraintExpr(S, D, ACs[0].ConstraintExpr, ACs[0].ArgPackSubstIndex);
2375 for (
unsigned I = 1; I < ACs.size(); ++I) {
2376 auto *
Next = fromConstraintExpr(S, D, ACs[I].ConstraintExpr,
2377 ACs[I].ArgPackSubstIndex);
2388 assert(E !=
nullptr);
2396 llvm::FoldingSetNodeID
ID;
2400 SatisfactionStackRAII StackRAII(S, D, ID);
2407 if (LogicalBinOp BO = E) {
2408 auto *LHS = fromConstraintExpr(S, D, BO.getLHS(), SubstIndex);
2411 auto *RHS = fromConstraintExpr(S, D, BO.getRHS(), SubstIndex);
2418 if (
auto *CSE = dyn_cast<const ConceptSpecializationExpr>(E)) {
2434 SubNF = NormalizedConstraint::fromAssociatedConstraints(
2436 AssociatedConstraint(Res.get(), SubstIndex));
2443 if (
auto *FE = dyn_cast<const CXXFoldExpr>(E);
2445 (FE->getOperator() == BinaryOperatorKind::BO_LAnd ||
2446 FE->getOperator() == BinaryOperatorKind::BO_LOr)) {
2451 FE->getOperator() == BinaryOperatorKind::BO_LAnd
2455 if (FE->getInit()) {
2456 auto *LHS = fromConstraintExpr(S, D, FE->getLHS(), SubstIndex);
2457 auto *RHS = fromConstraintExpr(S, D, FE->getRHS(), SubstIndex);
2461 if (FE->isRightFold())
2474 auto *
Sub = fromConstraintExpr(S, D, FE->
getPattern(), SubstIndex);
2486 if (!ConstrainedDeclOrNestedReq) {
2487 auto *Normalized = NormalizedConstraint::fromAssociatedConstraints(
2488 *
this,
nullptr, AssociatedConstraints);
2490 SubstituteParameterMappings(*this).substitute(*Normalized))
2498 ConstrainedDeclOrNestedReq.dyn_cast<
const NamedDecl *>();
2499 auto CacheEntry = NormalizationCache.find(ConstrainedDeclOrNestedReq);
2500 if (CacheEntry == NormalizationCache.end()) {
2501 auto *Normalized = NormalizedConstraint::fromAssociatedConstraints(
2502 *
this, ND, AssociatedConstraints);
2504 NormalizationCache.try_emplace(ConstrainedDeclOrNestedReq,
nullptr);
2508 bool Failed = SubstituteParameterMappings(*this).substitute(*Normalized);
2510 NormalizationCache.try_emplace(ConstrainedDeclOrNestedReq, Normalized)
2515 return CacheEntry->second;
2538 if (It != BPacks.end())
2550 if (
const auto *FD1 = dyn_cast<FunctionDecl>(D1)) {
2556 const auto *FD2 = dyn_cast<FunctionDecl>(D2);
2557 assert(IsExpectedEntity(FD1) && FD2 && IsExpectedEntity(FD2) &&
2558 "use non-instantiated function declaration for constraints partial "
2573 std::pair<const NamedDecl *, const NamedDecl *> Key{D1, D2};
2574 auto CacheEntry = SubsumptionCache.find(Key);
2575 if (CacheEntry != SubsumptionCache.end()) {
2576 Result = CacheEntry->second;
2583 for (
size_t I = 0; I != AC1.size() && I != AC2.size(); ++I) {
2584 if (Depth2 > Depth1) {
2585 AC1[I].ConstraintExpr =
2586 AdjustConstraints(*
this, Depth2 - Depth1)
2587 .TransformExpr(
const_cast<Expr *
>(AC1[I].ConstraintExpr))
2589 }
else if (Depth1 > Depth2) {
2590 AC2[I].ConstraintExpr =
2591 AdjustConstraints(*
this, Depth1 - Depth2)
2592 .TransformExpr(
const_cast<Expr *
>(AC2[I].ConstraintExpr))
2601 const NamedDecl *DeclAC1 = D1, *DeclAC2 = D2;
2602 if (Depth2 > Depth1)
2604 else if (Depth1 > Depth2)
2606 std::optional<bool> Subsumes = SC.
Subsumes(DeclAC1, AC1, DeclAC2, AC2);
2612 SubsumptionCache.try_emplace(Key, *Subsumes);
2623 if (AC1.empty() || AC2.empty())
2626 const Expr *AmbiguousAtomic1 =
nullptr, *AmbiguousAtomic2 =
nullptr;
2637 llvm::FoldingSetNodeID IDA, IDB;
2639 EB->Profile(IDB,
Context,
true);
2643 AmbiguousAtomic1 = EA;
2644 AmbiguousAtomic2 = EB;
2659 bool Is1AtLeastAs2Normally = SC.
Subsumes(Normalized1, Normalized2);
2660 bool Is2AtLeastAs1Normally = SC.
Subsumes(Normalized2, Normalized1);
2663 bool Is1AtLeastAs2 = SC2.
Subsumes(Normalized1, Normalized2);
2664 bool Is2AtLeastAs1 = SC2.
Subsumes(Normalized2, Normalized1);
2666 if (Is1AtLeastAs2 == Is1AtLeastAs2Normally &&
2667 Is2AtLeastAs1 == Is2AtLeastAs1Normally)
2672 assert(AmbiguousAtomic1 && AmbiguousAtomic2);
2674 Diag(AmbiguousAtomic1->
getBeginLoc(), diag::note_ambiguous_atomic_constraints)
2676 Diag(AmbiguousAtomic2->getBeginLoc(),
2677 diag::note_ambiguous_atomic_constraints_similar_expression)
2678 << AmbiguousAtomic2->getSourceRange();
2689 : SemaRef(SemaRef), Callable(Callable), NextID(1) {}
2691uint16_t SubsumptionChecker::getNewLiteralId() {
2692 assert((
unsigned(NextID) + 1 < std::numeric_limits<uint16_t>::max()) &&
2693 "too many constraints!");
2698 auto &Elems = AtomicMap[Ori->getConstraintExpr()];
2713 llvm::FoldingSetNodeID ID;
2714 ID.AddBoolean(Ori->hasParameterMapping());
2715 if (Ori->hasParameterMapping()) {
2716 const auto &Mapping = Ori->getParameterMapping();
2718 Ori->mappingOccurenceListForSubsumption();
2719 for (
auto [Idx, TAL] : llvm::enumerate(Mapping)) {
2726 auto It = Elems.find(ID);
2727 if (It == Elems.end()) {
2730 MappedAtomicConstraint{
2731 Ori, {getNewLiteralId(), Literal::Atomic}}})
2733 ReverseMap[It->second.ID.Value] = Ori;
2735 return It->getSecond().ID;
2739 auto &Elems = FoldMap[Ori->getPattern()];
2741 FoldExpendedConstraintKey K;
2742 K.Kind = Ori->getFoldOperator();
2744 auto It = llvm::find_if(Elems, [&K](
const FoldExpendedConstraintKey &
Other) {
2745 return K.Kind ==
Other.Kind;
2747 if (It == Elems.end()) {
2748 K.ID = {getNewLiteralId(), Literal::FoldExpanded};
2749 It = Elems.insert(Elems.end(), std::move(K));
2750 ReverseMap[It->ID.Value] = Ori;
2756 return SubsumptionChecker::Normalize<CNFFormula>(
C);
2759 return SubsumptionChecker::Normalize<DNFFormula>(
C);
2775template <
typename FormulaType>
2779 auto Add = [&,
this](Clause
C) {
2782 C.erase(llvm::unique(
C),
C.end());
2783 AddUniqueClauseToFormula(Res, std::move(
C));
2788 return {{find(&
static_cast<const AtomicConstraint &
>(NC))}};
2791 return {{find(&
static_cast<const FoldExpandedConstraint &
>(NC))}};
2794 return Normalize<FormulaType>(
2795 static_cast<const ConceptIdConstraint &
>(NC).getNormalizedConstraint());
2798 const auto &Compound =
static_cast<const CompoundConstraint &
>(NC);
2800 SemaRef.runWithSufficientStackSpace(SourceLocation(), [&] {
2801 Left = Normalize<FormulaType>(Compound.getLHS());
2802 Right = Normalize<FormulaType>(Compound.getRHS());
2805 if (Compound.getCompoundKind() == FormulaType::Kind) {
2806 unsigned SizeLeft =
Left.size();
2807 Res = std::move(Left);
2808 Res.reserve(SizeLeft +
Right.size());
2809 std::for_each(std::make_move_iterator(
Right.begin()),
2810 std::make_move_iterator(
Right.end()), Add);
2814 Res.reserve(
Left.size() *
Right.size());
2815 for (
const auto <ransform : Left) {
2816 for (
const auto &RTransform : Right) {
2818 Combined.reserve(LTransform.size() + RTransform.size());
2819 llvm::copy(LTransform, std::back_inserter(Combined));
2820 llvm::copy(RTransform, std::back_inserter(Combined));
2821 Add(std::move(Combined));
2827 llvm_unreachable(
"Unknown ConstraintKind enum");
2830void SubsumptionChecker::AddUniqueClauseToFormula(Formula &F, Clause
C) {
2831 for (
auto &
Other : F) {
2832 if (llvm::equal(
C,
Other))
2842 SemaRef.getNormalizedAssociatedConstraints(DP, P);
2844 return std::nullopt;
2847 SemaRef.getNormalizedAssociatedConstraints(DQ, Q);
2849 return std::nullopt;
2851 return Subsumes(PNormalized, QNormalized);
2857 DNFFormula DNFP = DNF(*P);
2858 CNFFormula CNFQ = CNF(*Q);
2863 const CNFFormula &QCNF) {
2864 for (
const auto &Pi : PDNF) {
2865 for (
const auto &Qj : QCNF) {
2871 if (!DNFSubsumes(Pi, Qj))
2878bool SubsumptionChecker::DNFSubsumes(
const Clause &P,
const Clause &Q) {
2880 return llvm::any_of(P, [&](Literal LP) {
2881 return llvm::any_of(Q, [
this, LP](Literal LQ) {
return Subsumes(LP, LQ); });
2887 std::pair<const FoldExpandedConstraint *, const FoldExpandedConstraint *> Key{
2890 auto It = FoldSubsumptionCache.find(Key);
2891 if (It == FoldSubsumptionCache.end()) {
2900 It = FoldSubsumptionCache.try_emplace(std::move(Key), DoesSubsume).first;
2906 if (A.Kind != B.Kind)
2909 case Literal::Atomic:
2911 return A.Value == B.Value;
2913 *
static_cast<const AtomicConstraint *
>(ReverseMap[A.Value]),
2914 *
static_cast<const AtomicConstraint *
>(ReverseMap[B.Value]));
2915 case Literal::FoldExpanded:
2917 static_cast<const FoldExpandedConstraint *
>(ReverseMap[A.Value]),
2918 static_cast<const FoldExpandedConstraint *
>(ReverseMap[B.Value]));
2920 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 ASTConstraintSatisfaction & getSatisfaction() const
Get elaborated satisfaction info about the template arguments' satisfaction of the named concept.
ConceptDecl * getNamedConcept() const
The result of a constraint satisfaction check, containing the necessary information to diagnose an un...
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &C)
llvm::SmallVector< UnsatisfiedConstraintRecord, 4 > Details
The substituted constraint expr, if the template arguments could be substituted into them,...
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
DeclContext * getParent()
getParent - Returns the containing DeclContext.
bool isTransparentContext() const
isTransparentContext - Determines whether this context is a "transparent" context,...
bool isDependentContext() const
Determines whether this context is dependent on a template parameter.
DeclContext * getNonTransparentContext()
Decl - This represents one declaration (or definition), e.g.
FriendObjectKind getFriendObjectKind() const
Determines whether this declaration is the object of a friend declaration and, if so,...
bool isFunctionOrFunctionTemplate() const
Whether this declaration is a function or function template.
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()
SourceLocation getBeginLoc() const LLVM_READONLY
DeclContext * getLexicalDeclContext()
getLexicalDeclContext - The declaration context where this Decl was lexically declared (LexicalDC).
const AssociatedConstraint & getTrailingRequiresClause() const
Get the constraint-expression introduced by the trailing requires-clause in the function/member decla...
RAII object that enters a new expression evaluation context.
This represents one expression.
@ SE_NoSideEffects
Strictly evaluate the expression.
bool isValueDependent() const
Determines whether the value of this expression depends on.
bool isTypeDependent() const
Determines whether the type of this expression depends on.
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
bool containsErrors() const
Whether this expression contains subexpressions which had errors.
bool EvaluateAsConstantExpr(EvalResult &Result, const ASTContext &Ctx, ConstantExprKind Kind=ConstantExprKind::Normal) const
Evaluate an expression that is required to be a constant expression.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
Represents difference between two FPOptions values.
static bool AreCompatibleForSubsumption(const FoldExpandedConstraint &A, const FoldExpandedConstraint &B)
FoldOperatorKind getFoldOperator() const
const Expr * getPattern() const
static FoldExpandedConstraint * Create(ASTContext &Ctx, const Expr *Pattern, const NamedDecl *ConstraintDecl, FoldOperatorKind OpKind, NormalizedConstraint *Constraint)
const NormalizedConstraint & getNormalizedPattern() const
Represents a function declaration or definition.
FunctionTemplateDecl * getDescribedFunctionTemplate() const
Retrieves the function template that is described by this function declaration.
SourceLocation getPointOfInstantiation() const
Retrieve the (first) point of instantiation of a function template specialization or a member of a cl...
ArrayRef< ParmVarDecl * > parameters() const
FunctionTemplateDecl * getPrimaryTemplate() const
Retrieve the primary template that this function template specialization either specializes or was in...
const TemplateArgumentList * getTemplateSpecializationArgs() const
Retrieve the template arguments used to produce this function template specialization from the primar...
bool isTemplateInstantiation() const
Determines if the given function was instantiated from a function template.
TemplatedKind
The kind of templated function a FunctionDecl can be.
@ TK_MemberSpecialization
@ TK_DependentNonTemplate
@ TK_FunctionTemplateSpecialization
TemplatedKind getTemplatedKind() const
What kind of templated function this is.
FunctionDecl * getInstantiatedFromDecl() const
FunctionDecl * getInstantiatedFromMemberFunction() const
If this function is an instantiation of a member function of a class template specialization,...
Declaration of a template function.
FunctionDecl * getTemplatedDecl() const
Get the underlying function declaration of the template.
FunctionTemplateDecl * getInstantiatedFromMemberTemplate() const
static ImplicitCastExpr * Create(const ASTContext &Context, QualType T, CastKind Kind, Expr *Operand, const CXXCastPath *BasePath, ExprValueKind Cat, FPOptionsOverride FPO)
static ImplicitConceptSpecializationDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation SL, ArrayRef< TemplateArgument > ConvertedArgs)
const TypeClass * getTypePtr() const
A stack-allocated class that identifies which local variable declaration instantiations are present i...
Data structure that captures multiple levels of template argument lists for use in template instantia...
bool hasTemplateArgument(unsigned Depth, unsigned Index) const
Determine whether there is a non-NULL template argument at the given depth and index.
const ArgList & getInnermost() const
Retrieve the innermost template argument list.
void addOuterTemplateArguments(Decl *AssociatedDecl, ArgList Args, bool Final)
Add a new outmost level to the multi-level template argument list.
unsigned getNumLevels() const
Determine the number of levels in this template argument list.
unsigned getNumSubstitutedLevels() const
Determine the number of substituted levels in this template argument list.
void replaceOutermostTemplateArguments(Decl *AssociatedDecl, ArgList Args)
const ArgList & getOutermost() const
Retrieve the outermost template argument list.
bool isAnyArgInstantiationDependent() const
This represents a decl that may have a name.
unsigned getPosition() const
Get the position of the template parameter within its parameter list.
bool isParameterPack() const
Whether this parameter is a non-type template parameter pack.
unsigned getIndex() const
Get the index of the template parameter within its parameter list.
unsigned getDepth() const
Get the nesting depth of the template parameter.
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.