aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/tree.c
diff options
context:
space:
mode:
authorZack Weinberg <zack@wolery.cumb.org>2000-09-06 05:52:51 +0000
committerZack Weinberg <zack@gcc.gnu.org>2000-09-06 05:52:51 +0000
commit11f53b6a0879e853b8aa3e12b81b56f1582c38f6 (patch)
tree70e50e84e9a226d6722859ba63eba0a30b37d9c9 /gcc/cp/tree.c
parent3392dafcfdcbe74f8c60e14fa0f3ea73363552ab (diff)
downloadgcc-11f53b6a0879e853b8aa3e12b81b56f1582c38f6.zip
gcc-11f53b6a0879e853b8aa3e12b81b56f1582c38f6.tar.gz
gcc-11f53b6a0879e853b8aa3e12b81b56f1582c38f6.tar.bz2
tree.c (walk_tree): Expose tail recursion.
* tree.c (walk_tree): Expose tail recursion. (walk_stmt_tree): New function. * cp-tree.h: Prototype walk_stmt_tree. * semantics.c (prune_unused_decls): Operate on SCOPE_STMTs not the BLOCKs directly. If a BLOCK has no variables after pruning, discard it. (finish_stmt_tree): Use walk_stmt_tree. No need to save and restore the line number. From-SVN: r36178
Diffstat (limited to 'gcc/cp/tree.c')
-rw-r--r--gcc/cp/tree.c70
1 files changed, 69 insertions, 1 deletions
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index 0c51f54..0f88669 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -1319,7 +1319,8 @@ walk_tree (tp, func, data, htab)
WALK_SUBTREE (DECL_SIZE_UNIT (DECL_STMT_DECL (*tp)));
}
- WALK_SUBTREE (TREE_CHAIN (*tp));
+ /* This can be tail-recursion optimized if we write it this way. */
+ return walk_tree (&TREE_CHAIN (*tp), func, data, htab);
}
/* We didn't find what we were looking for. */
@@ -1454,6 +1455,73 @@ 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