[cfe-commits] r153544 - in /cfe/trunk: lib/Parse/ParseDecl.cpp lib/Parse/ParseTentative.cpp test/Parser/cxx0x-ambig.cpp
Richard Smith
richard-llvm at metafoo.co.uk
Tue Mar 27 16:05:05 PDT 2012
Author: rsmith
Date: Tue Mar 27 18:05:05 2012
New Revision: 153544
URL: http://llvm.org/viewvc/llvm-project?rev=153544&view=rev
Log:
If we see '(...' where we're expecting an abstract-declarator, that doesn't
necessarily mean we've found a function declarator. If the next token is not
a ')', this is actually a parenthesized pack expansion.
Modified:
cfe/trunk/lib/Parse/ParseDecl.cpp
cfe/trunk/lib/Parse/ParseTentative.cpp
cfe/trunk/test/Parser/cxx0x-ambig.cpp
Modified: cfe/trunk/lib/Parse/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=153544&r1=153543&r2=153544&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDecl.cpp Tue Mar 27 18:05:05 2012
@@ -3354,15 +3354,17 @@
return false;
}
- // Current class name must be followed by a left parentheses.
+ // Current class name must be followed by a left parenthesis.
if (Tok.isNot(tok::l_paren)) {
TPA.Revert();
return false;
}
ConsumeParen();
- // A right parentheses or ellipsis signals that we have a constructor.
- if (Tok.is(tok::r_paren) || Tok.is(tok::ellipsis)) {
+ // A right parenthesis, or ellipsis followed by a right parenthesis signals
+ // that we have a constructor.
+ if (Tok.is(tok::r_paren) ||
+ (Tok.is(tok::ellipsis) && NextToken().is(tok::r_paren))) {
TPA.Revert();
return true;
}
@@ -3948,7 +3950,8 @@
// paren, because we haven't seen the identifier yet.
isGrouping = true;
} else if (Tok.is(tok::r_paren) || // 'int()' is a function.
- (getLangOpts().CPlusPlus && Tok.is(tok::ellipsis)) || // C++ int(...)
+ (getLangOpts().CPlusPlus && Tok.is(tok::ellipsis) &&
+ NextToken().is(tok::r_paren)) || // C++ int(...)
isDeclarationSpecifier()) { // '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.
Modified: cfe/trunk/lib/Parse/ParseTentative.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseTentative.cpp?rev=153544&r1=153543&r2=153544&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseTentative.cpp (original)
+++ cfe/trunk/lib/Parse/ParseTentative.cpp Tue Mar 27 18:05:05 2012
@@ -553,7 +553,8 @@
ConsumeParen();
if (mayBeAbstract &&
(Tok.is(tok::r_paren) || // 'int()' is a function.
- Tok.is(tok::ellipsis) || // 'int(...)' is a function.
+ // 'int(...)' is a function.
+ (Tok.is(tok::ellipsis) && NextToken().is(tok::r_paren)) ||
isDeclarationSpecifier())) { // 'int(int)' is a function.
// '(' parameter-declaration-clause ')' cv-qualifier-seq[opt]
// exception-specification[opt]
@@ -1236,7 +1237,10 @@
// '...'[opt]
if (Tok.is(tok::ellipsis)) {
ConsumeToken();
- return TPResult::True(); // '...' is a sign of a function declarator.
+ if (Tok.is(tok::r_paren))
+ return TPResult::True(); // '...)' is a sign of a function declarator.
+ else
+ return TPResult::False();
}
ParsedAttributes attrs(AttrFactory);
@@ -1269,7 +1273,10 @@
if (Tok.is(tok::ellipsis)) {
ConsumeToken();
- return TPResult::True(); // '...' is a sign of a function declarator.
+ if (Tok.is(tok::r_paren))
+ return TPResult::True(); // '...)' is a sign of a function declarator.
+ else
+ return TPResult::False();
}
if (Tok.isNot(tok::comma))
Modified: cfe/trunk/test/Parser/cxx0x-ambig.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/cxx0x-ambig.cpp?rev=153544&r1=153543&r2=153544&view=diff
==============================================================================
--- cfe/trunk/test/Parser/cxx0x-ambig.cpp (original)
+++ cfe/trunk/test/Parser/cxx0x-ambig.cpp Tue Mar 27 18:05:05 2012
@@ -100,3 +100,28 @@
}
}
}
+
+namespace ellipsis {
+ template<typename...T>
+ struct S {
+ void e(S::S());
+ void f(S(...args[sizeof(T)])); // expected-note {{here}}
+ void f(S(...args)[sizeof(T)]); // expected-error {{redeclared}} expected-note {{here}}
+ void f(S ...args[sizeof(T)]); // expected-error {{redeclared}}
+ void g(S(...[sizeof(T)])); // expected-note {{here}}
+ void g(S(...)[sizeof(T)]); // expected-error {{function cannot return array type}}
+ void g(S ...[sizeof(T)]); // expected-error {{redeclared}}
+ void h(T(...)); // function type, expected-error {{unexpanded parameter pack}}
+ void h(T...); // pack expansion, ok
+ void i(int(T...)); // expected-note {{here}}
+ void i(int(T...a)); // expected-error {{redeclared}}
+ void i(int(T, ...)); // function type, expected-error {{unexpanded parameter pack}}
+ void i(int(T, ...a)); // expected-error {{expected ')'}} expected-note {{to match}} expected-error {{unexpanded parameter pack}}
+ void j(int(int...)); // function type, ok
+ void j(int(int...a)); // expected-error {{does not contain any unexpanded parameter packs}}
+ void j(T(int...)); // expected-error {{unexpanded parameter pack}}
+ void j(T(T...)); // expected-error {{unexpanded parameter pack}}
+ void k(int(...)(T)); // expected-error {{cannot return function type}}
+ void k(int ...(T));
+ };
+}
More information about the cfe-commits
mailing list