From 7bc3a46c6872e9b7a7e624495a2c3ea02f0503a2 Mon Sep 17 00:00:00 2001 From: zack Date: Tue, 29 Aug 2000 22:13:20 +0000 Subject: [PATCH] * cp/semantics.c (prune_unused_decls): New function. (finish_stmt_tree): Call it via walk_tree. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@36056 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/cp/ChangeLog | 5 +++++ gcc/cp/semantics.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 84954e7a703..b0842f5f7cb 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,10 @@ 2000-08-29 Zack Weinberg + * cp/semantics.c (prune_unused_decls): New function. + (finish_stmt_tree): Call it via walk_tree. + +2000-08-29 Zack Weinberg + * class.c (build_secondary_vtable): Constify a char *. * decl.c (init_decl_processing): Initialize function_id_node, pretty_function_id_node, and func_id_node. diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 70ef712ca84..6584a4204f9 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -48,6 +48,7 @@ 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)); @@ -2241,6 +2242,57 @@ 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) == BLOCK) + { + /* walk_tree doesn't inspect BLOCK_VARS, so we must do it by hand. */ + tree *vp; + + for (vp = &BLOCK_VARS (t); *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 (BLOCK_VARS (t) == NULL_TREE) + TREE_USED (t) = 0; + } + return NULL_TREE; +} + /* Create an empty statement tree rooted at T. */ void @@ -2262,12 +2314,19 @@ finish_stmt_tree (t) tree *t; { tree stmt; + int old_lineno; /* 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_tree messes with + the line number, so save/restore it. */ + old_lineno = lineno; + walk_tree (t, prune_unused_decls, 0); + lineno = old_lineno; + if (cfun) { /* The line-number recorded in the outermost statement in a function -- 2.11.4.GIT