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

Reply via email to