OSDN Git Service

* decl.c (grokdeclarator): Count partial specializations when
[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", bit_position (t));
554         }
555       break;
556
557     case FUNCTION_DECL:
558     case THUNK_DECL:
559       dump_child ("scpe", CP_DECL_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 ("rslt", DECL_TEMPLATE_RESULT (t));
613       dump_child ("inst", DECL_TEMPLATE_INSTANTIATIONS (t));
614       dump_child ("spcs", DECL_TEMPLATE_SPECIALIZATIONS (t));
615       break;
616
617     case OVERLOAD:
618       dump_child ("crnt", OVL_CURRENT (t));
619       dump_child ("chan", OVL_CHAIN (t));
620       break;
621
622     case ASM_STMT:
623       dump_stmt (di, t);
624       if (ASM_VOLATILE_P (t))
625         dump_string (di, "volatile");
626       dump_child ("strg", ASM_STRING (t));
627       dump_child ("outs", ASM_OUTPUTS (t));
628       dump_child ("ins", ASM_INPUTS (t));
629       dump_child ("clbr", ASM_CLOBBERS (t));
630       dump_next_stmt (di, t);
631       break;
632
633     case BREAK_STMT:
634     case CONTINUE_STMT:
635       dump_stmt (di, t);
636       dump_next_stmt (di, t);
637       break;
638
639     case CASE_LABEL:
640       /* Note that a case label is not like other statments; there is
641          no way to get the line-number of a case label.  */
642       dump_child ("low", CASE_LOW (t));
643       dump_child ("high", CASE_HIGH (t));
644       dump_next_stmt (di, t);
645       break;
646
647     case COMPOUND_STMT:
648       dump_stmt (di, t);
649       dump_child ("body", COMPOUND_BODY (t));
650       dump_next_stmt (di, t);
651       break;
652
653     case CTOR_STMT:
654       dump_stmt (di, t);
655       if (CTOR_BEGIN_P (t))
656         dump_string (di, "begn");
657       else
658         dump_string (di, "end");
659       dump_next_stmt (di, t);
660       break;
661
662     case DECL_STMT:
663       dump_stmt (di, t);
664       dump_child ("decl", DECL_STMT_DECL (t));
665       dump_next_stmt (di, t);
666       break;
667       
668     case DO_STMT:
669       dump_stmt (di, t);
670       dump_child ("body", DO_BODY (t));
671       dump_child ("cond", DO_COND (t));
672       dump_next_stmt (di, t);
673       break;
674
675     case EXPR_STMT:
676       dump_stmt (di, t);
677       dump_child ("expr", EXPR_STMT_EXPR (t));
678       dump_next_stmt (di, t);
679       break;
680
681     case FOR_STMT:
682       dump_stmt (di, t);
683       dump_child ("init", FOR_INIT_STMT (t));
684       dump_child ("cond", FOR_COND (t));
685       dump_child ("expr", FOR_EXPR (t));
686       dump_child ("body", FOR_BODY (t));
687       dump_next_stmt (di, t);
688       break;
689
690     case GOTO_STMT:
691       dump_stmt (di, t);
692       dump_child ("dest", GOTO_DESTINATION (t));
693       dump_next_stmt (di, t);
694       break;
695
696     case HANDLER:
697       dump_stmt (di, t);
698       dump_child ("body", HANDLER_BODY (t));
699       dump_next_stmt (di, t);
700       break;
701
702     case IF_STMT:
703       dump_stmt (di, t);
704       dump_child ("cond", IF_COND (t));
705       dump_child ("then", THEN_CLAUSE (t));
706       dump_child ("else", ELSE_CLAUSE (t));
707       dump_next_stmt (di, t);
708       break;
709
710     case LABEL_STMT:
711       dump_stmt (di, t);
712       dump_child ("labl", LABEL_STMT_LABEL (t));
713       dump_next_stmt (di, t);
714       break;
715
716     case RETURN_STMT:
717       dump_stmt (di, t);
718       dump_child ("expr", RETURN_EXPR (t));
719       dump_next_stmt (di, t);
720       break;
721
722     case SWITCH_STMT:
723       dump_stmt (di, t);
724       dump_child ("cond", SWITCH_COND (t));
725       dump_child ("body", SWITCH_BODY (t));
726       dump_next_stmt (di, t);
727       break;
728
729     case TRY_BLOCK:
730       dump_stmt (di, t);
731       if (CLEANUP_P (t))
732         dump_string (di, "cleanup");
733       dump_child ("body", TRY_STMTS (t));
734       dump_child ("hdlr", TRY_HANDLERS (t));
735       dump_next_stmt (di, t);
736       break;
737
738     case WHILE_STMT:
739       dump_stmt (di, t);
740       dump_child ("cond", WHILE_COND (t));
741       dump_child ("body", WHILE_BODY (t));
742       dump_next_stmt (di, t);
743       break;
744
745     case SUBOBJECT:
746       dump_stmt (di, t);
747       dump_child ("clnp", TREE_OPERAND (t, 0));
748       dump_next_stmt (di, t);
749       break;
750
751     case START_CATCH_STMT:
752       dump_stmt (di, t);
753       queue_and_dump_type (di, t);
754       dump_next_stmt (di, t);
755       break;
756
757     case CLEANUP_STMT:
758       dump_stmt (di, t);
759       dump_child ("decl", CLEANUP_DECL (t));
760       dump_child ("expr", CLEANUP_EXPR (t));
761       dump_next_stmt (di, t);
762       break;
763
764     case SCOPE_STMT:
765       dump_stmt (di, t);
766       if (SCOPE_BEGIN_P (t))
767         dump_string (di, "begn");
768       else
769         dump_string (di, "end");
770       if (SCOPE_NULLIFIED_P (t))
771         dump_string (di, "null");
772       if (!SCOPE_NO_CLEANUPS_P (t))
773         dump_string (di, "clnp");
774       dump_next_stmt (di, t);
775       break;
776
777     case INTEGER_CST:
778       if (TREE_INT_CST_HIGH (t))
779         dump_int (di, "high", TREE_INT_CST_HIGH (t));
780       dump_int (di, "low", TREE_INT_CST_LOW (t));
781       break;
782
783     case STRING_CST:
784       fprintf (di->stream, "strg: %-7s ", TREE_STRING_POINTER (t));
785       dump_int (di, "lngt", TREE_STRING_LENGTH (t));
786       break;
787
788     case PTRMEM_CST:
789       dump_child ("clas", PTRMEM_CST_CLASS (t));
790       dump_child ("mbr", PTRMEM_CST_MEMBER (t));
791       break;
792
793     case TRUTH_NOT_EXPR:
794     case ADDR_EXPR:
795     case INDIRECT_REF:
796     case THROW_EXPR:
797     case CLEANUP_POINT_EXPR:
798     case SAVE_EXPR:
799       /* These nodes are unary, but do not have code class `1'.  */
800       dump_child ("op 0", TREE_OPERAND (t, 0));
801       break;
802
803     case TRUTH_ANDIF_EXPR:
804     case TRUTH_ORIF_EXPR:
805     case INIT_EXPR:
806     case MODIFY_EXPR:
807     case COMPONENT_REF:
808     case COMPOUND_EXPR:
809     case ARRAY_REF:
810     case PREDECREMENT_EXPR:
811     case PREINCREMENT_EXPR:
812     case POSTDECREMENT_EXPR:
813     case POSTINCREMENT_EXPR:
814       /* These nodes are binary, but do not have code class `2'.  */
815       dump_child ("op 0", TREE_OPERAND (t, 0));
816       dump_child ("op 1", TREE_OPERAND (t, 1));
817       break;
818
819     case COND_EXPR:
820       dump_child ("op 0", TREE_OPERAND (t, 0));
821       dump_child ("op 1", TREE_OPERAND (t, 1));
822       dump_child ("op 2", TREE_OPERAND (t, 2));
823       break;
824
825     case CALL_EXPR:
826       dump_child ("fn", TREE_OPERAND (t, 0));
827       dump_child ("args", TREE_OPERAND (t, 1));
828       break;
829
830     case CONSTRUCTOR:
831       dump_child ("elts", TREE_OPERAND (t, 1));
832       break;
833
834     case STMT_EXPR:
835       dump_child ("stmt", STMT_EXPR_STMT (t));
836       break;
837
838     case BIND_EXPR:
839       dump_child ("vars", TREE_OPERAND (t, 0));
840       dump_child ("body", TREE_OPERAND (t, 1));
841       break;
842
843     case LOOP_EXPR:
844       dump_child ("body", TREE_OPERAND (t, 0));
845       break;
846
847     case EXIT_EXPR:
848       dump_child ("cond", TREE_OPERAND (t, 0));
849       break;
850
851     case TARGET_EXPR:
852       dump_child ("decl", TREE_OPERAND (t, 0));
853       dump_child ("init", TREE_OPERAND (t, 1));
854       dump_child ("clnp", TREE_OPERAND (t, 2));
855       /* There really are two possible places the initializer can be.
856          After RTL expansion, the second operand is moved to the
857          position of the fourth operand, and the second operand
858          becomes NULL.  */
859       dump_child ("init", TREE_OPERAND (t, 3));
860       break;
861       
862     case AGGR_INIT_EXPR:
863       dump_int (di, "ctor", AGGR_INIT_VIA_CTOR_P (t));
864       dump_child ("fn", TREE_OPERAND (t, 0));
865       dump_child ("args", TREE_OPERAND (t, 1));
866       dump_child ("decl", TREE_OPERAND (t, 2));
867       break;
868       
869     case EXPR_WITH_FILE_LOCATION:
870       dump_child ("expr", EXPR_WFL_NODE (t));
871       break;
872
873     default:
874       /* There are no additional fields to print.  */
875       break;
876     }
877
878  done:
879   /* Terminate the line.  */
880   fprintf (di->stream, "\n");
881 }
882
883 /* Dump T, and all its children, on STREAM.  */
884
885 static void
886 dump_node (t, stream)
887      tree t;
888      FILE *stream;
889 {
890   struct dump_info di;
891   dump_queue_p dq;
892   dump_queue_p next_dq;
893
894   /* Initialize the dump-information structure.  */
895   di.stream = stream;
896   di.index = 0;
897   di.column = 0;
898   di.queue = 0;
899   di.queue_end = 0;
900   di.free_list = 0;
901   di.nodes = splay_tree_new (splay_tree_compare_pointers, 0, 
902                              (splay_tree_delete_value_fn) &free);
903
904   /* Queue up the first node.  */
905   queue (&di, t, DUMP_NONE);
906
907   /* Until the queue is empty, keep dumping nodes.  */
908   while (di.queue)
909     dequeue_and_dump (&di);
910
911   /* Now, clean up.  */
912   for (dq = di.free_list; dq; dq = next_dq)
913     {
914       next_dq = dq->next;
915       free (dq);
916     }
917   splay_tree_delete (di.nodes);
918 }
919
920 /* Dump T, and all its children, to FILE.  */
921
922 void
923 dump_node_to_file (t, file)
924      tree t;
925      const char *file;
926 {
927   FILE *f;
928
929   f = fopen (file, "w");
930   if (!f)
931     cp_error ("could not open `%s'", file);
932   else
933     {
934       dump_node (t, f);
935       fclose (f);
936     }
937 }