print-tree.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470
  1. /* Prints out tree in human readable form - GNU C-compiler
  2. Copyright (C) 1987 Free Software Foundation, Inc.
  3. This file is part of GNU CC.
  4. GNU CC is distributed in the hope that it will be useful,
  5. but WITHOUT ANY WARRANTY. No author or distributor
  6. accepts responsibility to anyone for the consequences of using it
  7. or for whether it serves any particular purpose or works at all,
  8. unless he says so in writing. Refer to the GNU CC General Public
  9. License for full details.
  10. Everyone is granted permission to copy, modify and redistribute
  11. GNU CC, but only under the conditions described in the
  12. GNU CC General Public License. A copy of this license is
  13. supposed to have been given to you along with GNU CC so you
  14. can know your rights and responsibilities. It should be in a
  15. file named COPYING. Among other things, the copyright notice
  16. and this notice must be preserved on all copies. */
  17. #include "config.h"
  18. #include <stdio.h>
  19. #include <strings.h>
  20. #include "tree.h"
  21. /* Names of tree components.
  22. Used for printing out the tree and error messages. */
  23. #define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME,
  24. char *tree_code_name[] = {
  25. #include "tree.def"
  26. };
  27. #undef DEFTREECODE
  28. extern char *tree_code_type[];
  29. extern int tree_code_length[];
  30. extern char *mode_name[];
  31. extern char *spaces;
  32. #define MIN(x,y) ((x < y) ? x : y)
  33. static FILE *outfile;
  34. extern int tree_node_counter;
  35. /* markvec[i] is 1 if node number i has been seen already. */
  36. static char *markvec;
  37. static void dump ();
  38. void
  39. dump_tree (outf, root)
  40. FILE *outf;
  41. tree root;
  42. {
  43. markvec = (char *) alloca (tree_node_counter + 1);
  44. bzero (markvec, tree_node_counter + 1);
  45. outfile = outf;
  46. dump (root, 0);
  47. fflush (outf);
  48. }
  49. static
  50. void
  51. wruid (node)
  52. tree node;
  53. {
  54. if (node == NULL)
  55. fputs ("<>", outfile);
  56. else {
  57. fprintf (outfile, "%1d", TREE_UID (node));
  58. }
  59. }
  60. static
  61. void
  62. part (title, node)
  63. char title[];
  64. tree node;
  65. {
  66. fprintf (outfile, " %s = ", title);
  67. wruid (node);
  68. putc (';', outfile);
  69. }
  70. /* Similar to `part' but prefix with @ if value is not constant
  71. and print the constant value if it is constant. */
  72. static
  73. void
  74. cpart (title, ct, punct)
  75. char *title;
  76. tree ct;
  77. char punct;
  78. {
  79. fprintf (outfile, " %s = ", title);
  80. if (ct == NULL)
  81. fputs ("<>", outfile);
  82. else
  83. {
  84. if (!TREE_LITERAL (ct))
  85. {
  86. putc ('@', outfile);
  87. wruid (ct);
  88. }
  89. else
  90. fprintf (outfile, "%ld", TREE_INT_CST_LOW (ct));
  91. }
  92. putc(punct, outfile);
  93. }
  94. static
  95. void
  96. walk (node, leaf, indent)
  97. tree node;
  98. tree leaf;
  99. int indent;
  100. {
  101. if (node != NULL
  102. /* Don't walk any global nodes reached from local nodes!
  103. The global nodes will be dumped at the end, all together.
  104. Also don't mention a FUNCTION_DECL node that is marked local
  105. since it was fully described when it was dumped locally. */
  106. && (TREE_CODE (node) != FUNCTION_DECL
  107. || TREE_PERMANENT (node))
  108. && (TREE_PERMANENT (leaf) == TREE_PERMANENT (node)))
  109. dump (node, indent+1);
  110. }
  111. static
  112. void
  113. cwalk (s, leaf, indent)
  114. tree s;
  115. tree leaf;
  116. int indent;
  117. {
  118. if (s != NULL)
  119. if (!TREE_LITERAL (s))
  120. walk(s, leaf, indent);
  121. }
  122. static
  123. void
  124. prtypeinfo (node)
  125. register tree node;
  126. {
  127. int first;
  128. part ("type", TREE_TYPE (node));
  129. first = 1;
  130. fputs (" [", outfile);
  131. if (TREE_EXTERNAL (node))
  132. {
  133. if (!first) putc (' ', outfile);
  134. fputs ("external", outfile);
  135. first = 0;
  136. }
  137. if (TREE_PUBLIC (node))
  138. {
  139. if (!first) putc (' ', outfile);
  140. fputs ("public", outfile);
  141. first = 0;
  142. }
  143. if (TREE_STATIC (node))
  144. {
  145. if (!first) putc (' ', outfile);
  146. fputs ("static", outfile);
  147. first = 0;
  148. }
  149. if (TREE_NONLOCAL (node))
  150. {
  151. if (!first) putc (' ', outfile);
  152. fputs ("nonlocal", outfile);
  153. first = 0;
  154. }
  155. if (TREE_PACKED (node))
  156. {
  157. if (!first) putc (' ', outfile);
  158. fputs ("packed", outfile);
  159. first = 0;
  160. }
  161. if (TREE_LITERAL (node))
  162. {
  163. if (!first) putc (' ', outfile);
  164. fputs ("literal", outfile);
  165. first = 0;
  166. }
  167. if (TREE_VOLATILE (node))
  168. {
  169. if (!first) putc (' ', outfile);
  170. fputs ("volatile", outfile);
  171. first = 0;
  172. }
  173. if (TREE_READONLY (node))
  174. {
  175. if (!first) putc (' ', outfile);
  176. fputs ("readonly", outfile);
  177. first = 0;
  178. }
  179. if (TREE_ADDRESSABLE (node))
  180. {
  181. if (!first) putc (' ', outfile);
  182. fputs ("addressable", outfile);
  183. first = 0;
  184. }
  185. if (TREE_REGDECL (node))
  186. {
  187. if (!first) putc (' ', outfile);
  188. fputs ("regdecl", outfile);
  189. first = 0;
  190. }
  191. fputs ("] ", outfile);
  192. }
  193. static
  194. void
  195. prdeclmodeinfo(node)
  196. tree node;
  197. {
  198. register enum machine_mode mode = DECL_MODE (node);
  199. fprintf (outfile, " %s;", mode_name[(int) mode]);
  200. cpart ("size", DECL_SIZE (node), '*');
  201. fprintf (outfile, "%d;", DECL_SIZE_UNIT (node));
  202. fprintf (outfile, " alignment = %1d;", DECL_ALIGN (node));
  203. }
  204. static
  205. void
  206. prtypemodeinfo(node)
  207. tree node;
  208. {
  209. register enum machine_mode mode = TYPE_MODE (node);
  210. fprintf (outfile, " %s;", mode_name[(int) mode]);
  211. cpart ("size", TYPE_SIZE (node), '*');
  212. fprintf (outfile, "%d;", TYPE_SIZE_UNIT (node));
  213. fprintf (outfile, " alignment = %1d;", TYPE_ALIGN (node));
  214. }
  215. static
  216. void
  217. skip (indent)
  218. int indent;
  219. {
  220. putc ('\n',outfile);
  221. fputs (spaces + (128 - (12 + MIN(40,(indent+1)*2))), outfile);
  222. }
  223. /* Output a description of the tree node NODE
  224. if its description has not been output already. */
  225. static
  226. void
  227. dump (node, indent)
  228. tree node;
  229. int indent;
  230. {
  231. register enum tree_code code = TREE_CODE (node);
  232. register int i;
  233. register int len;
  234. if (markvec[TREE_UID (node)])
  235. return;
  236. markvec[TREE_UID (node)] = 1;
  237. fputs (" ", outfile);
  238. fprintf (outfile, "%5d", TREE_UID (node));
  239. fputs (spaces + (128 - MIN(40, (indent+1)*2)), outfile);
  240. fputs (tree_code_name[(int) code], outfile);
  241. switch (*tree_code_type[(int) code])
  242. {
  243. case 'd':
  244. fputs (" name = ", outfile);
  245. if (DECL_NAME (node) == NULL)
  246. fputs("<>;", outfile);
  247. else
  248. fprintf (outfile, "%s;",
  249. IDENTIFIER_POINTER (DECL_NAME (node)));
  250. fprintf (outfile, " at %s line %d;",
  251. DECL_SOURCE_FILE (node), DECL_SOURCE_LINE (node));
  252. skip (indent);
  253. prdeclmodeinfo (node);
  254. prtypeinfo (node);
  255. skip (indent);
  256. fprintf (outfile, " offset = %1d;", DECL_OFFSET (node));
  257. if (DECL_VOFFSET (node) != NULL)
  258. {
  259. fputs ("voffset = ", outfile);
  260. wruid (DECL_VOFFSET (node));
  261. fprintf (outfile, "*%1d;", DECL_VOFFSET_UNIT (node));
  262. }
  263. part ("context", DECL_CONTEXT (node));
  264. if (DECL_ARGUMENTS (node) || DECL_RESULT (node)
  265. || DECL_INITIAL (node))
  266. {
  267. skip(indent);
  268. part ("arguments", DECL_ARGUMENTS (node));
  269. part ("result", DECL_RESULT (node));
  270. if ((int) (DECL_INITIAL (node)) == 1)
  271. fprintf (outfile, " initial = const 1;");
  272. else
  273. part ("initial", DECL_INITIAL (node));
  274. }
  275. part ("chain", TREE_CHAIN (node));
  276. fputc ('\n', outfile);
  277. cwalk (DECL_SIZE (node), node, indent);
  278. walk (TREE_TYPE (node), node, indent);
  279. walk (DECL_VOFFSET (node), node, indent);
  280. walk (DECL_CONTEXT (node), node, indent);
  281. walk (DECL_ARGUMENTS (node), node, indent);
  282. walk (DECL_RESULT (node), node, indent);
  283. if ((int) (DECL_INITIAL (node)) != 1)
  284. walk (DECL_INITIAL (node), node, indent);
  285. break;
  286. case 't':
  287. prtypemodeinfo (node);
  288. prtypeinfo (node);
  289. skip (indent);
  290. part ("pointers_to_this", TYPE_POINTER_TO (node));
  291. if (code == ARRAY_TYPE || code == SET_TYPE)
  292. {
  293. part ("domain", TYPE_DOMAIN (node));
  294. cpart ("separation", TYPE_SEP (node), '*');
  295. fprintf (outfile, "%d;", TYPE_SEP_UNIT (node));
  296. }
  297. else if (code == INTEGER_TYPE)
  298. {
  299. cpart ("min", TYPE_MIN_VALUE (node), ';');
  300. cpart ("max", TYPE_MAX_VALUE (node), ';');
  301. fprintf (outfile, "precision = %d;", TYPE_PRECISION (node));
  302. }
  303. else if (code == ENUMERAL_TYPE)
  304. {
  305. cpart ("min", TYPE_MIN_VALUE (node), ';');
  306. cpart ("max", TYPE_MAX_VALUE (node), ';');
  307. part ("values", TYPE_VALUES (node));
  308. fprintf (outfile, "precision = %d;", TYPE_PRECISION (node));
  309. }
  310. else if (code == REAL_TYPE)
  311. {
  312. fprintf (outfile, "precision = %d;", TYPE_PRECISION (node));
  313. }
  314. else if (code == RECORD_TYPE
  315. || code == UNION_TYPE)
  316. {
  317. part ("fields", TYPE_FIELDS (node));
  318. }
  319. else if (code == FUNCTION_TYPE)
  320. {
  321. part ("arg_types", TYPE_ARG_TYPES (node));
  322. }
  323. part ("chain", TREE_CHAIN (node));
  324. fputc ('\n', outfile);
  325. cwalk (TYPE_SIZE (node), node, indent);
  326. walk (TREE_TYPE (node), node, indent);
  327. walk (TYPE_VALUES (node), node, indent);
  328. walk (TYPE_SEP (node), node, indent);
  329. walk (TYPE_POINTER_TO (node), node, indent);
  330. break;
  331. case 'e':
  332. case 'r':
  333. prtypeinfo (node);
  334. fputs (" ops =", outfile);
  335. len = tree_code_length[(int) code];
  336. for (i = 0; i < len; i++)
  337. {
  338. fputs (" ", outfile);
  339. wruid (TREE_OPERAND (node, i));
  340. fputs (";", outfile);
  341. }
  342. part ("chain", TREE_CHAIN (node));
  343. fputc ('\n', outfile);
  344. walk (TREE_TYPE (node), node, indent);
  345. for (i = 0; i < len; i++)
  346. walk (TREE_OPERAND (node, i), node, indent);
  347. break;
  348. case 's':
  349. prtypeinfo (node);
  350. fprintf (outfile, " at %s line %d;",
  351. STMT_SOURCE_FILE (node), STMT_SOURCE_LINE (node));
  352. fputs (" ops =", outfile);
  353. len = tree_code_length[(int) code];
  354. for (i = 0; i < len; i++)
  355. {
  356. fputs (" ", outfile);
  357. wruid (TREE_OPERAND (node, i+2));
  358. fputs (";", outfile);
  359. }
  360. part ("chain", TREE_CHAIN (node));
  361. fputc ('\n', outfile);
  362. walk (TREE_TYPE (node), node, indent);
  363. for (i = 0; i < len; i++)
  364. walk (TREE_OPERAND (node, i+2), node, indent);
  365. break;
  366. case 'c':
  367. switch (code)
  368. {
  369. case INTEGER_CST:
  370. if (TREE_INT_CST_HIGH (node) == 0)
  371. fprintf (outfile, " = %1u;", TREE_INT_CST_LOW (node));
  372. else if (TREE_INT_CST_HIGH (node) == -1
  373. && TREE_INT_CST_LOW (node) != 0)
  374. fprintf (outfile, " = -%1u;", -TREE_INT_CST_LOW (node));
  375. else
  376. fprintf (outfile, " = 0x%x%08x;",
  377. TREE_INT_CST_HIGH (node),
  378. TREE_INT_CST_LOW (node));
  379. break;
  380. case REAL_CST:
  381. fprintf (outfile, " = %e;", TREE_REAL_CST (node));
  382. break;
  383. case COMPLEX_CST:
  384. part ("realpart", TREE_REALPART (node));
  385. part ("imagpart", TREE_IMAGPART (node));
  386. walk (TREE_REALPART (node), node, indent);
  387. walk (TREE_IMAGPART (node), node, indent);
  388. break;
  389. case STRING_CST:
  390. fprintf (outfile, " = \"%s\";", TREE_STRING_POINTER (node));
  391. }
  392. prtypeinfo(node);
  393. part ("chain", TREE_CHAIN (node));
  394. fputc ('\n', outfile);
  395. walk (TREE_TYPE (node), node, indent);
  396. break;
  397. case 'x':
  398. if (code == IDENTIFIER_NODE)
  399. fprintf (outfile, " = %s;\n", IDENTIFIER_POINTER (node));
  400. else if (code == TREE_LIST)
  401. {
  402. prtypeinfo (node);
  403. part ("purpose", TREE_PURPOSE (node));
  404. part ("value", TREE_VALUE (node));
  405. part ("chain", TREE_CHAIN (node));
  406. fputc ('\n', outfile);
  407. walk (TREE_TYPE (node), node, indent);
  408. walk (TREE_PURPOSE (node), node, indent);
  409. walk (TREE_VALUE (node), node, indent);
  410. }
  411. else if (code == ERROR_MARK)
  412. fputc ('\n', outfile);
  413. else abort ();
  414. break;
  415. default:
  416. abort ();
  417. } /* switch */
  418. if (TREE_CHAIN (node) != NULL)
  419. dump(TREE_CHAIN (node), indent);
  420. }