* dump.c (dequeue_and_dump): Fix thinko for catch-clauses.
[official-gcc.git] / gcc / cp / dump.c
blobef92f182964a6668bec037498f30d03036a0c1b1
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"
26 #include "splay-tree.h"
28 /* Flags used with queue functions. */
29 #define DUMP_NONE 0
30 #define DUMP_BINFO 1
32 /* Information about a node to be dumped. */
34 typedef struct dump_node_info
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;
42 /* A dump_queue is a link in the queue of things to be dumped. */
44 typedef struct dump_queue
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;
52 /* A dump_info gives information about how we should perform the dump
53 and about the current state of the dump. */
55 typedef struct dump_info
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;
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));
89 /* Add T to the end of the queue of nodes to dump. Returns the index
90 assigned to T. */
92 static unsigned int
93 queue (di, t, flags)
94 dump_info_p di;
95 tree t;
96 int flags;
98 dump_queue_p dq;
99 dump_node_info_p dni;
100 unsigned int index;
102 /* Assign the next available index to T. */
103 index = ++di->index;
105 /* Obtain a new queue node. */
106 if (di->free_list)
108 dq = di->free_list;
109 di->free_list = dq->next;
111 else
112 dq = (dump_queue_p) xmalloc (sizeof (struct dump_queue));
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);
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;
129 /* Return the index. */
130 return index;
133 static void
134 dump_index (di, index)
135 dump_info_p di;
136 unsigned int index;
138 fprintf (di->stream, "@%-6u ", index);
139 di->column += 8;
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. */
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;
153 unsigned int index;
154 splay_tree_node n;
156 /* If there's no node, just return. This makes for fewer checks in
157 our callers. */
158 if (!t)
159 return;
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);
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);
176 /* Dump the type of T. */
178 static void
179 queue_and_dump_type (di, t)
180 dump_info_p di;
181 tree t;
183 queue_and_dump_index (di, "type", TREE_TYPE (t), DUMP_NONE);
186 /* Insert a new line in the dump output, and indent to an appropriate
187 place to start printing more fields. */
189 static void
190 dump_new_line (di)
191 dump_info_p di;
193 fprintf (di->stream, "\n%25s", "");
194 di->column = 25;
197 /* If necessary, insert a new line. */
199 static void
200 dump_maybe_newline (di)
201 dump_info_p di;
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)
209 fprintf (di->stream, "%*s", 14 - ((di->column - 25) % 14), "");
210 di->column += 14 - (di->column - 25) % 14;
214 /* Dump I using FIELD to identity it. */
216 static void
217 dump_int (di, field, i)
218 dump_info_p di;
219 const char *field;
220 int i;
222 dump_maybe_newline (di);
223 fprintf (di->stream, "%-4s: %-7d ", field, i);
224 di->column += 14;
227 /* Dump the string S. */
229 static void
230 dump_string (di, string)
231 dump_info_p di;
232 const char *string;
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;
242 /* Dump the string field S. */
244 static void
245 dump_string_field (di, field, string)
246 dump_info_p di;
247 const char *field;
248 const char *string;
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;
258 /* Dump information common to statements from STMT. */
260 static void
261 dump_stmt (di, t)
262 dump_info_p di;
263 tree t;
265 dump_int (di, "line", STMT_LINENO (t));
268 /* Dump the CHILD and its children. */
269 #define dump_child(field, child) \
270 queue_and_dump_index (di, field, child, DUMP_NONE)
272 /* Dump the next statement after STMT. */
274 static void
275 dump_next_stmt (di, t)
276 dump_info_p di;
277 tree t;
279 dump_child ("next", TREE_CHAIN (t));
282 /* Dump the next node in the queue. */
284 static void
285 dequeue_and_dump (di)
286 dump_info_p di;
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;
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;
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;
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;
321 /* Figure out what kind of node this is. */
322 code = TREE_CODE (t);
323 code_class = TREE_CODE_CLASS (code);
325 /* Although BINFOs are TREE_VECs, we dump them specially so as to be
326 more informative. */
327 if (dni->binfo_p)
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");
338 dump_child ("type", BINFO_TYPE (t));
339 dump_child ("base", BINFO_BASETYPES (t));
341 goto done;
344 /* We can knock off a bunch of expression nodes in exactly the same
345 way. */
346 if (IS_EXPR_CODE_CLASS (code_class))
348 /* If we're dumping children, dump them now. */
349 queue_and_dump_type (di, t);
351 switch (code_class)
353 case '1':
354 dump_child ("op 0", TREE_OPERAND (t, 0));
355 break;
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;
363 case 'e':
364 /* These nodes are handled explicitly below. */
365 break;
367 default:
368 my_friendly_abort (19990726);
371 else if (code_class == 'd')
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 dump_child ("scpe", DECL_CONTEXT (t));
379 /* And a source position. */
380 if (DECL_SOURCE_FILE (t))
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;
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;
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));
400 else if (code_class == 't')
402 /* All types have qualifiers. */
403 int quals = CP_TYPE_QUALS (t);
404 if (quals != TYPE_UNQUALIFIED)
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;
413 /* All types have associated declarations. */
414 dump_child ("name", TYPE_NAME (t));
416 /* All types have a main variant. */
417 if (TYPE_MAIN_VARIANT (t) != t)
418 dump_child ("unql", TYPE_MAIN_VARIANT (t));
420 /* And sizes. */
421 dump_child ("size", TYPE_SIZE (t));
423 /* All types have alignments. */
424 dump_int (di, "algn", TYPE_ALIGN (t));
426 else if (code_class == 'c')
427 /* All constants can have types. */
428 queue_and_dump_type (di, t);
430 /* Now handle the various kinds of nodes. */
431 switch (code)
433 int i;
435 case IDENTIFIER_NODE:
436 if (IDENTIFIER_OPNAME_P (t))
437 dump_string (di, "operator");
438 else if (IDENTIFIER_TYPENAME_P (t))
439 dump_child ("tynm", TREE_TYPE (t));
440 else if (t == anonymous_namespace_name)
441 dump_string (di, "unnamed");
442 else
444 dump_string_field (di, "strg", IDENTIFIER_POINTER (t));
445 dump_int (di, "lngt", IDENTIFIER_LENGTH (t));
447 break;
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;
455 case TREE_VEC:
456 dump_int (di, "lngt", IDENTIFIER_LENGTH (t));
457 for (i = 0; i < TREE_VEC_LENGTH (t); ++i)
459 char buffer[32];
460 sprintf (buffer, "%u", i);
461 dump_child (buffer, TREE_VEC_ELT (t, i));
463 break;
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));
473 if (code == ENUMERAL_TYPE)
474 dump_child ("csts", TYPE_VALUES (t));
475 break;
477 case REAL_TYPE:
478 dump_int (di, "prec", TYPE_PRECISION (t));
479 break;
481 case POINTER_TYPE:
482 if (TYPE_PTRMEM_P (t))
484 dump_string (di, "ptrmem");
485 dump_child ("ptd", TYPE_PTRMEM_POINTED_TO_TYPE (t));
486 dump_child ("csl", TYPE_PTRMEM_CLASS_TYPE (t));
488 else
489 dump_child ("ptd", TREE_TYPE (t));
490 break;
492 case REFERENCE_TYPE:
493 dump_child ("refd", TREE_TYPE (t));
494 break;
496 case METHOD_TYPE:
497 dump_child ("clas", TYPE_METHOD_BASETYPE (t));
498 /* Fall through. */
500 case FUNCTION_TYPE:
501 dump_child ("retn", TREE_TYPE (t));
502 dump_child ("prms", TYPE_ARG_TYPES (t));
503 break;
505 case ARRAY_TYPE:
506 dump_child ("elts", TREE_TYPE (t));
507 dump_child ("domn", TYPE_DOMAIN (t));
508 break;
510 case RECORD_TYPE:
511 case UNION_TYPE:
512 if (TYPE_PTRMEMFUNC_P (t))
514 dump_string (di, "ptrmem");
515 dump_child ("ptd", TYPE_PTRMEM_POINTED_TO_TYPE (t));
516 dump_child ("cls", TYPE_PTRMEM_CLASS_TYPE (t));
518 else
520 if (CLASSTYPE_DECLARED_CLASS (t))
521 dump_string (di, "class");
522 else if (TREE_CODE (t) == RECORD_TYPE)
523 dump_string (di, "struct");
524 else
525 dump_string (di, "union");
527 dump_child ("flds", TYPE_FIELDS (t));
528 dump_child ("fncs", TYPE_METHODS (t));
529 dump_child ("vfld", TYPE_VFIELD (t));
530 queue_and_dump_index (di, "binf", TYPE_BINFO (t),
531 DUMP_BINFO);
533 break;
535 case CONST_DECL:
536 dump_child ("cnst", DECL_INITIAL (t));
537 break;
539 case VAR_DECL:
540 case PARM_DECL:
541 case FIELD_DECL:
542 case RESULT_DECL:
543 if (TREE_CODE (t) == PARM_DECL)
544 dump_child ("argt", DECL_ARG_TYPE (t));
545 else
546 dump_child ("init", DECL_INITIAL (t));
547 dump_child ("size", DECL_SIZE (t));
548 dump_int (di, "algn", DECL_ALIGN (t));
550 if (TREE_CODE (t) == FIELD_DECL)
552 if (DECL_C_BIT_FIELD (t))
553 dump_string (di, "bitfield");
554 dump_child ("bpos", DECL_FIELD_BITPOS (t));
556 break;
558 case FUNCTION_DECL:
559 case THUNK_DECL:
560 dump_child ("scpe", DECL_REAL_CONTEXT (t));
561 dump_child ("mngl", DECL_ASSEMBLER_NAME (t));
562 dump_child ("args", DECL_ARGUMENTS (t));
563 if (DECL_EXTERNAL (t))
564 dump_string (di, "undefined");
565 if (TREE_PUBLIC (t))
566 dump_string(di, "extern");
567 else
568 dump_string (di, "static");
569 if (TREE_CODE (t) == FUNCTION_DECL)
571 if (DECL_FUNCTION_MEMBER_P (t))
572 dump_string (di, "member");
573 if (DECL_CONSTRUCTOR_P (t))
574 dump_string (di, "constructor");
575 if (DECL_DESTRUCTOR_P (t))
576 dump_string (di, "destructor");
577 if (DECL_OVERLOADED_OPERATOR_P (t))
578 dump_string (di, "operator");
579 if (DECL_CONV_FN_P (t))
580 dump_string (di, "conversion");
581 if (DECL_GLOBAL_CTOR_P (t) || DECL_GLOBAL_DTOR_P (t))
583 if (DECL_GLOBAL_CTOR_P (t))
584 dump_string (di, "global init");
585 if (DECL_GLOBAL_DTOR_P (t))
586 dump_string (di, "global fini");
587 dump_int (di, "prio", GLOBAL_INIT_PRIORITY (t));
590 dump_child ("body", DECL_SAVED_TREE (t));
592 else
594 dump_int (di, "dlta", THUNK_DELTA (t));
595 dump_child ("init", DECL_INITIAL (t));
597 break;
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 dump_child ("dcls", cp_namespace_decls (t));
605 break;
607 case TEMPLATE_DECL:
608 dump_child ("spcs", DECL_TEMPLATE_SPECIALIZATIONS (t));
609 break;
611 case OVERLOAD:
612 dump_child ("crnt", OVL_CURRENT (t));
613 dump_child ("chan", OVL_CHAIN (t));
614 break;
616 case ASM_STMT:
617 dump_stmt (di, t);
618 if (ASM_VOLATILE_P (t))
619 dump_string (di, "volatile");
620 dump_child ("strg", ASM_STRING (t));
621 dump_child ("outs", ASM_OUTPUTS (t));
622 dump_child ("ins", ASM_INPUTS (t));
623 dump_child ("clbr", ASM_CLOBBERS (t));
624 dump_next_stmt (di, t);
625 break;
627 case BREAK_STMT:
628 case CONTINUE_STMT:
629 dump_stmt (di, t);
630 dump_next_stmt (di, t);
631 break;
633 case CASE_LABEL:
634 /* Note that a case label is not like other statments; there is
635 no way to get the line-number of a case label. */
636 dump_child ("low", CASE_LOW (t));
637 dump_child ("high", CASE_HIGH (t));
638 dump_next_stmt (di, t);
639 break;
641 case COMPOUND_STMT:
642 dump_stmt (di, t);
643 dump_child ("body", COMPOUND_BODY (t));
644 dump_next_stmt (di, t);
645 break;
647 case DECL_STMT:
648 dump_stmt (di, t);
649 dump_child ("decl", DECL_STMT_DECL (t));
650 dump_next_stmt (di, t);
651 break;
653 case DO_STMT:
654 dump_stmt (di, t);
655 dump_child ("body", DO_BODY (t));
656 dump_child ("cond", DO_COND (t));
657 dump_next_stmt (di, t);
658 break;
660 case EXPR_STMT:
661 dump_stmt (di, t);
662 dump_child ("expr", EXPR_STMT_EXPR (t));
663 dump_next_stmt (di, t);
664 break;
666 case FOR_STMT:
667 dump_stmt (di, t);
668 dump_child ("init", FOR_INIT_STMT (t));
669 dump_child ("cond", FOR_COND (t));
670 dump_child ("expr", FOR_EXPR (t));
671 dump_child ("body", FOR_BODY (t));
672 dump_next_stmt (di, t);
673 break;
675 case GOTO_STMT:
676 dump_stmt (di, t);
677 dump_child ("dest", GOTO_DESTINATION (t));
678 dump_next_stmt (di, t);
679 break;
681 case HANDLER:
682 dump_stmt (di, t);
683 dump_child ("body", HANDLER_BODY (t));
684 dump_next_stmt (di, t);
685 break;
687 case IF_STMT:
688 dump_stmt (di, t);
689 dump_child ("cond", IF_COND (t));
690 dump_child ("then", THEN_CLAUSE (t));
691 dump_child ("else", ELSE_CLAUSE (t));
692 dump_next_stmt (di, t);
693 break;
695 case LABEL_STMT:
696 dump_stmt (di, t);
697 dump_child ("labl", LABEL_STMT_LABEL (t));
698 dump_next_stmt (di, t);
699 break;
701 case RETURN_STMT:
702 dump_stmt (di, t);
703 dump_child ("expr", RETURN_EXPR (t));
704 dump_next_stmt (di, t);
705 break;
707 case SWITCH_STMT:
708 dump_stmt (di, t);
709 dump_child ("cond", SWITCH_COND (t));
710 dump_child ("body", SWITCH_BODY (t));
711 dump_next_stmt (di, t);
712 break;
714 case TRY_BLOCK:
715 dump_stmt (di, t);
716 if (CLEANUP_P (t))
717 dump_string (di, "cleanup");
718 dump_child ("body", TRY_STMTS (t));
719 dump_child ("hdlr", TRY_HANDLERS (t));
720 dump_next_stmt (di, t);
721 break;
723 case WHILE_STMT:
724 dump_stmt (di, t);
725 dump_child ("cond", WHILE_COND (t));
726 dump_child ("body", WHILE_BODY (t));
727 dump_next_stmt (di, t);
728 break;
730 case SUBOBJECT:
731 dump_stmt (di, t);
732 dump_child ("clnp", TREE_OPERAND (t, 0));
733 dump_next_stmt (di, t);
734 break;
736 case START_CATCH_STMT:
737 dump_stmt (di, t);
738 queue_and_dump_type (di, t);
739 dump_next_stmt (di, t);
740 break;
742 case CLEANUP_STMT:
743 dump_stmt (di, t);
744 dump_child ("decl", CLEANUP_DECL (t));
745 dump_child ("expr", CLEANUP_EXPR (t));
746 dump_next_stmt (di, t);
747 break;
749 case SCOPE_STMT:
750 dump_stmt (di, t);
751 if (SCOPE_BEGIN_P (t))
752 dump_string (di, "begn");
753 else
754 dump_string (di, "end");
755 if (SCOPE_NULLIFIED_P (t))
756 dump_string (di, "null");
757 dump_next_stmt (di, t);
758 break;
760 case INTEGER_CST:
761 if (TREE_INT_CST_HIGH (t))
762 dump_int (di, "high", TREE_INT_CST_HIGH (t));
763 dump_int (di, "low", TREE_INT_CST_LOW (t));
764 break;
766 case STRING_CST:
767 fprintf (di->stream, "strg: %-7s ", TREE_STRING_POINTER (t));
768 dump_int (di, "lngt", TREE_STRING_LENGTH (t));
769 break;
771 case PTRMEM_CST:
772 dump_child ("clas", PTRMEM_CST_CLASS (t));
773 dump_child ("mbr", PTRMEM_CST_MEMBER (t));
774 break;
776 case TRUTH_NOT_EXPR:
777 case ADDR_EXPR:
778 case INDIRECT_REF:
779 case THROW_EXPR:
780 case CLEANUP_POINT_EXPR:
781 case SAVE_EXPR:
782 /* These nodes are unary, but do not have code class `1'. */
783 dump_child ("op 0", TREE_OPERAND (t, 0));
784 break;
786 case TRUTH_ANDIF_EXPR:
787 case TRUTH_ORIF_EXPR:
788 case INIT_EXPR:
789 case MODIFY_EXPR:
790 case COMPONENT_REF:
791 case COMPOUND_EXPR:
792 case ARRAY_REF:
793 /* These nodes are binary, but do not have code class `2'. */
794 dump_child ("op 0", TREE_OPERAND (t, 0));
795 dump_child ("op 1", TREE_OPERAND (t, 1));
796 break;
798 case COND_EXPR:
799 dump_child ("op 0", TREE_OPERAND (t, 0));
800 dump_child ("op 1", TREE_OPERAND (t, 1));
801 dump_child ("op 2", TREE_OPERAND (t, 2));
802 break;
804 case CALL_EXPR:
805 dump_child ("fn", TREE_OPERAND (t, 0));
806 dump_child ("args", TREE_OPERAND (t, 1));
807 break;
809 case CONSTRUCTOR:
810 dump_child ("elts", TREE_OPERAND (t, 1));
811 break;
813 case STMT_EXPR:
814 dump_child ("stmt", STMT_EXPR_STMT (t));
815 break;
817 case BIND_EXPR:
818 dump_child ("vars", TREE_OPERAND (t, 0));
819 dump_child ("body", TREE_OPERAND (t, 1));
820 break;
822 case LOOP_EXPR:
823 dump_child ("body", TREE_OPERAND (t, 0));
824 break;
826 case EXIT_EXPR:
827 dump_child ("cond", TREE_OPERAND (t, 0));
828 break;
830 case TARGET_EXPR:
831 dump_child ("decl", TREE_OPERAND (t, 0));
832 dump_child ("init", TREE_OPERAND (t, 1));
833 dump_child ("clnp", TREE_OPERAND (t, 2));
834 /* There really are two possible places the initializer can be.
835 After RTL expansion, the second operand is moved to the
836 position of the fourth operand, and the second operand
837 becomes NULL. */
838 dump_child ("init", TREE_OPERAND (t, 3));
839 break;
841 case AGGR_INIT_EXPR:
842 dump_int (di, "ctor", AGGR_INIT_VIA_CTOR_P (t));
843 dump_child ("fn", TREE_OPERAND (t, 0));
844 dump_child ("args", TREE_OPERAND (t, 1));
845 dump_child ("decl", TREE_OPERAND (t, 2));
846 break;
848 default:
849 /* There are no additional fields to print. */
850 break;
853 done:
854 /* Terminate the line. */
855 fprintf (di->stream, "\n");
858 /* Dump T, and all its children, on STREAM. */
860 static void
861 dump_node (t, stream)
862 tree t;
863 FILE *stream;
865 struct dump_info di;
866 dump_queue_p dq;
867 dump_queue_p next_dq;
869 /* Initialize the dump-information structure. */
870 di.stream = stream;
871 di.index = 0;
872 di.column = 0;
873 di.queue = 0;
874 di.queue_end = 0;
875 di.free_list = 0;
876 di.nodes = splay_tree_new (splay_tree_compare_pointers, 0,
877 (splay_tree_delete_value_fn) &free);
879 /* Queue up the first node. */
880 queue (&di, t, DUMP_NONE);
882 /* Until the queue is empty, keep dumping nodes. */
883 while (di.queue)
884 dequeue_and_dump (&di);
886 /* Now, clean up. */
887 for (dq = di.free_list; dq; dq = next_dq)
889 next_dq = dq->next;
890 free (dq);
892 splay_tree_delete (di.nodes);
895 /* Dump T, and all its children, to FILE. */
897 void
898 dump_node_to_file (t, file)
899 tree t;
900 const char *file;
902 FILE *f;
904 f = fopen (file, "w");
905 if (!f)
906 cp_error ("could not open `%s'", file);
907 else
909 dump_node (t, f);
910 fclose (f);