summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaDecl.cpp
diff options
context:
space:
mode:
authorSaar Raz <saar@raz.email>2020-01-09 15:07:51 +0200
committerSaar Raz <saar@raz.email>2020-01-09 15:07:51 +0200
commitb65b1f322bd88513586a4539d2b5f18aeb698f3f (patch)
treea5d8eb911df5b6d857675415efc125270826a740 /clang/lib/Sema/SemaDecl.cpp
parent9c91d79dadc660cb6a0ec736389341debd8cd118 (diff)
downloadbcm5719-llvm-b65b1f322bd88513586a4539d2b5f18aeb698f3f.tar.gz
bcm5719-llvm-b65b1f322bd88513586a4539d2b5f18aeb698f3f.zip
[Concepts] Function trailing requires clauses
Function trailing requires clauses now parsed, supported in overload resolution and when calling, referencing and taking the address of functions or function templates. Differential Revision: https://reviews.llvm.org/D43357
Diffstat (limited to 'clang/lib/Sema/SemaDecl.cpp')
-rw-r--r--clang/lib/Sema/SemaDecl.cpp39
1 files changed, 30 insertions, 9 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 92b115c8a3f..468db9cfc7f 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -7895,7 +7895,13 @@ struct FindOverriddenMethod {
Path.Decls = Path.Decls.slice(1)) {
NamedDecl *D = Path.Decls.front();
if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D)) {
- if (MD->isVirtual() && !S->IsOverload(Method, MD, false))
+ if (MD->isVirtual() &&
+ !S->IsOverload(
+ Method, MD, /*UseMemberUsingDeclRules=*/false,
+ /*ConsiderCudaAttrs=*/true,
+ // C++2a [class.virtual]p2 does not consider requires clauses
+ // when overriding.
+ /*ConsiderRequiresClauses=*/false))
return true;
}
}
@@ -8240,7 +8246,8 @@ static FunctionDecl *CreateNewFunctionDecl(Sema &SemaRef, Declarator &D,
NewFD = FunctionDecl::Create(SemaRef.Context, DC, D.getBeginLoc(), NameInfo,
R, TInfo, SC, isInline, HasPrototype,
- CSK_unspecified);
+ CSK_unspecified,
+ /*TrailingRequiresClause=*/nullptr);
if (D.isInvalidType())
NewFD->setInvalidDecl();
@@ -8257,6 +8264,7 @@ static FunctionDecl *CreateNewFunctionDecl(Sema &SemaRef, Declarator &D,
ConstexprKind = CSK_unspecified;
D.getMutableDeclSpec().ClearConstexprSpec();
}
+ Expr *TrailingRequiresClause = D.getTrailingRequiresClause();
// Check that the return type is not an abstract class type.
// For record types, this is done by the AbstractClassUsageDiagnoser once
@@ -8276,7 +8284,8 @@ static FunctionDecl *CreateNewFunctionDecl(Sema &SemaRef, Declarator &D,
return CXXConstructorDecl::Create(
SemaRef.Context, cast<CXXRecordDecl>(DC), D.getBeginLoc(), NameInfo, R,
TInfo, ExplicitSpecifier, isInline,
- /*isImplicitlyDeclared=*/false, ConstexprKind);
+ /*isImplicitlyDeclared=*/false, ConstexprKind, InheritedConstructor(),
+ TrailingRequiresClause);
} else if (Name.getNameKind() == DeclarationName::CXXDestructorName) {
// This is a C++ destructor declaration.
@@ -8285,8 +8294,8 @@ static FunctionDecl *CreateNewFunctionDecl(Sema &SemaRef, Declarator &D,
CXXRecordDecl *Record = cast<CXXRecordDecl>(DC);
CXXDestructorDecl *NewDD = CXXDestructorDecl::Create(
SemaRef.Context, Record, D.getBeginLoc(), NameInfo, R, TInfo,
- isInline,
- /*isImplicitlyDeclared=*/false, ConstexprKind);
+ isInline, /*isImplicitlyDeclared=*/false, ConstexprKind,
+ TrailingRequiresClause);
// If the destructor needs an implicit exception specification, set it
// now. FIXME: It'd be nice to be able to create the right type to start
@@ -8306,7 +8315,8 @@ static FunctionDecl *CreateNewFunctionDecl(Sema &SemaRef, Declarator &D,
return FunctionDecl::Create(SemaRef.Context, DC, D.getBeginLoc(),
D.getIdentifierLoc(), Name, R, TInfo, SC,
isInline,
- /*hasPrototype=*/true, ConstexprKind);
+ /*hasPrototype=*/true, ConstexprKind,
+ TrailingRequiresClause);
}
} else if (Name.getNameKind() == DeclarationName::CXXConversionFunctionName) {
@@ -8323,9 +8333,14 @@ static FunctionDecl *CreateNewFunctionDecl(Sema &SemaRef, Declarator &D,
IsVirtualOkay = true;
return CXXConversionDecl::Create(
SemaRef.Context, cast<CXXRecordDecl>(DC), D.getBeginLoc(), NameInfo, R,
- TInfo, isInline, ExplicitSpecifier, ConstexprKind, SourceLocation());
+ TInfo, isInline, ExplicitSpecifier, ConstexprKind, SourceLocation(),
+ TrailingRequiresClause);
} else if (Name.getNameKind() == DeclarationName::CXXDeductionGuideName) {
+ if (TrailingRequiresClause)
+ SemaRef.Diag(TrailingRequiresClause->getBeginLoc(),
+ diag::err_trailing_requires_clause_on_deduction_guide)
+ << TrailingRequiresClause->getSourceRange();
SemaRef.CheckDeductionGuideDeclarator(D, R, SC);
return CXXDeductionGuideDecl::Create(SemaRef.Context, DC, D.getBeginLoc(),
@@ -8347,7 +8362,8 @@ static FunctionDecl *CreateNewFunctionDecl(Sema &SemaRef, Declarator &D,
// This is a C++ method declaration.
CXXMethodDecl *Ret = CXXMethodDecl::Create(
SemaRef.Context, cast<CXXRecordDecl>(DC), D.getBeginLoc(), NameInfo, R,
- TInfo, SC, isInline, ConstexprKind, SourceLocation());
+ TInfo, SC, isInline, ConstexprKind, SourceLocation(),
+ TrailingRequiresClause);
IsVirtualOkay = !Ret->isStatic();
return Ret;
} else {
@@ -8361,7 +8377,7 @@ static FunctionDecl *CreateNewFunctionDecl(Sema &SemaRef, Declarator &D,
// - we're in C++ (where every function has a prototype),
return FunctionDecl::Create(SemaRef.Context, DC, D.getBeginLoc(), NameInfo,
R, TInfo, SC, isInline, true /*HasPrototype*/,
- ConstexprKind);
+ ConstexprKind, TrailingRequiresClause);
}
}
@@ -10572,6 +10588,11 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,
}
}
}
+ if (Method->isVirtual() && NewFD->getTrailingRequiresClause())
+ // C++2a [class.virtual]p6
+ // A virtual method shall not have a requires-clause.
+ Diag(NewFD->getTrailingRequiresClause()->getBeginLoc(),
+ diag::err_constrained_virtual_method);
if (Method->isStatic())
checkThisInStaticMemberFunctionType(Method);
OpenPOWER on IntegriCloud