On Thu, Jul 11, 2019 at 12:41 PM Alexandre Oliva <ol...@adacore.com> wrote: > > 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?
OK. Thanks a lot! Richard. > 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