[clang] support pack expansions for trailing requires clauses (#133190)
This commit is contained in:
parent
c1ada72b09
commit
49fd0bf35d
@ -100,9 +100,9 @@ computeReferencedDecls(const clang::Expr *Expr) {
|
|||||||
TraverseLambdaCapture(LExpr, &Capture, Initializer);
|
TraverseLambdaCapture(LExpr, &Capture, Initializer);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (clang::Expr *const RequiresClause =
|
if (const clang::Expr *RequiresClause =
|
||||||
LExpr->getTrailingRequiresClause()) {
|
LExpr->getTrailingRequiresClause().ConstraintExpr) {
|
||||||
TraverseStmt(RequiresClause);
|
TraverseStmt(const_cast<clang::Expr *>(RequiresClause));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto *const TemplateParam : LExpr->getExplicitTemplateParameters())
|
for (auto *const TemplateParam : LExpr->getExplicitTemplateParameters())
|
||||||
|
@ -385,6 +385,8 @@ Bug Fixes to C++ Support
|
|||||||
- Improved fix for an issue with pack expansions of type constraints, where this
|
- Improved fix for an issue with pack expansions of type constraints, where this
|
||||||
now also works if the constraint has non-type or template template parameters.
|
now also works if the constraint has non-type or template template parameters.
|
||||||
(#GH131798)
|
(#GH131798)
|
||||||
|
- Fix crash when evaluating the trailing requires clause of generic lambdas which are part of
|
||||||
|
a pack expansion.
|
||||||
- Fixes matching of nested template template parameters. (#GH130362)
|
- Fixes matching of nested template template parameters. (#GH130362)
|
||||||
- Correctly diagnoses template template paramters which have a pack parameter
|
- Correctly diagnoses template template paramters which have a pack parameter
|
||||||
not in the last position.
|
not in the last position.
|
||||||
|
@ -2907,6 +2907,14 @@ public:
|
|||||||
/// that they may be used in declarations of the same template.
|
/// that they may be used in declarations of the same template.
|
||||||
bool isSameTemplateParameter(const NamedDecl *X, const NamedDecl *Y) const;
|
bool isSameTemplateParameter(const NamedDecl *X, const NamedDecl *Y) const;
|
||||||
|
|
||||||
|
/// Determine whether two 'requires' expressions are similar enough that they
|
||||||
|
/// may be used in re-declarations.
|
||||||
|
///
|
||||||
|
/// Use of 'requires' isn't mandatory, works with constraints expressed in
|
||||||
|
/// other ways too.
|
||||||
|
bool isSameAssociatedConstraint(const AssociatedConstraint &ACX,
|
||||||
|
const AssociatedConstraint &ACY) const;
|
||||||
|
|
||||||
/// Determine whether two 'requires' expressions are similar enough that they
|
/// Determine whether two 'requires' expressions are similar enough that they
|
||||||
/// may be used in re-declarations.
|
/// may be used in re-declarations.
|
||||||
///
|
///
|
||||||
|
@ -538,8 +538,8 @@ public:
|
|||||||
for (const auto *Parameter : D->parameters())
|
for (const auto *Parameter : D->parameters())
|
||||||
Visit(Parameter);
|
Visit(Parameter);
|
||||||
|
|
||||||
if (const Expr *TRC = D->getTrailingRequiresClause())
|
if (const AssociatedConstraint &TRC = D->getTrailingRequiresClause())
|
||||||
Visit(TRC);
|
Visit(TRC.ConstraintExpr);
|
||||||
|
|
||||||
if (Traversal == TK_IgnoreUnlessSpelledInSource && D->isDefaulted())
|
if (Traversal == TK_IgnoreUnlessSpelledInSource && D->isDefaulted())
|
||||||
return;
|
return;
|
||||||
|
@ -81,13 +81,19 @@ enum class ImplicitParamKind;
|
|||||||
// Holds a constraint expression along with a pack expansion index, if
|
// Holds a constraint expression along with a pack expansion index, if
|
||||||
// expanded.
|
// expanded.
|
||||||
struct AssociatedConstraint {
|
struct AssociatedConstraint {
|
||||||
const Expr *ConstraintExpr;
|
const Expr *ConstraintExpr = nullptr;
|
||||||
int ArgumentPackSubstitutionIndex;
|
int ArgumentPackSubstitutionIndex = -1;
|
||||||
|
|
||||||
|
constexpr AssociatedConstraint() = default;
|
||||||
|
|
||||||
explicit AssociatedConstraint(const Expr *ConstraintExpr,
|
explicit AssociatedConstraint(const Expr *ConstraintExpr,
|
||||||
int ArgumentPackSubstitutionIndex = -1)
|
int ArgumentPackSubstitutionIndex = -1)
|
||||||
: ConstraintExpr(ConstraintExpr),
|
: ConstraintExpr(ConstraintExpr),
|
||||||
ArgumentPackSubstitutionIndex(ArgumentPackSubstitutionIndex) {}
|
ArgumentPackSubstitutionIndex(ArgumentPackSubstitutionIndex) {}
|
||||||
|
|
||||||
|
explicit operator bool() const { return ConstraintExpr != nullptr; }
|
||||||
|
|
||||||
|
bool isNull() const { return !operator bool(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
/// The top declaration context.
|
/// The top declaration context.
|
||||||
@ -754,7 +760,7 @@ class DeclaratorDecl : public ValueDecl {
|
|||||||
// and constrained function decls.
|
// and constrained function decls.
|
||||||
struct ExtInfo : public QualifierInfo {
|
struct ExtInfo : public QualifierInfo {
|
||||||
TypeSourceInfo *TInfo = nullptr;
|
TypeSourceInfo *TInfo = nullptr;
|
||||||
Expr *TrailingRequiresClause = nullptr;
|
AssociatedConstraint TrailingRequiresClause;
|
||||||
};
|
};
|
||||||
|
|
||||||
llvm::PointerUnion<TypeSourceInfo *, ExtInfo *> DeclInfo;
|
llvm::PointerUnion<TypeSourceInfo *, ExtInfo *> DeclInfo;
|
||||||
@ -823,17 +829,12 @@ public:
|
|||||||
/// \brief Get the constraint-expression introduced by the trailing
|
/// \brief Get the constraint-expression introduced by the trailing
|
||||||
/// requires-clause in the function/member declaration, or null if no
|
/// requires-clause in the function/member declaration, or null if no
|
||||||
/// requires-clause was provided.
|
/// requires-clause was provided.
|
||||||
Expr *getTrailingRequiresClause() {
|
const AssociatedConstraint &getTrailingRequiresClause() const {
|
||||||
return hasExtInfo() ? getExtInfo()->TrailingRequiresClause
|
static constexpr AssociatedConstraint Null;
|
||||||
: nullptr;
|
return hasExtInfo() ? getExtInfo()->TrailingRequiresClause : Null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Expr *getTrailingRequiresClause() const {
|
void setTrailingRequiresClause(const AssociatedConstraint &AC);
|
||||||
return hasExtInfo() ? getExtInfo()->TrailingRequiresClause
|
|
||||||
: nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setTrailingRequiresClause(Expr *TrailingRequiresClause);
|
|
||||||
|
|
||||||
unsigned getNumTemplateParameterLists() const {
|
unsigned getNumTemplateParameterLists() const {
|
||||||
return hasExtInfo() ? getExtInfo()->NumTemplParamLists : 0;
|
return hasExtInfo() ? getExtInfo()->NumTemplParamLists : 0;
|
||||||
@ -2102,7 +2103,7 @@ protected:
|
|||||||
const DeclarationNameInfo &NameInfo, QualType T,
|
const DeclarationNameInfo &NameInfo, QualType T,
|
||||||
TypeSourceInfo *TInfo, StorageClass S, bool UsesFPIntrin,
|
TypeSourceInfo *TInfo, StorageClass S, bool UsesFPIntrin,
|
||||||
bool isInlineSpecified, ConstexprSpecKind ConstexprKind,
|
bool isInlineSpecified, ConstexprSpecKind ConstexprKind,
|
||||||
Expr *TrailingRequiresClause = nullptr);
|
const AssociatedConstraint &TrailingRequiresClause);
|
||||||
|
|
||||||
using redeclarable_base = Redeclarable<FunctionDecl>;
|
using redeclarable_base = Redeclarable<FunctionDecl>;
|
||||||
|
|
||||||
@ -2138,7 +2139,7 @@ public:
|
|||||||
TypeSourceInfo *TInfo, StorageClass SC, bool UsesFPIntrin = false,
|
TypeSourceInfo *TInfo, StorageClass SC, bool UsesFPIntrin = false,
|
||||||
bool isInlineSpecified = false, bool hasWrittenPrototype = true,
|
bool isInlineSpecified = false, bool hasWrittenPrototype = true,
|
||||||
ConstexprSpecKind ConstexprKind = ConstexprSpecKind::Unspecified,
|
ConstexprSpecKind ConstexprKind = ConstexprSpecKind::Unspecified,
|
||||||
Expr *TrailingRequiresClause = nullptr) {
|
const AssociatedConstraint &TrailingRequiresClause = {}) {
|
||||||
DeclarationNameInfo NameInfo(N, NLoc);
|
DeclarationNameInfo NameInfo(N, NLoc);
|
||||||
return FunctionDecl::Create(C, DC, StartLoc, NameInfo, T, TInfo, SC,
|
return FunctionDecl::Create(C, DC, StartLoc, NameInfo, T, TInfo, SC,
|
||||||
UsesFPIntrin, isInlineSpecified,
|
UsesFPIntrin, isInlineSpecified,
|
||||||
@ -2151,7 +2152,7 @@ public:
|
|||||||
const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo,
|
const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo,
|
||||||
StorageClass SC, bool UsesFPIntrin, bool isInlineSpecified,
|
StorageClass SC, bool UsesFPIntrin, bool isInlineSpecified,
|
||||||
bool hasWrittenPrototype, ConstexprSpecKind ConstexprKind,
|
bool hasWrittenPrototype, ConstexprSpecKind ConstexprKind,
|
||||||
Expr *TrailingRequiresClause);
|
const AssociatedConstraint &TrailingRequiresClause);
|
||||||
|
|
||||||
static FunctionDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID);
|
static FunctionDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID);
|
||||||
|
|
||||||
@ -2644,9 +2645,9 @@ public:
|
|||||||
/// Use this instead of getTrailingRequiresClause for concepts APIs that
|
/// Use this instead of getTrailingRequiresClause for concepts APIs that
|
||||||
/// accept an ArrayRef of constraint expressions.
|
/// accept an ArrayRef of constraint expressions.
|
||||||
void
|
void
|
||||||
getAssociatedConstraints(SmallVectorImpl<AssociatedConstraint> &AC) const {
|
getAssociatedConstraints(SmallVectorImpl<AssociatedConstraint> &ACs) const {
|
||||||
if (auto *TRC = getTrailingRequiresClause())
|
if (const AssociatedConstraint &AC = getTrailingRequiresClause())
|
||||||
AC.emplace_back(TRC);
|
ACs.emplace_back(AC);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the message that indicates why this function was deleted.
|
/// Get the message that indicates why this function was deleted.
|
||||||
|
@ -1974,7 +1974,7 @@ private:
|
|||||||
const DeclarationNameInfo &NameInfo, QualType T,
|
const DeclarationNameInfo &NameInfo, QualType T,
|
||||||
TypeSourceInfo *TInfo, SourceLocation EndLocation,
|
TypeSourceInfo *TInfo, SourceLocation EndLocation,
|
||||||
CXXConstructorDecl *Ctor, DeductionCandidate Kind,
|
CXXConstructorDecl *Ctor, DeductionCandidate Kind,
|
||||||
Expr *TrailingRequiresClause,
|
const AssociatedConstraint &TrailingRequiresClause,
|
||||||
const CXXDeductionGuideDecl *GeneratedFrom,
|
const CXXDeductionGuideDecl *GeneratedFrom,
|
||||||
SourceDeductionGuideKind SourceKind)
|
SourceDeductionGuideKind SourceKind)
|
||||||
: FunctionDecl(CXXDeductionGuide, C, DC, StartLoc, NameInfo, T, TInfo,
|
: FunctionDecl(CXXDeductionGuide, C, DC, StartLoc, NameInfo, T, TInfo,
|
||||||
@ -2007,7 +2007,7 @@ public:
|
|||||||
TypeSourceInfo *TInfo, SourceLocation EndLocation,
|
TypeSourceInfo *TInfo, SourceLocation EndLocation,
|
||||||
CXXConstructorDecl *Ctor = nullptr,
|
CXXConstructorDecl *Ctor = nullptr,
|
||||||
DeductionCandidate Kind = DeductionCandidate::Normal,
|
DeductionCandidate Kind = DeductionCandidate::Normal,
|
||||||
Expr *TrailingRequiresClause = nullptr,
|
const AssociatedConstraint &TrailingRequiresClause = {},
|
||||||
const CXXDeductionGuideDecl *SourceDG = nullptr,
|
const CXXDeductionGuideDecl *SourceDG = nullptr,
|
||||||
SourceDeductionGuideKind SK = SourceDeductionGuideKind::None);
|
SourceDeductionGuideKind SK = SourceDeductionGuideKind::None);
|
||||||
|
|
||||||
@ -2115,7 +2115,7 @@ protected:
|
|||||||
QualType T, TypeSourceInfo *TInfo, StorageClass SC,
|
QualType T, TypeSourceInfo *TInfo, StorageClass SC,
|
||||||
bool UsesFPIntrin, bool isInline,
|
bool UsesFPIntrin, bool isInline,
|
||||||
ConstexprSpecKind ConstexprKind, SourceLocation EndLocation,
|
ConstexprSpecKind ConstexprKind, SourceLocation EndLocation,
|
||||||
Expr *TrailingRequiresClause = nullptr)
|
const AssociatedConstraint &TrailingRequiresClause = {})
|
||||||
: FunctionDecl(DK, C, RD, StartLoc, NameInfo, T, TInfo, SC, UsesFPIntrin,
|
: FunctionDecl(DK, C, RD, StartLoc, NameInfo, T, TInfo, SC, UsesFPIntrin,
|
||||||
isInline, ConstexprKind, TrailingRequiresClause) {
|
isInline, ConstexprKind, TrailingRequiresClause) {
|
||||||
if (EndLocation.isValid())
|
if (EndLocation.isValid())
|
||||||
@ -2128,7 +2128,7 @@ public:
|
|||||||
const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo,
|
const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo,
|
||||||
StorageClass SC, bool UsesFPIntrin, bool isInline,
|
StorageClass SC, bool UsesFPIntrin, bool isInline,
|
||||||
ConstexprSpecKind ConstexprKind, SourceLocation EndLocation,
|
ConstexprSpecKind ConstexprKind, SourceLocation EndLocation,
|
||||||
Expr *TrailingRequiresClause = nullptr);
|
const AssociatedConstraint &TrailingRequiresClause = {});
|
||||||
|
|
||||||
static CXXMethodDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID);
|
static CXXMethodDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID);
|
||||||
|
|
||||||
@ -2596,7 +2596,7 @@ class CXXConstructorDecl final
|
|||||||
bool UsesFPIntrin, bool isInline,
|
bool UsesFPIntrin, bool isInline,
|
||||||
bool isImplicitlyDeclared, ConstexprSpecKind ConstexprKind,
|
bool isImplicitlyDeclared, ConstexprSpecKind ConstexprKind,
|
||||||
InheritedConstructor Inherited,
|
InheritedConstructor Inherited,
|
||||||
Expr *TrailingRequiresClause);
|
const AssociatedConstraint &TrailingRequiresClause);
|
||||||
|
|
||||||
void anchor() override;
|
void anchor() override;
|
||||||
|
|
||||||
@ -2639,7 +2639,7 @@ public:
|
|||||||
ExplicitSpecifier ES, bool UsesFPIntrin, bool isInline,
|
ExplicitSpecifier ES, bool UsesFPIntrin, bool isInline,
|
||||||
bool isImplicitlyDeclared, ConstexprSpecKind ConstexprKind,
|
bool isImplicitlyDeclared, ConstexprSpecKind ConstexprKind,
|
||||||
InheritedConstructor Inherited = InheritedConstructor(),
|
InheritedConstructor Inherited = InheritedConstructor(),
|
||||||
Expr *TrailingRequiresClause = nullptr);
|
const AssociatedConstraint &TrailingRequiresClause = {});
|
||||||
|
|
||||||
void setExplicitSpecifier(ExplicitSpecifier ES) {
|
void setExplicitSpecifier(ExplicitSpecifier ES) {
|
||||||
assert((!ES.getExpr() ||
|
assert((!ES.getExpr() ||
|
||||||
@ -2859,7 +2859,7 @@ class CXXDestructorDecl : public CXXMethodDecl {
|
|||||||
const DeclarationNameInfo &NameInfo, QualType T,
|
const DeclarationNameInfo &NameInfo, QualType T,
|
||||||
TypeSourceInfo *TInfo, bool UsesFPIntrin, bool isInline,
|
TypeSourceInfo *TInfo, bool UsesFPIntrin, bool isInline,
|
||||||
bool isImplicitlyDeclared, ConstexprSpecKind ConstexprKind,
|
bool isImplicitlyDeclared, ConstexprSpecKind ConstexprKind,
|
||||||
Expr *TrailingRequiresClause = nullptr)
|
const AssociatedConstraint &TrailingRequiresClause = {})
|
||||||
: CXXMethodDecl(CXXDestructor, C, RD, StartLoc, NameInfo, T, TInfo,
|
: CXXMethodDecl(CXXDestructor, C, RD, StartLoc, NameInfo, T, TInfo,
|
||||||
SC_None, UsesFPIntrin, isInline, ConstexprKind,
|
SC_None, UsesFPIntrin, isInline, ConstexprKind,
|
||||||
SourceLocation(), TrailingRequiresClause) {
|
SourceLocation(), TrailingRequiresClause) {
|
||||||
@ -2874,7 +2874,7 @@ public:
|
|||||||
const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo,
|
const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo,
|
||||||
bool UsesFPIntrin, bool isInline, bool isImplicitlyDeclared,
|
bool UsesFPIntrin, bool isInline, bool isImplicitlyDeclared,
|
||||||
ConstexprSpecKind ConstexprKind,
|
ConstexprSpecKind ConstexprKind,
|
||||||
Expr *TrailingRequiresClause = nullptr);
|
const AssociatedConstraint &TrailingRequiresClause = {});
|
||||||
static CXXDestructorDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID);
|
static CXXDestructorDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID);
|
||||||
|
|
||||||
void setOperatorDelete(FunctionDecl *OD, Expr *ThisArg);
|
void setOperatorDelete(FunctionDecl *OD, Expr *ThisArg);
|
||||||
@ -2925,7 +2925,7 @@ class CXXConversionDecl : public CXXMethodDecl {
|
|||||||
TypeSourceInfo *TInfo, bool UsesFPIntrin, bool isInline,
|
TypeSourceInfo *TInfo, bool UsesFPIntrin, bool isInline,
|
||||||
ExplicitSpecifier ES, ConstexprSpecKind ConstexprKind,
|
ExplicitSpecifier ES, ConstexprSpecKind ConstexprKind,
|
||||||
SourceLocation EndLocation,
|
SourceLocation EndLocation,
|
||||||
Expr *TrailingRequiresClause = nullptr)
|
const AssociatedConstraint &TrailingRequiresClause = {})
|
||||||
: CXXMethodDecl(CXXConversion, C, RD, StartLoc, NameInfo, T, TInfo,
|
: CXXMethodDecl(CXXConversion, C, RD, StartLoc, NameInfo, T, TInfo,
|
||||||
SC_None, UsesFPIntrin, isInline, ConstexprKind,
|
SC_None, UsesFPIntrin, isInline, ConstexprKind,
|
||||||
EndLocation, TrailingRequiresClause),
|
EndLocation, TrailingRequiresClause),
|
||||||
@ -2943,7 +2943,7 @@ public:
|
|||||||
const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo,
|
const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo,
|
||||||
bool UsesFPIntrin, bool isInline, ExplicitSpecifier ES,
|
bool UsesFPIntrin, bool isInline, ExplicitSpecifier ES,
|
||||||
ConstexprSpecKind ConstexprKind, SourceLocation EndLocation,
|
ConstexprSpecKind ConstexprKind, SourceLocation EndLocation,
|
||||||
Expr *TrailingRequiresClause = nullptr);
|
const AssociatedConstraint &TrailingRequiresClause = {});
|
||||||
static CXXConversionDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID);
|
static CXXConversionDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID);
|
||||||
|
|
||||||
ExplicitSpecifier getExplicitSpecifier() {
|
ExplicitSpecifier getExplicitSpecifier() {
|
||||||
|
@ -2129,7 +2129,7 @@ public:
|
|||||||
ArrayRef<NamedDecl *> getExplicitTemplateParameters() const;
|
ArrayRef<NamedDecl *> getExplicitTemplateParameters() const;
|
||||||
|
|
||||||
/// Get the trailing requires clause, if any.
|
/// Get the trailing requires clause, if any.
|
||||||
Expr *getTrailingRequiresClause() const;
|
const AssociatedConstraint &getTrailingRequiresClause() const;
|
||||||
|
|
||||||
/// Whether this is a generic lambda.
|
/// Whether this is a generic lambda.
|
||||||
bool isGenericLambda() const { return getTemplateParameterList(); }
|
bool isGenericLambda() const { return getTemplateParameterList(); }
|
||||||
|
@ -2253,8 +2253,10 @@ bool RecursiveASTVisitor<Derived>::TraverseFunctionHelper(FunctionDecl *D) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Visit the trailing requires clause, if any.
|
// Visit the trailing requires clause, if any.
|
||||||
if (Expr *TrailingRequiresClause = D->getTrailingRequiresClause()) {
|
if (const AssociatedConstraint &TrailingRequiresClause =
|
||||||
TRY_TO(TraverseStmt(TrailingRequiresClause));
|
D->getTrailingRequiresClause()) {
|
||||||
|
TRY_TO(TraverseStmt(
|
||||||
|
const_cast<Expr *>(TrailingRequiresClause.ConstraintExpr)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(D)) {
|
if (CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(D)) {
|
||||||
@ -2768,7 +2770,8 @@ DEF_TRAVERSE_STMT(LambdaExpr, {
|
|||||||
|
|
||||||
if (S->hasExplicitResultType())
|
if (S->hasExplicitResultType())
|
||||||
TRY_TO(TraverseTypeLoc(Proto.getReturnLoc()));
|
TRY_TO(TraverseTypeLoc(Proto.getReturnLoc()));
|
||||||
TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getTrailingRequiresClause());
|
TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(
|
||||||
|
const_cast<Expr *>(S->getTrailingRequiresClause().ConstraintExpr));
|
||||||
|
|
||||||
TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getBody());
|
TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getBody());
|
||||||
}
|
}
|
||||||
|
@ -8867,11 +8867,13 @@ public:
|
|||||||
CXXMethodDecl *CallOperator, CXXRecordDecl *Class,
|
CXXMethodDecl *CallOperator, CXXRecordDecl *Class,
|
||||||
TemplateParameterList *TemplateParams);
|
TemplateParameterList *TemplateParams);
|
||||||
|
|
||||||
void CompleteLambdaCallOperator(
|
void
|
||||||
CXXMethodDecl *Method, SourceLocation LambdaLoc,
|
CompleteLambdaCallOperator(CXXMethodDecl *Method, SourceLocation LambdaLoc,
|
||||||
SourceLocation CallOperatorLoc, Expr *TrailingRequiresClause,
|
SourceLocation CallOperatorLoc,
|
||||||
TypeSourceInfo *MethodTyInfo, ConstexprSpecKind ConstexprKind,
|
const AssociatedConstraint &TrailingRequiresClause,
|
||||||
StorageClass SC, ArrayRef<ParmVarDecl *> Params,
|
TypeSourceInfo *MethodTyInfo,
|
||||||
|
ConstexprSpecKind ConstexprKind, StorageClass SC,
|
||||||
|
ArrayRef<ParmVarDecl *> Params,
|
||||||
bool HasExplicitResultType);
|
bool HasExplicitResultType);
|
||||||
|
|
||||||
/// Returns true if the explicit object parameter was invalid.
|
/// Returns true if the explicit object parameter was invalid.
|
||||||
|
@ -7070,6 +7070,15 @@ bool ASTContext::hasSameTemplateName(const TemplateName &X,
|
|||||||
getCanonicalTemplateName(Y, IgnoreDeduced);
|
getCanonicalTemplateName(Y, IgnoreDeduced);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ASTContext::isSameAssociatedConstraint(
|
||||||
|
const AssociatedConstraint &ACX, const AssociatedConstraint &ACY) const {
|
||||||
|
if (ACX.ArgumentPackSubstitutionIndex != ACY.ArgumentPackSubstitutionIndex)
|
||||||
|
return false;
|
||||||
|
if (!isSameConstraintExpr(ACX.ConstraintExpr, ACY.ConstraintExpr))
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool ASTContext::isSameConstraintExpr(const Expr *XCE, const Expr *YCE) const {
|
bool ASTContext::isSameConstraintExpr(const Expr *XCE, const Expr *YCE) const {
|
||||||
if (!XCE != !YCE)
|
if (!XCE != !YCE)
|
||||||
return false;
|
return false;
|
||||||
@ -7386,7 +7395,7 @@ bool ASTContext::isSameEntity(const NamedDecl *X, const NamedDecl *Y) const {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isSameConstraintExpr(FuncX->getTrailingRequiresClause(),
|
if (!isSameAssociatedConstraint(FuncX->getTrailingRequiresClause(),
|
||||||
FuncY->getTrailingRequiresClause()))
|
FuncY->getTrailingRequiresClause()))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -3915,8 +3915,9 @@ ExpectedDecl ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
|
|||||||
auto ToEndLoc = importChecked(Err, D->getEndLoc());
|
auto ToEndLoc = importChecked(Err, D->getEndLoc());
|
||||||
auto ToDefaultLoc = importChecked(Err, D->getDefaultLoc());
|
auto ToDefaultLoc = importChecked(Err, D->getDefaultLoc());
|
||||||
auto ToQualifierLoc = importChecked(Err, D->getQualifierLoc());
|
auto ToQualifierLoc = importChecked(Err, D->getQualifierLoc());
|
||||||
auto TrailingRequiresClause =
|
AssociatedConstraint TrailingRequiresClause = D->getTrailingRequiresClause();
|
||||||
importChecked(Err, D->getTrailingRequiresClause());
|
TrailingRequiresClause.ConstraintExpr =
|
||||||
|
importChecked(Err, TrailingRequiresClause.ConstraintExpr);
|
||||||
if (Err)
|
if (Err)
|
||||||
return std::move(Err);
|
return std::move(Err);
|
||||||
|
|
||||||
|
@ -2009,8 +2009,8 @@ void DeclaratorDecl::setQualifierInfo(NestedNameSpecifierLoc QualifierLoc) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeclaratorDecl::setTrailingRequiresClause(Expr *TrailingRequiresClause) {
|
void DeclaratorDecl::setTrailingRequiresClause(const AssociatedConstraint &AC) {
|
||||||
assert(TrailingRequiresClause);
|
assert(AC);
|
||||||
// Make sure the extended decl info is allocated.
|
// Make sure the extended decl info is allocated.
|
||||||
if (!hasExtInfo()) {
|
if (!hasExtInfo()) {
|
||||||
// Save (non-extended) type source info pointer.
|
// Save (non-extended) type source info pointer.
|
||||||
@ -2021,7 +2021,7 @@ void DeclaratorDecl::setTrailingRequiresClause(Expr *TrailingRequiresClause) {
|
|||||||
getExtInfo()->TInfo = savedTInfo;
|
getExtInfo()->TInfo = savedTInfo;
|
||||||
}
|
}
|
||||||
// Set requires clause info.
|
// Set requires clause info.
|
||||||
getExtInfo()->TrailingRequiresClause = TrailingRequiresClause;
|
getExtInfo()->TrailingRequiresClause = AC;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeclaratorDecl::setTemplateParameterListsInfo(
|
void DeclaratorDecl::setTemplateParameterListsInfo(
|
||||||
@ -3047,7 +3047,7 @@ FunctionDecl::FunctionDecl(Kind DK, ASTContext &C, DeclContext *DC,
|
|||||||
TypeSourceInfo *TInfo, StorageClass S,
|
TypeSourceInfo *TInfo, StorageClass S,
|
||||||
bool UsesFPIntrin, bool isInlineSpecified,
|
bool UsesFPIntrin, bool isInlineSpecified,
|
||||||
ConstexprSpecKind ConstexprKind,
|
ConstexprSpecKind ConstexprKind,
|
||||||
Expr *TrailingRequiresClause)
|
const AssociatedConstraint &TrailingRequiresClause)
|
||||||
: DeclaratorDecl(DK, DC, NameInfo.getLoc(), NameInfo.getName(), T, TInfo,
|
: DeclaratorDecl(DK, DC, NameInfo.getLoc(), NameInfo.getName(), T, TInfo,
|
||||||
StartLoc),
|
StartLoc),
|
||||||
DeclContext(DK), redeclarable_base(C), Body(), ODRHash(0),
|
DeclContext(DK), redeclarable_base(C), Body(), ODRHash(0),
|
||||||
@ -3571,7 +3571,7 @@ bool FunctionDecl::isMemberLikeConstrainedFriend() const {
|
|||||||
// If these friends don't have constraints, they aren't constrained, and
|
// If these friends don't have constraints, they aren't constrained, and
|
||||||
// thus don't fall under temp.friend p9. Else the simple presence of a
|
// thus don't fall under temp.friend p9. Else the simple presence of a
|
||||||
// constraint makes them unique.
|
// constraint makes them unique.
|
||||||
return getTrailingRequiresClause();
|
return !getTrailingRequiresClause().isNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
return FriendConstraintRefersToEnclosingTemplate();
|
return FriendConstraintRefersToEnclosingTemplate();
|
||||||
@ -5453,7 +5453,7 @@ FunctionDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
|
|||||||
TypeSourceInfo *TInfo, StorageClass SC, bool UsesFPIntrin,
|
TypeSourceInfo *TInfo, StorageClass SC, bool UsesFPIntrin,
|
||||||
bool isInlineSpecified, bool hasWrittenPrototype,
|
bool isInlineSpecified, bool hasWrittenPrototype,
|
||||||
ConstexprSpecKind ConstexprKind,
|
ConstexprSpecKind ConstexprKind,
|
||||||
Expr *TrailingRequiresClause) {
|
const AssociatedConstraint &TrailingRequiresClause) {
|
||||||
FunctionDecl *New = new (C, DC) FunctionDecl(
|
FunctionDecl *New = new (C, DC) FunctionDecl(
|
||||||
Function, C, DC, StartLoc, NameInfo, T, TInfo, SC, UsesFPIntrin,
|
Function, C, DC, StartLoc, NameInfo, T, TInfo, SC, UsesFPIntrin,
|
||||||
isInlineSpecified, ConstexprKind, TrailingRequiresClause);
|
isInlineSpecified, ConstexprKind, TrailingRequiresClause);
|
||||||
@ -5464,7 +5464,8 @@ FunctionDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
|
|||||||
FunctionDecl *FunctionDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) {
|
FunctionDecl *FunctionDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) {
|
||||||
return new (C, ID) FunctionDecl(
|
return new (C, ID) FunctionDecl(
|
||||||
Function, C, nullptr, SourceLocation(), DeclarationNameInfo(), QualType(),
|
Function, C, nullptr, SourceLocation(), DeclarationNameInfo(), QualType(),
|
||||||
nullptr, SC_None, false, false, ConstexprSpecKind::Unspecified, nullptr);
|
nullptr, SC_None, false, false, ConstexprSpecKind::Unspecified,
|
||||||
|
/*TrailingRequiresClause=*/{});
|
||||||
}
|
}
|
||||||
|
|
||||||
BlockDecl *BlockDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L) {
|
BlockDecl *BlockDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L) {
|
||||||
|
@ -2304,7 +2304,7 @@ CXXDeductionGuideDecl *CXXDeductionGuideDecl::Create(
|
|||||||
ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
|
ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
|
||||||
ExplicitSpecifier ES, const DeclarationNameInfo &NameInfo, QualType T,
|
ExplicitSpecifier ES, const DeclarationNameInfo &NameInfo, QualType T,
|
||||||
TypeSourceInfo *TInfo, SourceLocation EndLocation, CXXConstructorDecl *Ctor,
|
TypeSourceInfo *TInfo, SourceLocation EndLocation, CXXConstructorDecl *Ctor,
|
||||||
DeductionCandidate Kind, Expr *TrailingRequiresClause,
|
DeductionCandidate Kind, const AssociatedConstraint &TrailingRequiresClause,
|
||||||
const CXXDeductionGuideDecl *GeneratedFrom,
|
const CXXDeductionGuideDecl *GeneratedFrom,
|
||||||
SourceDeductionGuideKind SourceKind) {
|
SourceDeductionGuideKind SourceKind) {
|
||||||
return new (C, DC) CXXDeductionGuideDecl(
|
return new (C, DC) CXXDeductionGuideDecl(
|
||||||
@ -2318,7 +2318,7 @@ CXXDeductionGuideDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) {
|
|||||||
C, /*DC=*/nullptr, SourceLocation(), ExplicitSpecifier(),
|
C, /*DC=*/nullptr, SourceLocation(), ExplicitSpecifier(),
|
||||||
DeclarationNameInfo(), QualType(), /*TInfo=*/nullptr, SourceLocation(),
|
DeclarationNameInfo(), QualType(), /*TInfo=*/nullptr, SourceLocation(),
|
||||||
/*Ctor=*/nullptr, DeductionCandidate::Normal,
|
/*Ctor=*/nullptr, DeductionCandidate::Normal,
|
||||||
/*TrailingRequiresClause=*/nullptr,
|
/*TrailingRequiresClause=*/{},
|
||||||
/*GeneratedFrom=*/nullptr, SourceDeductionGuideKind::None);
|
/*GeneratedFrom=*/nullptr, SourceDeductionGuideKind::None);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2427,7 +2427,7 @@ CXXMethodDecl::Create(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
|
|||||||
TypeSourceInfo *TInfo, StorageClass SC, bool UsesFPIntrin,
|
TypeSourceInfo *TInfo, StorageClass SC, bool UsesFPIntrin,
|
||||||
bool isInline, ConstexprSpecKind ConstexprKind,
|
bool isInline, ConstexprSpecKind ConstexprKind,
|
||||||
SourceLocation EndLocation,
|
SourceLocation EndLocation,
|
||||||
Expr *TrailingRequiresClause) {
|
const AssociatedConstraint &TrailingRequiresClause) {
|
||||||
return new (C, RD) CXXMethodDecl(
|
return new (C, RD) CXXMethodDecl(
|
||||||
CXXMethod, C, RD, StartLoc, NameInfo, T, TInfo, SC, UsesFPIntrin,
|
CXXMethod, C, RD, StartLoc, NameInfo, T, TInfo, SC, UsesFPIntrin,
|
||||||
isInline, ConstexprKind, EndLocation, TrailingRequiresClause);
|
isInline, ConstexprKind, EndLocation, TrailingRequiresClause);
|
||||||
@ -2435,10 +2435,11 @@ CXXMethodDecl::Create(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
|
|||||||
|
|
||||||
CXXMethodDecl *CXXMethodDecl::CreateDeserialized(ASTContext &C,
|
CXXMethodDecl *CXXMethodDecl::CreateDeserialized(ASTContext &C,
|
||||||
GlobalDeclID ID) {
|
GlobalDeclID ID) {
|
||||||
return new (C, ID) CXXMethodDecl(
|
return new (C, ID)
|
||||||
CXXMethod, C, nullptr, SourceLocation(), DeclarationNameInfo(),
|
CXXMethodDecl(CXXMethod, C, nullptr, SourceLocation(),
|
||||||
QualType(), nullptr, SC_None, false, false,
|
DeclarationNameInfo(), QualType(), nullptr, SC_None, false,
|
||||||
ConstexprSpecKind::Unspecified, SourceLocation(), nullptr);
|
false, ConstexprSpecKind::Unspecified, SourceLocation(),
|
||||||
|
/*TrailingRequiresClause=*/{});
|
||||||
}
|
}
|
||||||
|
|
||||||
CXXMethodDecl *CXXMethodDecl::getDevirtualizedMethod(const Expr *Base,
|
CXXMethodDecl *CXXMethodDecl::getDevirtualizedMethod(const Expr *Base,
|
||||||
@ -2834,7 +2835,8 @@ CXXConstructorDecl::CXXConstructorDecl(
|
|||||||
const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo,
|
const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo,
|
||||||
ExplicitSpecifier ES, bool UsesFPIntrin, bool isInline,
|
ExplicitSpecifier ES, bool UsesFPIntrin, bool isInline,
|
||||||
bool isImplicitlyDeclared, ConstexprSpecKind ConstexprKind,
|
bool isImplicitlyDeclared, ConstexprSpecKind ConstexprKind,
|
||||||
InheritedConstructor Inherited, Expr *TrailingRequiresClause)
|
InheritedConstructor Inherited,
|
||||||
|
const AssociatedConstraint &TrailingRequiresClause)
|
||||||
: CXXMethodDecl(CXXConstructor, C, RD, StartLoc, NameInfo, T, TInfo,
|
: CXXMethodDecl(CXXConstructor, C, RD, StartLoc, NameInfo, T, TInfo,
|
||||||
SC_None, UsesFPIntrin, isInline, ConstexprKind,
|
SC_None, UsesFPIntrin, isInline, ConstexprKind,
|
||||||
SourceLocation(), TrailingRequiresClause) {
|
SourceLocation(), TrailingRequiresClause) {
|
||||||
@ -2861,7 +2863,7 @@ CXXConstructorDecl *CXXConstructorDecl::CreateDeserialized(ASTContext &C,
|
|||||||
auto *Result = new (C, ID, Extra) CXXConstructorDecl(
|
auto *Result = new (C, ID, Extra) CXXConstructorDecl(
|
||||||
C, nullptr, SourceLocation(), DeclarationNameInfo(), QualType(), nullptr,
|
C, nullptr, SourceLocation(), DeclarationNameInfo(), QualType(), nullptr,
|
||||||
ExplicitSpecifier(), false, false, false, ConstexprSpecKind::Unspecified,
|
ExplicitSpecifier(), false, false, false, ConstexprSpecKind::Unspecified,
|
||||||
InheritedConstructor(), nullptr);
|
InheritedConstructor(), /*TrailingRequiresClause=*/{});
|
||||||
Result->setInheritingConstructor(isInheritingConstructor);
|
Result->setInheritingConstructor(isInheritingConstructor);
|
||||||
Result->CXXConstructorDeclBits.HasTrailingExplicitSpecifier =
|
Result->CXXConstructorDeclBits.HasTrailingExplicitSpecifier =
|
||||||
hasTrailingExplicit;
|
hasTrailingExplicit;
|
||||||
@ -2874,7 +2876,8 @@ CXXConstructorDecl *CXXConstructorDecl::Create(
|
|||||||
const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo,
|
const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo,
|
||||||
ExplicitSpecifier ES, bool UsesFPIntrin, bool isInline,
|
ExplicitSpecifier ES, bool UsesFPIntrin, bool isInline,
|
||||||
bool isImplicitlyDeclared, ConstexprSpecKind ConstexprKind,
|
bool isImplicitlyDeclared, ConstexprSpecKind ConstexprKind,
|
||||||
InheritedConstructor Inherited, Expr *TrailingRequiresClause) {
|
InheritedConstructor Inherited,
|
||||||
|
const AssociatedConstraint &TrailingRequiresClause) {
|
||||||
assert(NameInfo.getName().getNameKind()
|
assert(NameInfo.getName().getNameKind()
|
||||||
== DeclarationName::CXXConstructorName &&
|
== DeclarationName::CXXConstructorName &&
|
||||||
"Name must refer to a constructor");
|
"Name must refer to a constructor");
|
||||||
@ -3000,14 +3003,16 @@ CXXDestructorDecl *CXXDestructorDecl::CreateDeserialized(ASTContext &C,
|
|||||||
GlobalDeclID ID) {
|
GlobalDeclID ID) {
|
||||||
return new (C, ID) CXXDestructorDecl(
|
return new (C, ID) CXXDestructorDecl(
|
||||||
C, nullptr, SourceLocation(), DeclarationNameInfo(), QualType(), nullptr,
|
C, nullptr, SourceLocation(), DeclarationNameInfo(), QualType(), nullptr,
|
||||||
false, false, false, ConstexprSpecKind::Unspecified, nullptr);
|
false, false, false, ConstexprSpecKind::Unspecified,
|
||||||
|
/*TrailingRequiresClause=*/{});
|
||||||
}
|
}
|
||||||
|
|
||||||
CXXDestructorDecl *CXXDestructorDecl::Create(
|
CXXDestructorDecl *CXXDestructorDecl::Create(
|
||||||
ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
|
ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
|
||||||
const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo,
|
const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo,
|
||||||
bool UsesFPIntrin, bool isInline, bool isImplicitlyDeclared,
|
bool UsesFPIntrin, bool isInline, bool isImplicitlyDeclared,
|
||||||
ConstexprSpecKind ConstexprKind, Expr *TrailingRequiresClause) {
|
ConstexprSpecKind ConstexprKind,
|
||||||
|
const AssociatedConstraint &TrailingRequiresClause) {
|
||||||
assert(NameInfo.getName().getNameKind()
|
assert(NameInfo.getName().getNameKind()
|
||||||
== DeclarationName::CXXDestructorName &&
|
== DeclarationName::CXXDestructorName &&
|
||||||
"Name must refer to a destructor");
|
"Name must refer to a destructor");
|
||||||
@ -3062,7 +3067,7 @@ CXXConversionDecl *CXXConversionDecl::CreateDeserialized(ASTContext &C,
|
|||||||
return new (C, ID) CXXConversionDecl(
|
return new (C, ID) CXXConversionDecl(
|
||||||
C, nullptr, SourceLocation(), DeclarationNameInfo(), QualType(), nullptr,
|
C, nullptr, SourceLocation(), DeclarationNameInfo(), QualType(), nullptr,
|
||||||
false, false, ExplicitSpecifier(), ConstexprSpecKind::Unspecified,
|
false, false, ExplicitSpecifier(), ConstexprSpecKind::Unspecified,
|
||||||
SourceLocation(), nullptr);
|
SourceLocation(), /*TrailingRequiresClause=*/{});
|
||||||
}
|
}
|
||||||
|
|
||||||
CXXConversionDecl *CXXConversionDecl::Create(
|
CXXConversionDecl *CXXConversionDecl::Create(
|
||||||
@ -3070,7 +3075,7 @@ CXXConversionDecl *CXXConversionDecl::Create(
|
|||||||
const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo,
|
const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo,
|
||||||
bool UsesFPIntrin, bool isInline, ExplicitSpecifier ES,
|
bool UsesFPIntrin, bool isInline, ExplicitSpecifier ES,
|
||||||
ConstexprSpecKind ConstexprKind, SourceLocation EndLocation,
|
ConstexprSpecKind ConstexprKind, SourceLocation EndLocation,
|
||||||
Expr *TrailingRequiresClause) {
|
const AssociatedConstraint &TrailingRequiresClause) {
|
||||||
assert(NameInfo.getName().getNameKind()
|
assert(NameInfo.getName().getNameKind()
|
||||||
== DeclarationName::CXXConversionFunctionName &&
|
== DeclarationName::CXXConversionFunctionName &&
|
||||||
"Name must refer to a conversion function");
|
"Name must refer to a conversion function");
|
||||||
|
@ -842,10 +842,14 @@ void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) {
|
|||||||
}
|
}
|
||||||
Out << Proto;
|
Out << Proto;
|
||||||
|
|
||||||
if (Expr *TrailingRequiresClause = D->getTrailingRequiresClause()) {
|
if (const AssociatedConstraint &TrailingRequiresClause =
|
||||||
|
D->getTrailingRequiresClause()) {
|
||||||
Out << " requires ";
|
Out << " requires ";
|
||||||
TrailingRequiresClause->printPretty(Out, nullptr, SubPolicy, Indentation,
|
// FIXME: The printer could support printing expressions and types as if
|
||||||
"\n", &Context);
|
// expanded by an index. Pass in the ArgumentPackSubstitutionIndex when
|
||||||
|
// that's supported.
|
||||||
|
TrailingRequiresClause.ConstraintExpr->printPretty(
|
||||||
|
Out, nullptr, SubPolicy, Indentation, "\n", &Context);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Ty.print(Out, Policy, Proto);
|
Ty.print(Out, Policy, Proto);
|
||||||
|
@ -291,7 +291,7 @@ void TemplateDecl::getAssociatedConstraints(
|
|||||||
llvm::SmallVectorImpl<AssociatedConstraint> &ACs) const {
|
llvm::SmallVectorImpl<AssociatedConstraint> &ACs) const {
|
||||||
TemplateParams->getAssociatedConstraints(ACs);
|
TemplateParams->getAssociatedConstraints(ACs);
|
||||||
if (auto *FD = dyn_cast_or_null<FunctionDecl>(getTemplatedDecl()))
|
if (auto *FD = dyn_cast_or_null<FunctionDecl>(getTemplatedDecl()))
|
||||||
if (const Expr *TRC = FD->getTrailingRequiresClause())
|
if (const AssociatedConstraint &TRC = FD->getTrailingRequiresClause())
|
||||||
ACs.emplace_back(TRC);
|
ACs.emplace_back(TRC);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -299,7 +299,7 @@ bool TemplateDecl::hasAssociatedConstraints() const {
|
|||||||
if (TemplateParams->hasAssociatedConstraints())
|
if (TemplateParams->hasAssociatedConstraints())
|
||||||
return true;
|
return true;
|
||||||
if (auto *FD = dyn_cast_or_null<FunctionDecl>(getTemplatedDecl()))
|
if (auto *FD = dyn_cast_or_null<FunctionDecl>(getTemplatedDecl()))
|
||||||
return FD->getTrailingRequiresClause();
|
return static_cast<bool>(FD->getTrailingRequiresClause());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1402,7 +1402,7 @@ ArrayRef<NamedDecl *> LambdaExpr::getExplicitTemplateParameters() const {
|
|||||||
return Record->getLambdaExplicitTemplateParameters();
|
return Record->getLambdaExplicitTemplateParameters();
|
||||||
}
|
}
|
||||||
|
|
||||||
Expr *LambdaExpr::getTrailingRequiresClause() const {
|
const AssociatedConstraint &LambdaExpr::getTrailingRequiresClause() const {
|
||||||
return getCallOperator()->getTrailingRequiresClause();
|
return getCallOperator()->getTrailingRequiresClause();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3781,7 +3781,7 @@ void CXXNameMangler::mangleBareFunctionType(const FunctionProtoType *Proto,
|
|||||||
|
|
||||||
if (FD) {
|
if (FD) {
|
||||||
FunctionTypeDepth.enterResultType();
|
FunctionTypeDepth.enterResultType();
|
||||||
mangleRequiresClause(FD->getTrailingRequiresClause());
|
mangleRequiresClause(FD->getTrailingRequiresClause().ConstraintExpr);
|
||||||
}
|
}
|
||||||
|
|
||||||
FunctionTypeDepth.pop(saved);
|
FunctionTypeDepth.pop(saved);
|
||||||
|
@ -584,7 +584,8 @@ public:
|
|||||||
|
|
||||||
if (LE->hasExplicitResultType())
|
if (LE->hasExplicitResultType())
|
||||||
TraverseTypeLoc(Proto.getReturnLoc());
|
TraverseTypeLoc(Proto.getReturnLoc());
|
||||||
TraverseStmt(LE->getTrailingRequiresClause());
|
TraverseStmt(
|
||||||
|
const_cast<Expr *>(LE->getTrailingRequiresClause().ConstraintExpr));
|
||||||
}
|
}
|
||||||
|
|
||||||
TraverseStmt(LE->getBody());
|
TraverseStmt(LE->getBody());
|
||||||
|
@ -132,8 +132,8 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (auto *C = D->getTrailingRequiresClause())
|
if (const AssociatedConstraint &C = D->getTrailingRequiresClause())
|
||||||
IndexCtx.indexBody(C, Parent);
|
IndexCtx.indexBody(C.ConstraintExpr, Parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool handleObjCMethod(const ObjCMethodDecl *D,
|
bool handleObjCMethod(const ObjCMethodDecl *D,
|
||||||
|
@ -848,10 +848,8 @@ bool Sema::CheckFunctionConstraints(const FunctionDecl *FD,
|
|||||||
ForOverloadResolution);
|
ForOverloadResolution);
|
||||||
|
|
||||||
return CheckConstraintSatisfaction(
|
return CheckConstraintSatisfaction(
|
||||||
FD,
|
FD, FD->getTrailingRequiresClause(), *MLTAL,
|
||||||
AssociatedConstraint(FD->getTrailingRequiresClause(),
|
SourceRange(UsageLoc.isValid() ? UsageLoc : FD->getLocation()),
|
||||||
ArgumentPackSubstitutionIndex),
|
|
||||||
*MLTAL, SourceRange(UsageLoc.isValid() ? UsageLoc : FD->getLocation()),
|
|
||||||
Satisfaction);
|
Satisfaction);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9353,7 +9353,7 @@ static FunctionDecl *CreateNewFunctionDecl(Sema &SemaRef, Declarator &D,
|
|||||||
SemaRef.Context, DC, D.getBeginLoc(), NameInfo, R, TInfo, SC,
|
SemaRef.Context, DC, D.getBeginLoc(), NameInfo, R, TInfo, SC,
|
||||||
SemaRef.getCurFPFeatures().isFPConstrained(), isInline, HasPrototype,
|
SemaRef.getCurFPFeatures().isFPConstrained(), isInline, HasPrototype,
|
||||||
ConstexprSpecKind::Unspecified,
|
ConstexprSpecKind::Unspecified,
|
||||||
/*TrailingRequiresClause=*/nullptr);
|
/*TrailingRequiresClause=*/{});
|
||||||
if (D.isInvalidType())
|
if (D.isInvalidType())
|
||||||
NewFD->setInvalidDecl();
|
NewFD->setInvalidDecl();
|
||||||
|
|
||||||
@ -9361,7 +9361,7 @@ static FunctionDecl *CreateNewFunctionDecl(Sema &SemaRef, Declarator &D,
|
|||||||
}
|
}
|
||||||
|
|
||||||
ExplicitSpecifier ExplicitSpecifier = D.getDeclSpec().getExplicitSpecifier();
|
ExplicitSpecifier ExplicitSpecifier = D.getDeclSpec().getExplicitSpecifier();
|
||||||
Expr *TrailingRequiresClause = D.getTrailingRequiresClause();
|
AssociatedConstraint TrailingRequiresClause(D.getTrailingRequiresClause());
|
||||||
|
|
||||||
SemaRef.CheckExplicitObjectMemberFunction(DC, D, Name, R);
|
SemaRef.CheckExplicitObjectMemberFunction(DC, D, Name, R);
|
||||||
|
|
||||||
@ -10531,7 +10531,7 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
|
|||||||
diag::ext_operator_new_delete_declared_inline)
|
diag::ext_operator_new_delete_declared_inline)
|
||||||
<< NewFD->getDeclName();
|
<< NewFD->getDeclName();
|
||||||
|
|
||||||
if (Expr *TRC = NewFD->getTrailingRequiresClause()) {
|
if (const Expr *TRC = NewFD->getTrailingRequiresClause().ConstraintExpr) {
|
||||||
// C++20 [dcl.decl.general]p4:
|
// C++20 [dcl.decl.general]p4:
|
||||||
// The optional requires-clause in an init-declarator or
|
// The optional requires-clause in an init-declarator or
|
||||||
// member-declarator shall be present only if the declarator declares a
|
// member-declarator shall be present only if the declarator declares a
|
||||||
@ -12261,7 +12261,7 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,
|
|||||||
if (Method->isVirtual() && NewFD->getTrailingRequiresClause())
|
if (Method->isVirtual() && NewFD->getTrailingRequiresClause())
|
||||||
// C++2a [class.virtual]p6
|
// C++2a [class.virtual]p6
|
||||||
// A virtual method shall not have a requires-clause.
|
// A virtual method shall not have a requires-clause.
|
||||||
Diag(NewFD->getTrailingRequiresClause()->getBeginLoc(),
|
Diag(NewFD->getTrailingRequiresClause().ConstraintExpr->getBeginLoc(),
|
||||||
diag::err_constrained_virtual_method);
|
diag::err_constrained_virtual_method);
|
||||||
|
|
||||||
if (Method->isStatic())
|
if (Method->isStatic())
|
||||||
@ -19085,8 +19085,7 @@ static void SetEligibleMethods(Sema &S, CXXRecordDecl *Record,
|
|||||||
SmallVector<bool, 4> SatisfactionStatus;
|
SmallVector<bool, 4> SatisfactionStatus;
|
||||||
|
|
||||||
for (CXXMethodDecl *Method : Methods) {
|
for (CXXMethodDecl *Method : Methods) {
|
||||||
const Expr *Constraints = Method->getTrailingRequiresClause();
|
if (!Method->getTrailingRequiresClause())
|
||||||
if (!Constraints)
|
|
||||||
SatisfactionStatus.push_back(true);
|
SatisfactionStatus.push_back(true);
|
||||||
else {
|
else {
|
||||||
ConstraintSatisfaction Satisfaction;
|
ConstraintSatisfaction Satisfaction;
|
||||||
@ -19105,7 +19104,7 @@ static void SetEligibleMethods(Sema &S, CXXRecordDecl *Record,
|
|||||||
if (FunctionDecl *MF = OrigMethod->getInstantiatedFromMemberFunction())
|
if (FunctionDecl *MF = OrigMethod->getInstantiatedFromMemberFunction())
|
||||||
OrigMethod = cast<CXXMethodDecl>(MF);
|
OrigMethod = cast<CXXMethodDecl>(MF);
|
||||||
|
|
||||||
const Expr *Constraints = OrigMethod->getTrailingRequiresClause();
|
AssociatedConstraint Orig = OrigMethod->getTrailingRequiresClause();
|
||||||
bool AnotherMethodIsMoreConstrained = false;
|
bool AnotherMethodIsMoreConstrained = false;
|
||||||
for (size_t j = 0; j < Methods.size(); j++) {
|
for (size_t j = 0; j < Methods.size(); j++) {
|
||||||
if (i == j || !SatisfactionStatus[j])
|
if (i == j || !SatisfactionStatus[j])
|
||||||
@ -19118,15 +19117,13 @@ static void SetEligibleMethods(Sema &S, CXXRecordDecl *Record,
|
|||||||
CSM))
|
CSM))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const Expr *OtherConstraints = OtherMethod->getTrailingRequiresClause();
|
AssociatedConstraint Other = OtherMethod->getTrailingRequiresClause();
|
||||||
if (!OtherConstraints)
|
if (!Other)
|
||||||
continue;
|
continue;
|
||||||
if (!Constraints) {
|
if (!Orig) {
|
||||||
AnotherMethodIsMoreConstrained = true;
|
AnotherMethodIsMoreConstrained = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
AssociatedConstraint Other(OtherConstraints);
|
|
||||||
AssociatedConstraint Orig(Constraints);
|
|
||||||
if (S.IsAtLeastAsConstrained(OtherMethod, {Other}, OrigMethod, {Orig},
|
if (S.IsAtLeastAsConstrained(OtherMethod, {Other}, OrigMethod, {Orig},
|
||||||
AnotherMethodIsMoreConstrained)) {
|
AnotherMethodIsMoreConstrained)) {
|
||||||
// There was an error with the constraints comparison. Exit the loop
|
// There was an error with the constraints comparison. Exit the loop
|
||||||
|
@ -18995,8 +18995,8 @@ bool Sema::checkThisInStaticMemberFunctionType(CXXMethodDecl *Method) {
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
// Check the trailing requires clause
|
// Check the trailing requires clause
|
||||||
if (Expr *E = Method->getTrailingRequiresClause())
|
if (const AssociatedConstraint &TRC = Method->getTrailingRequiresClause())
|
||||||
if (!Finder.TraverseStmt(E))
|
if (!Finder.TraverseStmt(const_cast<Expr *>(TRC.ConstraintExpr)))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return checkThisInStaticMemberFunctionAttributes(Method);
|
return checkThisInStaticMemberFunctionAttributes(Method);
|
||||||
|
@ -990,7 +990,7 @@ private:
|
|||||||
followDestructor(dyn_cast<CXXRecordDecl>(Dtor->getParent()), Dtor);
|
followDestructor(dyn_cast<CXXRecordDecl>(Dtor->getParent()), Dtor);
|
||||||
|
|
||||||
if (auto *FD = dyn_cast<FunctionDecl>(CurrentCaller.CDecl)) {
|
if (auto *FD = dyn_cast<FunctionDecl>(CurrentCaller.CDecl)) {
|
||||||
TrailingRequiresClause = FD->getTrailingRequiresClause();
|
TrailingRequiresClause = FD->getTrailingRequiresClause().ConstraintExpr;
|
||||||
|
|
||||||
// Note that FD->getType->getAs<FunctionProtoType>() can yield a
|
// Note that FD->getType->getAs<FunctionProtoType>() can yield a
|
||||||
// noexcept Expr which has been boiled down to a constant expression.
|
// noexcept Expr which has been boiled down to a constant expression.
|
||||||
|
@ -1015,7 +1015,7 @@ CXXMethodDecl *Sema::CreateLambdaCallOperator(SourceRange IntroducerRange,
|
|||||||
QualType(), /*Tinfo=*/nullptr, SC_None,
|
QualType(), /*Tinfo=*/nullptr, SC_None,
|
||||||
getCurFPFeatures().isFPConstrained(),
|
getCurFPFeatures().isFPConstrained(),
|
||||||
/*isInline=*/true, ConstexprSpecKind::Unspecified, SourceLocation(),
|
/*isInline=*/true, ConstexprSpecKind::Unspecified, SourceLocation(),
|
||||||
/*TrailingRequiresClause=*/nullptr);
|
/*TrailingRequiresClause=*/{});
|
||||||
Method->setAccess(AS_public);
|
Method->setAccess(AS_public);
|
||||||
return Method;
|
return Method;
|
||||||
}
|
}
|
||||||
@ -1033,7 +1033,8 @@ void Sema::AddTemplateParametersToLambdaCallOperator(
|
|||||||
|
|
||||||
void Sema::CompleteLambdaCallOperator(
|
void Sema::CompleteLambdaCallOperator(
|
||||||
CXXMethodDecl *Method, SourceLocation LambdaLoc,
|
CXXMethodDecl *Method, SourceLocation LambdaLoc,
|
||||||
SourceLocation CallOperatorLoc, Expr *TrailingRequiresClause,
|
SourceLocation CallOperatorLoc,
|
||||||
|
const AssociatedConstraint &TrailingRequiresClause,
|
||||||
TypeSourceInfo *MethodTyInfo, ConstexprSpecKind ConstexprKind,
|
TypeSourceInfo *MethodTyInfo, ConstexprSpecKind ConstexprKind,
|
||||||
StorageClass SC, ArrayRef<ParmVarDecl *> Params,
|
StorageClass SC, ArrayRef<ParmVarDecl *> Params,
|
||||||
bool HasExplicitResultType) {
|
bool HasExplicitResultType) {
|
||||||
@ -1461,8 +1462,9 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro,
|
|||||||
|
|
||||||
CompleteLambdaCallOperator(
|
CompleteLambdaCallOperator(
|
||||||
Method, Intro.Range.getBegin(), CallOperatorLoc,
|
Method, Intro.Range.getBegin(), CallOperatorLoc,
|
||||||
ParamInfo.getTrailingRequiresClause(), MethodTyInfo,
|
AssociatedConstraint(ParamInfo.getTrailingRequiresClause(),
|
||||||
ParamInfo.getDeclSpec().getConstexprSpecifier(),
|
/*ArgumentPackSubstitutionIndex=*/-1),
|
||||||
|
MethodTyInfo, ParamInfo.getDeclSpec().getConstexprSpecifier(),
|
||||||
IsLambdaStatic ? SC_Static : SC_None, Params, ExplicitResultType);
|
IsLambdaStatic ? SC_Static : SC_None, Params, ExplicitResultType);
|
||||||
|
|
||||||
CheckCXXDefaultArguments(Method);
|
CheckCXXDefaultArguments(Method);
|
||||||
@ -1545,7 +1547,7 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro,
|
|||||||
// The optional requires-clause ([temp.pre]) in an init-declarator or
|
// The optional requires-clause ([temp.pre]) in an init-declarator or
|
||||||
// member-declarator shall be present only if the declarator declares a
|
// member-declarator shall be present only if the declarator declares a
|
||||||
// templated function ([dcl.fct]).
|
// templated function ([dcl.fct]).
|
||||||
if (Expr *TRC = Method->getTrailingRequiresClause()) {
|
if (const AssociatedConstraint &TRC = Method->getTrailingRequiresClause()) {
|
||||||
// [temp.pre]/8:
|
// [temp.pre]/8:
|
||||||
// An entity is templated if it is
|
// An entity is templated if it is
|
||||||
// - a template,
|
// - a template,
|
||||||
@ -1568,7 +1570,8 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro,
|
|||||||
// applies to the call operator, which we already know is a member function,
|
// applies to the call operator, which we already know is a member function,
|
||||||
// AND defined.
|
// AND defined.
|
||||||
if (!Method->getDescribedFunctionTemplate() && !Method->isTemplated()) {
|
if (!Method->getDescribedFunctionTemplate() && !Method->isTemplated()) {
|
||||||
Diag(TRC->getBeginLoc(), diag::err_constrained_non_templated_function);
|
Diag(TRC.ConstraintExpr->getBeginLoc(),
|
||||||
|
diag::err_constrained_non_templated_function);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1791,7 +1794,8 @@ static void addFunctionPointerConversion(Sema &S, SourceRange IntroducerRange,
|
|||||||
|
|
||||||
// A non-generic lambda may still be a templated entity. We need to preserve
|
// A non-generic lambda may still be a templated entity. We need to preserve
|
||||||
// constraints when converting the lambda to a function pointer. See GH63181.
|
// constraints when converting the lambda to a function pointer. See GH63181.
|
||||||
if (Expr *Requires = CallOperator->getTrailingRequiresClause())
|
if (const AssociatedConstraint &Requires =
|
||||||
|
CallOperator->getTrailingRequiresClause())
|
||||||
Conversion->setTrailingRequiresClause(Requires);
|
Conversion->setTrailingRequiresClause(Requires);
|
||||||
|
|
||||||
if (Class->isGenericLambda()) {
|
if (Class->isGenericLambda()) {
|
||||||
|
@ -1551,12 +1551,16 @@ static bool IsOverloadOrOverrideImpl(Sema &SemaRef, FunctionDecl *New,
|
|||||||
|
|
||||||
if (!UseOverrideRules &&
|
if (!UseOverrideRules &&
|
||||||
New->getTemplateSpecializationKind() != TSK_ExplicitSpecialization) {
|
New->getTemplateSpecializationKind() != TSK_ExplicitSpecialization) {
|
||||||
Expr *NewRC = New->getTrailingRequiresClause(),
|
AssociatedConstraint NewRC = New->getTrailingRequiresClause(),
|
||||||
*OldRC = Old->getTrailingRequiresClause();
|
OldRC = Old->getTrailingRequiresClause();
|
||||||
if ((NewRC != nullptr) != (OldRC != nullptr))
|
if (!NewRC != !OldRC)
|
||||||
|
return true;
|
||||||
|
if (NewRC.ArgumentPackSubstitutionIndex !=
|
||||||
|
OldRC.ArgumentPackSubstitutionIndex)
|
||||||
return true;
|
return true;
|
||||||
if (NewRC &&
|
if (NewRC &&
|
||||||
!SemaRef.AreConstraintExpressionsEqual(OldDecl, OldRC, NewDecl, NewRC))
|
!SemaRef.AreConstraintExpressionsEqual(OldDecl, OldRC.ConstraintExpr,
|
||||||
|
NewDecl, NewRC.ConstraintExpr))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -200,7 +200,7 @@ buildDeductionGuide(Sema &SemaRef, TemplateDecl *OriginalTemplate,
|
|||||||
TypeSourceInfo *TInfo, SourceLocation LocStart,
|
TypeSourceInfo *TInfo, SourceLocation LocStart,
|
||||||
SourceLocation Loc, SourceLocation LocEnd, bool IsImplicit,
|
SourceLocation Loc, SourceLocation LocEnd, bool IsImplicit,
|
||||||
llvm::ArrayRef<TypedefNameDecl *> MaterializedTypedefs = {},
|
llvm::ArrayRef<TypedefNameDecl *> MaterializedTypedefs = {},
|
||||||
Expr *FunctionTrailingRC = nullptr) {
|
const AssociatedConstraint &FunctionTrailingRC = {}) {
|
||||||
DeclContext *DC = OriginalTemplate->getDeclContext();
|
DeclContext *DC = OriginalTemplate->getDeclContext();
|
||||||
auto DeductionGuideName =
|
auto DeductionGuideName =
|
||||||
SemaRef.Context.DeclarationNames.getCXXDeductionGuideName(
|
SemaRef.Context.DeclarationNames.getCXXDeductionGuideName(
|
||||||
@ -356,7 +356,8 @@ struct ConvertConstructorToDeductionGuideTransform {
|
|||||||
TemplateParameterList *TemplateParams =
|
TemplateParameterList *TemplateParams =
|
||||||
SemaRef.GetTemplateParameterList(Template);
|
SemaRef.GetTemplateParameterList(Template);
|
||||||
SmallVector<TemplateArgument, 16> Depth1Args;
|
SmallVector<TemplateArgument, 16> Depth1Args;
|
||||||
Expr *OuterRC = TemplateParams->getRequiresClause();
|
AssociatedConstraint OuterRC(TemplateParams->getRequiresClause(),
|
||||||
|
/*ArgumentPackSubstitutionIndex=*/-1);
|
||||||
if (FTD) {
|
if (FTD) {
|
||||||
TemplateParameterList *InnerParams = FTD->getTemplateParameters();
|
TemplateParameterList *InnerParams = FTD->getTemplateParameters();
|
||||||
SmallVector<NamedDecl *, 16> AllParams;
|
SmallVector<NamedDecl *, 16> AllParams;
|
||||||
@ -456,18 +457,20 @@ struct ConvertConstructorToDeductionGuideTransform {
|
|||||||
// At this point, the function parameters are already 'instantiated' in the
|
// At this point, the function parameters are already 'instantiated' in the
|
||||||
// current scope. Substitute into the constructor's trailing
|
// current scope. Substitute into the constructor's trailing
|
||||||
// requires-clause, if any.
|
// requires-clause, if any.
|
||||||
Expr *FunctionTrailingRC = nullptr;
|
AssociatedConstraint FunctionTrailingRC;
|
||||||
if (Expr *RC = CD->getTrailingRequiresClause()) {
|
if (const AssociatedConstraint &RC = CD->getTrailingRequiresClause()) {
|
||||||
MultiLevelTemplateArgumentList Args;
|
MultiLevelTemplateArgumentList Args;
|
||||||
Args.setKind(TemplateSubstitutionKind::Rewrite);
|
Args.setKind(TemplateSubstitutionKind::Rewrite);
|
||||||
Args.addOuterTemplateArguments(Depth1Args);
|
Args.addOuterTemplateArguments(Depth1Args);
|
||||||
Args.addOuterRetainedLevel();
|
Args.addOuterRetainedLevel();
|
||||||
if (NestedPattern)
|
if (NestedPattern)
|
||||||
Args.addOuterRetainedLevels(NestedPattern->getTemplateDepth());
|
Args.addOuterRetainedLevels(NestedPattern->getTemplateDepth());
|
||||||
ExprResult E = SemaRef.SubstConstraintExprWithoutSatisfaction(RC, Args);
|
ExprResult E = SemaRef.SubstConstraintExprWithoutSatisfaction(
|
||||||
|
const_cast<Expr *>(RC.ConstraintExpr), Args);
|
||||||
if (!E.isUsable())
|
if (!E.isUsable())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
FunctionTrailingRC = E.get();
|
FunctionTrailingRC =
|
||||||
|
AssociatedConstraint(E.get(), RC.ArgumentPackSubstitutionIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
// C++ [over.match.class.deduct]p1:
|
// C++ [over.match.class.deduct]p1:
|
||||||
@ -480,13 +483,19 @@ struct ConvertConstructorToDeductionGuideTransform {
|
|||||||
if (OuterRC) {
|
if (OuterRC) {
|
||||||
// The outer template parameters are not transformed, so their
|
// The outer template parameters are not transformed, so their
|
||||||
// associated constraints don't need substitution.
|
// associated constraints don't need substitution.
|
||||||
|
// FIXME: Should simply add another field for the OuterRC, instead of
|
||||||
|
// combining them like this.
|
||||||
if (!FunctionTrailingRC)
|
if (!FunctionTrailingRC)
|
||||||
FunctionTrailingRC = OuterRC;
|
FunctionTrailingRC = OuterRC;
|
||||||
else
|
else
|
||||||
FunctionTrailingRC = BinaryOperator::Create(
|
FunctionTrailingRC = AssociatedConstraint(
|
||||||
SemaRef.Context, /*lhs=*/OuterRC, /*rhs=*/FunctionTrailingRC,
|
BinaryOperator::Create(
|
||||||
|
SemaRef.Context,
|
||||||
|
/*lhs=*/const_cast<Expr *>(OuterRC.ConstraintExpr),
|
||||||
|
/*rhs=*/const_cast<Expr *>(FunctionTrailingRC.ConstraintExpr),
|
||||||
BO_LAnd, SemaRef.Context.BoolTy, VK_PRValue, OK_Ordinary,
|
BO_LAnd, SemaRef.Context.BoolTy, VK_PRValue, OK_Ordinary,
|
||||||
TemplateParams->getTemplateLoc(), FPOptionsOverride());
|
TemplateParams->getTemplateLoc(), FPOptionsOverride()),
|
||||||
|
FunctionTrailingRC.ArgumentPackSubstitutionIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
return buildDeductionGuide(
|
return buildDeductionGuide(
|
||||||
@ -1238,14 +1247,20 @@ void DeclareImplicitDeductionGuidesForTypeAlias(
|
|||||||
// FIXME: Here the synthesized deduction guide is not a templated
|
// FIXME: Here the synthesized deduction guide is not a templated
|
||||||
// function. Per [dcl.decl]p4, the requires-clause shall be present only
|
// function. Per [dcl.decl]p4, the requires-clause shall be present only
|
||||||
// if the declarator declares a templated function, a bug in standard?
|
// if the declarator declares a templated function, a bug in standard?
|
||||||
auto *Constraint = buildIsDeducibleConstraint(
|
AssociatedConstraint Constraint(
|
||||||
SemaRef, AliasTemplate, Transformed->getReturnType(), {});
|
buildIsDeducibleConstraint(SemaRef, AliasTemplate,
|
||||||
if (auto *RC = DG->getTrailingRequiresClause()) {
|
Transformed->getReturnType(), {}),
|
||||||
auto Conjunction =
|
/*ArgumentPackSubstitutionIndex=*/-1);
|
||||||
SemaRef.BuildBinOp(SemaRef.getCurScope(), SourceLocation{},
|
if (const AssociatedConstraint &RC = DG->getTrailingRequiresClause()) {
|
||||||
BinaryOperatorKind::BO_LAnd, RC, Constraint);
|
auto Conjunction = SemaRef.BuildBinOp(
|
||||||
if (!Conjunction.isInvalid())
|
SemaRef.getCurScope(), SourceLocation{},
|
||||||
Constraint = Conjunction.getAs<Expr>();
|
BinaryOperatorKind::BO_LAnd, const_cast<Expr *>(RC.ConstraintExpr),
|
||||||
|
const_cast<Expr *>(Constraint.ConstraintExpr));
|
||||||
|
if (!Conjunction.isInvalid()) {
|
||||||
|
Constraint.ConstraintExpr = Conjunction.getAs<Expr>();
|
||||||
|
Constraint.ArgumentPackSubstitutionIndex =
|
||||||
|
RC.ArgumentPackSubstitutionIndex;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Transformed->setTrailingRequiresClause(Constraint);
|
Transformed->setTrailingRequiresClause(Constraint);
|
||||||
continue;
|
continue;
|
||||||
|
@ -2671,7 +2671,7 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
Expr *TrailingRequiresClause = D->getTrailingRequiresClause();
|
AssociatedConstraint TrailingRequiresClause = D->getTrailingRequiresClause();
|
||||||
|
|
||||||
// If we're instantiating a local function declaration, put the result
|
// If we're instantiating a local function declaration, put the result
|
||||||
// in the enclosing namespace; otherwise we need to find the instantiated
|
// in the enclosing namespace; otherwise we need to find the instantiated
|
||||||
@ -3102,7 +3102,7 @@ Decl *TemplateDeclInstantiator::VisitCXXMethodDecl(
|
|||||||
}
|
}
|
||||||
|
|
||||||
CXXRecordDecl *Record = cast<CXXRecordDecl>(DC);
|
CXXRecordDecl *Record = cast<CXXRecordDecl>(DC);
|
||||||
Expr *TrailingRequiresClause = D->getTrailingRequiresClause();
|
AssociatedConstraint TrailingRequiresClause = D->getTrailingRequiresClause();
|
||||||
|
|
||||||
DeclarationNameInfo NameInfo
|
DeclarationNameInfo NameInfo
|
||||||
= SemaRef.SubstDeclarationNameInfo(D->getNameInfo(), TemplateArgs);
|
= SemaRef.SubstDeclarationNameInfo(D->getNameInfo(), TemplateArgs);
|
||||||
|
@ -15659,10 +15659,13 @@ TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {
|
|||||||
auto FPTL = NewCallOpTSI->getTypeLoc().getAsAdjusted<FunctionProtoTypeLoc>();
|
auto FPTL = NewCallOpTSI->getTypeLoc().getAsAdjusted<FunctionProtoTypeLoc>();
|
||||||
assert(FPTL && "Not a FunctionProtoType?");
|
assert(FPTL && "Not a FunctionProtoType?");
|
||||||
|
|
||||||
|
AssociatedConstraint TRC = E->getCallOperator()->getTrailingRequiresClause();
|
||||||
|
if (TRC.ArgumentPackSubstitutionIndex == -1)
|
||||||
|
TRC.ArgumentPackSubstitutionIndex = SemaRef.ArgumentPackSubstitutionIndex;
|
||||||
|
|
||||||
getSema().CompleteLambdaCallOperator(
|
getSema().CompleteLambdaCallOperator(
|
||||||
NewCallOperator, E->getCallOperator()->getLocation(),
|
NewCallOperator, E->getCallOperator()->getLocation(),
|
||||||
E->getCallOperator()->getInnerLocStart(),
|
E->getCallOperator()->getInnerLocStart(), TRC, NewCallOpTSI,
|
||||||
E->getCallOperator()->getTrailingRequiresClause(), NewCallOpTSI,
|
|
||||||
E->getCallOperator()->getConstexprKind(),
|
E->getCallOperator()->getConstexprKind(),
|
||||||
E->getCallOperator()->getStorageClass(), FPTL.getParams(),
|
E->getCallOperator()->getStorageClass(), FPTL.getParams(),
|
||||||
E->hasExplicitResultType());
|
E->hasExplicitResultType());
|
||||||
|
@ -904,7 +904,8 @@ void ASTDeclReader::VisitDeclaratorDecl(DeclaratorDecl *DD) {
|
|||||||
if (Record.readInt()) { // hasExtInfo
|
if (Record.readInt()) { // hasExtInfo
|
||||||
auto *Info = new (Reader.getContext()) DeclaratorDecl::ExtInfo();
|
auto *Info = new (Reader.getContext()) DeclaratorDecl::ExtInfo();
|
||||||
Record.readQualifierInfo(*Info);
|
Record.readQualifierInfo(*Info);
|
||||||
Info->TrailingRequiresClause = Record.readExpr();
|
Info->TrailingRequiresClause =
|
||||||
|
AssociatedConstraint(Record.readExpr(), int(Record.readInt()));
|
||||||
DD->DeclInfo = Info;
|
DD->DeclInfo = Info;
|
||||||
}
|
}
|
||||||
QualType TSIType = Record.readType();
|
QualType TSIType = Record.readType();
|
||||||
|
@ -728,7 +728,10 @@ void ASTDeclWriter::VisitDeclaratorDecl(DeclaratorDecl *D) {
|
|||||||
if (D->hasExtInfo()) {
|
if (D->hasExtInfo()) {
|
||||||
DeclaratorDecl::ExtInfo *Info = D->getExtInfo();
|
DeclaratorDecl::ExtInfo *Info = D->getExtInfo();
|
||||||
Record.AddQualifierInfo(*Info);
|
Record.AddQualifierInfo(*Info);
|
||||||
Record.AddStmt(Info->TrailingRequiresClause);
|
Record.AddStmt(
|
||||||
|
const_cast<Expr *>(Info->TrailingRequiresClause.ConstraintExpr));
|
||||||
|
Record.push_back(
|
||||||
|
Info->TrailingRequiresClause.ArgumentPackSubstitutionIndex);
|
||||||
}
|
}
|
||||||
// The location information is deferred until the end of the record.
|
// The location information is deferred until the end of the record.
|
||||||
Record.AddTypeRef(D->getTypeSourceInfo() ? D->getTypeSourceInfo()->getType()
|
Record.AddTypeRef(D->getTypeSourceInfo() ? D->getTypeSourceInfo()->getType()
|
||||||
|
@ -267,6 +267,15 @@ static_assert(bazz<1, 2>()(1));
|
|||||||
// expected-error@-1 {{is ambiguous}}
|
// expected-error@-1 {{is ambiguous}}
|
||||||
// expected-note@#bazz 2{{candidate function [with value:auto = int]}}
|
// expected-note@#bazz 2{{candidate function [with value:auto = int]}}
|
||||||
|
|
||||||
|
template <class T> concept C2 = sizeof(T) >= sizeof(int);
|
||||||
|
template <class... Ts> static constexpr auto trailing() {
|
||||||
|
return Overloaded{[](auto) requires (C2<Ts> && C2<int>) { return 0; }...}; // #trailing
|
||||||
|
}
|
||||||
|
static_assert(trailing<int, long>()(0));
|
||||||
|
// expected-error@-1 {{is ambiguous}}
|
||||||
|
// expected-note@#trailing 2{{candidate function [with auto:1 = int]}}
|
||||||
|
|
||||||
|
|
||||||
} // namespace GH101754
|
} // namespace GH101754
|
||||||
|
|
||||||
namespace GH131798 {
|
namespace GH131798 {
|
||||||
|
@ -872,7 +872,7 @@ bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
|
|||||||
// FIXME: Attributes?
|
// FIXME: Attributes?
|
||||||
}
|
}
|
||||||
|
|
||||||
if (auto *E = ND->getTrailingRequiresClause()) {
|
if (auto *E = ND->getTrailingRequiresClause().ConstraintExpr) {
|
||||||
if (Visit(E))
|
if (Visit(E))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user