dumpidf.c 7.5 KB

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