* config/darwin.c (darwin_assemble_visibility): Treat
[official-gcc.git] / gcc / tree-dump.c
bloba1511ea7eea443d378c79e5506994d4f5adffd31
1 /* Tree-dumping functionality for intermediate representation.
2 Copyright (C) 1999, 2000, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
3 2010, 2011, 2012 Free Software Foundation, Inc.
4 Written by Mark Mitchell <mark@codesourcery.com>
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 3, or (at your option) any later
11 version.
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 for more details.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3. If not see
20 <http://www.gnu.org/licenses/>. */
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tm.h"
26 #include "tree.h"
27 #include "splay-tree.h"
28 #include "filenames.h"
29 #include "tree-dump.h"
30 #include "langhooks.h"
31 #include "tree-iterator.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: %-8lx ", field, (unsigned long) ptr);
181 di->column += 15;
184 /* Dump integer I using FIELD to identify it. */
186 void
187 dump_int (dump_info_p di, const char *field, int i)
189 dump_maybe_newline (di);
190 fprintf (di->stream, "%-4s: %-7d ", field, i);
191 di->column += 14;
194 /* Dump the floating point value R, using FIELD to identify it. */
196 static void
197 dump_real (dump_info_p di, const char *field, const REAL_VALUE_TYPE *r)
199 char buf[32];
200 real_to_decimal (buf, r, sizeof (buf), 0, true);
201 dump_maybe_newline (di);
202 fprintf (di->stream, "%-4s: %s ", field, buf);
203 di->column += strlen (buf) + 7;
206 /* Dump the fixed-point value F, using FIELD to identify it. */
208 static void
209 dump_fixed (dump_info_p di, const char *field, const FIXED_VALUE_TYPE *f)
211 char buf[32];
212 fixed_to_decimal (buf, f, sizeof (buf));
213 dump_maybe_newline (di);
214 fprintf (di->stream, "%-4s: %s ", field, buf);
215 di->column += strlen (buf) + 7;
219 /* Dump the string S. */
221 void
222 dump_string (dump_info_p di, const char *string)
224 dump_maybe_newline (di);
225 fprintf (di->stream, "%-13s ", string);
226 if (strlen (string) > 13)
227 di->column += strlen (string) + 1;
228 else
229 di->column += 14;
232 /* Dump the string field S. */
234 void
235 dump_string_field (dump_info_p di, const char *field, const char *string)
237 dump_maybe_newline (di);
238 fprintf (di->stream, "%-4s: %-7s ", field, string);
239 if (strlen (string) > 7)
240 di->column += 6 + strlen (string) + 1;
241 else
242 di->column += 14;
245 /* Dump the next node in the queue. */
247 static void
248 dequeue_and_dump (dump_info_p di)
250 dump_queue_p dq;
251 splay_tree_node stn;
252 dump_node_info_p dni;
253 tree t;
254 unsigned int index;
255 enum tree_code code;
256 enum tree_code_class code_class;
257 const char* code_name;
259 /* Get the next node from the queue. */
260 dq = di->queue;
261 stn = dq->node;
262 t = (tree) stn->key;
263 dni = (dump_node_info_p) stn->value;
264 index = dni->index;
266 /* Remove the node from the queue, and put it on the free list. */
267 di->queue = dq->next;
268 if (!di->queue)
269 di->queue_end = 0;
270 dq->next = di->free_list;
271 di->free_list = dq;
273 /* Print the node index. */
274 dump_index (di, index);
275 /* And the type of node this is. */
276 if (dni->binfo_p)
277 code_name = "binfo";
278 else
279 code_name = tree_code_name[(int) TREE_CODE (t)];
280 fprintf (di->stream, "%-16s ", code_name);
281 di->column = 25;
283 /* Figure out what kind of node this is. */
284 code = TREE_CODE (t);
285 code_class = TREE_CODE_CLASS (code);
287 /* Although BINFOs are TREE_VECs, we dump them specially so as to be
288 more informative. */
289 if (dni->binfo_p)
291 unsigned ix;
292 tree base;
293 VEC(tree,gc) *accesses = BINFO_BASE_ACCESSES (t);
295 dump_child ("type", BINFO_TYPE (t));
297 if (BINFO_VIRTUAL_P (t))
298 dump_string_field (di, "spec", "virt");
300 dump_int (di, "bases", BINFO_N_BASE_BINFOS (t));
301 for (ix = 0; BINFO_BASE_ITERATE (t, ix, base); ix++)
303 tree access = (accesses ? VEC_index (tree, accesses, ix)
304 : 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 ",
393 (quals & TYPE_QUAL_CONST) ? 'c' : ' ',
394 (quals & TYPE_QUAL_VOLATILE) ? 'v' : ' ',
395 (quals & TYPE_QUAL_RESTRICT) ? 'r' : ' ');
396 di->column += 14;
399 /* All types have associated declarations. */
400 dump_child ("name", TYPE_NAME (t));
402 /* All types have a main variant. */
403 if (TYPE_MAIN_VARIANT (t) != t)
404 dump_child ("unql", TYPE_MAIN_VARIANT (t));
406 /* And sizes. */
407 dump_child ("size", TYPE_SIZE (t));
409 /* All types have alignments. */
410 dump_int (di, "algn", TYPE_ALIGN (t));
412 else if (code_class == tcc_constant)
413 /* All constants can have types. */
414 queue_and_dump_type (di, t);
416 /* Give the language-specific code a chance to print something. If
417 it's completely taken care of things, don't bother printing
418 anything more ourselves. */
419 if (lang_hooks.tree_dump.dump_tree (di, t))
420 goto done;
422 /* Now handle the various kinds of nodes. */
423 switch (code)
425 int i;
427 case IDENTIFIER_NODE:
428 dump_string_field (di, "strg", IDENTIFIER_POINTER (t));
429 dump_int (di, "lngt", IDENTIFIER_LENGTH (t));
430 break;
432 case TREE_LIST:
433 dump_child ("purp", TREE_PURPOSE (t));
434 dump_child ("valu", TREE_VALUE (t));
435 dump_child ("chan", TREE_CHAIN (t));
436 break;
438 case STATEMENT_LIST:
440 tree_stmt_iterator it;
441 for (i = 0, it = tsi_start (t); !tsi_end_p (it); tsi_next (&it), i++)
443 char buffer[32];
444 sprintf (buffer, "%u", i);
445 dump_child (buffer, tsi_stmt (it));
448 break;
450 case TREE_VEC:
451 dump_int (di, "lngt", TREE_VEC_LENGTH (t));
452 for (i = 0; i < TREE_VEC_LENGTH (t); ++i)
454 char buffer[32];
455 sprintf (buffer, "%u", i);
456 dump_child (buffer, TREE_VEC_ELT (t, i));
458 break;
460 case INTEGER_TYPE:
461 case ENUMERAL_TYPE:
462 dump_int (di, "prec", TYPE_PRECISION (t));
463 dump_string_field (di, "sign", TYPE_UNSIGNED (t) ? "unsigned": "signed");
464 dump_child ("min", TYPE_MIN_VALUE (t));
465 dump_child ("max", TYPE_MAX_VALUE (t));
467 if (code == ENUMERAL_TYPE)
468 dump_child ("csts", TYPE_VALUES (t));
469 break;
471 case REAL_TYPE:
472 dump_int (di, "prec", TYPE_PRECISION (t));
473 break;
475 case FIXED_POINT_TYPE:
476 dump_int (di, "prec", TYPE_PRECISION (t));
477 dump_string_field (di, "sign", TYPE_UNSIGNED (t) ? "unsigned": "signed");
478 dump_string_field (di, "saturating",
479 TYPE_SATURATING (t) ? "saturating": "non-saturating");
480 break;
482 case POINTER_TYPE:
483 dump_child ("ptd", TREE_TYPE (t));
484 break;
486 case REFERENCE_TYPE:
487 dump_child ("refd", TREE_TYPE (t));
488 break;
490 case METHOD_TYPE:
491 dump_child ("clas", TYPE_METHOD_BASETYPE (t));
492 /* Fall through. */
494 case FUNCTION_TYPE:
495 dump_child ("retn", TREE_TYPE (t));
496 dump_child ("prms", TYPE_ARG_TYPES (t));
497 break;
499 case ARRAY_TYPE:
500 dump_child ("elts", TREE_TYPE (t));
501 dump_child ("domn", TYPE_DOMAIN (t));
502 break;
504 case RECORD_TYPE:
505 case UNION_TYPE:
506 if (TREE_CODE (t) == RECORD_TYPE)
507 dump_string_field (di, "tag", "struct");
508 else
509 dump_string_field (di, "tag", "union");
511 dump_child ("flds", TYPE_FIELDS (t));
512 dump_child ("fncs", TYPE_METHODS (t));
513 queue_and_dump_index (di, "binf", TYPE_BINFO (t),
514 DUMP_BINFO);
515 break;
517 case CONST_DECL:
518 dump_child ("cnst", DECL_INITIAL (t));
519 break;
521 case DEBUG_EXPR_DECL:
522 dump_int (di, "-uid", DEBUG_TEMP_UID (t));
523 /* Fall through. */
525 case VAR_DECL:
526 case PARM_DECL:
527 case FIELD_DECL:
528 case RESULT_DECL:
529 if (TREE_CODE (t) == PARM_DECL)
530 dump_child ("argt", DECL_ARG_TYPE (t));
531 else
532 dump_child ("init", DECL_INITIAL (t));
533 dump_child ("size", DECL_SIZE (t));
534 dump_int (di, "algn", DECL_ALIGN (t));
536 if (TREE_CODE (t) == FIELD_DECL)
538 if (DECL_FIELD_OFFSET (t))
539 dump_child ("bpos", bit_position (t));
541 else if (TREE_CODE (t) == VAR_DECL
542 || TREE_CODE (t) == PARM_DECL)
544 dump_int (di, "used", TREE_USED (t));
545 if (DECL_REGISTER (t))
546 dump_string_field (di, "spec", "register");
548 break;
550 case FUNCTION_DECL:
551 dump_child ("args", DECL_ARGUMENTS (t));
552 if (DECL_EXTERNAL (t))
553 dump_string_field (di, "body", "undefined");
554 if (TREE_PUBLIC (t))
555 dump_string_field (di, "link", "extern");
556 else
557 dump_string_field (di, "link", "static");
558 if (DECL_SAVED_TREE (t) && !dump_flag (di, TDF_SLIM, t))
559 dump_child ("body", DECL_SAVED_TREE (t));
560 break;
562 case INTEGER_CST:
563 if (TREE_INT_CST_HIGH (t))
564 dump_int (di, "high", TREE_INT_CST_HIGH (t));
565 dump_int (di, "low", TREE_INT_CST_LOW (t));
566 break;
568 case STRING_CST:
569 fprintf (di->stream, "strg: %-7s ", TREE_STRING_POINTER (t));
570 dump_int (di, "lngt", TREE_STRING_LENGTH (t));
571 break;
573 case REAL_CST:
574 dump_real (di, "valu", TREE_REAL_CST_PTR (t));
575 break;
577 case FIXED_CST:
578 dump_fixed (di, "valu", TREE_FIXED_CST_PTR (t));
579 break;
581 case TRUTH_NOT_EXPR:
582 case ADDR_EXPR:
583 case INDIRECT_REF:
584 case CLEANUP_POINT_EXPR:
585 case SAVE_EXPR:
586 case REALPART_EXPR:
587 case IMAGPART_EXPR:
588 /* These nodes are unary, but do not have code class `1'. */
589 dump_child ("op 0", TREE_OPERAND (t, 0));
590 break;
592 case TRUTH_ANDIF_EXPR:
593 case TRUTH_ORIF_EXPR:
594 case INIT_EXPR:
595 case MODIFY_EXPR:
596 case COMPOUND_EXPR:
597 case PREDECREMENT_EXPR:
598 case PREINCREMENT_EXPR:
599 case POSTDECREMENT_EXPR:
600 case POSTINCREMENT_EXPR:
601 /* These nodes are binary, but do not have code class `2'. */
602 dump_child ("op 0", TREE_OPERAND (t, 0));
603 dump_child ("op 1", TREE_OPERAND (t, 1));
604 break;
606 case COMPONENT_REF:
607 case BIT_FIELD_REF:
608 dump_child ("op 0", TREE_OPERAND (t, 0));
609 dump_child ("op 1", TREE_OPERAND (t, 1));
610 dump_child ("op 2", TREE_OPERAND (t, 2));
611 break;
613 case ARRAY_REF:
614 case ARRAY_RANGE_REF:
615 dump_child ("op 0", TREE_OPERAND (t, 0));
616 dump_child ("op 1", TREE_OPERAND (t, 1));
617 dump_child ("op 2", TREE_OPERAND (t, 2));
618 dump_child ("op 3", TREE_OPERAND (t, 3));
619 break;
621 case COND_EXPR:
622 dump_child ("op 0", TREE_OPERAND (t, 0));
623 dump_child ("op 1", TREE_OPERAND (t, 1));
624 dump_child ("op 2", TREE_OPERAND (t, 2));
625 break;
627 case TRY_FINALLY_EXPR:
628 dump_child ("op 0", TREE_OPERAND (t, 0));
629 dump_child ("op 1", TREE_OPERAND (t, 1));
630 break;
632 case CALL_EXPR:
634 int i = 0;
635 tree arg;
636 call_expr_arg_iterator iter;
637 dump_child ("fn", CALL_EXPR_FN (t));
638 FOR_EACH_CALL_EXPR_ARG (arg, iter, t)
640 char buffer[32];
641 sprintf (buffer, "%u", i);
642 dump_child (buffer, arg);
643 i++;
646 break;
648 case CONSTRUCTOR:
650 unsigned HOST_WIDE_INT cnt;
651 tree index, value;
652 dump_int (di, "lngt", VEC_length (constructor_elt,
653 CONSTRUCTOR_ELTS (t)));
654 FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (t), cnt, index, value)
656 dump_child ("idx", index);
657 dump_child ("val", value);
660 break;
662 case BIND_EXPR:
663 dump_child ("vars", TREE_OPERAND (t, 0));
664 dump_child ("body", TREE_OPERAND (t, 1));
665 break;
667 case LOOP_EXPR:
668 dump_child ("body", TREE_OPERAND (t, 0));
669 break;
671 case EXIT_EXPR:
672 dump_child ("cond", TREE_OPERAND (t, 0));
673 break;
675 case RETURN_EXPR:
676 dump_child ("expr", TREE_OPERAND (t, 0));
677 break;
679 case TARGET_EXPR:
680 dump_child ("decl", TREE_OPERAND (t, 0));
681 dump_child ("init", TREE_OPERAND (t, 1));
682 dump_child ("clnp", TREE_OPERAND (t, 2));
683 /* There really are two possible places the initializer can be.
684 After RTL expansion, the second operand is moved to the
685 position of the fourth operand, and the second operand
686 becomes NULL. */
687 dump_child ("init", TREE_OPERAND (t, 3));
688 break;
690 case CASE_LABEL_EXPR:
691 dump_child ("name", CASE_LABEL (t));
692 if (CASE_LOW (t))
694 dump_child ("low ", CASE_LOW (t));
695 if (CASE_HIGH (t))
696 dump_child ("high", CASE_HIGH (t));
698 break;
699 case LABEL_EXPR:
700 dump_child ("name", TREE_OPERAND (t,0));
701 break;
702 case GOTO_EXPR:
703 dump_child ("labl", TREE_OPERAND (t, 0));
704 break;
705 case SWITCH_EXPR:
706 dump_child ("cond", TREE_OPERAND (t, 0));
707 dump_child ("body", TREE_OPERAND (t, 1));
708 if (TREE_OPERAND (t, 2))
710 dump_child ("labl", TREE_OPERAND (t,2));
712 break;
713 case OMP_CLAUSE:
715 int i;
716 fprintf (di->stream, "%s\n", omp_clause_code_name[OMP_CLAUSE_CODE (t)]);
717 for (i = 0; i < omp_clause_num_ops[OMP_CLAUSE_CODE (t)]; i++)
718 dump_child ("op: ", OMP_CLAUSE_OPERAND (t, i));
720 break;
721 default:
722 /* There are no additional fields to print. */
723 break;
726 done:
727 if (dump_flag (di, TDF_ADDRESS, NULL))
728 dump_pointer (di, "addr", (void *)t);
730 /* Terminate the line. */
731 fprintf (di->stream, "\n");
734 /* Return nonzero if FLAG has been specified for the dump, and NODE
735 is not the root node of the dump. */
737 int dump_flag (dump_info_p di, int flag, const_tree node)
739 return (di->flags & flag) && (node != di->node);
742 /* Dump T, and all its children, on STREAM. */
744 void
745 dump_node (const_tree t, int flags, FILE *stream)
747 struct dump_info di;
748 dump_queue_p dq;
749 dump_queue_p next_dq;
751 /* Initialize the dump-information structure. */
752 di.stream = stream;
753 di.index = 0;
754 di.column = 0;
755 di.queue = 0;
756 di.queue_end = 0;
757 di.free_list = 0;
758 di.flags = flags;
759 di.node = t;
760 di.nodes = splay_tree_new (splay_tree_compare_pointers, 0,
761 (splay_tree_delete_value_fn) &free);
763 /* Queue up the first node. */
764 queue (&di, t, DUMP_NONE);
766 /* Until the queue is empty, keep dumping nodes. */
767 while (di.queue)
768 dequeue_and_dump (&di);
770 /* Now, clean up. */
771 for (dq = di.free_list; dq; dq = next_dq)
773 next_dq = dq->next;
774 free (dq);
776 splay_tree_delete (di.nodes);