OSDN Git Service

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