diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 12 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 7 | ||||
-rw-r--r-- | gcc/cp/decl.c | 6 | ||||
-rw-r--r-- | gcc/cp/optimize.c | 14 | ||||
-rw-r--r-- | gcc/cp/tree.c | 67 |
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 |