OSDN Git Service

* cp-tree.h (function_depth): Declare.
authormmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 27 Jul 2000 21:10:29 +0000 (21:10 +0000)
committermmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 27 Jul 2000 21:10:29 +0000 (21:10 +0000)
(verify_stmt_tree): Likewise.
(find_tree): Likewise.
* decl.c (function_depth): Give it external linkage.
* optimize.c (optimize_function): Increment and decrement it.
* tree.c (verify_stmt_tree_r): New function.
(verify_stmt_tree): Likewise.
(find_tree_r): Likewise.
(find_tree): Likewise.

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

gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/optimize.c
gcc/cp/tree.c

index c981ca6..e032ce2 100644 (file)
@@ -1,3 +1,15 @@
+2000-07-27  Mark Mitchell  <mark@codesourcery.com>
+
+       * cp-tree.h (function_depth): Declare.
+       (verify_stmt_tree): Likewise.
+       (find_tree): Likewise.
+       * decl.c (function_depth): Give it external linkage.
+       * optimize.c (optimize_function): Increment and decrement it.
+       * tree.c (verify_stmt_tree_r): New function.
+       (verify_stmt_tree): Likewise.
+       (find_tree_r): Likewise.
+       (find_tree): Likewise.
+
 2000-07-27  Jason Merrill  <jason@redhat.com>
 
        * typeck.c (common_type): If we're just returning one of our
index 56798f1..6e592ca 100644 (file)
@@ -3290,6 +3290,11 @@ extern tree integer_two_node, integer_three_node;
 
 extern tree anonymous_namespace_name;
 
+/* The number of function bodies which we are currently processing.
+   (Zero if we are at namespace scope, one inside the body of a
+   function, two inside the body of a function in a local class, etc.)  */
+extern int function_depth;
+
 /* in pt.c  */
 
 /* These values are used for the `STRICT' parameter to type_unfication and
@@ -4539,6 +4544,8 @@ extern tree build_shared_int_cst                PARAMS ((int));
 extern special_function_kind special_function_p PARAMS ((tree));
 extern int count_trees                          PARAMS ((tree));
 extern int char_type_p                          PARAMS ((tree));
+extern void verify_stmt_tree                    PARAMS ((tree));
+extern tree find_tree                           PARAMS ((tree, tree));
   
 /* in typeck.c */
 extern int string_conv_p                       PARAMS ((tree, tree, int));
index 2f2d17b..3beeb8d 100644 (file)
@@ -374,6 +374,10 @@ tree signed_size_zero_node;
    unit.  */
 tree anonymous_namespace_name;
 
+/* The number of function bodies which we are currently processing.
+   (Zero if we are at namespace scope, one inside the body of a
+   function, two inside the body of a function in a local class, etc.)  */
+int function_depth;
 \f
 /* For each binding contour we allocate a binding_level structure
    which records the names defined in that contour.
@@ -13370,8 +13374,6 @@ build_enumerator (name, value, enumtype)
 }
 
 \f
-static int function_depth;
-
 /* We're defining DECL.  Make sure that it's type is OK.  */
 
 static void
index 1f87c9c..c9898b8 100644 (file)
@@ -801,6 +801,17 @@ void
 optimize_function (fn)
      tree fn;
 {
+  /* While in this function, we may choose to go off and compile
+     another function.  For example, we might instantiate a function
+     in the hopes of inlining it.  Normally, that wouldn't trigger any
+     actual RTL code-generation -- but it will if the template is
+     actually needed.  (For example, if it's address is taken, or if
+     some other function already refers to the template.)  If
+     code-generation occurs, then garbage collection will occur, so we
+     must protect ourselves, just as we do while building up the body
+     of the function.  */
+  ++function_depth;
+
   /* Expand calls to inline functions.  */
   if (flag_inline_trees)
     {
@@ -839,6 +850,9 @@ optimize_function (fn)
       VARRAY_FREE (id.fns);
       VARRAY_FREE (id.target_exprs);
     }
+
+  /* Undo the call to ggc_push_context above.  */
+  --function_depth;
 }
 
 /* Called from calls_setjmp_p via walk_tree.  */
index b17915f..bed0d49 100644 (file)
@@ -26,6 +26,7 @@ Boston, MA 02111-1307, USA.  */
 #include "tree.h"
 #include "cp-tree.h"
 #include "flags.h"
+#include "hashtab.h"
 #include "rtl.h"
 #include "toplev.h"
 #include "ggc.h"
@@ -48,6 +49,8 @@ static tree cp_unsave_r PARAMS ((tree *, int *, void *));
 static void cp_unsave PARAMS ((tree *));
 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 *));
 
 /* If REF is an lvalue, returns the kind of lvalue that REF is.
    Otherwise, returns clk_none.  If TREAT_CLASS_RVALUES_AS_LVALUES is
@@ -1440,6 +1443,70 @@ count_trees (t)
   return n_trees;
 }  
 
+/* Called from verify_stmt_tree via walk_tree.  */
+
+static tree
+verify_stmt_tree_r (tp, walk_subtrees, data)
+     tree *tp;
+     int *walk_subtrees ATTRIBUTE_UNUSED;
+     void *data;
+{
+  tree t = *tp;
+  htab_t *statements = (htab_t *) data;
+  void **slot;
+
+  if (!statement_code_p (TREE_CODE (t)))
+    return NULL_TREE;
+
+  /* If this statement is already present in the hash table, then
+     there is a circularity in the statement tree.  */
+  if (htab_find (*statements, t))
+    my_friendly_abort (20000727);
+  
+  slot = htab_find_slot (*statements, t, INSERT);
+  *slot = t;
+
+  return NULL_TREE;
+}
+
+/* Debugging function to check that the statement T has not been
+   corrupted.  For now, this function simply checks that T contains no
+   circularities.  */
+
+void
+verify_stmt_tree (t)
+     tree t;
+{
+  htab_t statements;
+  statements = htab_create (37, htab_hash_pointer, htab_eq_pointer, NULL);
+  walk_tree (&t, verify_stmt_tree_r, &statements);
+  htab_delete (statements);
+}
+
+/* Called from find_tree via walk_tree.  */
+
+static tree
+find_tree_r (tp, walk_subtrees, data)
+     tree *tp;
+     int *walk_subtrees ATTRIBUTE_UNUSED;
+     void *data;
+{
+  if (*tp == (tree) data)
+    return (tree) data;
+
+  return NULL_TREE;
+}
+
+/* Returns X if X appears in the tree structure rooted at T.  */
+
+tree
+find_tree (t, x)
+     tree t;
+     tree x;
+{
+  return walk_tree (&t, find_tree_r, x);
+}
+
 /* Passed to walk_tree.  Checks for the use of types with no linkage.  */
 
 static tree