diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2011-12-25 21:17:58 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2011-12-25 21:17:58 +0000 |
commit | dd4b350143c26c030a482f091908a2e077503411 (patch) | |
tree | 889218a05101e9cdf2a61db02ebf8ff09ce51fe8 /lib/Sema/SemaDecl.cpp | |
parent | eba05b2e396e1474f7bd6e8e8e1bd7752effef4d (diff) |
Fix constexpr handling to allow 'extern constexpr' variable declarations. We no
longer have access to the source locations we need to produce the
'replace constexpr with const' fixits, so they're gone for now.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@147273 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaDecl.cpp')
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 52 |
1 files changed, 14 insertions, 38 deletions
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index d9d7f0a99d..00c6b9fcf0 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -3948,38 +3948,8 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, TemplateParamLists.release()); } - if (D.getDeclSpec().isConstexprSpecified()) { - // FIXME: once we know whether there's an initializer, apply this to - // static data members too. - if (!NewVD->isStaticDataMember() && - !NewVD->isThisDeclarationADefinition()) { - // 'constexpr' is redundant and ill-formed on a non-defining declaration - // of a variable. Suggest replacing it with 'const' if appropriate. - SourceLocation ConstexprLoc = D.getDeclSpec().getConstexprSpecLoc(); - SourceRange ConstexprRange(ConstexprLoc, ConstexprLoc); - // If the declarator is complex, we need to move the keyword to the - // innermost chunk as we switch it from 'constexpr' to 'const'. - int Kind = DeclaratorChunk::Paren; - for (unsigned I = 0, E = D.getNumTypeObjects(); I != E; ++I) { - Kind = D.getTypeObject(I).Kind; - if (Kind != DeclaratorChunk::Paren) - break; - } - if ((D.getDeclSpec().getTypeQualifiers() & DeclSpec::TQ_const) || - Kind == DeclaratorChunk::Reference) - Diag(ConstexprLoc, diag::err_invalid_constexpr_var_decl) - << FixItHint::CreateRemoval(ConstexprRange); - else if (Kind == DeclaratorChunk::Paren) - Diag(ConstexprLoc, diag::err_invalid_constexpr_var_decl) - << FixItHint::CreateReplacement(ConstexprRange, "const"); - else - Diag(ConstexprLoc, diag::err_invalid_constexpr_var_decl) - << FixItHint::CreateRemoval(ConstexprRange) - << FixItHint::CreateInsertion(D.getIdentifierLoc(), "const "); - } else { - NewVD->setConstexpr(true); - } - } + if (D.getDeclSpec().isConstexprSpecified()) + NewVD->setConstexpr(true); } // Set the lexical context. If the declarator has a C++ scope specifier, the @@ -6244,7 +6214,7 @@ void Sema::ActOnUninitializedDecl(Decl *RealDecl, if (VarDecl *Var = dyn_cast<VarDecl>(RealDecl)) { QualType Type = Var->getType(); - // C++0x [dcl.spec.auto]p3 + // C++11 [dcl.spec.auto]p3 if (TypeMayContainAuto && Type->getContainedAutoType()) { Diag(Var->getLocation(), diag::err_auto_var_requires_init) << Var->getDeclName() << Type; @@ -6252,13 +6222,19 @@ void Sema::ActOnUninitializedDecl(Decl *RealDecl, return; } - // C++0x [class.static.data]p3: A static data member can be declared with + // C++11 [class.static.data]p3: A static data member can be declared with // the constexpr specifier; if so, its declaration shall specify // a brace-or-equal-initializer. - if (Var->isConstexpr() && Var->isStaticDataMember() && - !Var->isThisDeclarationADefinition()) { - Diag(Var->getLocation(), diag::err_constexpr_static_mem_var_requires_init) - << Var->getDeclName(); + // C++11 [dcl.constexpr]p1: The constexpr specifier shall be applied only to + // the definition of a variable [...] or the declaration of a static data + // member. + if (Var->isConstexpr() && !Var->isThisDeclarationADefinition()) { + if (Var->isStaticDataMember()) + Diag(Var->getLocation(), + diag::err_constexpr_static_mem_var_requires_init) + << Var->getDeclName(); + else + Diag(Var->getLocation(), diag::err_invalid_constexpr_var_decl); Var->setInvalidDecl(); return; } |