summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/include/clang/Basic/DiagnosticParseKinds.td7
-rw-r--r--clang/lib/Parse/ParseDecl.cpp2
-rw-r--r--clang/lib/Parse/ParseDeclCXX.cpp7
-rw-r--r--clang/test/Parser/cxx0x-attributes.cpp4
4 files changed, 14 insertions, 6 deletions
diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td
index 9c94feb96e9..cdcfddd8bd9 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<CXX98Compat>, DefaultIgnore;
def warn_cxx14_compat_attribute : Warning<
- "attribute on %0 declarations are incompatible with C++ standards before "
- "C++1z">, InGroup<CXXPre1zCompat>, DefaultIgnore;
+ "attributes on %select{a namespace|an enumerator}0 declaration are "
+ "incompatible with C++ standards before C++1z">,
+ InGroup<CXXPre1zCompat>, DefaultIgnore;
def warn_cxx98_compat_alignas : Warning<"'alignas' is incompatible with C++98">,
InGroup<CXX98Compat>, DefaultIgnore;
def warn_cxx98_compat_attribute : Warning<
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index bc162fc6978..b2fa88db2b6 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 1f56c8ba3b5..7c98d70b683 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 3c36a6e1dc4..e366d8582e8 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}}
OpenPOWER on IntegriCloud