gcc/
[official-gcc.git] / gcc / tree-dump.c
blob9b3494f7ba816d5b5109ec734474ac32dd6dbcb7
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 "alias.h"
26 #include "symtab.h"
27 #include "tree.h"
28 #include "splay-tree.h"
29 #include "filenames.h"
30 #include "tree-dump.h"
31 #include "langhooks.h"
32 #include "tree-iterator.h"
33 #include "tree-pretty-print.h"
34 #include "tree-cfg.h"
35 #include "wide-int-print.h"
37 static unsigned int queue (dump_info_p, const_tree, int);
38 static void dump_index (dump_info_p, unsigned int);
39 static void dequeue_and_dump (dump_info_p);
40 static void dump_new_line (dump_info_p);
41 static void dump_maybe_newline (dump_info_p);
43 /* Add T to the end of the queue of nodes to dump. Returns the index
44 assigned to T. */
46 static unsigned int
47 queue (dump_info_p di, const_tree t, int flags)
49 dump_queue_p dq;
50 dump_node_info_p dni;
51 unsigned int index;
53 /* Assign the next available index to T. */
54 index = ++di->index;
56 /* Obtain a new queue node. */
57 if (di->free_list)
59 dq = di->free_list;
60 di->free_list = dq->next;
62 else
63 dq = XNEW (struct dump_queue);
65 /* Create a new entry in the splay-tree. */
66 dni = XNEW (struct dump_node_info);
67 dni->index = index;
68 dni->binfo_p = ((flags & DUMP_BINFO) != 0);
69 dq->node = splay_tree_insert (di->nodes, (splay_tree_key) t,
70 (splay_tree_value) dni);
72 /* Add it to the end of the queue. */
73 dq->next = 0;
74 if (!di->queue_end)
75 di->queue = dq;
76 else
77 di->queue_end->next = dq;
78 di->queue_end = dq;
80 /* Return the index. */
81 return index;
84 static void
85 dump_index (dump_info_p di, unsigned int index)
87 fprintf (di->stream, "@%-6u ", index);
88 di->column += 8;
91 /* If T has not already been output, queue it for subsequent output.
92 FIELD is a string to print before printing the index. Then, the
93 index of T is printed. */
95 void
96 queue_and_dump_index (dump_info_p di, const char *field, const_tree t, int flags)
98 unsigned int index;
99 splay_tree_node n;
101 /* If there's no node, just return. This makes for fewer checks in
102 our callers. */
103 if (!t)
104 return;
106 /* See if we've already queued or dumped this node. */
107 n = splay_tree_lookup (di->nodes, (splay_tree_key) t);
108 if (n)
109 index = ((dump_node_info_p) n->value)->index;
110 else
111 /* If we haven't, add it to the queue. */
112 index = queue (di, t, flags);
114 /* Print the index of the node. */
115 dump_maybe_newline (di);
116 fprintf (di->stream, "%-4s: ", field);
117 di->column += 6;
118 dump_index (di, index);
121 /* Dump the type of T. */
123 void
124 queue_and_dump_type (dump_info_p di, const_tree t)
126 queue_and_dump_index (di, "type", TREE_TYPE (t), DUMP_NONE);
129 /* Dump column control */
130 #define SOL_COLUMN 25 /* Start of line column. */
131 #define EOL_COLUMN 55 /* End of line column. */
132 #define COLUMN_ALIGNMENT 15 /* Alignment. */
134 /* Insert a new line in the dump output, and indent to an appropriate
135 place to start printing more fields. */
137 static void
138 dump_new_line (dump_info_p di)
140 fprintf (di->stream, "\n%*s", SOL_COLUMN, "");
141 di->column = SOL_COLUMN;
144 /* If necessary, insert a new line. */
146 static void
147 dump_maybe_newline (dump_info_p di)
149 int extra;
151 /* See if we need a new line. */
152 if (di->column > EOL_COLUMN)
153 dump_new_line (di);
154 /* See if we need any padding. */
155 else if ((extra = (di->column - SOL_COLUMN) % COLUMN_ALIGNMENT) != 0)
157 fprintf (di->stream, "%*s", COLUMN_ALIGNMENT - extra, "");
158 di->column += COLUMN_ALIGNMENT - extra;
162 /* Dump FUNCTION_DECL FN as tree dump PHASE. */
164 void
165 dump_function (int phase, tree fn)
167 FILE *stream;
168 int flags;
170 stream = dump_begin (phase, &flags);
171 if (stream)
173 dump_function_to_file (fn, stream, flags);
174 dump_end (phase, stream);
178 /* Dump pointer PTR using FIELD to identify it. */
180 void
181 dump_pointer (dump_info_p di, const char *field, void *ptr)
183 dump_maybe_newline (di);
184 fprintf (di->stream, "%-4s: %-8" HOST_WIDE_INT_PRINT "x ", field,
185 (unsigned HOST_WIDE_INT) (uintptr_t) ptr);
186 di->column += 15;
189 /* Dump integer I using FIELD to identify it. */
191 void
192 dump_int (dump_info_p di, const char *field, int i)
194 dump_maybe_newline (di);
195 fprintf (di->stream, "%-4s: %-7d ", field, i);
196 di->column += 14;
199 /* Dump the floating point value R, using FIELD to identify it. */
201 static void
202 dump_real (dump_info_p di, const char *field, const REAL_VALUE_TYPE *r)
204 char buf[32];
205 real_to_decimal (buf, r, sizeof (buf), 0, true);
206 dump_maybe_newline (di);
207 fprintf (di->stream, "%-4s: %s ", field, buf);
208 di->column += strlen (buf) + 7;
211 /* Dump the fixed-point value F, using FIELD to identify it. */
213 static void
214 dump_fixed (dump_info_p di, const char *field, const FIXED_VALUE_TYPE *f)
216 char buf[32];
217 fixed_to_decimal (buf, f, sizeof (buf));
218 dump_maybe_newline (di);
219 fprintf (di->stream, "%-4s: %s ", field, buf);
220 di->column += strlen (buf) + 7;
224 /* Dump the string S. */
226 void
227 dump_string (dump_info_p di, const char *string)
229 dump_maybe_newline (di);
230 fprintf (di->stream, "%-13s ", string);
231 if (strlen (string) > 13)
232 di->column += strlen (string) + 1;
233 else
234 di->column += 14;
237 /* Dump the string field S. */
239 void
240 dump_string_field (dump_info_p di, const char *field, const char *string)
242 dump_maybe_newline (di);
243 fprintf (di->stream, "%-4s: %-7s ", field, string);
244 if (strlen (string) > 7)
245 di->column += 6 + strlen (string) + 1;
246 else
247 di->column += 14;
250 /* Dump the next node in the queue. */
252 static void
253 dequeue_and_dump (dump_info_p di)
255 dump_queue_p dq;
256 splay_tree_node stn;
257 dump_node_info_p dni;
258 tree t;
259 unsigned int index;
260 enum tree_code code;
261 enum tree_code_class code_class;
262 const char* code_name;
264 /* Get the next node from the queue. */
265 dq = di->queue;
266 stn = dq->node;
267 t = (tree) stn->key;
268 dni = (dump_node_info_p) stn->value;
269 index = dni->index;
271 /* Remove the node from the queue, and put it on the free list. */
272 di->queue = dq->next;
273 if (!di->queue)
274 di->queue_end = 0;
275 dq->next = di->free_list;
276 di->free_list = dq;
278 /* Print the node index. */
279 dump_index (di, index);
280 /* And the type of node this is. */
281 if (dni->binfo_p)
282 code_name = "binfo";
283 else
284 code_name = get_tree_code_name (TREE_CODE (t));
285 fprintf (di->stream, "%-16s ", code_name);
286 di->column = 25;
288 /* Figure out what kind of node this is. */
289 code = TREE_CODE (t);
290 code_class = TREE_CODE_CLASS (code);
292 /* Although BINFOs are TREE_VECs, we dump them specially so as to be
293 more informative. */
294 if (dni->binfo_p)
296 unsigned ix;
297 tree base;
298 vec<tree, va_gc> *accesses = BINFO_BASE_ACCESSES (t);
300 dump_child ("type", BINFO_TYPE (t));
302 if (BINFO_VIRTUAL_P (t))
303 dump_string_field (di, "spec", "virt");
305 dump_int (di, "bases", BINFO_N_BASE_BINFOS (t));
306 for (ix = 0; BINFO_BASE_ITERATE (t, ix, base); ix++)
308 tree access = (accesses ? (*accesses)[ix] : access_public_node);
309 const char *string = NULL;
311 if (access == access_public_node)
312 string = "pub";
313 else if (access == access_protected_node)
314 string = "prot";
315 else if (access == access_private_node)
316 string = "priv";
317 else
318 gcc_unreachable ();
320 dump_string_field (di, "accs", string);
321 queue_and_dump_index (di, "binf", base, DUMP_BINFO);
324 goto done;
327 /* We can knock off a bunch of expression nodes in exactly the same
328 way. */
329 if (IS_EXPR_CODE_CLASS (code_class))
331 /* If we're dumping children, dump them now. */
332 queue_and_dump_type (di, t);
334 switch (code_class)
336 case tcc_unary:
337 dump_child ("op 0", TREE_OPERAND (t, 0));
338 break;
340 case tcc_binary:
341 case tcc_comparison:
342 dump_child ("op 0", TREE_OPERAND (t, 0));
343 dump_child ("op 1", TREE_OPERAND (t, 1));
344 break;
346 case tcc_expression:
347 case tcc_reference:
348 case tcc_statement:
349 case tcc_vl_exp:
350 /* These nodes are handled explicitly below. */
351 break;
353 default:
354 gcc_unreachable ();
357 else if (DECL_P (t))
359 expanded_location xloc;
360 /* All declarations have names. */
361 if (DECL_NAME (t))
362 dump_child ("name", DECL_NAME (t));
363 if (DECL_ASSEMBLER_NAME_SET_P (t)
364 && DECL_ASSEMBLER_NAME (t) != DECL_NAME (t))
365 dump_child ("mngl", DECL_ASSEMBLER_NAME (t));
366 if (DECL_ABSTRACT_ORIGIN (t))
367 dump_child ("orig", DECL_ABSTRACT_ORIGIN (t));
368 /* And types. */
369 queue_and_dump_type (di, t);
370 dump_child ("scpe", DECL_CONTEXT (t));
371 /* And a source position. */
372 xloc = expand_location (DECL_SOURCE_LOCATION (t));
373 if (xloc.file)
375 const char *filename = lbasename (xloc.file);
377 dump_maybe_newline (di);
378 fprintf (di->stream, "srcp: %s:%-6d ", filename,
379 xloc.line);
380 di->column += 6 + strlen (filename) + 8;
382 /* And any declaration can be compiler-generated. */
383 if (CODE_CONTAINS_STRUCT (TREE_CODE (t), TS_DECL_COMMON)
384 && DECL_ARTIFICIAL (t))
385 dump_string_field (di, "note", "artificial");
386 if (DECL_CHAIN (t) && !dump_flag (di, TDF_SLIM, NULL))
387 dump_child ("chain", DECL_CHAIN (t));
389 else if (code_class == tcc_type)
391 /* All types have qualifiers. */
392 int quals = lang_hooks.tree_dump.type_quals (t);
394 if (quals != TYPE_UNQUALIFIED)
396 fprintf (di->stream, "qual: %c%c%c ",
397 (quals & TYPE_QUAL_CONST) ? 'c' : ' ',
398 (quals & TYPE_QUAL_VOLATILE) ? 'v' : ' ',
399 (quals & TYPE_QUAL_RESTRICT) ? 'r' : ' ');
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 fprintf (di->stream, "int: ");
568 print_decs (t, di->stream);
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);