Pristine Ack-5.5
[Ack-5.5.git] / lang / m2 / comp / enter.c
1 /*
2  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
3  * See the copyright notice in the ACK home directory, in the file "Copyright".
4  *
5  * Author: Ceriel J.H. Jacobs
6  */
7
8 /* H I G H   L E V E L   S Y M B O L   E N T R Y */
9
10 /* $Id: enter.c,v 1.66 1995/05/02 12:23:28 ceriel Exp $ */
11
12 #include        "debug.h"
13
14 #include        <alloc.h>
15 #include        <em_arith.h>
16 #include        <em_label.h>
17 #include        <em_code.h>
18 #include        <assert.h>
19
20 #include        "dbsymtab.h"
21 #include        "idf.h"
22 #include        "LLlex.h"
23 #include        "def.h"
24 #include        "type.h"
25 #include        "scope.h"
26 #include        "node.h"
27 #include        "main.h"
28 #include        "misc.h"
29 #include        "f_info.h"
30
31 t_def *
32 Enter(name, kind, type, pnam)
33         char *name;
34         t_type *type;
35 {
36         /*      Enter a definition for "name" with kind "kind" and type
37                 "type" in the Current Scope. If it is a standard name, also
38                 put its number in the definition structure.
39         */
40         register t_def *df;
41
42         df = define(str2idf(name, 0), CurrentScope, kind);
43         df->df_type = type;
44         if (pnam) df->df_value.df_stdname = pnam;
45 #ifdef DBSYMTAB
46         else if (options['g']) stb_string(df, kind);
47 #endif /* DBSYMTAB */
48         return df;
49 }
50
51 t_def *
52 EnterType(name, type)
53         char *name;
54         t_type *type;
55 {
56         /*      Enter a type definition for "name"  and type
57                 "type" in the Current Scope.
58         */
59
60         return Enter(name, D_TYPE, type, 0);
61 }
62
63 EnterEnumList(Idlist, type)
64         t_node *Idlist;
65         register t_type *type;
66 {
67         /*      Put a list of enumeration literals in the symbol table.
68                 They all have type "type".
69                 Also assign numbers to them, and link them together.
70                 We must link them together because an enumeration type may
71                 be exported, in which case its literals must also be exported.
72                 Thus, we need an easy way to get to them.
73         */
74         register t_def *df, *df1 = 0;
75         register t_node *idlist = Idlist;
76
77         type->enm_ncst = 0;
78         for (; idlist; idlist = idlist->nd_NEXT) {
79                 df = define(idlist->nd_IDF, CurrentScope, D_ENUM);
80                 df->df_type = type;
81                 df->enm_val = (type->enm_ncst)++;
82                 if (! df1) {
83                         type->enm_enums = df;
84                 }
85                 else    df1->enm_next = df;
86                 df1 = df;
87         }
88         FreeNode(Idlist);
89 }
90
91 EnterFieldList(Idlist, type, scope, addr)
92         t_node *Idlist;
93         register t_type *type;
94         t_scope *scope;
95         arith *addr;
96 {
97         /*      Put a list of fields in the symbol table.
98                 They all have type "type", and are put in scope "scope".
99                 Mark them as QUALIFIED EXPORT, because that's exactly what
100                 fields are, you can get to them by qualifying them.
101         */
102         register t_def *df;
103         register t_node *idlist = Idlist;
104
105         for (; idlist; idlist = idlist->nd_NEXT) {
106                 df = define(idlist->nd_IDF, scope, D_FIELD);
107                 df->df_type = type;
108                 df->df_flags |= D_QEXPORTED;
109                 df->fld_off = align(*addr, type->tp_align);
110                 *addr = df->fld_off + type->tp_size;
111         }
112         FreeNode(Idlist);
113 }
114
115 EnterVarList(Idlist, type, local)
116         t_node *Idlist;
117         t_type *type;
118 {
119         /*      Enter a list of identifiers representing variables into the
120                 name list. "type" represents the type of the variables.
121                 "local" is set if the variables are declared local to a
122                 procedure.
123         */
124         register t_def *df;
125         register t_node *idlist = Idlist;
126         register t_scopelist *sc = CurrVis;
127         char buf[256];
128         extern char *sprint();
129
130         if (local) {
131                 /* Find the closest enclosing open scope. This
132                    is the procedure that we are dealing with
133                 */
134                 while (sc->sc_scope->sc_scopeclosed) sc = enclosing(sc);
135         }
136
137         for (; idlist; idlist = idlist->nd_RIGHT) {
138                 df = define(idlist->nd_LEFT->nd_IDF, CurrentScope, D_VARIABLE);
139                 df->df_type = type;
140                 if (idlist->nd_LEFT->nd_NEXT) {
141                         /* An address was supplied
142                         */
143                         register t_type *tp = idlist->nd_LEFT->nd_NEXT->nd_type;
144
145                         df->df_flags |= D_ADDRGIVEN | D_NOREG;
146                         if (tp != error_type && !(tp->tp_fund & T_CARDINAL)){
147                                 node_error(idlist->nd_LEFT->nd_NEXT,
148                                            "illegal type for address");
149                         }
150                         df->var_off = idlist->nd_LEFT->nd_NEXT->nd_INT;
151                 }
152                 else if (local) {
153                         /* subtract aligned size of variable to the offset,
154                            as the variable list exists only local to a
155                            procedure
156                         */
157                         sc->sc_scope->sc_off =
158                                 -WA(align(type->tp_size - sc->sc_scope->sc_off,
159                                                 type->tp_align));
160                         df->var_off = sc->sc_scope->sc_off;
161                 }
162                 else {
163                         /* Global name, possibly external
164                         */
165                         if (sc->sc_scope->sc_definedby->df_flags & D_FOREIGN) {
166                                 df->var_name = df->df_idf->id_text;
167                         }
168                         else {
169                                 sprint(buf,"%s_%s", sc->sc_scope->sc_name,
170                                             df->df_idf->id_text);
171                                 df->var_name = Salloc(buf,
172                                                 (unsigned)(strlen(buf)+1));
173                         }
174                         df->df_flags |= D_NOREG;
175
176                         if (DefinitionModule) {
177                                 df->df_flags |= D_USED | D_DEFINED;
178                                 if (sc == Defined->mod_vis) {
179                                         C_exa_dnam(df->var_name);
180                                 }
181                         }
182                         else {
183                                 C_ina_dnam(df->var_name);
184                         }
185                 }
186         }
187         FreeNode(Idlist);
188 }
189
190 EnterParamList(ppr, Idlist, type, VARp, off)
191         t_param **ppr;
192         t_node *Idlist;
193         t_type *type;
194         int VARp;
195         arith *off;
196 {
197         /*      Create (part of) a parameterlist of a procedure.
198                 "ids" indicates the list of identifiers, "tp" their type, and
199                 "VARp" indicates D_VARPAR or D_VALPAR.
200         */
201         register t_param *pr;
202         register t_def *df;
203         register t_node *idlist = Idlist;
204         t_node *dummy = 0;
205         static t_param *last;
206
207         if (! idlist) {
208                 /* Can only happen when a procedure type is defined */
209                 dummy = Idlist = idlist = dot2leaf(Name);
210         }
211         for ( ; idlist; idlist = idlist->nd_NEXT) {
212                 pr = new_paramlist();
213                 pr->par_next = 0;
214                 if (!*ppr) *ppr = pr;
215                 else    last->par_next = pr;
216                 last = pr;
217                 if (!DefinitionModule && idlist != dummy) {
218                         df = define(idlist->nd_IDF, CurrentScope, D_VARIABLE);
219                         df->var_off = *off;
220                 }
221                 else    df = new_def();
222                 pr->par_def = df;
223                 df->df_type = type;
224                 df->df_flags |= VARp;
225
226                 if (IsConformantArray(type)) {
227                         /* we need room for the base address and a descriptor:
228                            arr_low and arr_high are set to their offset
229                         */
230                         type->arr_low = *off + pointer_size;
231                         type->arr_high = *off + pointer_size + word_size;
232                         *off += pointer_size + word_size + dword_size;
233                 }
234                 else if (VARp == D_VARPAR) {
235                         *off += pointer_size;
236                 }
237                 else {
238                         *off += WA(type->tp_size);
239                 }
240         }
241         FreeNode(Idlist);
242 }
243
244 STATIC t_def *DoImport();
245
246 ImportEffects(idef, scope, flag)
247         register t_def *idef;
248         t_scope *scope;
249 {
250         /*      Handle side effects of an import:
251                 - a module could have unqualified exports ???
252                 - importing an enumeration type also imports literals
253         */
254         register t_def *df = idef;
255         register t_type *tp;
256
257         while ((df->df_kind & D_IMPORTED) && df->imp_def != df) {
258                 /* The second condition could occur on some (erroneous and
259                    obscure) input such as:
260                         IMPLEMENTATION MODULE Test;
261                         FROM X IMPORT XType, XType;
262                         END Test.
263                    when X does not exist.
264                 */
265
266                 df = df->imp_def;
267         }
268
269         tp = BaseType(df->df_type);
270         if (df->df_kind == D_TYPE && tp->tp_fund == T_ENUMERATION) {
271                 /* Also import all enumeration literals
272                 */
273                 for (df = tp->enm_enums; df; df = df->enm_next) {
274                         /* But be careful; we could have a situation where f.i.
275                            different subrange types of the enumeration type
276                            are imported. If the literal is already imported
277                            in some way, don't do it again; we don't want
278                            a multiple defined error message here.
279                         */
280                         t_def *df1;
281
282                         df->df_flags |= D_QEXPORTED;
283                         if ((!(df1 = lookup(df->df_idf, scope, D_IMPORT, 0)) ||
284                              df1 != df) &&
285                             ! DoImport(df, scope, flag|D_USED)) assert(0);
286                                 /* don't complain when not used ... */
287                 }
288                 idef->df_flags |= D_USED;       /* don't complain ... */
289         }
290         else if (df->df_kind == D_MODULE) {
291                 if (df->mod_vis == CurrVis) {
292                         error("cannot import current module \"%s\"",
293                                 df->df_idf->id_text);
294                         return;
295                 }
296                 if (df->df_scope == GlobalScope) return;
297                 /* Also import all definitions that are exported from this
298                    module
299                 */
300                 for (df = df->mod_vis->sc_scope->sc_def;
301                      df;
302                      df = df->df_nextinscope) {
303                         if (df->df_flags & D_EXPORTED) {
304                                 if (!DoImport(df, scope, D_IMP_BY_EXP|D_USED)){
305                                         assert(0);
306                                 }
307                                 /* don't complain when these are not used */
308                         }
309                 }
310                 idef->df_flags |= D_USED;       /* don't complain ... */
311         }
312 }
313
314 STATIC t_def *
315 DoImport(df, scope, flag)
316         register t_def *df;
317         t_scope *scope;
318 {
319         /*      Definition "df" is imported to scope "scope".
320         */
321         register t_def *idef = define(df->df_idf, scope, D_IMPORT);
322
323         idef->imp_def = df;
324         idef->df_flags |= flag;
325         ImportEffects(idef, scope, flag);
326         return idef;
327 }
328
329
330 STATIC
331 ForwModule(df, nd)
332         register t_def *df;
333         t_node *nd;
334 {
335         /*      An import is done from a not yet defined module "df".
336                 We could also end up here for not found DEFINITION MODULES.
337                 Create a declaration and a scope for this module.
338         */
339         register t_scopelist *vis;
340
341         if (df->df_scope != GlobalScope) {
342                 df->df_scope = enclosing(CurrVis)->sc_scope;
343                 df->df_kind = D_FORWMODULE;
344         }
345         open_scope(CLOSEDSCOPE);
346         vis = CurrVis;          /* The new scope, but watch out, it's "sc_encl"
347                                    field is not set right. It must indicate the
348                                    enclosing scope, but this must be done AFTER
349                                    closing this one
350                                 */
351         close_scope(0); 
352         vis->sc_encl = enclosing(CurrVis);
353                                 /* Here ! */
354         df->for_vis = vis;
355         df->for_node = nd;
356 }
357
358 STATIC t_def *
359 ForwDef(ids, scope)
360         register t_node *ids;
361         t_scope *scope;
362 {
363         /*      Enter a forward definition of "ids" in scope "scope",
364                 if it is not already defined.
365         */
366         register t_def *df;
367
368         if (!(df = lookup(ids->nd_IDF, scope, 0, 0))) {
369                 df = define(ids->nd_IDF, scope, D_FORWARD);
370                 df->for_node = new_node();
371                 *(df->for_node) = *ids;
372                 df->for_node->nd_NEXT = 0;
373         }
374         return df;
375 }
376
377 EnterExportList(Idlist, qualified)
378         t_node *Idlist;
379 {
380         /*      From the current scope, the list of identifiers "ids" is
381                 exported. Note this fact. If the export is not qualified, make
382                 all the "ids" visible in the enclosing scope by defining them
383                 in this scope as "imported".
384         */
385         register t_node *idlist = Idlist;
386         register t_def *df, *df1;
387
388         for (;idlist; idlist = idlist->nd_NEXT) {
389                 df = lookup(idlist->nd_IDF, CurrentScope, 0, 0);
390
391                 if (!df) {
392                         /* undefined item in export list
393                         */
394                         node_error(idlist,
395                                    "identifier \"%s\" not defined",
396                                    idlist->nd_IDF->id_text);
397                         continue;
398                 }
399
400                 if (df->df_flags & (D_EXPORTED|D_QEXPORTED)) {
401                         node_error(idlist,
402                                 "multiple occurrences of \"%s\" in export list",
403                                 idlist->nd_IDF->id_text);
404                         continue;
405                 }
406
407                 df->df_flags |= qualified;
408                 if (qualified == D_EXPORTED) {
409                         /* Export, but not qualified.
410                            Find all imports of the module in which this export
411                            occurs, and export the current definition to it
412                         */
413                         df1 = CurrentScope->sc_definedby->df_idf->id_def;
414                         while (df1) {
415                                 if ((df1->df_kind & D_IMPORTED) &&
416                                     df1->imp_def == CurrentScope->sc_definedby) {
417                                         if (! DoImport(df, df1->df_scope, D_IMP_BY_EXP)) assert(0);
418                                 }
419                                 df1 = df1->df_next;
420                         }
421                         /* Also handle the definition as if the enclosing
422                            scope imports it.
423                         */
424                         df1 = lookup(idlist->nd_IDF,
425                                      enclosing(CurrVis)->sc_scope,
426                                      D_IMPORTED,
427                                      0);
428                         if (df1) {
429                                 /* It was already defined in the enclosing
430                                    scope. There are two legal possibilities,
431                                    which are examined below.
432                                 */
433                                 t_def *df2 = df;
434
435                                 while (df2->df_kind & D_IMPORTED) {
436                                         df2 = df2->imp_def;
437                                 }
438                                 if (df1->df_kind == D_PROCHEAD &&
439                                      df2->df_kind == D_PROCEDURE) {
440                                         df1->df_kind = D_IMPORT;
441                                         df1->df_flags |= D_IMP_BY_EXP;
442                                         df1->imp_def = df;
443                                         continue;
444                                 }
445                                 if (df1->df_kind == D_HIDDEN &&
446                                     df2->df_kind == D_TYPE) {
447                                         DeclareType(idlist, df1, df2->df_type);
448                                         df1->df_kind = D_TYPE;
449                                         continue;
450                                 }
451                         }
452
453                         if (! DoImport(df,enclosing(CurrVis)->sc_scope,D_IMP_BY_EXP)) assert(0);
454                 }
455         }
456         FreeNode(Idlist);
457 }
458
459 CheckForImports(df)
460         t_def *df;
461 {
462         /*      We have a definition for "df"; check all imports of
463                 it for side-effects
464         */
465         register t_def *df1 = df->df_idf->id_def;
466
467         while (df1) {
468                 if (df1->df_kind & D_IMPORTED) {
469                         register t_def *df2 = df1->imp_def;
470
471                         while (df2->df_kind & D_IMPORTED) df2 = df2->imp_def;
472                         if (df2 == df) {
473                                 ImportEffects(df1, df1->df_scope, 0);
474                         }
475                 }
476                 df1 = df1->df_next;
477         }
478 }
479
480 EnterFromImportList(idlist, FromDef, FromId)
481         register t_node *idlist;
482         register t_def *FromDef;
483         t_node *FromId;
484 {
485         /*      Import the list Idlist from the module indicated by Fromdef.
486         */
487         t_scope *sc;
488         register t_def *df;
489         char *module_name = FromDef->df_idf->id_text;
490
491         switch(FromDef->df_kind) {
492         case D_ERROR:
493         case D_FORWARD:
494                 /* The module from which the import was done
495                    is not yet declared. I'm not sure if I must
496                    accept this, but for the time being I will.
497                    We also end up here if some definition module could not
498                    be found.
499                    ???
500                 */
501                 ForwModule(FromDef, FromId);
502                 /* Fall through */
503         case D_FORWMODULE:
504                 EnterImportList(idlist, 1, FromDef->for_vis->sc_scope);
505                 return;
506         case D_MODULE:
507                 sc = FromDef->mod_vis->sc_scope;
508                 if (sc == CurrentScope) {
509 node_error(FromId, "cannot import from current module \"%s\"", module_name);
510                         return;
511                 }
512                 break;
513         default:
514 node_error(FromId,"identifier \"%s\" does not represent a module",module_name);
515                 return;
516         }
517
518         for (; idlist; idlist = idlist->nd_NEXT) {
519                 if (! (df = lookup(idlist->nd_IDF, sc, 0, 0))) {
520                         if (! is_anon_idf(idlist->nd_IDF)) {
521                                 node_error(idlist,
522                         "identifier \"%s\" not declared in module \"%s\"",
523                                         idlist->nd_IDF->id_text,
524                                         module_name);
525                         }
526                         df = define(idlist->nd_IDF,sc,D_ERROR);
527                 }
528                 else if (! (df->df_flags & (D_EXPORTED|D_QEXPORTED))) {
529                         node_error(idlist,
530                         "identifier \"%s\" not exported from module \"%s\"",
531                         idlist->nd_IDF->id_text,
532                         module_name);
533                         df->df_flags |= D_QEXPORTED;
534                 }
535                 if (! DoImport(df, CurrentScope, 0)) assert(0);
536         }
537
538         FreeNode(FromId);
539 }
540
541 EnterImportList(idlist, local, sc)
542         register t_node *idlist;
543         t_scope *sc;
544 {
545         /*      Import "idlist" from scope "sc".
546                 If the import is not local, definition modules must be read
547                 for "idlist".
548         */
549         extern t_def *GetDefinitionModule();
550         struct f_info f;
551         
552         f = file_info;
553
554         for (; idlist; idlist = idlist->nd_NEXT) {
555                 if (! DoImport(local ?
556                            ForwDef(idlist, sc) :
557                            GetDefinitionModule(idlist->nd_IDF, 1), 
558                          CurrentScope, 0)) assert(0);
559                 file_info = f;
560         }
561 }