Merge trunk version 197958 into gupc branch.
[official-gcc.git] / gcc / tree-dump.c
blobd74c2b5a2091d94e0a38f1c9f75687f448f6e62e
1 /* Tree-dumping functionality for intermediate representation.
2 Copyright (C) 1999-2013 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"
33 static unsigned int queue (dump_info_p, const_tree, int);
34 static void dump_index (dump_info_p, unsigned int);
35 static void dequeue_and_dump (dump_info_p);
36 static void dump_new_line (dump_info_p);
37 static void dump_maybe_newline (dump_info_p);
39 /* Add T to the end of the queue of nodes to dump. Returns the index
40 assigned to T. */
42 static unsigned int
43 queue (dump_info_p di, const_tree t, int flags)
45 dump_queue_p dq;
46 dump_node_info_p dni;
47 unsigned int index;
49 /* Assign the next available index to T. */
50 index = ++di->index;
52 /* Obtain a new queue node. */
53 if (di->free_list)
55 dq = di->free_list;
56 di->free_list = dq->next;
58 else
59 dq = XNEW (struct dump_queue);
61 /* Create a new entry in the splay-tree. */
62 dni = XNEW (struct dump_node_info);
63 dni->index = index;
64 dni->binfo_p = ((flags & DUMP_BINFO) != 0);
65 dq->node = splay_tree_insert (di->nodes, (splay_tree_key) t,
66 (splay_tree_value) dni);
68 /* Add it to the end of the queue. */
69 dq->next = 0;
70 if (!di->queue_end)
71 di->queue = dq;
72 else
73 di->queue_end->next = dq;
74 di->queue_end = dq;
76 /* Return the index. */
77 return index;
80 static void
81 dump_index (dump_info_p di, unsigned int index)
83 fprintf (di->stream, "@%-6u ", index);
84 di->column += 8;
87 /* If T has not already been output, queue it for subsequent output.
88 FIELD is a string to print before printing the index. Then, the
89 index of T is printed. */
91 void
92 queue_and_dump_index (dump_info_p di, const char *field, const_tree t, int flags)
94 unsigned int index;
95 splay_tree_node n;
97 /* If there's no node, just return. This makes for fewer checks in
98 our callers. */
99 if (!t)
100 return;
102 /* See if we've already queued or dumped this node. */
103 n = splay_tree_lookup (di->nodes, (splay_tree_key) t);
104 if (n)
105 index = ((dump_node_info_p) n->value)->index;
106 else
107 /* If we haven't, add it to the queue. */
108 index = queue (di, t, flags);
110 /* Print the index of the node. */
111 dump_maybe_newline (di);
112 fprintf (di->stream, "%-4s: ", field);
113 di->column += 6;
114 dump_index (di, index);
117 /* Dump the type of T. */
119 void
120 queue_and_dump_type (dump_info_p di, const_tree t)
122 queue_and_dump_index (di, "type", TREE_TYPE (t), DUMP_NONE);
125 /* Dump column control */
126 #define SOL_COLUMN 25 /* Start of line column. */
127 #define EOL_COLUMN 55 /* End of line column. */
128 #define COLUMN_ALIGNMENT 15 /* Alignment. */
130 /* Insert a new line in the dump output, and indent to an appropriate
131 place to start printing more fields. */
133 static void
134 dump_new_line (dump_info_p di)
136 fprintf (di->stream, "\n%*s", SOL_COLUMN, "");
137 di->column = SOL_COLUMN;
140 /* If necessary, insert a new line. */
142 static void
143 dump_maybe_newline (dump_info_p di)
145 int extra;
147 /* See if we need a new line. */
148 if (di->column > EOL_COLUMN)
149 dump_new_line (di);
150 /* See if we need any padding. */
151 else if ((extra = (di->column - SOL_COLUMN) % COLUMN_ALIGNMENT) != 0)
153 fprintf (di->stream, "%*s", COLUMN_ALIGNMENT - extra, "");
154 di->column += COLUMN_ALIGNMENT - extra;
158 /* Dump FUNCTION_DECL FN as tree dump PHASE. */
160 void
161 dump_function (int phase, tree fn)
163 FILE *stream;
164 int flags;
166 stream = dump_begin (phase, &flags);
167 if (stream)
169 dump_function_to_file (fn, stream, flags);
170 dump_end (phase, stream);
174 /* Dump pointer PTR using FIELD to identify it. */
176 void
177 dump_pointer (dump_info_p di, const char *field, void *ptr)
179 dump_maybe_newline (di);
180 fprintf (di->stream, "%-4s: %-8" HOST_WIDE_INT_PRINT "x ", field,
181 (unsigned HOST_WIDE_INT) (uintptr_t) ptr);
182 di->column += 15;
185 /* Dump integer I using FIELD to identify it. */
187 void
188 dump_int (dump_info_p di, const char *field, int i)
190 dump_maybe_newline (di);
191 fprintf (di->stream, "%-4s: %-7d ", field, i);
192 di->column += 14;
195 /* Dump the floating point value R, using FIELD to identify it. */
197 static void
198 dump_real (dump_info_p di, const char *field, const REAL_VALUE_TYPE *r)
200 char buf[32];
201 real_to_decimal (buf, r, sizeof (buf), 0, true);
202 dump_maybe_newline (di);
203 fprintf (di->stream, "%-4s: %s ", field, buf);
204 di->column += strlen (buf) + 7;
207 /* Dump the fixed-point value F, using FIELD to identify it. */
209 static void
210 dump_fixed (dump_info_p di, const char *field, const FIXED_VALUE_TYPE *f)
212 char buf[32];
213 fixed_to_decimal (buf, f, sizeof (buf));
214 dump_maybe_newline (di);
215 fprintf (di->stream, "%-4s: %s ", field, buf);
216 di->column += strlen (buf) + 7;
220 /* Dump the string S. */
222 void
223 dump_string (dump_info_p di, const char *string)
225 dump_maybe_newline (di);
226 fprintf (di->stream, "%-13s ", string);
227 if (strlen (string) > 13)
228 di->column += strlen (string) + 1;
229 else
230 di->column += 14;
233 /* Dump the string field S. */
235 void
236 dump_string_field (dump_info_p di, const char *field, const char *string)
238 dump_maybe_newline (di);
239 fprintf (di->stream, "%-4s: %-7s ", field, string);
240 if (strlen (string) > 7)
241 di->column += 6 + strlen (string) + 1;
242 else
243 di->column += 14;
246 /* Dump the next node in the queue. */
248 static void
249 dequeue_and_dump (dump_info_p di)
251 dump_queue_p dq;
252 splay_tree_node stn;
253 dump_node_info_p dni;
254 tree t;
255 unsigned int index;
256 enum tree_code code;
257 enum tree_code_class code_class;
258 const char* code_name;
260 /* Get the next node from the queue. */
261 dq = di->queue;
262 stn = dq->node;
263 t = (tree) stn->key;
264 dni = (dump_node_info_p) stn->value;
265 index = dni->index;
267 /* Remove the node from the queue, and put it on the free list. */
268 di->queue = dq->next;
269 if (!di->queue)
270 di->queue_end = 0;
271 dq->next = di->free_list;
272 di->free_list = dq;
274 /* Print the node index. */
275 dump_index (di, index);
276 /* And the type of node this is. */
277 if (dni->binfo_p)
278 code_name = "binfo";
279 else
280 code_name = tree_code_name[(int) TREE_CODE (t)];
281 fprintf (di->stream, "%-16s ", code_name);
282 di->column = 25;
284 /* Figure out what kind of node this is. */
285 code = TREE_CODE (t);
286 code_class = TREE_CODE_CLASS (code);
288 /* Although BINFOs are TREE_VECs, we dump them specially so as to be
289 more informative. */
290 if (dni->binfo_p)
292 unsigned ix;
293 tree base;
294 vec<tree, va_gc> *accesses = BINFO_BASE_ACCESSES (t);
296 dump_child ("type", BINFO_TYPE (t));
298 if (BINFO_VIRTUAL_P (t))
299 dump_string_field (di, "spec", "virt");
301 dump_int (di, "bases", BINFO_N_BASE_BINFOS (t));
302 for (ix = 0; BINFO_BASE_ITERATE (t, ix, base); ix++)
304 tree access = (accesses ? (*accesses)[ix] : access_public_node);
305 const char *string = NULL;
307 if (access == access_public_node)
308 string = "pub";
309 else if (access == access_protected_node)
310 string = "prot";
311 else if (access == access_private_node)
312 string = "priv";
313 else
314 gcc_unreachable ();
316 dump_string_field (di, "accs", string);
317 queue_and_dump_index (di, "binf", base, DUMP_BINFO);
320 goto done;
323 /* We can knock off a bunch of expression nodes in exactly the same
324 way. */
325 if (IS_EXPR_CODE_CLASS (code_class))
327 /* If we're dumping children, dump them now. */
328 queue_and_dump_type (di, t);
330 switch (code_class)
332 case tcc_unary:
333 dump_child ("op 0", TREE_OPERAND (t, 0));
334 break;
336 case tcc_binary:
337 case tcc_comparison:
338 dump_child ("op 0", TREE_OPERAND (t, 0));
339 dump_child ("op 1", TREE_OPERAND (t, 1));
340 break;
342 case tcc_expression:
343 case tcc_reference:
344 case tcc_statement:
345 case tcc_vl_exp:
346 /* These nodes are handled explicitly below. */
347 break;
349 default:
350 gcc_unreachable ();
353 else if (DECL_P (t))
355 expanded_location xloc;
356 /* All declarations have names. */
357 if (DECL_NAME (t))
358 dump_child ("name", DECL_NAME (t));
359 if (DECL_ASSEMBLER_NAME_SET_P (t)
360 && DECL_ASSEMBLER_NAME (t) != DECL_NAME (t))
361 dump_child ("mngl", DECL_ASSEMBLER_NAME (t));
362 if (DECL_ABSTRACT_ORIGIN (t))
363 dump_child ("orig", DECL_ABSTRACT_ORIGIN (t));
364 /* And types. */
365 queue_and_dump_type (di, t);
366 dump_child ("scpe", DECL_CONTEXT (t));
367 /* And a source position. */
368 xloc = expand_location (DECL_SOURCE_LOCATION (t));
369 if (xloc.file)
371 const char *filename = lbasename (xloc.file);
373 dump_maybe_newline (di);
374 fprintf (di->stream, "srcp: %s:%-6d ", filename,
375 xloc.line);
376 di->column += 6 + strlen (filename) + 8;
378 /* And any declaration can be compiler-generated. */
379 if (CODE_CONTAINS_STRUCT (TREE_CODE (t), TS_DECL_COMMON)
380 && DECL_ARTIFICIAL (t))
381 dump_string_field (di, "note", "artificial");
382 if (DECL_CHAIN (t) && !dump_flag (di, TDF_SLIM, NULL))
383 dump_child ("chain", DECL_CHAIN (t));
385 else if (code_class == tcc_type)
387 /* All types have qualifiers. */
388 int quals = lang_hooks.tree_dump.type_quals (t);
390 if (quals != TYPE_UNQUALIFIED)
392 fprintf (di->stream, "qual: %c%c%c%c%c%c ",
393 (quals & TYPE_QUAL_CONST) ? 'c' : ' ',
394 (quals & TYPE_QUAL_VOLATILE) ? 'v' : ' ',
395 (quals & TYPE_QUAL_RESTRICT) ? 'r' : ' ',
396 (quals & TYPE_QUAL_SHARED) ? 's' : ' ',
397 (quals & TYPE_QUAL_STRICT) ? 't' : ' ',
398 (quals & TYPE_QUAL_RELAXED) ? 'x' : ' ');
399 di->column += 14;
402 /* All types have associated declarations. */
403 dump_child ("name", TYPE_NAME (t));
405 /* All types have a main variant. */
406 if (TYPE_MAIN_VARIANT (t) != t)
407 dump_child ("unql", TYPE_MAIN_VARIANT (t));
409 /* And sizes. */
410 dump_child ("size", TYPE_SIZE (t));
412 /* All types have alignments. */
413 dump_int (di, "algn", TYPE_ALIGN (t));
415 else if (code_class == tcc_constant)
416 /* All constants can have types. */
417 queue_and_dump_type (di, t);
419 /* Give the language-specific code a chance to print something. If
420 it's completely taken care of things, don't bother printing
421 anything more ourselves. */
422 if (lang_hooks.tree_dump.dump_tree (di, t))
423 goto done;
425 /* Now handle the various kinds of nodes. */
426 switch (code)
428 int i;
430 case IDENTIFIER_NODE:
431 dump_string_field (di, "strg", IDENTIFIER_POINTER (t));
432 dump_int (di, "lngt", IDENTIFIER_LENGTH (t));
433 break;
435 case TREE_LIST:
436 dump_child ("purp", TREE_PURPOSE (t));
437 dump_child ("valu", TREE_VALUE (t));
438 dump_child ("chan", TREE_CHAIN (t));
439 break;
441 case STATEMENT_LIST:
443 tree_stmt_iterator it;
444 for (i = 0, it = tsi_start (t); !tsi_end_p (it); tsi_next (&it), i++)
446 char buffer[32];
447 sprintf (buffer, "%u", i);
448 dump_child (buffer, tsi_stmt (it));
451 break;
453 case TREE_VEC:
454 dump_int (di, "lngt", TREE_VEC_LENGTH (t));
455 for (i = 0; i < TREE_VEC_LENGTH (t); ++i)
457 char buffer[32];
458 sprintf (buffer, "%u", i);
459 dump_child (buffer, TREE_VEC_ELT (t, i));
461 break;
463 case INTEGER_TYPE:
464 case ENUMERAL_TYPE:
465 dump_int (di, "prec", TYPE_PRECISION (t));
466 dump_string_field (di, "sign", TYPE_UNSIGNED (t) ? "unsigned": "signed");
467 dump_child ("min", TYPE_MIN_VALUE (t));
468 dump_child ("max", TYPE_MAX_VALUE (t));
470 if (code == ENUMERAL_TYPE)
471 dump_child ("csts", TYPE_VALUES (t));
472 break;
474 case REAL_TYPE:
475 dump_int (di, "prec", TYPE_PRECISION (t));
476 break;
478 case FIXED_POINT_TYPE:
479 dump_int (di, "prec", TYPE_PRECISION (t));
480 dump_string_field (di, "sign", TYPE_UNSIGNED (t) ? "unsigned": "signed");
481 dump_string_field (di, "saturating",
482 TYPE_SATURATING (t) ? "saturating": "non-saturating");
483 break;
485 case POINTER_TYPE:
486 dump_child ("ptd", TREE_TYPE (t));
487 break;
489 case REFERENCE_TYPE:
490 dump_child ("refd", TREE_TYPE (t));
491 break;
493 case METHOD_TYPE:
494 dump_child ("clas", TYPE_METHOD_BASETYPE (t));
495 /* Fall through. */
497 case FUNCTION_TYPE:
498 dump_child ("retn", TREE_TYPE (t));
499 dump_child ("prms", TYPE_ARG_TYPES (t));
500 break;
502 case ARRAY_TYPE:
503 dump_child ("elts", TREE_TYPE (t));
504 dump_child ("domn", TYPE_DOMAIN (t));
505 break;
507 case RECORD_TYPE:
508 case UNION_TYPE:
509 if (TREE_CODE (t) == RECORD_TYPE)
510 dump_string_field (di, "tag", "struct");
511 else
512 dump_string_field (di, "tag", "union");
514 dump_child ("flds", TYPE_FIELDS (t));
515 dump_child ("fncs", TYPE_METHODS (t));
516 queue_and_dump_index (di, "binf", TYPE_BINFO (t),
517 DUMP_BINFO);
518 break;
520 case CONST_DECL:
521 dump_child ("cnst", DECL_INITIAL (t));
522 break;
524 case DEBUG_EXPR_DECL:
525 dump_int (di, "-uid", DEBUG_TEMP_UID (t));
526 /* Fall through. */
528 case VAR_DECL:
529 case PARM_DECL:
530 case FIELD_DECL:
531 case RESULT_DECL:
532 if (TREE_CODE (t) == PARM_DECL)
533 dump_child ("argt", DECL_ARG_TYPE (t));
534 else
535 dump_child ("init", DECL_INITIAL (t));
536 dump_child ("size", DECL_SIZE (t));
537 dump_int (di, "algn", DECL_ALIGN (t));
539 if (TREE_CODE (t) == FIELD_DECL)
541 if (DECL_FIELD_OFFSET (t))
542 dump_child ("bpos", bit_position (t));
544 else if (TREE_CODE (t) == VAR_DECL
545 || TREE_CODE (t) == PARM_DECL)
547 dump_int (di, "used", TREE_USED (t));
548 if (DECL_REGISTER (t))
549 dump_string_field (di, "spec", "register");
551 break;
553 case FUNCTION_DECL:
554 dump_child ("args", DECL_ARGUMENTS (t));
555 if (DECL_EXTERNAL (t))
556 dump_string_field (di, "body", "undefined");
557 if (TREE_PUBLIC (t))
558 dump_string_field (di, "link", "extern");
559 else
560 dump_string_field (di, "link", "static");
561 if (DECL_SAVED_TREE (t) && !dump_flag (di, TDF_SLIM, t))
562 dump_child ("body", DECL_SAVED_TREE (t));
563 break;
565 case INTEGER_CST:
566 if (TREE_INT_CST_HIGH (t))
567 dump_int (di, "high", TREE_INT_CST_HIGH (t));
568 dump_int (di, "low", TREE_INT_CST_LOW (t));
569 break;
571 case STRING_CST:
572 fprintf (di->stream, "strg: %-7s ", TREE_STRING_POINTER (t));
573 dump_int (di, "lngt", TREE_STRING_LENGTH (t));
574 break;
576 case REAL_CST:
577 dump_real (di, "valu", TREE_REAL_CST_PTR (t));
578 break;
580 case FIXED_CST:
581 dump_fixed (di, "valu", TREE_FIXED_CST_PTR (t));
582 break;
584 case TRUTH_NOT_EXPR:
585 case ADDR_EXPR:
586 case INDIRECT_REF:
587 case CLEANUP_POINT_EXPR:
588 case SAVE_EXPR:
589 case REALPART_EXPR:
590 case IMAGPART_EXPR:
591 /* These nodes are unary, but do not have code class `1'. */
592 dump_child ("op 0", TREE_OPERAND (t, 0));
593 break;
595 case TRUTH_ANDIF_EXPR:
596 case TRUTH_ORIF_EXPR:
597 case INIT_EXPR:
598 case MODIFY_EXPR:
599 case COMPOUND_EXPR:
600 case PREDECREMENT_EXPR:
601 case PREINCREMENT_EXPR:
602 case POSTDECREMENT_EXPR:
603 case POSTINCREMENT_EXPR:
604 /* These nodes are binary, but do not have code class `2'. */
605 dump_child ("op 0", TREE_OPERAND (t, 0));
606 dump_child ("op 1", TREE_OPERAND (t, 1));
607 break;
609 case COMPONENT_REF:
610 case BIT_FIELD_REF:
611 dump_child ("op 0", TREE_OPERAND (t, 0));
612 dump_child ("op 1", TREE_OPERAND (t, 1));
613 dump_child ("op 2", TREE_OPERAND (t, 2));
614 break;
616 case ARRAY_REF:
617 case ARRAY_RANGE_REF:
618 dump_child ("op 0", TREE_OPERAND (t, 0));
619 dump_child ("op 1", TREE_OPERAND (t, 1));
620 dump_child ("op 2", TREE_OPERAND (t, 2));
621 dump_child ("op 3", TREE_OPERAND (t, 3));
622 break;
624 case COND_EXPR:
625 dump_child ("op 0", TREE_OPERAND (t, 0));
626 dump_child ("op 1", TREE_OPERAND (t, 1));
627 dump_child ("op 2", TREE_OPERAND (t, 2));
628 break;
630 case TRY_FINALLY_EXPR:
631 dump_child ("op 0", TREE_OPERAND (t, 0));
632 dump_child ("op 1", TREE_OPERAND (t, 1));
633 break;
635 case CALL_EXPR:
637 int i = 0;
638 tree arg;
639 call_expr_arg_iterator iter;
640 dump_child ("fn", CALL_EXPR_FN (t));
641 FOR_EACH_CALL_EXPR_ARG (arg, iter, t)
643 char buffer[32];
644 sprintf (buffer, "%u", i);
645 dump_child (buffer, arg);
646 i++;
649 break;
651 case CONSTRUCTOR:
653 unsigned HOST_WIDE_INT cnt;
654 tree index, value;
655 dump_int (di, "lngt", vec_safe_length (CONSTRUCTOR_ELTS (t)));
656 FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (t), cnt, index, value)
658 dump_child ("idx", index);
659 dump_child ("val", value);
662 break;
664 case BIND_EXPR:
665 dump_child ("vars", TREE_OPERAND (t, 0));
666 dump_child ("body", TREE_OPERAND (t, 1));
667 break;
669 case LOOP_EXPR:
670 dump_child ("body", TREE_OPERAND (t, 0));
671 break;
673 case EXIT_EXPR:
674 dump_child ("cond", TREE_OPERAND (t, 0));
675 break;
677 case RETURN_EXPR:
678 dump_child ("expr", TREE_OPERAND (t, 0));
679 break;
681 case TARGET_EXPR:
682 dump_child ("decl", TREE_OPERAND (t, 0));
683 dump_child ("init", TREE_OPERAND (t, 1));
684 dump_child ("clnp", TREE_OPERAND (t, 2));
685 /* There really are two possible places the initializer can be.
686 After RTL expansion, the second operand is moved to the
687 position of the fourth operand, and the second operand
688 becomes NULL. */
689 dump_child ("init", TREE_OPERAND (t, 3));
690 break;
692 case CASE_LABEL_EXPR:
693 dump_child ("name", CASE_LABEL (t));
694 if (CASE_LOW (t))
696 dump_child ("low ", CASE_LOW (t));
697 if (CASE_HIGH (t))
698 dump_child ("high", CASE_HIGH (t));
700 break;
701 case LABEL_EXPR:
702 dump_child ("name", TREE_OPERAND (t,0));
703 break;
704 case GOTO_EXPR:
705 dump_child ("labl", TREE_OPERAND (t, 0));
706 break;
707 case SWITCH_EXPR:
708 dump_child ("cond", TREE_OPERAND (t, 0));
709 dump_child ("body", TREE_OPERAND (t, 1));
710 if (TREE_OPERAND (t, 2))
712 dump_child ("labl", TREE_OPERAND (t,2));
714 break;
715 case OMP_CLAUSE:
717 int i;
718 fprintf (di->stream, "%s\n", omp_clause_code_name[OMP_CLAUSE_CODE (t)]);
719 for (i = 0; i < omp_clause_num_ops[OMP_CLAUSE_CODE (t)]; i++)
720 dump_child ("op: ", OMP_CLAUSE_OPERAND (t, i));
722 break;
723 default:
724 /* There are no additional fields to print. */
725 break;
728 done:
729 if (dump_flag (di, TDF_ADDRESS, NULL))
730 dump_pointer (di, "addr", (void *)t);
732 /* Terminate the line. */
733 fprintf (di->stream, "\n");
736 /* Return nonzero if FLAG has been specified for the dump, and NODE
737 is not the root node of the dump. */
739 int dump_flag (dump_info_p di, int flag, const_tree node)
741 return (di->flags & flag) && (node != di->node);
744 /* Dump T, and all its children, on STREAM. */
746 void
747 dump_node (const_tree t, int flags, FILE *stream)
749 struct dump_info di;
750 dump_queue_p dq;
751 dump_queue_p next_dq;
753 /* Initialize the dump-information structure. */
754 di.stream = stream;
755 di.index = 0;
756 di.column = 0;
757 di.queue = 0;
758 di.queue_end = 0;
759 di.free_list = 0;
760 di.flags = flags;
761 di.node = t;
762 di.nodes = splay_tree_new (splay_tree_compare_pointers, 0,
763 (splay_tree_delete_value_fn) &free);
765 /* Queue up the first node. */
766 queue (&di, t, DUMP_NONE);
768 /* Until the queue is empty, keep dumping nodes. */
769 while (di.queue)
770 dequeue_and_dump (&di);
772 /* Now, clean up. */
773 for (dq = di.free_list; dq; dq = next_dq)
775 next_dq = dq->next;
776 free (dq);
778 splay_tree_delete (di.nodes);