aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran/module.c
diff options
context:
space:
mode:
authorChristopher D. Rickett <crickett@lanl.gov>2007-07-02 02:47:21 +0000
committerSteven G. Kargl <kargl@gcc.gnu.org>2007-07-02 02:47:21 +0000
commita8b3b0b633eb1f33d41c8f49a77641d4f767cd01 (patch)
treeac4b8eff52a0e3e3d04868300cc36392b6ca3faa /gcc/fortran/module.c
parent5edfe9e86fb349a11ad604074fcbdfc917f3c04a (diff)
downloadgcc-a8b3b0b633eb1f33d41c8f49a77641d4f767cd01.zip
gcc-a8b3b0b633eb1f33d41c8f49a77641d4f767cd01.tar.gz
gcc-a8b3b0b633eb1f33d41c8f49a77641d4f767cd01.tar.bz2
[multiple changes]
2007-07-01 Christopher D. Rickett <crickett@lanl.gov> * interface.c (gfc_compare_derived_types): Special case for comparing derived types across namespaces. (gfc_compare_types): Deal with BT_VOID. (compare_parameter): Use BT_VOID to accept ISO C Binding pointers. * trans-expr.c (gfc_conv_function_call): Remove setting parm_kind to SCALAR (gfc_conv_initializer): Deal with ISO C Binding NULL_PTR and NULL_FUNPTR. (gfc_conv_expr): Convert expressions for ISO C Binding derived types. * symbol.c (gfc_set_default_type): BIND(C) variables should not be implicitly declared. (check_conflict): Add BIND(C) and check for conflicts. (gfc_add_explicit_interface): Whitespace. (gfc_add_is_bind_c): New function. (gfc_copy_attr): Use it. (gfc_new_symbol): Initialize ISO C Binding objects. (get_iso_c_binding_dt): New function. (verify_bind_c_derived_type): Ditto. (gen_special_c_interop_ptr): Ditto. (add_formal_arg): Ditto. (gen_cptr_param): Ditto. (gen_fptr_param): Ditto. (gen_shape_param): Ditto. (add_proc_interface): Ditto. (build_formal_args): Ditto. (generate_isocbinding_symbol): Ditto. (get_iso_c_sym): Ditto. * decl.c (num_idents_on_line, has_name_equals): New variables. (verify_c_interop_param): New function. (build_sym): Finish binding labels and deal with COMMON blocks. (add_init_expr_to_sym): Check if the initialized expression is an iso_c_binding named constants (variable_decl): Set ISO C Binding type_spec components. (gfc_match_kind_spec): Check match for C interoperable kind. (match_char_spec): Fix comment. Chnage gfc_match_small_int to gfc_match_small_int_expr. Check for C interoperable kind. (match_type_spec): Clear the current binding label. (match_attr_spec): Add DECL_IS_BIND_C. If BIND(C) is found, use it to set attributes. (set_binding_label): New function. (set_com_block_bind_c): Ditto. (verify_c_interop): Ditto. (verify_com_block_vars_c_interop): Ditto. (verify_bind_c_sym): Ditto. (set_verify_bind_c_sym): Ditto. (set_verify_bind_c_com_block): Ditto. (get_bind_c_idents): Ditto. (gfc_match_bind_c_stmt): Ditto. (gfc_match_data_decl): Use num_idents_on_line. (match_result): Deal with right paren in BIND(C). (gfc_match_suffix): New function. (gfc_match_function_decl): Use it. Code is re-arranged to deal with ISO C Binding result clauses. (gfc_match_subroutine): Deal with BIND(C). (gfc_match_bind_c): New function. (gfc_get_type_attr_spec): New function. Code is re-arranged in and taken from gfc_match_derived_decl. (gfc_match_derived_decl): Add check for BIND(C). * trans-common.c: Forward declare gfc_get_common. (gfc_sym_mangled_common_id): Change arg from 'const char *name' to 'gfc_common_head *com'. Check for ISO C Binding of the common block. (build_common_decl): 'com->name' to 'com in SET_DECL_ASSEMBLER_NAME. * gfortran.h: Add GFC_MAX_BINDING_LABEL_LEN (bt): Add BT_VOID (sym_flavor): Add FL_VOID. (iso_fortran_env_symbol, iso_c_binding_symbol, intmod_id): New enum (CInteropKind_t): New struct. (c_interop_kinds_table): Use it. Declare an array of structs. (symbol_attribute): Add is_bind_c, is_c_interop, and is_iso_c bitfields. (gfc_typespec): Add is_c_interop; is_iso_c, and f90_type members. (gfc_symbol): Add from_intmod, intmod_sym_id, binding_label, and common_block members. (gfc_common_head): Add binding_label and is_bind_c members. (gfc_gsymbol): Add sym_name, mod_name, and binding_label members. Add prototypes for get_c_kind, gfc_validate_c_kind, gfc_check_any_c_kind, gfc_add_is_bind_c, gfc_add_value, verify_c_interop, verify_c_interop_param, verify_bind_c_sym, verify_bind_c_derived_type, verify_com_block_vars_c_interop, generate_isocbinding_symbol, get_iso_c_sym, gfc_iso_c_sub_interface * iso-c-binding.def: New file. This file contains the definitions of the types provided by the Fortran 2003 ISO_C_BINDING intrinsic module. * trans-const.c (gfc_conv_constant_to_tree): Deal with C_NULL_PTR or C_NULL_FUNPTR expressions. * expr.c (gfc_copy_expr): Add BT_VOID case. For BT_CHARACTER, the ISO C Binding requires a minimum string length of 1 for '\0'. * module.c (intmod_sym): New struct. (pointer_info): Add binding_label member. (write_atom): Set len to 0 for NULL pointers. Check for NULL p and *p. (ab_attribute): Add AB_IS_BIND_C, AB_IS_C_INTEROP and AB_IS_ISO_C. (attr_bits): Add "IS_BIND_C", "IS_C_INTEROP", and "IS_ISO_C". (mio_symbol_attribute): Deal with ISO C Binding attributes. (bt_types): Add "VOID". (mio_typespec): Deal with ISO C Binding components. (mio_namespace_ref): Add intmod variable. (mio_symbol): Check for symbols from an intrinsic module. (load_commons): Check for BIND(C) common block. (read_module): Read binding_label and use it. (write_common): Add label. Write BIND(C) info. (write_blank_common): Blank commons are not BIND(C). Explicitly set is_bind_c=0. (write_symbol): Deal with binding_label. (sort_iso_c_rename_list): New function. (import_iso_c_binding_module): Ditto. (create_int_parameter): Add to args. (use_iso_fortran_env_module): Adjust to deal with iso_c_binding intrinsic module. * trans-types.c (c_interop_kinds_table): new array of structs. (gfc_validate_c_kind): New function. (gfc_check_any_c_kind): Ditto. (get_real_kind_from_node): Ditto. (get_int_kind_from_node): Ditto. (get_int_kind_from_width): Ditto. (get_int_kind_from_minimal_width): Ditto. (init_c_interop_kinds): Ditto. (gfc_init_kinds): call init_c_interop_kinds. (gfc_typenode_for_spec): Adjust for BT_VOID and ISO C Binding pointers. Adjust handling of BT_DERIVED. (gfc_sym_type): Whitespace. (gfc_get_derived_type): Account for iso_c_binding derived types * resolve.c (is_scalar_expr_ptr): New function. (gfc_iso_c_func_interface): Ditto. (resolve_function): Use gfc_iso_c_func_interface. (set_name_and_label): New function. (gfc_iso_c_sub_interface): Ditto. (resolve_specific_s0): Use gfc_iso_c_sub_interface. (resolve_bind_c_comms): New function. (resolve_bind_c_derived_types): Ditto. (gfc_verify_binding_labels): Ditto. (resolve_fl_procedure): Check for ISO C interoperability. (resolve_symbol): Check C interoperability. (resolve_types): Walk the namespace. Check COMMON blocks. * trans-decl.c (gfc_sym_mangled_identifier): Prevent the mangling of identifiers that have an assigned binding label. (gfc_sym_mangled_function_id): Use the binding label rather than the mangled name. (gfc_finish_var_decl): Put variables that are BIND(C) into a common segment of the object file, because this is what C would do. (gfc_create_module_variable): Conver to proper types (set_tree_decl_type_code): New function. (generate_local_decl): Check dummy variables and derived types for ISO C Binding attributes. * match.c (gfc_match_small_int_expr): New function. (gfc_match_name_C): Ditto. (match_common_name): Deal with ISO C Binding in COMMON blocks * trans-io.c (transfer_expr): Deal with C_NULL_PTR or C_NULL_FUNPTR expressions * match.h: Add prototypes for gfc_match_small_int_expr, gfc_match_name_C, match_common_name, set_com_block_bind_c, set_binding_label, set_verify_bind_c_sym, set_verify_bind_c_com_block, get_bind_c_idents, gfc_match_bind_c_stmt, gfc_match_suffix, gfc_match_bind_c, gfc_get_type_attr_spec * parse.c (decode_statement): Use gfc_match_bind_c_stmt (parse_derived): Init *derived_sym = NULL, and gfc_current_block later for valiadation. * primary.c (got_delim): Set ISO C Binding components of ts. (match_logical_constant): Ditto. (match_complex_constant): Ditto. (match_complex_constant): Ditto. (gfc_match_rvalue): Check for existence of at least one arg for C_LOC, C_FUNLOC, and C_ASSOCIATED. * misc.c (gfc_clear_ts): Clear ISO C Bindoing components in ts. (get_c_kind): New function. 2007-07-01 Christopher D. Rickett <crickett@lanl.gov> * Makefile.in: Add support for iso_c_generated_procs.c and iso_c_binding.c. * Makefile.am: Ditto. * intrinsics/iso_c_generated_procs.c: New file containing helper functions. * intrinsics/iso_c_binding.c: Ditto. * intrinsics/iso_c_binding.h: New file * gfortran.map: Include the __iso_c_binding_c_* functions. * libgfortran.h: define GFC_NUM_RANK_BITS. 2007-06-23 Christopher D. Rickett <crickett@lanl.gov> * bind_c_array_params.f03: New files for Fortran 2003 ISO C Binding. * bind_c_coms.f90: Ditto. * bind_c_coms_driver.c: Ditto. * bind_c_dts.f90: Ditto. * bind_c_dts_2.f03: Ditto. * bind_c_dts_2_driver.c: Ditto. * bind_c_dts_3.f03: Ditto. * bind_c_dts_4.f03: Ditto. * bind_c_dts_driver.c: Ditto. * bind_c_implicit_vars.f03: Ditto. * bind_c_procs.f03: Ditto. * bind_c_usage_2.f03: Ditto. * bind_c_usage_3.f03: Ditto. * bind_c_usage_5.f03: Ditto. * bind_c_usage_6.f03: Ditto. * bind_c_usage_7.f03: Ditto. * bind_c_vars.f90: Ditto. * bind_c_vars_driver.c: Ditto. * binding_c_table_15_1.f03: Ditto. * binding_label_tests.f03: Ditto. * binding_label_tests_10.f03: Ditto. * binding_label_tests_10_main.f03: Ditto. * binding_label_tests_11.f03: Ditto. * binding_label_tests_11_main.f03: Ditto. * binding_label_tests_12.f03: Ditto. * binding_label_tests_13.f03: Ditto. * binding_label_tests_13_main.f03: Ditto. * binding_label_tests_14.f03: Ditto. * binding_label_tests_2.f03: Ditto. * binding_label_tests_3.f03: Ditto. * binding_label_tests_4.f03: Ditto. * binding_label_tests_5.f03: Ditto. * binding_label_tests_6.f03: Ditto. * binding_label_tests_7.f03: Ditto. * binding_label_tests_8.f03: Ditto. * binding_label_tests_9.f03: Ditto. * c_assoc.f90: Ditto. * c_assoc_2.f03: Ditto. * c_f_pointer_shape_test.f90: Ditto. * c_f_pointer_tests.f90: Ditto. * c_f_tests_driver.c: Ditto. * c_funloc_tests.f03: Ditto. * c_funloc_tests_2.f03: Ditto. * c_funloc_tests_3.f03: Ditto. * c_funloc_tests_3_funcs.c: Ditto. * c_kind_params.f90: Ditto. * c_kind_tests_2.f03: Ditto. * c_kinds.c: Ditto. * c_loc_driver.c: Ditto. * c_loc_test.f90: Ditto. * c_loc_tests_2.f03: Ditto. * c_loc_tests_2_funcs.c: Ditto. * c_loc_tests_3.f03: Ditto. * c_loc_tests_4.f03: Ditto. * c_loc_tests_5.f03: Ditto. * c_loc_tests_6.f03: Ditto. * c_loc_tests_7.f03: Ditto. * c_loc_tests_8.f03: Ditto. * c_ptr_tests.f03: Ditto. * c_ptr_tests_10.f03: Ditto. * c_ptr_tests_5.f03: Ditto. * c_ptr_tests_7.f03: Ditto. * c_ptr_tests_7_driver.c: Ditto. * c_ptr_tests_8.f03: Ditto. * c_ptr_tests_8_funcs.c: Ditto. * c_ptr_tests_9.f03: Ditto. * c_ptr_tests_driver.c: Ditto. * c_size_t_driver.c: Ditto. * c_size_t_test.f03: Ditto. * com_block_driver.f90: Ditto. * global_vars_c_init.f90: Ditto. * global_vars_c_init_driver.c: Ditto. * global_vars_f90_init.f90: Ditto. * global_vars_f90_init_driver.c: Ditto. * interop_params.f03: Ditto. * iso_c_binding_only.f03: Ditto. * iso_c_binding_rename_1.f03: Ditto. * iso_c_binding_rename_1_driver.c: Ditto. * iso_c_binding_rename_2.f03: Ditto. * iso_c_binding_rename_2_driver.c: Ditto. * kind_tests_2.f03: Ditto. * kind_tests_3.f03: Ditto. * module_md5_1.f90: Ditto. * only_clause_main.c: Ditto. * print_c_kinds.f90: Ditto. * test_bind_c_parens.f03: Ditto. * test_c_assoc.c: Ditto. * test_com_block.f90: Ditto. * test_common_binding_labels.f03: Ditto. * test_common_binding_labels_2.f03: Ditto. * test_common_binding_labels_2_main.f03: Ditto. * test_common_binding_labels_3.f03: Ditto. * test_common_binding_labels_3_main.f03: Ditto. * test_only_clause.f90: Ditto. * use_iso_c_binding.f90: Ditto. * value_5.f90: Ditto. * value_test.f90: Ditto. * value_tests_f03.f90: Ditto. From-SVN: r126185
Diffstat (limited to 'gcc/fortran/module.c')
-rw-r--r--gcc/fortran/module.c310
1 files changed, 285 insertions, 25 deletions
diff --git a/gcc/fortran/module.c b/gcc/fortran/module.c
index 14d26d9..665f6a1 100644
--- a/gcc/fortran/module.c
+++ b/gcc/fortran/module.c
@@ -86,6 +86,15 @@ typedef struct
}
module_locus;
+/* Structure for list of symbols of intrinsic modules. */
+typedef struct
+{
+ int id;
+ const char *name;
+ int value;
+}
+intmod_sym;
+
typedef enum
{
@@ -132,6 +141,7 @@ typedef struct pointer_info
module_locus where;
fixup_t *stfixup;
gfc_symtree *symtree;
+ char binding_label[GFC_MAX_SYMBOL_LEN + 1];
}
rsym;
@@ -1333,6 +1343,9 @@ write_atom (atom_type atom, const void *v)
}
+ if(p == NULL || *p == '\0')
+ len = 0;
+ else
len = strlen (p);
if (atom != ATOM_RPAREN)
@@ -1350,7 +1363,7 @@ write_atom (atom_type atom, const void *v)
if (atom == ATOM_STRING)
write_char ('\'');
- while (*p)
+ while (p != NULL && *p)
{
if (atom == ATOM_STRING && *p == '\'')
write_char ('\'');
@@ -1503,7 +1516,8 @@ typedef enum
AB_IN_NAMELIST, AB_IN_COMMON, AB_FUNCTION, AB_SUBROUTINE, AB_SEQUENCE,
AB_ELEMENTAL, AB_PURE, AB_RECURSIVE, AB_GENERIC, AB_ALWAYS_EXPLICIT,
AB_CRAY_POINTER, AB_CRAY_POINTEE, AB_THREADPRIVATE, AB_ALLOC_COMP,
- AB_VALUE, AB_VOLATILE, AB_PROTECTED
+ AB_VALUE, AB_VOLATILE, AB_PROTECTED, AB_IS_BIND_C, AB_IS_C_INTEROP,
+ AB_IS_ISO_C
}
ab_attribute;
@@ -1516,7 +1530,6 @@ static const mstring attr_bits[] =
minit ("OPTIONAL", AB_OPTIONAL),
minit ("POINTER", AB_POINTER),
minit ("SAVE", AB_SAVE),
- minit ("VALUE", AB_VALUE),
minit ("VOLATILE", AB_VOLATILE),
minit ("TARGET", AB_TARGET),
minit ("THREADPRIVATE", AB_THREADPRIVATE),
@@ -1535,11 +1548,16 @@ static const mstring attr_bits[] =
minit ("ALWAYS_EXPLICIT", AB_ALWAYS_EXPLICIT),
minit ("CRAY_POINTER", AB_CRAY_POINTER),
minit ("CRAY_POINTEE", AB_CRAY_POINTEE),
+ minit ("IS_BIND_C", AB_IS_BIND_C),
+ minit ("IS_C_INTEROP", AB_IS_C_INTEROP),
+ minit ("IS_ISO_C", AB_IS_ISO_C),
+ minit ("VALUE", AB_VALUE),
minit ("ALLOC_COMP", AB_ALLOC_COMP),
minit ("PROTECTED", AB_PROTECTED),
minit (NULL, -1)
};
+
/* Specialization of mio_name. */
DECL_MIO_NAME (ab_attribute)
DECL_MIO_NAME (ar_type)
@@ -1633,6 +1651,12 @@ mio_symbol_attribute (symbol_attribute *attr)
MIO_NAME (ab_attribute) (AB_CRAY_POINTER, attr_bits);
if (attr->cray_pointee)
MIO_NAME (ab_attribute) (AB_CRAY_POINTEE, attr_bits);
+ if (attr->is_bind_c)
+ MIO_NAME(ab_attribute) (AB_IS_BIND_C, attr_bits);
+ if (attr->is_c_interop)
+ MIO_NAME(ab_attribute) (AB_IS_C_INTEROP, attr_bits);
+ if (attr->is_iso_c)
+ MIO_NAME(ab_attribute) (AB_IS_ISO_C, attr_bits);
if (attr->alloc_comp)
MIO_NAME (ab_attribute) (AB_ALLOC_COMP, attr_bits);
@@ -1732,6 +1756,15 @@ mio_symbol_attribute (symbol_attribute *attr)
case AB_CRAY_POINTEE:
attr->cray_pointee = 1;
break;
+ case AB_IS_BIND_C:
+ attr->is_bind_c = 1;
+ break;
+ case AB_IS_C_INTEROP:
+ attr->is_c_interop = 1;
+ break;
+ case AB_IS_ISO_C:
+ attr->is_iso_c = 1;
+ break;
case AB_ALLOC_COMP:
attr->alloc_comp = 1;
break;
@@ -1750,6 +1783,7 @@ static const mstring bt_types[] = {
minit ("DERIVED", BT_DERIVED),
minit ("PROCEDURE", BT_PROCEDURE),
minit ("UNKNOWN", BT_UNKNOWN),
+ minit ("VOID", BT_VOID),
minit (NULL, -1)
};
@@ -1820,6 +1854,18 @@ mio_typespec (gfc_typespec *ts)
else
mio_symbol_ref (&ts->derived);
+ /* Add info for C interop and is_iso_c. */
+ mio_integer (&ts->is_c_interop);
+ mio_integer (&ts->is_iso_c);
+
+ /* If the typespec is for an identifier either from iso_c_binding, or
+ a constant that was initialized to an identifier from it, use the
+ f90_type. Otherwise, use the ts->type, since it shouldn't matter. */
+ if (ts->is_iso_c)
+ ts->f90_type = MIO_NAME (bt) (ts->f90_type, bt_types);
+ else
+ ts->f90_type = MIO_NAME (bt) (ts->type, bt_types);
+
if (ts->type != BT_CHARACTER)
{
/* ts->cl is only valid for BT_CHARACTER. */
@@ -2951,6 +2997,8 @@ mio_namespace_ref (gfc_namespace **nsp)
static void
mio_symbol (gfc_symbol *sym)
{
+ int intmod = INTMOD_NONE;
+
gfc_formal_arglist *formal;
mio_lparen ();
@@ -3006,6 +3054,23 @@ mio_symbol (gfc_symbol *sym)
= MIO_NAME (gfc_access) (sym->component_access, access_types);
mio_namelist (sym);
+
+ /* Add the fields that say whether this is from an intrinsic module,
+ and if so, what symbol it is within the module. */
+/* mio_integer (&(sym->from_intmod)); */
+ if (iomode == IO_OUTPUT)
+ {
+ intmod = sym->from_intmod;
+ mio_integer (&intmod);
+ }
+ else
+ {
+ mio_integer (&intmod);
+ sym->from_intmod = intmod;
+ }
+
+ mio_integer (&(sym->intmod_sym_id));
+
mio_rparen ();
}
@@ -3179,6 +3244,11 @@ load_commons (void)
p->threadprivate = 1;
p->use_assoc = 1;
+ /* Get whether this was a bind(c) common or not. */
+ mio_integer (&p->is_bind_c);
+ /* Get the binding label. */
+ mio_internal_string (p->binding_label);
+
mio_rparen ();
}
@@ -3415,7 +3485,9 @@ read_module (void)
mio_internal_string (info->u.rsym.true_name);
mio_internal_string (info->u.rsym.module);
+ mio_internal_string (info->u.rsym.binding_label);
+
require_atom (ATOM_INTEGER);
info->u.rsym.ns = atom_int;
@@ -3525,6 +3597,11 @@ read_module (void)
gfc_current_ns);
sym = info->u.rsym.sym;
sym->module = gfc_get_string (info->u.rsym.module);
+
+ /* TODO: hmm, can we test this? Do we know it will be
+ initialized to zeros? */
+ if (info->u.rsym.binding_label[0] != '\0')
+ strcpy (sym->binding_label, info->u.rsym.binding_label);
}
st->n.sym = sym;
@@ -3648,7 +3725,8 @@ write_common (gfc_symtree *st)
gfc_common_head *p;
const char * name;
int flags;
-
+ const char *label;
+
if (st == NULL)
return;
@@ -3668,16 +3746,35 @@ write_common (gfc_symtree *st)
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));
+
+ /* Write out the binding label, or the com name if no label given. */
+ if (p->is_bind_c)
+ {
+ label = p->binding_label;
+ mio_pool_string (&label);
+ }
+ else
+ {
+ label = p->name;
+ mio_pool_string (&label);
+ }
+
mio_rparen ();
}
-/* Write the blank common block to the module */
+
+/* Write the blank common block to the module. */
static void
write_blank_common (void)
{
const char * name = BLANK_COMMON_NAME;
int saved;
+ /* TODO: Blank commons are not bind(c). The F2003 standard probably says
+ this, but it hasn't been checked. Just making it so for now. */
+ int is_bind_c = 0;
if (gfc_current_ns->blank_common.head == NULL)
return;
@@ -3690,6 +3787,13 @@ write_blank_common (void)
saved = gfc_current_ns->blank_common.saved;
mio_integer (&saved);
+ /* Write out whether the common block is bind(c) or not. */
+ mio_integer (&is_bind_c);
+
+ /* Write out the binding label, which is BLANK_COMMON_NAME, though
+ it doesn't matter because the label isn't used. */
+ mio_pool_string (&name);
+
mio_rparen ();
}
@@ -3726,6 +3830,7 @@ write_equiv (void)
static void
write_symbol (int n, gfc_symbol *sym)
{
+ const char *label;
if (sym->attr.flavor == FL_UNKNOWN || sym->attr.flavor == FL_LABEL)
gfc_internal_error ("write_symbol(): bad module symbol '%s'", sym->name);
@@ -3734,6 +3839,14 @@ write_symbol (int n, gfc_symbol *sym)
mio_pool_string (&sym->name);
mio_pool_string (&sym->module);
+ if (sym->attr.is_bind_c || sym->attr.is_iso_c)
+ {
+ label = sym->binding_label;
+ mio_pool_string (&label);
+ }
+ else
+ mio_pool_string (&sym->name);
+
mio_pointer_ref (&sym->ns);
mio_symbol (sym);
@@ -3777,8 +3890,6 @@ write_symbol0 (gfc_symtree *st)
write_symbol (p->integer, sym);
p->u.wsym.state = WRITTEN;
-
- return;
}
@@ -4080,9 +4191,145 @@ gfc_dump_module (const char *name, int dump_flag)
}
+static void
+sort_iso_c_rename_list (void)
+{
+ gfc_use_rename *tmp_list = NULL;
+ gfc_use_rename *curr;
+ gfc_use_rename *kinds_used[ISOCBINDING_NUMBER] = {NULL};
+ int c_kind;
+ int i;
+
+ for (curr = gfc_rename_list; curr; curr = curr->next)
+ {
+ c_kind = get_c_kind (curr->use_name, c_interop_kinds_table);
+ if (c_kind == ISOCBINDING_INVALID || c_kind == ISOCBINDING_LAST)
+ {
+ gfc_error ("Symbol '%s' referenced at %L does not exist in "
+ "intrinsic module ISO_C_BINDING.", curr->use_name,
+ &curr->where);
+ }
+ else
+ /* Put it in the list. */
+ kinds_used[c_kind] = curr;
+ }
+
+ /* Make a new (sorted) rename list. */
+ i = 0;
+ while (i < ISOCBINDING_NUMBER && kinds_used[i] == NULL)
+ i++;
+
+ if (i < ISOCBINDING_NUMBER)
+ {
+ tmp_list = kinds_used[i];
+
+ i++;
+ curr = tmp_list;
+ for (; i < ISOCBINDING_NUMBER; i++)
+ if (kinds_used[i] != NULL)
+ {
+ curr->next = kinds_used[i];
+ curr = curr->next;
+ curr->next = NULL;
+ }
+ }
+
+ gfc_rename_list = tmp_list;
+}
+
+
+/* Import the instrinsic ISO_C_BINDING module, generating symbols in
+ the current namespace for all named constants, pointer types, and
+ procedures in the module unless the only clause was used or a rename
+ list was provided. */
+
+static void
+import_iso_c_binding_module (void)
+{
+ gfc_symbol *mod_sym = NULL;
+ gfc_symtree *mod_symtree = NULL;
+ const char *iso_c_module_name = "__iso_c_binding";
+ gfc_use_rename *u;
+ int i;
+ char *local_name;
+
+ /* Look only in the current namespace. */
+ mod_symtree = gfc_find_symtree (gfc_current_ns->sym_root, iso_c_module_name);
+
+ if (mod_symtree == NULL)
+ {
+ /* symtree doesn't already exist in current namespace. */
+ gfc_get_sym_tree (iso_c_module_name, gfc_current_ns, &mod_symtree);
+
+ if (mod_symtree != NULL)
+ mod_sym = mod_symtree->n.sym;
+ else
+ gfc_internal_error ("import_iso_c_binding_module(): Unable to "
+ "create symbol for %s", iso_c_module_name);
+
+ mod_sym->attr.flavor = FL_MODULE;
+ mod_sym->attr.intrinsic = 1;
+ mod_sym->module = gfc_get_string (iso_c_module_name);
+ mod_sym->from_intmod = INTMOD_ISO_C_BINDING;
+ }
+
+ /* Generate the symbols for the named constants representing
+ the kinds for intrinsic data types. */
+ if (only_flag)
+ {
+ /* Sort the rename list because there are dependencies between types
+ and procedures (e.g., c_loc needs c_ptr). */
+ sort_iso_c_rename_list ();
+
+ for (u = gfc_rename_list; u; u = u->next)
+ {
+ i = get_c_kind (u->use_name, c_interop_kinds_table);
+
+ if (i == ISOCBINDING_INVALID || i == ISOCBINDING_LAST)
+ {
+ gfc_error ("Symbol '%s' referenced at %L does not exist in "
+ "intrinsic module ISO_C_BINDING.", u->use_name,
+ &u->where);
+ continue;
+ }
+
+ generate_isocbinding_symbol (iso_c_module_name, i, u->local_name);
+ }
+ }
+ else
+ {
+ for (i = 0; i < ISOCBINDING_NUMBER; i++)
+ {
+ local_name = NULL;
+ for (u = gfc_rename_list; u; u = u->next)
+ {
+ if (strcmp (c_interop_kinds_table[i].name, u->use_name) == 0)
+ {
+ local_name = u->local_name;
+ u->found = 1;
+ break;
+ }
+ }
+ generate_isocbinding_symbol (iso_c_module_name, i, local_name);
+ }
+
+ for (u = gfc_rename_list; u; u = u->next)
+ {
+ if (u->found)
+ continue;
+
+ gfc_error ("Symbol '%s' referenced at %L not found in intrinsic "
+ "module ISO_C_BINDING", u->use_name, &u->where);
+ }
+ }
+}
+
+
/* Add an integer named constant from a given module. */
+
static void
-create_int_parameter (const char *name, int value, const char *modname)
+create_int_parameter (const char *name, int value, const char *modname,
+ intmod_id module, int id)
{
gfc_symtree *tmp_symtree;
gfc_symbol *sym;
@@ -4105,6 +4352,8 @@ create_int_parameter (const char *name, int value, const char *modname)
sym->ts.kind = gfc_default_integer_kind;
sym->value = gfc_int_expr (value);
sym->attr.use_assoc = 1;
+ sym->from_intmod = module;
+ sym->intmod_sym_id = id;
}
@@ -4120,14 +4369,14 @@ use_iso_fortran_env_module (void)
gfc_symtree *mod_symtree;
int i;
- mstring symbol[] = {
-#define NAMED_INTCST(a,b,c) minit(b,0),
+ intmod_sym symbol[] = {
+#define NAMED_INTCST(a,b,c) { a, b, 0 },
#include "iso-fortran-env.def"
#undef NAMED_INTCST
- minit (NULL, -1234) };
+ { ISOFORTRANENV_INVALID, NULL, -1234 } };
i = 0;
-#define NAMED_INTCST(a,b,c) symbol[i++].tag = c;
+#define NAMED_INTCST(a,b,c) symbol[i++].value = c;
#include "iso-fortran-env.def"
#undef NAMED_INTCST
@@ -4142,6 +4391,7 @@ use_iso_fortran_env_module (void)
mod_sym->attr.flavor = FL_MODULE;
mod_sym->attr.intrinsic = 1;
mod_sym->module = gfc_get_string (mod);
+ mod_sym->from_intmod = INTMOD_ISO_FORTRAN_ENV;
}
else
if (!mod_symtree->n.sym->attr.intrinsic)
@@ -4152,11 +4402,11 @@ use_iso_fortran_env_module (void)
if (only_flag)
for (u = gfc_rename_list; u; u = u->next)
{
- for (i = 0; symbol[i].string; i++)
- if (strcmp (symbol[i].string, u->use_name) == 0)
+ for (i = 0; symbol[i].name; i++)
+ if (strcmp (symbol[i].name, u->use_name) == 0)
break;
- if (symbol[i].string == NULL)
+ if (symbol[i].name == NULL)
{
gfc_error ("Symbol '%s' referenced at %L does not exist in "
"intrinsic module ISO_FORTRAN_ENV", u->use_name,
@@ -4165,7 +4415,7 @@ use_iso_fortran_env_module (void)
}
if ((gfc_option.flag_default_integer || gfc_option.flag_default_real)
- && strcmp (symbol[i].string, "numeric_storage_size") == 0)
+ && symbol[i].id == ISOFORTRANENV_NUMERIC_STORAGE_SIZE)
gfc_warning_now ("Use of the NUMERIC_STORAGE_SIZE named constant "
"from intrinsic module ISO_FORTRAN_ENV at %L is "
"incompatible with option %s", &u->where,
@@ -4173,17 +4423,18 @@ use_iso_fortran_env_module (void)
? "-fdefault-integer-8" : "-fdefault-real-8");
create_int_parameter (u->local_name[0] ? u->local_name
- : symbol[i].string,
- symbol[i].tag, mod);
+ : symbol[i].name,
+ symbol[i].value, mod, INTMOD_ISO_FORTRAN_ENV,
+ symbol[i].id);
}
else
{
- for (i = 0; symbol[i].string; i++)
+ for (i = 0; symbol[i].name; i++)
{
local_name = NULL;
for (u = gfc_rename_list; u; u = u->next)
{
- if (strcmp (symbol[i].string, u->use_name) == 0)
+ if (strcmp (symbol[i].name, u->use_name) == 0)
{
local_name = u->local_name;
u->found = 1;
@@ -4192,15 +4443,16 @@ use_iso_fortran_env_module (void)
}
if ((gfc_option.flag_default_integer || gfc_option.flag_default_real)
- && strcmp (symbol[i].string, "numeric_storage_size") == 0)
+ && symbol[i].id == ISOFORTRANENV_NUMERIC_STORAGE_SIZE)
gfc_warning_now ("Use of the NUMERIC_STORAGE_SIZE named constant "
"from intrinsic module ISO_FORTRAN_ENV at %C is "
"incompatible with option %s",
gfc_option.flag_default_integer
? "-fdefault-integer-8" : "-fdefault-real-8");
- create_int_parameter (local_name ? local_name : symbol[i].string,
- symbol[i].tag, mod);
+ create_int_parameter (local_name ? local_name : symbol[i].name,
+ symbol[i].value, mod, INTMOD_ISO_FORTRAN_ENV,
+ symbol[i].id);
}
for (u = gfc_rename_list; u; u = u->next)
@@ -4248,11 +4500,19 @@ gfc_use_module (void)
return;
}
+ if (strcmp (module_name, "iso_c_binding") == 0
+ && gfc_notify_std (GFC_STD_F2003, "Fortran 2003: "
+ "ISO_C_BINDING module at %C") != FAILURE)
+ {
+ import_iso_c_binding_module();
+ return;
+ }
+
module_fp = gfc_open_intrinsic_module (filename);
if (module_fp == NULL && specified_int)
- gfc_fatal_error ("Can't find an intrinsic module named '%s' at %C",
- module_name);
+ gfc_fatal_error ("Can't find an intrinsic module named '%s' at %C",
+ module_name);
}
if (module_fp == NULL)