The following adds parsing of clobbers to the GIMPLE FE. Rather
than parsing { CLOBBER [(bob|bos|eob|eos)] } with the CLOBBER
identifier uglified I've changed this to __CLOBBER [ (bob|bos|eob|eos) ]
which also does not expose the CONSTRUCTOR implementation detail.
The type of the clobber is infered from the LHS.
Parsing of {v} in the assignment is not implemented as part of this
and it should not be necessary as it's infered from the LHS/RHS
by the operand scanner (so it's redundant info). It's still
printed with -gimple dumping.
I hope to eventually switch non -gimple dumping to the -gimple
dumping syntax for some bits like __MEM dumping and this would
also be a candidate.
Bootstrapped on x86_64-unknown-linux-gnu, testing in progress.
Any comments?
Thanks,
Richard.
gcc/c/
* gimple-parser.cc (c_parser_gimple_postfix_expression):
Add ret_type argument, defaulted to error_mark_node.
Add parsing of __CLOBBER.
(c_parser_gimple_binary_expression): Pass ret_type down to
c_parser_gimple_postfix_expression.
gcc/testsuite/
* gcc.dg/gimplefe-60.c: New testcase.
---
gcc/c/gimple-parser.cc | 39 +++++++++++++++++++++++++++---
gcc/testsuite/gcc.dg/gimplefe-60.c | 16 ++++++++++++
gcc/tree-pretty-print.cc | 22 +++++++++++++++++
3 files changed, 74 insertions(+), 3 deletions(-)
create mode 100644 gcc/testsuite/gcc.dg/gimplefe-60.c
diff --git a/gcc/c/gimple-parser.cc b/gcc/c/gimple-parser.cc
index 59cb29f420c..7d374dd66b0 100644
--- a/gcc/c/gimple-parser.cc
+++ b/gcc/c/gimple-parser.cc
@@ -110,7 +110,8 @@ static void c_parser_gimple_label (gimple_parser &,
gimple_seq *);
static void c_parser_gimple_statement (gimple_parser &, gimple_seq *);
static struct c_expr c_parser_gimple_binary_expression (gimple_parser &, tree);
static struct c_expr c_parser_gimple_unary_expression (gimple_parser &);
-static struct c_expr c_parser_gimple_postfix_expression (gimple_parser &);
+static struct c_expr c_parser_gimple_postfix_expression
+ (gimple_parser &, tree = error_mark_node);
static struct c_expr c_parser_gimple_postfix_expression_after_primary
(gimple_parser &, location_t, struct c_expr);
static void c_parser_gimple_declaration (gimple_parser &);
@@ -1023,7 +1024,7 @@ c_parser_gimple_binary_expression (gimple_parser &parser,
tree ret_type)
struct c_expr ret, lhs, rhs;
enum tree_code code = ERROR_MARK;
ret.set_error ();
- lhs = c_parser_gimple_postfix_expression (parser);
+ lhs = c_parser_gimple_postfix_expression (parser, ret_type);
if (c_parser_error (parser))
return ret;
switch (c_parser_peek_token (parser)->type)
@@ -1488,7 +1489,7 @@ c_parser_gimple_typespec (gimple_parser &parser)
*/
static struct c_expr
-c_parser_gimple_postfix_expression (gimple_parser &parser)
+c_parser_gimple_postfix_expression (gimple_parser &parser, tree ret_type)
{
location_t loc = c_parser_peek_token (parser)->location;
source_range tok_range = c_parser_peek_token (parser)->get_range ();
@@ -1752,6 +1753,38 @@ c_parser_gimple_postfix_expression (gimple_parser
&parser)
}
break;
}
+ else if (strcmp (IDENTIFIER_POINTER (id), "__CLOBBER") == 0)
+ {
+ /* __CLOBBER [ '(' bob | eob | bos | eos ')' ] */
+ clobber_kind kind = CLOBBER_UNDEF;
+ c_parser_consume_token (parser);
+ if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
+ {
+ c_parser_consume_token (parser);
+ auto tok = c_parser_peek_token (parser);
+ if (c_parser_require (parser, CPP_NAME,
+ "expected clobber kind"))
+ {
+ const char *kind_str = IDENTIFIER_POINTER (tok->value);
+ if (strcmp (kind_str, "bos") == 0)
+ kind = CLOBBER_STORAGE_BEGIN;
+ else if (strcmp (kind_str, "bob") == 0)
+ kind = CLOBBER_OBJECT_BEGIN;
+ else if (strcmp (kind_str, "eob") == 0)
+ kind = CLOBBER_OBJECT_END;
+ else if (strcmp (kind_str, "eos") == 0)
+ kind = CLOBBER_STORAGE_END;
+ else
+ c_parser_error (parser, "expected one of %<bos%>, "
+ "%<eos%>, %<bob>, %<eob%>");
+ }
+ c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
+ "expected %<)%>");
+ }
+ /* We infer the (redundant) type from the LHS. */
+ expr.value = build_clobber (ret_type, kind);
+ break;
+ }
else if (strcmp (IDENTIFIER_POINTER (id), "_Literal") == 0)
{
/* _Literal '(' type-name ')' ( [ '-' ] constant | constructor )
*/
diff --git a/gcc/testsuite/gcc.dg/gimplefe-60.c
b/gcc/testsuite/gcc.dg/gimplefe-60.c
new file mode 100644
index 00000000000..13e9114496e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/gimplefe-60.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-fgimple" } */
+
+struct X { int i; };
+
+void __GIMPLE
+foo ()
+{
+ struct X x;
+ x = __CLOBBER;
+ x = __CLOBBER(bos);
+ x = __CLOBBER (eos);
+ x = __CLOBBER(bob);
+ x = __CLOBBER(eob);
+ return;
+}
diff --git a/gcc/tree-pretty-print.cc b/gcc/tree-pretty-print.cc
index ed96728cbc4..89fe93a1f6d 100644
--- a/gcc/tree-pretty-print.cc
+++ b/gcc/tree-pretty-print.cc
@@ -3047,6 +3047,28 @@ dump_generic_node (pretty_printer *pp, tree node, int
spc, dump_flags_t flags,
widest_int curidx;
if (flags & TDF_GIMPLE)
{
+ if (TREE_CLOBBER_P (node))
+ {
+ pp_string (pp, "__CLOBBER");
+ switch (CLOBBER_KIND (node))
+ {
+ case CLOBBER_STORAGE_BEGIN:
+ pp_string (pp, "(bos)");
+ break;
+ case CLOBBER_STORAGE_END:
+ pp_string (pp, "(eos)");
+ break;
+ case CLOBBER_OBJECT_BEGIN:
+ pp_string (pp, "(bob)");
+ break;
+ case CLOBBER_OBJECT_END:
+ pp_string (pp, "(eob)");
+ break;
+ default:
+ break;
+ }
+ break;
+ }
pp_string (pp, "_Literal (");
dump_generic_node (pp, TREE_TYPE (node), spc, flags, false);
pp_string (pp, ") ");
--
2.51.0