OSDN Git Service

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