aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2008-08-29 20:41:19 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2008-08-29 20:41:19 +0200
commita64f5186dd1a3ea27bc7540c625ab24afd8030a3 (patch)
treeb8ebe79cda960c2d7a984748713c834f78fc8847 /gcc/fortran
parentca30a5396af8e55bb19746eeb323de7064da6c46 (diff)
downloadgcc-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/ChangeLog45
-rw-r--r--gcc/fortran/Make-lang.in2
-rw-r--r--gcc/fortran/f95-lang.c21
-rw-r--r--gcc/fortran/gfortran.h33
-rw-r--r--gcc/fortran/module.c42
-rw-r--r--gcc/fortran/symbol.c1
-rw-r--r--gcc/fortran/trans-common.c3
-rw-r--r--gcc/fortran/trans-decl.c203
-rw-r--r--gcc/fortran/trans-types.c17
-rw-r--r--gcc/fortran/trans.c24
-rw-r--r--gcc/fortran/trans.h10
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 *);