OSDN Git Service

Move statement-tree facilities from C++ to C front-end.
authormmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 7 Sep 2000 01:36:11 +0000 (01:36 +0000)
committermmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 7 Sep 2000 01:36:11 +0000 (01:36 +0000)
* c-common.h (c_tree_index): Add CTI_VOID_ZERO.
(void_zero_node): New macro.
(struct stmt_tree_s): New type.
(stmt_tree): New typedef.
(struct language_function): New type.
(last_tree): New macro.
(last_expr_type): Likewise.
(walk_tree_fn): New typedef.
(current_stmt_tree): New function.
(begin_stmt_tree): Likewise.
(add_stmt): Likewise.
(finish_stmt_tree): Likewise.
(statement_code_p): Likewise.
(lang_statement_code_p): New variable.
(walk_stmt_tree): New function.
(STMT_IS_FULL_EXPR_P): New macro.
* c-common.c (lang_statement_code_p): New variable.
(c_common_nodes_and_builtins): Initialize void_zero_node.
(statement_code_p): New function.
(walk_stmt_tree): Likewise.
* c-decl.c (language_function): Rename to ...
(c_language_function): ... this.  Include language_function.
(push_c_function_context): Adjust accordingly.
(pop_c_function_context): Likewise.
(mark_c_function_context): Likewise.
(current_stmt_tree): Define.
* c-semantics.c (begin_stmt_tree): New function.
(add_stmt): Likewise.
(prune_unused_decls): Likewise.
(finish_stmt_tree): Likewise.

Move statement-tree facilities from C++ to C front-end.
* cp-tree.h (cp_tree_index): Remove CPTI_VOID_ZERO.
(void_zero_node): Remove.
(stmt_tree): Likewise.
(scope_chain): Adjust.
(language_function): Rename to cp_language_function.
(cp_function_chain): Adjust.
(current_stmt_tree): Remove.
(last_tree): Likewise.
(last_expr_type): Likewise.
(struct lang_decl): Adjust.
(STMT_IS_FULL_EXPR_P): Remove.
(add_tree): Remove.
(begin_stmt_tree): Likewise.
(finish_stmt_tree): Likewise.
(walk_tree_fn): Likewise.
(walk_stmt_tree): Likewise.
* class.c (finish_struct): Replace use of add_tree with add_stmt.
* decl.c (mark_stmt_tree): Adjust type.
(init_decl_processing): Don't build void_zero_node.
(initialize_local_var): Adjust usage of current_stmt_tree.
(finish_enum): Use add_stmt, not add_tree.
(save_function_data): Adjust use of language_function.
(finish_constructor_body): Use add_stmt, not add_tree.
(finish_destructor_body): Likewise.
(push_cp_function_context): Adjust use of language_function.
(pop_cp_function_context): Likewise.
(mark_lang_function): Likewise.
(mark_cp_function_context): Likewise.
* init.c (build_aggr_init): Adjust use of current_stmt_tree.
(build_vec_init): Likewise.
* semantics.c (SET_LAST_STMT): Remove.
(RECHAIN_STMTS): Don't use it.
(stmts_are_full_exprs_p): Adjust use of current_stmt_tree.
(current_stmt_tree): Define.
(add_tree): Remove.
(finish_goto_stmt): Use add_stmt, not add_tree.
(finish_expr_stmt): Likewise.
(begin_if_stmt): Likewise.
(finish_then_clause): Likewise.
(begin_while_stmt): Likewise.
(begin_do_stmt): Likewise.
(finish_return_stmt): Likewise.
(begin_for_stmt): Likewise.
(finish_break_stmt): Likewise.
(finish_continue_stmt): Likewise.
(begin_switch_stmt): Likewise.
(finish_case_label): Likewise.
(begin_try_block): Likewise.
(begin_function_try_block): Likewise.
(begin_handler): Likewise.
(begin_catch_block): Likewise.
(begin_compound_stmt): Likewise.
(begin_asm_stmt): Likewise.
(finish_asm_stmt): Likewise.
(finish_label_stmt): Likewise.
(add_decl_stmt): Likewise.
(finish_subobject): Likewise.
(finish_decl_cleanup): Likewise.
(finish_named_return_value): Likewise.
(setup_vtbl_ptr): Likewise.
(add_scope_stmt): Likewise.
(finish_stmt_expr): Likewise.
(prune_unused_decls): Remove.
(begin_stmt_tree): Likewise.
(finish_stmt_tree): Likewise.
(prep_stmt): Adjust use of current_stmt_tree.
(lang_expand_stmt): Likewise.
* tree.c (statement_code_p): Remove.
(cp_statement_code_p): New function.
(walk_stmt_tree): Remove.
(init_tree): Set lang_statement_code_p.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@36221 138bc75d-0d04-0410-961f-82ee72b054a4

14 files changed:
gcc/ChangeLog
gcc/c-common.c
gcc/c-common.h
gcc/c-decl.c
gcc/c-semantics.c
gcc/cp/ChangeLog
gcc/cp/class.c
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/init.c
gcc/cp/semantics.c
gcc/cp/tree.c
libio/editbuf.h
libobjc/encoding.c

index 0214e8d..7cc7fda 100644 (file)
@@ -1,3 +1,37 @@
+2000-09-06  Mark Mitchell  <mark@codesourcery.com>
+
+       Move statement-tree facilities from C++ to C front-end.
+       * c-common.h (c_tree_index): Add CTI_VOID_ZERO.
+       (void_zero_node): New macro.
+       (struct stmt_tree_s): New type.
+       (stmt_tree): New typedef.
+       (struct language_function): New type.
+       (last_tree): New macro.
+       (last_expr_type): Likewise.
+       (walk_tree_fn): New typedef.
+       (current_stmt_tree): New function.
+       (begin_stmt_tree): Likewise.
+       (add_stmt): Likewise.
+       (finish_stmt_tree): Likewise.
+       (statement_code_p): Likewise.
+       (lang_statement_code_p): New variable.
+       (walk_stmt_tree): New function.
+       (STMT_IS_FULL_EXPR_P): New macro.
+       * c-common.c (lang_statement_code_p): New variable.
+       (c_common_nodes_and_builtins): Initialize void_zero_node.
+       (statement_code_p): New function.
+       (walk_stmt_tree): Likewise.
+       * c-decl.c (language_function): Rename to ...
+       (c_language_function): ... this.  Include language_function.
+       (push_c_function_context): Adjust accordingly.
+       (pop_c_function_context): Likewise.
+       (mark_c_function_context): Likewise.
+       (current_stmt_tree): Define.
+       * c-semantics.c (begin_stmt_tree): New function.
+       (add_stmt): Likewise.
+       (prune_unused_decls): Likewise.
+       (finish_stmt_tree): Likewise.
+
 2000-09-06 Herman A.J. ten Brugge <Haj.Ten.Brugge@net.HCC.nl>
 
         * flow.c (insn_dead_p): Detect dead memory stores with auto increments.
index efb81a3..fc8476a 100644 (file)
@@ -144,6 +144,10 @@ tree *ridpointers;
 
 tree (*make_fname_decl)                PARAMS ((tree, const char *, int));
 
+/* If non-NULL, the address of a language-specific function that
+   returns 1 for language-specific statement codes.  */
+int (*lang_statement_code_p)           PARAMS ((enum tree_code));
+
 /* Nonzero means the expression being parsed will never be evaluated.
    This is a count, since unevaluated expressions can nest.  */
 int skip_evaluation;
@@ -3870,6 +3874,9 @@ c_common_nodes_and_builtins (cplus_mode, no_builtins, no_nonansi_builtins)
                                                            sizetype,
                                                            endlink))));
 
+  void_zero_node = build_int_2 (0, 0);
+  TREE_TYPE (void_zero_node) = void_type_node;
+
   /* Prototype for strcpy.  */
   string_ftype_ptr_ptr
     = build_function_type (string_type_node,
@@ -4378,6 +4385,111 @@ expand_tree_builtin (function, params, coerced_params)
   return NULL_TREE;
 }
 
+/* Returns non-zero if CODE is the code for a statement.  */
+
+int
+statement_code_p (code)
+     enum tree_code code;
+{
+  switch (code)
+    {
+    case EXPR_STMT:
+    case COMPOUND_STMT:
+    case DECL_STMT:
+    case IF_STMT:
+    case FOR_STMT:
+    case WHILE_STMT:
+    case DO_STMT:
+    case RETURN_STMT:
+    case BREAK_STMT:
+    case CONTINUE_STMT:
+    case SWITCH_STMT:
+    case GOTO_STMT:
+    case LABEL_STMT:
+    case ASM_STMT:
+    case CASE_LABEL:
+      return 1;
+
+    default:
+      if (lang_statement_code_p)
+       return (*lang_statement_code_p) (code);
+      return 0;
+    }
+}
+
+/* Walk the statemen tree, rooted at *tp.  Apply FUNC to all the
+   sub-trees of *TP in a pre-order traversal.  FUNC is called with the
+   DATA and the address of each sub-tree.  If FUNC returns a non-NULL
+   value, the traversal is aborted, and the value returned by FUNC is
+   returned.  If FUNC sets WALK_SUBTREES to zero, then the subtrees of
+   the node being visited are not walked.
+
+   We don't need a without_duplicates variant of this one because the
+   statement tree is a tree, not a graph.  */
+
+tree 
+walk_stmt_tree (tp, func, data)
+     tree *tp;
+     walk_tree_fn func;
+     void *data;
+{
+  enum tree_code code;
+  int walk_subtrees;
+  tree result;
+  int i, len;
+
+#define WALK_SUBTREE(NODE)                             \
+  do                                                   \
+    {                                                  \
+      result = walk_stmt_tree (&(NODE), func, data);   \
+      if (result)                                      \
+       return result;                                  \
+    }                                                  \
+  while (0)
+
+  /* Skip empty subtrees.  */
+  if (!*tp)
+    return NULL_TREE;
+
+  /* Skip subtrees below non-statement nodes.  */
+  if (!statement_code_p (TREE_CODE (*tp)))
+    return NULL_TREE;
+
+  /* Call the function.  */
+  walk_subtrees = 1;
+  result = (*func) (tp, &walk_subtrees, data);
+
+  /* If we found something, return it.  */
+  if (result)
+    return result;
+
+  /* Even if we didn't, FUNC may have decided that there was nothing
+     interesting below this point in the tree.  */
+  if (!walk_subtrees)
+    return NULL_TREE;
+
+  /* FUNC may have modified the tree, recheck that we're looking at a
+     statement node.  */
+  code = TREE_CODE (*tp);
+  if (!statement_code_p (code))
+    return NULL_TREE;
+
+  /* Walk over all the sub-trees of this operand.  Statement nodes never
+     contain RTL, and we needn't worry about TARGET_EXPRs.  */
+  len = TREE_CODE_LENGTH (code);
+
+  /* Go through the subtrees.  We need to do this in forward order so
+     that the scope of a FOR_EXPR is handled properly.  */
+  for (i = 0; i < len; ++i)
+    WALK_SUBTREE (TREE_OPERAND (*tp, i));
+
+  /* Finally visit the chain.  This can be tail-recursion optimized if
+     we write it this way.  */
+  return walk_stmt_tree (&TREE_CHAIN (*tp), func, data);
+
+#undef WALK_SUBTREE
+}
+
 /* Tree code classes. */
 
 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE,
index 7b4912c..6f442c4 100644 (file)
@@ -147,6 +147,8 @@ enum c_tree_index
     CTI_PRETTY_FUNCTION_ID,
     CTI_FUNC_ID,
 
+    CTI_VOID_ZERO,
+
     CTI_MAX
 };
 
@@ -187,6 +189,9 @@ enum c_tree_index
 #define pretty_function_id_node                c_global_trees[CTI_PRETTY_FUNCTION_ID]
 #define func_id_node                   c_global_trees[CTI_FUNC_ID]
 
+/* A node for `((void) 0)'.  */
+#define void_zero_node                  c_global_trees[CTI_VOID_ZERO]
+
 extern tree c_global_trees[CTI_MAX];
 
 typedef enum c_language_kind
@@ -198,6 +203,68 @@ typedef enum c_language_kind
 } 
 c_language_kind;
 
+/* Information about a statement tree.  */
+
+struct stmt_tree_s {
+  /* The last statement added to the tree.  */
+  tree x_last_stmt;
+  /* The type of the last expression statement.  (This information is
+     needed to implement the statement-expression extension.)  */
+  tree x_last_expr_type;
+  /* In C++, Non-zero if we should treat statements as full
+     expressions.  In particular, this variable is no-zero if at the
+     end of a statement we should destroy any temporaries created
+     during that statement.  Similarly, if, at the end of a block, we
+     should destroy any local variables in this block.  Normally, this
+     variable is non-zero, since those are the normal semantics of
+     C++.
+
+     However, in order to represent aggregate initialization code as
+     tree structure, we use statement-expressions.  The statements
+     within the statement expression should not result in cleanups
+     being run until the entire enclosing statement is complete.  
+
+     This flag has no effect in C.  */
+  int stmts_are_full_exprs_p; 
+};
+
+typedef struct stmt_tree_s *stmt_tree;
+
+/* Global state pertinent to the current function.  Some C dialects
+   extend this structure with additional fields.  */
+
+struct language_function {
+  /* While we are parsing the function, this contains information
+     about the statement-tree that we are building.  */
+  struct stmt_tree_s x_stmt_tree;
+};
+
+/* When building a statement-tree, this is the last statement added to
+   the tree.  */
+
+#define last_tree (current_stmt_tree ()->x_last_stmt)
+
+/* The type of the last expression-statement we have seen.  */
+
+#define last_expr_type (current_stmt_tree ()->x_last_expr_type)
+
+/* The type of a function that walks over tree structure.  */
+
+typedef tree (*walk_tree_fn)                    PARAMS ((tree *, 
+                                                        int *, 
+                                                        void *));
+
+extern stmt_tree current_stmt_tree              PARAMS ((void));
+extern void begin_stmt_tree                     PARAMS ((tree *));
+extern void add_stmt                           PARAMS ((tree));
+extern void finish_stmt_tree                    PARAMS ((tree *));
+
+extern int statement_code_p                     PARAMS ((enum tree_code));
+extern int (*lang_statement_code_p)             PARAMS ((enum tree_code));
+extern tree walk_stmt_tree                     PARAMS ((tree *,
+                                                        walk_tree_fn,
+                                                        void *));
+
 /* The variant of the C language being processed.  Each C language
    front-end defines this variable.  */
 
@@ -337,8 +404,13 @@ extern tree build_va_arg                   PARAMS ((tree, tree));
 extern int self_promoting_args_p               PARAMS ((tree));
 extern tree simple_type_promotes_to            PARAMS ((tree));
 
-/* These macros provide convenient access to the various _STMT nodes
-   created when parsing template declarations.  */
+/* These macros provide convenient access to the various _STMT nodes.  */
+
+/* Nonzero if this statement should be considered a full-expression,
+   i.e., if temporaries created during this statement should have
+   their destructors run at the end of this statement.  (In C, this
+   will always be false, since there are no destructors.)  */
+#define STMT_IS_FULL_EXPR_P(NODE) TREE_LANG_FLAG_1 ((NODE))
 
 /* IF_STMT accessors. These give access to the condtion of the if
    statement, the then block of the if statement, and the else block
index af9428b..a5dc3d6 100644 (file)
@@ -6761,8 +6761,9 @@ finish_function (nested)
    that keep track of the progress of compilation of the current function.
    Used for nested functions.  */
 
-struct language_function
+struct c_language_function
 {
+  struct language_function base;
   tree named_labels;
   tree shadowed_labels;
   int returns_value;
@@ -6779,9 +6780,10 @@ void
 push_c_function_context (f)
      struct function *f;
 {
-  struct language_function *p;
-  p = (struct language_function *) xmalloc (sizeof (struct language_function));
-  f->language = p;
+  struct c_language_function *p;
+  p = ((struct c_language_function *) 
+       xmalloc (sizeof (struct c_language_function)));
+  f->language = (struct language_function *) p;
 
   p->named_labels = named_labels;
   p->shadowed_labels = shadowed_labels;
@@ -6798,7 +6800,8 @@ void
 pop_c_function_context (f)
      struct function *f;
 {
-  struct language_function *p = f->language;
+  struct c_language_function *p 
+    = (struct c_language_function *) f->language;
   tree link;
 
   /* Bring back all the labels that were shadowed.  */
@@ -6834,7 +6837,8 @@ void
 mark_c_function_context (f)
      struct function *f;
 {
-  struct language_function *p = f->language;
+  struct c_language_function *p 
+    = (struct c_language_function *) f->language;
 
   if (p == 0)
     return;
@@ -6899,6 +6903,16 @@ stmts_are_full_exprs_p ()
   return 0;
 }
 
+/* Returns the stmt_tree (if any) to which statements are currently
+   being added.  If there is no active statement-tree, NULL is
+   returned.  */
+
+stmt_tree
+current_stmt_tree ()
+{
+  return cfun ? &cfun->language->x_stmt_tree : NULL;
+}
+
 /* Nonzero if TYPE is an anonymous union or struct type.  Always 0 in
    C.  */
 
index 2e0d537..eea9f92 100644 (file)
@@ -36,6 +36,119 @@ Boston, MA 02111-1307, USA.  */
 #include "output.h"
 #include "timevar.h"
 
+static tree prune_unused_decls PARAMS ((tree *, int *, void *));
+
+/* Create an empty statement tree rooted at T.  */
+
+void
+begin_stmt_tree (t)
+     tree *t;
+{
+  /* We create a trivial EXPR_STMT so that last_tree is never NULL in
+     what follows.  We remove the extraneous statement in
+     finish_stmt_tree.  */
+  *t = build_nt (EXPR_STMT, void_zero_node);
+  last_tree = *t;
+  last_expr_type = NULL_TREE;
+}
+
+/* T is a statement.  Add it to the statement-tree.  */
+
+void
+add_stmt (t)
+     tree t;
+{
+  /* Add T to the statement-tree.  */
+  TREE_CHAIN (last_tree) = t;
+  last_tree = t;
+  /* When we expand a statement-tree, we must know whether or not the
+     statements are full-expresions.  We record that fact here.  */
+  STMT_IS_FULL_EXPR_P (last_tree) = stmts_are_full_exprs_p ();
+}
+
+/* Remove declarations of internal variables that are not used from a
+   stmt tree.  To qualify, the variable must have a name and must have
+   a zero DECL_SOURCE_LINE.  We tried to remove all variables for
+   which TREE_USED was false, but it turns out that there's tons of
+   variables for which TREE_USED is false but that are still in fact
+   used.  */
+
+static tree
+prune_unused_decls (tp, walk_subtrees, data)
+     tree *tp;
+     int *walk_subtrees ATTRIBUTE_UNUSED;
+     void *data ATTRIBUTE_UNUSED;
+{
+  tree t = *tp;
+
+  if (t == NULL_TREE)
+    {
+      *walk_subtrees = 0;
+      return NULL_TREE;
+    }
+
+  if (TREE_CODE (t) == DECL_STMT)
+    {
+      tree d = DECL_STMT_DECL (t);
+      if (!TREE_USED (d) && DECL_NAME (d) && DECL_SOURCE_LINE (d) == 0)
+       {
+         *tp = TREE_CHAIN (t);
+         /* Recurse on the new value of tp, otherwise we will skip
+            the next statement.  */
+         return prune_unused_decls (tp, walk_subtrees, data);
+       }
+    }
+  else if (TREE_CODE (t) == SCOPE_STMT)
+    {
+      /* Remove all unused decls from the BLOCK of this SCOPE_STMT.  */
+      tree block = SCOPE_STMT_BLOCK (t);
+
+      if (block)
+       {
+         tree *vp;
+
+         for (vp = &BLOCK_VARS (block); *vp; )
+           {
+             tree v = *vp;
+             if (! TREE_USED (v) && DECL_NAME (v) && DECL_SOURCE_LINE (v) == 0)
+               *vp = TREE_CHAIN (v);  /* drop */
+             else
+               vp = &TREE_CHAIN (v);  /* advance */
+           }
+         /* If there are now no variables, the entire BLOCK can be dropped.
+            (This causes SCOPE_NULLIFIED_P (t) to be true.)  */
+         if (BLOCK_VARS (block) == NULL_TREE)
+           SCOPE_STMT_BLOCK (t) = NULL_TREE;
+       }
+    }
+  return NULL_TREE;
+}
+
+/* Finish the statement tree rooted at T.  */
+
+void
+finish_stmt_tree (t)
+     tree *t;
+{
+  tree stmt;
+  
+  /* Remove the fake extra statement added in begin_stmt_tree.  */
+  stmt = TREE_CHAIN (*t);
+  *t = stmt;
+  last_tree = NULL_TREE;
+
+  /* Remove unused decls from the stmt tree.  */
+  walk_stmt_tree (t, prune_unused_decls, NULL);
+
+  if (cfun)
+    {
+      /* The line-number recorded in the outermost statement in a function
+        is the line number of the end of the function.  */
+      STMT_LINENO (stmt) = lineno;
+      STMT_LINENO_FOR_FN_P (stmt) = 1;
+    }
+}
+
 /* Build a generic statement based on the given type of node and
    arguments. Similar to `build_nt', except that we set
    TREE_COMPLEXITY to be the current line number.  */
index 4b28703..5f6ea87 100644 (file)
@@ -1,3 +1,78 @@
+2000-09-06  Mark Mitchell  <mark@codesourcery.com>
+
+       Move statement-tree facilities from C++ to C front-end.
+       * cp-tree.h (cp_tree_index): Remove CPTI_VOID_ZERO.
+       (void_zero_node): Remove.
+       (stmt_tree): Likewise.
+       (scope_chain): Adjust.
+       (language_function): Rename to cp_language_function.
+       (cp_function_chain): Adjust.
+       (current_stmt_tree): Remove.
+       (last_tree): Likewise.
+       (last_expr_type): Likewise.
+       (struct lang_decl): Adjust.
+       (STMT_IS_FULL_EXPR_P): Remove.
+       (add_tree): Remove.
+       (begin_stmt_tree): Likewise.
+       (finish_stmt_tree): Likewise.
+       (walk_tree_fn): Likewise.
+       (walk_stmt_tree): Likewise.
+       * class.c (finish_struct): Replace use of add_tree with add_stmt.
+       * decl.c (mark_stmt_tree): Adjust type.
+       (init_decl_processing): Don't build void_zero_node.
+       (initialize_local_var): Adjust usage of current_stmt_tree.
+       (finish_enum): Use add_stmt, not add_tree.
+       (save_function_data): Adjust use of language_function.
+       (finish_constructor_body): Use add_stmt, not add_tree.
+       (finish_destructor_body): Likewise.
+       (push_cp_function_context): Adjust use of language_function.
+       (pop_cp_function_context): Likewise.
+       (mark_lang_function): Likewise.
+       (mark_cp_function_context): Likewise.
+       * init.c (build_aggr_init): Adjust use of current_stmt_tree.
+       (build_vec_init): Likewise.
+       * semantics.c (SET_LAST_STMT): Remove.
+       (RECHAIN_STMTS): Don't use it.
+       (stmts_are_full_exprs_p): Adjust use of current_stmt_tree.
+       (current_stmt_tree): Define.
+       (add_tree): Remove.
+       (finish_goto_stmt): Use add_stmt, not add_tree.
+       (finish_expr_stmt): Likewise.
+       (begin_if_stmt): Likewise.
+       (finish_then_clause): Likewise.
+       (begin_while_stmt): Likewise.
+       (begin_do_stmt): Likewise.
+       (finish_return_stmt): Likewise.
+       (begin_for_stmt): Likewise.
+       (finish_break_stmt): Likewise.
+       (finish_continue_stmt): Likewise.
+       (begin_switch_stmt): Likewise.
+       (finish_case_label): Likewise.
+       (begin_try_block): Likewise.
+       (begin_function_try_block): Likewise.
+       (begin_handler): Likewise.
+       (begin_catch_block): Likewise.
+       (begin_compound_stmt): Likewise.
+       (begin_asm_stmt): Likewise.
+       (finish_asm_stmt): Likewise.
+       (finish_label_stmt): Likewise.
+       (add_decl_stmt): Likewise.
+       (finish_subobject): Likewise.
+       (finish_decl_cleanup): Likewise.
+       (finish_named_return_value): Likewise.
+       (setup_vtbl_ptr): Likewise.
+       (add_scope_stmt): Likewise.
+       (finish_stmt_expr): Likewise.
+       (prune_unused_decls): Remove.
+       (begin_stmt_tree): Likewise.
+       (finish_stmt_tree): Likewise.
+       (prep_stmt): Adjust use of current_stmt_tree.
+       (lang_expand_stmt): Likewise.
+       * tree.c (statement_code_p): Remove.
+       (cp_statement_code_p): New function.
+       (walk_stmt_tree): Remove.
+       (init_tree): Set lang_statement_code_p.
+       
 2000-09-06  Zack Weinberg  <zack@wolery.cumb.org>
 
        Integrated preprocessor.
index 0306df7..6477261 100644 (file)
@@ -5265,7 +5265,7 @@ finish_struct (t, attributes)
     {
       tree scope = current_scope ();
       if (scope && TREE_CODE (scope) == FUNCTION_DECL)
-       add_tree (build_min (TAG_DEFN, t));
+       add_stmt (build_min (TAG_DEFN, t));
     }
 
   return t;
index b32367b..9fb04e5 100644 (file)
@@ -559,7 +559,6 @@ enum cp_tree_index
     CPTI_JAVA_CHAR_TYPE,
     CPTI_JAVA_BOOLEAN_TYPE,
 
-    CPTI_VOID_ZERO,
     CPTI_WCHAR_DECL,
     CPTI_VTABLE_ENTRY_TYPE,
     CPTI_DELTA_TYPE,
@@ -652,7 +651,6 @@ extern tree cp_global_trees[CPTI_MAX];
 #define java_char_type_node            cp_global_trees[CPTI_JAVA_CHAR_TYPE]
 #define java_boolean_type_node         cp_global_trees[CPTI_JAVA_BOOLEAN_TYPE]
 
-#define void_zero_node                 cp_global_trees[CPTI_VOID_ZERO]
 #define wchar_decl_node                        cp_global_trees[CPTI_WCHAR_DECL]
 #define vtable_entry_type              cp_global_trees[CPTI_VTABLE_ENTRY_TYPE]
 /* The type used to represent an offset by which to adjust the `this'
@@ -784,23 +782,6 @@ extern tree cp_global_trees[CPTI_MAX];
 
 /* Global state.  */
 
-struct stmt_tree {
-  tree x_last_stmt;
-  tree x_last_expr_type;
-/* Non-zero if we should treat statements as full expressions.  In
-   particular, this variable is no-zero if at the end of a statement
-   we should destroy any temporaries created during that statement.
-   Similarly, if, at the end of a block, we should destroy any local
-   variables in this block.  Normally, this variable is non-zero,
-   since those are the normal semantics of C++.
-
-   However, in order to represent aggregate initialization code as
-   tree structure, we use statement-expressions.  The statements
-   within the statement expression should not result in cleanups being
-   run until the entire enclosing statement is complete.  */
-  int stmts_are_full_exprs_p; 
-};
-
 struct saved_scope {
   tree old_bindings;
   tree old_namespace;
@@ -824,7 +805,7 @@ struct saved_scope {
   int x_processing_explicit_instantiation;
   int need_pop_function_context;
 
-  struct stmt_tree x_stmt_tree;
+  struct stmt_tree_s x_stmt_tree;
 
   struct binding_level *class_bindings;
   struct binding_level *bindings;
@@ -890,8 +871,10 @@ extern struct saved_scope *scope_chain;
 
 /* Global state pertinent to the current function.  */
 
-struct language_function
+struct cp_language_function
 {
+  struct language_function base;
+
   tree x_ctor_label;
   tree x_dtor_label;
   tree x_current_class_ptr;
@@ -912,8 +895,6 @@ struct language_function
   int name_declared;
   int vtbls_set_up_p;
 
-  struct stmt_tree x_stmt_tree;
-
   struct named_label_use_list *x_named_label_uses;
   struct named_label_list *x_named_labels;
   struct binding_level *bindings;
@@ -923,7 +904,8 @@ struct language_function
 
 /* The current C++-specific per-function global variables.  */
 
-#define cp_function_chain (cfun->language)
+#define cp_function_chain \
+  ((struct cp_language_function *) (cfun->language))
 
 /* In a destructor, the point at which all derived class destroying
    has been done, just before any base class destroying will be done.  */
@@ -944,24 +926,6 @@ struct language_function
 #define current_class_ref \
   (cfun ? cp_function_chain->x_current_class_ref : NULL_TREE)
 
-/* Information about the current statement tree.  */
-
-#define current_stmt_tree                      \
-  (cfun                                                \
-   ? &cp_function_chain->x_stmt_tree           \
-   : &scope_chain->x_stmt_tree)
-
-/* When building a statement-tree, this is the last statement added to
-   the tree.  */
-
-#define last_tree current_stmt_tree->x_last_stmt
-
-/* The type of the last expression-statement we have seen.  This is
-   required because the type of a statement-expression is the type of
-   the last expression statement.  */
-
-#define last_expr_type current_stmt_tree->x_last_expr_type
-
 /* The TRY_BLOCK for the exception-specifiers for the current
    function, if any.  */
 
@@ -1927,7 +1891,7 @@ struct lang_decl
   {
     tree sorted_fields;
     struct unparsed_text *pending_inline_info;
-    struct language_function *saved_language_function;
+    struct cp_language_function *saved_language_function;
   } u;
 
   union {
@@ -2474,9 +2438,6 @@ struct lang_decl
 #define AGGR_INIT_VIA_CTOR_P(NODE) \
   TREE_LANG_FLAG_0 (AGGR_INIT_EXPR_CHECK (NODE))
 
-/* Nonzero if this statement should be considered a full-expression.  */
-#define STMT_IS_FULL_EXPR_P(NODE) TREE_LANG_FLAG_1 ((NODE))
-
 /* The TYPE_MAIN_DECL for a class template type is a TYPE_DECL, not a
    TEMPLATE_DECL.  This macro determines whether or not a given class
    type is really a template type, as opposed to an instantiation or
@@ -4231,7 +4192,6 @@ extern void do_decl_instantiation         PARAMS ((tree, tree, tree));
 extern void do_type_instantiation              PARAMS ((tree, tree, int));
 extern tree instantiate_decl                   PARAMS ((tree, int));
 extern tree get_bindings                       PARAMS ((tree, tree, tree));
-extern void add_tree                           PARAMS ((tree));
 extern void add_maybe_template                 PARAMS ((tree, tree));
 extern void pop_tinst_level                    PARAMS ((void));
 extern int more_specialized_class              PARAMS ((tree, tree));
@@ -4409,8 +4369,6 @@ extern void add_decl_stmt                       PARAMS ((tree));
 extern void finish_decl_cleanup                 PARAMS ((tree, tree));
 extern void finish_named_return_value           PARAMS ((tree, tree));
 extern void expand_body                         PARAMS ((tree));
-extern void begin_stmt_tree                     PARAMS ((tree *));
-extern void finish_stmt_tree                    PARAMS ((tree *));
 extern void prep_stmt                           PARAMS ((tree));
 extern tree add_scope_stmt                      PARAMS ((int, int));
 extern void do_pushlevel                        PARAMS ((void));
@@ -4494,7 +4452,6 @@ extern void debug_binfo                           PARAMS ((tree));
 extern tree build_dummy_object                 PARAMS ((tree));
 extern tree maybe_dummy_object                 PARAMS ((tree, tree *));
 extern int is_dummy_object                     PARAMS ((tree));
-typedef tree (*walk_tree_fn)                    PARAMS ((tree *, int *, void *));
 extern tree walk_tree                           PARAMS ((tree *,
                                                         walk_tree_fn,
                                                         void *, 
@@ -4502,9 +4459,6 @@ extern tree walk_tree                           PARAMS ((tree *,
 extern tree walk_tree_without_duplicates        PARAMS ((tree *,
                                                         walk_tree_fn,
                                                         void *));
-extern tree walk_stmt_tree                     PARAMS ((tree *,
-                                                        walk_tree_fn,
-                                                        void *));
 extern tree copy_tree_r                         PARAMS ((tree *, int *, void *));
 extern int cp_valid_lang_attribute             PARAMS ((tree, tree, tree, tree));
 extern tree make_ptrmem_cst                     PARAMS ((tree, tree));
index 03d8c6a..5ca1e55 100644 (file)
@@ -169,8 +169,8 @@ static void mark_binding_level PARAMS ((void *));
 static void mark_named_label_lists PARAMS ((void *, void *));
 static void mark_cp_function_context PARAMS ((struct function *));
 static void mark_saved_scope PARAMS ((void *));
-static void mark_lang_function PARAMS ((struct language_function *));
-static void mark_stmt_tree PARAMS ((struct stmt_tree *));
+static void mark_lang_function PARAMS ((struct cp_language_function *));
+static void mark_stmt_tree PARAMS ((stmt_tree));
 static void save_function_data PARAMS ((tree));
 static void check_function_type PARAMS ((tree));
 static void destroy_local_var PARAMS ((tree));
@@ -200,7 +200,6 @@ tree error_mark_list;
 
    C++ extensions
        tree wchar_decl_node;
-       tree void_zero_node;
 
        tree vtable_entry_type;
        tree delta_type_node;
@@ -2453,7 +2452,7 @@ struct saved_scope *scope_chain;
 
 static void
 mark_stmt_tree (st)
-     struct stmt_tree *st;
+     stmt_tree st;
 {
   ggc_mark_tree (st->x_last_stmt);
   ggc_mark_tree (st->x_last_expr_type);
@@ -6471,10 +6470,6 @@ init_decl_processing ()
   void_list_node = build_tree_list (NULL_TREE, void_type_node);
   TREE_PARMLIST (void_list_node) = 1;
 
-  /* Used for expressions that do nothing, but are not errors.  */
-  void_zero_node = build_int_2 (0, 0);
-  TREE_TYPE (void_zero_node) = void_type_node;
-
   string_type_node = build_pointer_type (char_type_node);
   const_string_type_node
     = build_pointer_type (build_qualified_type (char_type_node,
@@ -7965,12 +7960,13 @@ initialize_local_var (decl, init, flags)
          emit_line_note (DECL_SOURCE_FILE (decl),
                          DECL_SOURCE_LINE (decl));
          saved_stmts_are_full_exprs_p = stmts_are_full_exprs_p ();
-         current_stmt_tree->stmts_are_full_exprs_p = 1;
+         current_stmt_tree ()->stmts_are_full_exprs_p = 1;
          if (building_stmt_tree ())
            finish_expr_stmt (build_aggr_init (decl, init, flags));
          else
            genrtl_expr_stmt (build_aggr_init (decl, init, flags));
-         current_stmt_tree->stmts_are_full_exprs_p = saved_stmts_are_full_exprs_p;
+         current_stmt_tree ()->stmts_are_full_exprs_p = 
+           saved_stmts_are_full_exprs_p;
        }
 
       /* Set this to 0 so we can tell whether an aggregate which was
@@ -13244,7 +13240,7 @@ finish_enum (enumtype)
     {
       tree scope = current_scope ();
       if (scope && TREE_CODE (scope) == FUNCTION_DECL)
-       add_tree (build_min (TAG_DEFN, enumtype));
+       add_stmt (build_min (TAG_DEFN, enumtype));
     }
   else
     {
@@ -14037,7 +14033,7 @@ static void
 save_function_data (decl)
      tree decl;
 {
-  struct language_function *f;
+  struct cp_language_function *f;
 
   /* Save the language-specific per-function data so that we can
      get it back when we really expand this function.  */
@@ -14045,15 +14041,15 @@ save_function_data (decl)
                      19990908);
 
   /* Make a copy.  */
-  f = ((struct language_function *)
-       xmalloc (sizeof (struct language_function)));
+  f = ((struct cp_language_function *)
+       xmalloc (sizeof (struct cp_language_function)));
   bcopy ((char *) cp_function_chain, (char *) f,
-        sizeof (struct language_function));
+        sizeof (struct cp_language_function));
   DECL_SAVED_FUNCTION_DATA (decl) = f;
 
   /* Clear out the bits we don't need.  */
-  f->x_stmt_tree.x_last_stmt = NULL_TREE;
-  f->x_stmt_tree.x_last_expr_type = NULL_TREE;
+  f->base.x_stmt_tree.x_last_stmt = NULL_TREE;
+  f->base.x_stmt_tree.x_last_expr_type = NULL_TREE;
   f->x_result_rtx = NULL_RTX;
   f->x_named_label_uses = NULL;
   f->bindings = NULL;
@@ -14075,7 +14071,7 @@ finish_constructor_body ()
 {
   /* Any return from a constructor will end up here.  */
   if (ctor_label)
-    add_tree (build_stmt (LABEL_STMT, ctor_label));
+    add_stmt (build_stmt (LABEL_STMT, ctor_label));
 
   /* Clear CTOR_LABEL so that finish_return_stmt knows to really
      generate the return, rather than a goto to CTOR_LABEL.  */
@@ -14084,7 +14080,7 @@ finish_constructor_body ()
      constructor to a return of `this'.  */
   finish_return_stmt (NULL_TREE);
   /* Mark the end of the constructor.  */
-  add_tree (build_stmt (CTOR_STMT));
+  add_stmt (build_stmt (CTOR_STMT));
 }
 
 /* At the end of every destructor we generate code to restore virtual
@@ -14103,7 +14099,7 @@ finish_destructor_body ()
   compound_stmt = begin_compound_stmt (/*has_no_scope=*/0);
 
   /* Any return from a destructor will end up here.  */
-  add_tree (build_stmt (LABEL_STMT, dtor_label));
+  add_stmt (build_stmt (LABEL_STMT, dtor_label));
 
   /* Generate the code to call destructor on base class.  If this
      destructor belongs to a class with virtual functions, then set
@@ -14896,10 +14892,10 @@ static void
 push_cp_function_context (f)
      struct function *f;
 {
-  struct language_function *p
-    = ((struct language_function *)
-       xcalloc (1, sizeof (struct language_function)));
-  f->language = p;
+  struct cp_language_function *p
+    = ((struct cp_language_function *)
+       xcalloc (1, sizeof (struct cp_language_function)));
+  f->language = (struct language_function *) p;
 
   /* It takes an explicit call to expand_body to generate RTL for a
      function.  */
@@ -14907,7 +14903,7 @@ push_cp_function_context (f)
 
   /* Whenever we start a new function, we destroy temporaries in the
      usual way.  */
-  current_stmt_tree->stmts_are_full_exprs_p = 1;
+  current_stmt_tree ()->stmts_are_full_exprs_p = 1;
 }
 
 /* Free the language-specific parts of F, now that we've finished
@@ -14926,7 +14922,7 @@ pop_cp_function_context (f)
 
 static void
 mark_lang_function (p)
-     struct language_function *p;
+     struct cp_language_function *p;
 {
   if (!p)
     return;
@@ -14941,7 +14937,7 @@ mark_lang_function (p)
   ggc_mark_rtx (p->x_result_rtx);
 
   mark_named_label_lists (&p->x_named_labels, &p->x_named_label_uses);
-  mark_stmt_tree (&p->x_stmt_tree);
+  mark_stmt_tree (&p->base.x_stmt_tree);
   mark_binding_level (&p->bindings);
 }
 
@@ -14951,7 +14947,7 @@ static void
 mark_cp_function_context (f)
      struct function *f;
 {
-  mark_lang_function (f->language);
+  mark_lang_function ((struct cp_language_function *) f->language);
 }
 
 void
index 68f92b6..f39f37f 100644 (file)
@@ -1228,11 +1228,11 @@ build_aggr_init (exp, init, flags)
   TREE_TYPE (exp) = TYPE_MAIN_VARIANT (type);
   begin_init_stmts (&stmt_expr, &compound_stmt);
   destroy_temps = stmts_are_full_exprs_p ();
-  current_stmt_tree->stmts_are_full_exprs_p = 0;
+  current_stmt_tree ()->stmts_are_full_exprs_p = 0;
   expand_aggr_init_1 (TYPE_BINFO (type), exp, exp,
                      init, LOOKUP_NORMAL|flags);
   stmt_expr = finish_init_stmts (stmt_expr, compound_stmt);
-  current_stmt_tree->stmts_are_full_exprs_p = destroy_temps;
+  current_stmt_tree ()->stmts_are_full_exprs_p = destroy_temps;
   TREE_TYPE (exp) = type;
   TREE_READONLY (exp) = was_const;
   TREE_THIS_VOLATILE (exp) = was_volatile;
@@ -2873,7 +2873,7 @@ build_vec_init (decl, base, maxindex, init, from_array)
 
   begin_init_stmts (&stmt_expr, &compound_stmt);
   destroy_temps = stmts_are_full_exprs_p ();
-  current_stmt_tree->stmts_are_full_exprs_p = 0;
+  current_stmt_tree ()->stmts_are_full_exprs_p = 0;
   rval = get_temp_regvar (ptype, 
                          cp_convert (ptype, default_conversion (base)));
   base = get_temp_regvar (ptype, rval);
@@ -3035,9 +3035,9 @@ build_vec_init (decl, base, maxindex, init, from_array)
        }
       else
        {
-         current_stmt_tree->stmts_are_full_exprs_p = 1;
+         current_stmt_tree ()->stmts_are_full_exprs_p = 1;
          finish_expr_stmt (elt_init);
-         current_stmt_tree->stmts_are_full_exprs_p = 0;
+         current_stmt_tree ()->stmts_are_full_exprs_p = 0;
        }
 
       finish_expr_stmt (build_modify_expr
@@ -3087,7 +3087,7 @@ build_vec_init (decl, base, maxindex, init, from_array)
   finish_expr_stmt (rval);
 
   stmt_expr = finish_init_stmts (stmt_expr, compound_stmt);
-  current_stmt_tree->stmts_are_full_exprs_p = destroy_temps;
+  current_stmt_tree ()->stmts_are_full_exprs_p = destroy_temps;
   return stmt_expr;
 }
 
index 8b1efab..0435e2f 100644 (file)
 
 static tree maybe_convert_cond PARAMS ((tree));
 static tree simplify_aggr_init_exprs_r PARAMS ((tree *, int *, void *));
-static tree prune_unused_decls PARAMS ((tree *, int *, void *));
 static void deferred_type_access_control PARAMS ((void));
 static void emit_associated_thunks PARAMS ((tree));
 
-/* Record the fact that STMT was the last statement added to the
-   statement tree.  */
-
-#define SET_LAST_STMT(stmt) \
-  (current_stmt_tree->x_last_stmt = (stmt))
-
 /* When parsing a template, LAST_TREE contains the last statement
    parsed.  These are chained together through the TREE_CHAIN field,
    but often need to be re-organized since the parse is performed
    bottom-up.  This macro makes LAST_TREE the indicated SUBSTMT of
    STMT.  */
 
-#define RECHAIN_STMTS(stmt, substmt)   \
-  do {                                 \
-    substmt = TREE_CHAIN (stmt);       \
-    TREE_CHAIN (stmt) = NULL_TREE;     \
-    SET_LAST_STMT (stmt);              \
+#define RECHAIN_STMTS(stmt, substmt)           \
+  do {                                         \
+    substmt = TREE_CHAIN (stmt);               \
+    TREE_CHAIN (stmt) = NULL_TREE;             \
+    last_tree = stmt;                          \
   } while (0)
 
 /* Finish processing the COND, the SUBSTMT condition for STMT.  */
@@ -108,7 +101,19 @@ set_current_function_name_declared (i)
 int
 stmts_are_full_exprs_p ()
 {
-  return current_stmt_tree->stmts_are_full_exprs_p;
+  return current_stmt_tree ()->stmts_are_full_exprs_p;
+}
+
+/* Returns the stmt_tree (if any) to which statements are currently
+   being added.  If there is no active statement-tree, NULL is
+   returned.  */
+
+stmt_tree
+current_stmt_tree ()
+{
+  return (cfun 
+         ? &cfun->language->x_stmt_tree 
+         : &scope_chain->x_stmt_tree);
 }
 
 /* One if we have already declared __FUNCTION__ (and related
@@ -170,20 +175,6 @@ do_pushlevel ()
     }
 }
 
-/* T is a statement.  Add it to the statement-tree.  */
-
-void
-add_tree (t)
-     tree t;
-{
-  /* Add T to the statement-tree.  */
-  TREE_CHAIN (last_tree) = t;
-  SET_LAST_STMT (t);
-  /* When we expand a statement-tree, we must know whether or not the
-     statements are full-expresions.  We record that fact here.  */
-  STMT_IS_FULL_EXPR_P (last_tree) = stmts_are_full_exprs_p ();
-}
-
 /* Finish a goto-statement.  */
 
 void
@@ -207,7 +198,7 @@ finish_goto_stmt (destination)
   
   check_goto (destination);
 
-  add_tree (build_stmt (GOTO_STMT, destination));
+  add_stmt (build_stmt (GOTO_STMT, destination));
 }
 
 /* COND is the condition-expression for an if, while, etc.,
@@ -251,7 +242,7 @@ finish_expr_stmt (expr)
       if (!processing_template_decl)
        expr = break_out_cleanups (expr);
       
-      add_tree (build_stmt (EXPR_STMT, expr));
+      add_stmt (build_stmt (EXPR_STMT, expr));
     }
 
   finish_stmt ();
@@ -271,7 +262,7 @@ begin_if_stmt ()
   tree r;
   do_pushlevel ();
   r = build_stmt (IF_STMT, NULL_TREE, NULL_TREE, NULL_TREE);
-  add_tree (r);
+  add_stmt (r);
   return r;
 }
 
@@ -295,7 +286,7 @@ finish_then_clause (if_stmt)
      tree if_stmt;
 {
   RECHAIN_STMTS (if_stmt, THEN_CLAUSE (if_stmt));
-  SET_LAST_STMT (if_stmt);
+  last_tree = if_stmt;
   return if_stmt;
 }
 
@@ -346,7 +337,7 @@ begin_while_stmt ()
 {
   tree r;
   r = build_stmt (WHILE_STMT, NULL_TREE, NULL_TREE);
-  add_tree (r);
+  add_stmt (r);
   do_pushlevel ();
   return r;
 }
@@ -382,7 +373,7 @@ tree
 begin_do_stmt ()
 {
   tree r = build_stmt (DO_STMT, NULL_TREE, NULL_TREE);
-  add_tree (r);
+  add_stmt (r);
   return r;
 }
 
@@ -440,7 +431,7 @@ finish_return_stmt (expr)
          return;
        }
     }
-  add_tree (build_stmt (RETURN_STMT, expr));
+  add_stmt (build_stmt (RETURN_STMT, expr));
   finish_stmt ();
 }
 
@@ -454,7 +445,7 @@ begin_for_stmt ()
   r = build_stmt (FOR_STMT, NULL_TREE, NULL_TREE, 
                  NULL_TREE, NULL_TREE);
   NEW_FOR_SCOPE_P (r) = flag_new_for_scope > 0;
-  add_tree (r);
+  add_stmt (r);
   if (NEW_FOR_SCOPE_P (r))
     {
       do_pushlevel ();
@@ -521,7 +512,7 @@ finish_for_stmt (for_stmt)
 void
 finish_break_stmt ()
 {
-  add_tree (build_stmt (BREAK_STMT));
+  add_stmt (build_stmt (BREAK_STMT));
 }
 
 /* Finish a continue-statement.  */
@@ -529,7 +520,7 @@ finish_break_stmt ()
 void
 finish_continue_stmt ()
 {
-  add_tree (build_stmt (CONTINUE_STMT));
+  add_stmt (build_stmt (CONTINUE_STMT));
 }
 
 /* Begin a switch-statement.  Returns a new SWITCH_STMT if
@@ -540,7 +531,7 @@ begin_switch_stmt ()
 {
   tree r;
   r = build_stmt (SWITCH_STMT, NULL_TREE, NULL_TREE);
-  add_tree (r);
+  add_stmt (r);
   do_pushlevel ();
   return r;
 }
@@ -593,7 +584,7 @@ finish_case_label (low_value, high_value)
 {
   /* Add a representation for the case label to the statement
      tree.  */
-  add_tree (build_stmt (CASE_LABEL, low_value, high_value));
+  add_stmt (build_stmt (CASE_LABEL, low_value, high_value));
   /* And warn about crossing initializations, etc.  */
   if (!processing_template_decl)
     define_case_label ();
@@ -649,7 +640,7 @@ tree
 begin_try_block ()
 {
   tree r = build_stmt (TRY_BLOCK, NULL_TREE, NULL_TREE);
-  add_tree (r);
+  add_stmt (r);
   return r;
 }
 
@@ -660,7 +651,7 @@ begin_function_try_block ()
 {
   tree r = build_stmt (TRY_BLOCK, NULL_TREE, NULL_TREE);
   FN_TRY_BLOCK_P (r) = 1;
-  add_tree (r);
+  add_stmt (r);
   return r;
 }
 
@@ -761,7 +752,7 @@ begin_handler ()
 {
   tree r;
   r = build_stmt (HANDLER, NULL_TREE, NULL_TREE);
-  add_tree (r);
+  add_stmt (r);
   do_pushlevel ();
   return r;
 }
@@ -813,7 +804,7 @@ void
 begin_catch_block (type)
      tree type;
 {
-  add_tree (build (START_CATCH_STMT, type));
+  add_stmt (build (START_CATCH_STMT, type));
 }
 
 /* Finish a handler, which may be given by HANDLER.  The BLOCKs are
@@ -861,7 +852,7 @@ begin_compound_stmt (has_no_scope)
   if (last_tree && TREE_CODE (last_tree) == TRY_BLOCK)
     is_try = 1;
 
-  add_tree (r);
+  add_stmt (r);
   if (has_no_scope)
     COMPOUND_STMT_NO_SCOPE (r) = 1;
 
@@ -957,7 +948,7 @@ finish_asm_stmt (cv_qualifier, string, output_operands,
   r = build_stmt (ASM_STMT, cv_qualifier, string,
                  output_operands, input_operands,
                  clobbers);
-  add_tree (r);
+  add_stmt (r);
 }
 
 /* Finish a label with the indicated NAME.  */
@@ -967,7 +958,7 @@ finish_label_stmt (name)
      tree name;
 {
   tree decl = define_label (input_filename, lineno, name);
-  add_tree (build_stmt (LABEL_STMT, decl));
+  add_stmt (build_stmt (LABEL_STMT, decl));
 }
 
 /* Finish a series of declarations for local labels.  G++ allows users
@@ -993,7 +984,7 @@ add_decl_stmt (decl)
 
   /* We need the type to last until instantiation time.  */
   decl_stmt = build_stmt (DECL_STMT, decl);
-  add_tree (decl_stmt); 
+  add_stmt (decl_stmt); 
 }
 
 /* Generate the RTL for a SUBOBJECT. */
@@ -1014,7 +1005,7 @@ finish_subobject (cleanup)
      tree cleanup;
 {
   tree r = build_stmt (SUBOBJECT, cleanup);
-  add_tree (r);
+  add_stmt (r);
 }
 
 /* When DECL goes out of scope, make sure that CLEANUP is executed.  */
@@ -1024,7 +1015,7 @@ finish_decl_cleanup (decl, cleanup)
      tree decl;
      tree cleanup;
 {
-  add_tree (build_stmt (CLEANUP_STMT, decl, cleanup));
+  add_stmt (build_stmt (CLEANUP_STMT, decl, cleanup));
 }
 
 /* Generate the RTL for a RETURN_INIT. */
@@ -1103,10 +1094,10 @@ finish_named_return_value (return_id, init)
       if (!processing_template_decl) 
        {
          cp_finish_decl (decl, init, NULL_TREE, 0);
-         add_tree (build_stmt (RETURN_INIT, NULL_TREE, NULL_TREE));
+         add_stmt (build_stmt (RETURN_INIT, NULL_TREE, NULL_TREE));
        }
       else
-       add_tree (build_stmt (RETURN_INIT, return_id, init));
+       add_stmt (build_stmt (RETURN_INIT, return_id, init));
     }
 
   /* Don't use tree-inlining for functions with named return values.
@@ -1192,7 +1183,7 @@ setup_vtbl_ptr (member_init_list, base_init_list)
   if (DECL_CONSTRUCTOR_P (current_function_decl))
     {
       if (processing_template_decl)
-       add_tree (build_min_nt
+       add_stmt (build_min_nt
                  (CTOR_INITIALIZER,
                   member_init_list, base_init_list));
       else
@@ -1202,7 +1193,7 @@ setup_vtbl_ptr (member_init_list, base_init_list)
          /* Mark the beginning of the constructor.  */
          ctor_stmt = build_stmt (CTOR_STMT);
          CTOR_BEGIN_P (ctor_stmt) = 1;
-         add_tree (ctor_stmt);
+         add_stmt (ctor_stmt);
          
          /* And actually initialize the base-classes and members.  */
          emit_base_init (member_init_list, base_init_list);
@@ -1299,7 +1290,7 @@ add_scope_stmt (begin_p, partial_p)
     }
 
   /* Add the new statement to the statement-tree.  */
-  add_tree (ss);
+  add_stmt (ss);
 
   return top;
 }
@@ -1391,7 +1382,7 @@ finish_stmt_expr (rtl_expr)
   
   /* Remove the compound statement from the tree structure; it is
      now saved in the STMT_EXPR.  */
-  SET_LAST_STMT (rtl_expr);
+  last_tree = rtl_expr;
   TREE_CHAIN (last_tree) = NULL_TREE;
 
   /* If we created a statement-tree for this statement-expression,
@@ -2223,103 +2214,6 @@ finish_typeof (expr)
   return TREE_TYPE (expr);
 }
 
-/* Remove declarations of internal variables that are not used from a
-   stmt tree.  To qualify, the variable must have a name and must have
-   a zero DECL_SOURCE_LINE.  We tried to remove all variables for
-   which TREE_USED was false, but it turns out that there's tons of
-   variables for which TREE_USED is false but that are still in fact
-   used.  */
-
-static tree
-prune_unused_decls (tp, walk_subtrees, data)
-     tree *tp;
-     int *walk_subtrees ATTRIBUTE_UNUSED;
-     void *data ATTRIBUTE_UNUSED;
-{
-  tree t = *tp;
-
-  if (t == NULL_TREE)
-    {
-      *walk_subtrees = 0;
-      return NULL_TREE;
-    }
-
-  if (TREE_CODE (t) == DECL_STMT)
-    {
-      tree d = DECL_STMT_DECL (t);
-      if (!TREE_USED (d) && DECL_NAME (d) && DECL_SOURCE_LINE (d) == 0)
-       {
-         *tp = TREE_CHAIN (t);
-         /* Recurse on the new value of tp, otherwise we will skip
-            the next statement.  */
-         return prune_unused_decls (tp, walk_subtrees, data);
-       }
-    }
-  else if (TREE_CODE (t) == SCOPE_STMT)
-    {
-      /* Remove all unused decls from the BLOCK of this SCOPE_STMT.  */
-      tree block = SCOPE_STMT_BLOCK (t);
-
-      if (block)
-       {
-         tree *vp;
-
-         for (vp = &BLOCK_VARS (block); *vp; )
-           {
-             tree v = *vp;
-             if (! TREE_USED (v) && DECL_NAME (v) && DECL_SOURCE_LINE (v) == 0)
-               *vp = TREE_CHAIN (v);  /* drop */
-             else
-               vp = &TREE_CHAIN (v);  /* advance */
-           }
-         /* If there are now no variables, the entire BLOCK can be dropped.
-            (This causes SCOPE_NULLIFIED_P (t) to be true.)  */
-         if (BLOCK_VARS (block) == NULL_TREE)
-           SCOPE_STMT_BLOCK (t) = NULL_TREE;
-       }
-    }
-  return NULL_TREE;
-}
-
-/* Create an empty statement tree rooted at T.  */
-
-void
-begin_stmt_tree (t)
-     tree *t;
-{
-  /* We create a trivial EXPR_STMT so that last_tree is never NULL in
-     what follows.  We remove the extraneous statement in
-     finish_stmt_tree.  */
-  *t = build_nt (EXPR_STMT, void_zero_node);
-  SET_LAST_STMT (*t);
-  last_expr_type = NULL_TREE;
-}
-
-/* Finish the statement tree rooted at T.  */
-
-void
-finish_stmt_tree (t)
-     tree *t;
-{
-  tree stmt;
-  
-  /* Remove the fake extra statement added in begin_stmt_tree.  */
-  stmt = TREE_CHAIN (*t);
-  *t = stmt;
-  SET_LAST_STMT (NULL_TREE);
-
-  /* Remove unused decls from the stmt tree.  */
-  walk_stmt_tree (t, prune_unused_decls, NULL);
-
-  if (cfun)
-    {
-      /* The line-number recorded in the outermost statement in a function
-        is the line number of the end of the function.  */
-      STMT_LINENO (stmt) = lineno;
-      STMT_LINENO_FOR_FN_P (stmt) = 1;
-    }
-}
-
 /* We're about to expand T, a statement.  Set up appropriate context
    for the substitution.  */
 
@@ -2329,7 +2223,7 @@ prep_stmt (t)
 {
   if (!STMT_LINENO_FOR_FN_P (t))
     lineno = STMT_LINENO (t);
-  current_stmt_tree->stmts_are_full_exprs_p = STMT_IS_FULL_EXPR_P (t);
+  current_stmt_tree ()->stmts_are_full_exprs_p = STMT_IS_FULL_EXPR_P (t);
 }
 
 /* Generate RTL for the statement T, and its substatements, and any
@@ -2453,7 +2347,8 @@ lang_expand_stmt (t)
        }
 
       /* Restore saved state.  */
-      current_stmt_tree->stmts_are_full_exprs_p = saved_stmts_are_full_exprs_p;
+      current_stmt_tree ()->stmts_are_full_exprs_p = 
+       saved_stmts_are_full_exprs_p;
 
       /* Go on to the next statement in this scope.  */
       t = TREE_CHAIN (t);
index 0f88669..396b5c4 100644 (file)
@@ -42,7 +42,6 @@ static cp_lvalue_kind lvalue_p_1 PARAMS ((tree, int));
 static tree no_linkage_helper PARAMS ((tree *, int *, void *));
 static tree build_srcloc PARAMS ((const char *, int));
 static void mark_list_hash PARAMS ((void *));
-static int statement_code_p PARAMS ((enum tree_code));
 static tree mark_local_for_remap_r PARAMS ((tree *, int *, void *));
 static tree cp_unsave_r PARAMS ((tree *, int *, void *));
 static void cp_unsave PARAMS ((tree *));
@@ -50,6 +49,7 @@ static tree build_target_expr PARAMS ((tree, tree));
 static tree count_trees_r PARAMS ((tree *, int *, void *));
 static tree verify_stmt_tree_r PARAMS ((tree *, int *, void *));
 static tree find_tree_r PARAMS ((tree *, int *, void *));
+extern int cp_statement_code_p PARAMS ((enum tree_code));
 
 /* If REF is an lvalue, returns the kind of lvalue that REF is.
    Otherwise, returns clk_none.  If TREAT_CLASS_RVALUES_AS_LVALUES is
@@ -1071,33 +1071,18 @@ is_aggr_type_2 (t1, t2)
 
 /* Returns non-zero if CODE is the code for a statement.  */
 
-static int
-statement_code_p (code)
+int
+cp_statement_code_p (code)
      enum tree_code code;
 {
   switch (code)
     {
-    case EXPR_STMT:
-    case COMPOUND_STMT:
-    case DECL_STMT:
-    case IF_STMT:
-    case FOR_STMT:
-    case WHILE_STMT:
-    case DO_STMT:
-    case RETURN_STMT:
-    case BREAK_STMT:
-    case CONTINUE_STMT:
-    case SWITCH_STMT:
-    case GOTO_STMT:
-    case LABEL_STMT:
-    case ASM_STMT:
     case SUBOBJECT:
     case CLEANUP_STMT:
     case START_CATCH_STMT:
     case CTOR_STMT:
     case SCOPE_STMT:
     case CTOR_INITIALIZER:
-    case CASE_LABEL:
     case RETURN_INIT:
     case TRY_BLOCK:
     case HANDLER:
@@ -1223,9 +1208,9 @@ copy_template_template_parm (t, newargs)
 /* Apply FUNC to all the sub-trees of TP in a pre-order traversal.
    FUNC is called with the DATA and the address of each sub-tree.  If
    FUNC returns a non-NULL value, the traversal is aborted, and the
-   value returned by FUNC is returned.  The FLAGS govern the way in
-   which nodes are walked.  If HTAB is non-NULL it is used to record
-   the nodes visited, and to avoid visiting a node more than once.  */
+   value returned by FUNC is returned.  If HTAB is non-NULL it is used
+   to record the nodes visited, and to avoid visiting a node more than
+   once.  */
 
 tree 
 walk_tree (tp, func, data, htab)
@@ -1455,73 +1440,6 @@ walk_tree_without_duplicates (tp, func, data)
   return result;
 }
 
-/* Like walk_tree, but only examines statement nodes.  We don't need a
-   without_duplicates variant of this one because the statement tree is
-   a tree, not a graph.  */
-
-tree 
-walk_stmt_tree (tp, func, data)
-     tree *tp;
-     walk_tree_fn func;
-     void *data;
-{
-  enum tree_code code;
-  int walk_subtrees;
-  tree result;
-  int i, len;
-
-#define WALK_SUBTREE(NODE)                             \
-  do                                                   \
-    {                                                  \
-      result = walk_stmt_tree (&(NODE), func, data);   \
-      if (result)                                      \
-       return result;                                  \
-    }                                                  \
-  while (0)
-
-  /* Skip empty subtrees.  */
-  if (!*tp)
-    return NULL_TREE;
-
-  /* Skip subtrees below non-statement nodes.  */
-  if (!statement_code_p (TREE_CODE (*tp)))
-    return NULL_TREE;
-
-  /* Call the function.  */
-  walk_subtrees = 1;
-  result = (*func) (tp, &walk_subtrees, data);
-
-  /* If we found something, return it.  */
-  if (result)
-    return result;
-
-  /* Even if we didn't, FUNC may have decided that there was nothing
-     interesting below this point in the tree.  */
-  if (!walk_subtrees)
-    return NULL_TREE;
-
-  /* FUNC may have modified the tree, recheck that we're looking at a
-     statement node.  */
-  code = TREE_CODE (*tp);
-  if (!statement_code_p (code))
-    return NULL_TREE;
-
-  /* Walk over all the sub-trees of this operand.  Statement nodes never
-     contain RTL, and we needn't worry about TARGET_EXPRs.  */
-  len = TREE_CODE_LENGTH (code);
-
-  /* Go through the subtrees.  We need to do this in forward order so
-     that the scope of a FOR_EXPR is handled properly.  */
-  for (i = 0; i < len; ++i)
-    WALK_SUBTREE (TREE_OPERAND (*tp, i));
-
-  /* Finally visit the chain.  This can be tail-recursion optimized if
-     we write it this way.  */
-  return walk_stmt_tree (&TREE_CHAIN (*tp), func, data);
-
-#undef WALK_SUBTREE
-}
-
 /* Called from count_trees via walk_tree.  */
 
 static tree
@@ -2477,6 +2395,7 @@ init_tree ()
 {
   make_lang_type_fn = cp_make_lang_type;
   lang_unsave = cp_unsave;
+  lang_statement_code_p = cp_statement_code_p;
   ggc_add_root (list_hash_table, 
                ARRAY_SIZE (list_hash_table),
                sizeof (struct list_hash *),
index c548133..21574a9 100644 (file)
@@ -1,5 +1,5 @@
 /* This is part of libio/iostream, providing -*- C++ -*- input/output.
-Copyright (C) 1993 Free Software Foundation
+Copyright (C) 1993, 2000 Free Software Foundation
 
 This file is part of the GNU IO Library.  This library is free
 software; you can redistribute it and/or modify it under the
index 7841196..ea60b7b 100644 (file)
@@ -1,5 +1,5 @@
 /* Encoding of types for Objective C.
-   Copyright (C) 1993, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+   Copyright (C) 1993, 1995, 1996, 1997, 1998, 2000 Free Software Foundation, Inc.
    Contributed by Kresten Krab Thorup
    Bitfield support by Ovidiu Predescu