* cp-tree.def (SCOPE_STMT): Take one operand.
[official-gcc.git] / gcc / cp / dump.c
blob6e3fbcceab70e366a791a766cd4d89e6a360dbf4
1 /* Tree-dumping functionality for intermediate representation.
2 Copyright (C) 1999 Free Software Foundation, Inc.
3 Written by Mark Mitchell <mark@codesourcery.com>
5 This file is part of GNU CC.
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.
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.
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. */
22 #include "config.h"
23 #include "system.h"
24 #include "tree.h"
25 #include "cp-tree.h"
27 /* Flags used with queue functions. */
28 #define DUMP_NONE 0
29 #define DUMP_BINFO 1
31 /* Information about a node to be dumped. */
33 typedef struct dump_node_info
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;
41 /* A dump_queue is a link in the queue of things to be dumped. */
43 typedef struct dump_queue
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;
51 /* A dump_info gives information about how we should perform the dump
52 and about the current state of the dump. */
54 typedef struct dump_info
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;
74 static unsigned int queue PROTO ((dump_info_p, tree, int));
75 static void dump_index PROTO ((dump_info_p, unsigned int));
76 static void queue_and_dump_index PROTO ((dump_info_p, const char *, tree, int));
77 static void queue_and_dump_type PROTO ((dump_info_p, tree));
78 static void dequeue_and_dump PROTO ((dump_info_p));
79 static void dump_new_line PROTO ((dump_info_p));
80 static void dump_maybe_newline PROTO ((dump_info_p));
81 static void dump_int PROTO ((dump_info_p, const char *, int));
82 static void dump_string PROTO ((dump_info_p, const char *));
83 static void dump_string_field PROTO ((dump_info_p, const char *, const char *));
84 static void dump_node PROTO ((tree, FILE *));
85 static void dump_stmt PROTO ((dump_info_p, tree));
86 static void dump_next_stmt PROTO ((dump_info_p, tree));
88 /* Add T to the end of the queue of nodes to dump. Returns the index
89 assigned to T. */
91 static unsigned int
92 queue (di, t, flags)
93 dump_info_p di;
94 tree t;
95 int flags;
97 dump_queue_p dq;
98 dump_node_info_p dni;
99 unsigned int index;
101 /* Assign the next available index to T. */
102 index = ++di->index;
104 /* Obtain a new queue node. */
105 if (di->free_list)
107 dq = di->free_list;
108 di->free_list = dq->next;
110 else
111 dq = (dump_queue_p) xmalloc (sizeof (struct dump_queue));
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);
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;
128 /* Return the index. */
129 return index;
132 static void
133 dump_index (di, index)
134 dump_info_p di;
135 unsigned int index;
137 fprintf (di->stream, "@%-6u ", index);
138 di->column += 8;
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. */
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;
152 unsigned int index;
153 splay_tree_node n;
155 /* If there's no node, just return. This makes for fewer checks in
156 our callers. */
157 if (!t)
158 return;
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);
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);
175 /* Dump the type of T. */
177 static void
178 queue_and_dump_type (di, t)
179 dump_info_p di;
180 tree t;
182 queue_and_dump_index (di, "type", TREE_TYPE (t), DUMP_NONE);
185 /* Insert a new line in the dump output, and indent to an appropriate
186 place to start printing more fields. */
188 static void
189 dump_new_line (di)
190 dump_info_p di;
192 fprintf (di->stream, "\n%25s", "");
193 di->column = 25;
196 /* If necessary, insert a new line. */
198 static void
199 dump_maybe_newline (di)
200 dump_info_p di;
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)
208 fprintf (di->stream, "%*s", 14 - ((di->column - 25) % 14), "");
209 di->column += 14 - (di->column - 25) % 14;
213 /* Dump I using FIELD to identity it. */
215 static void
216 dump_int (di, field, i)
217 dump_info_p di;
218 const char *field;
219 int i;
221 dump_maybe_newline (di);
222 fprintf (di->stream, "%-4s: %-7d ", field, i);
223 di->column += 14;
226 /* Dump the string S. */
228 static void
229 dump_string (di, string)
230 dump_info_p di;
231 const char *string;
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;
241 /* Dump the string field S. */
243 static void
244 dump_string_field (di, field, string)
245 dump_info_p di;
246 const char *field;
247 const char *string;
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;
257 /* Dump information common to statements from STMT. */
259 static void
260 dump_stmt (di, t)
261 dump_info_p di;
262 tree t;
264 dump_int (di, "line", STMT_LINENO (t));
267 /* Dump the CHILD and its children. */
268 #define dump_child(field, child) \
269 queue_and_dump_index (di, field, child, DUMP_NONE)
271 /* Dump the next statement after STMT. */
273 static void
274 dump_next_stmt (di, t)
275 dump_info_p di;
276 tree t;
278 dump_child ("next", TREE_CHAIN (t));
281 /* Dump the next node in the queue. */
283 static void
284 dequeue_and_dump (di)
285 dump_info_p di;
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;
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;
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;
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;
320 /* Figure out what kind of node this is. */
321 code = TREE_CODE (t);
322 code_class = TREE_CODE_CLASS (code);
324 /* Although BINFOs are TREE_VECs, we dump them specially so as to be
325 more informative. */
326 if (dni->binfo_p)
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");
337 dump_child ("type", BINFO_TYPE (t));
338 dump_child ("base", BINFO_BASETYPES (t));
340 goto done;
343 /* We can knock off a bunch of expression nodes in exactly the same
344 way. */
345 if (IS_EXPR_CODE_CLASS (code_class))
347 /* If we're dumping children, dump them now. */
348 queue_and_dump_type (di, t);
350 switch (code_class)
352 case '1':
353 dump_child ("op 0", TREE_OPERAND (t, 0));
354 break;
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;
362 case 'e':
363 /* These nodes are handled explicitly below. */
364 break;
366 default:
367 my_friendly_abort (19990726);
370 else if (code_class == 'd')
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))
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;
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;
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));
399 else if (code_class == 't')
401 /* All types have qualifiers. */
402 int quals = CP_TYPE_QUALS (t);
403 if (quals != TYPE_UNQUALIFIED)
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;
412 /* All types have associated declarations. */
413 dump_child ("name", TYPE_NAME (t));
415 /* All types have a main variant. */
416 if (TYPE_MAIN_VARIANT (t) != t)
417 dump_child ("unql", TYPE_MAIN_VARIANT (t));
419 /* And sizes. */
420 dump_child ("size", TYPE_SIZE (t));
422 /* All types have alignments. */
423 dump_int (di, "algn", TYPE_ALIGN (t));
425 else if (code_class == 'c')
426 /* All constants can have types. */
427 queue_and_dump_type (di, t);
429 /* Now handle the various kinds of nodes. */
430 switch (code)
432 int i;
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
443 dump_string_field (di, "strg", IDENTIFIER_POINTER (t));
444 dump_int (di, "lngt", IDENTIFIER_LENGTH (t));
446 break;
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;
454 case TREE_VEC:
455 dump_int (di, "lngt", IDENTIFIER_LENGTH (t));
456 for (i = 0; i < TREE_VEC_LENGTH (t); ++i)
458 char buffer[32];
459 sprintf (buffer, "%u", i);
460 dump_child (buffer, TREE_VEC_ELT (t, i));
462 break;
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));
472 if (code == ENUMERAL_TYPE)
473 dump_child ("csts", TYPE_VALUES (t));
474 break;
476 case REAL_TYPE:
477 dump_int (di, "prec", TYPE_PRECISION (t));
478 break;
480 case POINTER_TYPE:
481 if (TYPE_PTRMEM_P (t))
483 dump_string (di, "ptrmem");
484 dump_child ("ptd", TYPE_PTRMEM_POINTED_TO_TYPE (t));
485 dump_child ("csl", TYPE_PTRMEM_CLASS_TYPE (t));
487 else
488 dump_child ("ptd", TREE_TYPE (t));
489 break;
491 case REFERENCE_TYPE:
492 dump_child ("refd", TREE_TYPE (t));
493 break;
495 case METHOD_TYPE:
496 dump_child ("clas", TYPE_METHOD_BASETYPE (t));
497 /* Fall through. */
499 case FUNCTION_TYPE:
500 dump_child ("retn", TREE_TYPE (t));
501 dump_child ("prms", TYPE_ARG_TYPES (t));
502 break;
504 case ARRAY_TYPE:
505 dump_child ("elts", TREE_TYPE (t));
506 dump_child ("domn", TYPE_DOMAIN (t));
507 break;
509 case RECORD_TYPE:
510 case UNION_TYPE:
511 if (TYPE_PTRMEMFUNC_P (t))
513 dump_string (di, "ptrmem");
514 dump_child ("ptd", TYPE_PTRMEM_POINTED_TO_TYPE (t));
515 dump_child ("cls", TYPE_PTRMEM_CLASS_TYPE (t));
517 else
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");
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);
532 break;
534 case CONST_DECL:
535 dump_child ("cnst", DECL_INITIAL (t));
536 break;
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));
549 if (TREE_CODE (t) == FIELD_DECL)
551 if (DECL_C_BIT_FIELD (t))
552 dump_string (di, "bitfield");
553 dump_child ("bpos", DECL_FIELD_BITPOS (t));
555 break;
557 case FUNCTION_DECL:
558 case THUNK_DECL:
559 dump_child ("scpe", DECL_REAL_CONTEXT (t));
560 dump_child ("mngl", DECL_ASSEMBLER_NAME (t));
561 dump_child ("args", DECL_ARGUMENTS (t));
562 if (DECL_EXTERNAL (t))
563 dump_string (di, "undefined");
564 if (TREE_PUBLIC (t))
565 dump_string(di, "extern");
566 else
567 dump_string (di, "static");
568 if (TREE_CODE (t) == FUNCTION_DECL)
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))
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));
589 dump_child ("body", DECL_SAVED_TREE (t));
591 else
593 dump_int (di, "dlta", THUNK_DELTA (t));
594 dump_child ("init", DECL_INITIAL (t));
596 break;
598 case NAMESPACE_DECL:
599 /* The fake `::std' namespace does not have DECL_LANG_SPECIFIC,
600 and therefore many other macros do not work on it. */
601 if (t == std_node)
602 break;
603 dump_child ("dcls", cp_namespace_decls (t));
604 break;
606 case TEMPLATE_DECL:
607 dump_child ("spcs", DECL_TEMPLATE_SPECIALIZATIONS (t));
608 break;
610 case OVERLOAD:
611 dump_child ("crnt", OVL_CURRENT (t));
612 dump_child ("chan", OVL_CHAIN (t));
613 break;
615 case ASM_STMT:
616 dump_stmt (di, t);
617 if (ASM_VOLATILE_P (t))
618 dump_string (di, "volatile");
619 dump_child ("strg", ASM_STRING (t));
620 dump_child ("outs", ASM_OUTPUTS (t));
621 dump_child ("ins", ASM_INPUTS (t));
622 dump_child ("clbr", ASM_CLOBBERS (t));
623 dump_next_stmt (di, t);
624 break;
626 case BREAK_STMT:
627 case CONTINUE_STMT:
628 dump_stmt (di, t);
629 dump_next_stmt (di, t);
630 break;
632 case CASE_LABEL:
633 /* Note that a case label is not like other statments; there is
634 no way to get the line-number of a case label. */
635 dump_child ("low", CASE_LOW (t));
636 dump_child ("high", CASE_HIGH (t));
637 dump_next_stmt (di, t);
638 break;
640 case COMPOUND_STMT:
641 dump_stmt (di, t);
642 dump_child ("body", COMPOUND_BODY (t));
643 dump_next_stmt (di, t);
644 break;
646 case DECL_STMT:
647 dump_stmt (di, t);
648 dump_child ("decl", DECL_STMT_DECL (t));
649 dump_next_stmt (di, t);
650 break;
652 case DO_STMT:
653 dump_stmt (di, t);
654 dump_child ("body", DO_BODY (t));
655 dump_child ("cond", DO_COND (t));
656 dump_next_stmt (di, t);
657 break;
659 case EXPR_STMT:
660 dump_stmt (di, t);
661 dump_child ("expr", EXPR_STMT_EXPR (t));
662 dump_next_stmt (di, t);
663 break;
665 case FOR_STMT:
666 dump_stmt (di, t);
667 dump_child ("init", FOR_INIT_STMT (t));
668 dump_child ("cond", FOR_COND (t));
669 dump_child ("expr", FOR_EXPR (t));
670 dump_child ("body", FOR_BODY (t));
671 dump_next_stmt (di, t);
672 break;
674 case GOTO_STMT:
675 dump_stmt (di, t);
676 dump_child ("dest", GOTO_DESTINATION (t));
677 dump_next_stmt (di, t);
678 break;
680 case HANDLER:
681 dump_stmt (di, t);
682 dump_child ("body", HANDLER_BODY (t));
683 dump_next_stmt (di, t);
684 break;
686 case IF_STMT:
687 dump_stmt (di, t);
688 dump_child ("cond", IF_COND (t));
689 dump_child ("then", THEN_CLAUSE (t));
690 dump_child ("else", ELSE_CLAUSE (t));
691 dump_next_stmt (di, t);
692 break;
694 case LABEL_STMT:
695 dump_stmt (di, t);
696 dump_child ("labl", LABEL_STMT_LABEL (t));
697 dump_next_stmt (di, t);
698 break;
700 case RETURN_STMT:
701 dump_stmt (di, t);
702 dump_child ("expr", RETURN_EXPR (t));
703 dump_next_stmt (di, t);
704 break;
706 case SWITCH_STMT:
707 dump_stmt (di, t);
708 dump_child ("cond", SWITCH_COND (t));
709 dump_child ("body", SWITCH_BODY (t));
710 dump_next_stmt (di, t);
711 break;
713 case TRY_BLOCK:
714 dump_stmt (di, t);
715 if (CLEANUP_P (t))
716 dump_string (di, "cleanup");
717 dump_child ("body", TRY_STMTS (t));
718 dump_child ("hdlr", TRY_HANDLERS (t));
719 dump_next_stmt (di, t);
720 break;
722 case WHILE_STMT:
723 dump_stmt (di, t);
724 dump_child ("cond", WHILE_COND (t));
725 dump_child ("body", WHILE_BODY (t));
726 dump_next_stmt (di, t);
727 break;
729 case SUBOBJECT:
730 dump_stmt (di, t);
731 dump_child ("clnp", TREE_OPERAND (t, 0));
732 dump_next_stmt (di, t);
733 break;
735 case START_CATCH_STMT:
736 dump_stmt (di, t);
737 queue_and_dump_type (di, t);
738 dump_next_stmt (di, t);
739 break;
741 case CLEANUP_STMT:
742 dump_stmt (di, t);
743 dump_child ("decl", CLEANUP_DECL (t));
744 dump_child ("expr", CLEANUP_EXPR (t));
745 dump_next_stmt (di, t);
746 break;
748 case SCOPE_STMT:
749 dump_stmt (di, t);
750 if (SCOPE_BEGIN_P (t))
751 dump_string (di, "begn");
752 else
753 dump_string (di, "end");
754 if (SCOPE_NULLIFIED_P (t))
755 dump_string (di, "null");
756 dump_next_stmt (di, t);
757 break;
759 case INTEGER_CST:
760 if (TREE_INT_CST_HIGH (t))
761 dump_int (di, "high", TREE_INT_CST_HIGH (t));
762 dump_int (di, "low", TREE_INT_CST_LOW (t));
763 break;
765 case STRING_CST:
766 fprintf (di->stream, "strg: %-7s ", TREE_STRING_POINTER (t));
767 dump_int (di, "lngt", TREE_STRING_LENGTH (t));
768 break;
770 case PTRMEM_CST:
771 dump_child ("clas", PTRMEM_CST_CLASS (t));
772 dump_child ("mbr", PTRMEM_CST_MEMBER (t));
773 break;
775 case TRUTH_NOT_EXPR:
776 case ADDR_EXPR:
777 case INDIRECT_REF:
778 case THROW_EXPR:
779 case CLEANUP_POINT_EXPR:
780 case SAVE_EXPR:
781 /* These nodes are unary, but do not have code class `1'. */
782 dump_child ("op 0", TREE_OPERAND (t, 0));
783 break;
785 case TRUTH_ANDIF_EXPR:
786 case TRUTH_ORIF_EXPR:
787 case INIT_EXPR:
788 case MODIFY_EXPR:
789 case COMPONENT_REF:
790 case COMPOUND_EXPR:
791 case ARRAY_REF:
792 /* These nodes are binary, but do not have code class `2'. */
793 dump_child ("op 0", TREE_OPERAND (t, 0));
794 dump_child ("op 1", TREE_OPERAND (t, 1));
795 break;
797 case COND_EXPR:
798 dump_child ("op 0", TREE_OPERAND (t, 0));
799 dump_child ("op 1", TREE_OPERAND (t, 1));
800 dump_child ("op 2", TREE_OPERAND (t, 2));
801 break;
803 case CALL_EXPR:
804 dump_child ("fn", TREE_OPERAND (t, 0));
805 dump_child ("args", TREE_OPERAND (t, 1));
806 break;
808 case CONSTRUCTOR:
809 dump_child ("elts", TREE_OPERAND (t, 1));
810 break;
812 case STMT_EXPR:
813 dump_child ("stmt", STMT_EXPR_STMT (t));
814 break;
816 case BIND_EXPR:
817 dump_child ("vars", TREE_OPERAND (t, 0));
818 dump_child ("body", TREE_OPERAND (t, 1));
819 break;
821 case LOOP_EXPR:
822 dump_child ("body", TREE_OPERAND (t, 0));
823 break;
825 case EXIT_EXPR:
826 dump_child ("cond", TREE_OPERAND (t, 0));
827 break;
829 case TARGET_EXPR:
830 dump_child ("decl", TREE_OPERAND (t, 0));
831 dump_child ("init", TREE_OPERAND (t, 1));
832 dump_child ("clnp", TREE_OPERAND (t, 2));
833 /* There really are two possible places the initializer can be.
834 After RTL expansion, the second operand is moved to the
835 position of the fourth operand, and the second operand
836 becomes NULL. */
837 dump_child ("init", TREE_OPERAND (t, 3));
838 break;
840 case AGGR_INIT_EXPR:
841 dump_int (di, "ctor", AGGR_INIT_VIA_CTOR_P (t));
842 dump_child ("fn", TREE_OPERAND (t, 0));
843 dump_child ("args", TREE_OPERAND (t, 1));
844 dump_child ("decl", TREE_OPERAND (t, 2));
845 break;
847 default:
848 /* There are no additional fields to print. */
849 break;
852 done:
853 /* Terminate the line. */
854 fprintf (di->stream, "\n");
857 /* Dump T, and all its children, on STREAM. */
859 static void
860 dump_node (t, stream)
861 tree t;
862 FILE *stream;
864 struct dump_info di;
865 dump_queue_p dq;
866 dump_queue_p next_dq;
868 /* Initialize the dump-information structure. */
869 di.stream = stream;
870 di.index = 0;
871 di.column = 0;
872 di.queue = 0;
873 di.queue_end = 0;
874 di.free_list = 0;
875 di.nodes = splay_tree_new (splay_tree_compare_pointers, 0,
876 (splay_tree_delete_value_fn) &free);
878 /* Queue up the first node. */
879 queue (&di, t, DUMP_NONE);
881 /* Until the queue is empty, keep dumping nodes. */
882 while (di.queue)
883 dequeue_and_dump (&di);
885 /* Now, clean up. */
886 for (dq = di.free_list; dq; dq = next_dq)
888 next_dq = dq->next;
889 free (dq);
891 splay_tree_delete (di.nodes);
894 /* Dump T, and all its children, to FILE. */
896 void
897 dump_node_to_file (t, file)
898 tree t;
899 const char *file;
901 FILE *f;
903 f = fopen (file, "w");
904 if (!f)
905 cp_error ("could not open `%s'", file);
906 else
908 dump_node (t, f);
909 fclose (f);