diff options
author | David Blaikie <dblaikie@gmail.com> | 2013-01-30 01:22:18 +0000 |
---|---|---|
committer | David Blaikie <dblaikie@gmail.com> | 2013-01-30 01:22:18 +0000 |
commit | 1d87fbaeea4a9fbbd73b3a53641f59f1673098e5 (patch) | |
tree | 366c9b6f38131c732d020fbe9c635b95085bb897 /lib/Sema/SemaDeclCXX.cpp | |
parent | 7adf4179f827b14b025135829dadeaa2442e1d42 (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.cpp | 31 |
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) { |