#include <assert.h>
#include "Lpars.h"
#include "def.h"
+#include "type.h"
#include "idf.h"
#include "misc.h"
#include "main.h"
df->df_kind = kind;
return df;
}
- error("identifier \"%s\" already declared", id->id_text);
+ if (kind != D_ERROR) {
+ error("identifier \"%s\" already declared", id->id_text);
+ }
return df;
}
df = new_def();
while (df) {
if (df->df_scope == scope) {
if (df->df_kind == D_IMPORT) {
- df = lookup(id, df->imp_scopenr);
+ df = df->imp_def;
assert(df != 0);
return df;
- /* ??? But this does damage to the self-
- organizing character of the list
- */
}
if (df1) {
df1->next = df->next;
return 0;
}
-/* From the current scope, the list of identifiers "ids" is
- exported. Note this fact. If the export is not qualified, make
- all the "ids" visible in the enclosing scope by defining them
- in this scope as "imported".
-*/
Export(ids, qualified)
register struct id_list *ids;
{
+ /* From the current scope, the list of identifiers "ids" is
+ exported. Note this fact. If the export is not qualified, make
+ all the "ids" visible in the enclosing scope by defining them
+ in this scope as "imported".
+ */
register struct def *df;
while (ids) {
}
}
-/* "ids" is a list of imported identifiers.
- If "id" is a null-pointer, the identifiers are imported from the
- enclosing scope. Otherwise they are imported from the module
- indicated by "id", ehich must be visible in the enclosing scope.
- An exception must be made for imports of the Compilation Unit.
- This case is indicated by the value 0 of the flag "local".
- In this case, if "id" is a null pointer, the "ids" identifiers
- are all module identifiers. Their Definition Modules must be read.
- Otherwise "id" is a module identifier whose Definition Module must
- be read. "ids" then represents a list of identifiers defined in
- this module.
-*/
Import(ids, id, local)
register struct id_list *ids;
struct idf *id;
{
+ /* "ids" is a list of imported identifiers.
+ If "id" is a null-pointer, the identifiers are imported from the
+ enclosing scope. Otherwise they are imported from the module
+ indicated by "id", ehich must be visible in the enclosing scope.
+ An exception must be made for imports of the Compilation Unit.
+ This case is indicated by the value 0 of the flag "local".
+ In this case, if "id" is a null pointer, the "ids" identifiers
+ are all module identifiers. Their Definition Modules must be
+ read. Otherwise "id" is a module identifier whose Definition
+ Module must be read. "ids" then represents a list of
+ identifiers defined in this module.
+ */
register struct def *df;
int scope;
int kind;
+ int imp_kind;
+#define FROM_MODULE 0
+#define FROM_ENCLOSING 1
struct def *lookfor();
if (local) {
kind = D_IMPORT;
- if (!id) scope = enclosing(currscope)->sc_scope;
+ scope = enclosing(currscope)->sc_scope;
+ if (!id) imp_kind = FROM_ENCLOSING;
else {
- df = lookfor(id, 1);
+ imp_kind = FROM_MODULE;
+ df = lookfor(id, enclosing(currscope), 1);
if (df->df_kind != D_MODULE) {
+ /* enter all "ids" with type D_ERROR */
+ kind = D_ERROR;
if (df->df_kind != D_ERROR) {
error("identifier \"%s\" does not represent a module", id->id_text);
}
- /* enter all "ids" with type D_ERROR */
- kind = D_ERROR;
- scope = enclosing(currscope)->sc_scope;
}
else scope = df->mod_scope;
}
while (ids) {
- df = lookup(ids->id_ptr, scope);
- if (!df) {
- error("identifier \"%s\" not declared",
- ids->id_ptr->id_text);
+ if (imp_kind == FROM_MODULE) {
+ if (!(df = lookup(ids->id_ptr, scope))) {
+error("identifier \"%s\" not declared in qualifying module",
+ids->id_ptr->id_text);
+ df = ill_df;
+ }
+ else
+ if (!(df->df_flags&(D_EXPORTED|D_QEXPORTED))) {
+error("identifier \"%s\" not exported from qualifying module",
+ids->id_ptr->id_text);
+ }
+ }
+ else {
+ df = lookfor(ids->id_ptr, enclosing(currscope), 0);
+ if (df->df_kind == D_ERROR) {
+error("identifier \"%s\" not visible in enclosing scope",
+ids->id_ptr->id_text);
+ }
+ }
+ define(ids->id_ptr, CurrentScope, kind)->imp_def = df;
+ if (df->df_kind == D_TYPE &&
+ df->df_type->tp_fund == ENUMERATION) {
+ /* Also import all enumeration literals */
+ exprt_literals(df->df_type->enm_enums, currscope);
}
- df = define(ids->id_ptr, CurrentScope, D_IMPORT);
- df->imp_scopenr = scope;
ids = ids->next;
}
return;
}
/* ???? */
}
+
+exprt_literals(df, toscope)
+ register struct def *df;
+ register struct scope *toscope;
+{
+ /* A list of enumeration literals is exported. This is implemented
+ as an import from the scope "toscope".
+ */
+ while (df) {
+ define(df->df_idf, toscope->sc_scope, D_IMPORT)->imp_def = df;
+ df = df->enm_next;
+ }
+}
}
}
-/* Look for an identifier in the current visibility range.
- If it is not defined, give an error message, and
- create a dummy definition.
-*/
struct def *
-lookfor(id, give_error)
+lookfor(id, scope, give_error)
struct idf *id;
+ struct scope *scope;
{
- register struct scope *sc = currscope;
+ /* Look for an identifier in the visibility range started by
+ "scope".
+ If it is not defined, give an error message, and
+ create a dummy definition.
+ */
struct def *df;
+ register struct scope *sc = scope;
while (sc) {
df = lookup(id, sc->sc_scope);
sc = nextvisible(sc);
}
if (give_error) error("Identifier \"%s\" not declared", id->id_text);
- return define(id, CurrentScope, D_ERROR);
+ return define(id, scope->sc_scope, D_ERROR);
}