diff options
author | Alexandre Oliva <oliva@adacore.com> | 2019-07-12 13:50:49 +0000 |
---|---|---|
committer | Alexandre Oliva <aoliva@gcc.gnu.org> | 2019-07-12 13:50:49 +0000 |
commit | fdc1f34302906036637445455a53a09f25a4acfd (patch) | |
tree | 6699885ac98338fa7078d87d30d5e4787d6ae1a1 | |
parent | 0d67cd380d37f2a28156d3430b9964a5df67a101 (diff) | |
download | gcc-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
-rw-r--r-- | gcc/c/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/c/gimple-parser.c | 61 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/gimplefe-43.c | 25 |
4 files changed, 95 insertions, 0 deletions
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index c58680c..927fa91 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,8 @@ +2019-07-12 Alexandre Oliva <oliva@adacore.com> + + * gimple-parser.c (c_parser_gimple_try_stmt): New. + (c_parser_compound_statement): Call it. + 2019-07-12 Jakub Jelinek <jakub@redhat.com> * c-parser.c (c_parser_omp_clause_name): Handle order clause. 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: diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index dfda37f..c235200 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2019-07-12 Alexandre Oliva <oliva@adacore.com> + + * gcc.dg/gimplefe-43.c: New. + 2019-07-12 Richard Biener <rguenther@suse.de> * gcc.dg/tree-ssa/vector-7.c: New testcase. diff --git a/gcc/testsuite/gcc.dg/gimplefe-43.c b/gcc/testsuite/gcc.dg/gimplefe-43.c new file mode 100644 index 0000000..5fd66e6 --- /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 + { + ; + } +} |