aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaDeclCXX.cpp
diff options
context:
space:
mode:
authorDavid Blaikie <dblaikie@gmail.com>2013-01-30 01:22:18 +0000
committerDavid Blaikie <dblaikie@gmail.com>2013-01-30 01:22:18 +0000
commit1d87fbaeea4a9fbbd73b3a53641f59f1673098e5 (patch)
tree366c9b6f38131c732d020fbe9c635b95085bb897 /lib/Sema/SemaDeclCXX.cpp
parent7adf4179f827b14b025135829dadeaa2442e1d42 (diff)
Provide a fixit for constexpr non-static data members.
If the member has an initializer, assume it was probably intended to be static and suggest/recover with that. If the member doesn't have an initializer, assume it was probably intended to be const instead of constexpr and suggest that. (if the attempt to apply these changes fails, don't make any suggestion & produce the same diagnostic experience as before. The only case where this can come up that I know of is with a mutable constexpr with an initializer, since mutable is incompatible with static (but it's already incompatible with const anyway)) git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@173873 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaDeclCXX.cpp')
-rw-r--r--lib/Sema/SemaDeclCXX.cpp31
1 files changed, 30 insertions, 1 deletions
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index 448d083aaf..59d1e91f36 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -1666,6 +1666,35 @@ Sema::ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS, Declarator &D,
DS.getStorageClassSpec() == DeclSpec::SCS_mutable) &&
!isFunc);
+ if (DS.isConstexprSpecified() && isInstField) {
+ SemaDiagnosticBuilder B =
+ Diag(DS.getConstexprSpecLoc(), diag::err_invalid_constexpr_member);
+ SourceLocation ConstexprLoc = DS.getConstexprSpecLoc();
+ if (InitStyle == ICIS_NoInit) {
+ B << 0 << 0 << FixItHint::CreateReplacement(ConstexprLoc, "const");
+ D.getMutableDeclSpec().ClearConstexprSpec();
+ const char *PrevSpec;
+ unsigned DiagID;
+ bool Failed = D.getMutableDeclSpec().SetTypeQual(DeclSpec::TQ_const, ConstexprLoc,
+ PrevSpec, DiagID, getLangOpts());
+ assert(!Failed && "Making a constexpr member const shouldn't fail");
+ } else {
+ B << 1;
+ const char *PrevSpec;
+ unsigned DiagID;
+ DeclSpec::SCS PrevSCS = DS.getStorageClassSpec();
+ if (D.getMutableDeclSpec().SetStorageClassSpec(
+ *this, DeclSpec::SCS_static, ConstexprLoc, PrevSpec, DiagID)) {
+ assert(PrevSCS == DeclSpec::SCS_mutable &&
+ "This is the only DeclSpec that should fail to be applied");
+ B << 1;
+ } else {
+ B << 0 << FixItHint::CreateInsertion(ConstexprLoc, "static ");
+ isInstField = false;
+ }
+ }
+ }
+
NamedDecl *Member;
if (isInstField) {
CXXScopeSpec &SS = D.getCXXScopeSpec();
@@ -1720,7 +1749,7 @@ Sema::ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS, Declarator &D,
InitStyle, AS);
assert(Member && "HandleField never returns null");
} else {
- assert(InitStyle == ICIS_NoInit);
+ assert(InitStyle == ICIS_NoInit || D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_static);
Member = HandleDeclarator(S, D, TemplateParameterLists);
if (!Member) {