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)
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. */
26 #include "splay-tree.h"
28 /* Flags used with queue functions. */
32 /* Information about a node to be dumped. */
34 typedef struct dump_node_info
36 /* The index for the node. */
38 /* Nonzero if the node is a binfo. */
39 unsigned int binfo_p
: 1;
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. */
48 /* The next node in the queue. */
49 struct dump_queue
*next
;
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. */
59 /* The next unused node index. */
61 /* The next column. */
63 /* The first node in the queue of nodes to be written out. */
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. */
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
102 /* Assign the next available index to T. */
105 /* Obtain a new queue node. */
109 di
->free_list
= dq
->next
;
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
));
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. */
126 di
->queue_end
->next
= dq
;
129 /* Return the index. */
134 dump_index (di
, index
)
138 fprintf (di
->stream
, "@%-6u ", index
);
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. */
147 queue_and_dump_index (di
, field
, t
, flags
)
156 /* If there's no node, just return. This makes for fewer checks in
161 /* See if we've already queued or dumped this node. */
162 n
= splay_tree_lookup (di
->nodes
, (splay_tree_key
) t
);
164 index
= ((dump_node_info_p
) n
->value
)->index
;
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
);
173 dump_index (di
, index
);
176 /* Dump the type of T. */
179 queue_and_dump_type (di
, 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. */
193 fprintf (di
->stream
, "\n%25s", "");
197 /* If necessary, insert a new line. */
200 dump_maybe_newline (di
)
203 /* See if we need a new line. */
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. */
217 dump_int (di
, field
, i
)
222 dump_maybe_newline (di
);
223 fprintf (di
->stream
, "%-4s: %-7d ", field
, i
);
227 /* Dump the string S. */
230 dump_string (di
, string
)
234 dump_maybe_newline (di
);
235 fprintf (di
->stream
, "%-13s ", string
);
236 if (strlen (string
) > 13)
237 di
->column
+= strlen (string
) + 1;
242 /* Dump the string field S. */
245 dump_string_field (di
, field
, 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;
258 /* Dump information common to statements from STMT. */
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. */
275 dump_next_stmt (di
, t
)
279 dump_child ("next", TREE_CHAIN (t
));
282 /* Dump the next node in the queue. */
285 dequeue_and_dump (di
)
290 dump_node_info_p dni
;
295 const char* code_name
;
297 /* Get the next node from the queue. */
301 dni
= (dump_node_info_p
) stn
->value
;
304 /* Remove the node from the queue, and put it on the free list. */
305 di
->queue
= dq
->next
;
308 dq
->next
= di
->free_list
;
311 /* Print the node index. */
312 dump_index (di
, index
);
313 /* And the type of node this is. */
317 code_name
= tree_code_name
[(int) TREE_CODE (t
)];
318 fprintf (di
->stream
, "%-16s ", code_name
);
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
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
));
344 /* We can knock off a bunch of expression nodes in exactly the same
346 if (IS_EXPR_CODE_CLASS (code_class
))
348 /* If we're dumping children, dump them now. */
349 queue_and_dump_type (di
, t
);
354 dump_child ("op 0", TREE_OPERAND (t
, 0));
359 dump_child ("op 0", TREE_OPERAND (t
, 0));
360 dump_child ("op 1", TREE_OPERAND (t
, 1));
364 /* These nodes are handled explicitly below. */
368 my_friendly_abort (19990726);
371 else if (code_class
== 'd')
373 /* All declarations have names. */
375 dump_child ("name", DECL_NAME (t
));
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
), '/');
384 filename
= DECL_SOURCE_FILE (t
);
386 /* Skip the slash. */
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");
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' : ' ');
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
));
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. */
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");
444 dump_string_field (di
, "strg", IDENTIFIER_POINTER (t
));
445 dump_int (di
, "lngt", IDENTIFIER_LENGTH (t
));
450 dump_child ("purp", TREE_PURPOSE (t
));
451 dump_child ("valu", TREE_VALUE (t
));
452 dump_child ("chan", TREE_CHAIN (t
));
456 dump_int (di
, "lngt", IDENTIFIER_LENGTH (t
));
457 for (i
= 0; i
< TREE_VEC_LENGTH (t
); ++i
)
460 sprintf (buffer
, "%u", i
);
461 dump_child (buffer
, TREE_VEC_ELT (t
, i
));
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
));
478 dump_int (di
, "prec", TYPE_PRECISION (t
));
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
));
489 dump_child ("ptd", TREE_TYPE (t
));
493 dump_child ("refd", TREE_TYPE (t
));
497 dump_child ("clas", TYPE_METHOD_BASETYPE (t
));
501 dump_child ("retn", TREE_TYPE (t
));
502 dump_child ("prms", TYPE_ARG_TYPES (t
));
506 dump_child ("elts", TREE_TYPE (t
));
507 dump_child ("domn", TYPE_DOMAIN (t
));
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
));
520 if (CLASSTYPE_DECLARED_CLASS (t
))
521 dump_string (di
, "class");
522 else if (TREE_CODE (t
) == RECORD_TYPE
)
523 dump_string (di
, "struct");
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
),
536 dump_child ("cnst", DECL_INITIAL (t
));
543 if (TREE_CODE (t
) == PARM_DECL
)
544 dump_child ("argt", DECL_ARG_TYPE (t
));
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
));
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");
566 dump_string(di
, "extern");
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
));
594 dump_int (di
, "dlta", THUNK_DELTA (t
));
595 dump_child ("init", DECL_INITIAL (t
));
600 /* The fake `::std' namespace does not have DECL_LANG_SPECIFIC,
601 and therefore many other macros do not work on it. */
604 dump_child ("dcls", cp_namespace_decls (t
));
608 dump_child ("spcs", DECL_TEMPLATE_SPECIALIZATIONS (t
));
612 dump_child ("crnt", OVL_CURRENT (t
));
613 dump_child ("chan", OVL_CHAIN (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
);
630 dump_next_stmt (di
, t
);
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
);
643 dump_child ("body", COMPOUND_BODY (t
));
644 dump_next_stmt (di
, t
);
649 dump_child ("decl", DECL_STMT_DECL (t
));
650 dump_next_stmt (di
, t
);
655 dump_child ("body", DO_BODY (t
));
656 dump_child ("cond", DO_COND (t
));
657 dump_next_stmt (di
, t
);
662 dump_child ("expr", EXPR_STMT_EXPR (t
));
663 dump_next_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
);
677 dump_child ("dest", GOTO_DESTINATION (t
));
678 dump_next_stmt (di
, t
);
683 dump_child ("body", HANDLER_BODY (t
));
684 dump_next_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
);
697 dump_child ("labl", LABEL_STMT_LABEL (t
));
698 dump_next_stmt (di
, t
);
703 dump_child ("expr", RETURN_EXPR (t
));
704 dump_next_stmt (di
, t
);
709 dump_child ("cond", SWITCH_COND (t
));
710 dump_child ("body", SWITCH_BODY (t
));
711 dump_next_stmt (di
, 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
);
725 dump_child ("cond", WHILE_COND (t
));
726 dump_child ("body", WHILE_BODY (t
));
727 dump_next_stmt (di
, t
);
732 dump_child ("clnp", TREE_OPERAND (t
, 0));
733 dump_next_stmt (di
, t
);
736 case START_CATCH_STMT
:
738 queue_and_dump_type (di
, t
);
739 dump_next_stmt (di
, t
);
744 dump_child ("decl", CLEANUP_DECL (t
));
745 dump_child ("expr", CLEANUP_EXPR (t
));
746 dump_next_stmt (di
, t
);
751 if (SCOPE_BEGIN_P (t
))
752 dump_string (di
, "begn");
754 dump_string (di
, "end");
755 if (SCOPE_NULLIFIED_P (t
))
756 dump_string (di
, "null");
757 dump_next_stmt (di
, t
);
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
));
767 fprintf (di
->stream
, "strg: %-7s ", TREE_STRING_POINTER (t
));
768 dump_int (di
, "lngt", TREE_STRING_LENGTH (t
));
772 dump_child ("clas", PTRMEM_CST_CLASS (t
));
773 dump_child ("mbr", PTRMEM_CST_MEMBER (t
));
780 case CLEANUP_POINT_EXPR
:
782 /* These nodes are unary, but do not have code class `1'. */
783 dump_child ("op 0", TREE_OPERAND (t
, 0));
786 case TRUTH_ANDIF_EXPR
:
787 case TRUTH_ORIF_EXPR
:
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));
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));
805 dump_child ("fn", TREE_OPERAND (t
, 0));
806 dump_child ("args", TREE_OPERAND (t
, 1));
810 dump_child ("elts", TREE_OPERAND (t
, 1));
814 dump_child ("stmt", STMT_EXPR_STMT (t
));
818 dump_child ("vars", TREE_OPERAND (t
, 0));
819 dump_child ("body", TREE_OPERAND (t
, 1));
823 dump_child ("body", TREE_OPERAND (t
, 0));
827 dump_child ("cond", TREE_OPERAND (t
, 0));
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
838 dump_child ("init", TREE_OPERAND (t
, 3));
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));
849 /* There are no additional fields to print. */
854 /* Terminate the line. */
855 fprintf (di
->stream
, "\n");
858 /* Dump T, and all its children, on STREAM. */
861 dump_node (t
, stream
)
867 dump_queue_p next_dq
;
869 /* Initialize the dump-information structure. */
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. */
884 dequeue_and_dump (&di
);
887 for (dq
= di
.free_list
; dq
; dq
= next_dq
)
892 splay_tree_delete (di
.nodes
);
895 /* Dump T, and all its children, to FILE. */
898 dump_node_to_file (t
, file
)
904 f
= fopen (file
, "w");
906 cp_error ("could not open `%s'", file
);