On Jul 4, 2019, Richard Biener <richard.guent...@gmail.com> wrote: > Yeah. For other stuff we're simply looking at CPP_NAME and > string-matching, see c_parser_gimple_compound_statement > where you'd probably hook this into.
Here's a working patch that introduces try/finally[/else] in gimplefe. Regstrapped on x86_64-linux-gnu. Ok to install? introduce try/finally/else in gimplefe for gcc/c/ChangeLog * gimple-parser.c (c_parser_gimple_try_stmt): New. (c_parser_compound_statement): Call it. for gcc/testsuite/ChangeLog * gcc.dg/gimplefe-43.c: New. --- gcc/c/gimple-parser.c | 61 ++++++++++++++++++++++++++++++++++++ gcc/testsuite/gcc.dg/gimplefe-43.c | 25 +++++++++++++++ 2 files changed, 86 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/gimplefe-43.c diff --git a/gcc/c/gimple-parser.c b/gcc/c/gimple-parser.c index a0ea7215984a..4970ae1e9e08 100644 --- a/gcc/c/gimple-parser.c +++ b/gcc/c/gimple-parser.c @@ -117,6 +117,7 @@ static struct c_expr c_parser_gimple_postfix_expression_after_primary static void c_parser_gimple_declaration (gimple_parser &); static void c_parser_gimple_goto_stmt (gimple_parser &, location_t, tree, gimple_seq *); +static void c_parser_gimple_try_stmt (gimple_parser &, gimple_seq *); static void c_parser_gimple_if_stmt (gimple_parser &, gimple_seq *); static void c_parser_gimple_switch_stmt (gimple_parser &, gimple_seq *); static void c_parser_gimple_return_stmt (gimple_parser &, gimple_seq *); @@ -407,6 +408,9 @@ c_parser_gimple_compound_statement (gimple_parser &parser, gimple_seq *seq) case CPP_KEYWORD: switch (c_parser_peek_token (parser)->keyword) { + case RID_AT_TRY: + c_parser_gimple_try_stmt (parser, seq); + break; case RID_IF: c_parser_gimple_if_stmt (parser, seq); break; @@ -448,6 +452,14 @@ c_parser_gimple_compound_statement (gimple_parser &parser, gimple_seq *seq) c_parser_gimple_label (parser, seq); break; } + if (c_parser_next_token_is (parser, CPP_NAME) + && c_parser_peek_token (parser)->id_kind == C_ID_ID + && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value), + "try") == 0) + { + c_parser_gimple_try_stmt (parser, seq); + break; + } /* Basic block specification. __BB (index, ...) */ if ((cfun->curr_properties & PROP_cfg) @@ -2092,6 +2104,55 @@ c_parser_gimple_paren_condition (gimple_parser &parser) return cond; } +/* Parse gimple try statement. + + try-statement: + try { ... } finally { ... } + try { ... } finally { ... } else { ... } + + This could support try/catch as well, but it's not implemented yet. + */ + +static void +c_parser_gimple_try_stmt (gimple_parser &parser, gimple_seq *seq) +{ + gimple_seq tryseq = NULL; + c_parser_consume_token (parser); + c_parser_gimple_compound_statement (parser, &tryseq); + + if ((c_parser_next_token_is (parser, CPP_KEYWORD) + && c_parser_peek_token (parser)->keyword == RID_AT_FINALLY) + || (c_parser_next_token_is (parser, CPP_NAME) + && c_parser_peek_token (parser)->id_kind == C_ID_ID + && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value), + "finally") == 0)) + { + gimple_seq finseq = NULL; + c_parser_consume_token (parser); + c_parser_gimple_compound_statement (parser, &finseq); + + if (c_parser_next_token_is (parser, CPP_KEYWORD) + && c_parser_peek_token (parser)->keyword == RID_ELSE) + { + gimple_seq elsseq = NULL; + c_parser_consume_token (parser); + c_parser_gimple_compound_statement (parser, &elsseq); + + geh_else *stmt = gimple_build_eh_else (finseq, elsseq); + finseq = NULL; + gimple_seq_add_stmt_without_update (&finseq, stmt); + } + + gtry *stmt = gimple_build_try (tryseq, finseq, GIMPLE_TRY_FINALLY); + gimple_seq_add_stmt_without_update (seq, stmt); + } + else if (c_parser_next_token_is (parser, CPP_KEYWORD) + && c_parser_peek_token (parser)->keyword == RID_AT_CATCH) + c_parser_error (parser, "%<catch%> is not supported"); + else + c_parser_error (parser, "expected %<finally%> or %<catch%>"); +} + /* Parse gimple if-else statement. if-statement: diff --git a/gcc/testsuite/gcc.dg/gimplefe-43.c b/gcc/testsuite/gcc.dg/gimplefe-43.c new file mode 100644 index 000000000000..5fd66e6dfa5c --- /dev/null +++ b/gcc/testsuite/gcc.dg/gimplefe-43.c @@ -0,0 +1,25 @@ +/* { dg-do compile } */ +/* { dg-options "-fgimple" } */ + +void __GIMPLE foo() +{ + try + { + try + { + ; + } + finally + { + ; + } + else + { + ; + } + } + finally + { + ; + } +} -- Alexandre Oliva, freedom fighter he/him https://FSFLA.org/blogs/lxo Be the change, be Free! FSF Latin America board member GNU Toolchain Engineer Free Software Evangelist Hay que enGNUrecerse, pero sin perder la terGNUra jamás - Che GNUevara