aboutsummaryrefslogtreecommitdiff
path: root/gcc/c/gimple-parser.c
diff options
context:
space:
mode:
authorAlexandre Oliva <oliva@adacore.com>2019-07-12 13:50:49 +0000
committerAlexandre Oliva <aoliva@gcc.gnu.org>2019-07-12 13:50:49 +0000
commitfdc1f34302906036637445455a53a09f25a4acfd (patch)
tree6699885ac98338fa7078d87d30d5e4787d6ae1a1 /gcc/c/gimple-parser.c
parent0d67cd380d37f2a28156d3430b9964a5df67a101 (diff)
downloadgcc-fdc1f34302906036637445455a53a09f25a4acfd.zip
gcc-fdc1f34302906036637445455a53a09f25a4acfd.tar.gz
gcc-fdc1f34302906036637445455a53a09f25a4acfd.tar.bz2
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. From-SVN: r273443
Diffstat (limited to 'gcc/c/gimple-parser.c')
-rw-r--r--gcc/c/gimple-parser.c61
1 files changed, 61 insertions, 0 deletions
diff --git a/gcc/c/gimple-parser.c b/gcc/c/gimple-parser.c
index a0ea721..4970ae1 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: