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
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index 448d083..59d1e91 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -1666,6 +1666,35 @@
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 @@
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) {