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. 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