diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2016-06-24 12:15:12 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2016-06-24 12:15:12 +0000 |
commit | c318a9f90b5dce5c879928ec0a82761d404775ad (patch) | |
tree | 639f9c19470cfbbe8ef5820e23daa5d4374d55c3 | |
parent | c6ffb6cd00cc4ca5cfa11b863870b5a83853ae49 (diff) |
Using for attributes voted into C++17.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@273666 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/Basic/DiagnosticParseKinds.td | 8 | ||||
-rw-r--r-- | lib/Parse/ParseDeclCXX.cpp | 27 | ||||
-rw-r--r-- | test/CXX/dcl.dcl/dcl.attr/dcl.attr.grammar/p2-1z.cpp | 16 | ||||
-rw-r--r-- | www/cxx_status.html | 2 |
4 files changed, 52 insertions, 1 deletions
diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td index d7ecef77a2..699e4d6e61 100644 --- a/include/clang/Basic/DiagnosticParseKinds.td +++ b/include/clang/Basic/DiagnosticParseKinds.td @@ -560,6 +560,14 @@ def err_cxx11_attribute_forbids_ellipsis : Error< "attribute '%0' cannot be used as an attribute pack">; def err_cxx11_attribute_repeated : Error< "attribute %0 cannot appear multiple times in an attribute specifier">; +def warn_cxx14_compat_using_attribute_ns : Warning< + "default scope specifier for attributes is incompatible with C++ standards " + "before C++1z">, InGroup<CXXPre1zCompat>, DefaultIgnore; +def ext_using_attribute_ns : ExtWarn< + "default scope specifier for attributes is a C++1z extension">, + InGroup<CXX1z>; +def err_using_attribute_ns_conflict : Error< + "attribute with scope specifier cannot follow default scope specifier">; def err_attributes_not_allowed : Error<"an attribute list cannot appear here">; def err_l_square_l_square_not_attribute : Error< "C++11 only allows consecutive left square brackets when " diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp index 5718e1e50e..51f1192fae 100644 --- a/lib/Parse/ParseDeclCXX.cpp +++ b/lib/Parse/ParseDeclCXX.cpp @@ -3771,6 +3771,23 @@ void Parser::ParseCXX11AttributeSpecifier(ParsedAttributes &attrs, ConsumeBracket(); ConsumeBracket(); + SourceLocation CommonScopeLoc; + IdentifierInfo *CommonScopeName = nullptr; + if (Tok.is(tok::kw_using)) { + Diag(Tok.getLocation(), getLangOpts().CPlusPlus1z + ? diag::warn_cxx14_compat_using_attribute_ns + : diag::ext_using_attribute_ns); + ConsumeToken(); + + CommonScopeName = TryParseCXX11AttributeIdentifier(CommonScopeLoc); + if (!CommonScopeName) { + Diag(Tok.getLocation(), diag::err_expected) << tok::identifier; + SkipUntil(tok::r_square, tok::colon, StopBeforeMatch); + } + if (!TryConsumeToken(tok::colon) && CommonScopeName) + Diag(Tok.getLocation(), diag::err_expected) << tok::colon; + } + llvm::SmallDenseMap<IdentifierInfo*, SourceLocation, 4> SeenAttrs; while (Tok.isNot(tok::r_square)) { @@ -3799,6 +3816,16 @@ void Parser::ParseCXX11AttributeSpecifier(ParsedAttributes &attrs, } } + if (CommonScopeName) { + if (ScopeName) { + Diag(ScopeLoc, diag::err_using_attribute_ns_conflict) + << SourceRange(CommonScopeLoc); + } else { + ScopeName = CommonScopeName; + ScopeLoc = CommonScopeLoc; + } + } + bool StandardAttr = IsBuiltInOrStandardCXX11Attribute(AttrName, ScopeName); bool AttrParsed = false; diff --git a/test/CXX/dcl.dcl/dcl.attr/dcl.attr.grammar/p2-1z.cpp b/test/CXX/dcl.dcl/dcl.attr/dcl.attr.grammar/p2-1z.cpp new file mode 100644 index 0000000000..192fa12610 --- /dev/null +++ b/test/CXX/dcl.dcl/dcl.attr/dcl.attr.grammar/p2-1z.cpp @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -std=c++1z -verify %s + +[[disable_tail_calls, noduplicate]] void f() {} // expected-warning {{unknown attribute 'disable_tail_calls'}} expected-warning {{unknown attribute 'noduplicate'}} + +[[using clang: disable_tail_calls, noduplicate]] void g() {} // ok + +[[using]] extern int n; // expected-error {{expected identifier}} +[[using foo +] // expected-error {{expected ':'}} +] extern int n; +[[using 42:]] extern int n; // expected-error {{expected identifier}} +[[using clang:]] extern int n; // ok +[[using blah: clang::optnone]] extern int n; // expected-error {{attribute with scope specifier cannot follow}} expected-warning {{only applies to functions}} + +[[using clang: unknown_attr]] extern int n; // expected-warning {{unknown attribute}} +[[using unknown_ns: something]] extern int n; // expected-warning {{unknown attribute}} diff --git a/www/cxx_status.html b/www/cxx_status.html index ef254731b2..8da905e181 100644 --- a/www/cxx_status.html +++ b/www/cxx_status.html @@ -672,12 +672,12 @@ as the draft C++1z standard evolves.</p> <td class="full" align="center">Yes</td> </tr> <!-- Oulu papers --> - <!-- <tr> <td>Using attribute namespaces without repetition</td> <td><a href="http://wg21.link/p0028r4">P0028R4</a></td> <td class="none" align="center">No</td> </tr> + <!-- <tr> <td>Dynamic memory allocation for over-aligned data</td> <td><a href="http://wg21.link/p0035r4">P0035R4</a></td> |