dumpidf.c 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402
  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. /* DUMP ROUTINES */
  7. #include "debug.h"
  8. #ifdef DEBUG
  9. #include "nofloat.h"
  10. #include "nopp.h"
  11. #include "nobitfield.h"
  12. #include "arith.h"
  13. #include "stack.h"
  14. #include "idf.h"
  15. #include "def.h"
  16. #include "type.h"
  17. #include "struct.h"
  18. #include "field.h"
  19. #include "Lpars.h"
  20. #include "label.h"
  21. #include "expr.h"
  22. #include "static.h"
  23. /* Some routines (symbol2str, token2str, type2str) which should have
  24. * yielded strings are written to yield a pointer to a transient piece
  25. * of memory, containing the string, since this is the only reasonable
  26. * thing to do in C. `Transient' means that the result may soon
  27. * disappear, which is generally not a problem, since normally it is
  28. * consumed immediately. Sometimes we need more than one of them, and
  29. * MAXTRANS is the maximum number we will need simultaneously.
  30. */
  31. #define MAXTRANS 6
  32. extern char options[];
  33. extern struct idf *idf_hashtable[];
  34. extern char *symbol2str(), *type2str(), *next_transient();
  35. enum sdef_kind {selector, field}; /* parameter for dumpsdefs */
  36. static int dumplevel;
  37. static
  38. newline() {
  39. register int dl = dumplevel;
  40. print("\n");
  41. while (dl >= 2) {
  42. print("\t");
  43. dl -= 2;
  44. }
  45. if (dl)
  46. print(" ");
  47. }
  48. dumpidftab(msg, opt)
  49. char msg[];
  50. {
  51. /* Dumps the identifier table in readable form (but in
  52. arbitrary order).
  53. Unless opt & 1, macros are not dumped.
  54. Unless opt & 2, reserved identifiers are not dumped.
  55. Unless opt & 4, universal identifiers are not dumped.
  56. */
  57. int i;
  58. print(">>> DUMPIDF, %s (start)", msg);
  59. dumpstack();
  60. for (i = 0; i < HASHSIZE; i++) {
  61. register struct idf *notch = idf_hashtable[i];
  62. while (notch) {
  63. dumpidf(notch, opt);
  64. notch = notch->next;
  65. }
  66. }
  67. newline();
  68. print(">>> DUMPIDF, %s (end)\n", msg);
  69. }
  70. dumpstack()
  71. {
  72. /* Dumps the identifier stack, starting at the top.
  73. */
  74. register struct stack_level *stl = local_level;
  75. while (stl) {
  76. register struct stack_entry *se = stl->sl_entry;
  77. newline();
  78. print("%3d: ", stl->sl_level);
  79. while (se) {
  80. print("%s ", se->se_idf->id_text);
  81. se = se->next;
  82. }
  83. stl = stl->sl_previous;
  84. }
  85. print("\n");
  86. }
  87. dumpidf(idf, opt)
  88. register struct idf *idf;
  89. {
  90. /* All information about the identifier idf is divulged in a
  91. hopefully readable format.
  92. */
  93. int started = 0;
  94. if (!idf)
  95. return;
  96. #ifndef NOPP
  97. if ((opt&1) && idf->id_macro) {
  98. if (!started++) {
  99. newline();
  100. print("%s:", idf->id_text);
  101. }
  102. print(" macro");
  103. }
  104. #endif /* NOPP */
  105. if ((opt&2) && idf->id_reserved) {
  106. if (!started++) {
  107. newline();
  108. print("%s:", idf->id_text);
  109. }
  110. print(" reserved: %d;", idf->id_reserved);
  111. }
  112. if (idf->id_def && ((opt&4) || idf->id_def->df_level)) {
  113. if (!started++) {
  114. newline();
  115. print("%s:", idf->id_text);
  116. }
  117. dumpdefs(idf->id_def, opt);
  118. }
  119. if (idf->id_sdef) {
  120. if (!started++) {
  121. newline();
  122. print("%s:", idf->id_text);
  123. }
  124. dumpsdefs(idf->id_sdef, selector);
  125. }
  126. if (idf->id_struct) {
  127. if (!started++) {
  128. newline();
  129. print("%s:", idf->id_text);
  130. }
  131. dumptags(idf->id_struct);
  132. }
  133. if (idf->id_enum) {
  134. if (!started++) {
  135. newline();
  136. print("%s:", idf->id_text);
  137. }
  138. dumptags(idf->id_enum);
  139. }
  140. }
  141. dumpdefs(def, opt)
  142. register struct def *def;
  143. {
  144. dumplevel++;
  145. while (def && ((opt&4) || def->df_level)) {
  146. newline();
  147. print("L%d: %s %s%s%s%s %lo;",
  148. def->df_level,
  149. symbol2str(def->df_sc),
  150. def->df_initialized ? "init'd " : "",
  151. def->df_used ? "used " : "",
  152. type2str(def->df_type),
  153. def->df_sc == ENUM ? ", =" : " at",
  154. def->df_address
  155. );
  156. print("%s, line %u",
  157. def->df_file ? def->df_file : "NO_FILE", def->df_line);
  158. def = def->next;
  159. }
  160. dumplevel--;
  161. }
  162. dumptags(tag)
  163. register struct tag *tag;
  164. {
  165. dumplevel++;
  166. while (tag) {
  167. register struct type *tp = tag->tg_type;
  168. register int fund = tp->tp_fund;
  169. newline();
  170. print("L%d: %s %s",
  171. tag->tg_level,
  172. fund == STRUCT ? "struct" :
  173. fund == UNION ? "union" :
  174. fund == ENUM ? "enum" : "<UNKNOWN>",
  175. tp->tp_idf->id_text
  176. );
  177. if (is_struct_or_union(fund)) {
  178. print(" {");
  179. dumpsdefs(tp->tp_sdef, field);
  180. newline();
  181. print("}");
  182. }
  183. print(";");
  184. tag = tag->next;
  185. }
  186. dumplevel--;
  187. }
  188. dumpsdefs(sdef, sdk)
  189. register struct sdef *sdef;
  190. enum sdef_kind sdk;
  191. {
  192. /* Since sdef's are members of two chains, there are actually
  193. two dumpsdefs's, one following the chain of all selectors
  194. belonging to the same idf, starting at idf->id_sdef;
  195. and the other following the chain of all selectors belonging
  196. to the same struct, starting at stp->tp_sdef.
  197. */
  198. dumplevel++;
  199. while (sdef) {
  200. newline();
  201. print("L%d: ", sdef->sd_level);
  202. #ifndef NOBITFIELD
  203. if (sdk == selector)
  204. #endif /* NOBITFIELD */
  205. print("selector %s at offset %lu in %s;",
  206. type2str(sdef->sd_type),
  207. sdef->sd_offset, type2str(sdef->sd_stype)
  208. );
  209. #ifndef NOBITFIELD
  210. else print("field %s at offset %lu;",
  211. type2str(sdef->sd_type), sdef->sd_offset
  212. );
  213. #endif /* NOBITFIELD */
  214. sdef = (sdk == selector ? sdef->next : sdef->sd_sdef);
  215. }
  216. dumplevel--;
  217. }
  218. char *
  219. type2str(tp)
  220. register struct type *tp;
  221. {
  222. /* Yields a pointer to a one-line description of the type tp.
  223. */
  224. char *buf = next_transient();
  225. int ops = 1;
  226. buf[0] = '\0';
  227. if (!tp) {
  228. sprint(buf, "<NILTYPE>");
  229. return buf;
  230. }
  231. sprint(buf, "%s(#%ld, &%d) ", buf, (long)tp->tp_size, tp->tp_align);
  232. while (ops) {
  233. switch (tp->tp_fund) {
  234. case POINTER:
  235. sprint(buf, "%spointer to ", buf);
  236. break;
  237. case ARRAY:
  238. sprint(buf, "%sarray [%ld] of ", buf, tp->tp_size);
  239. break;
  240. case FUNCTION:
  241. sprint(buf, "%sfunction yielding ", buf);
  242. break;
  243. default:
  244. sprint(buf, "%s%s%s", buf,
  245. tp->tp_unsigned ? "unsigned " : "",
  246. symbol2str(tp->tp_fund)
  247. );
  248. if (tp->tp_idf)
  249. sprint(buf, "%s %s", buf,
  250. tp->tp_idf->id_text);
  251. #ifndef NOBITFIELD
  252. if (tp->tp_field) {
  253. struct field *fd = tp->tp_field;
  254. sprint(buf, "%s [s=%ld,w=%ld] of ", buf,
  255. fd->fd_shift, fd->fd_width);
  256. }
  257. else
  258. #endif /* NOBITFIELD */
  259. ops = 0;
  260. break;
  261. }
  262. tp = tp->tp_up;
  263. }
  264. return buf;
  265. }
  266. GSTATIC char trans_buf[MAXTRANS][300];
  267. char * /* the ultimate transient buffer supplier */
  268. next_transient()
  269. {
  270. static int bnum;
  271. if (++bnum == MAXTRANS)
  272. bnum = 0;
  273. return trans_buf[bnum];
  274. }
  275. print_expr(msg, expr)
  276. char msg[];
  277. struct expr *expr;
  278. {
  279. /* Provisional routine to print an expression preceded by a
  280. message msg.
  281. */
  282. if (options['x']) {
  283. print("\n%s: ", msg);
  284. print("(L=line, T=type, r/lV=r/lvalue, F=flags, D=depth)\n");
  285. p1_expr(0, expr);
  286. }
  287. }
  288. p1_expr(lvl, expr)
  289. register struct expr *expr;
  290. {
  291. p1_indent(lvl);
  292. if (!expr) {
  293. print("NILEXPR\n");
  294. return;
  295. }
  296. print("expr: L=%u, T=%s, %cV, F=%03o, D=%d, %s: ",
  297. expr->ex_line,
  298. type2str(expr->ex_type),
  299. expr->ex_lvalue ? 'l' : 'r',
  300. expr->ex_flags & 0xFF,
  301. expr->ex_depth,
  302. expr->ex_class == Value ? "Value" :
  303. expr->ex_class == String ? "String" :
  304. #ifndef NOFLOAT
  305. expr->ex_class == Float ? "Float" :
  306. #endif /* NOFLOAT */
  307. expr->ex_class == Oper ? "Oper" :
  308. expr->ex_class == Type ? "Type" : "UNKNOWN CLASS"
  309. );
  310. switch (expr->ex_class) {
  311. struct oper *o;
  312. case Value:
  313. switch (expr->VL_CLASS) {
  314. case Const:
  315. print("(Const) ");
  316. break;
  317. case Name:
  318. print("(Name) %s + ", expr->VL_IDF->id_text);
  319. break;
  320. case Label:
  321. print("(Label) .%lu + ", expr->VL_LBL);
  322. break;
  323. default:
  324. print("(Unknown) ");
  325. break;
  326. }
  327. print(expr->ex_type->tp_unsigned ? "%lu\n" : "%ld\n",
  328. expr->VL_VALUE);
  329. break;
  330. case String:
  331. {
  332. char *bts2str();
  333. print(
  334. "\"%s\"\n",
  335. bts2str(expr->SG_VALUE, expr->SG_LEN-1,
  336. next_transient())
  337. );
  338. break;
  339. }
  340. #ifndef NOFLOAT
  341. case Float:
  342. print("%s\n", expr->FL_VALUE);
  343. break;
  344. #endif /* NOFLOAT */
  345. case Oper:
  346. o = &expr->ex_object.ex_oper;
  347. print("\n");
  348. p1_expr(lvl+1, o->op_left);
  349. p1_indent(lvl);
  350. print("%s <%s>\n", symbol2str(o->op_oper),
  351. type2str(o->op_type)
  352. );
  353. p1_expr(lvl+1, o->op_right);
  354. break;
  355. case Type:
  356. print("\n");
  357. break;
  358. default:
  359. print("UNKNOWN CLASS\n");
  360. break;
  361. }
  362. }
  363. p1_indent(lvl)
  364. register int lvl;
  365. {
  366. while (lvl--)
  367. print(" ");
  368. }
  369. #endif /* DEBUG */