24 #include "llvm/ADT/DenseMap.h"
25 #include "llvm/ADT/PointerUnion.h"
26 #include "llvm/ADT/StringExtras.h"
28 using namespace clang;
34 const Expr *LHS =
nullptr;
35 const Expr *RHS =
nullptr;
38 LogicalBinOp(
const Expr *E) {
39 if (
auto *BO = dyn_cast<BinaryOperator>(E)) {
43 }
else if (
auto *OO = dyn_cast<CXXOperatorCallExpr>(E)) {
45 if (OO->getNumArgs() == 2) {
46 Op = OO->getOperator();
53 bool isAnd()
const {
return Op == OO_AmpAmp; }
54 bool isOr()
const {
return Op == OO_PipePipe; }
55 explicit operator bool()
const {
return isAnd() || isOr(); }
57 const Expr *getLHS()
const {
return LHS; }
58 const Expr *getRHS()
const {
return RHS; }
63 Token NextToken,
bool *PossibleNonPrimary,
64 bool IsTrailingRequiresClause) {
70 if (LogicalBinOp BO = ConstraintExpression) {
71 return CheckConstraintExpression(BO.getLHS(), NextToken,
72 PossibleNonPrimary) &&
73 CheckConstraintExpression(BO.getRHS(), NextToken,
75 }
else if (
auto *C = dyn_cast<ExprWithCleanups>(ConstraintExpression))
76 return CheckConstraintExpression(C->getSubExpr(), NextToken,
81 auto CheckForNonPrimary = [&] {
82 if (PossibleNonPrimary)
89 (NextToken.
is(tok::l_paren) &&
90 (IsTrailingRequiresClause ||
92 isa<UnresolvedLookupExpr>(ConstraintExpression)) ||
107 CheckForNonPrimary();
113 diag::err_non_bool_atomic_constraint) <<
Type
115 CheckForNonPrimary();
119 if (PossibleNonPrimary)
120 *PossibleNonPrimary =
false;
124 template <
typename AtomicEvaluator>
128 AtomicEvaluator &&Evaluator) {
131 if (LogicalBinOp BO = ConstraintExpr) {
138 if (BO.isOr() && IsLHSSatisfied)
147 if (BO.isAnd() && !IsLHSSatisfied)
157 S, BO.getRHS(), Satisfaction, std::forward<AtomicEvaluator>(Evaluator));
158 }
else if (
auto *C = dyn_cast<ExprWithCleanups>(ConstraintExpr)) {
160 std::forward<AtomicEvaluator>(Evaluator));
164 ExprResult SubstitutedAtomicExpr = Evaluator(ConstraintExpr);
169 if (!SubstitutedAtomicExpr.
isUsable())
177 EvalResult.
Diag = &EvaluationDiags;
180 !EvaluationDiags.empty()) {
184 diag::err_non_constant_constraint_expression)
187 S.
Diag(PDiag.first, PDiag.second);
192 "evaluating bool expression didn't produce int");
195 Satisfaction.
Details.emplace_back(ConstraintExpr,
196 SubstitutedAtomicExpr.
get());
229 SubstitutedExpression =
252 unsigned MessageSize = DiagString.size();
253 char *Mem =
new (S.
Context)
char[MessageSize];
254 memcpy(Mem, DiagString.c_str(), MessageSize);
255 Satisfaction.
Details.emplace_back(
258 SubstDiag.first, StringRef(Mem, MessageSize)});
267 return SubstitutedExpression;
276 if (ConstraintExprs.empty()) {
281 for (
auto& Arg : TemplateArgs)
282 if (Arg.isInstantiationDependent()) {
290 const_cast<NamedDecl *
>(Template), TemplateArgs, TemplateIDRange);
297 for (
const Expr *ConstraintExpr : ConstraintExprs) {
300 ConstraintExpr, Satisfaction))
316 if (ConstraintExprs.empty()) {
322 TemplateArgs, TemplateIDRange,
325 llvm::FoldingSetNodeID
ID;
328 if (
auto *Cached = SatisfactionCache.FindNodeOrInsertPos(
ID, InsertPos)) {
329 OutSatisfaction = *Cached;
333 std::make_unique<ConstraintSatisfaction>(Template, TemplateArgs);
335 TemplateArgs, TemplateIDRange,
339 OutSatisfaction = *Satisfaction;
343 SatisfactionCache.InsertNode(Satisfaction.release());
350 *
this, ConstraintExpr, Satisfaction,
366 if (
auto *Method = dyn_cast<CXXMethodDecl>(FD)) {
367 ThisQuals = Method->getMethodQualifiers();
387 TemplateIDRange, Satisfaction))
392 TemplateArgString =
" ";
393 TemplateArgString += getTemplateArgumentBindingsText(
397 diag::err_template_arg_list_constraints_not_satisfied)
399 << TemplateArgString << TemplateIDRange;
400 DiagnoseUnsatisfiedConstraint(Satisfaction);
416 if (TemplateAC.empty()) {
429 if (
Decl->isTemplateInstantiation()) {
436 *
Decl->getTemplateSpecializationArgs());
437 if (addInstantiatedParametersToScope(
438 Decl,
Decl->getPrimaryTemplate()->getTemplatedDecl(),
Scope, MLTAL))
443 if (
auto *Method = dyn_cast<CXXMethodDecl>(
Decl)) {
444 ThisQuals = Method->getMethodQualifiers();
449 PointOfInstantiation, Satisfaction);
456 &&
"Diagnose() can only be used on an unsatisfied requirement");
459 llvm_unreachable(
"Diagnosing a dependent requirement");
463 if (!SubstDiag->DiagMessage.empty())
464 S.
Diag(SubstDiag->DiagLoc,
465 diag::note_expr_requirement_expr_substitution_error)
466 << (
int)
First << SubstDiag->SubstitutedEntity
467 << SubstDiag->DiagMessage;
469 S.
Diag(SubstDiag->DiagLoc,
470 diag::note_expr_requirement_expr_unknown_substitution_error)
471 << (
int)
First << SubstDiag->SubstitutedEntity;
476 diag::note_expr_requirement_noexcept_not_met)
482 if (!SubstDiag->DiagMessage.empty())
483 S.
Diag(SubstDiag->DiagLoc,
484 diag::note_expr_requirement_type_requirement_substitution_error)
485 << (
int)
First << SubstDiag->SubstitutedEntity
486 << SubstDiag->DiagMessage;
488 S.
Diag(SubstDiag->DiagLoc,
489 diag::note_expr_requirement_type_requirement_unknown_substitution_error)
490 << (
int)
First << SubstDiag->SubstitutedEntity;
501 diag::note_expr_requirement_constraints_not_satisfied_simple)
506 diag::note_expr_requirement_constraints_not_satisfied)
507 << (
int)
First << ConstraintExpr;
513 llvm_unreachable(
"We checked this above");
521 &&
"Diagnose() can only be used on an unsatisfied requirement");
524 llvm_unreachable(
"Diagnosing a dependent requirement");
528 if (!SubstDiag->DiagMessage.empty())
529 S.
Diag(SubstDiag->DiagLoc,
530 diag::note_type_requirement_substitution_error) << (
int)
First
531 << SubstDiag->SubstitutedEntity << SubstDiag->DiagMessage;
533 S.
Diag(SubstDiag->DiagLoc,
534 diag::note_type_requirement_unknown_substitution_error)
535 << (
int)
First << SubstDiag->SubstitutedEntity;
539 llvm_unreachable(
"Unknown satisfaction status");
552 diag::note_nested_requirement_substitution_error)
557 diag::note_nested_requirement_unknown_substitution_error)
570 switch (BO->getOpcode()) {
582 BO->getLHS()->EvaluateKnownConstInt(S.
Context).getBoolValue();
593 BO->getRHS()->EvaluateKnownConstInt(S.
Context).getBoolValue();
605 if (BO->getLHS()->getType()->isIntegerType() &&
606 BO->getRHS()->getType()->isIntegerType()) {
609 BO->getLHS()->EvaluateAsInt(SimplifiedLHS, S.
Context,
612 BO->getRHS()->EvaluateAsInt(SimplifiedRHS, S.
Context,
615 if (!SimplifiedLHS.
Diag && ! SimplifiedRHS.
Diag) {
617 diag::note_atomic_constraint_evaluated_to_false_elaborated)
630 }
else if (
auto *CSE = dyn_cast<ConceptSpecializationExpr>(SubstExpr)) {
631 if (CSE->getTemplateArgsAsWritten()->NumTemplateArgs == 1) {
633 CSE->getSourceRange().getBegin(),
635 note_single_arg_concept_specialization_constraint_evaluated_to_false)
637 << CSE->getTemplateArgsAsWritten()->arguments()[0].getArgument()
638 << CSE->getNamedConcept();
641 diag::note_concept_specialization_constraint_evaluated_to_false)
642 << (
int)
First << CSE;
646 }
else if (
auto *RE = dyn_cast<RequiresExpr>(SubstExpr)) {
648 if (!Req->isDependent() && !Req->isSatisfied()) {
649 if (
auto *E = dyn_cast<concepts::ExprRequirement>(Req))
651 else if (
auto *T = dyn_cast<concepts::TypeRequirement>(Req))
655 S, cast<concepts::NestedRequirement>(Req),
First);
662 diag::note_atomic_constraint_evaluated_to_false)
666 template<
typename SubstitutionDiagnostic>
669 const llvm::PointerUnion<Expr *, SubstitutionDiagnostic *> &Record,
671 if (
auto *
Diag = Record.template dyn_cast<SubstitutionDiagnostic *>()){
672 S.
Diag(
Diag->first, diag::note_substituted_constraint_expr_is_ill_formed)
678 Record.template get<Expr *>(),
First);
685 "Attempted to diagnose a satisfied constraint");
686 for (
auto &Pair : Satisfaction.
Details) {
696 "Attempted to diagnose a satisfied constraint");
697 for (
auto &Pair : Satisfaction) {
706 auto CacheEntry = NormalizationCache.find(ConstrainedDecl);
707 if (CacheEntry == NormalizationCache.end()) {
709 NormalizedConstraint::fromConstraintExprs(*
this, ConstrainedDecl,
710 AssociatedConstraints);
713 .try_emplace(ConstrainedDecl,
716 std::move(*Normalized))
720 return CacheEntry->second;
740 llvm::SmallBitVector OccurringIndices(TemplateParams->
size());
742 0, OccurringIndices);
746 OccurringIndices.count()));
747 for (
unsigned I = 0, J = 0, C = TemplateParams->
size(); I != C; ++I)
748 if (OccurringIndices[I])
760 ArgsAsWritten->
arguments()[I].getLocation() :
764 S, ArgsAsWritten->
arguments().front().getSourceRange().getBegin(),
767 ArgsAsWritten->
arguments().back().getSourceRange().getEnd()));
780 NormalizedConstraint::fromConstraintExprs(
Sema &S,
NamedDecl *D,
782 assert(E.size() != 0);
783 auto Conjunction = fromConstraintExpr(S, D, E[0]);
786 for (
unsigned I = 1; I < E.size(); ++I) {
787 auto Next = fromConstraintExpr(S, D, E[I]);
791 std::move(*Next), CCK_Conjunction);
798 assert(E !=
nullptr);
805 if (LogicalBinOp BO = E) {
806 auto LHS = fromConstraintExpr(S, D, BO.getLHS());
809 auto RHS = fromConstraintExpr(S, D, BO.getRHS());
814 BO.isAnd() ? CCK_Conjunction : CCK_Disjunction);
815 }
else if (
auto *CSE = dyn_cast<const ConceptSpecializationExpr>(E)) {
819 S, CSE->getExprLoc(),
821 CSE->getSourceRange());
839 New.emplace(S.
Context, *SubNF);
842 S, *New, CSE->getNamedConcept(),
843 CSE->getTemplateArguments(), CSE->getTemplateArgsAsWritten()))
861 LCNF.reserve(LCNF.size() + RCNF.size());
862 while (!RCNF.empty())
863 LCNF.push_back(RCNF.pop_back_val());
869 Res.reserve(LCNF.size() * RCNF.size());
870 for (
auto &LDisjunction : LCNF)
871 for (
auto &RDisjunction : RCNF) {
872 NormalForm::value_type Combined;
873 Combined.reserve(LDisjunction.size() + RDisjunction.size());
874 std::copy(LDisjunction.begin(), LDisjunction.end(),
875 std::back_inserter(Combined));
876 std::copy(RDisjunction.begin(), RDisjunction.end(),
877 std::back_inserter(Combined));
878 Res.emplace_back(Combined);
890 LDNF.reserve(LDNF.size() + RDNF.size());
891 while (!RDNF.empty())
892 LDNF.push_back(RDNF.pop_back_val());
898 Res.reserve(LDNF.size() * RDNF.size());
899 for (
auto &LConjunction : LDNF) {
900 for (
auto &RConjunction : RDNF) {
901 NormalForm::value_type Combined;
902 Combined.reserve(LConjunction.size() + RConjunction.size());
903 std::copy(LConjunction.begin(), LConjunction.end(),
904 std::back_inserter(Combined));
905 std::copy(RConjunction.begin(), RConjunction.end(),
906 std::back_inserter(Combined));
907 Res.emplace_back(Combined);
913 template<
typename AtomicSubsumptionEvaluator>
915 AtomicSubsumptionEvaluator E) {
920 for (
const auto &Pi : PDNF) {
921 for (
const auto &Qj : QCNF) {
945 template<
typename AtomicSubsumptionEvaluator>
948 AtomicSubsumptionEvaluator E) {
971 Result = AC2.empty();
980 std::pair<NamedDecl *, NamedDecl *> Key{D1, D2};
981 auto CacheEntry = SubsumptionCache.find(Key);
982 if (CacheEntry != SubsumptionCache.end()) {
983 Result = CacheEntry->second;
987 if (
subsumes(*
this, D1, AC1, D2, AC2, Result,
992 SubsumptionCache.try_emplace(Key, Result);
998 if (isSFINAEContext())
1002 if (AC1.empty() || AC2.empty())
1005 auto NormalExprEvaluator =
1010 const Expr *AmbiguousAtomic1 =
nullptr, *AmbiguousAtomic2 =
nullptr;
1011 auto IdenticalExprEvaluator =
1021 llvm::FoldingSetNodeID IDA, IDB;
1022 EA->
Profile(IDA, Context,
true);
1023 EB->Profile(IDB, Context,
true);
1027 AmbiguousAtomic1 = EA;
1028 AmbiguousAtomic2 = EB;
1035 auto *Normalized1 = getNormalizedAssociatedConstraints(D1, AC1);
1041 auto *Normalized2 = getNormalizedAssociatedConstraints(D2, AC2);
1047 bool Is1AtLeastAs2Normally =
subsumes(DNF1, CNF2, NormalExprEvaluator);
1048 bool Is2AtLeastAs1Normally =
subsumes(DNF2, CNF1, NormalExprEvaluator);
1049 bool Is1AtLeastAs2 =
subsumes(DNF1, CNF2, IdenticalExprEvaluator);
1050 bool Is2AtLeastAs1 =
subsumes(DNF2, CNF1, IdenticalExprEvaluator);
1051 if (Is1AtLeastAs2 == Is1AtLeastAs2Normally &&
1052 Is2AtLeastAs1 == Is2AtLeastAs1Normally)
1058 assert(AmbiguousAtomic1 && AmbiguousAtomic2);
1060 Diag(AmbiguousAtomic1->
getBeginLoc(), diag::note_ambiguous_atomic_constraints)
1062 Diag(AmbiguousAtomic2->getBeginLoc(),
1063 diag::note_ambiguous_atomic_constraints_similar_expression)
1064 << AmbiguousAtomic2->getSourceRange();
1072 Requirement(IsSimple ? RK_Simple : RK_Compound, Status == SS_Dependent,
1073 Status == SS_Dependent &&
1074 (E->containsUnexpandedParameterPack() ||
1075 Req.containsUnexpandedParameterPack()),
1076 Status == SS_Satisfied),
Value(E), NoexceptLoc(NoexceptLoc),
1077 TypeReq(Req), SubstitutedConstraintExpr(SubstitutedConstraintExpr),
1080 "Simple requirement must not have a return type requirement or a "
1081 "noexcept specification");
1083 (SubstitutedConstraintExpr !=
nullptr));
1087 SubstitutionDiagnostic *ExprSubstDiag,
bool IsSimple,
1089 Requirement(IsSimple ? RK_Simple : RK_Compound, Req.isDependent(),
1090 Req.containsUnexpandedParameterPack(),
false),
1091 Value(ExprSubstDiag), NoexceptLoc(NoexceptLoc), TypeReq(Req),
1092 Status(SS_ExprSubstitutionFailure) {
1093 assert((!IsSimple || (Req.isEmpty() && NoexceptLoc.
isInvalid())) &&
1094 "Simple requirement must not have a return type requirement or a "
1095 "noexcept specification");
1100 TypeConstraintInfo(TPL,
false) {
1101 assert(TPL->
size() == 1);
1103 cast<TemplateTypeParmDecl>(TPL->
getParam(0))->getTypeConstraint();
1105 "TPL must have a template type parameter with a type constraint");
1109 Constraint->getTemplateArgsAsWritten() &&
1111 Constraint->getTemplateArgsAsWritten()->arguments().drop_front(1));
1112 TypeConstraintInfo.setInt(Dependent ?
true :
false);
1123 Status(T->getType()->isInstantiationDependentType() ?
SS_Dependent