[c++1z] Support for attributes on namespaces and enumerators.
authorAaron Ballman <aaron@aaronballman.com>
Sat, 8 Nov 2014 15:33:35 +0000 (15:33 +0000)
committerAaron Ballman <aaron@aaronballman.com>
Sat, 8 Nov 2014 15:33:35 +0000 (15:33 +0000)
llvm-svn: 221580

clang/include/clang/Basic/DiagnosticParseKinds.td
clang/lib/Parse/ParseDecl.cpp
clang/lib/Parse/ParseDeclCXX.cpp
clang/test/Parser/cxx0x-attributes.cpp
clang/test/Parser/cxx1z-attributes.cpp [new file with mode: 0644]
clang/www/cxx_status.html

index e9efc45..9c94feb 100644 (file)
@@ -561,6 +561,9 @@ def warn_cxx98_compat_noexcept_expr : Warning<
 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;
 def warn_cxx98_compat_alignas : Warning<"'alignas' is incompatible with C++98">,
   InGroup<CXX98Compat>, DefaultIgnore;
 def warn_cxx98_compat_attribute : Warning<
index 6934752..bc162fc 100644 (file)
@@ -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;
index 223046c..1f56c8b 100644 (file)
@@ -73,7 +73,14 @@ Decl *Parser::ParseNamespace(unsigned Context,
   std::vector<IdentifierInfo*> ExtraIdent;
   std::vector<SourceLocation> 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);
index f8abc76..3c36a6e 100644 (file)
@@ -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/clang/test/Parser/cxx1z-attributes.cpp b/clang/test/Parser/cxx1z-attributes.cpp
new file mode 100644 (file)
index 0000000..52b0a53
--- /dev/null
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++1z %s\r
+\r
+namespace [[]] foo {}\r
+namespace [[]] {}\r
+namespace [[]] bad = foo; // expected-error {{attributes cannot be specified on namespace alias}}\r
+\r
+enum test {\r
+  bing [[]],\r
+  bar [[]] = 1,\r
+  baz [[]][[]],\r
+  quux [[]][[]] = 4\r
+};\r
index 345226b..1ba4106 100644 (file)
@@ -562,6 +562,11 @@ as the draft C++1z standard evolves.</p>
       <td><!--<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4230.html">-->N4230<!--</a>--></td>
       <td class="svn" align="center">SVN</td>
     </tr>
+    <tr>
+      <td>Attributes for namespaces and enumerators</td>
+      <td><!--<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4266.html">-->N4266<!--</a>--></td>
+      <td class="svn" align="center">SVN</td>
+    </tr>
 </table>
 
 <h2 id="ts">Technical specifications and standing documents</h2>