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".
5 /* $Id: stack.c,v 1.10 1994/06/27 08:02:30 ceriel Exp $ */
6 /* S T A C K / U N S T A C K R O U T I N E S */
16 #include "botch_free.h"
28 /* #include <em_reg.h> */
30 extern char options[];
32 static struct stack_level UniversalLevel;
33 struct stack_level *local_level = &UniversalLevel;
34 /* The main reason for having this secondary stacking
35 mechanism besides the linked lists pointed to by the idf's
37 To remove the idf's of a given level, one could scan the
38 hash table and chase down the idf chains; with a hash
39 table size of 100 this is feasible, but with a size of say
40 100000 this becomes painful. Therefore all idf's are also
41 kept in a stack of sets, one set for each level.
44 int level; /* Always equal to local_level->sl_level. */
47 /* A new level is added on top of the identifier stack.
49 register struct stack_level *stl = new_stack_level();
50 register struct stack_level *loclev = local_level;
52 loclev->sl_next = stl;
53 stl->sl_previous = loclev;
54 stl->sl_level = ++level;
55 stl->sl_max_block = loclev->sl_max_block;
64 register struct stack_level *stl;
66 /* The identifier idf is inserted in the stack on level stl,
67 but only if it is not already present at this level.
69 register struct stack_entry *se;
73 if (se->se_idf == idf) return;
77 se = new_stack_entry();
79 /* link it into the stack level */
80 se->next = stl->sl_entry;
88 /* The stack_level corresponding to level lvl is returned.
89 The stack should probably be an array, to be extended with
92 register struct stack_level *stl;
96 stl = &UniversalLevel;
98 while (stl->sl_level != lvl) {
106 /* The top level of the identifier stack is removed.
108 struct stack_level *lastlvl;
112 dumpidftab("before unstackidfs", 0);
116 lint_end_local(local_level);
119 /* The implementation below is more careful than strictly
120 necessary. Optimists may optimize it afterwards.
122 while (local_level->sl_entry) {
123 register struct stack_entry *se = local_level->sl_entry;
124 register struct idf *idf = se->se_idf;
125 register struct def *def;
126 register struct sdef *sdef;
127 register struct tag *tag;
129 /* unlink it from the local stack level */
130 local_level->sl_entry = se->next;
131 free_stack_entry(se);
133 if (level == L_LOCAL && (def = idf->id_label)) {
138 while ((def = idf->id_def) && def->df_level >= level) {
139 /* unlink it from the def list under the idf block */
140 if (def->df_sc == REGISTER || def->df_sc == AUTO)
141 FreeLocal(def->df_address);
142 idf->id_def = def->next;
146 while ( (sdef = idf->id_sdef)
147 && sdef->sd_level >= level
149 /* unlink it from the sdef list under the idf block */
150 idf->id_sdef = sdef->next;
153 while ( (tag = idf->id_tag)
154 && tag->tg_level >= level
156 /* unlink it from the struct list under the idf block */
157 idf->id_tag = tag->next;
161 /* Unlink the local stack level from the stack.
163 lastlvl = local_level;
164 local_level = local_level->sl_previous;
165 if (level >= L_LOCAL) {
166 local_level->sl_max_block = lastlvl->sl_max_block;
168 free_stack_level(lastlvl);
169 local_level->sl_next = (struct stack_level *) 0;
170 level = local_level->sl_level;
174 dumpidftab("after unstackidfs", 0);
180 /* The global level of identifiers is scanned, and final
181 decisions are taken about such issues as
182 extern/static/global and un/initialized.
183 Effects on the code generator: initialised variables
184 have already been encoded while the uninitialised ones
185 are not and have to be encoded at this moment.
187 register struct stack_entry *se = local_level->sl_entry;
190 lint_end_global(local_level);
195 #endif /* GEN_NM_LIST */
198 register struct idf *idf = se->se_idf;
199 register struct def *def = idf->id_def;
202 /* global selectors, etc. */
211 print("\"%s\", %s, %s, %s, %s\n",
213 (def->df_alloc == 0) ? "no alloc" :
214 (def->df_alloc == ALLOC_SEEN) ? "alloc seen" :
215 (def->df_alloc == ALLOC_DONE) ? "alloc done" :
216 "illegal alloc info",
217 symbol2str(def->df_sc),
218 def->df_initialized ? "init" : "no init",
219 def->df_used ? "used" : "not used");
222 if (def->df_sc == STATIC
223 && def->df_type->tp_fund == FUNCTION
224 && !def->df_initialized) {
225 /* orphaned static function */
226 warning("static function %s never defined, %s"
228 , "changed to extern");
232 if (def->df_alloc == ALLOC_SEEN
233 && !def->df_initialized) {
234 /* space must be allocated */
237 if (def->df_sc != STATIC)
238 namelist(idf->id_text); /* may be common */
239 #endif /* GEN_NM_LIST */
240 def->df_alloc = ALLOC_DONE; /* see Note below */
245 df_alloc must be set to ALLOC_DONE because the idf entry
246 may occur several times in the list.
247 The reason for this is that the same name may be used
248 for different purposes on the same level, e.g.
250 is a legal definition and contains 3 defining occurrences
252 Each definition has been entered into the identifier stack.
253 Although only one of them concerns a variable, we meet the
254 s 3 times when scanning the identifier stack.
259 /* A list of potential common names is kept, to be fed to
260 an understanding loader. The list is written to a file
261 the name of which is nmlist. If nmlist == NULL, no name
264 extern char *nmlist; /* BAH! -- main.c */
265 static File *nfp = 0;
269 if (nmlist && sys_open(nmlist, OP_WRITE, &nfp) == 0)
270 fatal("cannot create namelist %s", nmlist);
277 sys_write(nfp, nm, strlen(nm));
278 sys_write(nfp, "\n", 1);
281 #endif /* GEN_NM_LIST */