1987-04-29 10:22:07 +00:00
|
|
|
/*
|
|
|
|
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
|
|
|
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
|
|
|
*
|
|
|
|
* Author: Ceriel J.H. Jacobs
|
|
|
|
*/
|
|
|
|
|
1986-06-10 13:18:52 +00:00
|
|
|
/* H I G H L E V E L S Y M B O L E N T R Y */
|
1986-03-26 17:53:13 +00:00
|
|
|
|
1994-06-24 14:02:31 +00:00
|
|
|
/* $Id$ */
|
1987-04-29 10:22:07 +00:00
|
|
|
|
2006-07-30 23:40:35 +00:00
|
|
|
#include <stdlib.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
2013-05-14 21:24:38 +00:00
|
|
|
#include "parameters.h"
|
1986-05-01 19:06:53 +00:00
|
|
|
#include "debug.h"
|
1986-03-26 17:53:13 +00:00
|
|
|
|
2006-07-30 23:40:35 +00:00
|
|
|
#include "alloc.h"
|
|
|
|
#include "em_arith.h"
|
|
|
|
#include "em_label.h"
|
|
|
|
#include "em_code.h"
|
|
|
|
#include "assert.h"
|
1986-05-01 19:06:53 +00:00
|
|
|
|
2019-03-01 17:39:25 +00:00
|
|
|
#include "enter.h"
|
1986-03-26 17:53:13 +00:00
|
|
|
#include "idf.h"
|
1987-07-30 13:37:39 +00:00
|
|
|
#include "LLlex.h"
|
1986-03-26 17:53:13 +00:00
|
|
|
#include "def.h"
|
|
|
|
#include "type.h"
|
2019-03-01 17:39:25 +00:00
|
|
|
#include "error.h"
|
1986-03-26 17:53:13 +00:00
|
|
|
#include "scope.h"
|
1986-04-06 17:42:56 +00:00
|
|
|
#include "node.h"
|
2019-03-01 17:39:25 +00:00
|
|
|
#include "stab.h"
|
1986-04-18 17:53:47 +00:00
|
|
|
#include "main.h"
|
2019-03-01 17:39:25 +00:00
|
|
|
#include "lookup.h"
|
1986-12-01 10:06:53 +00:00
|
|
|
#include "misc.h"
|
1987-07-22 10:59:24 +00:00
|
|
|
#include "f_info.h"
|
1986-03-26 17:53:13 +00:00
|
|
|
|
2019-03-01 17:39:25 +00:00
|
|
|
|
2019-05-10 17:09:03 +00:00
|
|
|
static struct def *DoImport(register struct def *, struct scope *, int);
|
2019-03-01 17:39:25 +00:00
|
|
|
|
2019-05-10 17:09:03 +00:00
|
|
|
struct def *Enter(char *name, int kind, struct type *type, int pnam)
|
1986-03-26 17:53:13 +00:00
|
|
|
{
|
1986-04-07 17:40:38 +00:00
|
|
|
/* Enter a definition for "name" with kind "kind" and type
|
|
|
|
"type" in the Current Scope. If it is a standard name, also
|
|
|
|
put its number in the definition structure.
|
|
|
|
*/
|
2019-05-10 17:09:03 +00:00
|
|
|
register struct def *df;
|
1986-03-26 17:53:13 +00:00
|
|
|
|
1986-06-10 13:18:52 +00:00
|
|
|
df = define(str2idf(name, 0), CurrentScope, kind);
|
1986-03-26 17:53:13 +00:00
|
|
|
df->df_type = type;
|
1986-06-10 13:18:52 +00:00
|
|
|
if (pnam) df->df_value.df_stdname = pnam;
|
1991-02-18 17:18:36 +00:00
|
|
|
#ifdef DBSYMTAB
|
1990-07-30 15:56:25 +00:00
|
|
|
else if (options['g']) stb_string(df, kind);
|
1991-02-18 17:18:36 +00:00
|
|
|
#endif /* DBSYMTAB */
|
1986-03-26 22:46:48 +00:00
|
|
|
return df;
|
|
|
|
}
|
|
|
|
|
2019-05-10 17:09:03 +00:00
|
|
|
struct def *EnterType(char *name, struct type *type)
|
1987-05-21 09:37:28 +00:00
|
|
|
{
|
|
|
|
/* Enter a type definition for "name" and type
|
|
|
|
"type" in the Current Scope.
|
|
|
|
*/
|
|
|
|
|
1990-07-30 15:56:25 +00:00
|
|
|
return Enter(name, D_TYPE, type, 0);
|
1987-05-21 09:37:28 +00:00
|
|
|
}
|
|
|
|
|
2019-05-10 17:09:03 +00:00
|
|
|
void EnterEnumList(struct node *Idlist, register struct type *type)
|
1986-03-26 22:46:48 +00:00
|
|
|
{
|
1986-06-10 13:18:52 +00:00
|
|
|
/* Put a list of enumeration literals in the symbol table.
|
|
|
|
They all have type "type".
|
|
|
|
Also assign numbers to them, and link them together.
|
|
|
|
We must link them together because an enumeration type may
|
|
|
|
be exported, in which case its literals must also be exported.
|
|
|
|
Thus, we need an easy way to get to them.
|
1986-04-07 17:40:38 +00:00
|
|
|
*/
|
2019-05-10 17:09:03 +00:00
|
|
|
register struct def *df, *df1 = 0;
|
|
|
|
register struct node *idlist = Idlist;
|
1986-03-26 22:46:48 +00:00
|
|
|
|
1986-06-10 13:18:52 +00:00
|
|
|
type->enm_ncst = 0;
|
1991-03-12 16:52:00 +00:00
|
|
|
for (; idlist; idlist = idlist->nd_NEXT) {
|
1986-06-10 13:18:52 +00:00
|
|
|
df = define(idlist->nd_IDF, CurrentScope, D_ENUM);
|
1986-03-26 22:46:48 +00:00
|
|
|
df->df_type = type;
|
1986-06-10 13:18:52 +00:00
|
|
|
df->enm_val = (type->enm_ncst)++;
|
1990-07-30 15:56:25 +00:00
|
|
|
if (! df1) {
|
|
|
|
type->enm_enums = df;
|
|
|
|
}
|
|
|
|
else df1->enm_next = df;
|
|
|
|
df1 = df;
|
1986-06-10 13:18:52 +00:00
|
|
|
}
|
|
|
|
FreeNode(Idlist);
|
|
|
|
}
|
1986-05-21 18:32:20 +00:00
|
|
|
|
2019-05-10 17:09:03 +00:00
|
|
|
void EnterFieldList(struct node *Idlist, register struct type *type, struct scope *scope,
|
2019-03-01 17:39:25 +00:00
|
|
|
arith *addr)
|
1986-06-10 13:18:52 +00:00
|
|
|
{
|
|
|
|
/* Put a list of fields in the symbol table.
|
|
|
|
They all have type "type", and are put in scope "scope".
|
|
|
|
Mark them as QUALIFIED EXPORT, because that's exactly what
|
|
|
|
fields are, you can get to them by qualifying them.
|
|
|
|
*/
|
2019-05-10 17:09:03 +00:00
|
|
|
register struct def *df;
|
|
|
|
register struct node *idlist = Idlist;
|
1986-04-22 22:36:16 +00:00
|
|
|
|
1991-03-12 16:52:00 +00:00
|
|
|
for (; idlist; idlist = idlist->nd_NEXT) {
|
1986-06-10 13:18:52 +00:00
|
|
|
df = define(idlist->nd_IDF, scope, D_FIELD);
|
|
|
|
df->df_type = type;
|
|
|
|
df->df_flags |= D_QEXPORTED;
|
|
|
|
df->fld_off = align(*addr, type->tp_align);
|
|
|
|
*addr = df->fld_off + type->tp_size;
|
1986-03-27 17:37:41 +00:00
|
|
|
}
|
1986-06-10 13:18:52 +00:00
|
|
|
FreeNode(Idlist);
|
1986-03-27 17:37:41 +00:00
|
|
|
}
|
|
|
|
|
2019-05-10 17:09:03 +00:00
|
|
|
void EnterVarList(struct node *Idlist, struct type *type, int local)
|
1986-04-15 17:51:53 +00:00
|
|
|
{
|
2019-05-10 17:09:03 +00:00
|
|
|
register struct def *df;
|
|
|
|
register struct node *idlist = Idlist;
|
|
|
|
register struct scopelist *sc = CurrVis;
|
1986-04-21 17:27:06 +00:00
|
|
|
char buf[256];
|
1986-06-06 02:22:09 +00:00
|
|
|
extern char *sprint();
|
1986-04-15 17:51:53 +00:00
|
|
|
|
|
|
|
if (local) {
|
|
|
|
/* Find the closest enclosing open scope. This
|
|
|
|
is the procedure that we are dealing with
|
|
|
|
*/
|
1986-04-28 18:06:58 +00:00
|
|
|
while (sc->sc_scope->sc_scopeclosed) sc = enclosing(sc);
|
1986-04-15 17:51:53 +00:00
|
|
|
}
|
|
|
|
|
1991-03-12 16:52:00 +00:00
|
|
|
for (; idlist; idlist = idlist->nd_RIGHT) {
|
|
|
|
df = define(idlist->nd_LEFT->nd_IDF, CurrentScope, D_VARIABLE);
|
1986-04-15 17:51:53 +00:00
|
|
|
df->df_type = type;
|
1991-03-12 16:52:00 +00:00
|
|
|
if (idlist->nd_LEFT->nd_NEXT) {
|
1986-04-21 17:27:06 +00:00
|
|
|
/* An address was supplied
|
|
|
|
*/
|
2019-05-10 17:09:03 +00:00
|
|
|
register struct type *tp = idlist->nd_LEFT->nd_NEXT->nd_type;
|
1986-11-28 11:59:08 +00:00
|
|
|
|
1987-06-29 12:46:00 +00:00
|
|
|
df->df_flags |= D_ADDRGIVEN | D_NOREG;
|
1986-11-28 11:59:08 +00:00
|
|
|
if (tp != error_type && !(tp->tp_fund & T_CARDINAL)){
|
1991-03-12 16:52:00 +00:00
|
|
|
node_error(idlist->nd_LEFT->nd_NEXT,
|
1986-11-05 14:33:00 +00:00
|
|
|
"illegal type for address");
|
1986-04-15 17:51:53 +00:00
|
|
|
}
|
1991-03-12 16:52:00 +00:00
|
|
|
df->var_off = idlist->nd_LEFT->nd_NEXT->nd_INT;
|
1986-04-15 17:51:53 +00:00
|
|
|
}
|
|
|
|
else if (local) {
|
1986-04-22 22:36:16 +00:00
|
|
|
/* subtract aligned size of variable to the offset,
|
|
|
|
as the variable list exists only local to a
|
|
|
|
procedure
|
1986-04-15 17:51:53 +00:00
|
|
|
*/
|
1986-04-28 18:06:58 +00:00
|
|
|
sc->sc_scope->sc_off =
|
1986-06-10 13:18:52 +00:00
|
|
|
-WA(align(type->tp_size - sc->sc_scope->sc_off,
|
|
|
|
type->tp_align));
|
1986-04-28 18:06:58 +00:00
|
|
|
df->var_off = sc->sc_scope->sc_off;
|
1986-04-15 17:51:53 +00:00
|
|
|
}
|
1986-04-21 17:27:06 +00:00
|
|
|
else {
|
1986-04-22 22:36:16 +00:00
|
|
|
/* Global name, possibly external
|
|
|
|
*/
|
1987-04-29 10:22:07 +00:00
|
|
|
if (sc->sc_scope->sc_definedby->df_flags & D_FOREIGN) {
|
|
|
|
df->var_name = df->df_idf->id_text;
|
|
|
|
}
|
|
|
|
else {
|
1988-03-23 17:44:25 +00:00
|
|
|
sprint(buf,"%s_%s", sc->sc_scope->sc_name,
|
1986-04-21 17:27:06 +00:00
|
|
|
df->df_idf->id_text);
|
1987-04-29 10:22:07 +00:00
|
|
|
df->var_name = Salloc(buf,
|
|
|
|
(unsigned)(strlen(buf)+1));
|
|
|
|
}
|
1986-06-17 12:04:05 +00:00
|
|
|
df->df_flags |= D_NOREG;
|
1986-05-16 17:15:36 +00:00
|
|
|
|
1986-04-21 17:27:06 +00:00
|
|
|
if (DefinitionModule) {
|
1987-10-19 11:28:37 +00:00
|
|
|
df->df_flags |= D_USED | D_DEFINED;
|
1986-06-17 12:04:05 +00:00
|
|
|
if (sc == Defined->mod_vis) {
|
|
|
|
C_exa_dnam(df->var_name);
|
|
|
|
}
|
1986-04-21 17:27:06 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
C_ina_dnam(df->var_name);
|
|
|
|
}
|
1986-04-18 17:53:47 +00:00
|
|
|
}
|
1986-06-10 13:18:52 +00:00
|
|
|
}
|
|
|
|
FreeNode(Idlist);
|
|
|
|
}
|
|
|
|
|
2019-05-10 17:09:03 +00:00
|
|
|
void EnterParamList(struct paramlist **ppr,
|
|
|
|
struct node *Idlist,
|
|
|
|
struct type *type,
|
2019-03-01 17:39:25 +00:00
|
|
|
int VARp,
|
|
|
|
arith *off)
|
1986-06-10 13:18:52 +00:00
|
|
|
{
|
2019-05-10 17:09:03 +00:00
|
|
|
register struct paramlist *pr;
|
|
|
|
register struct def *df;
|
|
|
|
register struct node *idlist = Idlist;
|
|
|
|
struct node *dummy = 0;
|
|
|
|
static struct paramlist *last;
|
1986-06-10 13:18:52 +00:00
|
|
|
|
1986-08-26 14:33:24 +00:00
|
|
|
if (! idlist) {
|
1986-09-25 19:39:06 +00:00
|
|
|
/* Can only happen when a procedure type is defined */
|
1987-08-10 21:43:47 +00:00
|
|
|
dummy = Idlist = idlist = dot2leaf(Name);
|
1986-08-26 14:33:24 +00:00
|
|
|
}
|
1991-03-12 16:52:00 +00:00
|
|
|
for ( ; idlist; idlist = idlist->nd_NEXT) {
|
1986-06-10 13:18:52 +00:00
|
|
|
pr = new_paramlist();
|
1987-07-16 19:51:40 +00:00
|
|
|
pr->par_next = 0;
|
1986-10-06 20:36:30 +00:00
|
|
|
if (!*ppr) *ppr = pr;
|
1987-07-16 19:51:40 +00:00
|
|
|
else last->par_next = pr;
|
1986-06-17 12:04:05 +00:00
|
|
|
last = pr;
|
1986-09-25 19:39:06 +00:00
|
|
|
if (!DefinitionModule && idlist != dummy) {
|
1986-08-26 14:33:24 +00:00
|
|
|
df = define(idlist->nd_IDF, CurrentScope, D_VARIABLE);
|
|
|
|
df->var_off = *off;
|
|
|
|
}
|
1986-10-06 20:36:30 +00:00
|
|
|
else df = new_def();
|
1986-06-10 13:18:52 +00:00
|
|
|
pr->par_def = df;
|
|
|
|
df->df_type = type;
|
1989-03-13 15:04:05 +00:00
|
|
|
df->df_flags |= VARp;
|
1986-08-26 14:33:24 +00:00
|
|
|
|
1986-06-10 13:18:52 +00:00
|
|
|
if (IsConformantArray(type)) {
|
1990-07-30 15:56:25 +00:00
|
|
|
/* we need room for the base address and a descriptor:
|
|
|
|
arr_low and arr_high are set to their offset
|
1986-06-10 13:18:52 +00:00
|
|
|
*/
|
1990-07-30 15:56:25 +00:00
|
|
|
type->arr_low = *off + pointer_size;
|
|
|
|
type->arr_high = *off + pointer_size + word_size;
|
1989-03-13 15:04:05 +00:00
|
|
|
*off += pointer_size + word_size + dword_size;
|
1986-06-10 13:18:52 +00:00
|
|
|
}
|
1991-03-13 13:49:56 +00:00
|
|
|
else if (VARp == D_VARPAR) {
|
1986-06-10 13:18:52 +00:00
|
|
|
*off += pointer_size;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
*off += WA(type->tp_size);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
FreeNode(Idlist);
|
|
|
|
}
|
1986-05-16 17:15:36 +00:00
|
|
|
|
1988-06-30 14:50:30 +00:00
|
|
|
|
2019-05-10 17:09:03 +00:00
|
|
|
static void ImportEffects(register struct def *idef, struct scope *scope, int flag)
|
1986-06-10 13:18:52 +00:00
|
|
|
{
|
1988-06-30 14:50:30 +00:00
|
|
|
/* Handle side effects of an import:
|
|
|
|
- a module could have unqualified exports ???
|
|
|
|
- importing an enumeration type also imports literals
|
1986-06-10 13:18:52 +00:00
|
|
|
*/
|
2019-05-10 17:09:03 +00:00
|
|
|
register struct def *df = idef;
|
|
|
|
register struct type *tp;
|
1986-06-10 13:18:52 +00:00
|
|
|
|
1995-05-02 12:23:28 +00:00
|
|
|
while ((df->df_kind & D_IMPORTED) && df->imp_def != df) {
|
|
|
|
/* The second condition could occur on some (erroneous and
|
|
|
|
obscure) input such as:
|
|
|
|
IMPLEMENTATION MODULE Test;
|
|
|
|
FROM X IMPORT XType, XType;
|
|
|
|
END Test.
|
|
|
|
when X does not exist.
|
|
|
|
*/
|
|
|
|
|
1987-10-19 11:28:37 +00:00
|
|
|
df = df->imp_def;
|
|
|
|
}
|
|
|
|
|
1988-06-30 14:50:30 +00:00
|
|
|
tp = BaseType(df->df_type);
|
1988-11-15 14:45:59 +00:00
|
|
|
if (df->df_kind == D_TYPE && tp->tp_fund == T_ENUMERATION) {
|
1986-06-10 13:18:52 +00:00
|
|
|
/* Also import all enumeration literals
|
|
|
|
*/
|
1988-06-30 14:50:30 +00:00
|
|
|
for (df = tp->enm_enums; df; df = df->enm_next) {
|
1989-02-08 10:24:10 +00:00
|
|
|
/* But be careful; we could have a situation where f.i.
|
|
|
|
different subrange types of the enumeration type
|
|
|
|
are imported. If the literal is already imported
|
|
|
|
in some way, don't do it again; we don't want
|
|
|
|
a multiple defined error message here.
|
|
|
|
*/
|
2019-05-10 17:09:03 +00:00
|
|
|
struct def *df1;
|
1989-02-08 10:24:10 +00:00
|
|
|
|
1988-07-05 19:06:40 +00:00
|
|
|
df->df_flags |= D_QEXPORTED;
|
1989-02-08 10:24:10 +00:00
|
|
|
if ((!(df1 = lookup(df->df_idf, scope, D_IMPORT, 0)) ||
|
|
|
|
df1 != df) &&
|
|
|
|
! DoImport(df, scope, flag|D_USED)) assert(0);
|
1988-06-30 14:50:30 +00:00
|
|
|
/* don't complain when not used ... */
|
1986-06-10 13:18:52 +00:00
|
|
|
}
|
1987-10-27 09:45:27 +00:00
|
|
|
idef->df_flags |= D_USED; /* don't complain ... */
|
1986-06-10 13:18:52 +00:00
|
|
|
}
|
|
|
|
else if (df->df_kind == D_MODULE) {
|
1986-11-28 11:59:08 +00:00
|
|
|
if (df->mod_vis == CurrVis) {
|
|
|
|
error("cannot import current module \"%s\"",
|
|
|
|
df->df_idf->id_text);
|
1988-06-30 14:50:30 +00:00
|
|
|
return;
|
1986-11-28 11:59:08 +00:00
|
|
|
}
|
1988-06-30 14:50:30 +00:00
|
|
|
if (df->df_scope == GlobalScope) return;
|
|
|
|
/* Also import all definitions that are exported from this
|
|
|
|
module
|
|
|
|
*/
|
1986-09-25 19:39:06 +00:00
|
|
|
for (df = df->mod_vis->sc_scope->sc_def;
|
|
|
|
df;
|
|
|
|
df = df->df_nextinscope) {
|
1986-06-10 13:18:52 +00:00
|
|
|
if (df->df_flags & D_EXPORTED) {
|
1988-06-30 14:50:30 +00:00
|
|
|
if (!DoImport(df, scope, D_IMP_BY_EXP|D_USED)){
|
|
|
|
assert(0);
|
|
|
|
}
|
1987-10-21 11:29:52 +00:00
|
|
|
/* don't complain when these are not used */
|
1986-06-10 13:18:52 +00:00
|
|
|
}
|
|
|
|
}
|
1987-10-27 09:45:27 +00:00
|
|
|
idef->df_flags |= D_USED; /* don't complain ... */
|
1986-04-15 17:51:53 +00:00
|
|
|
}
|
1988-06-30 14:50:30 +00:00
|
|
|
}
|
|
|
|
|
2019-05-10 17:09:03 +00:00
|
|
|
static struct def *DoImport(register struct def *df, struct scope *scope, int flag)
|
1988-06-30 14:50:30 +00:00
|
|
|
{
|
|
|
|
/* Definition "df" is imported to scope "scope".
|
|
|
|
*/
|
2019-05-10 17:09:03 +00:00
|
|
|
register struct def *idef = define(df->df_idf, scope, D_IMPORT);
|
1988-06-30 14:50:30 +00:00
|
|
|
|
|
|
|
idef->imp_def = df;
|
|
|
|
idef->df_flags |= flag;
|
|
|
|
ImportEffects(idef, scope, flag);
|
1987-10-28 11:10:30 +00:00
|
|
|
return idef;
|
1986-04-15 17:51:53 +00:00
|
|
|
}
|
|
|
|
|
1988-06-30 14:50:30 +00:00
|
|
|
|
2019-05-10 17:09:03 +00:00
|
|
|
static void ForwModule(register struct def *df, struct node *nd)
|
1986-06-10 13:18:52 +00:00
|
|
|
{
|
1986-11-05 14:33:00 +00:00
|
|
|
/* An import is done from a not yet defined module "df".
|
|
|
|
We could also end up here for not found DEFINITION MODULES.
|
1986-06-10 13:18:52 +00:00
|
|
|
Create a declaration and a scope for this module.
|
|
|
|
*/
|
2019-05-10 17:09:03 +00:00
|
|
|
register struct scopelist *vis;
|
1986-06-10 13:18:52 +00:00
|
|
|
|
1986-11-05 14:33:00 +00:00
|
|
|
if (df->df_scope != GlobalScope) {
|
|
|
|
df->df_scope = enclosing(CurrVis)->sc_scope;
|
|
|
|
df->df_kind = D_FORWMODULE;
|
|
|
|
}
|
1986-06-10 13:18:52 +00:00
|
|
|
open_scope(CLOSEDSCOPE);
|
|
|
|
vis = CurrVis; /* The new scope, but watch out, it's "sc_encl"
|
|
|
|
field is not set right. It must indicate the
|
|
|
|
enclosing scope, but this must be done AFTER
|
|
|
|
closing this one
|
|
|
|
*/
|
|
|
|
close_scope(0);
|
|
|
|
vis->sc_encl = enclosing(CurrVis);
|
|
|
|
/* Here ! */
|
1986-10-06 20:36:30 +00:00
|
|
|
df->for_vis = vis;
|
1986-11-05 14:33:00 +00:00
|
|
|
df->for_node = nd;
|
1986-06-10 13:18:52 +00:00
|
|
|
}
|
|
|
|
|
2019-05-10 17:09:03 +00:00
|
|
|
static struct def *ForwDef(register struct node *ids, struct scope *scope)
|
1986-03-27 17:37:41 +00:00
|
|
|
{
|
1986-06-10 13:18:52 +00:00
|
|
|
/* Enter a forward definition of "ids" in scope "scope",
|
|
|
|
if it is not already defined.
|
1986-04-02 17:34:21 +00:00
|
|
|
*/
|
2019-05-10 17:09:03 +00:00
|
|
|
register struct def *df;
|
1986-06-10 13:18:52 +00:00
|
|
|
|
1987-10-21 11:29:52 +00:00
|
|
|
if (!(df = lookup(ids->nd_IDF, scope, 0, 0))) {
|
1986-06-10 13:18:52 +00:00
|
|
|
df = define(ids->nd_IDF, scope, D_FORWARD);
|
1991-03-18 16:30:49 +00:00
|
|
|
df->for_node = new_node();
|
|
|
|
*(df->for_node) = *ids;
|
|
|
|
df->for_node->nd_NEXT = 0;
|
1986-03-27 17:37:41 +00:00
|
|
|
}
|
1986-06-10 13:18:52 +00:00
|
|
|
return df;
|
|
|
|
}
|
1986-04-18 17:53:47 +00:00
|
|
|
|
2019-05-10 17:09:03 +00:00
|
|
|
void EnterExportList(struct node *Idlist, int qualified)
|
1986-06-10 13:18:52 +00:00
|
|
|
{
|
2019-05-10 17:09:03 +00:00
|
|
|
register struct node *idlist = Idlist;
|
|
|
|
register struct def *df, *df1;
|
1986-06-10 13:18:52 +00:00
|
|
|
|
1991-03-12 16:52:00 +00:00
|
|
|
for (;idlist; idlist = idlist->nd_NEXT) {
|
1987-10-21 11:29:52 +00:00
|
|
|
df = lookup(idlist->nd_IDF, CurrentScope, 0, 0);
|
1986-06-10 13:18:52 +00:00
|
|
|
|
|
|
|
if (!df) {
|
|
|
|
/* undefined item in export list
|
|
|
|
*/
|
1986-10-06 20:36:30 +00:00
|
|
|
node_error(idlist,
|
|
|
|
"identifier \"%s\" not defined",
|
|
|
|
idlist->nd_IDF->id_text);
|
1986-06-10 13:18:52 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (df->df_flags & (D_EXPORTED|D_QEXPORTED)) {
|
1986-10-06 20:36:30 +00:00
|
|
|
node_error(idlist,
|
|
|
|
"multiple occurrences of \"%s\" in export list",
|
|
|
|
idlist->nd_IDF->id_text);
|
1988-06-30 14:50:30 +00:00
|
|
|
continue;
|
1986-06-10 13:18:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
df->df_flags |= qualified;
|
|
|
|
if (qualified == D_EXPORTED) {
|
|
|
|
/* Export, but not qualified.
|
|
|
|
Find all imports of the module in which this export
|
|
|
|
occurs, and export the current definition to it
|
|
|
|
*/
|
1986-10-06 20:36:30 +00:00
|
|
|
df1 = CurrentScope->sc_definedby->df_idf->id_def;
|
|
|
|
while (df1) {
|
1987-10-21 11:29:52 +00:00
|
|
|
if ((df1->df_kind & D_IMPORTED) &&
|
1986-10-06 20:36:30 +00:00
|
|
|
df1->imp_def == CurrentScope->sc_definedby) {
|
1988-06-30 14:50:30 +00:00
|
|
|
if (! DoImport(df, df1->df_scope, D_IMP_BY_EXP)) assert(0);
|
1986-06-10 13:18:52 +00:00
|
|
|
}
|
1987-07-16 19:51:40 +00:00
|
|
|
df1 = df1->df_next;
|
1986-06-10 13:18:52 +00:00
|
|
|
}
|
|
|
|
/* Also handle the definition as if the enclosing
|
|
|
|
scope imports it.
|
|
|
|
*/
|
|
|
|
df1 = lookup(idlist->nd_IDF,
|
1987-11-11 13:10:08 +00:00
|
|
|
enclosing(CurrVis)->sc_scope,
|
|
|
|
D_IMPORTED,
|
|
|
|
0);
|
1986-06-10 13:18:52 +00:00
|
|
|
if (df1) {
|
|
|
|
/* It was already defined in the enclosing
|
|
|
|
scope. There are two legal possibilities,
|
|
|
|
which are examined below.
|
|
|
|
*/
|
2019-05-10 17:09:03 +00:00
|
|
|
struct def *df2 = df;
|
1987-10-19 11:28:37 +00:00
|
|
|
|
1987-10-21 11:29:52 +00:00
|
|
|
while (df2->df_kind & D_IMPORTED) {
|
1987-10-19 11:28:37 +00:00
|
|
|
df2 = df2->imp_def;
|
|
|
|
}
|
1986-09-25 19:39:06 +00:00
|
|
|
if (df1->df_kind == D_PROCHEAD &&
|
1987-10-19 11:28:37 +00:00
|
|
|
df2->df_kind == D_PROCEDURE) {
|
1987-10-28 11:10:30 +00:00
|
|
|
df1->df_kind = D_IMPORT;
|
|
|
|
df1->df_flags |= D_IMP_BY_EXP;
|
1986-06-10 13:18:52 +00:00
|
|
|
df1->imp_def = df;
|
|
|
|
continue;
|
|
|
|
}
|
1986-09-25 19:39:06 +00:00
|
|
|
if (df1->df_kind == D_HIDDEN &&
|
1988-11-15 14:45:59 +00:00
|
|
|
df2->df_kind == D_TYPE) {
|
1987-10-19 11:28:37 +00:00
|
|
|
DeclareType(idlist, df1, df2->df_type);
|
1986-09-25 19:39:06 +00:00
|
|
|
df1->df_kind = D_TYPE;
|
|
|
|
continue;
|
|
|
|
}
|
1986-06-10 13:18:52 +00:00
|
|
|
}
|
1986-04-18 17:53:47 +00:00
|
|
|
|
1988-06-30 14:50:30 +00:00
|
|
|
if (! DoImport(df,enclosing(CurrVis)->sc_scope,D_IMP_BY_EXP)) assert(0);
|
1986-06-10 13:18:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
FreeNode(Idlist);
|
|
|
|
}
|
|
|
|
|
2019-05-10 17:09:03 +00:00
|
|
|
void CheckForImports(struct def *df)
|
1988-06-30 14:50:30 +00:00
|
|
|
{
|
|
|
|
/* We have a definition for "df"; check all imports of
|
|
|
|
it for side-effects
|
|
|
|
*/
|
2019-05-10 17:09:03 +00:00
|
|
|
register struct def *df1 = df->df_idf->id_def;
|
1988-06-30 14:50:30 +00:00
|
|
|
|
|
|
|
while (df1) {
|
|
|
|
if (df1->df_kind & D_IMPORTED) {
|
2019-05-10 17:09:03 +00:00
|
|
|
register struct def *df2 = df1->imp_def;
|
1988-06-30 14:50:30 +00:00
|
|
|
|
|
|
|
while (df2->df_kind & D_IMPORTED) df2 = df2->imp_def;
|
|
|
|
if (df2 == df) {
|
|
|
|
ImportEffects(df1, df1->df_scope, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
df1 = df1->df_next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-10 17:09:03 +00:00
|
|
|
void EnterFromImportList(struct node *idlist, struct def *FromDef, struct node *FromId)
|
1986-06-10 13:18:52 +00:00
|
|
|
{
|
1986-08-26 14:33:24 +00:00
|
|
|
/* Import the list Idlist from the module indicated by Fromdef.
|
1986-06-10 13:18:52 +00:00
|
|
|
*/
|
2019-05-10 17:09:03 +00:00
|
|
|
struct scope *sc;
|
|
|
|
register struct def *df;
|
1986-12-01 10:06:53 +00:00
|
|
|
char *module_name = FromDef->df_idf->id_text;
|
1986-06-10 13:18:52 +00:00
|
|
|
|
1986-08-26 14:33:24 +00:00
|
|
|
switch(FromDef->df_kind) {
|
|
|
|
case D_ERROR:
|
1988-06-30 14:50:30 +00:00
|
|
|
case D_FORWARD:
|
1986-08-26 14:33:24 +00:00
|
|
|
/* 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.
|
1986-11-05 14:33:00 +00:00
|
|
|
We also end up here if some definition module could not
|
|
|
|
be found.
|
1986-08-26 14:33:24 +00:00
|
|
|
???
|
|
|
|
*/
|
1988-06-30 14:50:30 +00:00
|
|
|
ForwModule(FromDef, FromId);
|
|
|
|
/* Fall through */
|
1986-08-26 14:33:24 +00:00
|
|
|
case D_FORWMODULE:
|
1988-06-30 14:50:30 +00:00
|
|
|
EnterImportList(idlist, 1, FromDef->for_vis->sc_scope);
|
|
|
|
return;
|
1986-08-26 14:33:24 +00:00
|
|
|
case D_MODULE:
|
1988-06-30 14:50:30 +00:00
|
|
|
sc = FromDef->mod_vis->sc_scope;
|
|
|
|
if (sc == CurrentScope) {
|
1986-12-01 10:06:53 +00:00
|
|
|
node_error(FromId, "cannot import from current module \"%s\"", module_name);
|
1986-11-28 11:59:08 +00:00
|
|
|
return;
|
|
|
|
}
|
1986-08-26 14:33:24 +00:00
|
|
|
break;
|
|
|
|
default:
|
1986-12-01 10:06:53 +00:00
|
|
|
node_error(FromId,"identifier \"%s\" does not represent a module",module_name);
|
1986-11-28 11:59:08 +00:00
|
|
|
return;
|
1986-06-10 13:18:52 +00:00
|
|
|
}
|
|
|
|
|
1991-03-12 16:52:00 +00:00
|
|
|
for (; idlist; idlist = idlist->nd_NEXT) {
|
1988-06-30 14:50:30 +00:00
|
|
|
if (! (df = lookup(idlist->nd_IDF, sc, 0, 0))) {
|
1986-12-01 10:06:53 +00:00
|
|
|
if (! is_anon_idf(idlist->nd_IDF)) {
|
|
|
|
node_error(idlist,
|
|
|
|
"identifier \"%s\" not declared in module \"%s\"",
|
|
|
|
idlist->nd_IDF->id_text,
|
|
|
|
module_name);
|
|
|
|
}
|
1988-06-30 14:50:30 +00:00
|
|
|
df = define(idlist->nd_IDF,sc,D_ERROR);
|
1986-06-10 13:18:52 +00:00
|
|
|
}
|
1986-10-06 20:36:30 +00:00
|
|
|
else if (! (df->df_flags & (D_EXPORTED|D_QEXPORTED))) {
|
|
|
|
node_error(idlist,
|
1986-12-01 10:06:53 +00:00
|
|
|
"identifier \"%s\" not exported from module \"%s\"",
|
|
|
|
idlist->nd_IDF->id_text,
|
|
|
|
module_name);
|
1986-06-10 13:18:52 +00:00
|
|
|
df->df_flags |= D_QEXPORTED;
|
|
|
|
}
|
1988-06-30 14:50:30 +00:00
|
|
|
if (! DoImport(df, CurrentScope, 0)) assert(0);
|
1986-06-10 13:18:52 +00:00
|
|
|
}
|
|
|
|
|
1988-06-30 14:50:30 +00:00
|
|
|
FreeNode(FromId);
|
1986-06-10 13:18:52 +00:00
|
|
|
}
|
|
|
|
|
2019-05-10 17:09:03 +00:00
|
|
|
void EnterImportList(struct node *idlist, int local, struct scope *sc)
|
1986-06-10 13:18:52 +00:00
|
|
|
{
|
1988-06-30 14:50:30 +00:00
|
|
|
/* Import "idlist" from scope "sc".
|
1988-02-10 14:06:34 +00:00
|
|
|
If the import is not local, definition modules must be read
|
|
|
|
for "idlist".
|
1986-06-10 13:18:52 +00:00
|
|
|
*/
|
2019-05-10 17:09:03 +00:00
|
|
|
extern struct def *GetDefinitionModule();
|
1987-07-22 10:59:24 +00:00
|
|
|
struct f_info f;
|
|
|
|
|
|
|
|
f = file_info;
|
1986-06-10 13:18:52 +00:00
|
|
|
|
1991-03-12 16:52:00 +00:00
|
|
|
for (; idlist; idlist = idlist->nd_NEXT) {
|
1988-03-21 17:22:26 +00:00
|
|
|
if (! DoImport(local ?
|
1988-02-10 14:06:34 +00:00
|
|
|
ForwDef(idlist, sc) :
|
|
|
|
GetDefinitionModule(idlist->nd_IDF, 1),
|
1988-06-30 14:50:30 +00:00
|
|
|
CurrentScope, 0)) assert(0);
|
1987-07-22 10:59:24 +00:00
|
|
|
file_info = f;
|
1986-06-10 13:18:52 +00:00
|
|
|
}
|
1987-10-19 11:28:37 +00:00
|
|
|
}
|