diff options
author | Tobias Burnus <burnus@gcc.gnu.org> | 2011-11-09 20:36:54 +0100 |
---|---|---|
committer | Tobias Burnus <burnus@gcc.gnu.org> | 2011-11-09 20:36:54 +0100 |
commit | a5b3d713ccade591a3dd972f5586912f8ef5cb48 (patch) | |
tree | 49fac99f233a41394dac7a4594189d6e57d2bc08 | |
parent | 5cc66776c46dedbda21a89d5422663feb4a7cc45 (diff) | |
download | gcc-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/ChangeLog | 12 | ||||
-rw-r--r-- | gcc/fortran/symbol.c | 82 |
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); } |