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

Reply via email to