aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog12
-rw-r--r--gcc/cp/cp-tree.h7
-rw-r--r--gcc/cp/decl.c6
-rw-r--r--gcc/cp/optimize.c14
-rw-r--r--gcc/cp/tree.c67
5 files changed, 104 insertions, 2 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index c981ca6..e032ce2 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 56798f1..6e592ca 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -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));
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 2f2d17b..3beeb8d 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -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;
/* 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)
}
-static int function_depth;
-
/* We're defining DECL. Make sure that it's type is OK. */
static void
diff --git a/gcc/cp/optimize.c b/gcc/cp/optimize.c
index 1f87c9c..c9898b8 100644
--- a/gcc/cp/optimize.c
+++ b/gcc/cp/optimize.c
@@ -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. */
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index b17915f..bed0d49 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -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