26 #include "llvm/ADT/DenseMap.h" 27 #include "llvm/ADT/PointerUnion.h" 28 using namespace clang;
33 bool *PossibleNonPrimary,
34 bool IsTrailingRequiresClause) {
40 if (
auto *BinOp = dyn_cast<BinaryOperator>(ConstraintExpression)) {
41 if (BinOp->getOpcode() == BO_LAnd || BinOp->getOpcode() == BO_LOr)
42 return CheckConstraintExpression(BinOp->getLHS(), NextToken,
43 PossibleNonPrimary) &&
44 CheckConstraintExpression(BinOp->getRHS(), NextToken,
46 }
else if (
auto *C = dyn_cast<ExprWithCleanups>(ConstraintExpression))
47 return CheckConstraintExpression(C->getSubExpr(), NextToken,
52 auto CheckForNonPrimary = [&] {
53 if (PossibleNonPrimary)
60 (NextToken.
is(tok::l_paren) &&
61 (IsTrailingRequiresClause ||
63 IsDependentFunctionNameExpr(ConstraintExpression)) ||
84 diag::err_non_bool_atomic_constraint) << Type
90 if (PossibleNonPrimary)
91 *PossibleNonPrimary =
false;
95 template <
typename AtomicEvaluator>
99 AtomicEvaluator &&Evaluator) {
102 if (
auto *BO = dyn_cast<BinaryOperator>(ConstraintExpr)) {
103 if (BO->getOpcode() == BO_LAnd || BO->getOpcode() == BO_LOr) {
110 if (BO->getOpcode() == BO_LOr && IsLHSSatisfied)
119 if (BO->getOpcode() == BO_LAnd && !IsLHSSatisfied)
129 std::forward<AtomicEvaluator>(Evaluator));
132 else if (
auto *C = dyn_cast<ExprWithCleanups>(ConstraintExpr))
134 std::forward<AtomicEvaluator>(Evaluator));
137 ExprResult SubstitutedAtomicExpr = Evaluator(ConstraintExpr);
142 if (!SubstitutedAtomicExpr.
isUsable())
150 EvalResult.
Diag = &EvaluationDiags;
151 if (!SubstitutedAtomicExpr.
get()->EvaluateAsRValue(EvalResult, S.
Context)) {
154 S.
Diag(SubstitutedAtomicExpr.
get()->getBeginLoc(),
155 diag::err_non_constant_constraint_expression)
156 << SubstitutedAtomicExpr.
get()->getSourceRange();
158 S.
Diag(PDiag.first, PDiag.second);
164 Satisfaction.
Details.emplace_back(ConstraintExpr,
165 SubstitutedAtomicExpr.
get());
187 if (Inst.isInvalid())
191 SubstitutedExpression = S.
SubstExpr(const_cast<Expr *>(AtomicExpr),
214 unsigned MessageSize = DiagString.size();
215 char *Mem =
new (S.
Context)
char[MessageSize];
216 memcpy(Mem, DiagString.c_str(), MessageSize);
217 Satisfaction.
Details.emplace_back(
220 SubstDiag.first, StringRef(Mem, MessageSize)});
229 return SubstitutedExpression;
238 if (ConstraintExprs.empty()) {
243 for (
auto& Arg : TemplateArgs)
244 if (Arg.isInstantiationDependent()) {
252 const_cast<NamedDecl *
>(Template), TemplateArgs, TemplateIDRange);
259 for (
const Expr *ConstraintExpr : ConstraintExprs) {
262 ConstraintExpr, Satisfaction))
278 if (ConstraintExprs.empty()) {
283 llvm::FoldingSetNodeID
ID;
286 bool ShouldCache = LangOpts.ConceptSatisfactionCaching && Template;
289 Satisfaction = SatisfactionCache.FindNodeOrInsertPos(ID, InsertPos);
291 OutSatisfaction = *Satisfaction;
296 Satisfaction = &OutSatisfaction;
299 TemplateArgs, TemplateIDRange,
309 SatisfactionCache.InsertNode(Satisfaction);
310 OutSatisfaction = *Satisfaction;
318 *
this, ConstraintExpr, Satisfaction,
320 return ExprResult(const_cast<Expr *>(AtomicExpr));
334 if (
auto *Method = dyn_cast<CXXMethodDecl>(FD)) {
335 ThisQuals = Method->getMethodQualifiers();
355 TemplateIDRange, Satisfaction))
360 TemplateArgString =
" ";
361 TemplateArgString += getTemplateArgumentBindingsText(
365 diag::err_template_arg_list_constraints_not_satisfied)
366 << (
int)getTemplateNameKindForDiagnostics(
TemplateName(TD)) << TD
367 << TemplateArgString << TemplateIDRange;
368 DiagnoseUnsatisfiedConstraint(Satisfaction);
378 &&
"Diagnose() can only be used on an unsatisfied requirement");
381 llvm_unreachable(
"Diagnosing a dependent requirement");
385 if (!SubstDiag->DiagMessage.empty())
386 S.
Diag(SubstDiag->DiagLoc,
387 diag::note_expr_requirement_expr_substitution_error)
388 << (int)First << SubstDiag->SubstitutedEntity
389 << SubstDiag->DiagMessage;
391 S.
Diag(SubstDiag->DiagLoc,
392 diag::note_expr_requirement_expr_unknown_substitution_error)
393 << (int)First << SubstDiag->SubstitutedEntity;
398 diag::note_expr_requirement_noexcept_not_met)
399 << (
int)First << Req->
getExpr();
404 if (!SubstDiag->DiagMessage.empty())
405 S.
Diag(SubstDiag->DiagLoc,
406 diag::note_expr_requirement_type_requirement_substitution_error)
407 << (int)First << SubstDiag->SubstitutedEntity
408 << SubstDiag->DiagMessage;
410 S.
Diag(SubstDiag->DiagLoc,
411 diag::note_expr_requirement_type_requirement_unknown_substitution_error)
412 << (int)First << SubstDiag->SubstitutedEntity;
422 diag::note_expr_requirement_constraints_not_satisfied_simple)
428 diag::note_expr_requirement_constraints_not_satisfied)
429 << (
int)First << ConstraintExpr;
434 llvm_unreachable(
"We checked this above");
442 &&
"Diagnose() can only be used on an unsatisfied requirement");
445 llvm_unreachable(
"Diagnosing a dependent requirement");
449 if (!SubstDiag->DiagMessage.empty())
450 S.
Diag(SubstDiag->DiagLoc,
451 diag::note_type_requirement_substitution_error) << (int)First
452 << SubstDiag->SubstitutedEntity << SubstDiag->DiagMessage;
454 S.
Diag(SubstDiag->DiagLoc,
455 diag::note_type_requirement_unknown_substitution_error)
456 << (int)First << SubstDiag->SubstitutedEntity;
460 llvm_unreachable(
"Unknown satisfaction status");
473 diag::note_nested_requirement_substitution_error)
478 diag::note_nested_requirement_unknown_substitution_error)
491 switch (BO->getOpcode()) {
503 BO->getLHS()->EvaluateAsBooleanCondition(LHSSatisfied, S.
Context);
514 BO->getRHS()->EvaluateAsBooleanCondition(RHSSatisfied, S.
Context);
525 if (BO->getLHS()->getType()->isIntegerType() &&
526 BO->getRHS()->getType()->isIntegerType()) {
529 BO->getLHS()->EvaluateAsInt(SimplifiedLHS, S.
Context);
530 BO->getRHS()->EvaluateAsInt(SimplifiedRHS, S.
Context);
531 if (!SimplifiedLHS.
Diag && ! SimplifiedRHS.
Diag) {
533 diag::note_atomic_constraint_evaluated_to_false_elaborated)
534 << (
int)
First << SubstExpr
535 << SimplifiedLHS.
Val.
getInt().toString(10)
537 << SimplifiedRHS.
Val.
getInt().toString(10);
546 }
else if (
auto *CSE = dyn_cast<ConceptSpecializationExpr>(SubstExpr)) {
547 if (CSE->getTemplateArgsAsWritten()->NumTemplateArgs == 1) {
549 CSE->getSourceRange().getBegin(),
551 note_single_arg_concept_specialization_constraint_evaluated_to_false)
553 << CSE->getTemplateArgsAsWritten()->arguments()[0].getArgument()
554 << CSE->getNamedConcept();
557 diag::note_concept_specialization_constraint_evaluated_to_false)
558 << (
int)
First << CSE;
562 }
else if (
auto *RE = dyn_cast<RequiresExpr>(SubstExpr)) {
564 if (!Req->isDependent() && !Req->isSatisfied()) {
565 if (
auto *E = dyn_cast<concepts::ExprRequirement>(Req))
567 else if (
auto *T = dyn_cast<concepts::TypeRequirement>(Req))
571 S, cast<concepts::NestedRequirement>(Req),
First);
578 diag::note_atomic_constraint_evaluated_to_false)
579 << (
int)
First << SubstExpr;
582 template<
typename SubstitutionDiagnostic>
585 const llvm::PointerUnion<Expr *, SubstitutionDiagnostic *> &Record,
587 if (
auto *
Diag = Record.template dyn_cast<SubstitutionDiagnostic *>()){
588 S.
Diag(
Diag->first, diag::note_substituted_constraint_expr_is_ill_formed)
594 Record.template get<Expr *>(),
First);
601 "Attempted to diagnose a satisfied constraint");
602 for (
auto &Pair : Satisfaction.
Details) {
612 "Attempted to diagnose a satisfied constraint");
613 for (
auto &Pair : Satisfaction) {
622 auto CacheEntry = NormalizationCache.find(ConstrainedDecl);
623 if (CacheEntry == NormalizationCache.end()) {
625 NormalizedConstraint::fromConstraintExprs(*
this, ConstrainedDecl,
626 AssociatedConstraints);
629 .try_emplace(ConstrainedDecl,
632 std::move(*Normalized))
636 return CacheEntry->second;
656 llvm::SmallBitVector OccurringIndices(TemplateParams->size());
658 0, OccurringIndices);
662 OccurringIndices.count()));
663 for (
unsigned I = 0, J = 0, C = TemplateParams->size(); I != C; ++I)
664 if (OccurringIndices[I])
676 ArgsAsWritten->
arguments()[I].getLocation() :
680 S, ArgsAsWritten->
arguments().front().getSourceRange().getBegin(),
683 ArgsAsWritten->
arguments().back().getSourceRange().getEnd()));
696 NormalizedConstraint::fromConstraintExprs(
Sema &S,
NamedDecl *D,
698 assert(E.size() != 0);
699 auto First = fromConstraintExpr(S, D, E[0]);
702 auto Second = fromConstraintExpr(S, D, E[1]);
706 Conjunction.emplace(S.
Context, std::move(*First), std::move(*Second),
708 for (
unsigned I = 2; I < E.size(); ++I) {
709 auto Next = fromConstraintExpr(S, D, E[I]);
713 std::move(*Next), CCK_Conjunction);
714 *Conjunction = std::move(NewConjunction);
721 assert(E !=
nullptr);
728 if (
auto *BO = dyn_cast<const BinaryOperator>(E)) {
729 if (BO->getOpcode() == BO_LAnd || BO->getOpcode() == BO_LOr) {
730 auto LHS = fromConstraintExpr(S, D, BO->getLHS());
733 auto RHS = fromConstraintExpr(S, D, BO->getRHS());
738 S.
Context, std::move(*LHS), std::move(*RHS),
739 BO->getOpcode() == BO_LAnd ? CCK_Conjunction : CCK_Disjunction);
741 }
else if (
auto *CSE = dyn_cast<const ConceptSpecializationExpr>(E)) {
745 S, CSE->getExprLoc(),
759 {CD->getConstraintExpr()});
765 New.emplace(S.
Context, *SubNF);
768 S, *New, CSE->getNamedConcept(),
769 CSE->getTemplateArguments(), CSE->getTemplateArgsAsWritten()))
787 LCNF.reserve(LCNF.size() + RCNF.size());
788 while (!RCNF.empty())
789 LCNF.push_back(RCNF.pop_back_val());
795 Res.reserve(LCNF.size() * RCNF.size());
796 for (
auto &LDisjunction : LCNF)
797 for (
auto &RDisjunction : RCNF) {
798 NormalForm::value_type Combined;
799 Combined.reserve(LDisjunction.size() + RDisjunction.size());
800 std::copy(LDisjunction.begin(), LDisjunction.end(),
801 std::back_inserter(Combined));
802 std::copy(RDisjunction.begin(), RDisjunction.end(),
803 std::back_inserter(Combined));
804 Res.emplace_back(Combined);
816 LDNF.reserve(LDNF.size() + RDNF.size());
817 while (!RDNF.empty())
818 LDNF.push_back(RDNF.pop_back_val());
824 Res.reserve(LDNF.size() * RDNF.size());
825 for (
auto &LConjunction : LDNF) {
826 for (
auto &RConjunction : RDNF) {
827 NormalForm::value_type Combined;
828 Combined.reserve(LConjunction.size() + RConjunction.size());
829 std::copy(LConjunction.begin(), LConjunction.end(),
830 std::back_inserter(Combined));
831 std::copy(RConjunction.begin(), RConjunction.end(),
832 std::back_inserter(Combined));
833 Res.emplace_back(Combined);
839 template<
typename AtomicSubsumptionEvaluator>
841 AtomicSubsumptionEvaluator E) {
846 for (
const auto &Pi : PDNF) {
847 for (
const auto &Qj : QCNF) {
871 template<
typename AtomicSubsumptionEvaluator>
874 AtomicSubsumptionEvaluator E) {
897 Result = AC2.empty();
906 std::pair<NamedDecl *, NamedDecl *> Key{D1, D2};
907 auto CacheEntry = SubsumptionCache.find(Key);
908 if (CacheEntry != SubsumptionCache.end()) {
909 Result = CacheEntry->second;
913 if (
subsumes(*
this, D1, AC1, D2, AC2, Result,
918 SubsumptionCache.try_emplace(Key, Result);
924 if (isSFINAEContext())
928 if (AC1.empty() || AC2.empty())
931 auto NormalExprEvaluator =
936 const Expr *AmbiguousAtomic1 =
nullptr, *AmbiguousAtomic2 =
nullptr;
937 auto IdenticalExprEvaluator =
947 llvm::FoldingSetNodeID IDA, IDB;
948 EA->
Profile(IDA, Context,
true);
949 EB->Profile(IDB, Context,
true);
953 AmbiguousAtomic1 = EA;
954 AmbiguousAtomic2 = EB;
961 auto *Normalized1 = getNormalizedAssociatedConstraints(D1, AC1);
967 auto *Normalized2 = getNormalizedAssociatedConstraints(D2, AC2);
973 bool Is1AtLeastAs2Normally =
subsumes(DNF1, CNF2, NormalExprEvaluator);
974 bool Is2AtLeastAs1Normally =
subsumes(DNF2, CNF1, NormalExprEvaluator);
975 bool Is1AtLeastAs2 =
subsumes(DNF1, CNF2, IdenticalExprEvaluator);
976 bool Is2AtLeastAs1 =
subsumes(DNF2, CNF1, IdenticalExprEvaluator);
977 if (Is1AtLeastAs2 == Is1AtLeastAs2Normally &&
978 Is2AtLeastAs1 == Is2AtLeastAs1Normally)
984 assert(AmbiguousAtomic1 && AmbiguousAtomic2);
986 Diag(AmbiguousAtomic1->
getBeginLoc(), diag::note_ambiguous_atomic_constraints)
988 Diag(AmbiguousAtomic2->getBeginLoc(),
989 diag::note_ambiguous_atomic_constraints_similar_expression)
990 << AmbiguousAtomic2->getSourceRange();
998 Requirement(IsSimple ? RK_Simple : RK_Compound, Status == SS_Dependent,
999 Status == SS_Dependent &&
1000 (E->containsUnexpandedParameterPack() ||
1001 Req.containsUnexpandedParameterPack()),
1002 Status == SS_Satisfied),
Value(E), NoexceptLoc(NoexceptLoc),
1003 TypeReq(Req), SubstitutedConstraintExpr(SubstitutedConstraintExpr),
1006 "Simple requirement must not have a return type requirement or a " 1007 "noexcept specification");
1009 (SubstitutedConstraintExpr !=
nullptr));
1017 Value(ExprSubstDiag), NoexceptLoc(NoexceptLoc), TypeReq(Req),
1020 "Simple requirement must not have a return type requirement or a " 1021 "noexcept specification");
1026 TypeConstraintInfo(TPL, 0) {
1027 assert(TPL->
size() == 1);
1031 "TPL must have a template type parameter with a type constraint");
1033 cast_or_null<ConceptSpecializationExpr>(
1034 TC->getImmediatelyDeclaredConstraint());
1035 bool Dependent =
false;
1036 if (Constraint->getTemplateArgsAsWritten()) {
1038 Constraint->getTemplateArgsAsWritten()->arguments().drop_front(1)) {
1039 if (ArgLoc.getArgument().isDependent()) {
1045 TypeConstraintInfo.setInt(Dependent ? 1 : 0);
Represents a function declaration or definition.
static bool CheckConstraintSatisfaction(Sema &S, const NamedDecl *Template, ArrayRef< const Expr *> ConstraintExprs, ArrayRef< TemplateArgument > TemplateArgs, SourceRange TemplateIDRange, ConstraintSatisfaction &Satisfaction)
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.
A (possibly-)qualified type.
void DiagnoseUnsatisfiedConstraint(const ConstraintSatisfaction &Satisfaction, bool First=true)
Emit diagnostics explaining why a constraint expression was deemed unsatisfied.
A requires-expression requirement which queries the validity and properties of an expression ('simple...
void addOuterTemplateArguments(const TemplateArgumentList *TemplateArgs)
Add a new outermost level to the multi-level template argument list.
Provides information about an attempted template argument deduction, whose success or failure was des...
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)) {...
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
Emit a diagnostic.
bool subsumes(ASTContext &C, const AtomicConstraint &Other) const
The base class of the type hierarchy.
const Expr * ConstraintExpr
NamedDecl * getParam(unsigned Idx)
A container of type source information.
SubstitutionDiagnostic * getSubstitutionDiagnostic() const
SubstitutionDiagnostic * getExprSubstitutionDiagnostic() const
RAII object that enters a new expression evaluation context.
static void diagnoseUnsatisfiedConstraintExpr(Sema &S, const Expr *E, const llvm::PointerUnion< Expr *, SubstitutionDiagnostic *> &Record, bool First=true)
ExprRequirement(Expr *E, bool IsSimple, SourceLocation NoexceptLoc, ReturnTypeRequirement Req, SatisfactionStatus Status, ConceptSpecializationExpr *SubstitutedConstraintExpr=nullptr)
Construct a compound requirement.
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, bool Canonical) const
Produce a unique representation of the given statement.
RAII object used to temporarily allow the C++ 'this' expression to be used, with the given qualifiers...
Represents an explicit template argument list in C++, e.g., the "<int>" in "sort<int>".
Stores a list of template parameters for a TemplateDecl and its derived classes.
static void diagnoseUnsatisfiedRequirement(Sema &S, concepts::ExprRequirement *Req, bool First)
llvm::ArrayRef< TemplateArgumentLoc > arguments() const
tok::TokenKind getKind() const
The collection of all-type qualifiers we support.
SourceLocation getBeginLoc() const LLVM_READONLY
virtual SourceRange getSourceRange() const LLVM_READONLY
Source range that this declaration covers.
Token - This structure provides full information about a lexed token.
bool isSpecificBuiltinType(unsigned K) const
Test for a particular builtin type.
StringRef getOpcodeStr() const
SmallVectorImpl< PartialDiagnosticAt > * Diag
Diag - If this is non-null, it will be filled in with a stack of notes indicating why evaluation fail...
bool hasMatchingParameterMapping(ASTContext &C, const AtomicConstraint &Other) const
APValue Val
Val - This is the value the expression can be folded to.
A convenient class for passing around template argument information.
SatisfactionStatus getSatisfactionStatus() const
static bool calculateConstraintSatisfaction(Sema &S, const Expr *ConstraintExpr, ConstraintSatisfaction &Satisfaction, AtomicEvaluator &&Evaluator)
A builtin binary operation expression such as "x + y" or "x <= y".
ConceptDecl * getNamedConcept() const
bool MaybeEmitAmbiguousAtomicConstraintsDiagnostic(NamedDecl *D1, ArrayRef< const Expr *> AC1, NamedDecl *D2, ArrayRef< const Expr *> AC2)
If D1 was not at least as constrained as D2, but would've been if a pair of atomic constraints involv...
std::pair< SourceLocation, StringRef > SubstitutionDiagnostic
SubstitutionDiagnostic * getSubstitutionDiagnostic() const
TemplateArgumentLoc getIdentityTemplateArgumentLoc(NamedDecl *Param, SourceLocation Location)
Get a template argument mapping the given template parameter to itself, e.g.
bool isTypeDependent() const
isTypeDependent - Determines whether this expression is type-dependent (C++ [temp.dep.expr]), which means that its type could change from one template instantiation to the next.
The current context is "potentially evaluated" in C++11 terms, but the expression is evaluated at com...
bool IsAtLeastAsConstrained(NamedDecl *D1, ArrayRef< const Expr *> AC1, NamedDecl *D2, ArrayRef< const Expr *> AC2, bool &Result)
Check whether the given declaration's associated constraints are at least as constrained than another...
DiagnosticsEngine & getDiagnostics() const
RAII class used to determine whether SFINAE has trapped any errors that occur during template argumen...
Sema - This implements semantic analysis and AST building for C.
A requires-expression requirement which queries the existence of a type name or type template special...
static NormalForm makeCNF(const NormalizedConstraint &Normalized)
The result of a constraint satisfaction check, containing the necessary information to diagnose an un...
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
This represents one expression.
static bool substituteParameterMappings(Sema &S, NormalizedConstraint &N, ConceptDecl *Concept, ArrayRef< TemplateArgument > TemplateArgs, const ASTTemplateArgumentListInfo *ArgsAsWritten)
ConceptSpecializationExpr * getReturnTypeRequirementSubstitutedConstraintExpr() const
static bool subsumes(NormalForm PDNF, NormalForm QCNF, AtomicSubsumptionEvaluator E)
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &C)
void takeSFINAEDiagnostic(PartialDiagnosticAt &PD)
Take ownership of the SFINAE diagnostic.
bool CheckConstraintSatisfaction(const NamedDecl *Template, ArrayRef< const Expr *> ConstraintExprs, ArrayRef< TemplateArgument > TemplateArgs, SourceRange TemplateIDRange, ConstraintSatisfaction &Satisfaction)
Check whether the given list of constraint expressions are satisfied (as if in a 'conjunction') given...
unsigned NumTemplateArgs
The number of template arguments in TemplateArgs.
bool isInvalid() const
Determines whether we have exceeded the maximum recursive template instantiations.
bool containsUnexpandedParameterPack() const
bool isSubstitutionFailure() const
static void diagnoseWellFormedUnsatisfiedConstraintExpr(Sema &S, Expr *SubstExpr, bool First=true)
SatisfactionStatus getSatisfactionStatus() const
Represents a C++ template name within the type system.
bool isTypeConstraint() const
NormalizedConstraint & getRHS() const
Defines and computes precedence levels for binary/ternary operators.
Data structure that captures multiple levels of template argument lists for use in template instantia...
const ASTTemplateArgumentListInfo * getTemplateArgsAsWritten() const
StringRef SubstitutedEntity
CompoundConstraintKind getCompoundKind() const
Expr * getTrailingRequiresClause()
Get the constraint-expression introduced by the trailing requires-clause in the function/member decla...
ActionResult - This structure is used while parsing/acting on expressions, stmts, etc...
bool isInstantiationDependent() const
Whether this expression is instantiation-dependent, meaning that it depends in some way on a template...
A stack object to be created when performing template instantiation.
Encodes a location in the source.
std::pair< SourceLocation, PartialDiagnostic > PartialDiagnosticAt
A partial diagnostic along with the source location where this diagnostic occurs. ...
SourceLocation getNoexceptLoc() const
AtomicExpr - Variadic atomic builtins: __atomic_exchange, __atomic_fetch_*, __atomic_load, __atomic_store, and __atomic_compare_exchange_*, for the similarly-named C++11 instructions, and __c11 variants for <stdatomic.h>, and corresponding __opencl_atomic_* for OpenCL 2.0.
SubstitutionDiagnostic * getSubstitutionDiagnostic() const
bool SubstTemplateArguments(ArrayRef< TemplateArgumentLoc > Args, const MultiLevelTemplateArgumentList &TemplateArgs, TemplateArgumentListInfo &Outputs)
const NormalizedConstraint * getNormalizedAssociatedConstraints(NamedDecl *ConstrainedDecl, ArrayRef< const Expr *> AssociatedConstraints)
SourceLocation getBeginLoc() const LLVM_READONLY
A static requirement that can be used in a requires-expression to check properties of types and expre...
__DEVICE__ void * memcpy(void *__a, const void *__b, size_t __c)
bool hasSameUnqualifiedType(QualType T1, QualType T2) const
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
Dataflow Directional Tag Classes.
bool isValid() const
Return true if this is a valid SourceLocation object.
EvalResult is a struct with detailed info about an evaluated expression.
The base class of all kinds of template declarations (e.g., class, function, etc.).
const ASTConstraintSatisfaction & getConstraintSatisfaction() const
ReturnTypeRequirement()
No return type requirement was specified.
llvm::ArrayRef< TemplateArgumentLoc > arguments() const
NormalizedConstraint & getLHS() const
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
llvm::SmallVector< std::pair< const Expr *, Detail >, 4 > Details
Pairs of unsatisfied atomic constraint expressions along with the substituted constraint expr...
Location wrapper for a TemplateArgument.
bool CheckConstraintExpression(Expr *CE, Token NextToken=Token(), bool *PossibleNonPrimary=nullptr, bool IsTrailingRequiresClause=false)
Check whether the given expression is a valid constraint expression.
bool containsUnexpandedParameterPack() const
bool isFunctionType() const
The result of a constraint satisfaction check, containing the necessary information to diagnose an un...
QualType BuildDecltypeType(Expr *E, SourceLocation Loc, bool AsUnevaluated=true)
If AsUnevaluated is false, E is treated as though it were an evaluated context, such as when building...
bool CheckFunctionConstraints(const FunctionDecl *FD, ConstraintSatisfaction &Satisfaction, SourceLocation UsageLoc=SourceLocation())
Check whether the given function decl's trailing requires clause is satisfied, if any...
ExprResult SubstExpr(Expr *E, const MultiLevelTemplateArgumentList &TemplateArgs)
ActionResult< Expr * > ExprResult
Defines Expressions and AST nodes for C++2a concepts.
Represents a C++ struct/union/class.
void getAssociatedConstraints(llvm::SmallVectorImpl< const Expr *> &AC) const
Get the total constraint-expression associated with this template, including constraint-expressions d...
TypeRequirement(TypeSourceInfo *T)
Construct a type requirement from a type.
A requires-expression requirement which is satisfied when a general constraint expression is satisfie...
Represents the specialization of a concept - evaluates to a prvalue of type bool. ...
bool EnsureTemplateArgumentListConstraints(TemplateDecl *Template, ArrayRef< TemplateArgument > TemplateArgs, SourceRange TemplateIDRange)
Ensure that the given template arguments satisfy the constraints associated with the given template...
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
void MarkUsedTemplateParameters(const Expr *E, bool OnlyDeduced, unsigned Depth, llvm::SmallBitVector &Used)
Mark which template parameters are used in a given expression.
prec::Level getBinOpPrecedence(tok::TokenKind Kind, bool GreaterThanIsOperator, bool CPlusPlus11)
Return the precedence of the specified binary operator token.
AtomicConstraint * getAtomicConstraint() const
static NormalForm makeDNF(const NormalizedConstraint &Normalized)
A trivial tuple used to represent a source range.
This represents a decl that may have a name.
const TypeConstraint * getTypeConstraint() const
Optional< MutableArrayRef< TemplateArgumentLoc > > ParameterMapping
SourceLocation getBegin() const
SourceLocation getLocation() const
A normalized constraint, as defined in C++ [temp.constr.normal], is either an atomic constraint...
bool hasErrorOccurred() const
Determine whether any SFINAE errors have been trapped.
const ReturnTypeRequirement & getReturnTypeRequirement() const