dumpidf.c 7.7 KB

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