diff options
author | Jakub Jelinek <jakub@redhat.com> | 2008-08-29 20:41:19 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2008-08-29 20:41:19 +0200 |
commit | a64f5186dd1a3ea27bc7540c625ab24afd8030a3 (patch) | |
tree | b8ebe79cda960c2d7a984748713c834f78fc8847 /gcc/fortran | |
parent | ca30a5396af8e55bb19746eeb323de7064da6c46 (diff) | |
download | gcc-a64f5186dd1a3ea27bc7540c625ab24afd8030a3.zip gcc-a64f5186dd1a3ea27bc7540c625ab24afd8030a3.tar.gz gcc-a64f5186dd1a3ea27bc7540c625ab24afd8030a3.tar.bz2 |
re PR fortran/29635 (debug info of modules)
PR fortran/29635
PR fortran/23057
* debug.h (struct gcc_debug_hooks): Add NAME and CHILD
arguments to imported_module_or_decl.
(debug_nothing_tree_tree): Removed.
(debug_nothing_tree_tree_tree_bool): New prototype.
* debug.c (do_nothing_debug_hooks): Adjust.
(debug_nothing_tree_tree): Removed.
(debug_nothing_tree_tree_tree_bool): New function.
* dwarf2out.c (is_symbol_die): Handle DW_TAG_module.
(gen_variable_die): Put all common vars for the
same COMMON block under one DW_TAG_common_block.
(declare_in_namespace): Return new context_die, for Fortran
return the module DIE instead of adding extra declarations into
the namespace.
(gen_type_die_with_usage): Adjust declare_in_namespace caller.
(gen_namespace_die): If is_fortran (), generate DW_TAG_module
instead of DW_TAG_namespace. If DECL_EXTERNAL is set, add
DW_AT_declaration.
(dwarf2out_global_decl): Don't skip Fortran global vars.
(gen_decl_die): Likewise. Adjust declare_in_namespace callers.
(dwarf2out_imported_module_or_decl): Add NAME and CHILD arguments.
If NAME is non-NULL, add DW_AT_name. If CHILD is non-NULL, put
DW_TAG_imported_declaration as child of previous
DW_TAG_imported_module.
* dbxout.c (dbx_debug_hooks, xcoff_debug_hooks): Adjust.
* sdbout.c (sdb_debug_hooks): Likewise.
* vmsdbgout.c (vmsdbg_debug_hooks): Likewise.
* name-lookup.c (do_using_directive, cp_emit_debug_info_for_using):
Adjust debug_hooks->imported_module_or_decl callers.
* f95-lang.c (gfc_init_ts): New function.
(LANG_HOOKS_INIT_TS): Define.
* gfortran.h (gfc_use_rename): New type, moved from module.c.
(gfc_get_use_rename): New macro, moved from module.c.
(gfc_use_list): New type.
(gfc_get_use_list): New macro.
(gfc_namespace): Add use_stmts field.
(gfc_free_use_stmts): New prototype.
* Make-lang.in (fortran/trans-decl.o): Depend on debug.h.
* module.c (gfc_use_rename, gfc_get_use_rename): Moved to
gfortran.h.
(gfc_use_module): Chain the USE statement info to
ns->use_stmts.
(gfc_free_use_stmts): New function.
* symbol.c (gfc_free_namespace): Call gfc_free_use_stmts.
* trans.h (struct module_htab_entry): New type.
(gfc_find_module, gfc_module_add_decl): New functions.
* trans.c (gfc_generate_module_code): Create NAMESPACE_DECL for
the module, adjust DECL_CONTEXTs of module procedures and
call gfc_module_add_decl for them.
* trans-common.c (build_common_decl): Set DECL_IGNORED_P
on the common variable.
(create_common): Set DECL_IGNORED_P for use associated vars.
* trans-decl.c: Include debug.h.
(gfc_get_symbol_decl): Set DECL_IGNORED_P on use_assoc vars from
modules.
(build_function_decl): Allow current_function_decl's context
to be a NAMESPACE_DECL.
(module_htab, cur_module): New variables.
(module_htab_do_hash, module_htab_eq, module_htab_decls_hash,
module_htab_decls_eq, gfc_find_module, gfc_module_add_decl): New
functions.
(gfc_create_module_variable): Adjust DECL_CONTEXTs of module
variables and types and call gfc_module_add_decl for them.
(gfc_generate_module_vars): Temporarily set cur_module.
(gfc_trans_use_stmts): New function.
(gfc_generate_function_code): Call it.
(gfc_generate_block_data): Set DECL_IGNORED_P on decl.
* trans-types.c (gfc_get_derived_type): Adjust DECL_CONTEXT
and TYPE_CONTEXT of module derived types.
From-SVN: r139773
Diffstat (limited to 'gcc/fortran')
-rw-r--r-- | gcc/fortran/ChangeLog | 45 | ||||
-rw-r--r-- | gcc/fortran/Make-lang.in | 2 | ||||
-rw-r--r-- | gcc/fortran/f95-lang.c | 21 | ||||
-rw-r--r-- | gcc/fortran/gfortran.h | 33 | ||||
-rw-r--r-- | gcc/fortran/module.c | 42 | ||||
-rw-r--r-- | gcc/fortran/symbol.c | 1 | ||||
-rw-r--r-- | gcc/fortran/trans-common.c | 3 | ||||
-rw-r--r-- | gcc/fortran/trans-decl.c | 203 | ||||
-rw-r--r-- | gcc/fortran/trans-types.c | 17 | ||||
-rw-r--r-- | gcc/fortran/trans.c | 24 | ||||
-rw-r--r-- | gcc/fortran/trans.h | 10 |
11 files changed, 375 insertions, 26 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index e6b1866..a1a72e6 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,48 @@ +2008-08-29 Jakub Jelinek <jakub@redhat.com> + + PR fortran/29635 + PR fortran/23057 + * f95-lang.c (gfc_init_ts): New function. + (LANG_HOOKS_INIT_TS): Define. + * gfortran.h (gfc_use_rename): New type, moved from module.c. + (gfc_get_use_rename): New macro, moved from module.c. + (gfc_use_list): New type. + (gfc_get_use_list): New macro. + (gfc_namespace): Add use_stmts field. + (gfc_free_use_stmts): New prototype. + * Make-lang.in (fortran/trans-decl.o): Depend on debug.h. + * module.c (gfc_use_rename, gfc_get_use_rename): Moved to + gfortran.h. + (gfc_use_module): Chain the USE statement info to + ns->use_stmts. + (gfc_free_use_stmts): New function. + * symbol.c (gfc_free_namespace): Call gfc_free_use_stmts. + * trans.h (struct module_htab_entry): New type. + (gfc_find_module, gfc_module_add_decl): New functions. + * trans.c (gfc_generate_module_code): Create NAMESPACE_DECL for + the module, adjust DECL_CONTEXTs of module procedures and + call gfc_module_add_decl for them. + * trans-common.c (build_common_decl): Set DECL_IGNORED_P + on the common variable. + (create_common): Set DECL_IGNORED_P for use associated vars. + * trans-decl.c: Include debug.h. + (gfc_get_symbol_decl): Set DECL_IGNORED_P on use_assoc vars from + modules. + (build_function_decl): Allow current_function_decl's context + to be a NAMESPACE_DECL. + (module_htab, cur_module): New variables. + (module_htab_do_hash, module_htab_eq, module_htab_decls_hash, + module_htab_decls_eq, gfc_find_module, gfc_module_add_decl): New + functions. + (gfc_create_module_variable): Adjust DECL_CONTEXTs of module + variables and types and call gfc_module_add_decl for them. + (gfc_generate_module_vars): Temporarily set cur_module. + (gfc_trans_use_stmts): New function. + (gfc_generate_function_code): Call it. + (gfc_generate_block_data): Set DECL_IGNORED_P on decl. + * trans-types.c (gfc_get_derived_type): Adjust DECL_CONTEXT + and TYPE_CONTEXT of module derived types. + 2008-08-28 Daniel Kraft <d@domob.eu> * gfortran.h (enum expr_t): New value `EXPR_COMPCALL'. diff --git a/gcc/fortran/Make-lang.in b/gcc/fortran/Make-lang.in index 20ac249..255f07e 100644 --- a/gcc/fortran/Make-lang.in +++ b/gcc/fortran/Make-lang.in @@ -314,7 +314,7 @@ fortran/convert.o: $(GFORTRAN_TRANS_DEPS) fortran/trans.o: $(GFORTRAN_TRANS_DEPS) tree-iterator.h fortran/trans-decl.o: $(GFORTRAN_TRANS_DEPS) gt-fortran-trans-decl.h \ $(CGRAPH_H) $(TARGET_H) $(FUNCTION_H) $(FLAGS_H) $(RTL_H) $(GIMPLE_H) \ - $(TREE_DUMP_H) + $(TREE_DUMP_H) debug.h fortran/trans-types.o: $(GFORTRAN_TRANS_DEPS) gt-fortran-trans-types.h \ $(REAL_H) toplev.h $(TARGET_H) $(FLAGS_H) dwarf2out.h fortran/trans-const.o: $(GFORTRAN_TRANS_DEPS) diff --git a/gcc/fortran/f95-lang.c b/gcc/fortran/f95-lang.c index 82da3b1..30cc98e 100644 --- a/gcc/fortran/f95-lang.c +++ b/gcc/fortran/f95-lang.c @@ -99,6 +99,7 @@ int global_bindings_p (void); static void clear_binding_stack (void); static void gfc_be_parse_file (int); static alias_set_type gfc_get_alias_set (tree); +static void gfc_init_ts (void); #undef LANG_HOOKS_NAME #undef LANG_HOOKS_INIT @@ -112,6 +113,7 @@ static alias_set_type gfc_get_alias_set (tree); #undef LANG_HOOKS_TYPE_FOR_MODE #undef LANG_HOOKS_TYPE_FOR_SIZE #undef LANG_HOOKS_GET_ALIAS_SET +#undef LANG_HOOKS_INIT_TS #undef LANG_HOOKS_OMP_PRIVATIZE_BY_REFERENCE #undef LANG_HOOKS_OMP_PREDETERMINED_SHARING #undef LANG_HOOKS_OMP_CLAUSE_DEFAULT_CTOR @@ -134,10 +136,11 @@ static alias_set_type gfc_get_alias_set (tree); #define LANG_HOOKS_POST_OPTIONS gfc_post_options #define LANG_HOOKS_PRINT_IDENTIFIER gfc_print_identifier #define LANG_HOOKS_PARSE_FILE gfc_be_parse_file -#define LANG_HOOKS_MARK_ADDRESSABLE gfc_mark_addressable -#define LANG_HOOKS_TYPE_FOR_MODE gfc_type_for_mode -#define LANG_HOOKS_TYPE_FOR_SIZE gfc_type_for_size -#define LANG_HOOKS_GET_ALIAS_SET gfc_get_alias_set +#define LANG_HOOKS_MARK_ADDRESSABLE gfc_mark_addressable +#define LANG_HOOKS_TYPE_FOR_MODE gfc_type_for_mode +#define LANG_HOOKS_TYPE_FOR_SIZE gfc_type_for_size +#define LANG_HOOKS_GET_ALIAS_SET gfc_get_alias_set +#define LANG_HOOKS_INIT_TS gfc_init_ts #define LANG_HOOKS_OMP_PRIVATIZE_BY_REFERENCE gfc_omp_privatize_by_reference #define LANG_HOOKS_OMP_PREDETERMINED_SHARING gfc_omp_predetermined_sharing #define LANG_HOOKS_OMP_CLAUSE_DEFAULT_CTOR gfc_omp_clause_default_ctor @@ -1189,5 +1192,15 @@ gfc_init_builtin_functions (void) #undef DEFINE_MATH_BUILTIN_C #undef DEFINE_MATH_BUILTIN +static void +gfc_init_ts (void) +{ + tree_contains_struct[NAMESPACE_DECL][TS_DECL_NON_COMMON] = 1; + tree_contains_struct[NAMESPACE_DECL][TS_DECL_WITH_VIS] = 1; + tree_contains_struct[NAMESPACE_DECL][TS_DECL_WRTL] = 1; + tree_contains_struct[NAMESPACE_DECL][TS_DECL_COMMON] = 1; + tree_contains_struct[NAMESPACE_DECL][TS_DECL_MINIMAL] = 1; +} + #include "gt-fortran-f95-lang.h" #include "gtype-fortran.h" diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h index 386668d..81e48b7 100644 --- a/gcc/fortran/gfortran.h +++ b/gcc/fortran/gfortran.h @@ -1132,6 +1132,35 @@ gfc_entry_list; #define gfc_get_entry_list() \ (gfc_entry_list *) gfc_getmem(sizeof(gfc_entry_list)) +/* Lists of rename info for the USE statement. */ + +typedef struct gfc_use_rename +{ + char local_name[GFC_MAX_SYMBOL_LEN + 1], use_name[GFC_MAX_SYMBOL_LEN + 1]; + struct gfc_use_rename *next; + int found; + gfc_intrinsic_op op; + locus where; +} +gfc_use_rename; + +#define gfc_get_use_rename() XCNEW (gfc_use_rename); + +/* A list of all USE statements in a namespace. */ + +typedef struct gfc_use_list +{ + const char *module_name; + int only_flag; + struct gfc_use_rename *rename; + /* Next USE statement. */ + struct gfc_use_list *next; +} +gfc_use_list; + +#define gfc_get_use_list() \ + (gfc_use_list *) gfc_getmem(sizeof(gfc_use_list)) + /* Within a namespace, symbols are pointed to by symtree nodes that are linked together in a balanced binary tree. There can be several symtrees pointing to the same symbol node via USE @@ -1232,6 +1261,9 @@ typedef struct gfc_namespace /* A list of all alternate entry points to this procedure (or NULL). */ gfc_entry_list *entries; + /* A list of USE statements in this namespace. */ + gfc_use_list *use_stmts; + /* Set to 1 if namespace is a BLOCK DATA program unit. */ int is_block_data; @@ -2472,6 +2504,7 @@ void gfc_module_init_2 (void); void gfc_module_done_2 (void); void gfc_dump_module (const char *, int); bool gfc_check_access (gfc_access, gfc_access); +void gfc_free_use_stmts (gfc_use_list *); /* primary.c */ symbol_attribute gfc_variable_attr (gfc_expr *, gfc_typespec *); diff --git a/gcc/fortran/module.c b/gcc/fortran/module.c index 4cbaaa0..b67b878 100644 --- a/gcc/fortran/module.c +++ b/gcc/fortran/module.c @@ -162,20 +162,6 @@ pointer_info; #define gfc_get_pointer_info() XCNEW (pointer_info) -/* Lists of rename info for the USE statement. */ - -typedef struct gfc_use_rename -{ - char local_name[GFC_MAX_SYMBOL_LEN + 1], use_name[GFC_MAX_SYMBOL_LEN + 1]; - struct gfc_use_rename *next; - int found; - gfc_intrinsic_op op; - locus where; -} -gfc_use_rename; - -#define gfc_get_use_rename() XCNEW (gfc_use_rename); - /* Local variables */ /* The FILE for the module we're reading or writing. */ @@ -5058,6 +5044,7 @@ gfc_use_module (void) gfc_state_data *p; int c, line, start; gfc_symtree *mod_symtree; + gfc_use_list *use_stmt; filename = (char *) alloca (strlen (module_name) + strlen (MODULE_EXTENSION) + 1); @@ -5150,6 +5137,33 @@ gfc_use_module (void) pi_root = NULL; fclose (module_fp); + + use_stmt = gfc_get_use_list (); + use_stmt->module_name = gfc_get_string (module_name); + use_stmt->only_flag = only_flag; + use_stmt->rename = gfc_rename_list; + gfc_rename_list = NULL; + use_stmt->next = gfc_current_ns->use_stmts; + gfc_current_ns->use_stmts = use_stmt; +} + + +void +gfc_free_use_stmts (gfc_use_list *use_stmts) +{ + gfc_use_list *next; + for (; use_stmts; use_stmts = next) + { + gfc_use_rename *next_rename; + + for (; use_stmts->rename; use_stmts->rename = next_rename) + { + next_rename = use_stmts->rename->next; + gfc_free (use_stmts->rename); + } + next = use_stmts->next; + gfc_free (use_stmts); + } } diff --git a/gcc/fortran/symbol.c b/gcc/fortran/symbol.c index 0b202eb..41e8006 100644 --- a/gcc/fortran/symbol.c +++ b/gcc/fortran/symbol.c @@ -3023,6 +3023,7 @@ gfc_free_namespace (gfc_namespace *ns) gfc_free_equiv (ns->equiv); gfc_free_equiv_lists (ns->equiv_lists); + gfc_free_use_stmts (ns->use_stmts); for (i = GFC_INTRINSIC_BEGIN; i != GFC_INTRINSIC_END; i++) gfc_free_interface (ns->op[i]); diff --git a/gcc/fortran/trans-common.c b/gcc/fortran/trans-common.c index 8c30309..9e55792 100644 --- a/gcc/fortran/trans-common.c +++ b/gcc/fortran/trans-common.c @@ -416,6 +416,7 @@ build_common_decl (gfc_common_head *com, tree union_type, bool is_init) SET_DECL_ASSEMBLER_NAME (decl, gfc_sym_mangled_common_id (com)); TREE_PUBLIC (decl) = 1; TREE_STATIC (decl) = 1; + DECL_IGNORED_P (decl) = 1; if (!com->is_bind_c) DECL_ALIGN (decl) = BIGGEST_ALIGNMENT; else @@ -680,6 +681,8 @@ create_common (gfc_common_head *com, segment_info *head, bool saw_equiv) TREE_PUBLIC (var_decl) = TREE_PUBLIC (decl); TREE_STATIC (var_decl) = TREE_STATIC (decl); TREE_USED (var_decl) = TREE_USED (decl); + if (s->sym->attr.use_assoc) + DECL_IGNORED_P (var_decl) = 1; if (s->sym->attr.target) TREE_ADDRESSABLE (var_decl) = 1; /* This is a fake variable just for debugging purposes. */ diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c index 1dfa05c..59b33ca 100644 --- a/gcc/fortran/trans-decl.c +++ b/gcc/fortran/trans-decl.c @@ -35,6 +35,7 @@ along with GCC; see the file COPYING3. If not see #include "function.h" #include "flags.h" #include "cgraph.h" +#include "debug.h" #include "gfortran.h" #include "trans.h" #include "trans-types.h" @@ -994,7 +995,11 @@ gfc_get_symbol_decl (gfc_symbol * sym) This is done here rather than in gfc_finish_var_decl because it is different for string length variables. */ if (sym->module) - SET_DECL_ASSEMBLER_NAME (decl, gfc_sym_mangled_identifier (sym)); + { + SET_DECL_ASSEMBLER_NAME (decl, gfc_sym_mangled_identifier (sym)); + if (sym->attr.use_assoc) + DECL_IGNORED_P (decl) = 1; + } if (sym->attr.dimension) { @@ -1300,7 +1305,9 @@ build_function_decl (gfc_symbol * sym) /* Allow only one nesting level. Allow public declarations. */ gcc_assert (current_function_decl == NULL_TREE - || DECL_CONTEXT (current_function_decl) == NULL_TREE); + || DECL_CONTEXT (current_function_decl) == NULL_TREE + || TREE_CODE (DECL_CONTEXT (current_function_decl)) + == NAMESPACE_DECL); type = gfc_get_function_type (sym); fndecl = build_decl (FUNCTION_DECL, gfc_sym_identifier (sym), type); @@ -2922,6 +2929,88 @@ gfc_trans_deferred_vars (gfc_symbol * proc_sym, tree fnbody) return gfc_finish_block (&body); } +static GTY ((param_is (struct module_htab_entry))) htab_t module_htab; + +/* Hash and equality functions for module_htab. */ + +static hashval_t +module_htab_do_hash (const void *x) +{ + return htab_hash_string (((const struct module_htab_entry *)x)->name); +} + +static int +module_htab_eq (const void *x1, const void *x2) +{ + return strcmp ((((const struct module_htab_entry *)x1)->name), + (const char *)x2) == 0; +} + +/* Hash and equality functions for module_htab's decls. */ + +static hashval_t +module_htab_decls_hash (const void *x) +{ + const_tree t = (const_tree) x; + const_tree n = DECL_NAME (t); + if (n == NULL_TREE) + n = TYPE_NAME (TREE_TYPE (t)); + return htab_hash_string (IDENTIFIER_POINTER (n)); +} + +static int +module_htab_decls_eq (const void *x1, const void *x2) +{ + const_tree t1 = (const_tree) x1; + const_tree n1 = DECL_NAME (t1); + if (n1 == NULL_TREE) + n1 = TYPE_NAME (TREE_TYPE (t1)); + return strcmp (IDENTIFIER_POINTER (n1), (const char *) x2) == 0; +} + +struct module_htab_entry * +gfc_find_module (const char *name) +{ + void **slot; + + if (! module_htab) + module_htab = htab_create_ggc (10, module_htab_do_hash, + module_htab_eq, NULL); + + slot = htab_find_slot_with_hash (module_htab, name, + htab_hash_string (name), INSERT); + if (*slot == NULL) + { + struct module_htab_entry *entry = GGC_CNEW (struct module_htab_entry); + + entry->name = gfc_get_string (name); + entry->decls = htab_create_ggc (10, module_htab_decls_hash, + module_htab_decls_eq, NULL); + *slot = (void *) entry; + } + return (struct module_htab_entry *) *slot; +} + +void +gfc_module_add_decl (struct module_htab_entry *entry, tree decl) +{ + void **slot; + const char *name; + + if (DECL_NAME (decl)) + name = IDENTIFIER_POINTER (DECL_NAME (decl)); + else + { + gcc_assert (TREE_CODE (decl) == TYPE_DECL); + name = IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (decl))); + } + slot = htab_find_slot_with_hash (entry->decls, name, + htab_hash_string (name), INSERT); + if (*slot == NULL) + *slot = (void *) decl; +} + +static struct module_htab_entry *cur_module; /* Output an initialized decl for a module variable. */ @@ -2941,6 +3030,22 @@ gfc_create_module_variable (gfc_symbol * sym) && sym->ts.type == BT_DERIVED) sym->backend_decl = gfc_typenode_for_spec (&(sym->ts)); + if (sym->attr.flavor == FL_DERIVED + && sym->backend_decl + && TREE_CODE (sym->backend_decl) == RECORD_TYPE) + { + decl = sym->backend_decl; + gcc_assert (sym->ns->proc_name->attr.flavor == FL_MODULE); + gcc_assert (TYPE_CONTEXT (decl) == NULL_TREE + || TYPE_CONTEXT (decl) == sym->ns->proc_name->backend_decl); + gcc_assert (DECL_CONTEXT (TYPE_STUB_DECL (decl)) == NULL_TREE + || DECL_CONTEXT (TYPE_STUB_DECL (decl)) + == sym->ns->proc_name->backend_decl); + TYPE_CONTEXT (decl) = sym->ns->proc_name->backend_decl; + DECL_CONTEXT (TYPE_STUB_DECL (decl)) = sym->ns->proc_name->backend_decl; + gfc_module_add_decl (cur_module, TYPE_STUB_DECL (decl)); + } + /* Only output variables and array valued, or derived type, parameters. */ if (sym->attr.flavor != FL_VARIABLE @@ -2948,6 +3053,15 @@ gfc_create_module_variable (gfc_symbol * sym) && (sym->attr.dimension || sym->ts.type == BT_DERIVED))) return; + if ((sym->attr.in_common || sym->attr.in_equivalence) && sym->backend_decl) + { + decl = sym->backend_decl; + gcc_assert (DECL_CONTEXT (decl) == NULL_TREE); + gcc_assert (sym->ns->proc_name->attr.flavor == FL_MODULE); + DECL_CONTEXT (decl) = sym->ns->proc_name->backend_decl; + gfc_module_add_decl (cur_module, decl); + } + /* Don't generate variables from other modules. Variables from COMMONs will already have been generated. */ if (sym->attr.use_assoc || sym->attr.in_common) @@ -2955,8 +3069,8 @@ gfc_create_module_variable (gfc_symbol * sym) /* Equivalenced variables arrive here after creation. */ if (sym->backend_decl - && (sym->equiv_built || sym->attr.in_equivalence)) - return; + && (sym->equiv_built || sym->attr.in_equivalence)) + return; if (sym->backend_decl) internal_error ("backend decl for module variable %s already exists", @@ -2969,7 +3083,11 @@ gfc_create_module_variable (gfc_symbol * sym) /* Create the variable. */ pushdecl (decl); + gcc_assert (DECL_CONTEXT (decl) == NULL_TREE); + gcc_assert (sym->ns->proc_name->attr.flavor == FL_MODULE); + DECL_CONTEXT (decl) = sym->ns->proc_name->backend_decl; rest_of_decl_compilation (decl, 1, 0); + gfc_module_add_decl (cur_module, decl); /* Also add length of strings. */ if (sym->ts.type == BT_CHARACTER) @@ -2992,6 +3110,7 @@ void gfc_generate_module_vars (gfc_namespace * ns) { module_namespace = ns; + cur_module = gfc_find_module (ns->proc_name->name); /* Check if the frontend left the namespace in a reasonable state. */ gcc_assert (ns->proc_name && !ns->proc_name->tlink); @@ -3001,6 +3120,79 @@ gfc_generate_module_vars (gfc_namespace * ns) /* Create decls for all the module variables. */ gfc_traverse_ns (ns, gfc_create_module_variable); + + cur_module = NULL; +} + +static void +gfc_trans_use_stmts (gfc_namespace * ns) +{ + gfc_use_list *use_stmt; + for (use_stmt = ns->use_stmts; use_stmt; use_stmt = use_stmt->next) + { + struct module_htab_entry *entry + = gfc_find_module (use_stmt->module_name); + gfc_use_rename *rent; + + if (entry->namespace_decl == NULL) + { + entry->namespace_decl + = build_decl (NAMESPACE_DECL, + get_identifier (use_stmt->module_name), + void_type_node); + DECL_EXTERNAL (entry->namespace_decl) = 1; + } + if (!use_stmt->only_flag) + (*debug_hooks->imported_module_or_decl) (entry->namespace_decl, + NULL_TREE, + ns->proc_name->backend_decl, + false); + for (rent = use_stmt->rename; rent; rent = rent->next) + { + tree decl, local_name; + void **slot; + + if (rent->op != INTRINSIC_NONE) + continue; + + slot = htab_find_slot_with_hash (entry->decls, rent->use_name, + htab_hash_string (rent->use_name), + INSERT); + if (*slot == NULL) + { + gfc_symtree *st; + + st = gfc_find_symtree (ns->sym_root, + rent->local_name[0] + ? rent->local_name : rent->use_name); + gcc_assert (st && st->n.sym->attr.use_assoc); + if (st->n.sym->backend_decl && DECL_P (st->n.sym->backend_decl)) + { + gcc_assert (DECL_EXTERNAL (entry->namespace_decl)); + decl = copy_node (st->n.sym->backend_decl); + DECL_CONTEXT (decl) = entry->namespace_decl; + DECL_EXTERNAL (decl) = 1; + DECL_IGNORED_P (decl) = 0; + DECL_INITIAL (decl) = NULL_TREE; + } + else + { + *slot = error_mark_node; + htab_clear_slot (entry->decls, slot); + continue; + } + *slot = decl; + } + decl = (tree) *slot; + if (rent->local_name[0]) + local_name = get_identifier (rent->local_name); + else + local_name = NULL_TREE; + (*debug_hooks->imported_module_or_decl) (decl, local_name, + ns->proc_name->backend_decl, + !use_stmt->only_flag); + } + } } static void @@ -3533,6 +3725,8 @@ gfc_generate_function_code (gfc_namespace * ns) gfc_gimplify_function (fndecl); cgraph_finalize_function (fndecl, false); } + + gfc_trans_use_stmts (ns); } void @@ -3624,6 +3818,7 @@ gfc_generate_block_data (gfc_namespace * ns) decl = build_decl (VAR_DECL, id, gfc_array_index_type); TREE_PUBLIC (decl) = 1; TREE_STATIC (decl) = 1; + DECL_IGNORED_P (decl) = 1; pushdecl (decl); rest_of_decl_compilation (decl, 1, 0); diff --git a/gcc/fortran/trans-types.c b/gcc/fortran/trans-types.c index 49ab6a4..dbda199 100644 --- a/gcc/fortran/trans-types.c +++ b/gcc/fortran/trans-types.c @@ -1934,12 +1934,23 @@ gfc_get_derived_type (gfc_symbol * derived) gfc_finish_type (typenode); gfc_set_decl_location (TYPE_STUB_DECL (typenode), &derived->declared_at); + if (derived->module && derived->ns->proc_name->attr.flavor == FL_MODULE) + { + if (derived->ns->proc_name->backend_decl + && TREE_CODE (derived->ns->proc_name->backend_decl) + == NAMESPACE_DECL) + { + TYPE_CONTEXT (typenode) = derived->ns->proc_name->backend_decl; + DECL_CONTEXT (TYPE_STUB_DECL (typenode)) + = derived->ns->proc_name->backend_decl; + } + } derived->backend_decl = typenode; - /* Add this backend_decl to all the other, equal derived types. */ - for (dt = gfc_derived_types; dt; dt = dt->next) - copy_dt_decls_ifequal (derived, dt->derived); + /* Add this backend_decl to all the other, equal derived types. */ + for (dt = gfc_derived_types; dt; dt = dt->next) + copy_dt_decls_ifequal (derived, dt->derived); return derived->backend_decl; } diff --git a/gcc/fortran/trans.c b/gcc/fortran/trans.c index 911e379..1b115f4 100644 --- a/gcc/fortran/trans.c +++ b/gcc/fortran/trans.c @@ -1209,6 +1209,19 @@ void gfc_generate_module_code (gfc_namespace * ns) { gfc_namespace *n; + struct module_htab_entry *entry; + + gcc_assert (ns->proc_name->backend_decl == NULL); + ns->proc_name->backend_decl + = build_decl (NAMESPACE_DECL, get_identifier (ns->proc_name->name), + void_type_node); + gfc_set_decl_location (ns->proc_name->backend_decl, + &ns->proc_name->declared_at); + entry = gfc_find_module (ns->proc_name->name); + if (entry->namespace_decl) + /* Buggy sourcecode, using a module before defining it? */ + htab_empty (entry->decls); + entry->namespace_decl = ns->proc_name->backend_decl; gfc_generate_module_vars (ns); @@ -1216,10 +1229,21 @@ gfc_generate_module_code (gfc_namespace * ns) sibling calls. */ for (n = ns->contained; n; n = n->sibling) { + gfc_entry_list *el; + if (!n->proc_name) continue; gfc_create_function_decl (n); + gcc_assert (DECL_CONTEXT (n->proc_name->backend_decl) == NULL_TREE); + DECL_CONTEXT (n->proc_name->backend_decl) = ns->proc_name->backend_decl; + gfc_module_add_decl (entry, n->proc_name->backend_decl); + for (el = ns->entries; el; el = el->next) + { + gcc_assert (DECL_CONTEXT (el->sym->backend_decl) == NULL_TREE); + DECL_CONTEXT (el->sym->backend_decl) = ns->proc_name->backend_decl; + gfc_module_add_decl (entry, el->sym->backend_decl); + } } for (n = ns->contained; n; n = n->sibling) diff --git a/gcc/fortran/trans.h b/gcc/fortran/trans.h index 6e09f24..290c92b 100644 --- a/gcc/fortran/trans.h +++ b/gcc/fortran/trans.h @@ -429,6 +429,16 @@ void gfc_generate_block_data (gfc_namespace *); /* Output a decl for a module variable. */ void gfc_generate_module_vars (gfc_namespace *); +struct module_htab_entry GTY(()) +{ + const char *name; + tree namespace_decl; + htab_t GTY ((param_is (union tree_node))) decls; +}; + +struct module_htab_entry *gfc_find_module (const char *); +void gfc_module_add_decl (struct module_htab_entry *, tree); + /* Get and set the current location. */ void gfc_set_backend_locus (locus *); void gfc_get_backend_locus (locus *); |