dumpidf.c 9.8 KB

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