Merge trunk version 213968 into gupc branch.
[official-gcc.git] / gcc / tree-dump.c
blob70be5f5a4d7ed5ddcdb767578f7f953688797326
1 /* Tree-dumping functionality for intermediate representation.
2 Copyright (C) 1999-2014 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 "tree.h"
26 #include "splay-tree.h"
27 #include "filenames.h"
28 #include "tree-dump.h"
29 #include "langhooks.h"
30 #include "tree-iterator.h"
31 #include "tree-pretty-print.h"
32 #include "tree-cfg.h"
33 #include "wide-int.h"
34 #include "wide-int-print.h"
36 static unsigned int queue (dump_info_p, const_tree, int);
37 static void dump_index (dump_info_p, unsigned int);
38 static void dequeue_and_dump (dump_info_p);
39 static void dump_new_line (dump_info_p);
40 static void dump_maybe_newline (dump_info_p);
42 /* Add T to the end of the queue of nodes to dump. Returns the index
43 assigned to T. */
45 static unsigned int
46 queue (dump_info_p di, const_tree t, int flags)
48 dump_queue_p dq;
49 dump_node_info_p dni;
50 unsigned int index;
52 /* Assign the next available index to T. */
53 index = ++di->index;
55 /* Obtain a new queue node. */
56 if (di->free_list)
58 dq = di->free_list;
59 di->free_list = dq->next;
61 else
62 dq = XNEW (struct dump_queue);
64 /* Create a new entry in the splay-tree. */
65 dni = XNEW (struct dump_node_info);
66 dni->index = index;
67 dni->binfo_p = ((flags & DUMP_BINFO) != 0);
68 dq->node = splay_tree_insert (di->nodes, (splay_tree_key) t,
69 (splay_tree_value) dni);
71 /* Add it to the end of the queue. */
72 dq->next = 0;
73 if (!di->queue_end)
74 di->queue = dq;
75 else
76 di->queue_end->next = dq;
77 di->queue_end = dq;
79 /* Return the index. */
80 return index;
83 static void
84 dump_index (dump_info_p di, unsigned int index)
86 fprintf (di->stream, "@%-6u ", index);
87 di->column += 8;
90 /* If T has not already been output, queue it for subsequent output.
91 FIELD is a string to print before printing the index. Then, the
92 index of T is printed. */
94 void
95 queue_and_dump_index (dump_info_p di, const char *field, const_tree t, int flags)
97 unsigned int index;
98 splay_tree_node n;
100 /* If there's no node, just return. This makes for fewer checks in
101 our callers. */
102 if (!t)
103 return;
105 /* See if we've already queued or dumped this node. */
106 n = splay_tree_lookup (di->nodes, (splay_tree_key) t);
107 if (n)
108 index = ((dump_node_info_p) n->value)->index;
109 else
110 /* If we haven't, add it to the queue. */
111 index = queue (di, t, flags);
113 /* Print the index of the node. */
114 dump_maybe_newline (di);
115 fprintf (di->stream, "%-4s: ", field);
116 di->column += 6;
117 dump_index (di, index);
120 /* Dump the type of T. */
122 void
123 queue_and_dump_type (dump_info_p di, const_tree t)
125 queue_and_dump_index (di, "type", TREE_TYPE (t), DUMP_NONE);
128 /* Dump column control */
129 #define SOL_COLUMN 25 /* Start of line column. */
130 #define EOL_COLUMN 55 /* End of line column. */
131 #define COLUMN_ALIGNMENT 15 /* Alignment. */
133 /* Insert a new line in the dump output, and indent to an appropriate
134 place to start printing more fields. */
136 static void
137 dump_new_line (dump_info_p di)
139 fprintf (di->stream, "\n%*s", SOL_COLUMN, "");
140 di->column = SOL_COLUMN;
143 /* If necessary, insert a new line. */
145 static void
146 dump_maybe_newline (dump_info_p di)
148 int extra;
150 /* See if we need a new line. */
151 if (di->column > EOL_COLUMN)
152 dump_new_line (di);
153 /* See if we need any padding. */
154 else if ((extra = (di->column - SOL_COLUMN) % COLUMN_ALIGNMENT) != 0)
156 fprintf (di->stream, "%*s", COLUMN_ALIGNMENT - extra, "");
157 di->column += COLUMN_ALIGNMENT - extra;
161 /* Dump FUNCTION_DECL FN as tree dump PHASE. */
163 void
164 dump_function (int phase, tree fn)
166 FILE *stream;
167 int flags;
169 stream = dump_begin (phase, &flags);
170 if (stream)
172 dump_function_to_file (fn, stream, flags);
173 dump_end (phase, stream);
177 /* Dump pointer PTR using FIELD to identify it. */
179 void
180 dump_pointer (dump_info_p di, const char *field, void *ptr)
182 dump_maybe_newline (di);
183 fprintf (di->stream, "%-4s: %-8" HOST_WIDE_INT_PRINT "x ", field,
184 (unsigned HOST_WIDE_INT) (uintptr_t) ptr);
185 di->column += 15;
188 /* Dump integer I using FIELD to identify it. */
190 void
191 dump_int (dump_info_p di, const char *field, int i)
193 dump_maybe_newline (di);
194 fprintf (di->stream, "%-4s: %-7d ", field, i);
195 di->column += 14;
198 /* Dump the floating point value R, using FIELD to identify it. */
200 static void
201 dump_real (dump_info_p di, const char *field, const REAL_VALUE_TYPE *r)
203 char buf[32];
204 real_to_decimal (buf, r, sizeof (buf), 0, true);
205 dump_maybe_newline (di);
206 fprintf (di->stream, "%-4s: %s ", field, buf);
207 di->column += strlen (buf) + 7;
210 /* Dump the fixed-point value F, using FIELD to identify it. */
212 static void
213 dump_fixed (dump_info_p di, const char *field, const FIXED_VALUE_TYPE *f)
215 char buf[32];
216 fixed_to_decimal (buf, f, sizeof (buf));
217 dump_maybe_newline (di);
218 fprintf (di->stream, "%-4s: %s ", field, buf);
219 di->column += strlen (buf) + 7;
223 /* Dump the string S. */
225 void
226 dump_string (dump_info_p di, const char *string)
228 dump_maybe_newline (di);
229 fprintf (di->stream, "%-13s ", string);
230 if (strlen (string) > 13)
231 di->column += strlen (string) + 1;
232 else
233 di->column += 14;
236 /* Dump the string field S. */
238 void
239 dump_string_field (dump_info_p di, const char *field, const char *string)
241 dump_maybe_newline (di);
242 fprintf (di->stream, "%-4s: %-7s ", field, string);
243 if (strlen (string) > 7)
244 di->column += 6 + strlen (string) + 1;
245 else
246 di->column += 14;
249 /* Dump the next node in the queue. */
251 static void
252 dequeue_and_dump (dump_info_p di)
254 dump_queue_p dq;
255 splay_tree_node stn;
256 dump_node_info_p dni;
257 tree t;
258 unsigned int index;
259 enum tree_code code;
260 enum tree_code_class code_class;
261 const char* code_name;
263 /* Get the next node from the queue. */
264 dq = di->queue;
265 stn = dq->node;
266 t = (tree) stn->key;
267 dni = (dump_node_info_p) stn->value;
268 index = dni->index;
270 /* Remove the node from the queue, and put it on the free list. */
271 di->queue = dq->next;
272 if (!di->queue)
273 di->queue_end = 0;
274 dq->next = di->free_list;
275 di->free_list = dq;
277 /* Print the node index. */
278 dump_index (di, index);
279 /* And the type of node this is. */
280 if (dni->binfo_p)
281 code_name = "binfo";
282 else
283 code_name = get_tree_code_name (TREE_CODE (t));
284 fprintf (di->stream, "%-16s ", code_name);
285 di->column = 25;
287 /* Figure out what kind of node this is. */
288 code = TREE_CODE (t);
289 code_class = TREE_CODE_CLASS (code);
291 /* Although BINFOs are TREE_VECs, we dump them specially so as to be
292 more informative. */
293 if (dni->binfo_p)
295 unsigned ix;
296 tree base;
297 vec<tree, va_gc> *accesses = BINFO_BASE_ACCESSES (t);
299 dump_child ("type", BINFO_TYPE (t));
301 if (BINFO_VIRTUAL_P (t))
302 dump_string_field (di, "spec", "virt");
304 dump_int (di, "bases", BINFO_N_BASE_BINFOS (t));
305 for (ix = 0; BINFO_BASE_ITERATE (t, ix, base); ix++)
307 tree access = (accesses ? (*accesses)[ix] : access_public_node);
308 const char *string = NULL;
310 if (access == access_public_node)
311 string = "pub";
312 else if (access == access_protected_node)
313 string = "prot";
314 else if (access == access_private_node)
315 string = "priv";
316 else
317 gcc_unreachable ();
319 dump_string_field (di, "accs", string);
320 queue_and_dump_index (di, "binf", base, DUMP_BINFO);
323 goto done;
326 /* We can knock off a bunch of expression nodes in exactly the same
327 way. */
328 if (IS_EXPR_CODE_CLASS (code_class))
330 /* If we're dumping children, dump them now. */
331 queue_and_dump_type (di, t);
333 switch (code_class)
335 case tcc_unary:
336 dump_child ("op 0", TREE_OPERAND (t, 0));
337 break;
339 case tcc_binary:
340 case tcc_comparison:
341 dump_child ("op 0", TREE_OPERAND (t, 0));
342 dump_child ("op 1", TREE_OPERAND (t, 1));
343 break;
345 case tcc_expression:
346 case tcc_reference:
347 case tcc_statement:
348 case tcc_vl_exp:
349 /* These nodes are handled explicitly below. */
350 break;
352 default:
353 gcc_unreachable ();
356 else if (DECL_P (t))
358 expanded_location xloc;
359 /* All declarations have names. */
360 if (DECL_NAME (t))
361 dump_child ("name", DECL_NAME (t));
362 if (DECL_ASSEMBLER_NAME_SET_P (t)
363 && DECL_ASSEMBLER_NAME (t) != DECL_NAME (t))
364 dump_child ("mngl", DECL_ASSEMBLER_NAME (t));
365 if (DECL_ABSTRACT_ORIGIN (t))
366 dump_child ("orig", DECL_ABSTRACT_ORIGIN (t));
367 /* And types. */
368 queue_and_dump_type (di, t);
369 dump_child ("scpe", DECL_CONTEXT (t));
370 /* And a source position. */
371 xloc = expand_location (DECL_SOURCE_LOCATION (t));
372 if (xloc.file)
374 const char *filename = lbasename (xloc.file);
376 dump_maybe_newline (di);
377 fprintf (di->stream, "srcp: %s:%-6d ", filename,
378 xloc.line);
379 di->column += 6 + strlen (filename) + 8;
381 /* And any declaration can be compiler-generated. */
382 if (CODE_CONTAINS_STRUCT (TREE_CODE (t), TS_DECL_COMMON)
383 && DECL_ARTIFICIAL (t))
384 dump_string_field (di, "note", "artificial");
385 if (DECL_CHAIN (t) && !dump_flag (di, TDF_SLIM, NULL))
386 dump_child ("chain", DECL_CHAIN (t));
388 else if (code_class == tcc_type)
390 /* All types have qualifiers. */
391 int quals = lang_hooks.tree_dump.type_quals (t);
393 if (quals != TYPE_UNQUALIFIED)
395 fprintf (di->stream, "qual: %c%c%c%c%c%c ",
396 (quals & TYPE_QUAL_CONST) ? 'c' : ' ',
397 (quals & TYPE_QUAL_VOLATILE) ? 'v' : ' ',
398 (quals & TYPE_QUAL_RESTRICT) ? 'r' : ' ',
399 (quals & TYPE_QUAL_UPC_SHARED) ? 's' : ' ',
400 (quals & TYPE_QUAL_UPC_STRICT) ? 't' : ' ',
401 (quals & TYPE_QUAL_UPC_RELAXED) ? 'x' : ' ');
402 di->column += 14;
405 /* All types have associated declarations. */
406 dump_child ("name", TYPE_NAME (t));
408 /* All types have a main variant. */
409 if (TYPE_MAIN_VARIANT (t) != t)
410 dump_child ("unql", TYPE_MAIN_VARIANT (t));
412 /* And sizes. */
413 dump_child ("size", TYPE_SIZE (t));
415 /* All types have alignments. */
416 dump_int (di, "algn", TYPE_ALIGN (t));
418 else if (code_class == tcc_constant)
419 /* All constants can have types. */
420 queue_and_dump_type (di, t);
422 /* Give the language-specific code a chance to print something. If
423 it's completely taken care of things, don't bother printing
424 anything more ourselves. */
425 if (lang_hooks.tree_dump.dump_tree (di, t))
426 goto done;
428 /* Now handle the various kinds of nodes. */
429 switch (code)
431 int i;
433 case IDENTIFIER_NODE:
434 dump_string_field (di, "strg", IDENTIFIER_POINTER (t));
435 dump_int (di, "lngt", IDENTIFIER_LENGTH (t));
436 break;
438 case TREE_LIST:
439 dump_child ("purp", TREE_PURPOSE (t));
440 dump_child ("valu", TREE_VALUE (t));
441 dump_child ("chan", TREE_CHAIN (t));
442 break;
444 case STATEMENT_LIST:
446 tree_stmt_iterator it;
447 for (i = 0, it = tsi_start (t); !tsi_end_p (it); tsi_next (&it), i++)
449 char buffer[32];
450 sprintf (buffer, "%u", i);
451 dump_child (buffer, tsi_stmt (it));
454 break;
456 case TREE_VEC:
457 dump_int (di, "lngt", TREE_VEC_LENGTH (t));
458 for (i = 0; i < TREE_VEC_LENGTH (t); ++i)
460 char buffer[32];
461 sprintf (buffer, "%u", i);
462 dump_child (buffer, TREE_VEC_ELT (t, i));
464 break;
466 case INTEGER_TYPE:
467 case ENUMERAL_TYPE:
468 dump_int (di, "prec", TYPE_PRECISION (t));
469 dump_string_field (di, "sign", TYPE_UNSIGNED (t) ? "unsigned": "signed");
470 dump_child ("min", TYPE_MIN_VALUE (t));
471 dump_child ("max", TYPE_MAX_VALUE (t));
473 if (code == ENUMERAL_TYPE)
474 dump_child ("csts", TYPE_VALUES (t));
475 break;
477 case REAL_TYPE:
478 dump_int (di, "prec", TYPE_PRECISION (t));
479 break;
481 case FIXED_POINT_TYPE:
482 dump_int (di, "prec", TYPE_PRECISION (t));
483 dump_string_field (di, "sign", TYPE_UNSIGNED (t) ? "unsigned": "signed");
484 dump_string_field (di, "saturating",
485 TYPE_SATURATING (t) ? "saturating": "non-saturating");
486 break;
488 case POINTER_TYPE:
489 dump_child ("ptd", TREE_TYPE (t));
490 break;
492 case REFERENCE_TYPE:
493 dump_child ("refd", TREE_TYPE (t));
494 break;
496 case METHOD_TYPE:
497 dump_child ("clas", TYPE_METHOD_BASETYPE (t));
498 /* Fall through. */
500 case FUNCTION_TYPE:
501 dump_child ("retn", TREE_TYPE (t));
502 dump_child ("prms", TYPE_ARG_TYPES (t));
503 break;
505 case ARRAY_TYPE:
506 dump_child ("elts", TREE_TYPE (t));
507 dump_child ("domn", TYPE_DOMAIN (t));
508 break;
510 case RECORD_TYPE:
511 case UNION_TYPE:
512 if (TREE_CODE (t) == RECORD_TYPE)
513 dump_string_field (di, "tag", "struct");
514 else
515 dump_string_field (di, "tag", "union");
517 dump_child ("flds", TYPE_FIELDS (t));
518 dump_child ("fncs", TYPE_METHODS (t));
519 queue_and_dump_index (di, "binf", TYPE_BINFO (t),
520 DUMP_BINFO);
521 break;
523 case CONST_DECL:
524 dump_child ("cnst", DECL_INITIAL (t));
525 break;
527 case DEBUG_EXPR_DECL:
528 dump_int (di, "-uid", DEBUG_TEMP_UID (t));
529 /* Fall through. */
531 case VAR_DECL:
532 case PARM_DECL:
533 case FIELD_DECL:
534 case RESULT_DECL:
535 if (TREE_CODE (t) == PARM_DECL)
536 dump_child ("argt", DECL_ARG_TYPE (t));
537 else
538 dump_child ("init", DECL_INITIAL (t));
539 dump_child ("size", DECL_SIZE (t));
540 dump_int (di, "algn", DECL_ALIGN (t));
542 if (TREE_CODE (t) == FIELD_DECL)
544 if (DECL_FIELD_OFFSET (t))
545 dump_child ("bpos", bit_position (t));
547 else if (TREE_CODE (t) == VAR_DECL
548 || TREE_CODE (t) == PARM_DECL)
550 dump_int (di, "used", TREE_USED (t));
551 if (DECL_REGISTER (t))
552 dump_string_field (di, "spec", "register");
554 break;
556 case FUNCTION_DECL:
557 dump_child ("args", DECL_ARGUMENTS (t));
558 if (DECL_EXTERNAL (t))
559 dump_string_field (di, "body", "undefined");
560 if (TREE_PUBLIC (t))
561 dump_string_field (di, "link", "extern");
562 else
563 dump_string_field (di, "link", "static");
564 if (DECL_SAVED_TREE (t) && !dump_flag (di, TDF_SLIM, t))
565 dump_child ("body", DECL_SAVED_TREE (t));
566 break;
568 case INTEGER_CST:
569 fprintf (di->stream, "int: ");
570 print_decs (t, di->stream);
571 break;
573 case STRING_CST:
574 fprintf (di->stream, "strg: %-7s ", TREE_STRING_POINTER (t));
575 dump_int (di, "lngt", TREE_STRING_LENGTH (t));
576 break;
578 case REAL_CST:
579 dump_real (di, "valu", TREE_REAL_CST_PTR (t));
580 break;
582 case FIXED_CST:
583 dump_fixed (di, "valu", TREE_FIXED_CST_PTR (t));
584 break;
586 case TRUTH_NOT_EXPR:
587 case ADDR_EXPR:
588 case INDIRECT_REF:
589 case CLEANUP_POINT_EXPR:
590 case SAVE_EXPR:
591 case REALPART_EXPR:
592 case IMAGPART_EXPR:
593 /* These nodes are unary, but do not have code class `1'. */
594 dump_child ("op 0", TREE_OPERAND (t, 0));
595 break;
597 case TRUTH_ANDIF_EXPR:
598 case TRUTH_ORIF_EXPR:
599 case INIT_EXPR:
600 case MODIFY_EXPR:
601 case COMPOUND_EXPR:
602 case PREDECREMENT_EXPR:
603 case PREINCREMENT_EXPR:
604 case POSTDECREMENT_EXPR:
605 case POSTINCREMENT_EXPR:
606 /* These nodes are binary, but do not have code class `2'. */
607 dump_child ("op 0", TREE_OPERAND (t, 0));
608 dump_child ("op 1", TREE_OPERAND (t, 1));
609 break;
611 case COMPONENT_REF:
612 case BIT_FIELD_REF:
613 dump_child ("op 0", TREE_OPERAND (t, 0));
614 dump_child ("op 1", TREE_OPERAND (t, 1));
615 dump_child ("op 2", TREE_OPERAND (t, 2));
616 break;
618 case ARRAY_REF:
619 case ARRAY_RANGE_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 dump_child ("op 3", TREE_OPERAND (t, 3));
624 break;
626 case COND_EXPR:
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 break;
632 case TRY_FINALLY_EXPR:
633 dump_child ("op 0", TREE_OPERAND (t, 0));
634 dump_child ("op 1", TREE_OPERAND (t, 1));
635 break;
637 case CALL_EXPR:
639 int i = 0;
640 tree arg;
641 call_expr_arg_iterator iter;
642 dump_child ("fn", CALL_EXPR_FN (t));
643 FOR_EACH_CALL_EXPR_ARG (arg, iter, t)
645 char buffer[32];
646 sprintf (buffer, "%u", i);
647 dump_child (buffer, arg);
648 i++;
651 break;
653 case CONSTRUCTOR:
655 unsigned HOST_WIDE_INT cnt;
656 tree index, value;
657 dump_int (di, "lngt", vec_safe_length (CONSTRUCTOR_ELTS (t)));
658 FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (t), cnt, index, value)
660 dump_child ("idx", index);
661 dump_child ("val", value);
664 break;
666 case BIND_EXPR:
667 dump_child ("vars", TREE_OPERAND (t, 0));
668 dump_child ("body", TREE_OPERAND (t, 1));
669 break;
671 case LOOP_EXPR:
672 dump_child ("body", TREE_OPERAND (t, 0));
673 break;
675 case EXIT_EXPR:
676 dump_child ("cond", TREE_OPERAND (t, 0));
677 break;
679 case RETURN_EXPR:
680 dump_child ("expr", TREE_OPERAND (t, 0));
681 break;
683 case TARGET_EXPR:
684 dump_child ("decl", TREE_OPERAND (t, 0));
685 dump_child ("init", TREE_OPERAND (t, 1));
686 dump_child ("clnp", TREE_OPERAND (t, 2));
687 /* There really are two possible places the initializer can be.
688 After RTL expansion, the second operand is moved to the
689 position of the fourth operand, and the second operand
690 becomes NULL. */
691 dump_child ("init", TREE_OPERAND (t, 3));
692 break;
694 case CASE_LABEL_EXPR:
695 dump_child ("name", CASE_LABEL (t));
696 if (CASE_LOW (t))
698 dump_child ("low ", CASE_LOW (t));
699 if (CASE_HIGH (t))
700 dump_child ("high", CASE_HIGH (t));
702 break;
703 case LABEL_EXPR:
704 dump_child ("name", TREE_OPERAND (t,0));
705 break;
706 case GOTO_EXPR:
707 dump_child ("labl", TREE_OPERAND (t, 0));
708 break;
709 case SWITCH_EXPR:
710 dump_child ("cond", TREE_OPERAND (t, 0));
711 dump_child ("body", TREE_OPERAND (t, 1));
712 if (TREE_OPERAND (t, 2))
714 dump_child ("labl", TREE_OPERAND (t,2));
716 break;
717 case OMP_CLAUSE:
719 int i;
720 fprintf (di->stream, "%s\n", omp_clause_code_name[OMP_CLAUSE_CODE (t)]);
721 for (i = 0; i < omp_clause_num_ops[OMP_CLAUSE_CODE (t)]; i++)
722 dump_child ("op: ", OMP_CLAUSE_OPERAND (t, i));
724 break;
725 default:
726 /* There are no additional fields to print. */
727 break;
730 done:
731 if (dump_flag (di, TDF_ADDRESS, NULL))
732 dump_pointer (di, "addr", (void *)t);
734 /* Terminate the line. */
735 fprintf (di->stream, "\n");
738 /* Return nonzero if FLAG has been specified for the dump, and NODE
739 is not the root node of the dump. */
741 int dump_flag (dump_info_p di, int flag, const_tree node)
743 return (di->flags & flag) && (node != di->node);
746 /* Dump T, and all its children, on STREAM. */
748 void
749 dump_node (const_tree t, int flags, FILE *stream)
751 struct dump_info di;
752 dump_queue_p dq;
753 dump_queue_p next_dq;
755 /* Initialize the dump-information structure. */
756 di.stream = stream;
757 di.index = 0;
758 di.column = 0;
759 di.queue = 0;
760 di.queue_end = 0;
761 di.free_list = 0;
762 di.flags = flags;
763 di.node = t;
764 di.nodes = splay_tree_new (splay_tree_compare_pointers, 0,
765 (splay_tree_delete_value_fn) &free);
767 /* Queue up the first node. */
768 queue (&di, t, DUMP_NONE);
770 /* Until the queue is empty, keep dumping nodes. */
771 while (di.queue)
772 dequeue_and_dump (&di);
774 /* Now, clean up. */
775 for (dq = di.free_list; dq; dq = next_dq)
777 next_dq = dq->next;
778 free (dq);
780 splay_tree_delete (di.nodes);