From c0ae7dfe75e5980aaa65c8907211b3e96c85d1cc Mon Sep 17 00:00:00 2001 From: Aaron Ballman Date: Sat, 8 Nov 2014 17:07:15 +0000 Subject: [PATCH] Updated the wording for a diagnostic to be more grammatically correct, and use a %select. Also ensure that nested namespace definitions are diagnosed properly. Both changes are motivated by post-commit feedback from r221580. llvm-svn: 221581 --- clang/include/clang/Basic/DiagnosticParseKinds.td | 7 +++++-- clang/lib/Parse/ParseDecl.cpp | 2 +- clang/lib/Parse/ParseDeclCXX.cpp | 7 ++++++- clang/test/Parser/cxx0x-attributes.cpp | 4 ++-- 4 files changed, 14 insertions(+), 6 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td index 9c94feb..cdcfddd 100644 --- a/clang/include/clang/Basic/DiagnosticParseKinds.td +++ b/clang/include/clang/Basic/DiagnosticParseKinds.td @@ -197,6 +197,8 @@ def err_expected_semi_after_namespace_name : Error< "expected ';' after namespace name">; def err_unexpected_namespace_attributes_alias : Error< "attributes cannot be specified on namespace alias">; +def err_unexpected_nested_namespace_attribute : Error< + "attributes cannot be specified on a nested namespace definition">; def err_inline_namespace_alias : Error<"namespace alias cannot be inline">; def err_namespace_nonnamespace_scope : Error< "namespaces can only be defined in global or namespace scope">; @@ -562,8 +564,9 @@ def warn_cxx98_compat_nullptr : Warning< "'nullptr' is incompatible with C++98">, InGroup, DefaultIgnore; def warn_cxx14_compat_attribute : Warning< - "attribute on %0 declarations are incompatible with C++ standards before " - "C++1z">, InGroup, DefaultIgnore; + "attributes on %select{a namespace|an enumerator}0 declaration are " + "incompatible with C++ standards before C++1z">, + InGroup, DefaultIgnore; def warn_cxx98_compat_alignas : Warning<"'alignas' is incompatible with C++98">, InGroup, DefaultIgnore; def warn_cxx98_compat_attribute : Warning< diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index bc162fc..b2fa88d 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -3854,7 +3854,7 @@ void Parser::ParseEnumBody(SourceLocation StartLoc, Decl *EnumDecl) { if (getLangOpts().CPlusPlus11 && isCXX11AttributeSpecifier()) { if (!getLangOpts().CPlusPlus1z) Diag(Tok.getLocation(), diag::warn_cxx14_compat_attribute) - << "enumerator"; + << 1 /*enumerator*/; ParseCXX11Attributes(attrs); } diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp index 1f56c8b..7c98d70 100644 --- a/clang/lib/Parse/ParseDeclCXX.cpp +++ b/clang/lib/Parse/ParseDeclCXX.cpp @@ -77,7 +77,8 @@ Decl *Parser::ParseNamespace(unsigned Context, SourceLocation attrLoc; if (getLangOpts().CPlusPlus11 && isCXX11AttributeSpecifier()) { if (!getLangOpts().CPlusPlus1z) - Diag(Tok.getLocation(), diag::warn_cxx14_compat_attribute) << "namespace"; + Diag(Tok.getLocation(), diag::warn_cxx14_compat_attribute) + << 0 /*namespace*/; attrLoc = Tok.getLocation(); ParseCXX11Attributes(attrs); } @@ -92,6 +93,10 @@ Decl *Parser::ParseNamespace(unsigned Context, } } + // A nested namespace definition cannot have attributes. + if (!ExtraNamespaceLoc.empty() && attrLoc.isValid()) + Diag(attrLoc, diag::err_unexpected_nested_namespace_attribute); + // Read label attributes, if present. if (Tok.is(tok::kw___attribute)) { attrLoc = Tok.getLocation(); diff --git a/clang/test/Parser/cxx0x-attributes.cpp b/clang/test/Parser/cxx0x-attributes.cpp index 3c36a6e..e366d85 100644 --- a/clang/test/Parser/cxx0x-attributes.cpp +++ b/clang/test/Parser/cxx0x-attributes.cpp @@ -121,7 +121,7 @@ extern "C++" [[]] { } // expected-error {{an attribute list cannot appear here}} [[]] using ns::i; // expected-error {{an attribute list cannot appear here}} [[unknown]] using namespace ns; // expected-warning {{unknown attribute 'unknown' ignored}} [[noreturn]] using namespace ns; // expected-error {{'noreturn' attribute only applies to functions}} -namespace [[]] ns2 {} // expected-warning {{attribute on namespace declarations are incompatible with C++ standards before C++1z}} +namespace [[]] ns2 {} // expected-warning {{attributes on a namespace declaration are incompatible with C++ standards before C++1z}} using [[]] alignas(4) [[]] ns::i; // expected-error {{an attribute list cannot appear here}} using [[]] alignas(4) [[]] foobar = int; // expected-error {{an attribute list cannot appear here}} expected-error {{'alignas' attribute only applies to}} @@ -173,7 +173,7 @@ enum [[]] E2; // expected-error {{forbids forward references}} enum [[]] E1; enum [[]] E3 : int; enum [[]] { - k_123 [[]] = 123 // expected-warning {{attribute on enumerator declarations are incompatible with C++ standards before C++1z}} + k_123 [[]] = 123 // expected-warning {{attributes on an enumerator declaration are incompatible with C++ standards before C++1z}} }; enum [[]] E1 e; // expected-error {{an attribute list cannot appear here}} enum [[]] class E4 { }; // expected-error {{an attribute list cannot appear here}} -- 2.7.4