On Thu, Jul 4, 2019 at 10:29 AM Alexandre Oliva <ol...@adacore.com> wrote: > > On Jul 2, 2019, Richard Biener <richard.guent...@gmail.com> wrote: > > > Yeah, it's on trunk. The parser is ontop of the C frontend and resides > > in gcc/c/gimple-parser.c while testcases are in gcc.dg/gimplefe-*.c > > > The parsing is incomplete, there's no support for parsing try/catch/finally > > I'm afraid I haven't got very far, but I tried. It didn't recognize try > and finally as keywords, and since the parser is integrated with the C > parser IIUC, I wasn't sure how to enable the keywords only within gimple > functions.
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. > As mentioned in another message, I chose try/finally/else as the > notation for TRY_FINALLY_EXPR <..., EH_ELSE_EXPR <..., ...> >, to avoid > introducing yet another keyword such as eh_finally. > > I also considered try/noexcept/finally, or try/noexcept finally/finally, > but... else seems to be a lot more closely related with EH_ELSE_EXPR, > and at least in gimple it's non-ambiguous. > > > introduce try/finally/else in gimplefe (WIP FTR) > > From: Alexandre Oliva <ol...@adacore.com> > > > --- > gcc/c/gimple-parser.c | 49 > ++++++++++++++++++++++++++++++++++++ > gcc/testsuite/gcc.dg/gimplefe-43.c | 13 ++++++++++ > 2 files changed, 62 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 b2b364cc41a3..91f2499bb1cc 100644 > --- a/gcc/c/gimple-parser.c > +++ b/gcc/c/gimple-parser.c > @@ -115,6 +115,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 *); > @@ -405,6 +406,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; > @@ -2088,6 +2092,51 @@ 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) > + { > + 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, &finseq); > + > + 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..c740e06a78e1 > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/gimplefe-43.c > @@ -0,0 +1,13 @@ > +/* { dg-do compile } */ > +/* { dg-options "-fgimple" } */ > + > +void __GIMPLE foo() > +{ > + try { > + ; > + } finally { > + ; > + } else { > + ; > + } > +} > > > -- > 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