OSDN Git Service

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