From 87626313a9ebc518a40380e8884c3de6d02d7ad0 Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Wed, 14 May 2014 17:24:43 -0400
Subject: [PATCH 23/29] Introduce ggoto

This corresponds to:
  "[PATCH 22/89] Introduce gimple_goto"
    https://gcc.gnu.org/ml/gcc-patches/2014-04/msg01174.html
from v1 of the patch series.

gcc/
	* coretypes.h (ggoto): Add forward declaration.

	* gimple.h (ggoto): New subclass of gimple_with_ops, adding the
	invariant that stmt->code == GIMPLE_GOTO.
	(is_a_helper <ggoto *>::test): New.
	(gimple_build_goto): Return a ggoto rather than a
	plain gimple.

	* gimple-pretty-print.c (dump_gimple_goto): Require a ggoto
	rather than a plain gimple.
	(pp_gimple_stmt_1): Add a checked cast to ggoto within
	GIMPLE_GOTO case of switch statement.

	* gimple.c (gimple_build_goto): Return a ggoto rather than a
	plain gimple.

	* tree-cfg.c (verify_gimple_goto): Require a ggoto rather
	than a plain gimple.
	(verify_gimple_stmt): Add a checked cast to ggoto within
	GIMPLE_GOTO case of switch statement.

	* doc/gimple.texi: Update for above changes.
---
 gcc/coretypes.h           |  1 +
 gcc/doc/gimple.texi       |  6 ++++--
 gcc/gimple-pretty-print.c |  4 ++--
 gcc/gimple.c              |  5 +++--
 gcc/gimple.h              | 20 +++++++++++++++++++-
 gcc/tree-cfg.c            |  4 ++--
 6 files changed, 31 insertions(+), 9 deletions(-)

diff --git a/gcc/coretypes.h b/gcc/coretypes.h
index 32b338a..d0ae01d 100644
--- a/gcc/coretypes.h
+++ b/gcc/coretypes.h
@@ -72,6 +72,7 @@ struct gimple_stmt_iterator;
    Keep this in the same order as the corresponding codes in gimple.def.  */
 class gcond;
 class gdebug;
+class ggoto;
 class glabel;
 class gswitch;
 class gassign;
diff --git a/gcc/doc/gimple.texi b/gcc/doc/gimple.texi
index af188a9..0c1296b 100644
--- a/gcc/doc/gimple.texi
+++ b/gcc/doc/gimple.texi
@@ -312,7 +312,6 @@ kinds, along with their relationships to @code{GSS_} values (layouts) and
      |   |
      |   + gimple_with_ops
      |   |   |    layout: GSS_WITH_OPS
-     |   |   |    Used for code: GIMPLE_GOTO
      |   |   |
      |   |   + gcond
      |   |   |        code: GIMPLE_COND
@@ -320,6 +319,9 @@ kinds, along with their relationships to @code{GSS_} values (layouts) and
      |   |   + gdebug
      |   |   |        code: GIMPLE_DEBUG
      |   |   |
+     |   |   + ggoto
+     |   |   |        code: GIMPLE_GOTO
+     |   |   |
      |   |   + glabel
      |   |   |        code: GIMPLE_LABEL
      |   |   |
@@ -1708,7 +1710,7 @@ statement @code{G}.
 @end deftypefn
 
 
-@deftypefn {GIMPLE function} gimple *gimple_build_goto (tree dest)
+@deftypefn {GIMPLE function} ggoto *gimple_build_goto (tree dest)
 Build a @code{GIMPLE_GOTO} statement to label @code{DEST}.
 @end deftypefn
 
diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c
index 98b2e81..402094e 100644
--- a/gcc/gimple-pretty-print.c
+++ b/gcc/gimple-pretty-print.c
@@ -873,7 +873,7 @@ dump_gimple_label (pretty_printer *buffer, glabel *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, ggoto *gs, int spc, int flags)
 {
   tree label = gimple_goto_dest (gs);
   if (flags & TDF_RAW)
@@ -2108,7 +2108,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, as_a <ggoto *> (gs), spc, flags);
       break;
 
     case GIMPLE_NOP:
diff --git a/gcc/gimple.c b/gcc/gimple.c
index 6232661..e8151a9 100644
--- a/gcc/gimple.c
+++ b/gcc/gimple.c
@@ -496,10 +496,11 @@ gimple_build_label (tree label)
 
 /* Build a GIMPLE_GOTO statement to label DEST.  */
 
-gimple *
+ggoto *
 gimple_build_goto (tree dest)
 {
-  gimple *p = gimple_build_with_ops (GIMPLE_GOTO, ERROR_MARK, 1);
+  ggoto *p = as_a <ggoto *> (gimple_build_with_ops (GIMPLE_GOTO,
+						    ERROR_MARK, 1));
   gimple_goto_set_dest (p, dest);
   return p;
 }
diff --git a/gcc/gimple.h b/gcc/gimple.h
index bf15c07..955167f 100644
--- a/gcc/gimple.h
+++ b/gcc/gimple.h
@@ -781,6 +781,16 @@ struct GTY((tag("GSS_WITH_OPS")))
 };
 
 /* A statement with the invariant that
+      stmt->code == GIMPLE_GOTO
+   i.e. a goto statement.  */
+
+struct GTY((tag("GSS_WITH_OPS")))
+  ggoto : public gimple_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.  */
 
@@ -887,6 +897,14 @@ is_a_helper <gdebug *>::test (gimple *gs)
 template <>
 template <>
 inline bool
+is_a_helper <ggoto *>::test (gimple *gs)
+{
+  return gs->code == GIMPLE_GOTO;
+}
+
+template <>
+template <>
+inline bool
 is_a_helper <glabel *>::test (gimple *gs)
 {
   return gs->code == GIMPLE_LABEL;
@@ -1291,7 +1309,7 @@ gcond *gimple_build_cond (enum tree_code, tree, tree, tree, tree);
 gcond *gimple_build_cond_from_tree (tree, tree, tree);
 void gimple_cond_set_condition_from_tree (gcond *, tree);
 glabel *gimple_build_label (tree label);
-gimple *gimple_build_goto (tree dest);
+ggoto *gimple_build_goto (tree dest);
 gimple *gimple_build_nop (void);
 gbind *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 b2062a3..387def1 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -4242,7 +4242,7 @@ verify_gimple_return (greturn *stmt)
    is a problem, otherwise false.  */
 
 static bool
-verify_gimple_goto (gimple *stmt)
+verify_gimple_goto (ggoto *stmt)
 {
   tree dest = gimple_goto_dest (stmt);
 
@@ -4442,7 +4442,7 @@ verify_gimple_stmt (gimple *stmt)
 				       gimple_cond_rhs (stmt));
 
     case GIMPLE_GOTO:
-      return verify_gimple_goto (stmt);
+      return verify_gimple_goto (as_a <ggoto *> (stmt));
 
     case GIMPLE_SWITCH:
       return verify_gimple_switch (as_a <gswitch *> (stmt));
-- 
1.8.5.3

