[PATCH 08/18] convert cp *FOR_STMTs to use private scope fields

Nathan Froyd froydnj@codesourcery.com
Fri Mar 11 04:24:00 GMT 2011


C++'s FOR_STMT and RANGE_FOR_STMT store the scope in which they occur in
the TREE_CHAIN field of tree_exp.  If we're going to remove TREE_CHAIN,
that won't work very well.  This patch introduces an extra tree operand
to both tree kinds, accessor macros for those operands, and tweaks the
code to use those macros instead of TREE_CHAIN.  The end result is nicer
code and less reliance on TREE_CHAIN.

-Nathan

gcc/cp/
	* cp-tree.def (FOR_STMT, RANGE_FOR_STMT): Add an extra operand.
	* cp-objcp-common.c (cp_common_init_ts): Mark them as TS_TYPED.
	* cp-tree.h (FOR_SCOPE, RANGE_FOR_SCOPE): Define.
	* semantics.c (begin_for_stmt): Pass an extra arg to build_stmt.
	Use FOR_SCOPE instead of TREE_CHAIN.
	(begin_range_for_stmt): Likewise, with RANGE_FOR_SCOPE.
	(finish_for_stmt): Likewise.

diff --git a/gcc/cp/cp-objcp-common.c b/gcc/cp/cp-objcp-common.c
index 66d2d27..21fa57f 100644
--- a/gcc/cp/cp-objcp-common.c
+++ b/gcc/cp/cp-objcp-common.c
@@ -234,7 +234,6 @@ cp_common_init_ts (void)
   MARK_TS_COMMON (TEMPLATE_PARM_INDEX);
   MARK_TS_COMMON (OVERLOAD);
   MARK_TS_COMMON (TEMPLATE_INFO);
-  MARK_TS_COMMON (FOR_STMT);
   MARK_TS_COMMON (TYPENAME_TYPE);
   MARK_TS_COMMON (TYPEOF_TYPE);
   MARK_TS_COMMON (IF_STMT);
@@ -245,8 +244,9 @@ cp_common_init_ts (void)
   MARK_TS_COMMON (DECLTYPE_TYPE);
   MARK_TS_COMMON (BOUND_TEMPLATE_TEMPLATE_PARM);
   MARK_TS_COMMON (UNBOUND_CLASS_TEMPLATE);
-  MARK_TS_COMMON (RANGE_FOR_STMT);
 
+  MARK_TS_TYPED (FOR_STMT);
+  MARK_TS_TYPED (RANGE_FOR_STMT);
   MARK_TS_TYPED (AGGR_INIT_EXPR);
   MARK_TS_TYPED (EXPR_STMT);
   MARK_TS_TYPED (EH_SPEC_BLOCK);
diff --git a/gcc/cp/cp-tree.def b/gcc/cp/cp-tree.def
index 509d5e7..fdfe9b5 100644
--- a/gcc/cp/cp-tree.def
+++ b/gcc/cp/cp-tree.def
@@ -291,12 +291,12 @@ DEFTREECODE (IF_STMT, "if_stmt", tcc_statement, 3)
 
 /* Used to represent a `for' statement. The operands are
    FOR_INIT_STMT, FOR_COND, FOR_EXPR, and FOR_BODY, respectively.  */
-DEFTREECODE (FOR_STMT, "for_stmt", tcc_statement, 4)
+DEFTREECODE (FOR_STMT, "for_stmt", tcc_statement, 5)
 
 /* Used to represent a range-based `for' statement. The operands are
-   RANGE_FOR_DECL, RANGE_FOR_EXPR, RANGE_FOR_BODY, respectively.  Only used
-   in templates.  */
-DEFTREECODE (RANGE_FOR_STMT, "range_for_stmt", tcc_statement, 3)
+   RANGE_FOR_DECL, RANGE_FOR_EXPR, RANGE_FOR_BODY, and RANGE_FOR_SCOPE,
+   respectively.  Only used in templates.  */
+DEFTREECODE (RANGE_FOR_STMT, "range_for_stmt", tcc_statement, 4)
 
 /* Used to represent a 'while' statement. The operands are WHILE_COND
    and WHILE_BODY, respectively.  */
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 1783915..e542388 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -3799,12 +3799,14 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter)
 #define FOR_COND(NODE)		TREE_OPERAND (FOR_STMT_CHECK (NODE), 1)
 #define FOR_EXPR(NODE)		TREE_OPERAND (FOR_STMT_CHECK (NODE), 2)
 #define FOR_BODY(NODE)		TREE_OPERAND (FOR_STMT_CHECK (NODE), 3)
+#define FOR_SCOPE(NODE)		TREE_OPERAND (FOR_STMT_CHECK (NODE), 4)
 
 /* RANGE_FOR_STMT accessors. These give access to the declarator,
-   expression and body of the statement, respectively.  */
+   expression, body, and scope of the statement, respectively.  */
 #define RANGE_FOR_DECL(NODE)	TREE_OPERAND (RANGE_FOR_STMT_CHECK (NODE), 0)
 #define RANGE_FOR_EXPR(NODE)	TREE_OPERAND (RANGE_FOR_STMT_CHECK (NODE), 1)
 #define RANGE_FOR_BODY(NODE)	TREE_OPERAND (RANGE_FOR_STMT_CHECK (NODE), 2)
+#define RANGE_FOR_SCOPE(NODE)	TREE_OPERAND (RANGE_FOR_STMT_CHECK (NODE), 3)
 
 #define SWITCH_STMT_COND(NODE)	TREE_OPERAND (SWITCH_STMT_CHECK (NODE), 0)
 #define SWITCH_STMT_BODY(NODE)	TREE_OPERAND (SWITCH_STMT_CHECK (NODE), 1)
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 4af007d..c8e5619 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -856,7 +856,7 @@ begin_for_stmt (tree scope, tree init)
   tree r;
 
   r = build_stmt (input_location, FOR_STMT, NULL_TREE, NULL_TREE,
-		  NULL_TREE, NULL_TREE);
+		  NULL_TREE, NULL_TREE, NULL_TREE);
 
   if (scope == NULL_TREE)
     {
@@ -865,7 +865,7 @@ begin_for_stmt (tree scope, tree init)
 	scope = begin_for_scope (&init);
     }
   FOR_INIT_STMT (r) = init;
-  TREE_CHAIN (r) = scope;
+  FOR_SCOPE (r) = scope;
 
   return r;
 }
@@ -940,8 +940,12 @@ finish_for_stmt (tree for_stmt)
   /* Pop the scope for the body of the loop.  */
   if (flag_new_for_scope > 0)
     {
-      tree scope = TREE_CHAIN (for_stmt);
-      TREE_CHAIN (for_stmt) = NULL;
+      tree scope;
+      tree *scope_ptr = (TREE_CODE (for_stmt) == RANGE_FOR_STMT
+			 ? &RANGE_FOR_SCOPE (for_stmt)
+			 : &FOR_SCOPE (for_stmt));
+      scope = *scope_ptr;
+      *scope_ptr = NULL;
       add_stmt (do_poplevel (scope));
     }
 
@@ -959,7 +963,7 @@ begin_range_for_stmt (tree scope, tree init)
   tree r;
 
   r = build_stmt (input_location, RANGE_FOR_STMT,
-		  NULL_TREE, NULL_TREE, NULL_TREE);
+		  NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE);
 
   if (scope == NULL_TREE)
     {
@@ -972,7 +976,7 @@ begin_range_for_stmt (tree scope, tree init)
      pop it now.  */
   if (init)
     pop_stmt_list (init);
-  TREE_CHAIN (r) = scope;
+  RANGE_FOR_SCOPE (r) = scope;
 
   return r;
 }
-- 
1.7.0.4



More information about the Gcc-patches mailing list