From: Aaron Ballman
Date: Sat, 8 Nov 2014 15:33:35 +0000 (+0000)
Subject: [c++1z] Support for attributes on namespaces and enumerators.
X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=079c143c3e546936cf3e8884f898c18da133ad8d;p=clang
[c++1z] Support for attributes on namespaces and enumerators.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@221580 91177308-0d34-0410-b5e6-96231b3b80d8
---
diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td
index e9efc45fff..9c94feb96e 100644
--- a/include/clang/Basic/DiagnosticParseKinds.td
+++ b/include/clang/Basic/DiagnosticParseKinds.td
@@ -561,6 +561,9 @@ def warn_cxx98_compat_noexcept_expr : Warning<
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;
def warn_cxx98_compat_alignas : Warning<"'alignas' is incompatible with C++98">,
InGroup, DefaultIgnore;
def warn_cxx98_compat_attribute : Warning<
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp
index 6934752048..bc162fc697 100644
--- a/lib/Parse/ParseDecl.cpp
+++ b/lib/Parse/ParseDecl.cpp
@@ -3812,8 +3812,8 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
/// enumerator
/// enumerator-list ',' enumerator
/// enumerator:
-/// enumeration-constant
-/// enumeration-constant '=' constant-expression
+/// enumeration-constant attributes[opt]
+/// enumeration-constant attributes[opt] '=' constant-expression
/// enumeration-constant:
/// identifier
///
@@ -3850,8 +3850,13 @@ void Parser::ParseEnumBody(SourceLocation StartLoc, Decl *EnumDecl) {
// If attributes exist after the enumerator, parse them.
ParsedAttributesWithRange attrs(AttrFactory);
MaybeParseGNUAttributes(attrs);
- MaybeParseCXX11Attributes(attrs);
- ProhibitAttributes(attrs);
+ ProhibitAttributes(attrs); // GNU-style attributes are prohibited.
+ if (getLangOpts().CPlusPlus11 && isCXX11AttributeSpecifier()) {
+ if (!getLangOpts().CPlusPlus1z)
+ Diag(Tok.getLocation(), diag::warn_cxx14_compat_attribute)
+ << "enumerator";
+ ParseCXX11Attributes(attrs);
+ }
SourceLocation EqualLoc;
ExprResult AssignedVal;
diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp
index 223046c90d..1f56c8ba3b 100644
--- a/lib/Parse/ParseDeclCXX.cpp
+++ b/lib/Parse/ParseDeclCXX.cpp
@@ -73,7 +73,14 @@ Decl *Parser::ParseNamespace(unsigned Context,
std::vector ExtraIdent;
std::vector ExtraNamespaceLoc;
- Token attrTok;
+ ParsedAttributesWithRange attrs(AttrFactory);
+ SourceLocation attrLoc;
+ if (getLangOpts().CPlusPlus11 && isCXX11AttributeSpecifier()) {
+ if (!getLangOpts().CPlusPlus1z)
+ Diag(Tok.getLocation(), diag::warn_cxx14_compat_attribute) << "namespace";
+ attrLoc = Tok.getLocation();
+ ParseCXX11Attributes(attrs);
+ }
if (Tok.is(tok::identifier)) {
Ident = Tok.getIdentifierInfo();
@@ -86,9 +93,8 @@ Decl *Parser::ParseNamespace(unsigned Context,
}
// Read label attributes, if present.
- ParsedAttributes attrs(AttrFactory);
if (Tok.is(tok::kw___attribute)) {
- attrTok = Tok;
+ attrLoc = Tok.getLocation();
ParseGNUAttributes(attrs);
}
@@ -99,8 +105,8 @@ Decl *Parser::ParseNamespace(unsigned Context,
SkipUntil(tok::semi);
return nullptr;
}
- if (!attrs.empty())
- Diag(attrTok, diag::err_unexpected_namespace_attributes_alias);
+ if (attrLoc.isValid())
+ Diag(attrLoc, diag::err_unexpected_namespace_attributes_alias);
if (InlineLoc.isValid())
Diag(InlineLoc, diag::err_inline_namespace_alias)
<< FixItHint::CreateRemoval(InlineLoc);
diff --git a/test/Parser/cxx0x-attributes.cpp b/test/Parser/cxx0x-attributes.cpp
index f8abc76fb2..3c36a6e1dc 100644
--- a/test/Parser/cxx0x-attributes.cpp
+++ b/test/Parser/cxx0x-attributes.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -fsyntax-only -verify -std=c++11 %s
+// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -fsyntax-only -verify -std=c++11 -Wc++14-compat %s
// Need std::initializer_list
namespace std {
@@ -121,6 +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}}
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}}
@@ -172,7 +173,7 @@ enum [[]] E2; // expected-error {{forbids forward references}}
enum [[]] E1;
enum [[]] E3 : int;
enum [[]] {
- k_123 [[]] = 123 // expected-error {{an attribute list cannot appear here}}
+ k_123 [[]] = 123 // expected-warning {{attribute on enumerator declarations 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}}
diff --git a/test/Parser/cxx1z-attributes.cpp b/test/Parser/cxx1z-attributes.cpp
new file mode 100644
index 0000000000..52b0a53ad8
--- /dev/null
+++ b/test/Parser/cxx1z-attributes.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++1z %s
+
+namespace [[]] foo {}
+namespace [[]] {}
+namespace [[]] bad = foo; // expected-error {{attributes cannot be specified on namespace alias}}
+
+enum test {
+ bing [[]],
+ bar [[]] = 1,
+ baz [[]][[]],
+ quux [[]][[]] = 4
+};
diff --git a/www/cxx_status.html b/www/cxx_status.html
index 345226b92a..1ba4106458 100644
--- a/www/cxx_status.html
+++ b/www/cxx_status.html
@@ -562,6 +562,11 @@ as the draft C++1z standard evolves.
N4230 |
SVN |
+
+ Attributes for namespaces and enumerators |
+ N4266 |
+ SVN |
+
Technical specifications and standing documents