remove unused files
[platform/upstream/gcc48.git] / gcc / tree-dump.c
1 /* Tree-dumping functionality for intermediate representation.
2    Copyright (C) 1999-2013 Free Software Foundation, Inc.
3    Written by Mark Mitchell <mark@codesourcery.com>
4
5 This file is part of GCC.
6
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.
11
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.
16
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/>.  */
20
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
32 static unsigned int queue (dump_info_p, const_tree, int);
33 static void dump_index (dump_info_p, unsigned int);
34 static void dequeue_and_dump (dump_info_p);
35 static void dump_new_line (dump_info_p);
36 static void dump_maybe_newline (dump_info_p);
37
38 /* Add T to the end of the queue of nodes to dump.  Returns the index
39    assigned to T.  */
40
41 static unsigned int
42 queue (dump_info_p di, const_tree t, int flags)
43 {
44   dump_queue_p dq;
45   dump_node_info_p dni;
46   unsigned int index;
47
48   /* Assign the next available index to T.  */
49   index = ++di->index;
50
51   /* Obtain a new queue node.  */
52   if (di->free_list)
53     {
54       dq = di->free_list;
55       di->free_list = dq->next;
56     }
57   else
58     dq = XNEW (struct dump_queue);
59
60   /* Create a new entry in the splay-tree.  */
61   dni = XNEW (struct dump_node_info);
62   dni->index = index;
63   dni->binfo_p = ((flags & DUMP_BINFO) != 0);
64   dq->node = splay_tree_insert (di->nodes, (splay_tree_key) t,
65                                 (splay_tree_value) dni);
66
67   /* Add it to the end of the queue.  */
68   dq->next = 0;
69   if (!di->queue_end)
70     di->queue = dq;
71   else
72     di->queue_end->next = dq;
73   di->queue_end = dq;
74
75   /* Return the index.  */
76   return index;
77 }
78
79 static void
80 dump_index (dump_info_p di, unsigned int index)
81 {
82   fprintf (di->stream, "@%-6u ", index);
83   di->column += 8;
84 }
85
86 /* If T has not already been output, queue it for subsequent output.
87    FIELD is a string to print before printing the index.  Then, the
88    index of T is printed.  */
89
90 void
91 queue_and_dump_index (dump_info_p di, const char *field, const_tree t, int flags)
92 {
93   unsigned int index;
94   splay_tree_node n;
95
96   /* If there's no node, just return.  This makes for fewer checks in
97      our callers.  */
98   if (!t)
99     return;
100
101   /* See if we've already queued or dumped this node.  */
102   n = splay_tree_lookup (di->nodes, (splay_tree_key) t);
103   if (n)
104     index = ((dump_node_info_p) n->value)->index;
105   else
106     /* If we haven't, add it to the queue.  */
107     index = queue (di, t, flags);
108
109   /* Print the index of the node.  */
110   dump_maybe_newline (di);
111   fprintf (di->stream, "%-4s: ", field);
112   di->column += 6;
113   dump_index (di, index);
114 }
115
116 /* Dump the type of T.  */
117
118 void
119 queue_and_dump_type (dump_info_p di, const_tree t)
120 {
121   queue_and_dump_index (di, "type", TREE_TYPE (t), DUMP_NONE);
122 }
123
124 /* Dump column control */
125 #define SOL_COLUMN 25           /* Start of line column.  */
126 #define EOL_COLUMN 55           /* End of line column.  */
127 #define COLUMN_ALIGNMENT 15     /* Alignment.  */
128
129 /* Insert a new line in the dump output, and indent to an appropriate
130    place to start printing more fields.  */
131
132 static void
133 dump_new_line (dump_info_p di)
134 {
135   fprintf (di->stream, "\n%*s", SOL_COLUMN, "");
136   di->column = SOL_COLUMN;
137 }
138
139 /* If necessary, insert a new line.  */
140
141 static void
142 dump_maybe_newline (dump_info_p di)
143 {
144   int extra;
145
146   /* See if we need a new line.  */
147   if (di->column > EOL_COLUMN)
148     dump_new_line (di);
149   /* See if we need any padding.  */
150   else if ((extra = (di->column - SOL_COLUMN) % COLUMN_ALIGNMENT) != 0)
151     {
152       fprintf (di->stream, "%*s", COLUMN_ALIGNMENT - extra, "");
153       di->column += COLUMN_ALIGNMENT - extra;
154     }
155 }
156
157 /* Dump FUNCTION_DECL FN as tree dump PHASE.  */
158
159 void
160 dump_function (int phase, tree fn)
161 {
162   FILE *stream;
163   int flags;
164
165   stream = dump_begin (phase, &flags);
166   if (stream)
167     {
168       dump_function_to_file (fn, stream, flags);
169       dump_end (phase, stream);
170     }
171 }
172
173 /* Dump pointer PTR using FIELD to identify it.  */
174
175 void
176 dump_pointer (dump_info_p di, const char *field, void *ptr)
177 {
178   dump_maybe_newline (di);
179   fprintf (di->stream, "%-4s: %-8" HOST_WIDE_INT_PRINT "x ", field,
180            (unsigned HOST_WIDE_INT) (uintptr_t) ptr);
181   di->column += 15;
182 }
183
184 /* Dump integer I using FIELD to identify it.  */
185
186 void
187 dump_int (dump_info_p di, const char *field, int i)
188 {
189   dump_maybe_newline (di);
190   fprintf (di->stream, "%-4s: %-7d ", field, i);
191   di->column += 14;
192 }
193
194 /* Dump the floating point value R, using FIELD to identify it.  */
195
196 static void
197 dump_real (dump_info_p di, const char *field, const REAL_VALUE_TYPE *r)
198 {
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;
204 }
205
206 /* Dump the fixed-point value F, using FIELD to identify it.  */
207
208 static void
209 dump_fixed (dump_info_p di, const char *field, const FIXED_VALUE_TYPE *f)
210 {
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;
216 }
217
218
219 /* Dump the string S.  */
220
221 void
222 dump_string (dump_info_p di, const char *string)
223 {
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;
230 }
231
232 /* Dump the string field S.  */
233
234 void
235 dump_string_field (dump_info_p di, const char *field, const char *string)
236 {
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;
243 }
244
245 /* Dump the next node in the queue.  */
246
247 static void
248 dequeue_and_dump (dump_info_p di)
249 {
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;
258
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;
265
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;
272
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;
282
283   /* Figure out what kind of node this is.  */
284   code = TREE_CODE (t);
285   code_class = TREE_CODE_CLASS (code);
286
287   /* Although BINFOs are TREE_VECs, we dump them specially so as to be
288      more informative.  */
289   if (dni->binfo_p)
290     {
291       unsigned ix;
292       tree base;
293       vec<tree, va_gc> *accesses = BINFO_BASE_ACCESSES (t);
294
295       dump_child ("type", BINFO_TYPE (t));
296
297       if (BINFO_VIRTUAL_P (t))
298         dump_string_field (di, "spec", "virt");
299
300       dump_int (di, "bases", BINFO_N_BASE_BINFOS (t));
301       for (ix = 0; BINFO_BASE_ITERATE (t, ix, base); ix++)
302         {
303           tree access = (accesses ? (*accesses)[ix] : access_public_node);
304           const char *string = NULL;
305
306           if (access == access_public_node)
307             string = "pub";
308           else if (access == access_protected_node)
309             string = "prot";
310           else if (access == access_private_node)
311             string = "priv";
312           else
313             gcc_unreachable ();
314
315           dump_string_field (di, "accs", string);
316           queue_and_dump_index (di, "binf", base, DUMP_BINFO);
317         }
318
319       goto done;
320     }
321
322   /* We can knock off a bunch of expression nodes in exactly the same
323      way.  */
324   if (IS_EXPR_CODE_CLASS (code_class))
325     {
326       /* If we're dumping children, dump them now.  */
327       queue_and_dump_type (di, t);
328
329       switch (code_class)
330         {
331         case tcc_unary:
332           dump_child ("op 0", TREE_OPERAND (t, 0));
333           break;
334
335         case tcc_binary:
336         case tcc_comparison:
337           dump_child ("op 0", TREE_OPERAND (t, 0));
338           dump_child ("op 1", TREE_OPERAND (t, 1));
339           break;
340
341         case tcc_expression:
342         case tcc_reference:
343         case tcc_statement:
344         case tcc_vl_exp:
345           /* These nodes are handled explicitly below.  */
346           break;
347
348         default:
349           gcc_unreachable ();
350         }
351     }
352   else if (DECL_P (t))
353     {
354       expanded_location xloc;
355       /* All declarations have names.  */
356       if (DECL_NAME (t))
357         dump_child ("name", DECL_NAME (t));
358       if (DECL_ASSEMBLER_NAME_SET_P (t)
359           && DECL_ASSEMBLER_NAME (t) != DECL_NAME (t))
360         dump_child ("mngl", DECL_ASSEMBLER_NAME (t));
361       if (DECL_ABSTRACT_ORIGIN (t))
362         dump_child ("orig", DECL_ABSTRACT_ORIGIN (t));
363       /* And types.  */
364       queue_and_dump_type (di, t);
365       dump_child ("scpe", DECL_CONTEXT (t));
366       /* And a source position.  */
367       xloc = expand_location (DECL_SOURCE_LOCATION (t));
368       if (xloc.file)
369         {
370           const char *filename = lbasename (xloc.file);
371
372           dump_maybe_newline (di);
373           fprintf (di->stream, "srcp: %s:%-6d ", filename,
374                    xloc.line);
375           di->column += 6 + strlen (filename) + 8;
376         }
377       /* And any declaration can be compiler-generated.  */
378       if (CODE_CONTAINS_STRUCT (TREE_CODE (t), TS_DECL_COMMON)
379           && DECL_ARTIFICIAL (t))
380         dump_string_field (di, "note", "artificial");
381       if (DECL_CHAIN (t) && !dump_flag (di, TDF_SLIM, NULL))
382         dump_child ("chain", DECL_CHAIN (t));
383     }
384   else if (code_class == tcc_type)
385     {
386       /* All types have qualifiers.  */
387       int quals = lang_hooks.tree_dump.type_quals (t);
388
389       if (quals != TYPE_UNQUALIFIED)
390         {
391           fprintf (di->stream, "qual: %c%c%c     ",
392                    (quals & TYPE_QUAL_CONST) ? 'c' : ' ',
393                    (quals & TYPE_QUAL_VOLATILE) ? 'v' : ' ',
394                    (quals & TYPE_QUAL_RESTRICT) ? 'r' : ' ');
395           di->column += 14;
396         }
397
398       /* All types have associated declarations.  */
399       dump_child ("name", TYPE_NAME (t));
400
401       /* All types have a main variant.  */
402       if (TYPE_MAIN_VARIANT (t) != t)
403         dump_child ("unql", TYPE_MAIN_VARIANT (t));
404
405       /* And sizes.  */
406       dump_child ("size", TYPE_SIZE (t));
407
408       /* All types have alignments.  */
409       dump_int (di, "algn", TYPE_ALIGN (t));
410     }
411   else if (code_class == tcc_constant)
412     /* All constants can have types.  */
413     queue_and_dump_type (di, t);
414
415   /* Give the language-specific code a chance to print something.  If
416      it's completely taken care of things, don't bother printing
417      anything more ourselves.  */
418   if (lang_hooks.tree_dump.dump_tree (di, t))
419     goto done;
420
421   /* Now handle the various kinds of nodes.  */
422   switch (code)
423     {
424       int i;
425
426     case IDENTIFIER_NODE:
427       dump_string_field (di, "strg", IDENTIFIER_POINTER (t));
428       dump_int (di, "lngt", IDENTIFIER_LENGTH (t));
429       break;
430
431     case TREE_LIST:
432       dump_child ("purp", TREE_PURPOSE (t));
433       dump_child ("valu", TREE_VALUE (t));
434       dump_child ("chan", TREE_CHAIN (t));
435       break;
436
437     case STATEMENT_LIST:
438       {
439         tree_stmt_iterator it;
440         for (i = 0, it = tsi_start (t); !tsi_end_p (it); tsi_next (&it), i++)
441           {
442             char buffer[32];
443             sprintf (buffer, "%u", i);
444             dump_child (buffer, tsi_stmt (it));
445           }
446       }
447       break;
448
449     case TREE_VEC:
450       dump_int (di, "lngt", TREE_VEC_LENGTH (t));
451       for (i = 0; i < TREE_VEC_LENGTH (t); ++i)
452         {
453           char buffer[32];
454           sprintf (buffer, "%u", i);
455           dump_child (buffer, TREE_VEC_ELT (t, i));
456         }
457       break;
458
459     case INTEGER_TYPE:
460     case ENUMERAL_TYPE:
461       dump_int (di, "prec", TYPE_PRECISION (t));
462       dump_string_field (di, "sign", TYPE_UNSIGNED (t) ? "unsigned": "signed");
463       dump_child ("min", TYPE_MIN_VALUE (t));
464       dump_child ("max", TYPE_MAX_VALUE (t));
465
466       if (code == ENUMERAL_TYPE)
467         dump_child ("csts", TYPE_VALUES (t));
468       break;
469
470     case REAL_TYPE:
471       dump_int (di, "prec", TYPE_PRECISION (t));
472       break;
473
474     case FIXED_POINT_TYPE:
475       dump_int (di, "prec", TYPE_PRECISION (t));
476       dump_string_field (di, "sign", TYPE_UNSIGNED (t) ? "unsigned": "signed");
477       dump_string_field (di, "saturating",
478                          TYPE_SATURATING (t) ? "saturating": "non-saturating");
479       break;
480
481     case POINTER_TYPE:
482       dump_child ("ptd", TREE_TYPE (t));
483       break;
484
485     case REFERENCE_TYPE:
486       dump_child ("refd", TREE_TYPE (t));
487       break;
488
489     case METHOD_TYPE:
490       dump_child ("clas", TYPE_METHOD_BASETYPE (t));
491       /* Fall through.  */
492
493     case FUNCTION_TYPE:
494       dump_child ("retn", TREE_TYPE (t));
495       dump_child ("prms", TYPE_ARG_TYPES (t));
496       break;
497
498     case ARRAY_TYPE:
499       dump_child ("elts", TREE_TYPE (t));
500       dump_child ("domn", TYPE_DOMAIN (t));
501       break;
502
503     case RECORD_TYPE:
504     case UNION_TYPE:
505       if (TREE_CODE (t) == RECORD_TYPE)
506         dump_string_field (di, "tag", "struct");
507       else
508         dump_string_field (di, "tag", "union");
509
510       dump_child ("flds", TYPE_FIELDS (t));
511       dump_child ("fncs", TYPE_METHODS (t));
512       queue_and_dump_index (di, "binf", TYPE_BINFO (t),
513                             DUMP_BINFO);
514       break;
515
516     case CONST_DECL:
517       dump_child ("cnst", DECL_INITIAL (t));
518       break;
519
520     case DEBUG_EXPR_DECL:
521       dump_int (di, "-uid", DEBUG_TEMP_UID (t));
522       /* Fall through.  */
523
524     case VAR_DECL:
525     case PARM_DECL:
526     case FIELD_DECL:
527     case RESULT_DECL:
528       if (TREE_CODE (t) == PARM_DECL)
529         dump_child ("argt", DECL_ARG_TYPE (t));
530       else
531         dump_child ("init", DECL_INITIAL (t));
532       dump_child ("size", DECL_SIZE (t));
533       dump_int (di, "algn", DECL_ALIGN (t));
534
535       if (TREE_CODE (t) == FIELD_DECL)
536         {
537           if (DECL_FIELD_OFFSET (t))
538             dump_child ("bpos", bit_position (t));
539         }
540       else if (TREE_CODE (t) == VAR_DECL
541                || TREE_CODE (t) == PARM_DECL)
542         {
543           dump_int (di, "used", TREE_USED (t));
544           if (DECL_REGISTER (t))
545             dump_string_field (di, "spec", "register");
546         }
547       break;
548
549     case FUNCTION_DECL:
550       dump_child ("args", DECL_ARGUMENTS (t));
551       if (DECL_EXTERNAL (t))
552         dump_string_field (di, "body", "undefined");
553       if (TREE_PUBLIC (t))
554         dump_string_field (di, "link", "extern");
555       else
556         dump_string_field (di, "link", "static");
557       if (DECL_SAVED_TREE (t) && !dump_flag (di, TDF_SLIM, t))
558         dump_child ("body", DECL_SAVED_TREE (t));
559       break;
560
561     case INTEGER_CST:
562       if (TREE_INT_CST_HIGH (t))
563         dump_int (di, "high", TREE_INT_CST_HIGH (t));
564       dump_int (di, "low", TREE_INT_CST_LOW (t));
565       break;
566
567     case STRING_CST:
568       fprintf (di->stream, "strg: %-7s ", TREE_STRING_POINTER (t));
569       dump_int (di, "lngt", TREE_STRING_LENGTH (t));
570       break;
571
572     case REAL_CST:
573       dump_real (di, "valu", TREE_REAL_CST_PTR (t));
574       break;
575
576     case FIXED_CST:
577       dump_fixed (di, "valu", TREE_FIXED_CST_PTR (t));
578       break;
579
580     case TRUTH_NOT_EXPR:
581     case ADDR_EXPR:
582     case INDIRECT_REF:
583     case CLEANUP_POINT_EXPR:
584     case SAVE_EXPR:
585     case REALPART_EXPR:
586     case IMAGPART_EXPR:
587       /* These nodes are unary, but do not have code class `1'.  */
588       dump_child ("op 0", TREE_OPERAND (t, 0));
589       break;
590
591     case TRUTH_ANDIF_EXPR:
592     case TRUTH_ORIF_EXPR:
593     case INIT_EXPR:
594     case MODIFY_EXPR:
595     case COMPOUND_EXPR:
596     case PREDECREMENT_EXPR:
597     case PREINCREMENT_EXPR:
598     case POSTDECREMENT_EXPR:
599     case POSTINCREMENT_EXPR:
600       /* These nodes are binary, but do not have code class `2'.  */
601       dump_child ("op 0", TREE_OPERAND (t, 0));
602       dump_child ("op 1", TREE_OPERAND (t, 1));
603       break;
604
605     case COMPONENT_REF:
606     case BIT_FIELD_REF:
607       dump_child ("op 0", TREE_OPERAND (t, 0));
608       dump_child ("op 1", TREE_OPERAND (t, 1));
609       dump_child ("op 2", TREE_OPERAND (t, 2));
610       break;
611
612     case ARRAY_REF:
613     case ARRAY_RANGE_REF:
614       dump_child ("op 0", TREE_OPERAND (t, 0));
615       dump_child ("op 1", TREE_OPERAND (t, 1));
616       dump_child ("op 2", TREE_OPERAND (t, 2));
617       dump_child ("op 3", TREE_OPERAND (t, 3));
618       break;
619
620     case COND_EXPR:
621       dump_child ("op 0", TREE_OPERAND (t, 0));
622       dump_child ("op 1", TREE_OPERAND (t, 1));
623       dump_child ("op 2", TREE_OPERAND (t, 2));
624       break;
625
626     case TRY_FINALLY_EXPR:
627       dump_child ("op 0", TREE_OPERAND (t, 0));
628       dump_child ("op 1", TREE_OPERAND (t, 1));
629       break;
630
631     case CALL_EXPR:
632       {
633         int i = 0;
634         tree arg;
635         call_expr_arg_iterator iter;
636         dump_child ("fn", CALL_EXPR_FN (t));
637         FOR_EACH_CALL_EXPR_ARG (arg, iter, t)
638           {
639             char buffer[32];
640             sprintf (buffer, "%u", i);
641             dump_child (buffer, arg);
642             i++;
643           }
644       }
645       break;
646
647     case CONSTRUCTOR:
648       {
649         unsigned HOST_WIDE_INT cnt;
650         tree index, value;
651         dump_int (di, "lngt", vec_safe_length (CONSTRUCTOR_ELTS (t)));
652         FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (t), cnt, index, value)
653           {
654             dump_child ("idx", index);
655             dump_child ("val", value);
656           }
657       }
658       break;
659
660     case BIND_EXPR:
661       dump_child ("vars", TREE_OPERAND (t, 0));
662       dump_child ("body", TREE_OPERAND (t, 1));
663       break;
664
665     case LOOP_EXPR:
666       dump_child ("body", TREE_OPERAND (t, 0));
667       break;
668
669     case EXIT_EXPR:
670       dump_child ("cond", TREE_OPERAND (t, 0));
671       break;
672
673     case RETURN_EXPR:
674       dump_child ("expr", TREE_OPERAND (t, 0));
675       break;
676
677     case TARGET_EXPR:
678       dump_child ("decl", TREE_OPERAND (t, 0));
679       dump_child ("init", TREE_OPERAND (t, 1));
680       dump_child ("clnp", TREE_OPERAND (t, 2));
681       /* There really are two possible places the initializer can be.
682          After RTL expansion, the second operand is moved to the
683          position of the fourth operand, and the second operand
684          becomes NULL.  */
685       dump_child ("init", TREE_OPERAND (t, 3));
686       break;
687
688     case CASE_LABEL_EXPR:
689       dump_child ("name", CASE_LABEL (t));
690       if (CASE_LOW (t))
691         {
692           dump_child ("low ", CASE_LOW (t));
693           if (CASE_HIGH (t))
694             dump_child ("high", CASE_HIGH (t));
695         }
696       break;
697     case LABEL_EXPR:
698       dump_child ("name", TREE_OPERAND (t,0));
699       break;
700     case GOTO_EXPR:
701       dump_child ("labl", TREE_OPERAND (t, 0));
702       break;
703     case SWITCH_EXPR:
704       dump_child ("cond", TREE_OPERAND (t, 0));
705       dump_child ("body", TREE_OPERAND (t, 1));
706       if (TREE_OPERAND (t, 2))
707         {
708           dump_child ("labl", TREE_OPERAND (t,2));
709         }
710       break;
711     case OMP_CLAUSE:
712       {
713         int i;
714         fprintf (di->stream, "%s\n", omp_clause_code_name[OMP_CLAUSE_CODE (t)]);
715         for (i = 0; i < omp_clause_num_ops[OMP_CLAUSE_CODE (t)]; i++)
716           dump_child ("op: ", OMP_CLAUSE_OPERAND (t, i));
717       }
718       break;
719     default:
720       /* There are no additional fields to print.  */
721       break;
722     }
723
724  done:
725   if (dump_flag (di, TDF_ADDRESS, NULL))
726     dump_pointer (di, "addr", (void *)t);
727
728   /* Terminate the line.  */
729   fprintf (di->stream, "\n");
730 }
731
732 /* Return nonzero if FLAG has been specified for the dump, and NODE
733    is not the root node of the dump.  */
734
735 int dump_flag (dump_info_p di, int flag, const_tree node)
736 {
737   return (di->flags & flag) && (node != di->node);
738 }
739
740 /* Dump T, and all its children, on STREAM.  */
741
742 void
743 dump_node (const_tree t, int flags, FILE *stream)
744 {
745   struct dump_info di;
746   dump_queue_p dq;
747   dump_queue_p next_dq;
748
749   /* Initialize the dump-information structure.  */
750   di.stream = stream;
751   di.index = 0;
752   di.column = 0;
753   di.queue = 0;
754   di.queue_end = 0;
755   di.free_list = 0;
756   di.flags = flags;
757   di.node = t;
758   di.nodes = splay_tree_new (splay_tree_compare_pointers, 0,
759                              (splay_tree_delete_value_fn) &free);
760
761   /* Queue up the first node.  */
762   queue (&di, t, DUMP_NONE);
763
764   /* Until the queue is empty, keep dumping nodes.  */
765   while (di.queue)
766     dequeue_and_dump (&di);
767
768   /* Now, clean up.  */
769   for (dq = di.free_list; dq; dq = next_dq)
770     {
771       next_dq = dq->next;
772       free (dq);
773     }
774   splay_tree_delete (di.nodes);
775 }