/* Handle modules, which amounts to loading and saving symbols and
their attendant structures.
- Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+ Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
+ 2009, 2010
Free Software Foundation, Inc.
Contributed by Andy Vaught
#include "match.h"
#include "parse.h" /* FIXME */
#include "md5.h"
+#include "constructor.h"
#define MODULE_EXTENSION ".mod"
/* Don't put any single quote (') in MOD_VERSION,
if yout want it to be recognized. */
-#define MOD_VERSION "4"
+#define MOD_VERSION "5"
/* Structure that describes a position within a module file. */
AB_CRAY_POINTER, AB_CRAY_POINTEE, AB_THREADPRIVATE, AB_ALLOC_COMP,
AB_POINTER_COMP, AB_PRIVATE_COMP, AB_VALUE, AB_VOLATILE, AB_PROTECTED,
AB_IS_BIND_C, AB_IS_C_INTEROP, AB_IS_ISO_C, AB_ABSTRACT, AB_ZERO_COMP,
- AB_IS_CLASS, AB_PROCEDURE, AB_PROC_POINTER
+ AB_IS_CLASS, AB_PROCEDURE, AB_PROC_POINTER, AB_ASYNCHRONOUS, AB_CODIMENSION,
+ AB_COARRAY_COMP, AB_VTYPE, AB_VTAB
}
ab_attribute;
static const mstring attr_bits[] =
{
minit ("ALLOCATABLE", AB_ALLOCATABLE),
+ minit ("ASYNCHRONOUS", AB_ASYNCHRONOUS),
minit ("DIMENSION", AB_DIMENSION),
+ minit ("CODIMENSION", AB_CODIMENSION),
minit ("EXTERNAL", AB_EXTERNAL),
minit ("INTRINSIC", AB_INTRINSIC),
minit ("OPTIONAL", AB_OPTIONAL),
minit ("IS_ISO_C", AB_IS_ISO_C),
minit ("VALUE", AB_VALUE),
minit ("ALLOC_COMP", AB_ALLOC_COMP),
+ minit ("COARRAY_COMP", AB_COARRAY_COMP),
minit ("POINTER_COMP", AB_POINTER_COMP),
minit ("PRIVATE_COMP", AB_PRIVATE_COMP),
minit ("ZERO_COMP", AB_ZERO_COMP),
minit ("IS_CLASS", AB_IS_CLASS),
minit ("PROCEDURE", AB_PROCEDURE),
minit ("PROC_POINTER", AB_PROC_POINTER),
+ minit ("VTYPE", AB_VTYPE),
+ minit ("VTAB", AB_VTAB),
minit (NULL, -1)
};
{
if (attr->allocatable)
MIO_NAME (ab_attribute) (AB_ALLOCATABLE, attr_bits);
+ if (attr->asynchronous)
+ MIO_NAME (ab_attribute) (AB_ASYNCHRONOUS, attr_bits);
if (attr->dimension)
MIO_NAME (ab_attribute) (AB_DIMENSION, attr_bits);
+ if (attr->codimension)
+ MIO_NAME (ab_attribute) (AB_CODIMENSION, attr_bits);
if (attr->external)
MIO_NAME (ab_attribute) (AB_EXTERNAL, attr_bits);
if (attr->intrinsic)
MIO_NAME (ab_attribute) (AB_POINTER_COMP, attr_bits);
if (attr->private_comp)
MIO_NAME (ab_attribute) (AB_PRIVATE_COMP, attr_bits);
+ if (attr->coarray_comp)
+ MIO_NAME (ab_attribute) (AB_COARRAY_COMP, attr_bits);
if (attr->zero_comp)
MIO_NAME (ab_attribute) (AB_ZERO_COMP, attr_bits);
if (attr->is_class)
MIO_NAME (ab_attribute) (AB_PROCEDURE, attr_bits);
if (attr->proc_pointer)
MIO_NAME (ab_attribute) (AB_PROC_POINTER, attr_bits);
+ if (attr->vtype)
+ MIO_NAME (ab_attribute) (AB_VTYPE, attr_bits);
+ if (attr->vtab)
+ MIO_NAME (ab_attribute) (AB_VTAB, attr_bits);
mio_rparen ();
case AB_ALLOCATABLE:
attr->allocatable = 1;
break;
+ case AB_ASYNCHRONOUS:
+ attr->asynchronous = 1;
+ break;
case AB_DIMENSION:
attr->dimension = 1;
break;
+ case AB_CODIMENSION:
+ attr->codimension = 1;
+ break;
case AB_EXTERNAL:
attr->external = 1;
break;
case AB_ALLOC_COMP:
attr->alloc_comp = 1;
break;
+ case AB_COARRAY_COMP:
+ attr->coarray_comp = 1;
+ break;
case AB_POINTER_COMP:
attr->pointer_comp = 1;
break;
case AB_PROC_POINTER:
attr->proc_pointer = 1;
break;
+ case AB_VTYPE:
+ attr->vtype = 1;
+ break;
+ case AB_VTAB:
+ attr->vtab = 1;
+ break;
}
}
}
}
mio_integer (&as->rank);
+ mio_integer (&as->corank);
as->type = MIO_NAME (array_type) (as->type, array_spec_types);
- for (i = 0; i < as->rank; i++)
+ for (i = 0; i < as->rank + as->corank; i++)
{
mio_expr (&as->lower[i]);
mio_expr (&as->upper[i]);
static void
-mio_constructor (gfc_constructor **cp)
+mio_constructor (gfc_constructor_base *cp)
{
- gfc_constructor *c, *tail;
+ gfc_constructor *c;
mio_lparen ();
if (iomode == IO_OUTPUT)
{
- for (c = *cp; c; c = c->next)
+ for (c = gfc_constructor_first (*cp); c; c = gfc_constructor_next (c))
{
mio_lparen ();
mio_expr (&c->expr);
}
else
{
- *cp = NULL;
- tail = NULL;
-
while (peek_atom () != ATOM_RPAREN)
{
- c = gfc_get_constructor ();
-
- if (tail == NULL)
- *cp = c;
- else
- tail->next = c;
-
- tail = c;
+ c = gfc_constructor_append_expr (cp, NULL, NULL);
mio_lparen ();
mio_expr (&c->expr);
}
else if (e->expr_type == EXPR_FUNCTION && e->value.function.name)
{
+ gfc_symbol *sym;
+
/* In some circumstances, a function used in an initialization
expression, in one use associated module, can fail to be
coupled to its symtree when used in a specification
fname = e->value.function.esym ? e->value.function.esym->name
: e->value.function.isym->name;
e->symtree = gfc_find_symtree (gfc_current_ns->sym_root, fname);
+
+ if (e->symtree)
+ return;
+
+ /* This is probably a reference to a private procedure from another
+ module. To prevent a segfault, make a generic with no specific
+ instances. If this module is used, without the required
+ specific coming from somewhere, the appropriate error message
+ is issued. */
+ gfc_get_symbol (fname, gfc_current_ns, &sym);
+ sym->attr.flavor = FL_PROCEDURE;
+ sym->attr.generic = 1;
+ e->symtree = gfc_find_symtree (gfc_current_ns->sym_root, fname);
}
}
else
while (peek_atom () != ATOM_RPAREN)
{
- gfc_intrinsic_op op = 0; /* Silence GCC. */
+ gfc_intrinsic_op op = GFC_INTRINSIC_BEGIN; /* Silence GCC. */
mio_lparen ();
mio_intrinsic_op (&op);
const char *p;
char name[GFC_MAX_SYMBOL_LEN + 1], module[GFC_MAX_SYMBOL_LEN + 1];
gfc_symbol *sym;
- gfc_interface *generic = NULL;
+ gfc_interface *generic = NULL, *gen = NULL;
int n, i, renamed;
+ bool ambiguous_set = false;
mio_lparen ();
sym = st->n.sym;
if (st && !sym->attr.generic
+ && !st->ambiguous
&& sym->module
&& strcmp(module, sym->module))
- st->ambiguous = 1;
+ {
+ ambiguous_set = true;
+ st->ambiguous = 1;
+ }
}
sym->attr.use_only = only_flag;
sym->generic = generic;
sym->attr.generic_copy = 1;
}
+
+ /* If a procedure that is not generic has generic interfaces
+ that include itself, it is generic! We need to take care
+ to retain symbols ambiguous that were already so. */
+ if (sym->attr.use_assoc
+ && !sym->attr.generic
+ && sym->attr.flavor == FL_PROCEDURE)
+ {
+ for (gen = generic; gen; gen = gen->next)
+ {
+ if (gen->sym == sym)
+ {
+ sym->attr.generic = 1;
+ if (ambiguous_set)
+ st->ambiguous = 0;
+ break;
+ }
+ }
+ }
+
}
}
if (st_sym == rsym)
return false;
+ if (st_sym->attr.vtab || st_sym->attr.vtype)
+ return false;
+
/* If the existing symbol is generic from a different module and
the new symbol is generic there can be no ambiguity. */
if (st_sym->attr.generic
module_name);
}
- gfc_check_interfaces (gfc_current_ns);
-
/* Now we should be in a position to fill f2k_derived with derived type
extensions, since everything has been loaded. */
set_module_locus (&extensions);
sym->attr.flavor = FL_PARAMETER;
sym->ts.type = BT_INTEGER;
sym->ts.kind = gfc_default_integer_kind;
- sym->value = gfc_int_expr (value);
+ sym->value = gfc_get_int_expr (gfc_default_integer_kind, NULL, value);
sym->attr.use_assoc = 1;
sym->from_intmod = module;
sym->intmod_sym_id = id;
gfc_option.flag_default_integer
? "-fdefault-integer-8" : "-fdefault-real-8");
+ if (gfc_notify_std (symbol[i].standard, "The symbol '%s', referrenced "
+ "at %C, is not in the selected standard",
+ symbol[i].name) == FAILURE)
+ continue;
+
create_int_parameter (u->local_name[0] ? u->local_name
: symbol[i].name,
symbol[i].value, mod, INTMOD_ISO_FORTRAN_ENV,
for (i = 0; symbol[i].name; i++)
{
local_name = NULL;
+
+ if ((gfc_option.allow_std & symbol[i].standard) == 0)
+ break;
+
for (u = gfc_rename_list; u; u = u->next)
{
if (strcmp (symbol[i].name, u->use_name) == 0)
}
}
+ if (u && gfc_notify_std (symbol[i].standard, "The symbol '%s', "
+ "referrenced at %C, is not in the selected "
+ "standard", symbol[i].name) == FAILURE)
+ continue;
+ else if ((gfc_option.allow_std & symbol[i].standard) == 0)
+ continue;
+
if ((gfc_option.flag_default_integer || gfc_option.flag_default_real)
&& symbol[i].id == ISOFORTRANENV_NUMERIC_STORAGE_SIZE)
gfc_warning_now ("Use of the NUMERIC_STORAGE_SIZE named constant "
if (strcmp (atom_string, MOD_VERSION))
{
- gfc_fatal_error ("Wrong module version '%s' (expected '"
- MOD_VERSION "') for file '%s' opened"
- " at %C", atom_string, filename);
+ gfc_fatal_error ("Wrong module version '%s' (expected '%s') "
+ "for file '%s' opened at %C", atom_string,
+ MOD_VERSION, filename);
}
}