[cfe-commits] r154476 - in /cfe/trunk: lib/Parse/ParseDecl.cpp lib/Parse/ParseTentative.cpp test/Parser/cxx0x-attributes.cpp test/Parser/objcxx11-attributes.mm
Richard Smith
richard-llvm at metafoo.co.uk
Tue Apr 10 21:01:28 PDT 2012
Author: rsmith
Date: Tue Apr 10 23:01:28 2012
New Revision: 154476
URL: http://llvm.org/viewvc/llvm-project?rev=154476&view=rev
Log:
Support C++11 attributes at the start of a parameter-declaration.
Modified:
cfe/trunk/lib/Parse/ParseDecl.cpp
cfe/trunk/lib/Parse/ParseTentative.cpp
cfe/trunk/test/Parser/cxx0x-attributes.cpp
cfe/trunk/test/Parser/objcxx11-attributes.mm
Modified: cfe/trunk/lib/Parse/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=154476&r1=154475&r2=154476&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDecl.cpp Tue Apr 10 23:01:28 2012
@@ -4038,7 +4038,8 @@
} else if (Tok.is(tok::r_paren) || // 'int()' is a function.
(getLangOpts().CPlusPlus && Tok.is(tok::ellipsis) &&
NextToken().is(tok::r_paren)) || // C++ int(...)
- isDeclarationSpecifier()) { // 'int(int)' is a function.
+ isDeclarationSpecifier() || // 'int(int)' is a function.
+ isCXX11AttributeSpecifier()) { // 'int([[]]int)' is a function.
// This handles C99 6.7.5.3p11: in "typedef int X; void foo(X)", X is
// considered to be a type, not a K&R identifier-list.
isGrouping = false;
@@ -4318,9 +4319,9 @@
/// after the opening parenthesis. This function will not parse a K&R-style
/// identifier list.
///
-/// D is the declarator being parsed. If attrs is non-null, then the caller
-/// parsed those arguments immediately after the open paren - they should be
-/// considered to be the first argument of a parameter.
+/// D is the declarator being parsed. If FirstArgAttrs is non-null, then the
+/// caller parsed those arguments immediately after the open paren - they should
+/// be considered to be part of the first parameter.
///
/// After returning, ParamInfo will hold the parsed parameters. EllipsisLoc will
/// be the location of the ellipsis, if any was parsed.
@@ -4343,15 +4344,18 @@
/// [C++] declaration-specifiers abstract-declarator[opt]
/// '=' assignment-expression
/// [GNU] declaration-specifiers abstract-declarator[opt] attributes
+/// [C++11] attribute-specifier-seq parameter-declaration
///
void Parser::ParseParameterDeclarationClause(
Declarator &D,
- ParsedAttributes &attrs,
+ ParsedAttributes &FirstArgAttrs,
SmallVector<DeclaratorChunk::ParamInfo, 16> &ParamInfo,
SourceLocation &EllipsisLoc) {
while (1) {
if (Tok.is(tok::ellipsis)) {
+ // FIXME: Issue a diagnostic if we parsed an attribute-specifier-seq
+ // before deciding this was a parameter-declaration-clause.
EllipsisLoc = ConsumeToken(); // Consume the ellipsis.
break;
}
@@ -4360,6 +4364,9 @@
// Just use the ParsingDeclaration "scope" of the declarator.
DeclSpec DS(AttrFactory);
+ // Parse any C++11 attributes.
+ MaybeParseCXX0XAttributes(DS.getAttributes());
+
// Skip any Microsoft attributes before a param.
if (getLangOpts().MicrosoftExt && Tok.is(tok::l_square))
ParseMicrosoftAttributes(DS.getAttributes());
@@ -4368,12 +4375,10 @@
// If the caller parsed attributes for the first argument, add them now.
// Take them so that we only apply the attributes to the first parameter.
- // FIXME: If we saw an ellipsis first, this code is not reached. Are the
- // attributes lost? Should they even be allowed?
// FIXME: If we can leave the attributes in the token stream somehow, we can
- // get rid of a parameter (attrs) and this statement. It might be too much
- // hassle.
- DS.takeAttributesFrom(attrs);
+ // get rid of a parameter (FirstArgAttrs) and this statement. It might be
+ // too much hassle.
+ DS.takeAttributesFrom(FirstArgAttrs);
ParseDeclarationSpecifiers(DS);
Modified: cfe/trunk/lib/Parse/ParseTentative.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseTentative.cpp?rev=154476&r1=154475&r2=154476&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseTentative.cpp (original)
+++ cfe/trunk/lib/Parse/ParseTentative.cpp Tue Apr 10 23:01:28 2012
@@ -1322,6 +1322,11 @@
return TPResult::False();
}
+ // An attribute-specifier-seq here is a sign of a function declarator.
+ if (isCXX11AttributeSpecifier(/*Disambiguate*/false,
+ /*OuterMightBeMessageSend*/true))
+ return TPResult::True();
+
ParsedAttributes attrs(AttrFactory);
MaybeParseMicrosoftAttributes(attrs);
Modified: cfe/trunk/test/Parser/cxx0x-attributes.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/cxx0x-attributes.cpp?rev=154476&r1=154475&r2=154476&view=diff
==============================================================================
--- cfe/trunk/test/Parser/cxx0x-attributes.cpp (original)
+++ cfe/trunk/test/Parser/cxx0x-attributes.cpp Tue Apr 10 23:01:28 2012
@@ -71,6 +71,10 @@
(void)s.arr[ [] { return 0; }() ]; // expected-error {{C++11 only allows consecutive left square brackets when introducing an attribute}}
int n = __builtin_offsetof(S, arr[ [] { return 0; }() ]); // expected-error {{C++11 only allows consecutive left square brackets when introducing an attribute}}
+ void bar [[noreturn]] ([[]] int i, [[]] int j);
+ using FuncType = void ([[]] int);
+ void baz([[]]...); // expected-error {{expected parameter declarator}}
+
[[]] return;
}
Modified: cfe/trunk/test/Parser/objcxx11-attributes.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/objcxx11-attributes.mm?rev=154476&r1=154475&r2=154476&view=diff
==============================================================================
--- cfe/trunk/test/Parser/objcxx11-attributes.mm (original)
+++ cfe/trunk/test/Parser/objcxx11-attributes.mm Tue Apr 10 23:01:28 2012
@@ -34,6 +34,18 @@
[[int(), noreturn]];
[[class, test(foo 'x' bar),,,]];
[[bitand, noreturn]];
+
+ [[noreturn]]int(e)();
+
+ // A function taking a noreturn function.
+ int(f)([[noreturn]] int());
+ f(e);
+
+ // Variables initialized by a message send.
+ int(g)([[noreturn getSelf] getSize]);
+ int(h)([[noreturn]{return noreturn;}() getSize]);
+
+ int i = g + h;
}
template<typename...Ts> void f(Ts ...x) {
More information about the cfe-commits
mailing list