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

Reply via email to