aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTobias Burnus <burnus@gcc.gnu.org>2011-11-09 20:36:54 +0100
committerTobias Burnus <burnus@gcc.gnu.org>2011-11-09 20:36:54 +0100
commita5b3d713ccade591a3dd972f5586912f8ef5cb48 (patch)
tree49fac99f233a41394dac7a4594189d6e57d2bc08
parent5cc66776c46dedbda21a89d5422663feb4a7cc45 (diff)
downloadgcc-a5b3d713ccade591a3dd972f5586912f8ef5cb48.zip
gcc-a5b3d713ccade591a3dd972f5586912f8ef5cb48.tar.gz
gcc-a5b3d713ccade591a3dd972f5586912f8ef5cb48.tar.bz2
symbol.c (clear_sym_mark, [...]): Remove functions.
2011-11-09 Tobias Burnus <burnus@net-b.de> * symbol.c (clear_sym_mark, traverse_ns): Remove functions. (count_st_nodes, do_traverse_symtree, fill_st_vector): New functions. (gfc_traverse_symtree, gfc_traverse_ns): Call do_traverse_symtree. From-SVN: r181232
-rw-r--r--gcc/fortran/ChangeLog12
-rw-r--r--gcc/fortran/symbol.c82
2 files changed, 66 insertions, 28 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index 019680d..dca8398 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,7 +1,13 @@
+2011-11-09 Tobias Burnus <burnus@net-b.de>
+
+ * symbol.c (clear_sym_mark, traverse_ns): Remove functions.
+ (count_st_nodes, do_traverse_symtree, fill_st_vector): New functions.
+ (gfc_traverse_symtree, gfc_traverse_ns): Call do_traverse_symtree.
+
2011-11-09 Janne Blomqvist <jb@gcc.gnu.org>
- PR libfortran/50016
- * gfortran.texi (Data consistency and durability): New section.
+ PR libfortran/50016
+ * gfortran.texi (Data consistency and durability): New section.
2011-11-09 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
@@ -638,7 +644,7 @@
2011-10-23 Steven G. Kargl <kargl@gcc.gnu.org>
* simplify.c (simplify_transformation_to_array): Fix memory leak.
-
+
2011-10-20 Steven G. Kargl <kargl@gcc.gnu.org>
PR fortran/50821
diff --git a/gcc/fortran/symbol.c b/gcc/fortran/symbol.c
index 67d65cb..33ec706 100644
--- a/gcc/fortran/symbol.c
+++ b/gcc/fortran/symbol.c
@@ -3310,46 +3310,81 @@ gfc_symbol_done_2 (void)
}
-/* Clear mark bits from symbol nodes associated with a symtree node. */
+/* Count how many nodes a symtree has. */
-static void
-clear_sym_mark (gfc_symtree *st)
+static unsigned
+count_st_nodes (const gfc_symtree *st)
{
+ unsigned nodes;
+ if (!st)
+ return 0;
- st->n.sym->mark = 0;
+ nodes = count_st_nodes (st->left);
+ nodes++;
+ nodes += count_st_nodes (st->right);
+
+ return nodes;
}
-/* Recursively traverse the symtree nodes. */
+/* Convert symtree tree into symtree vector. */
-void
-gfc_traverse_symtree (gfc_symtree *st, void (*func) (gfc_symtree *))
+static unsigned
+fill_st_vector (gfc_symtree *st, gfc_symtree **st_vec, unsigned node_cntr)
{
if (!st)
- return;
+ return node_cntr;
+
+ node_cntr = fill_st_vector (st->left, st_vec, node_cntr);
+ st_vec[node_cntr++] = st;
+ node_cntr = fill_st_vector (st->right, st_vec, node_cntr);
- gfc_traverse_symtree (st->left, func);
- (*func) (st);
- gfc_traverse_symtree (st->right, func);
+ return node_cntr;
}
-/* Recursive namespace traversal function. */
+/* Traverse namespace. As the functions might modify the symtree, we store the
+ symtree as a vector and operate on this vector. Note: We assume that
+ sym_func or st_func never deletes nodes from the symtree - only adding is
+ allowed. Additionally, newly added nodes are not traversed. */
static void
-traverse_ns (gfc_symtree *st, void (*func) (gfc_symbol *))
+do_traverse_symtree (gfc_symtree *st, void (*st_func) (gfc_symtree *),
+ void (*sym_func) (gfc_symbol *))
{
+ gfc_symtree **st_vec;
+ unsigned nodes, i, node_cntr;
- if (st == NULL)
- return;
+ gcc_assert ((st_func && !sym_func) || (!st_func && sym_func));
+ nodes = count_st_nodes (st);
+ st_vec = XALLOCAVEC (gfc_symtree *, nodes);
+ node_cntr = 0;
+ fill_st_vector (st, st_vec, node_cntr);
+
+ if (sym_func)
+ {
+ /* Clear marks. */
+ for (i = 0; i < nodes; i++)
+ st_vec[i]->n.sym->mark = 0;
+ for (i = 0; i < nodes; i++)
+ if (!st_vec[i]->n.sym->mark)
+ {
+ (*sym_func) (st_vec[i]->n.sym);
+ st_vec[i]->n.sym->mark = 1;
+ }
+ }
+ else
+ for (i = 0; i < nodes; i++)
+ (*st_func) (st_vec[i]);
+}
- traverse_ns (st->left, func);
- if (st->n.sym->mark == 0)
- (*func) (st->n.sym);
- st->n.sym->mark = 1;
+/* Recursively traverse the symtree nodes. */
- traverse_ns (st->right, func);
+void
+gfc_traverse_symtree (gfc_symtree *st, void (*st_func) (gfc_symtree *))
+{
+ do_traverse_symtree (st, st_func, NULL);
}
@@ -3357,12 +3392,9 @@ traverse_ns (gfc_symtree *st, void (*func) (gfc_symbol *))
care that each gfc_symbol node is called exactly once. */
void
-gfc_traverse_ns (gfc_namespace *ns, void (*func) (gfc_symbol *))
+gfc_traverse_ns (gfc_namespace *ns, void (*sym_func) (gfc_symbol *))
{
-
- gfc_traverse_symtree (ns->sym_root, clear_sym_mark);
-
- traverse_ns (ns->sym_root, func);
+ do_traverse_symtree (ns->sym_root, NULL, sym_func);
}