From: fxcoudert Date: Sat, 17 Nov 2007 13:46:53 +0000 (+0000) Subject: PR fortran/30285 X-Git-Tag: upstream/4.9.2~45034 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=eefa0a2b0d0990c531d97afc7f548cb95b374e74;p=platform%2Fupstream%2Flinaro-gcc.git PR fortran/30285 * module.c (struct written_common, written_commons): New structure. (compare_written_commons, free_written_common, write_common_0): New functions. (write_common): Call recursive function write_common_0. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@130257 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 0d343eb..ad4a9f9 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,5 +1,13 @@ 2007-11-17 Francois-Xavier Coudert + PR fortran/30285 + * module.c (struct written_common, written_commons): New structure. + (compare_written_commons, free_written_common, write_common_0): + New functions. + (write_common): Call recursive function write_common_0. + +2007-11-17 Francois-Xavier Coudert + PR fortran/34108 * io.c (check_format_string): Only check character expressions. (match_dt_format): Return MATCH_ERROR if that is what diff --git a/gcc/fortran/module.c b/gcc/fortran/module.c index a05437a..b0962e0 100644 --- a/gcc/fortran/module.c +++ b/gcc/fortran/module.c @@ -3767,51 +3767,119 @@ gfc_check_access (gfc_access specific_access, gfc_access default_access) } -/* Write a common block to the module. */ +/* A structure to remember which commons we've already written. */ + +struct written_common +{ + BBT_HEADER(written_common); + const char *name, *label; +}; + +static struct written_common *written_commons = NULL; + +/* Comparison function used for balancing the binary tree. */ + +static int +compare_written_commons (void *a1, void *b1) +{ + const char *aname = ((struct written_common *) a1)->name; + const char *alabel = ((struct written_common *) a1)->label; + const char *bname = ((struct written_common *) b1)->name; + const char *blabel = ((struct written_common *) b1)->label; + int c = strcmp (aname, bname); + + return (c != 0 ? c : strcmp (alabel, blabel)); +} + +/* Free a list of written commons. */ static void -write_common (gfc_symtree *st) +free_written_common (struct written_common *w) +{ + if (!w) + return; + + if (w->left) + free_written_common (w->left); + if (w->right) + free_written_common (w->right); + + gfc_free (w); +} + +/* Write a common block to the module -- recursive helper function. */ + +static void +write_common_0 (gfc_symtree *st) { gfc_common_head *p; const char * name; int flags; const char *label; + struct written_common *w; + bool write_me = true; if (st == NULL) return; - write_common (st->left); - write_common (st->right); - - mio_lparen (); + write_common_0 (st->left); - /* Write the unmangled name. */ + /* We will write out the binding label, or the name if no label given. */ name = st->n.common->name; - - mio_pool_string (&name); - p = st->n.common; - mio_symbol_ref (&p->head); - flags = p->saved ? 1 : 0; - if (p->threadprivate) flags |= 2; - mio_integer (&flags); - - /* Write out whether the common block is bind(c) or not. */ - mio_integer (&(p->is_bind_c)); + label = p->is_bind_c ? p->binding_label : p->name; - /* Write out the binding label, or the com name if no label given. */ - if (p->is_bind_c) + /* Check if we've already output this common. */ + w = written_commons; + while (w) { - label = p->binding_label; - mio_pool_string (&label); + int c = strcmp (name, w->name); + c = (c != 0 ? c : strcmp (label, w->label)); + if (c == 0) + write_me = false; + + w = (c < 0) ? w->left : w->right; } - else + + if (write_me) { - label = p->name; + /* Write the common to the module. */ + mio_lparen (); + mio_pool_string (&name); + + mio_symbol_ref (&p->head); + flags = p->saved ? 1 : 0; + if (p->threadprivate) + flags |= 2; + mio_integer (&flags); + + /* Write out whether the common block is bind(c) or not. */ + mio_integer (&(p->is_bind_c)); + mio_pool_string (&label); + mio_rparen (); + + /* Record that we have written this common. */ + w = gfc_getmem (sizeof (struct written_common)); + w->name = p->name; + w->label = label; + gfc_insert_bbt (&written_commons, w, compare_written_commons); } - mio_rparen (); + write_common_0 (st->right); +} + + +/* Write a common, by initializing the list of written commons, calling + the recursive function write_common_0() and cleaning up afterwards. */ + +static void +write_common (gfc_symtree *st) +{ + written_commons = NULL; + write_common_0 (st); + free_written_common (written_commons); + written_commons = NULL; }