diff options
author | Nicola Pero <nicola.pero@meta-innovation.com> | 2010-11-29 03:15:40 +0000 |
---|---|---|
committer | Nicola Pero <nicola@gcc.gnu.org> | 2010-11-29 03:15:40 +0000 |
commit | 437c23222436111f80b29ec24d2fb863b567e589 (patch) | |
tree | 44406a903b8b5e0d042b1c9cd87592f05480f94d /gcc/cp/parser.c | |
parent | 45f9cadb2a94bbb57bfd0a3f68afe42346c79c57 (diff) | |
download | gcc-437c23222436111f80b29ec24d2fb863b567e589.tar.gz |
In gcc/objc/: 2010-11-29 Nicola Pero <nicola.pero@meta-innovation.com>
In gcc/objc/:
2010-11-29 Nicola Pero <nicola.pero@meta-innovation.com>
* objc-act.c (objc_eh_runtime_type): Avoid ICE if error_mark_node
is passed as argument.
(objc_begin_catch_clause): Added code to deal with an
error_mark_node or NULL_TREE argument. Improved checks for
invalid arguments. Added code to traverse typedefs.
In gcc/testsuite/:
2010-11-29 Nicola Pero <nicola.pero@meta-innovation.com>
* objc.dg/exceptions-1.m: New.
* objc.dg/exceptions-2.m: New.
* objc.dg/exceptions-3.m: New.
* objc.dg/exceptions-4.m: New.
* objc.dg/exceptions-5.m: New.
* obj-c++.dg/exceptions-1.mm: New.
* obj-c++.dg/exceptions-2.mm: New.
* obj-c++.dg/exceptions-3.mm: New.
* obj-c++.dg/exceptions-4.mm: New.
* obj-c++.dg/exceptions-5.mm: New.
In gcc/cp/:
2010-11-29 Nicola Pero <nicola.pero@meta-innovation.com>
* parser.c (cp_parser_objc_try_catch_finally_statement): Parse
@catch(...) and pass NULL_TREE to objc_begin_catch_clause() in
that case. Improved error recovery. Reorganized code to be
almost identical to c_parser_objc_try_catch_finally_statement.
In gcc/:
2010-11-29 Nicola Pero <nicola.pero@meta-innovation.com>
* c-parser.c (c_parser_objc_try_catch_statement): Renamed to
c_parser_objc_try_catch_finally_statement for consistency with the
C++ parser. Parse @catch(...) and pass NULL_TREE to
objc_begin_catch_clause() in that case. Improved error recovery.
Reorganized code to be almost identical to
cp_parser_objc_try_catch_finally_statement.
From-SVN: r167233
Diffstat (limited to 'gcc/cp/parser.c')
-rw-r--r-- | gcc/cp/parser.c | 78 |
1 files changed, 63 insertions, 15 deletions
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 3ed0579538a..917f75043b3 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -22598,15 +22598,25 @@ cp_parser_objc_declaration (cp_parser* parser, tree attributes) objc-catch-clause objc-catch-clause-seq [opt] objc-catch-clause: - @catch ( exception-declaration ) compound-statement + @catch ( objc-exception-declaration ) compound-statement - objc-finally-clause + objc-finally-clause: @finally compound-statement - Returns NULL_TREE. */ + objc-exception-declaration: + parameter-declaration + '...' + + where '...' is to be interpreted literally, that is, it means CPP_ELLIPSIS. + + Returns NULL_TREE. + + PS: This function is identical to c_parser_objc_try_catch_finally_statement + for C. Keep them in sync. */ static tree -cp_parser_objc_try_catch_finally_statement (cp_parser *parser) { +cp_parser_objc_try_catch_finally_statement (cp_parser *parser) +{ location_t location; tree stmt; @@ -22620,22 +22630,60 @@ cp_parser_objc_try_catch_finally_statement (cp_parser *parser) { while (cp_lexer_next_token_is_keyword (parser->lexer, RID_AT_CATCH)) { - cp_parameter_declarator *parmdecl; - tree parm; + cp_parameter_declarator *parm; + tree parameter_declaration = error_mark_node; + bool seen_open_paren = false; cp_lexer_consume_token (parser->lexer); - cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN); - parmdecl = cp_parser_parameter_declaration (parser, false, NULL); - parm = grokdeclarator (parmdecl->declarator, - &parmdecl->decl_specifiers, - PARM, /*initialized=*/0, - /*attrlist=*/NULL); - cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN); - objc_begin_catch_clause (parm); + if (cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN)) + seen_open_paren = true; + if (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS)) + { + /* We have "@catch (...)" (where the '...' are literally + what is in the code). Skip the '...'. + parameter_declaration is set to NULL_TREE, and + objc_being_catch_clauses() knows that that means + '...'. */ + cp_lexer_consume_token (parser->lexer); + parameter_declaration = NULL_TREE; + } + else + { + /* We have "@catch (NSException *exception)" or something + like that. Parse the parameter declaration. */ + parm = cp_parser_parameter_declaration (parser, false, NULL); + if (parm == NULL) + parameter_declaration = error_mark_node; + else + parameter_declaration = grokdeclarator (parm->declarator, + &parm->decl_specifiers, + PARM, /*initialized=*/0, + /*attrlist=*/NULL); + } + if (seen_open_paren) + cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN); + else + { + /* If there was no open parenthesis, we are recovering from + an error, and we are trying to figure out what mistake + the user has made. */ + + /* If there is an immediate closing parenthesis, the user + probably forgot the opening one (ie, they typed "@catch + NSException *e)". Parse the closing parenthesis and keep + going. */ + if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_PAREN)) + cp_lexer_consume_token (parser->lexer); + + /* If these is no immediate closing parenthesis, the user + probably doesn't know that parenthesis are required at + all (ie, they typed "@catch NSException *e"). So, just + forget about the closing parenthesis and keep going. */ + } + objc_begin_catch_clause (parameter_declaration); cp_parser_compound_statement (parser, NULL, false); objc_finish_catch_clause (); } - if (cp_lexer_next_token_is_keyword (parser->lexer, RID_AT_FINALLY)) { cp_lexer_consume_token (parser->lexer); |