diff options
author | law <law@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-11-30 05:16:36 +0000 |
---|---|---|
committer | law <law@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-11-30 05:16:36 +0000 |
commit | bc4381667a31bd5f1e677d64c789b1e959df00d5 (patch) | |
tree | a6b80dca8f72a2e7640e4d535901e42325b2a954 /gcc/fortran/trans-decl.c | |
parent | 1cd66bce1663eb648638d311b493de0dcc4146c3 (diff) | |
parent | 738c50b853f5ba0eaf93e23f6d29cbac761eef9e (diff) | |
download | gcc-reload-v2a.tar.gz |
Weekly merge from trunk. No regressions.reload-v2a
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/reload-v2a@181834 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/fortran/trans-decl.c')
-rw-r--r-- | gcc/fortran/trans-decl.c | 44 |
1 files changed, 40 insertions, 4 deletions
diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c index 80e4f555d1c..67bd3e233f0 100644 --- a/gcc/fortran/trans-decl.c +++ b/gcc/fortran/trans-decl.c @@ -699,6 +699,18 @@ gfc_get_module_backend_decl (gfc_symbol *sym) } else if (sym->attr.flavor == FL_DERIVED) { + if (s && s->attr.flavor == FL_PROCEDURE) + { + gfc_interface *intr; + gcc_assert (s->attr.generic); + for (intr = s->generic; intr; intr = intr->next) + if (intr->sym->attr.flavor == FL_DERIVED) + { + s = intr->sym; + break; + } + } + if (!s->backend_decl) s->backend_decl = gfc_get_derived_type (s); gfc_copy_dt_decls_ifequal (s, sym, true); @@ -706,7 +718,7 @@ gfc_get_module_backend_decl (gfc_symbol *sym) } else if (s->backend_decl) { - if (sym->ts.type == BT_DERIVED) + if (sym->ts.type == BT_DERIVED || sym->ts.type == BT_CLASS) gfc_copy_dt_decls_ifequal (s->ts.u.derived, sym->ts.u.derived, true); else if (sym->ts.type == BT_CHARACTER) @@ -1459,6 +1471,10 @@ gfc_get_symbol_decl (gfc_symbol * sym) && !sym->attr.proc_pointer) DECL_BY_REFERENCE (decl) = 1; + if (sym->attr.vtab + || (sym->name[0] == '_' && strncmp ("__def_init", sym->name, 10) == 0)) + GFC_DECL_PUSH_TOPLEVEL (decl) = 1; + return decl; } @@ -1654,6 +1670,11 @@ gfc_get_extern_function_decl (gfc_symbol * sym) gfc_find_symbol (sym->name, gsym->ns, 0, &s); if (s && s->backend_decl) { + if (sym->ts.type == BT_DERIVED || sym->ts.type == BT_CLASS) + gfc_copy_dt_decls_ifequal (s->ts.u.derived, sym->ts.u.derived, + true); + else if (sym->ts.type == BT_CHARACTER) + sym->ts.u.cl->backend_decl = s->ts.u.cl->backend_decl; sym->backend_decl = s->backend_decl; return sym->backend_decl; } @@ -1879,7 +1900,8 @@ build_function_decl (gfc_symbol * sym, bool global) /* Layout the function declaration and put it in the binding level of the current function. */ - if (global) + if (global + || (sym->name[0] == '_' && strncmp ("__copy", sym->name, 6) == 0)) pushdecl_top_level (fndecl); else pushdecl (fndecl); @@ -4035,7 +4057,18 @@ gfc_trans_use_stmts (gfc_namespace * ns) st = gfc_find_symtree (ns->sym_root, rent->local_name[0] ? rent->local_name : rent->use_name); - gcc_assert (st); + + /* The following can happen if a derived type is renamed. */ + if (!st) + { + char *name; + name = xstrdup (rent->local_name[0] + ? rent->local_name : rent->use_name); + name[0] = (char) TOUPPER ((unsigned char) name[0]); + st = gfc_find_symtree (ns->sym_root, name); + free (name); + gcc_assert (st); + } /* Sometimes, generic interfaces wind up being over-ruled by a local symbol (see PR41062). */ @@ -5293,7 +5326,10 @@ gfc_generate_function_code (gfc_namespace * ns) next = DECL_CHAIN (decl); DECL_CHAIN (decl) = NULL_TREE; - pushdecl (decl); + if (GFC_DECL_PUSH_TOPLEVEL (decl)) + pushdecl_top_level (decl); + else + pushdecl (decl); decl = next; } saved_function_decls = NULL_TREE; |