Update copyright notices.
[official-gcc.git] / gcc / tree-dump.c
blobe0edbd8f228042d932d86cb26ea5a1a2b0c7a126
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"
34 static unsigned int queue (dump_info_p, const_tree, int);
35 static void dump_index (dump_info_p, unsigned int);
36 static void dequeue_and_dump (dump_info_p);
37 static void dump_new_line (dump_info_p);
38 static void dump_maybe_newline (dump_info_p);
40 /* Add T to the end of the queue of nodes to dump. Returns the index
41 assigned to T. */
43 static unsigned int
44 queue (dump_info_p di, const_tree t, int flags)
46 dump_queue_p dq;
47 dump_node_info_p dni;
48 unsigned int index;
50 /* Assign the next available index to T. */
51 index = ++di->index;
53 /* Obtain a new queue node. */
54 if (di->free_list)
56 dq = di->free_list;
57 di->free_list = dq->next;
59 else
60 dq = XNEW (struct dump_queue);
62 /* Create a new entry in the splay-tree. */
63 dni = XNEW (struct dump_node_info);
64 dni->index = index;
65 dni->binfo_p = ((flags & DUMP_BINFO) != 0);
66 dq->node = splay_tree_insert (di->nodes, (splay_tree_key) t,
67 (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;
77 /* Return the index. */
78 return index;
81 static void
82 dump_index (dump_info_p di, unsigned int index)
84 fprintf (di->stream, "@%-6u ", index);
85 di->column += 8;
88 /* If T has not already been output, queue it for subsequent output.
89 FIELD is a string to print before printing the index. Then, the
90 index of T is printed. */
92 void
93 queue_and_dump_index (dump_info_p di, const char *field, const_tree t, int flags)
95 unsigned int index;
96 splay_tree_node n;
98 /* If there's no node, just return. This makes for fewer checks in
99 our callers. */
100 if (!t)
101 return;
103 /* See if we've already queued or dumped this node. */
104 n = splay_tree_lookup (di->nodes, (splay_tree_key) t);
105 if (n)
106 index = ((dump_node_info_p) n->value)->index;
107 else
108 /* If we haven't, add it to the queue. */
109 index = queue (di, t, flags);
111 /* Print the index of the node. */
112 dump_maybe_newline (di);
113 fprintf (di->stream, "%-4s: ", field);
114 di->column += 6;
115 dump_index (di, index);
118 /* Dump the type of T. */
120 void
121 queue_and_dump_type (dump_info_p di, const_tree t)
123 queue_and_dump_index (di, "type", TREE_TYPE (t), DUMP_NONE);
126 /* Dump column control */
127 #define SOL_COLUMN 25 /* Start of line column. */
128 #define EOL_COLUMN 55 /* End of line column. */
129 #define COLUMN_ALIGNMENT 15 /* Alignment. */
131 /* Insert a new line in the dump output, and indent to an appropriate
132 place to start printing more fields. */
134 static void
135 dump_new_line (dump_info_p di)
137 fprintf (di->stream, "\n%*s", SOL_COLUMN, "");
138 di->column = SOL_COLUMN;
141 /* If necessary, insert a new line. */
143 static void
144 dump_maybe_newline (dump_info_p di)
146 int extra;
148 /* See if we need a new line. */
149 if (di->column > EOL_COLUMN)
150 dump_new_line (di);
151 /* See if we need any padding. */
152 else if ((extra = (di->column - SOL_COLUMN) % COLUMN_ALIGNMENT) != 0)
154 fprintf (di->stream, "%*s", COLUMN_ALIGNMENT - extra, "");
155 di->column += COLUMN_ALIGNMENT - extra;
159 /* Dump FUNCTION_DECL FN as tree dump PHASE. */
161 void
162 dump_function (int phase, tree fn)
164 FILE *stream;
165 int flags;
167 stream = dump_begin (phase, &flags);
168 if (stream)
170 dump_function_to_file (fn, stream, flags);
171 dump_end (phase, stream);
175 /* Dump pointer PTR using FIELD to identify it. */
177 void
178 dump_pointer (dump_info_p di, const char *field, void *ptr)
180 dump_maybe_newline (di);
181 fprintf (di->stream, "%-4s: %-8" HOST_WIDE_INT_PRINT "x ", field,
182 (unsigned HOST_WIDE_INT) (uintptr_t) ptr);
183 di->column += 15;
186 /* Dump integer I using FIELD to identify it. */
188 void
189 dump_int (dump_info_p di, const char *field, int i)
191 dump_maybe_newline (di);
192 fprintf (di->stream, "%-4s: %-7d ", field, i);
193 di->column += 14;
196 /* Dump the floating point value R, using FIELD to identify it. */
198 static void
199 dump_real (dump_info_p di, const char *field, const REAL_VALUE_TYPE *r)
201 char buf[32];
202 real_to_decimal (buf, r, sizeof (buf), 0, true);
203 dump_maybe_newline (di);
204 fprintf (di->stream, "%-4s: %s ", field, buf);
205 di->column += strlen (buf) + 7;
208 /* Dump the fixed-point value F, using FIELD to identify it. */
210 static void
211 dump_fixed (dump_info_p di, const char *field, const FIXED_VALUE_TYPE *f)
213 char buf[32];
214 fixed_to_decimal (buf, f, sizeof (buf));
215 dump_maybe_newline (di);
216 fprintf (di->stream, "%-4s: %s ", field, buf);
217 di->column += strlen (buf) + 7;
221 /* Dump the string S. */
223 void
224 dump_string (dump_info_p di, const char *string)
226 dump_maybe_newline (di);
227 fprintf (di->stream, "%-13s ", string);
228 if (strlen (string) > 13)
229 di->column += strlen (string) + 1;
230 else
231 di->column += 14;
234 /* Dump the string field S. */
236 void
237 dump_string_field (dump_info_p di, const char *field, const char *string)
239 dump_maybe_newline (di);
240 fprintf (di->stream, "%-4s: %-7s ", field, string);
241 if (strlen (string) > 7)
242 di->column += 6 + strlen (string) + 1;
243 else
244 di->column += 14;
247 /* Dump the next node in the queue. */
249 static void
250 dequeue_and_dump (dump_info_p di)
252 dump_queue_p dq;
253 splay_tree_node stn;
254 dump_node_info_p dni;
255 tree t;
256 unsigned int index;
257 enum tree_code code;
258 enum tree_code_class code_class;
259 const char* code_name;
261 /* Get the next node from the queue. */
262 dq = di->queue;
263 stn = dq->node;
264 t = (tree) stn->key;
265 dni = (dump_node_info_p) stn->value;
266 index = dni->index;
268 /* Remove the node from the queue, and put it on the free list. */
269 di->queue = dq->next;
270 if (!di->queue)
271 di->queue_end = 0;
272 dq->next = di->free_list;
273 di->free_list = dq;
275 /* Print the node index. */
276 dump_index (di, index);
277 /* And the type of node this is. */
278 if (dni->binfo_p)
279 code_name = "binfo";
280 else
281 code_name = get_tree_code_name (TREE_CODE (t));
282 fprintf (di->stream, "%-16s ", code_name);
283 di->column = 25;
285 /* Figure out what kind of node this is. */
286 code = TREE_CODE (t);
287 code_class = TREE_CODE_CLASS (code);
289 /* Although BINFOs are TREE_VECs, we dump them specially so as to be
290 more informative. */
291 if (dni->binfo_p)
293 unsigned ix;
294 tree base;
295 vec<tree, va_gc> *accesses = BINFO_BASE_ACCESSES (t);
297 dump_child ("type", BINFO_TYPE (t));
299 if (BINFO_VIRTUAL_P (t))
300 dump_string_field (di, "spec", "virt");
302 dump_int (di, "bases", BINFO_N_BASE_BINFOS (t));
303 for (ix = 0; BINFO_BASE_ITERATE (t, ix, base); ix++)
305 tree access = (accesses ? (*accesses)[ix] : access_public_node);
306 const char *string = NULL;
308 if (access == access_public_node)
309 string = "pub";
310 else if (access == access_protected_node)
311 string = "prot";
312 else if (access == access_private_node)
313 string = "priv";
314 else
315 gcc_unreachable ();
317 dump_string_field (di, "accs", string);
318 queue_and_dump_index (di, "binf", base, DUMP_BINFO);
321 goto done;
324 /* We can knock off a bunch of expression nodes in exactly the same
325 way. */
326 if (IS_EXPR_CODE_CLASS (code_class))
328 /* If we're dumping children, dump them now. */
329 queue_and_dump_type (di, t);
331 switch (code_class)
333 case tcc_unary:
334 dump_child ("op 0", TREE_OPERAND (t, 0));
335 break;
337 case tcc_binary:
338 case tcc_comparison:
339 dump_child ("op 0", TREE_OPERAND (t, 0));
340 dump_child ("op 1", TREE_OPERAND (t, 1));
341 break;
343 case tcc_expression:
344 case tcc_reference:
345 case tcc_statement:
346 case tcc_vl_exp:
347 /* These nodes are handled explicitly below. */
348 break;
350 default:
351 gcc_unreachable ();
354 else if (DECL_P (t))
356 expanded_location xloc;
357 /* All declarations have names. */
358 if (DECL_NAME (t))
359 dump_child ("name", DECL_NAME (t));
360 if (DECL_ASSEMBLER_NAME_SET_P (t)
361 && DECL_ASSEMBLER_NAME (t) != DECL_NAME (t))
362 dump_child ("mngl", DECL_ASSEMBLER_NAME (t));
363 if (DECL_ABSTRACT_ORIGIN (t))
364 dump_child ("orig", DECL_ABSTRACT_ORIGIN (t));
365 /* And types. */
366 queue_and_dump_type (di, t);
367 dump_child ("scpe", DECL_CONTEXT (t));
368 /* And a source position. */
369 xloc = expand_location (DECL_SOURCE_LOCATION (t));
370 if (xloc.file)
372 const char *filename = lbasename (xloc.file);
374 dump_maybe_newline (di);
375 fprintf (di->stream, "srcp: %s:%-6d ", filename,
376 xloc.line);
377 di->column += 6 + strlen (filename) + 8;
379 /* And any declaration can be compiler-generated. */
380 if (CODE_CONTAINS_STRUCT (TREE_CODE (t), TS_DECL_COMMON)
381 && DECL_ARTIFICIAL (t))
382 dump_string_field (di, "note", "artificial");
383 if (DECL_CHAIN (t) && !dump_flag (di, TDF_SLIM, NULL))
384 dump_child ("chain", DECL_CHAIN (t));
386 else if (code_class == tcc_type)
388 /* All types have qualifiers. */
389 int quals = lang_hooks.tree_dump.type_quals (t);
391 if (quals != TYPE_UNQUALIFIED)
393 fprintf (di->stream, "qual: %c%c%c%c%c%c ",
394 (quals & TYPE_QUAL_CONST) ? 'c' : ' ',
395 (quals & TYPE_QUAL_VOLATILE) ? 'v' : ' ',
396 (quals & TYPE_QUAL_RESTRICT) ? 'r' : ' ',
397 (quals & TYPE_QUAL_SHARED) ? 's' : ' ',
398 (quals & TYPE_QUAL_STRICT) ? 't' : ' ',
399 (quals & TYPE_QUAL_RELAXED) ? 'x' : ' ');
400 di->column += 14;
403 /* All types have associated declarations. */
404 dump_child ("name", TYPE_NAME (t));
406 /* All types have a main variant. */
407 if (TYPE_MAIN_VARIANT (t) != t)
408 dump_child ("unql", TYPE_MAIN_VARIANT (t));
410 /* And sizes. */
411 dump_child ("size", TYPE_SIZE (t));
413 /* All types have alignments. */
414 dump_int (di, "algn", TYPE_ALIGN (t));
416 else if (code_class == tcc_constant)
417 /* All constants can have types. */
418 queue_and_dump_type (di, t);
420 /* Give the language-specific code a chance to print something. If
421 it's completely taken care of things, don't bother printing
422 anything more ourselves. */
423 if (lang_hooks.tree_dump.dump_tree (di, t))
424 goto done;
426 /* Now handle the various kinds of nodes. */
427 switch (code)
429 int i;
431 case IDENTIFIER_NODE:
432 dump_string_field (di, "strg", IDENTIFIER_POINTER (t));
433 dump_int (di, "lngt", IDENTIFIER_LENGTH (t));
434 break;
436 case TREE_LIST:
437 dump_child ("purp", TREE_PURPOSE (t));
438 dump_child ("valu", TREE_VALUE (t));
439 dump_child ("chan", TREE_CHAIN (t));
440 break;
442 case STATEMENT_LIST:
444 tree_stmt_iterator it;
445 for (i = 0, it = tsi_start (t); !tsi_end_p (it); tsi_next (&it), i++)
447 char buffer[32];
448 sprintf (buffer, "%u", i);
449 dump_child (buffer, tsi_stmt (it));
452 break;
454 case TREE_VEC:
455 dump_int (di, "lngt", TREE_VEC_LENGTH (t));
456 for (i = 0; i < TREE_VEC_LENGTH (t); ++i)
458 char buffer[32];
459 sprintf (buffer, "%u", i);
460 dump_child (buffer, TREE_VEC_ELT (t, i));
462 break;
464 case INTEGER_TYPE:
465 case ENUMERAL_TYPE:
466 dump_int (di, "prec", TYPE_PRECISION (t));
467 dump_string_field (di, "sign", TYPE_UNSIGNED (t) ? "unsigned": "signed");
468 dump_child ("min", TYPE_MIN_VALUE (t));
469 dump_child ("max", TYPE_MAX_VALUE (t));
471 if (code == ENUMERAL_TYPE)
472 dump_child ("csts", TYPE_VALUES (t));
473 break;
475 case REAL_TYPE:
476 dump_int (di, "prec", TYPE_PRECISION (t));
477 break;
479 case FIXED_POINT_TYPE:
480 dump_int (di, "prec", TYPE_PRECISION (t));
481 dump_string_field (di, "sign", TYPE_UNSIGNED (t) ? "unsigned": "signed");
482 dump_string_field (di, "saturating",
483 TYPE_SATURATING (t) ? "saturating": "non-saturating");
484 break;
486 case POINTER_TYPE:
487 dump_child ("ptd", TREE_TYPE (t));
488 break;
490 case REFERENCE_TYPE:
491 dump_child ("refd", TREE_TYPE (t));
492 break;
494 case METHOD_TYPE:
495 dump_child ("clas", TYPE_METHOD_BASETYPE (t));
496 /* Fall through. */
498 case FUNCTION_TYPE:
499 dump_child ("retn", TREE_TYPE (t));
500 dump_child ("prms", TYPE_ARG_TYPES (t));
501 break;
503 case ARRAY_TYPE:
504 dump_child ("elts", TREE_TYPE (t));
505 dump_child ("domn", TYPE_DOMAIN (t));
506 break;
508 case RECORD_TYPE:
509 case UNION_TYPE:
510 if (TREE_CODE (t) == RECORD_TYPE)
511 dump_string_field (di, "tag", "struct");
512 else
513 dump_string_field (di, "tag", "union");
515 dump_child ("flds", TYPE_FIELDS (t));
516 dump_child ("fncs", TYPE_METHODS (t));
517 queue_and_dump_index (di, "binf", TYPE_BINFO (t),
518 DUMP_BINFO);
519 break;
521 case CONST_DECL:
522 dump_child ("cnst", DECL_INITIAL (t));
523 break;
525 case DEBUG_EXPR_DECL:
526 dump_int (di, "-uid", DEBUG_TEMP_UID (t));
527 /* Fall through. */
529 case VAR_DECL:
530 case PARM_DECL:
531 case FIELD_DECL:
532 case RESULT_DECL:
533 if (TREE_CODE (t) == PARM_DECL)
534 dump_child ("argt", DECL_ARG_TYPE (t));
535 else
536 dump_child ("init", DECL_INITIAL (t));
537 dump_child ("size", DECL_SIZE (t));
538 dump_int (di, "algn", DECL_ALIGN (t));
540 if (TREE_CODE (t) == FIELD_DECL)
542 if (DECL_FIELD_OFFSET (t))
543 dump_child ("bpos", bit_position (t));
545 else if (TREE_CODE (t) == VAR_DECL
546 || TREE_CODE (t) == PARM_DECL)
548 dump_int (di, "used", TREE_USED (t));
549 if (DECL_REGISTER (t))
550 dump_string_field (di, "spec", "register");
552 break;
554 case FUNCTION_DECL:
555 dump_child ("args", DECL_ARGUMENTS (t));
556 if (DECL_EXTERNAL (t))
557 dump_string_field (di, "body", "undefined");
558 if (TREE_PUBLIC (t))
559 dump_string_field (di, "link", "extern");
560 else
561 dump_string_field (di, "link", "static");
562 if (DECL_SAVED_TREE (t) && !dump_flag (di, TDF_SLIM, t))
563 dump_child ("body", DECL_SAVED_TREE (t));
564 break;
566 case INTEGER_CST:
567 if (TREE_INT_CST_HIGH (t))
568 dump_int (di, "high", TREE_INT_CST_HIGH (t));
569 dump_int (di, "low", TREE_INT_CST_LOW (t));
570 break;
572 case STRING_CST:
573 fprintf (di->stream, "strg: %-7s ", TREE_STRING_POINTER (t));
574 dump_int (di, "lngt", TREE_STRING_LENGTH (t));
575 break;
577 case REAL_CST:
578 dump_real (di, "valu", TREE_REAL_CST_PTR (t));
579 break;
581 case FIXED_CST:
582 dump_fixed (di, "valu", TREE_FIXED_CST_PTR (t));
583 break;
585 case TRUTH_NOT_EXPR:
586 case ADDR_EXPR:
587 case INDIRECT_REF:
588 case CLEANUP_POINT_EXPR:
589 case SAVE_EXPR:
590 case REALPART_EXPR:
591 case IMAGPART_EXPR:
592 /* These nodes are unary, but do not have code class `1'. */
593 dump_child ("op 0", TREE_OPERAND (t, 0));
594 break;
596 case TRUTH_ANDIF_EXPR:
597 case TRUTH_ORIF_EXPR:
598 case INIT_EXPR:
599 case MODIFY_EXPR:
600 case COMPOUND_EXPR:
601 case PREDECREMENT_EXPR:
602 case PREINCREMENT_EXPR:
603 case POSTDECREMENT_EXPR:
604 case POSTINCREMENT_EXPR:
605 /* These nodes are binary, but do not have code class `2'. */
606 dump_child ("op 0", TREE_OPERAND (t, 0));
607 dump_child ("op 1", TREE_OPERAND (t, 1));
608 break;
610 case COMPONENT_REF:
611 case BIT_FIELD_REF:
612 dump_child ("op 0", TREE_OPERAND (t, 0));
613 dump_child ("op 1", TREE_OPERAND (t, 1));
614 dump_child ("op 2", TREE_OPERAND (t, 2));
615 break;
617 case ARRAY_REF:
618 case ARRAY_RANGE_REF:
619 dump_child ("op 0", TREE_OPERAND (t, 0));
620 dump_child ("op 1", TREE_OPERAND (t, 1));
621 dump_child ("op 2", TREE_OPERAND (t, 2));
622 dump_child ("op 3", TREE_OPERAND (t, 3));
623 break;
625 case COND_EXPR:
626 dump_child ("op 0", TREE_OPERAND (t, 0));
627 dump_child ("op 1", TREE_OPERAND (t, 1));
628 dump_child ("op 2", TREE_OPERAND (t, 2));
629 break;
631 case TRY_FINALLY_EXPR:
632 dump_child ("op 0", TREE_OPERAND (t, 0));
633 dump_child ("op 1", TREE_OPERAND (t, 1));
634 break;
636 case CALL_EXPR:
638 int i = 0;
639 tree arg;
640 call_expr_arg_iterator iter;
641 dump_child ("fn", CALL_EXPR_FN (t));
642 FOR_EACH_CALL_EXPR_ARG (arg, iter, t)
644 char buffer[32];
645 sprintf (buffer, "%u", i);
646 dump_child (buffer, arg);
647 i++;
650 break;
652 case CONSTRUCTOR:
654 unsigned HOST_WIDE_INT cnt;
655 tree index, value;
656 dump_int (di, "lngt", vec_safe_length (CONSTRUCTOR_ELTS (t)));
657 FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (t), cnt, index, value)
659 dump_child ("idx", index);
660 dump_child ("val", value);
663 break;
665 case BIND_EXPR:
666 dump_child ("vars", TREE_OPERAND (t, 0));
667 dump_child ("body", TREE_OPERAND (t, 1));
668 break;
670 case LOOP_EXPR:
671 dump_child ("body", TREE_OPERAND (t, 0));
672 break;
674 case EXIT_EXPR:
675 dump_child ("cond", TREE_OPERAND (t, 0));
676 break;
678 case RETURN_EXPR:
679 dump_child ("expr", TREE_OPERAND (t, 0));
680 break;
682 case TARGET_EXPR:
683 dump_child ("decl", TREE_OPERAND (t, 0));
684 dump_child ("init", TREE_OPERAND (t, 1));
685 dump_child ("clnp", TREE_OPERAND (t, 2));
686 /* There really are two possible places the initializer can be.
687 After RTL expansion, the second operand is moved to the
688 position of the fourth operand, and the second operand
689 becomes NULL. */
690 dump_child ("init", TREE_OPERAND (t, 3));
691 break;
693 case CASE_LABEL_EXPR:
694 dump_child ("name", CASE_LABEL (t));
695 if (CASE_LOW (t))
697 dump_child ("low ", CASE_LOW (t));
698 if (CASE_HIGH (t))
699 dump_child ("high", CASE_HIGH (t));
701 break;
702 case LABEL_EXPR:
703 dump_child ("name", TREE_OPERAND (t,0));
704 break;
705 case GOTO_EXPR:
706 dump_child ("labl", TREE_OPERAND (t, 0));
707 break;
708 case SWITCH_EXPR:
709 dump_child ("cond", TREE_OPERAND (t, 0));
710 dump_child ("body", TREE_OPERAND (t, 1));
711 if (TREE_OPERAND (t, 2))
713 dump_child ("labl", TREE_OPERAND (t,2));
715 break;
716 case OMP_CLAUSE:
718 int i;
719 fprintf (di->stream, "%s\n", omp_clause_code_name[OMP_CLAUSE_CODE (t)]);
720 for (i = 0; i < omp_clause_num_ops[OMP_CLAUSE_CODE (t)]; i++)
721 dump_child ("op: ", OMP_CLAUSE_OPERAND (t, i));
723 break;
724 default:
725 /* There are no additional fields to print. */
726 break;
729 done:
730 if (dump_flag (di, TDF_ADDRESS, NULL))
731 dump_pointer (di, "addr", (void *)t);
733 /* Terminate the line. */
734 fprintf (di->stream, "\n");
737 /* Return nonzero if FLAG has been specified for the dump, and NODE
738 is not the root node of the dump. */
740 int dump_flag (dump_info_p di, int flag, const_tree node)
742 return (di->flags & flag) && (node != di->node);
745 /* Dump T, and all its children, on STREAM. */
747 void
748 dump_node (const_tree t, int flags, FILE *stream)
750 struct dump_info di;
751 dump_queue_p dq;
752 dump_queue_p next_dq;
754 /* Initialize the dump-information structure. */
755 di.stream = stream;
756 di.index = 0;
757 di.column = 0;
758 di.queue = 0;
759 di.queue_end = 0;
760 di.free_list = 0;
761 di.flags = flags;
762 di.node = t;
763 di.nodes = splay_tree_new (splay_tree_compare_pointers, 0,
764 (splay_tree_delete_value_fn) &free);
766 /* Queue up the first node. */
767 queue (&di, t, DUMP_NONE);
769 /* Until the queue is empty, keep dumping nodes. */
770 while (di.queue)
771 dequeue_and_dump (&di);
773 /* Now, clean up. */
774 for (dq = di.free_list; dq; dq = next_dq)
776 next_dq = dq->next;
777 free (dq);
779 splay_tree_delete (di.nodes);