tree-dump.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789
  1. /* Tree-dumping functionality for intermediate representation.
  2. Copyright (C) 1999-2015 Free Software Foundation, Inc.
  3. Written by Mark Mitchell <mark@codesourcery.com>
  4. This file is part of GCC.
  5. GCC is free software; you can redistribute it and/or modify it under
  6. the terms of the GNU General Public License as published by the Free
  7. Software Foundation; either version 3, or (at your option) any later
  8. version.
  9. GCC is distributed in the hope that it will be useful, but WITHOUT ANY
  10. WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11. FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  12. for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with GCC; see the file COPYING3. If not see
  15. <http://www.gnu.org/licenses/>. */
  16. #include "config.h"
  17. #include "system.h"
  18. #include "coretypes.h"
  19. #include "tm.h"
  20. #include "hash-set.h"
  21. #include "machmode.h"
  22. #include "vec.h"
  23. #include "double-int.h"
  24. #include "input.h"
  25. #include "alias.h"
  26. #include "symtab.h"
  27. #include "wide-int.h"
  28. #include "inchash.h"
  29. #include "real.h"
  30. #include "tree.h"
  31. #include "fixed-value.h"
  32. #include "splay-tree.h"
  33. #include "filenames.h"
  34. #include "tree-dump.h"
  35. #include "langhooks.h"
  36. #include "tree-iterator.h"
  37. #include "tree-pretty-print.h"
  38. #include "tree-cfg.h"
  39. #include "wide-int-print.h"
  40. static unsigned int queue (dump_info_p, const_tree, int);
  41. static void dump_index (dump_info_p, unsigned int);
  42. static void dequeue_and_dump (dump_info_p);
  43. static void dump_new_line (dump_info_p);
  44. static void dump_maybe_newline (dump_info_p);
  45. /* Add T to the end of the queue of nodes to dump. Returns the index
  46. assigned to T. */
  47. static unsigned int
  48. queue (dump_info_p di, const_tree t, int flags)
  49. {
  50. dump_queue_p dq;
  51. dump_node_info_p dni;
  52. unsigned int index;
  53. /* Assign the next available index to T. */
  54. index = ++di->index;
  55. /* Obtain a new queue node. */
  56. if (di->free_list)
  57. {
  58. dq = di->free_list;
  59. di->free_list = dq->next;
  60. }
  61. else
  62. dq = XNEW (struct dump_queue);
  63. /* Create a new entry in the splay-tree. */
  64. dni = XNEW (struct dump_node_info);
  65. dni->index = index;
  66. dni->binfo_p = ((flags & DUMP_BINFO) != 0);
  67. dq->node = splay_tree_insert (di->nodes, (splay_tree_key) t,
  68. (splay_tree_value) dni);
  69. /* Add it to the end of the queue. */
  70. dq->next = 0;
  71. if (!di->queue_end)
  72. di->queue = dq;
  73. else
  74. di->queue_end->next = dq;
  75. di->queue_end = dq;
  76. /* Return the index. */
  77. return index;
  78. }
  79. static void
  80. dump_index (dump_info_p di, unsigned int index)
  81. {
  82. fprintf (di->stream, "@%-6u ", index);
  83. di->column += 8;
  84. }
  85. /* If T has not already been output, queue it for subsequent output.
  86. FIELD is a string to print before printing the index. Then, the
  87. index of T is printed. */
  88. void
  89. queue_and_dump_index (dump_info_p di, const char *field, const_tree t, int flags)
  90. {
  91. unsigned int index;
  92. splay_tree_node n;
  93. /* If there's no node, just return. This makes for fewer checks in
  94. our callers. */
  95. if (!t)
  96. return;
  97. /* See if we've already queued or dumped this node. */
  98. n = splay_tree_lookup (di->nodes, (splay_tree_key) t);
  99. if (n)
  100. index = ((dump_node_info_p) n->value)->index;
  101. else
  102. /* If we haven't, add it to the queue. */
  103. index = queue (di, t, flags);
  104. /* Print the index of the node. */
  105. dump_maybe_newline (di);
  106. fprintf (di->stream, "%-4s: ", field);
  107. di->column += 6;
  108. dump_index (di, index);
  109. }
  110. /* Dump the type of T. */
  111. void
  112. queue_and_dump_type (dump_info_p di, const_tree t)
  113. {
  114. queue_and_dump_index (di, "type", TREE_TYPE (t), DUMP_NONE);
  115. }
  116. /* Dump column control */
  117. #define SOL_COLUMN 25 /* Start of line column. */
  118. #define EOL_COLUMN 55 /* End of line column. */
  119. #define COLUMN_ALIGNMENT 15 /* Alignment. */
  120. /* Insert a new line in the dump output, and indent to an appropriate
  121. place to start printing more fields. */
  122. static void
  123. dump_new_line (dump_info_p di)
  124. {
  125. fprintf (di->stream, "\n%*s", SOL_COLUMN, "");
  126. di->column = SOL_COLUMN;
  127. }
  128. /* If necessary, insert a new line. */
  129. static void
  130. dump_maybe_newline (dump_info_p di)
  131. {
  132. int extra;
  133. /* See if we need a new line. */
  134. if (di->column > EOL_COLUMN)
  135. dump_new_line (di);
  136. /* See if we need any padding. */
  137. else if ((extra = (di->column - SOL_COLUMN) % COLUMN_ALIGNMENT) != 0)
  138. {
  139. fprintf (di->stream, "%*s", COLUMN_ALIGNMENT - extra, "");
  140. di->column += COLUMN_ALIGNMENT - extra;
  141. }
  142. }
  143. /* Dump FUNCTION_DECL FN as tree dump PHASE. */
  144. void
  145. dump_function (int phase, tree fn)
  146. {
  147. FILE *stream;
  148. int flags;
  149. stream = dump_begin (phase, &flags);
  150. if (stream)
  151. {
  152. dump_function_to_file (fn, stream, flags);
  153. dump_end (phase, stream);
  154. }
  155. }
  156. /* Dump pointer PTR using FIELD to identify it. */
  157. void
  158. dump_pointer (dump_info_p di, const char *field, void *ptr)
  159. {
  160. dump_maybe_newline (di);
  161. fprintf (di->stream, "%-4s: %-8" HOST_WIDE_INT_PRINT "x ", field,
  162. (unsigned HOST_WIDE_INT) (uintptr_t) ptr);
  163. di->column += 15;
  164. }
  165. /* Dump integer I using FIELD to identify it. */
  166. void
  167. dump_int (dump_info_p di, const char *field, int i)
  168. {
  169. dump_maybe_newline (di);
  170. fprintf (di->stream, "%-4s: %-7d ", field, i);
  171. di->column += 14;
  172. }
  173. /* Dump the floating point value R, using FIELD to identify it. */
  174. static void
  175. dump_real (dump_info_p di, const char *field, const REAL_VALUE_TYPE *r)
  176. {
  177. char buf[32];
  178. real_to_decimal (buf, r, sizeof (buf), 0, true);
  179. dump_maybe_newline (di);
  180. fprintf (di->stream, "%-4s: %s ", field, buf);
  181. di->column += strlen (buf) + 7;
  182. }
  183. /* Dump the fixed-point value F, using FIELD to identify it. */
  184. static void
  185. dump_fixed (dump_info_p di, const char *field, const FIXED_VALUE_TYPE *f)
  186. {
  187. char buf[32];
  188. fixed_to_decimal (buf, f, sizeof (buf));
  189. dump_maybe_newline (di);
  190. fprintf (di->stream, "%-4s: %s ", field, buf);
  191. di->column += strlen (buf) + 7;
  192. }
  193. /* Dump the string S. */
  194. void
  195. dump_string (dump_info_p di, const char *string)
  196. {
  197. dump_maybe_newline (di);
  198. fprintf (di->stream, "%-13s ", string);
  199. if (strlen (string) > 13)
  200. di->column += strlen (string) + 1;
  201. else
  202. di->column += 14;
  203. }
  204. /* Dump the string field S. */
  205. void
  206. dump_string_field (dump_info_p di, const char *field, const char *string)
  207. {
  208. dump_maybe_newline (di);
  209. fprintf (di->stream, "%-4s: %-7s ", field, string);
  210. if (strlen (string) > 7)
  211. di->column += 6 + strlen (string) + 1;
  212. else
  213. di->column += 14;
  214. }
  215. /* Dump the next node in the queue. */
  216. static void
  217. dequeue_and_dump (dump_info_p di)
  218. {
  219. dump_queue_p dq;
  220. splay_tree_node stn;
  221. dump_node_info_p dni;
  222. tree t;
  223. unsigned int index;
  224. enum tree_code code;
  225. enum tree_code_class code_class;
  226. const char* code_name;
  227. /* Get the next node from the queue. */
  228. dq = di->queue;
  229. stn = dq->node;
  230. t = (tree) stn->key;
  231. dni = (dump_node_info_p) stn->value;
  232. index = dni->index;
  233. /* Remove the node from the queue, and put it on the free list. */
  234. di->queue = dq->next;
  235. if (!di->queue)
  236. di->queue_end = 0;
  237. dq->next = di->free_list;
  238. di->free_list = dq;
  239. /* Print the node index. */
  240. dump_index (di, index);
  241. /* And the type of node this is. */
  242. if (dni->binfo_p)
  243. code_name = "binfo";
  244. else
  245. code_name = get_tree_code_name (TREE_CODE (t));
  246. fprintf (di->stream, "%-16s ", code_name);
  247. di->column = 25;
  248. /* Figure out what kind of node this is. */
  249. code = TREE_CODE (t);
  250. code_class = TREE_CODE_CLASS (code);
  251. /* Although BINFOs are TREE_VECs, we dump them specially so as to be
  252. more informative. */
  253. if (dni->binfo_p)
  254. {
  255. unsigned ix;
  256. tree base;
  257. vec<tree, va_gc> *accesses = BINFO_BASE_ACCESSES (t);
  258. dump_child ("type", BINFO_TYPE (t));
  259. if (BINFO_VIRTUAL_P (t))
  260. dump_string_field (di, "spec", "virt");
  261. dump_int (di, "bases", BINFO_N_BASE_BINFOS (t));
  262. for (ix = 0; BINFO_BASE_ITERATE (t, ix, base); ix++)
  263. {
  264. tree access = (accesses ? (*accesses)[ix] : access_public_node);
  265. const char *string = NULL;
  266. if (access == access_public_node)
  267. string = "pub";
  268. else if (access == access_protected_node)
  269. string = "prot";
  270. else if (access == access_private_node)
  271. string = "priv";
  272. else
  273. gcc_unreachable ();
  274. dump_string_field (di, "accs", string);
  275. queue_and_dump_index (di, "binf", base, DUMP_BINFO);
  276. }
  277. goto done;
  278. }
  279. /* We can knock off a bunch of expression nodes in exactly the same
  280. way. */
  281. if (IS_EXPR_CODE_CLASS (code_class))
  282. {
  283. /* If we're dumping children, dump them now. */
  284. queue_and_dump_type (di, t);
  285. switch (code_class)
  286. {
  287. case tcc_unary:
  288. dump_child ("op 0", TREE_OPERAND (t, 0));
  289. break;
  290. case tcc_binary:
  291. case tcc_comparison:
  292. dump_child ("op 0", TREE_OPERAND (t, 0));
  293. dump_child ("op 1", TREE_OPERAND (t, 1));
  294. break;
  295. case tcc_expression:
  296. case tcc_reference:
  297. case tcc_statement:
  298. case tcc_vl_exp:
  299. /* These nodes are handled explicitly below. */
  300. break;
  301. default:
  302. gcc_unreachable ();
  303. }
  304. }
  305. else if (DECL_P (t))
  306. {
  307. expanded_location xloc;
  308. /* All declarations have names. */
  309. if (DECL_NAME (t))
  310. dump_child ("name", DECL_NAME (t));
  311. if (DECL_ASSEMBLER_NAME_SET_P (t)
  312. && DECL_ASSEMBLER_NAME (t) != DECL_NAME (t))
  313. dump_child ("mngl", DECL_ASSEMBLER_NAME (t));
  314. if (DECL_ABSTRACT_ORIGIN (t))
  315. dump_child ("orig", DECL_ABSTRACT_ORIGIN (t));
  316. /* And types. */
  317. queue_and_dump_type (di, t);
  318. dump_child ("scpe", DECL_CONTEXT (t));
  319. /* And a source position. */
  320. xloc = expand_location (DECL_SOURCE_LOCATION (t));
  321. if (xloc.file)
  322. {
  323. const char *filename = lbasename (xloc.file);
  324. dump_maybe_newline (di);
  325. fprintf (di->stream, "srcp: %s:%-6d ", filename,
  326. xloc.line);
  327. di->column += 6 + strlen (filename) + 8;
  328. }
  329. /* And any declaration can be compiler-generated. */
  330. if (CODE_CONTAINS_STRUCT (TREE_CODE (t), TS_DECL_COMMON)
  331. && DECL_ARTIFICIAL (t))
  332. dump_string_field (di, "note", "artificial");
  333. if (DECL_CHAIN (t) && !dump_flag (di, TDF_SLIM, NULL))
  334. dump_child ("chain", DECL_CHAIN (t));
  335. }
  336. else if (code_class == tcc_type)
  337. {
  338. /* All types have qualifiers. */
  339. int quals = lang_hooks.tree_dump.type_quals (t);
  340. if (quals != TYPE_UNQUALIFIED)
  341. {
  342. fprintf (di->stream, "qual: %c%c%c ",
  343. (quals & TYPE_QUAL_CONST) ? 'c' : ' ',
  344. (quals & TYPE_QUAL_VOLATILE) ? 'v' : ' ',
  345. (quals & TYPE_QUAL_RESTRICT) ? 'r' : ' ');
  346. di->column += 14;
  347. }
  348. /* All types have associated declarations. */
  349. dump_child ("name", TYPE_NAME (t));
  350. /* All types have a main variant. */
  351. if (TYPE_MAIN_VARIANT (t) != t)
  352. dump_child ("unql", TYPE_MAIN_VARIANT (t));
  353. /* And sizes. */
  354. dump_child ("size", TYPE_SIZE (t));
  355. /* All types have alignments. */
  356. dump_int (di, "algn", TYPE_ALIGN (t));
  357. }
  358. else if (code_class == tcc_constant)
  359. /* All constants can have types. */
  360. queue_and_dump_type (di, t);
  361. /* Give the language-specific code a chance to print something. If
  362. it's completely taken care of things, don't bother printing
  363. anything more ourselves. */
  364. if (lang_hooks.tree_dump.dump_tree (di, t))
  365. goto done;
  366. /* Now handle the various kinds of nodes. */
  367. switch (code)
  368. {
  369. int i;
  370. case IDENTIFIER_NODE:
  371. dump_string_field (di, "strg", IDENTIFIER_POINTER (t));
  372. dump_int (di, "lngt", IDENTIFIER_LENGTH (t));
  373. break;
  374. case TREE_LIST:
  375. dump_child ("purp", TREE_PURPOSE (t));
  376. dump_child ("valu", TREE_VALUE (t));
  377. dump_child ("chan", TREE_CHAIN (t));
  378. break;
  379. case STATEMENT_LIST:
  380. {
  381. tree_stmt_iterator it;
  382. for (i = 0, it = tsi_start (t); !tsi_end_p (it); tsi_next (&it), i++)
  383. {
  384. char buffer[32];
  385. sprintf (buffer, "%u", i);
  386. dump_child (buffer, tsi_stmt (it));
  387. }
  388. }
  389. break;
  390. case TREE_VEC:
  391. dump_int (di, "lngt", TREE_VEC_LENGTH (t));
  392. for (i = 0; i < TREE_VEC_LENGTH (t); ++i)
  393. {
  394. char buffer[32];
  395. sprintf (buffer, "%u", i);
  396. dump_child (buffer, TREE_VEC_ELT (t, i));
  397. }
  398. break;
  399. case INTEGER_TYPE:
  400. case ENUMERAL_TYPE:
  401. dump_int (di, "prec", TYPE_PRECISION (t));
  402. dump_string_field (di, "sign", TYPE_UNSIGNED (t) ? "unsigned": "signed");
  403. dump_child ("min", TYPE_MIN_VALUE (t));
  404. dump_child ("max", TYPE_MAX_VALUE (t));
  405. if (code == ENUMERAL_TYPE)
  406. dump_child ("csts", TYPE_VALUES (t));
  407. break;
  408. case REAL_TYPE:
  409. dump_int (di, "prec", TYPE_PRECISION (t));
  410. break;
  411. case FIXED_POINT_TYPE:
  412. dump_int (di, "prec", TYPE_PRECISION (t));
  413. dump_string_field (di, "sign", TYPE_UNSIGNED (t) ? "unsigned": "signed");
  414. dump_string_field (di, "saturating",
  415. TYPE_SATURATING (t) ? "saturating": "non-saturating");
  416. break;
  417. case POINTER_TYPE:
  418. dump_child ("ptd", TREE_TYPE (t));
  419. break;
  420. case REFERENCE_TYPE:
  421. dump_child ("refd", TREE_TYPE (t));
  422. break;
  423. case METHOD_TYPE:
  424. dump_child ("clas", TYPE_METHOD_BASETYPE (t));
  425. /* Fall through. */
  426. case FUNCTION_TYPE:
  427. dump_child ("retn", TREE_TYPE (t));
  428. dump_child ("prms", TYPE_ARG_TYPES (t));
  429. break;
  430. case ARRAY_TYPE:
  431. dump_child ("elts", TREE_TYPE (t));
  432. dump_child ("domn", TYPE_DOMAIN (t));
  433. break;
  434. case RECORD_TYPE:
  435. case UNION_TYPE:
  436. if (TREE_CODE (t) == RECORD_TYPE)
  437. dump_string_field (di, "tag", "struct");
  438. else
  439. dump_string_field (di, "tag", "union");
  440. dump_child ("flds", TYPE_FIELDS (t));
  441. dump_child ("fncs", TYPE_METHODS (t));
  442. queue_and_dump_index (di, "binf", TYPE_BINFO (t),
  443. DUMP_BINFO);
  444. break;
  445. case CONST_DECL:
  446. dump_child ("cnst", DECL_INITIAL (t));
  447. break;
  448. case DEBUG_EXPR_DECL:
  449. dump_int (di, "-uid", DEBUG_TEMP_UID (t));
  450. /* Fall through. */
  451. case VAR_DECL:
  452. case PARM_DECL:
  453. case FIELD_DECL:
  454. case RESULT_DECL:
  455. if (TREE_CODE (t) == PARM_DECL)
  456. dump_child ("argt", DECL_ARG_TYPE (t));
  457. else
  458. dump_child ("init", DECL_INITIAL (t));
  459. dump_child ("size", DECL_SIZE (t));
  460. dump_int (di, "algn", DECL_ALIGN (t));
  461. if (TREE_CODE (t) == FIELD_DECL)
  462. {
  463. if (DECL_FIELD_OFFSET (t))
  464. dump_child ("bpos", bit_position (t));
  465. }
  466. else if (TREE_CODE (t) == VAR_DECL
  467. || TREE_CODE (t) == PARM_DECL)
  468. {
  469. dump_int (di, "used", TREE_USED (t));
  470. if (DECL_REGISTER (t))
  471. dump_string_field (di, "spec", "register");
  472. }
  473. break;
  474. case FUNCTION_DECL:
  475. dump_child ("args", DECL_ARGUMENTS (t));
  476. if (DECL_EXTERNAL (t))
  477. dump_string_field (di, "body", "undefined");
  478. if (TREE_PUBLIC (t))
  479. dump_string_field (di, "link", "extern");
  480. else
  481. dump_string_field (di, "link", "static");
  482. if (DECL_SAVED_TREE (t) && !dump_flag (di, TDF_SLIM, t))
  483. dump_child ("body", DECL_SAVED_TREE (t));
  484. break;
  485. case INTEGER_CST:
  486. fprintf (di->stream, "int: ");
  487. print_decs (t, di->stream);
  488. break;
  489. case STRING_CST:
  490. fprintf (di->stream, "strg: %-7s ", TREE_STRING_POINTER (t));
  491. dump_int (di, "lngt", TREE_STRING_LENGTH (t));
  492. break;
  493. case REAL_CST:
  494. dump_real (di, "valu", TREE_REAL_CST_PTR (t));
  495. break;
  496. case FIXED_CST:
  497. dump_fixed (di, "valu", TREE_FIXED_CST_PTR (t));
  498. break;
  499. case TRUTH_NOT_EXPR:
  500. case ADDR_EXPR:
  501. case INDIRECT_REF:
  502. case CLEANUP_POINT_EXPR:
  503. case SAVE_EXPR:
  504. case REALPART_EXPR:
  505. case IMAGPART_EXPR:
  506. /* These nodes are unary, but do not have code class `1'. */
  507. dump_child ("op 0", TREE_OPERAND (t, 0));
  508. break;
  509. case TRUTH_ANDIF_EXPR:
  510. case TRUTH_ORIF_EXPR:
  511. case INIT_EXPR:
  512. case MODIFY_EXPR:
  513. case COMPOUND_EXPR:
  514. case PREDECREMENT_EXPR:
  515. case PREINCREMENT_EXPR:
  516. case POSTDECREMENT_EXPR:
  517. case POSTINCREMENT_EXPR:
  518. /* These nodes are binary, but do not have code class `2'. */
  519. dump_child ("op 0", TREE_OPERAND (t, 0));
  520. dump_child ("op 1", TREE_OPERAND (t, 1));
  521. break;
  522. case COMPONENT_REF:
  523. case BIT_FIELD_REF:
  524. dump_child ("op 0", TREE_OPERAND (t, 0));
  525. dump_child ("op 1", TREE_OPERAND (t, 1));
  526. dump_child ("op 2", TREE_OPERAND (t, 2));
  527. break;
  528. case ARRAY_REF:
  529. case ARRAY_RANGE_REF:
  530. dump_child ("op 0", TREE_OPERAND (t, 0));
  531. dump_child ("op 1", TREE_OPERAND (t, 1));
  532. dump_child ("op 2", TREE_OPERAND (t, 2));
  533. dump_child ("op 3", TREE_OPERAND (t, 3));
  534. break;
  535. case COND_EXPR:
  536. dump_child ("op 0", TREE_OPERAND (t, 0));
  537. dump_child ("op 1", TREE_OPERAND (t, 1));
  538. dump_child ("op 2", TREE_OPERAND (t, 2));
  539. break;
  540. case TRY_FINALLY_EXPR:
  541. dump_child ("op 0", TREE_OPERAND (t, 0));
  542. dump_child ("op 1", TREE_OPERAND (t, 1));
  543. break;
  544. case CALL_EXPR:
  545. {
  546. int i = 0;
  547. tree arg;
  548. call_expr_arg_iterator iter;
  549. dump_child ("fn", CALL_EXPR_FN (t));
  550. FOR_EACH_CALL_EXPR_ARG (arg, iter, t)
  551. {
  552. char buffer[32];
  553. sprintf (buffer, "%u", i);
  554. dump_child (buffer, arg);
  555. i++;
  556. }
  557. }
  558. break;
  559. case CONSTRUCTOR:
  560. {
  561. unsigned HOST_WIDE_INT cnt;
  562. tree index, value;
  563. dump_int (di, "lngt", vec_safe_length (CONSTRUCTOR_ELTS (t)));
  564. FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (t), cnt, index, value)
  565. {
  566. dump_child ("idx", index);
  567. dump_child ("val", value);
  568. }
  569. }
  570. break;
  571. case BIND_EXPR:
  572. dump_child ("vars", TREE_OPERAND (t, 0));
  573. dump_child ("body", TREE_OPERAND (t, 1));
  574. break;
  575. case LOOP_EXPR:
  576. dump_child ("body", TREE_OPERAND (t, 0));
  577. break;
  578. case EXIT_EXPR:
  579. dump_child ("cond", TREE_OPERAND (t, 0));
  580. break;
  581. case RETURN_EXPR:
  582. dump_child ("expr", TREE_OPERAND (t, 0));
  583. break;
  584. case TARGET_EXPR:
  585. dump_child ("decl", TREE_OPERAND (t, 0));
  586. dump_child ("init", TREE_OPERAND (t, 1));
  587. dump_child ("clnp", TREE_OPERAND (t, 2));
  588. /* There really are two possible places the initializer can be.
  589. After RTL expansion, the second operand is moved to the
  590. position of the fourth operand, and the second operand
  591. becomes NULL. */
  592. dump_child ("init", TREE_OPERAND (t, 3));
  593. break;
  594. case CASE_LABEL_EXPR:
  595. dump_child ("name", CASE_LABEL (t));
  596. if (CASE_LOW (t))
  597. {
  598. dump_child ("low ", CASE_LOW (t));
  599. if (CASE_HIGH (t))
  600. dump_child ("high", CASE_HIGH (t));
  601. }
  602. break;
  603. case LABEL_EXPR:
  604. dump_child ("name", TREE_OPERAND (t,0));
  605. break;
  606. case GOTO_EXPR:
  607. dump_child ("labl", TREE_OPERAND (t, 0));
  608. break;
  609. case SWITCH_EXPR:
  610. dump_child ("cond", TREE_OPERAND (t, 0));
  611. dump_child ("body", TREE_OPERAND (t, 1));
  612. if (TREE_OPERAND (t, 2))
  613. {
  614. dump_child ("labl", TREE_OPERAND (t,2));
  615. }
  616. break;
  617. case OMP_CLAUSE:
  618. {
  619. int i;
  620. fprintf (di->stream, "%s\n", omp_clause_code_name[OMP_CLAUSE_CODE (t)]);
  621. for (i = 0; i < omp_clause_num_ops[OMP_CLAUSE_CODE (t)]; i++)
  622. dump_child ("op: ", OMP_CLAUSE_OPERAND (t, i));
  623. }
  624. break;
  625. default:
  626. /* There are no additional fields to print. */
  627. break;
  628. }
  629. done:
  630. if (dump_flag (di, TDF_ADDRESS, NULL))
  631. dump_pointer (di, "addr", (void *)t);
  632. /* Terminate the line. */
  633. fprintf (di->stream, "\n");
  634. }
  635. /* Return nonzero if FLAG has been specified for the dump, and NODE
  636. is not the root node of the dump. */
  637. int dump_flag (dump_info_p di, int flag, const_tree node)
  638. {
  639. return (di->flags & flag) && (node != di->node);
  640. }
  641. /* Dump T, and all its children, on STREAM. */
  642. void
  643. dump_node (const_tree t, int flags, FILE *stream)
  644. {
  645. struct dump_info di;
  646. dump_queue_p dq;
  647. dump_queue_p next_dq;
  648. /* Initialize the dump-information structure. */
  649. di.stream = stream;
  650. di.index = 0;
  651. di.column = 0;
  652. di.queue = 0;
  653. di.queue_end = 0;
  654. di.free_list = 0;
  655. di.flags = flags;
  656. di.node = t;
  657. di.nodes = splay_tree_new (splay_tree_compare_pointers, 0,
  658. (splay_tree_delete_value_fn) &free);
  659. /* Queue up the first node. */
  660. queue (&di, t, DUMP_NONE);
  661. /* Until the queue is empty, keep dumping nodes. */
  662. while (di.queue)
  663. dequeue_and_dump (&di);
  664. /* Now, clean up. */
  665. for (dq = di.free_list; dq; dq = next_dq)
  666. {
  667. next_dq = dq->next;
  668. free (dq);
  669. }
  670. splay_tree_delete (di.nodes);
  671. }