OSDN Git Service

* call.c: PROTO -> PARAMS.
[pf3gnuchains/gcc-fork.git] / gcc / cp / dump.c
1 /* Tree-dumping functionality for intermediate representation.
2    Copyright (C) 1999, 2000 Free Software Foundation, Inc.
3    Written by Mark Mitchell <mark@codesourcery.com>
4
5 This file is part of GNU CC.
6
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING.  If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA.  */
21
22 #include "config.h"
23 #include "system.h"
24 #include "tree.h"
25 #include "cp-tree.h"
26
27 /* Flags used with queue functions.  */
28 #define DUMP_NONE     0
29 #define DUMP_BINFO    1
30
31 /* Information about a node to be dumped.  */
32
33 typedef struct dump_node_info
34 {
35   /* The index for the node.  */
36   unsigned int index;
37   /* Nonzero if the node is a binfo.  */
38   unsigned int binfo_p : 1;
39 } *dump_node_info_p;
40
41 /* A dump_queue is a link in the queue of things to be dumped.  */
42
43 typedef struct dump_queue
44 {
45   /* The queued tree node.  */
46   splay_tree_node node;
47   /* The next node in the queue.  */
48   struct dump_queue *next;
49 } *dump_queue_p;
50
51 /* A dump_info gives information about how we should perform the dump 
52    and about the current state of the dump.  */
53
54 typedef struct dump_info
55 {
56   /* The stream on which to dump the information.  */
57   FILE *stream;
58   /* The next unused node index.  */
59   unsigned int index;
60   /* The next column.  */
61   unsigned int column;
62   /* The first node in the queue of nodes to be written out.  */
63   dump_queue_p queue;
64   /* The last node in the queue.  */
65   dump_queue_p queue_end;
66   /* Free queue nodes.  */
67   dump_queue_p free_list;
68   /* The tree nodes which we have already written out.  The 
69      keys are the addresses of the nodes; the values are the integer
70      indices we assigned them.  */
71   splay_tree nodes;
72 } *dump_info_p;
73
74 static unsigned int queue PARAMS ((dump_info_p, tree, int));
75 static void dump_index PARAMS ((dump_info_p, unsigned int));
76 static void queue_and_dump_index PARAMS ((dump_info_p, const char *, tree, int));
77 static void queue_and_dump_type PARAMS ((dump_info_p, tree));
78 static void dequeue_and_dump PARAMS ((dump_info_p));
79 static void dump_new_line PARAMS ((dump_info_p));
80 static void dump_maybe_newline PARAMS ((dump_info_p));
81 static void dump_int PARAMS ((dump_info_p, const char *, int));
82 static void dump_string PARAMS ((dump_info_p, const char *));
83 static void dump_string_field PARAMS ((dump_info_p, const char *, const char *));
84 static void dump_node PARAMS ((tree, FILE *));
85 static void dump_stmt PARAMS ((dump_info_p, tree));
86 static void dump_next_stmt PARAMS ((dump_info_p, tree));
87
88 /* Add T to the end of the queue of nodes to dump.  Returns the index
89    assigned to T.  */
90
91 static unsigned int
92 queue (di, t, flags)
93      dump_info_p di;
94      tree t;
95      int flags;
96 {
97   dump_queue_p dq;
98   dump_node_info_p dni;
99   unsigned int index;
100
101   /* Assign the next available index to T.  */
102   index = ++di->index;
103
104   /* Obtain a new queue node.  */
105   if (di->free_list)
106     {
107       dq = di->free_list;
108       di->free_list = dq->next;
109     }
110   else
111     dq = (dump_queue_p) xmalloc (sizeof (struct dump_queue));
112
113   /* Create a new entry in the splay-tree.  */
114   dni = (dump_node_info_p) xmalloc (sizeof (struct dump_node_info));
115   dni->index = index;
116   dni->binfo_p = ((flags & DUMP_BINFO) != 0);
117   dq->node = splay_tree_insert (di->nodes, (splay_tree_key) t, 
118                                 (splay_tree_value) dni);
119
120   /* Add it to the end of the queue.  */
121   dq->next = 0;
122   if (!di->queue_end)
123     di->queue = dq;
124   else
125     di->queue_end->next = dq;
126   di->queue_end = dq;
127
128   /* Return the index.  */
129   return index;
130 }
131
132 static void
133 dump_index (di, index)
134      dump_info_p di;
135      unsigned int index;
136 {
137   fprintf (di->stream, "@%-6u ", index);
138   di->column += 8;
139 }
140
141 /* If T has not already been output, queue it for subsequent output.
142    FIELD is a string to print before printing the index.  Then, the
143    index of T is printed.  */
144
145 static void
146 queue_and_dump_index (di, field, t, flags)
147      dump_info_p di;
148      const char *field;
149      tree t;
150      int flags;
151 {
152   unsigned int index;
153   splay_tree_node n;
154
155   /* If there's no node, just return.  This makes for fewer checks in
156      our callers.  */
157   if (!t)
158     return;
159
160   /* See if we've already queued or dumped this node.  */
161   n = splay_tree_lookup (di->nodes, (splay_tree_key) t);
162   if (n)
163     index = ((dump_node_info_p) n->value)->index;
164   else
165     /* If we haven't, add it to the queue.  */
166     index = queue (di, t, flags);
167
168   /* Print the index of the node.  */
169   dump_maybe_newline (di);
170   fprintf (di->stream, "%-4s: ", field);
171   di->column += 6;
172   dump_index (di, index);
173 }
174
175 /* Dump the type of T.  */
176
177 static void
178 queue_and_dump_type (di, t)
179      dump_info_p di;
180      tree t;
181 {
182   queue_and_dump_index (di, "type", TREE_TYPE (t), DUMP_NONE);
183 }
184
185 /* Insert a new line in the dump output, and indent to an appropriate
186    place to start printing more fields.  */
187
188 static void
189 dump_new_line (di)
190      dump_info_p di;
191 {
192   fprintf (di->stream, "\n%25s", "");
193   di->column = 25;
194 }
195
196 /* If necessary, insert a new line.  */
197
198 static void
199 dump_maybe_newline (di)
200      dump_info_p di;
201 {
202   /* See if we need a new line.  */
203   if (di->column > 53)
204     dump_new_line (di);
205   /* See if we need any padding.  */
206   else if ((di->column - 25) % 14 != 0)
207     {
208       fprintf (di->stream, "%*s", 14 - ((di->column - 25) % 14), "");
209       di->column += 14 - (di->column - 25) % 14;
210     }
211 }
212
213 /* Dump I using FIELD to identity it.  */
214
215 static void
216 dump_int (di, field, i)
217      dump_info_p di;
218      const char *field;
219      int i;
220 {
221   dump_maybe_newline (di);
222   fprintf (di->stream, "%-4s: %-7d ", field, i);
223   di->column += 14;
224 }
225
226 /* Dump the string S.  */
227
228 static void
229 dump_string (di, string)
230      dump_info_p di;
231      const char *string;
232 {
233   dump_maybe_newline (di);
234   fprintf (di->stream, "%-13s ", string);
235   if (strlen (string) > 13)
236     di->column += strlen (string) + 1;
237   else
238     di->column += 14;
239 }
240
241 /* Dump the string field S.  */
242
243 static void
244 dump_string_field (di, field, string)
245      dump_info_p di;
246      const char *field;
247      const char *string;
248 {
249   dump_maybe_newline (di);
250   fprintf (di->stream, "%-4s: %-7s ", field, string);
251   if (strlen (string) > 7)
252     di->column += 6 + strlen (string) + 1;
253   else
254     di->column += 14;
255 }
256
257 /* Dump information common to statements from STMT.  */
258
259 static void
260 dump_stmt (di, t)
261      dump_info_p di;
262      tree t;
263 {
264   dump_int (di, "line", STMT_LINENO (t));
265 }
266
267 /* Dump the CHILD and its children.  */
268 #define dump_child(field, child) \
269   queue_and_dump_index (di, field, child, DUMP_NONE)
270
271 /* Dump the next statement after STMT.  */
272
273 static void
274 dump_next_stmt (di, t)
275      dump_info_p di;
276      tree t;
277 {
278   dump_child ("next", TREE_CHAIN (t));
279 }
280
281 /* Dump the next node in the queue.  */
282
283 static void 
284 dequeue_and_dump (di)
285      dump_info_p di;
286 {
287   dump_queue_p dq;
288   splay_tree_node stn;
289   dump_node_info_p dni;
290   tree t;
291   unsigned int index;
292   enum tree_code code;
293   char code_class;
294   const char* code_name;
295
296   /* Get the next node from the queue.  */
297   dq = di->queue;
298   stn = dq->node;
299   t = (tree) stn->key;
300   dni = (dump_node_info_p) stn->value;
301   index = dni->index;
302
303   /* Remove the node from the queue, and put it on the free list.  */
304   di->queue = dq->next;
305   if (!di->queue)
306     di->queue_end = 0;
307   dq->next = di->free_list;
308   di->free_list = dq;
309
310   /* Print the node index.  */
311   dump_index (di, index);
312   /* And the type of node this is.  */
313   if (dni->binfo_p)
314     code_name = "binfo";
315   else
316     code_name = tree_code_name[(int) TREE_CODE (t)];
317   fprintf (di->stream, "%-16s ", code_name);
318   di->column = 25;
319
320   /* Figure out what kind of node this is.  */
321   code = TREE_CODE (t);
322   code_class = TREE_CODE_CLASS (code);
323
324   /* Although BINFOs are TREE_VECs, we dump them specially so as to be
325      more informative.  */
326   if (dni->binfo_p)
327     {
328       if (TREE_VIA_PUBLIC (t))
329         dump_string (di, "pub");
330       else if (TREE_VIA_PROTECTED (t))
331         dump_string (di, "prot");
332       else if (TREE_VIA_PRIVATE (t))
333         dump_string (di, "priv");
334       if (TREE_VIA_VIRTUAL (t))
335         dump_string (di, "virt");
336             
337       dump_child ("type", BINFO_TYPE (t));
338       dump_child ("base", BINFO_BASETYPES (t));
339
340       goto done;
341     }
342
343   /* We can knock off a bunch of expression nodes in exactly the same
344      way.  */
345   if (IS_EXPR_CODE_CLASS (code_class))
346     {
347       /* If we're dumping children, dump them now.  */
348       queue_and_dump_type (di, t);
349
350       switch (code_class)
351         {
352         case '1':
353           dump_child ("op 0", TREE_OPERAND (t, 0));
354           break;
355               
356         case '2':
357         case '<':
358           dump_child ("op 0", TREE_OPERAND (t, 0));
359           dump_child ("op 1", TREE_OPERAND (t, 1));
360           break;
361               
362         case 'e':
363           /* These nodes are handled explicitly below.  */
364           break;
365               
366         default:
367           my_friendly_abort (19990726);
368         }
369     }
370   else if (code_class == 'd')
371     {
372       /* All declarations have names.  */
373       if (DECL_NAME (t))
374         dump_child ("name", DECL_NAME (t));
375       /* And types.  */
376       queue_and_dump_type (di, t);
377       dump_child ("scpe", DECL_CONTEXT (t));
378       /* And a source position.  */
379       if (DECL_SOURCE_FILE (t))
380         {
381           const char *filename = rindex (DECL_SOURCE_FILE (t), '/');
382           if (!filename)
383             filename = DECL_SOURCE_FILE (t);
384           else
385             /* Skip the slash.  */
386             ++filename;
387
388           dump_maybe_newline (di);
389           fprintf (di->stream, "srcp: %s:%-6d ", filename, 
390                    DECL_SOURCE_LINE (t));
391           di->column += 6 + strlen (filename) + 8;
392         }
393       /* And any declaration can be compiler-generated.  */
394       if (DECL_ARTIFICIAL (t))
395         dump_string (di, "artificial");
396       if (TREE_CHAIN (t))
397         dump_child ("chan", TREE_CHAIN (t));
398     }
399   else if (code_class == 't')
400     {
401       /* All types have qualifiers.  */
402       int quals = CP_TYPE_QUALS (t);
403       if (quals != TYPE_UNQUALIFIED)
404         {
405           fprintf (di->stream, "qual: %c%c%c     ",
406                    (quals & TYPE_QUAL_CONST) ? 'c' : ' ',
407                    (quals & TYPE_QUAL_VOLATILE) ? 'v' : ' ',
408                    (quals & TYPE_QUAL_RESTRICT) ? 'r' : ' ');
409           di->column += 14;
410         }
411
412       /* All types have associated declarations.  */
413       dump_child ("name", TYPE_NAME (t));
414
415       /* All types have a main variant.  */
416       if (TYPE_MAIN_VARIANT (t) != t)
417         dump_child ("unql", TYPE_MAIN_VARIANT (t));
418       
419       /* And sizes.  */
420       dump_child ("size", TYPE_SIZE (t));
421
422       /* All types have alignments.  */
423       dump_int (di, "algn", TYPE_ALIGN (t));
424     }
425   else if (code_class == 'c')
426     /* All constants can have types.  */
427     queue_and_dump_type (di, t);
428
429   /* Now handle the various kinds of nodes.  */
430   switch (code)
431     {
432       int i;
433
434     case IDENTIFIER_NODE:
435       if (IDENTIFIER_OPNAME_P (t))
436         dump_string (di, "operator");
437       else if (IDENTIFIER_TYPENAME_P (t))
438         dump_child ("tynm", TREE_TYPE (t));
439       else if (t == anonymous_namespace_name)
440         dump_string (di, "unnamed");
441       else
442         {
443           dump_string_field (di, "strg", IDENTIFIER_POINTER (t));
444           dump_int (di, "lngt", IDENTIFIER_LENGTH (t));
445         }
446       break;
447
448     case TREE_LIST:
449       dump_child ("purp", TREE_PURPOSE (t));
450       dump_child ("valu", TREE_VALUE (t));
451       dump_child ("chan", TREE_CHAIN (t));
452       break;
453
454     case TREE_VEC:
455       dump_int (di, "lngt", IDENTIFIER_LENGTH (t));
456       for (i = 0; i < TREE_VEC_LENGTH (t); ++i)
457         {
458           char buffer[32];
459           sprintf (buffer, "%u", i);
460           dump_child (buffer, TREE_VEC_ELT (t, i));
461         }
462       break;
463
464     case INTEGER_TYPE:
465     case ENUMERAL_TYPE:
466       dump_int (di, "prec", TYPE_PRECISION (t));
467       if (TREE_UNSIGNED (t))
468         dump_string (di, "unsigned");
469       dump_child ("min", TYPE_MIN_VALUE (t));
470       dump_child ("max", TYPE_MAX_VALUE (t));
471
472       if (code == ENUMERAL_TYPE)
473         dump_child ("csts", TYPE_VALUES (t));
474       break;
475
476     case REAL_TYPE:
477       dump_int (di, "prec", TYPE_PRECISION (t));
478       break;
479
480     case POINTER_TYPE:
481       if (TYPE_PTRMEM_P (t))
482         {
483           dump_string (di, "ptrmem");
484           dump_child ("ptd", TYPE_PTRMEM_POINTED_TO_TYPE (t));
485           dump_child ("cls", TYPE_PTRMEM_CLASS_TYPE (t));
486         }
487       else
488         dump_child ("ptd", TREE_TYPE (t));
489       break;
490
491     case REFERENCE_TYPE:
492       dump_child ("refd", TREE_TYPE (t));
493       break;
494
495     case METHOD_TYPE:
496       dump_child ("clas", TYPE_METHOD_BASETYPE (t));
497       /* Fall through.  */
498
499     case FUNCTION_TYPE:
500       dump_child ("retn", TREE_TYPE (t));
501       dump_child ("prms", TYPE_ARG_TYPES (t));
502       break;
503
504     case ARRAY_TYPE:
505       dump_child ("elts", TREE_TYPE (t));
506       dump_child ("domn", TYPE_DOMAIN (t));
507       break;
508
509     case RECORD_TYPE:
510     case UNION_TYPE:
511       if (TYPE_PTRMEMFUNC_P (t))
512         {
513           dump_string (di, "ptrmem");
514           dump_child ("ptd", TYPE_PTRMEM_POINTED_TO_TYPE (t));
515           dump_child ("cls", TYPE_PTRMEM_CLASS_TYPE (t));
516         }
517       else
518         {
519           if (CLASSTYPE_DECLARED_CLASS (t))
520             dump_string (di, "class");
521           else if (TREE_CODE (t) == RECORD_TYPE)
522             dump_string (di, "struct");
523           else
524             dump_string (di, "union");
525
526           dump_child ("flds", TYPE_FIELDS (t));
527           dump_child ("fncs", TYPE_METHODS (t));
528           dump_child ("vfld", TYPE_VFIELD (t));
529           queue_and_dump_index (di, "binf", TYPE_BINFO (t), 
530                                 DUMP_BINFO);
531         }
532       break;
533
534     case CONST_DECL:
535       dump_child ("cnst", DECL_INITIAL (t));
536       break;
537
538     case VAR_DECL:
539     case PARM_DECL:
540     case FIELD_DECL:
541     case RESULT_DECL:
542       if (TREE_CODE (t) == PARM_DECL)
543         dump_child ("argt", DECL_ARG_TYPE (t));
544       else
545         dump_child ("init", DECL_INITIAL (t));
546       dump_child ("size", DECL_SIZE (t));
547       dump_int (di, "algn", DECL_ALIGN (t));
548
549       if (TREE_CODE (t) == FIELD_DECL)
550         {
551           if (DECL_C_BIT_FIELD (t))
552             dump_string (di, "bitfield");
553           dump_child ("bpos", DECL_FIELD_BITPOS (t));
554         }
555       break;
556
557     case FUNCTION_DECL:
558     case THUNK_DECL:
559       dump_child ("scpe", DECL_REAL_CONTEXT (t));
560       dump_child ("mngl", DECL_ASSEMBLER_NAME (t));
561       dump_child ("args", DECL_ARGUMENTS (t));
562       if (DECL_EXTERNAL (t))
563         dump_string (di, "undefined");
564       if (TREE_PUBLIC (t))
565         dump_string(di, "extern");
566       else
567         dump_string (di, "static");
568       if (TREE_CODE (t) == FUNCTION_DECL)
569         {
570           if (DECL_FUNCTION_MEMBER_P (t))
571             dump_string (di, "member");
572           if (DECL_CONSTRUCTOR_P (t))
573             dump_string (di, "constructor");
574           if (DECL_DESTRUCTOR_P (t))
575             dump_string (di, "destructor");
576           if (DECL_OVERLOADED_OPERATOR_P (t))
577             dump_string (di, "operator");
578           if (DECL_CONV_FN_P (t))
579             dump_string (di, "conversion");
580           if (DECL_GLOBAL_CTOR_P (t) || DECL_GLOBAL_DTOR_P (t))
581             {
582               if (DECL_GLOBAL_CTOR_P (t))
583                 dump_string (di, "global init");
584               if (DECL_GLOBAL_DTOR_P (t))
585                 dump_string (di, "global fini");
586               dump_int (di, "prio", GLOBAL_INIT_PRIORITY (t));
587             }
588           if (DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION (t))
589             dump_string (di, "pseudo tmpl");
590
591           dump_child ("body", DECL_SAVED_TREE (t));
592         }
593       else
594         {
595           dump_int (di, "dlta", THUNK_DELTA (t));
596           dump_child ("init", DECL_INITIAL (t));
597         }
598       break;
599
600     case NAMESPACE_DECL:
601       /* The fake `::std' namespace does not have DECL_LANG_SPECIFIC,
602          and therefore many other macros do not work on it.  */
603       if (t == std_node)
604         break;
605       if (DECL_NAMESPACE_ALIAS (t))
606         dump_child ("alis", DECL_NAMESPACE_ALIAS (t));
607       else
608         dump_child ("dcls", cp_namespace_decls (t));
609       break;
610
611     case TEMPLATE_DECL:
612       dump_child ("spcs", DECL_TEMPLATE_SPECIALIZATIONS (t));
613       break;
614
615     case OVERLOAD:
616       dump_child ("crnt", OVL_CURRENT (t));
617       dump_child ("chan", OVL_CHAIN (t));
618       break;
619
620     case ASM_STMT:
621       dump_stmt (di, t);
622       if (ASM_VOLATILE_P (t))
623         dump_string (di, "volatile");
624       dump_child ("strg", ASM_STRING (t));
625       dump_child ("outs", ASM_OUTPUTS (t));
626       dump_child ("ins", ASM_INPUTS (t));
627       dump_child ("clbr", ASM_CLOBBERS (t));
628       dump_next_stmt (di, t);
629       break;
630
631     case BREAK_STMT:
632     case CONTINUE_STMT:
633       dump_stmt (di, t);
634       dump_next_stmt (di, t);
635       break;
636
637     case CASE_LABEL:
638       /* Note that a case label is not like other statments; there is
639          no way to get the line-number of a case label.  */
640       dump_child ("low", CASE_LOW (t));
641       dump_child ("high", CASE_HIGH (t));
642       dump_next_stmt (di, t);
643       break;
644
645     case COMPOUND_STMT:
646       dump_stmt (di, t);
647       dump_child ("body", COMPOUND_BODY (t));
648       dump_next_stmt (di, t);
649       break;
650
651     case CTOR_STMT:
652       dump_stmt (di, t);
653       if (CTOR_BEGIN_P (t))
654         dump_string (di, "begn");
655       else
656         dump_string (di, "end");
657       dump_next_stmt (di, t);
658       break;
659
660     case DECL_STMT:
661       dump_stmt (di, t);
662       dump_child ("decl", DECL_STMT_DECL (t));
663       dump_next_stmt (di, t);
664       break;
665       
666     case DO_STMT:
667       dump_stmt (di, t);
668       dump_child ("body", DO_BODY (t));
669       dump_child ("cond", DO_COND (t));
670       dump_next_stmt (di, t);
671       break;
672
673     case EXPR_STMT:
674       dump_stmt (di, t);
675       dump_child ("expr", EXPR_STMT_EXPR (t));
676       dump_next_stmt (di, t);
677       break;
678
679     case FOR_STMT:
680       dump_stmt (di, t);
681       dump_child ("init", FOR_INIT_STMT (t));
682       dump_child ("cond", FOR_COND (t));
683       dump_child ("expr", FOR_EXPR (t));
684       dump_child ("body", FOR_BODY (t));
685       dump_next_stmt (di, t);
686       break;
687
688     case GOTO_STMT:
689       dump_stmt (di, t);
690       dump_child ("dest", GOTO_DESTINATION (t));
691       dump_next_stmt (di, t);
692       break;
693
694     case HANDLER:
695       dump_stmt (di, t);
696       dump_child ("body", HANDLER_BODY (t));
697       dump_next_stmt (di, t);
698       break;
699
700     case IF_STMT:
701       dump_stmt (di, t);
702       dump_child ("cond", IF_COND (t));
703       dump_child ("then", THEN_CLAUSE (t));
704       dump_child ("else", ELSE_CLAUSE (t));
705       dump_next_stmt (di, t);
706       break;
707
708     case LABEL_STMT:
709       dump_stmt (di, t);
710       dump_child ("labl", LABEL_STMT_LABEL (t));
711       dump_next_stmt (di, t);
712       break;
713
714     case RETURN_STMT:
715       dump_stmt (di, t);
716       dump_child ("expr", RETURN_EXPR (t));
717       dump_next_stmt (di, t);
718       break;
719
720     case SWITCH_STMT:
721       dump_stmt (di, t);
722       dump_child ("cond", SWITCH_COND (t));
723       dump_child ("body", SWITCH_BODY (t));
724       dump_next_stmt (di, t);
725       break;
726
727     case TRY_BLOCK:
728       dump_stmt (di, t);
729       if (CLEANUP_P (t))
730         dump_string (di, "cleanup");
731       dump_child ("body", TRY_STMTS (t));
732       dump_child ("hdlr", TRY_HANDLERS (t));
733       dump_next_stmt (di, t);
734       break;
735
736     case WHILE_STMT:
737       dump_stmt (di, t);
738       dump_child ("cond", WHILE_COND (t));
739       dump_child ("body", WHILE_BODY (t));
740       dump_next_stmt (di, t);
741       break;
742
743     case SUBOBJECT:
744       dump_stmt (di, t);
745       dump_child ("clnp", TREE_OPERAND (t, 0));
746       dump_next_stmt (di, t);
747       break;
748
749     case START_CATCH_STMT:
750       dump_stmt (di, t);
751       queue_and_dump_type (di, t);
752       dump_next_stmt (di, t);
753       break;
754
755     case CLEANUP_STMT:
756       dump_stmt (di, t);
757       dump_child ("decl", CLEANUP_DECL (t));
758       dump_child ("expr", CLEANUP_EXPR (t));
759       dump_next_stmt (di, t);
760       break;
761
762     case SCOPE_STMT:
763       dump_stmt (di, t);
764       if (SCOPE_BEGIN_P (t))
765         dump_string (di, "begn");
766       else
767         dump_string (di, "end");
768       if (SCOPE_NULLIFIED_P (t))
769         dump_string (di, "null");
770       dump_next_stmt (di, t);
771       break;
772
773     case INTEGER_CST:
774       if (TREE_INT_CST_HIGH (t))
775         dump_int (di, "high", TREE_INT_CST_HIGH (t));
776       dump_int (di, "low", TREE_INT_CST_LOW (t));
777       break;
778
779     case STRING_CST:
780       fprintf (di->stream, "strg: %-7s ", TREE_STRING_POINTER (t));
781       dump_int (di, "lngt", TREE_STRING_LENGTH (t));
782       break;
783
784     case PTRMEM_CST:
785       dump_child ("clas", PTRMEM_CST_CLASS (t));
786       dump_child ("mbr", PTRMEM_CST_MEMBER (t));
787       break;
788
789     case TRUTH_NOT_EXPR:
790     case ADDR_EXPR:
791     case INDIRECT_REF:
792     case THROW_EXPR:
793     case CLEANUP_POINT_EXPR:
794     case SAVE_EXPR:
795       /* These nodes are unary, but do not have code class `1'.  */
796       dump_child ("op 0", TREE_OPERAND (t, 0));
797       break;
798
799     case TRUTH_ANDIF_EXPR:
800     case TRUTH_ORIF_EXPR:
801     case INIT_EXPR:
802     case MODIFY_EXPR:
803     case COMPONENT_REF:
804     case COMPOUND_EXPR:
805     case ARRAY_REF:
806       /* These nodes are binary, but do not have code class `2'.  */
807       dump_child ("op 0", TREE_OPERAND (t, 0));
808       dump_child ("op 1", TREE_OPERAND (t, 1));
809       break;
810
811     case COND_EXPR:
812       dump_child ("op 0", TREE_OPERAND (t, 0));
813       dump_child ("op 1", TREE_OPERAND (t, 1));
814       dump_child ("op 2", TREE_OPERAND (t, 2));
815       break;
816
817     case CALL_EXPR:
818       dump_child ("fn", TREE_OPERAND (t, 0));
819       dump_child ("args", TREE_OPERAND (t, 1));
820       break;
821
822     case CONSTRUCTOR:
823       dump_child ("elts", TREE_OPERAND (t, 1));
824       break;
825
826     case STMT_EXPR:
827       dump_child ("stmt", STMT_EXPR_STMT (t));
828       break;
829
830     case BIND_EXPR:
831       dump_child ("vars", TREE_OPERAND (t, 0));
832       dump_child ("body", TREE_OPERAND (t, 1));
833       break;
834
835     case LOOP_EXPR:
836       dump_child ("body", TREE_OPERAND (t, 0));
837       break;
838
839     case EXIT_EXPR:
840       dump_child ("cond", TREE_OPERAND (t, 0));
841       break;
842
843     case TARGET_EXPR:
844       dump_child ("decl", TREE_OPERAND (t, 0));
845       dump_child ("init", TREE_OPERAND (t, 1));
846       dump_child ("clnp", TREE_OPERAND (t, 2));
847       /* There really are two possible places the initializer can be.
848          After RTL expansion, the second operand is moved to the
849          position of the fourth operand, and the second operand
850          becomes NULL.  */
851       dump_child ("init", TREE_OPERAND (t, 3));
852       break;
853       
854     case AGGR_INIT_EXPR:
855       dump_int (di, "ctor", AGGR_INIT_VIA_CTOR_P (t));
856       dump_child ("fn", TREE_OPERAND (t, 0));
857       dump_child ("args", TREE_OPERAND (t, 1));
858       dump_child ("decl", TREE_OPERAND (t, 2));
859       break;
860
861     default:
862       /* There are no additional fields to print.  */
863       break;
864     }
865
866  done:
867   /* Terminate the line.  */
868   fprintf (di->stream, "\n");
869 }
870
871 /* Dump T, and all its children, on STREAM.  */
872
873 static void
874 dump_node (t, stream)
875      tree t;
876      FILE *stream;
877 {
878   struct dump_info di;
879   dump_queue_p dq;
880   dump_queue_p next_dq;
881
882   /* Initialize the dump-information structure.  */
883   di.stream = stream;
884   di.index = 0;
885   di.column = 0;
886   di.queue = 0;
887   di.queue_end = 0;
888   di.free_list = 0;
889   di.nodes = splay_tree_new (splay_tree_compare_pointers, 0, 
890                              (splay_tree_delete_value_fn) &free);
891
892   /* Queue up the first node.  */
893   queue (&di, t, DUMP_NONE);
894
895   /* Until the queue is empty, keep dumping nodes.  */
896   while (di.queue)
897     dequeue_and_dump (&di);
898
899   /* Now, clean up.  */
900   for (dq = di.free_list; dq; dq = next_dq)
901     {
902       next_dq = dq->next;
903       free (dq);
904     }
905   splay_tree_delete (di.nodes);
906 }
907
908 /* Dump T, and all its children, to FILE.  */
909
910 void
911 dump_node_to_file (t, file)
912      tree t;
913      const char *file;
914 {
915   FILE *f;
916
917   f = fopen (file, "w");
918   if (!f)
919     cp_error ("could not open `%s'", file);
920   else
921     {
922       dump_node (t, f);
923       fclose (f);
924     }
925 }