symbol.c 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358
  1. /* $Id$ */
  2. /* Symbol handling */
  3. #include <stdio.h>
  4. #include <alloc.h>
  5. #include <out.h>
  6. #include <stb.h>
  7. #include <assert.h>
  8. #include "position.h"
  9. #include "file.h"
  10. #include "idf.h"
  11. #include "type.h"
  12. #include "symbol.h"
  13. #include "scope.h"
  14. #include "tree.h"
  15. #include "operator.h"
  16. #include "misc.h"
  17. p_symbol currfile, listfile;
  18. extern FILE *db_out;
  19. p_symbol
  20. NewSymbol(s, scope, class, nam)
  21. char *s;
  22. register p_scope scope;
  23. struct outname *nam;
  24. {
  25. register p_symbol sym;
  26. sym = new_symbol();
  27. sym->sy_idf = str2idf(s, 0);
  28. sym->sy_scope = scope;
  29. sym->sy_prev_sc = scope->sc_symbs;
  30. scope->sc_symbs = sym;
  31. sym->sy_next = sym->sy_idf->id_def;
  32. sym->sy_idf->id_def = sym;
  33. sym->sy_class = class;
  34. switch(class) {
  35. case MODULE:
  36. case PROC:
  37. case FUNCTION:
  38. case VAR:
  39. case REGVAR:
  40. case LOCVAR:
  41. case VARPAR:
  42. sym->sy_name.nm_value = nam->on_valu;
  43. break;
  44. default:
  45. break;
  46. }
  47. return sym;
  48. }
  49. /* Lookup a definition for 'id' in scope 'scope' with class in the 'class'
  50. bitset.
  51. */
  52. p_symbol
  53. Lookup(id, scope, class)
  54. struct idf *id;
  55. p_scope scope;
  56. int class;
  57. {
  58. register p_symbol p = id ? id->id_def : 0;
  59. while (p) {
  60. if (p->sy_scope == scope && (p->sy_class & class)) {
  61. return p;
  62. }
  63. p = p->sy_next;
  64. }
  65. return (p_symbol) 0;
  66. }
  67. /* Lookup a definition for 'id' with class in the 'class' bitset,
  68. starting in scope 'sc' and also looking in enclosing scopes.
  69. */
  70. p_symbol
  71. Lookfromscope(id, class, sc)
  72. register struct idf *id;
  73. int class;
  74. register p_scope sc;
  75. {
  76. if (! id) return (p_symbol) 0;
  77. while (sc) {
  78. register p_symbol sym = id->id_def;
  79. while (sym) {
  80. if (sym->sy_scope == sc && (sym->sy_class & class)) {
  81. return sym;
  82. }
  83. sym = sym->sy_next;
  84. }
  85. sc = sc->sc_static_encl;
  86. }
  87. return (p_symbol) 0;
  88. }
  89. extern char *strrchr();
  90. p_symbol
  91. add_file(s)
  92. char *s;
  93. {
  94. register p_symbol sym = NewSymbol(s,
  95. PervasiveScope,
  96. FILESYM,
  97. (struct outname *) 0);
  98. register char *p;
  99. sym->sy_file = new_file();
  100. sym->sy_file->f_sym = sym;
  101. p = strrchr(s, '.');
  102. if (p) {
  103. char c = *p;
  104. p_symbol sym1;
  105. *p = 0;
  106. s = Salloc(s, (unsigned) strlen(s)+1);
  107. *p = c;
  108. sym1 = NewSymbol(s,
  109. PervasiveScope,
  110. FILELINK,
  111. (struct outname *) 0);
  112. sym1->sy_filelink = sym;
  113. sym->sy_file->f_base = sym1;
  114. }
  115. return sym;
  116. }
  117. static p_scope
  118. def_scope(s)
  119. p_symbol s;
  120. {
  121. switch(s->sy_class) {
  122. case FILELINK:
  123. s = s->sy_filelink;
  124. /* fall through */
  125. case FILESYM:
  126. return s->sy_file->f_scope;
  127. case PROC:
  128. case FUNCTION:
  129. case MODULE:
  130. case TYPE:
  131. case VAR:
  132. case REGVAR:
  133. case LOCVAR:
  134. case VARPAR:
  135. return s->sy_name.nm_scope;
  136. }
  137. return 0;
  138. }
  139. /* Determine if the OP_SELECT tree indicated by 'p' could lead to scope 'sc'.
  140. */
  141. int
  142. consistent(p, sc)
  143. p_tree p;
  144. p_scope sc;
  145. {
  146. p_tree arg;
  147. p_symbol sym;
  148. p_scope target_sc;
  149. assert(p->t_oper == OP_SELECT);
  150. p = p->t_args[0];
  151. switch(p->t_oper) {
  152. case OP_NAME:
  153. #define CLASS (FILELINK|FILESYM|PROC|FUNCTION|MODULE|TYPE|VAR|REGVAR|LOCVAR|VARPAR|LBOUND|UBOUND)
  154. sym = Lookfromscope(p->t_idf, CLASS, sc->sc_static_encl);
  155. if (sym) {
  156. int precise = 1;
  157. target_sc = def_scope(sym);
  158. while (sc && sc != target_sc) {
  159. precise = 0;
  160. sc = sc->sc_static_encl;
  161. }
  162. return sc == 0 ? 0 : precise + 1 ;
  163. }
  164. return 0;
  165. case OP_SELECT:
  166. arg = p->t_args[1];
  167. sym = Lookfromscope(arg->t_idf, CLASS, sc->sc_static_encl);
  168. if (sym) {
  169. int precise = 1;
  170. target_sc = def_scope(sym);
  171. while (sc && sc != target_sc) {
  172. precise = 0;
  173. sc = sc->sc_static_encl;
  174. }
  175. if (sc == 0) return 0;
  176. if (precise) return consistent(p, sym->sy_scope);
  177. return consistent(p, sym->sy_scope) != 0;
  178. }
  179. return 0;
  180. default:
  181. assert(0);
  182. }
  183. return 0; /* notreached? */
  184. }
  185. /* Try to find the name referred to in the node indicated by 'p', and
  186. try to be just a little bit intelligent about it.
  187. */
  188. p_symbol
  189. identify(p, class_set)
  190. p_tree p;
  191. int class_set;
  192. {
  193. p_symbol sym = 0, sym1 = 0;
  194. register p_symbol s;
  195. p_tree arg;
  196. int precise = 0;
  197. switch(p->t_oper) {
  198. case OP_NAME:
  199. sym = Lookfromscope(p->t_idf, class_set, CurrentScope);
  200. if (sym) {
  201. /* Found it. */
  202. break;
  203. }
  204. /* We could not find it using the current scope; now we try to identify
  205. it using class_set. If this results in only one definition, we
  206. take this one.
  207. */
  208. s = p->t_idf->id_def;
  209. while (s) {
  210. if (s->sy_class & class_set) {
  211. if (sym) {
  212. error("could not identify \"%s\"", p->t_str);
  213. sym = 0;
  214. break;
  215. }
  216. sym = s;
  217. }
  218. s = s->sy_next;
  219. }
  220. if (!sym && !s) {
  221. error("could not find \"%s\"", p->t_str);
  222. }
  223. break;
  224. case OP_SELECT:
  225. arg = p->t_args[1];
  226. assert(arg->t_oper == OP_NAME);
  227. s = arg->t_idf->id_def;
  228. while (s) {
  229. int temp;
  230. if ((s->sy_class & class_set) &&
  231. (temp = consistent(p, s->sy_scope))) {
  232. if (temp > precise) {
  233. sym = s;
  234. precise = temp;
  235. sym1 = 0;
  236. }
  237. else if (sym && temp == precise) sym1 = s;
  238. }
  239. s = s->sy_next;
  240. }
  241. if (sym && sym1) {
  242. error("could not identify \"%s\"", arg->t_str);
  243. return 0;
  244. }
  245. if (!sym && !s) {
  246. error("could not find \"%s\"", arg->t_str);
  247. return 0;
  248. }
  249. break;
  250. default:
  251. assert(0);
  252. }
  253. return sym;
  254. }
  255. static
  256. pr_scopes(sc)
  257. p_scope sc;
  258. {
  259. if (! sc) return;
  260. pr_scopes(sc->sc_static_encl);
  261. if (sc->sc_definedby) {
  262. if (sc->sc_definedby->sy_class == FILESYM &&
  263. sc->sc_definedby->sy_file->f_base) {
  264. fprintf(db_out, "%s`", sc->sc_definedby->sy_file->f_base->sy_idf->id_text);
  265. }
  266. else fprintf(db_out, "%s`", sc->sc_definedby->sy_idf->id_text);
  267. }
  268. }
  269. pr_sym(s)
  270. p_symbol s;
  271. {
  272. switch(s->sy_class) {
  273. case CONST:
  274. fprintf(db_out, "Constant:\t");
  275. break;
  276. case TYPE:
  277. fprintf(db_out, "Type:\t\t");
  278. break;
  279. case TAG:
  280. fprintf(db_out, "Tag:\t\t");
  281. break;
  282. case MODULE:
  283. fprintf(db_out, "Module:\t\t");
  284. break;
  285. case PROC:
  286. case FUNCTION:
  287. fprintf(db_out, "Routine:\t");
  288. break;
  289. case VAR:
  290. case REGVAR:
  291. case LOCVAR:
  292. case VARPAR:
  293. case LBOUND:
  294. case UBOUND:
  295. fprintf(db_out, "Variable:\t");
  296. break;
  297. case FIELD:
  298. fprintf(db_out, "Field:\t\t");
  299. break;
  300. case FILESYM:
  301. case FILELINK:
  302. fprintf(db_out, "File:\t\t");
  303. break;
  304. default:
  305. assert(0);
  306. }
  307. pr_scopes(s->sy_scope);
  308. fprintf(db_out, "%s\n", s->sy_idf->id_text);
  309. }
  310. resolve_cross(tp)
  311. p_type tp;
  312. {
  313. register p_symbol sym = tp->ty_sym->sy_idf->id_def;
  314. while (sym) {
  315. if (sym->sy_class == TAG &&
  316. sym->sy_type->ty_class == T_CROSS &&
  317. sym->sy_type->ty_cross == (p_type) 0 &&
  318. sym->sy_type->ty_size == tp->ty_class &&
  319. scope_encloses(tp->ty_sym->sy_scope, sym->sy_scope)) {
  320. sym->sy_type->ty_cross = tp;
  321. sym->sy_type->ty_size = tp->ty_size;
  322. }
  323. sym = sym->sy_next;
  324. }
  325. }