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

Reply via email to