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