Commit d476655d by Tobias Schlüter

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
parent 271a8a16
2012-11-07 Tobias Schlüter <tobi@gcc.gnu.org>
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.
2012-11-07 Manuel López-Ibáñez <manu@gcc.gnu.org> 2012-11-07 Manuel López-Ibáñez <manu@gcc.gnu.org>
PR c/53063 PR c/53063
......
...@@ -5150,32 +5150,122 @@ write_symbol0 (gfc_symtree *st) ...@@ -5150,32 +5150,122 @@ write_symbol0 (gfc_symtree *st)
} }
/* Recursive traversal function to write the secondary set of symbols /* Type for the temporary tree used when writing secondary 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 struct sorted_pointer_info
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 BBT_HEADER (sorted_pointer_info);
symbol was written and pass that information upwards. */
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 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) if (!p)
return 0; 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)) sorted_pointer_info *spi_root = NULL;
{ find_symbols_to_write (&spi_root, p);
p->u.wsym.state = WRITTEN;
write_symbol (p->integer, p->u.wsym.sym); /* No symbols to write, return. */
result = 1; 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 1;
return result;
} }
...@@ -5205,19 +5295,18 @@ write_generic (gfc_symtree *st) ...@@ -5205,19 +5295,18 @@ write_generic (gfc_symtree *st)
return; return;
write_generic (st->left); write_generic (st->left);
write_generic (st->right);
sym = st->n.sym; sym = st->n.sym;
if (!sym || check_unique_name (st->name)) if (sym && !check_unique_name (st->name)
return; && sym->generic && gfc_check_symbol_access (sym))
{
if (sym->generic == NULL || !gfc_check_symbol_access (sym)) if (!sym->module)
return; sym->module = module_name;
if (sym->module == NULL) mio_symbol_interface (&st->name, &sym->module, &sym->generic);
sym->module = module_name; }
mio_symbol_interface (&st->name, &sym->module, &sym->generic); write_generic (st->right);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment