stack.c 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  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. /* $Id$ */
  6. /* S T A C K / U N S T A C K R O U T I N E S */
  7. #include "lint.h"
  8. #include <system.h>
  9. #ifndef LINT
  10. #include <em.h>
  11. #else
  12. #include "l_em.h"
  13. #endif /* LINT */
  14. #include "debug.h"
  15. #include "botch_free.h"
  16. #include <alloc.h>
  17. #include "Lpars.h"
  18. #include "arith.h"
  19. #include "stack.h"
  20. #include "stack_loc.h"
  21. #include "type.h"
  22. #include "idf.h"
  23. #include "idf_loc.h"
  24. #include "def.h"
  25. #include "struct.h"
  26. #include "level.h"
  27. #include "mes.h"
  28. #include "code_c.h"
  29. #include "error.h"
  30. #include "label.h"
  31. #include "util_loc.h"
  32. /* #include <em_reg.h> */
  33. extern char options[];
  34. static struct stack_level UniversalLevel;
  35. struct stack_level *local_level = &UniversalLevel;
  36. /* The main reason for having this secondary stacking
  37. mechanism besides the linked lists pointed to by the idf's
  38. is efficiency.
  39. To remove the idf's of a given level, one could scan the
  40. hash table and chase down the idf chains; with a hash
  41. table size of 100 this is feasible, but with a size of say
  42. 100000 this becomes painful. Therefore all idf's are also
  43. kept in a stack of sets, one set for each level.
  44. */
  45. int level; /* Always equal to local_level->sl_level. */
  46. void stack_level()
  47. {
  48. /* A new level is added on top of the identifier stack.
  49. */
  50. struct stack_level *stl = new_stack_level();
  51. 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;
  56. local_level = stl;
  57. #ifdef LINT
  58. lint_start_local();
  59. #endif /* LINT */
  60. }
  61. void stack_idf(struct idf *idf, struct stack_level *stl)
  62. {
  63. /* The identifier idf is inserted in the stack on level stl,
  64. but only if it is not already present at this level.
  65. */
  66. struct stack_entry *se;
  67. se = stl->sl_entry;
  68. while (se) {
  69. if (se->se_idf == idf) return;
  70. se = se->next;
  71. }
  72. se = new_stack_entry();
  73. /* link it into the stack level */
  74. se->next = stl->sl_entry;
  75. se->se_idf = idf;
  76. stl->sl_entry = se;
  77. }
  78. struct stack_level *stack_level_of(int lvl)
  79. {
  80. /* The stack_level corresponding to level lvl is returned.
  81. The stack should probably be an array, to be extended with
  82. realloc where needed.
  83. */
  84. struct stack_level *stl;
  85. if (lvl == level)
  86. return local_level;
  87. stl = &UniversalLevel;
  88. while (stl->sl_level != lvl) {
  89. stl = stl->sl_next;
  90. }
  91. return stl;
  92. }
  93. void unstack_level()
  94. {
  95. /* The top level of the identifier stack is removed.
  96. */
  97. struct stack_level *lastlvl;
  98. #ifdef DEBUG
  99. if (options['t'])
  100. dumpidftab("before unstackidfs", 0);
  101. #endif /* DEBUG */
  102. #ifdef LINT
  103. lint_end_local(local_level);
  104. #endif /* LINT */
  105. /* The implementation below is more careful than strictly
  106. necessary. Optimists may optimize it afterwards.
  107. */
  108. while (local_level->sl_entry) {
  109. struct stack_entry *se = local_level->sl_entry;
  110. struct idf *idf = se->se_idf;
  111. struct def *def;
  112. struct sdef *sdef;
  113. struct tag *tag;
  114. /* unlink it from the local stack level */
  115. local_level->sl_entry = se->next;
  116. free_stack_entry(se);
  117. if (level == L_LOCAL && (def = idf->id_label)) {
  118. unstack_label(idf);
  119. free_def(def);
  120. idf->id_label = 0;
  121. }
  122. while ((def = idf->id_def) && def->df_level >= level) {
  123. /* unlink it from the def list under the idf block */
  124. if (def->df_sc == REGISTER || def->df_sc == AUTO)
  125. FreeLocal(def->df_address);
  126. idf->id_def = def->next;
  127. free_def(def);
  128. update_ahead(idf);
  129. }
  130. while ( (sdef = idf->id_sdef)
  131. && sdef->sd_level >= level
  132. ) {
  133. /* unlink it from the sdef list under the idf block */
  134. idf->id_sdef = sdef->next;
  135. free_sdef(sdef);
  136. }
  137. while ( (tag = idf->id_tag)
  138. && tag->tg_level >= level
  139. ) {
  140. /* unlink it from the struct list under the idf block */
  141. idf->id_tag = tag->next;
  142. free_tag(tag);
  143. }
  144. }
  145. /* Unlink the local stack level from the stack.
  146. */
  147. lastlvl = local_level;
  148. local_level = local_level->sl_previous;
  149. if (level >= L_LOCAL) {
  150. local_level->sl_max_block = lastlvl->sl_max_block;
  151. }
  152. free_stack_level(lastlvl);
  153. local_level->sl_next = (struct stack_level *) 0;
  154. level = local_level->sl_level;
  155. #ifdef DEBUG
  156. if (options['t'])
  157. dumpidftab("after unstackidfs", 0);
  158. #endif /* DEBUG */
  159. }
  160. void unstack_world()
  161. {
  162. /* The global level of identifiers is scanned, and final
  163. decisions are taken about such issues as
  164. extern/static/global and un/initialized.
  165. Effects on the code generator: initialised variables
  166. have already been encoded while the uninitialised ones
  167. are not and have to be encoded at this moment.
  168. */
  169. struct stack_entry *se = local_level->sl_entry;
  170. #ifdef LINT
  171. lint_end_global(local_level);
  172. #endif /* LINT */
  173. #ifdef GEN_NM_LIST
  174. open_name_list();
  175. #endif /* GEN_NM_LIST */
  176. while (se) {
  177. struct idf *idf = se->se_idf;
  178. struct def *def = idf->id_def;
  179. if (!def) {
  180. /* global selectors, etc. */
  181. se = se->next;
  182. continue;
  183. }
  184. #ifdef DEBUG
  185. if (options['a']) {
  186. char *symbol2str();
  187. print("\"%s\", %s, %s, %s, %s\n",
  188. idf->id_text,
  189. (def->df_alloc == 0) ? "no alloc" :
  190. (def->df_alloc == ALLOC_SEEN) ? "alloc seen" :
  191. (def->df_alloc == ALLOC_DONE) ? "alloc done" :
  192. "illegal alloc info",
  193. symbol2str(def->df_sc),
  194. def->df_initialized ? "init" : "no init",
  195. def->df_used ? "used" : "not used");
  196. }
  197. #endif /* DEBUG */
  198. if (def->df_sc == STATIC
  199. && def->df_type->tp_fund == FUNCTION
  200. && !def->df_initialized) {
  201. /* orphaned static function */
  202. warning("static function %s never defined, %s"
  203. , idf->id_text
  204. , "changed to extern");
  205. def->df_sc = EXTERN;
  206. }
  207. if (def->df_alloc == ALLOC_SEEN
  208. && !def->df_initialized) {
  209. /* space must be allocated */
  210. bss(idf);
  211. #ifdef GEN_NM_LIST
  212. if (def->df_sc != STATIC)
  213. namelist(idf->id_text); /* may be common */
  214. #endif /* GEN_NM_LIST */
  215. def->df_alloc = ALLOC_DONE; /* see Note below */
  216. }
  217. se = se->next;
  218. }
  219. /* Note:
  220. df_alloc must be set to ALLOC_DONE because the idf entry
  221. may occur several times in the list.
  222. The reason for this is that the same name may be used
  223. for different purposes on the same level, e.g.
  224. struct s {int s;} s;
  225. is a legal definition and contains 3 defining occurrences
  226. of s.
  227. Each definition has been entered into the identifier stack.
  228. Although only one of them concerns a variable, we meet the
  229. s 3 times when scanning the identifier stack.
  230. */
  231. }
  232. #ifdef GEN_NM_LIST
  233. /* A list of potential common names is kept, to be fed to
  234. an understanding loader. The list is written to a file
  235. the name of which is nmlist. If nmlist == NULL, no name
  236. list is generated.
  237. */
  238. extern char *nmlist; /* BAH! -- main.c */
  239. static File *nfp = 0;
  240. void open_name_list()
  241. {
  242. if (nmlist && sys_open(nmlist, OP_WRITE, &nfp) == 0)
  243. fatal("cannot create namelist %s", nmlist);
  244. }
  245. void namelist(char *nm)
  246. {
  247. if (nmlist) {
  248. sys_write(nfp, nm, strlen(nm));
  249. sys_write(nfp, "\n", 1);
  250. }
  251. }
  252. #endif /* GEN_NM_LIST */