gcc/ * coretypes.h (gimple_goto): New typedef. (const_gimple_goto): New typedef.
* gimple.h (gimple_statement_goto): New subclass of gimple_statement_with_ops, adding the invariant that stmt->code == GIMPLE_GOTO. (gimple_statement_base::as_a_gimple_goto): New. (gimple_statement_base::dyn_cast_gimple_goto): New. (is_a_helper <gimple_statement_goto>::test): New. (gimple_build_goto): Return a gimple_goto rather than a plain gimple. * gimple-pretty-print.c (dump_gimple_goto): Require a gimple_goto rather than a plain gimple. (pp_gimple_stmt_1): Add a checked cast to gimple_goto within GIMPLE_GOTO case of switch statement. * gimple.c (gimple_build_goto): Return a gimple_goto rather than a plain gimple. * tree-cfg.c (verify_gimple_goto): Require a gimple_goto rather than a plain gimple. (verify_gimple_stmt): Add a checked cast to gimple_goto within GIMPLE_GOTO case of switch statement. --- gcc/coretypes.h | 4 ++++ gcc/gimple-pretty-print.c | 4 ++-- gcc/gimple.c | 5 +++-- gcc/gimple.h | 36 +++++++++++++++++++++++++++++++++++- gcc/tree-cfg.c | 4 ++-- 5 files changed, 46 insertions(+), 7 deletions(-) diff --git a/gcc/coretypes.h b/gcc/coretypes.h index d5c62b9..1d04d07 100644 --- a/gcc/coretypes.h +++ b/gcc/coretypes.h @@ -77,6 +77,10 @@ struct gimple_statement_debug; typedef struct gimple_statement_debug *gimple_debug; typedef const struct gimple_statement_debug *const_gimple_debug; +struct gimple_statement_goto; +typedef struct gimple_statement_goto *gimple_goto; +typedef const struct gimple_statement_goto *const_gimple_goto; + struct gimple_statement_label; typedef struct gimple_statement_label *gimple_label; typedef const struct gimple_statement_label *const_gimple_label; diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c index 90baded..6ee6ce9 100644 --- a/gcc/gimple-pretty-print.c +++ b/gcc/gimple-pretty-print.c @@ -874,7 +874,7 @@ dump_gimple_label (pretty_printer *buffer, gimple_label gs, int spc, int flags) TDF_* in dumpfile.h). */ static void -dump_gimple_goto (pretty_printer *buffer, gimple gs, int spc, int flags) +dump_gimple_goto (pretty_printer *buffer, gimple_goto gs, int spc, int flags) { tree label = gimple_goto_dest (gs); if (flags & TDF_RAW) @@ -2115,7 +2115,7 @@ pp_gimple_stmt_1 (pretty_printer *buffer, gimple gs, int spc, int flags) break; case GIMPLE_GOTO: - dump_gimple_goto (buffer, gs, spc, flags); + dump_gimple_goto (buffer, gs->as_a_gimple_goto (), spc, flags); break; case GIMPLE_NOP: diff --git a/gcc/gimple.c b/gcc/gimple.c index 222c068..b73fc74 100644 --- a/gcc/gimple.c +++ b/gcc/gimple.c @@ -495,10 +495,11 @@ gimple_build_label (tree label) /* Build a GIMPLE_GOTO statement to label DEST. */ -gimple +gimple_goto gimple_build_goto (tree dest) { - gimple p = gimple_build_with_ops (GIMPLE_GOTO, ERROR_MARK, 1); + gimple_goto p = gimple_build_with_ops (GIMPLE_GOTO, ERROR_MARK, + 1)->as_a_gimple_goto (); gimple_goto_set_dest (p, dest); return p; } diff --git a/gcc/gimple.h b/gcc/gimple.h index 39ac2dc..a4c7b30 100644 --- a/gcc/gimple.h +++ b/gcc/gimple.h @@ -222,6 +222,12 @@ public: return as_a <gimple_statement_debug> (this); } + inline gimple_goto + as_a_gimple_goto () + { + return as_a <gimple_statement_goto> (this); + } + inline gimple_label as_a_gimple_label () { @@ -290,6 +296,12 @@ public: return dyn_cast <gimple_statement_debug> (this); } + inline gimple_goto + dyn_cast_gimple_goto () + { + return dyn_cast <gimple_statement_goto> (this); + } + inline gimple_label dyn_cast_gimple_label () { @@ -922,6 +934,20 @@ struct GTY((tag("GSS_WITH_OPS"))) }; /* A statement with the invariant that + stmt->code == GIMPLE_GOTO + i.e. a goto statement. + + This type will normally be accessed via the gimple_goto and + const_gimple_goto typedefs (in coretypes.h), which are pointers to + this type. */ + +struct GTY((tag("GSS_WITH_OPS"))) + gimple_statement_goto : public gimple_statement_with_ops +{ + /* no additional fields; this uses the layout for GSS_WITH_OPS. */ +}; + +/* A statement with the invariant that stmt->code == GIMPLE_LABEL i.e. a label statement. @@ -1024,6 +1050,14 @@ is_a_helper <gimple_statement_debug>::test (gimple gs) template <> template <> inline bool +is_a_helper <gimple_statement_goto>::test (gimple gs) +{ + return gs->code == GIMPLE_GOTO; +} + +template <> +template <> +inline bool is_a_helper <gimple_statement_label>::test (gimple gs) { return gs->code == GIMPLE_LABEL; @@ -1429,7 +1463,7 @@ gimple_cond gimple_build_cond (enum tree_code, tree, tree, tree, tree); gimple_cond gimple_build_cond_from_tree (tree, tree, tree); void gimple_cond_set_condition_from_tree (gimple_cond, tree); gimple_label gimple_build_label (tree label); -gimple gimple_build_goto (tree dest); +gimple_goto gimple_build_goto (tree dest); gimple gimple_build_nop (void); gimple_bind gimple_build_bind (tree, gimple_seq, tree); gimple gimple_build_asm_vec (const char *, vec<tree, va_gc> *, diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index 1bfed7d..8b8020e 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -4229,7 +4229,7 @@ verify_gimple_return (gimple_return stmt) is a problem, otherwise false. */ static bool -verify_gimple_goto (gimple stmt) +verify_gimple_goto (gimple_goto stmt) { tree dest = gimple_goto_dest (stmt); @@ -4429,7 +4429,7 @@ verify_gimple_stmt (gimple stmt) gimple_cond_rhs (stmt)); case GIMPLE_GOTO: - return verify_gimple_goto (stmt); + return verify_gimple_goto (stmt->as_a_gimple_goto ()); case GIMPLE_SWITCH: return verify_gimple_switch (stmt->as_a_gimple_switch ()); -- 1.8.5.3