mods to handle forward references better
This commit is contained in:
parent
fa9e4c5ea3
commit
74c779b81e
|
@ -1137,7 +1137,6 @@ ChkStandard(expp)
|
|||
|
||||
case S_ORD:
|
||||
if (! (left = getarg(&arg, T_NOSUB, 0, edf))) return 0;
|
||||
MkCoercion(&(arg->nd_left), BaseType(left->nd_type));
|
||||
expp->nd_type = card_type;
|
||||
if (arg->nd_left->nd_class == Value) {
|
||||
arg->nd_left->nd_type = card_type;
|
||||
|
|
|
@ -137,7 +137,7 @@ define(id, scope, kind)
|
|||
another one, or we may have found the definition
|
||||
for this module.
|
||||
*/
|
||||
if (kind == D_FORWMODULE) {
|
||||
if (kind & (D_FORWMODULE|D_FORWARD)) {
|
||||
return df;
|
||||
}
|
||||
|
||||
|
@ -168,7 +168,7 @@ define(id, scope, kind)
|
|||
/* A forward reference, for which we may now have
|
||||
found a definition.
|
||||
*/
|
||||
if (kind != D_FORWARD) {
|
||||
if (! (kind & (D_FORWARD | D_FORWMODULE))) {
|
||||
FreeNode(df->for_node);
|
||||
}
|
||||
|
||||
|
@ -179,6 +179,9 @@ define(id, scope, kind)
|
|||
it found an error. Maybe, the user gives a
|
||||
definition after all.
|
||||
*/
|
||||
if (kind & (D_TYPE|D_PROCEDURE|D_CONST)) {
|
||||
df->df_flags = D_DEFINED;
|
||||
}
|
||||
df->df_kind = kind;
|
||||
return df;
|
||||
}
|
||||
|
|
|
@ -233,62 +233,75 @@ EnterParamList(ppr, Idlist, type, VARp, off)
|
|||
FreeNode(Idlist);
|
||||
}
|
||||
|
||||
STATIC t_def *
|
||||
DoImport(df, scope)
|
||||
register t_def *df;
|
||||
STATIC t_def *DoImport();
|
||||
|
||||
ImportEffects(idef, scope, flag)
|
||||
t_def *idef;
|
||||
t_scope *scope;
|
||||
{
|
||||
/* Definition "df" is imported to scope "scope".
|
||||
Handle the case that it is an enumeration type or a module.
|
||||
/* Handle side effects of an import:
|
||||
- a module could have unqualified exports ???
|
||||
- importing an enumeration type also imports literals
|
||||
*/
|
||||
register t_def *idef = define(df->df_idf, scope, D_IMPORT);
|
||||
|
||||
idef->imp_def = df;
|
||||
register t_def *df = idef;
|
||||
register t_type *tp;
|
||||
|
||||
while (df->df_kind & D_IMPORTED) {
|
||||
df = df->imp_def;
|
||||
}
|
||||
|
||||
if (df->df_kind == D_TYPE && df->df_type->tp_fund == T_ENUMERATION) {
|
||||
tp = BaseType(df->df_type);
|
||||
if ((df->df_kind & (D_TYPE|D_FTYPE)) &&
|
||||
tp->tp_fund == T_ENUMERATION) {
|
||||
/* Also import all enumeration literals
|
||||
*/
|
||||
for (df = df->df_type->enm_enums; df; df = df->enm_next) {
|
||||
register t_def *df1 = define(df->df_idf, scope, D_IMPORT);
|
||||
|
||||
df1->imp_def = df;
|
||||
df1->df_flags |= D_USED;/* don't complain when these
|
||||
are not used
|
||||
*/
|
||||
for (df = tp->enm_enums; df; df = df->enm_next) {
|
||||
if (! DoImport(df, scope, flag|D_USED)) assert(0);
|
||||
/* don't complain when not used ... */
|
||||
}
|
||||
idef->df_flags |= D_USED; /* don't complain ... */
|
||||
}
|
||||
else if (df->df_kind == D_MODULE) {
|
||||
/* Also import all definitions that are exported from this
|
||||
module
|
||||
*/
|
||||
if (df->mod_vis == CurrVis) {
|
||||
error("cannot import current module \"%s\"",
|
||||
df->df_idf->id_text);
|
||||
return idef;
|
||||
return;
|
||||
}
|
||||
if (df->df_scope == GlobalScope) return;
|
||||
/* Also import all definitions that are exported from this
|
||||
module
|
||||
*/
|
||||
for (df = df->mod_vis->sc_scope->sc_def;
|
||||
df;
|
||||
df = df->df_nextinscope) {
|
||||
if (df->df_flags & D_EXPORTED) {
|
||||
register t_def *df1 =
|
||||
define(df->df_idf, scope, D_IMPORT);
|
||||
|
||||
df1->imp_def = df;
|
||||
df1->df_flags |= D_USED;
|
||||
if (!DoImport(df, scope, D_IMP_BY_EXP|D_USED)){
|
||||
assert(0);
|
||||
}
|
||||
/* don't complain when these are not used */
|
||||
}
|
||||
}
|
||||
idef->df_flags |= D_USED; /* don't complain ... */
|
||||
}
|
||||
}
|
||||
|
||||
STATIC t_def *
|
||||
DoImport(df, scope, flag)
|
||||
register t_def *df;
|
||||
t_scope *scope;
|
||||
{
|
||||
/* Definition "df" is imported to scope "scope".
|
||||
*/
|
||||
t_def *idef = define(df->df_idf, scope, D_IMPORT);
|
||||
|
||||
idef->imp_def = df;
|
||||
idef->df_flags |= flag;
|
||||
ImportEffects(idef, scope, flag);
|
||||
return idef;
|
||||
}
|
||||
|
||||
STATIC t_scopelist *
|
||||
|
||||
STATIC
|
||||
ForwModule(df, nd)
|
||||
register t_def *df;
|
||||
t_node *nd;
|
||||
|
@ -314,7 +327,6 @@ ForwModule(df, nd)
|
|||
/* Here ! */
|
||||
df->for_vis = vis;
|
||||
df->for_node = nd;
|
||||
return vis;
|
||||
}
|
||||
|
||||
STATIC t_def *
|
||||
|
@ -361,6 +373,7 @@ EnterExportList(Idlist, qualified)
|
|||
node_error(idlist,
|
||||
"multiple occurrences of \"%s\" in export list",
|
||||
idlist->nd_IDF->id_text);
|
||||
continue;
|
||||
}
|
||||
|
||||
df->df_flags |= qualified;
|
||||
|
@ -373,12 +386,10 @@ EnterExportList(Idlist, qualified)
|
|||
while (df1) {
|
||||
if ((df1->df_kind & D_IMPORTED) &&
|
||||
df1->imp_def == CurrentScope->sc_definedby) {
|
||||
DoImport(df, df1->df_scope)->df_flags |=
|
||||
D_IMP_BY_EXP;
|
||||
if (! DoImport(df, df1->df_scope, D_IMP_BY_EXP)) assert(0);
|
||||
}
|
||||
df1 = df1->df_next;
|
||||
}
|
||||
|
||||
/* Also handle the definition as if the enclosing
|
||||
scope imports it.
|
||||
*/
|
||||
|
@ -404,20 +415,40 @@ EnterExportList(Idlist, qualified)
|
|||
continue;
|
||||
}
|
||||
if (df1->df_kind == D_HIDDEN &&
|
||||
df2->df_kind == D_TYPE) {
|
||||
(df2->df_kind & (D_TYPE|D_FTYPE))) {
|
||||
DeclareType(idlist, df1, df2->df_type);
|
||||
df1->df_kind = D_TYPE;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
DoImport(df, enclosing(CurrVis)->sc_scope)->df_flags |=
|
||||
D_IMP_BY_EXP;
|
||||
if (! DoImport(df,enclosing(CurrVis)->sc_scope,D_IMP_BY_EXP)) assert(0);
|
||||
}
|
||||
}
|
||||
FreeNode(Idlist);
|
||||
}
|
||||
|
||||
CheckForImports(df)
|
||||
t_def *df;
|
||||
{
|
||||
/* We have a definition for "df"; check all imports of
|
||||
it for side-effects
|
||||
*/
|
||||
register t_def *df1 = df->df_idf->id_def;
|
||||
|
||||
while (df1) {
|
||||
if (df1->df_kind & D_IMPORTED) {
|
||||
register t_def *df2 = df1->imp_def;
|
||||
|
||||
while (df2->df_kind & D_IMPORTED) df2 = df2->imp_def;
|
||||
if (df2 == df) {
|
||||
ImportEffects(df1, df1->df_scope, 0);
|
||||
}
|
||||
}
|
||||
df1 = df1->df_next;
|
||||
}
|
||||
}
|
||||
|
||||
EnterFromImportList(idlist, FromDef, FromId)
|
||||
register t_node *idlist;
|
||||
register t_def *FromDef;
|
||||
|
@ -425,13 +456,13 @@ EnterFromImportList(idlist, FromDef, FromId)
|
|||
{
|
||||
/* Import the list Idlist from the module indicated by Fromdef.
|
||||
*/
|
||||
register t_scopelist *vis;
|
||||
register t_scope *sc;
|
||||
register t_def *df;
|
||||
char *module_name = FromDef->df_idf->id_text;
|
||||
int forwflag = 0;
|
||||
|
||||
switch(FromDef->df_kind) {
|
||||
case D_ERROR:
|
||||
case D_FORWARD:
|
||||
/* The module from which the import was done
|
||||
is not yet declared. I'm not sure if I must
|
||||
accept this, but for the time being I will.
|
||||
|
@ -439,16 +470,14 @@ EnterFromImportList(idlist, FromDef, FromId)
|
|||
be found.
|
||||
???
|
||||
*/
|
||||
vis = ForwModule(FromDef, FromId);
|
||||
forwflag = 1;
|
||||
break;
|
||||
ForwModule(FromDef, FromId);
|
||||
/* Fall through */
|
||||
case D_FORWMODULE:
|
||||
vis = FromDef->for_vis;
|
||||
forwflag = 1;
|
||||
break;
|
||||
EnterImportList(idlist, 1, FromDef->for_vis->sc_scope);
|
||||
return;
|
||||
case D_MODULE:
|
||||
vis = FromDef->mod_vis;
|
||||
if (vis == CurrVis) {
|
||||
sc = FromDef->mod_vis->sc_scope;
|
||||
if (sc == CurrentScope) {
|
||||
node_error(FromId, "cannot import from current module \"%s\"", module_name);
|
||||
return;
|
||||
}
|
||||
|
@ -459,15 +488,14 @@ node_error(FromId,"identifier \"%s\" does not represent a module",module_name);
|
|||
}
|
||||
|
||||
for (; idlist; idlist = idlist->nd_left) {
|
||||
if (forwflag) df = ForwDef(idlist, vis->sc_scope);
|
||||
else if (! (df = lookup(idlist->nd_IDF, vis->sc_scope, 0, 0))) {
|
||||
if (! (df = lookup(idlist->nd_IDF, sc, 0, 0))) {
|
||||
if (! is_anon_idf(idlist->nd_IDF)) {
|
||||
node_error(idlist,
|
||||
"identifier \"%s\" not declared in module \"%s\"",
|
||||
idlist->nd_IDF->id_text,
|
||||
module_name);
|
||||
}
|
||||
df = define(idlist->nd_IDF,vis->sc_scope,D_ERROR);
|
||||
df = define(idlist->nd_IDF,sc,D_ERROR);
|
||||
}
|
||||
else if (! (df->df_flags & (D_EXPORTED|D_QEXPORTED))) {
|
||||
node_error(idlist,
|
||||
|
@ -476,20 +504,20 @@ node_error(FromId,"identifier \"%s\" does not represent a module",module_name);
|
|||
module_name);
|
||||
df->df_flags |= D_QEXPORTED;
|
||||
}
|
||||
if (! DoImport(df, CurrentScope)) assert(0);
|
||||
if (! DoImport(df, CurrentScope, 0)) assert(0);
|
||||
}
|
||||
|
||||
if (!forwflag) FreeNode(FromId);
|
||||
FreeNode(FromId);
|
||||
}
|
||||
|
||||
EnterImportList(idlist, local)
|
||||
EnterImportList(idlist, local, sc)
|
||||
register t_node *idlist;
|
||||
t_scope *sc;
|
||||
{
|
||||
/* Import "idlist" from the enclosing scope.
|
||||
/* Import "idlist" from scope "sc".
|
||||
If the import is not local, definition modules must be read
|
||||
for "idlist".
|
||||
*/
|
||||
t_scope *sc = enclosing(CurrVis)->sc_scope;
|
||||
extern t_def *GetDefinitionModule();
|
||||
struct f_info f;
|
||||
|
||||
|
@ -499,7 +527,7 @@ EnterImportList(idlist, local)
|
|||
if (! DoImport(local ?
|
||||
ForwDef(idlist, sc) :
|
||||
GetDefinitionModule(idlist->nd_IDF, 1),
|
||||
CurrentScope)) assert(0);
|
||||
CurrentScope, 0)) assert(0);
|
||||
file_info = f;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -116,7 +116,9 @@ import(int local;)
|
|||
{ if (FromId) {
|
||||
EnterFromImportList(ImportList, df, FromId);
|
||||
}
|
||||
else EnterImportList(ImportList, local);
|
||||
else EnterImportList(ImportList,
|
||||
local,
|
||||
enclosing(CurrVis)->sc_scope);
|
||||
FreeNode(ImportList);
|
||||
}
|
||||
;
|
||||
|
|
|
@ -637,7 +637,12 @@ DeclareType(nd, df, tp)
|
|||
df->df_idf->id_text);
|
||||
}
|
||||
}
|
||||
else df->df_type = tp;
|
||||
else {
|
||||
df->df_type = tp;
|
||||
if (BaseType(tp)->tp_fund == T_ENUMERATION) {
|
||||
CheckForImports(df);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
t_type *
|
||||
|
|
Loading…
Reference in a new issue