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