diff options
| author | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2011-12-17 04:13:22 +0000 |
|---|---|---|
| committer | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2011-12-17 04:13:22 +0000 |
| commit | e1ee623adabc9f2132de2cf557e8d920cc558868 (patch) | |
| tree | 597879b628cc8af2c48108bfc47bb4bfd72dbce7 | |
| parent | 9a174fb8ee5dd4c7bd61a7e619ea88223b730786 (diff) | |
| download | bcm5719-llvm-e1ee623adabc9f2132de2cf557e8d920cc558868.tar.gz bcm5719-llvm-e1ee623adabc9f2132de2cf557e8d920cc558868.zip | |
In Parser::SkipUntil do not stop at '@' unconditionally.
Stopping at '@' was originally intended to avoid skipping an '@' at the @interface context
when doing parser recovery, but we should not stop at all '@' tokens because they may be part
of expressions (e.g. in @"string", @selector(), etc.), so in most cases we will want to skip them.
This commit caused 'test/Parser/method-def-in-class.m' to fail for the cases where we tried to
recover from unmatched angle bracket but IMO it is not a big deal to not have good recovery
from such broken code and the way we did recovery would not always work anyway (e.g. if there was '@'
in an expression).
The case that rdar://7029784 is about still passes.
llvm-svn: 146815
| -rw-r--r-- | clang/lib/Parse/ParseObjc.cpp | 8 | ||||
| -rw-r--r-- | clang/lib/Parse/Parser.cpp | 3 | ||||
| -rw-r--r-- | clang/test/Parser/method-def-in-class.m | 11 |
3 files changed, 6 insertions, 16 deletions
diff --git a/clang/lib/Parse/ParseObjc.cpp b/clang/lib/Parse/ParseObjc.cpp index 56d5c57c056..1f20924c9b7 100644 --- a/clang/lib/Parse/ParseObjc.cpp +++ b/clang/lib/Parse/ParseObjc.cpp @@ -366,8 +366,12 @@ void Parser::ParseObjCInterfaceDeclList(tok::ObjCKeywordKind contextKey, allMethods.push_back(methodPrototype); // Consume the ';' here, since ParseObjCMethodPrototype() is re-used for // method definitions. - ExpectAndConsume(tok::semi, diag::err_expected_semi_after_method_proto, - "", tok::semi); + if (ExpectAndConsumeSemi(diag::err_expected_semi_after_method_proto)) { + // We didn't find a semi and we error'ed out. Skip until a ';' or '@'. + SkipUntil(tok::at, /*StopAtSemi=*/true, /*DontConsume=*/true); + if (Tok.is(tok::semi)) + ConsumeToken(); + } continue; } if (Tok.is(tok::l_paren)) { diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp index 95ce065ff76..c57711dbc6d 100644 --- a/clang/lib/Parse/Parser.cpp +++ b/clang/lib/Parse/Parser.cpp @@ -284,9 +284,6 @@ bool Parser::SkipUntil(const tok::TokenKind *Toks, unsigned NumToks, ConsumeStringToken(); break; - case tok::at: - return false; - case tok::semi: if (StopAtSemi) return false; diff --git a/clang/test/Parser/method-def-in-class.m b/clang/test/Parser/method-def-in-class.m index 490c0559d10..476ab9ba20e 100644 --- a/clang/test/Parser/method-def-in-class.m +++ b/clang/test/Parser/method-def-in-class.m @@ -7,19 +7,8 @@ } @end -@interface B --(id) f0 { // expected-error {{expected ';' after method prototype}} - assert(0); -@end - @interface C - (id) f0 { // expected-error {{expected ';' after method prototype}} assert(0); }; @end - -@interface D -- (id) f0 { // expected-error {{expected ';' after method prototype}} - assert(0); -@property int P; -@end |

