diff options
author | Tobias Schlüter <tobi@gcc.gnu.org> | 2012-11-08 16:46:07 +0100 |
---|---|---|
committer | Tobias Schlüter <tobi@gcc.gnu.org> | 2012-11-08 16:46:07 +0100 |
commit | d476655d1d50448593b4099d0d6e7a4124ab6984 (patch) | |
tree | 3ec961cbce5d8193453e4806801c712407a00d1c /gcc/fortran/module.c | |
parent | 271a8a16512f3cd9eaac3df04b87f8c59baa5fec (diff) | |
download | gcc-d476655d1d50448593b4099d0d6e7a4124ab6984.zip gcc-d476655d1d50448593b4099d0d6e7a4124ab6984.tar.gz gcc-d476655d1d50448593b4099d0d6e7a4124ab6984.tar.bz2 |
re PR fortran/51727 (Changing module files)
PR fortran/51727
* module.c (sorted_pointer_info): New.
(gfc_get_sorted_pointer_info): New.
(free_sorted_pointer_info_tree): New.
(compare_sorted_pointer_info): New.
(find_symbols_to_write): New.
(write_symbol1_recursion): New.
(write_symbol1): Collect symbols that need writing, output in order.
(write_generic): Traverse tree in order.
From-SVN: r193329
Diffstat (limited to 'gcc/fortran/module.c')
-rw-r--r-- | gcc/fortran/module.c | 141 |
1 files changed, 115 insertions, 26 deletions
diff --git a/gcc/fortran/module.c b/gcc/fortran/module.c index 5cfc335..4cfcae4 100644 --- a/gcc/fortran/module.c +++ b/gcc/fortran/module.c @@ -5150,32 +5150,122 @@ write_symbol0 (gfc_symtree *st) } -/* Recursive traversal function to write the secondary set of symbols - to the module file. These are symbols that were not public yet are - needed by the public symbols or another dependent symbol. The act - of writing a symbol can modify the pointer_info tree, so we cease - traversal if we find a symbol to write. We return nonzero if a - symbol was written and pass that information upwards. */ +/* Type for the temporary tree used when writing secondary symbols. */ + +struct sorted_pointer_info +{ + BBT_HEADER (sorted_pointer_info); + + pointer_info *p; +}; + +#define gfc_get_sorted_pointer_info() XCNEW (sorted_pointer_info) + +/* Recursively traverse the temporary tree, free its contents. */ + +static void +free_sorted_pointer_info_tree (sorted_pointer_info *p) +{ + if (!p) + return; + + free_sorted_pointer_info_tree (p->left); + free_sorted_pointer_info_tree (p->right); + + free (p); +} + +/* Comparison function for the temporary tree. */ static int -write_symbol1 (pointer_info *p) +compare_sorted_pointer_info (void *_spi1, void *_spi2) { - int result; + sorted_pointer_info *spi1, *spi2; + spi1 = (sorted_pointer_info *)_spi1; + spi2 = (sorted_pointer_info *)_spi2; + if (spi1->p->integer < spi2->p->integer) + return -1; + if (spi1->p->integer > spi2->p->integer) + return 1; + return 0; +} + + +/* Finds the symbols that need to be written and collects them in the + sorted_pi tree so that they can be traversed in an order + independent of memory addresses. */ + +static void +find_symbols_to_write(sorted_pointer_info **tree, pointer_info *p) +{ + if (!p) + return; + + if (p->type == P_SYMBOL && p->u.wsym.state == NEEDS_WRITE) + { + sorted_pointer_info *sp = gfc_get_sorted_pointer_info(); + sp->p = p; + + gfc_insert_bbt (tree, sp, compare_sorted_pointer_info); + } + + find_symbols_to_write (tree, p->left); + find_symbols_to_write (tree, p->right); +} + + +/* Recursive function that traverses the tree of symbols that need to be + written and writes them in order. */ + +static void +write_symbol1_recursion (sorted_pointer_info *sp) +{ + if (!sp) + return; + + write_symbol1_recursion (sp->left); + + pointer_info *p1 = sp->p; + gcc_assert (p1->type == P_SYMBOL && p1->u.wsym.state == NEEDS_WRITE); + + p1->u.wsym.state = WRITTEN; + write_symbol (p1->integer, p1->u.wsym.sym); + + write_symbol1_recursion (sp->right); +} + + +/* Write the secondary set of symbols to the module file. These are + symbols that were not public yet are needed by the public symbols + or another dependent symbol. The act of writing a symbol can add + symbols to the pointer_info tree, so we return nonzero if a symbol + was written and pass that information upwards. The caller will + then call this function again until nothing was written. It uses + the utility functions and a temporary tree to ensure a reproducible + ordering of the symbol output and thus the module file. */ + +static int +write_symbol1 (pointer_info *p) +{ if (!p) return 0; - result = write_symbol1 (p->left); + /* Put symbols that need to be written into a tree sorted on the + integer field. */ - if (!(p->type != P_SYMBOL || p->u.wsym.state != NEEDS_WRITE)) - { - p->u.wsym.state = WRITTEN; - write_symbol (p->integer, p->u.wsym.sym); - result = 1; - } + sorted_pointer_info *spi_root = NULL; + find_symbols_to_write (&spi_root, p); + + /* No symbols to write, return. */ + if (!spi_root) + return 0; + + /* Otherwise, write and free the tree again. */ + write_symbol1_recursion (spi_root); + free_sorted_pointer_info_tree (spi_root); - result |= write_symbol1 (p->right); - return result; + return 1; } @@ -5205,19 +5295,18 @@ write_generic (gfc_symtree *st) return; write_generic (st->left); - write_generic (st->right); sym = st->n.sym; - if (!sym || check_unique_name (st->name)) - return; - - if (sym->generic == NULL || !gfc_check_symbol_access (sym)) - return; + if (sym && !check_unique_name (st->name) + && sym->generic && gfc_check_symbol_access (sym)) + { + if (!sym->module) + sym->module = module_name; - if (sym->module == NULL) - sym->module = module_name; + mio_symbol_interface (&st->name, &sym->module, &sym->generic); + } - mio_symbol_interface (&st->name, &sym->module, &sym->generic); + write_generic (st->right); } |