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. */
30 #define DUMP_CHILDREN 1
33 /* Information about a node to be dumped. */
35 typedef struct dump_node_info
37 /* The index for the node. */
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;
45 /* A dump_queue is a link in the queue of things to be dumped. */
47 typedef struct dump_queue
49 /* The queued tree node. */
51 /* The next node in the queue. */
52 struct dump_queue *next;
55 /* A dump_info gives information about how we should perform the dump
56 and about the current state of the dump. */
58 typedef struct dump_info
60 /* The stream on which to dump the information. */
62 /* The next unused node index. */
64 /* The next column. */
66 /* The first node in the queue of nodes to be written out. */
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. */
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));
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. */
103 dump_node_info_p dni;
106 /* Assign the next available index to T. */
109 /* Obtain a new queue node. */
113 di->free_list = dq->next;
116 dq = (dump_queue_p) xmalloc (sizeof (struct dump_queue));
118 /* Create a new entry in the splay-tree. */
119 dni = (dump_node_info_p) xmalloc (sizeof (struct dump_node_info));
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);
126 /* Add it to the end of the queue. */
131 di->queue_end->next = dq;
134 /* Return the index. */
139 dump_index (di, index)
143 fprintf (di->stream, "@%-6u ", index);
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. */
152 queue_and_dump_index (di, field, t, flags)
161 /* If there's no node, just return. This makes for fewer checks in
166 /* See if we've already queued or dumped this node. */
167 n = splay_tree_lookup (di->nodes, (splay_tree_key) t);
169 index = ((dump_node_info_p) n->value)->index;
171 /* If we haven't, add it to the queue. */
172 index = queue (di, t, flags);
174 /* Print the index of the node. */
175 dump_maybe_newline (di);
176 fprintf (di->stream, "%-4s: ", field);
178 dump_index (di, index);
181 /* Dump the type of T. */
184 queue_and_dump_type (di, t, dump_children_p)
189 queue_and_dump_index (di, "type", TREE_TYPE (t), dump_children_p);
192 /* Insert a new line in the dump output, and indent to an appropriate
193 place to start printing more fields. */
199 fprintf (di->stream, "\n%25s", "");
203 /* If necessary, insert a new line. */
206 dump_maybe_newline (di)
209 /* See if we need a new line. */
212 /* See if we need any padding. */
213 else if ((di->column - 25) % 14 != 0)
215 fprintf (di->stream, "%*s", 14 - ((di->column - 25) % 14), "");
216 di->column += 14 - (di->column - 25) % 14;
220 /* Dump I using FIELD to identity it. */
223 dump_int (di, field, i)
228 dump_maybe_newline (di);
229 fprintf (di->stream, "%-4s: %-7d ", field, i);
233 /* Dump the string S. */
236 dump_string (di, string)
240 dump_maybe_newline (di);
241 fprintf (di->stream, "%-13s ", string);
242 if (strlen (string) > 13)
243 di->column += strlen (string) + 1;
248 /* Dump the string field S. */
251 dump_string_field (di, field, string)
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;
264 /* Dump information common to statements from STMT. */
271 dump_int (di, "line", STMT_LINENO (t));
274 /* Dump the CHILD and its children. */
275 #define dump_child(field, child) \
276 queue_and_dump_index (di, field, child, DUMP_CHILDREN)
278 /* Dump the next statement after STMT. */
281 dump_next_stmt (di, t)
285 dump_child ("next", TREE_CHAIN (t));
288 /* Dump the next node in the queue. */
291 dequeue_and_dump (di)
296 dump_node_info_p dni;
302 const char* code_name;
304 /* Get the next node from the queue. */
308 dni = (dump_node_info_p) stn->value;
310 dump_children_p = dni->dump_children_p;
312 /* Remove the node from the queue, and put it on the free list. */
313 di->queue = dq->next;
316 dq->next = di->free_list;
319 /* Print the node index. */
320 dump_index (di, index);
321 /* And the type of node this is. */
325 code_name = tree_code_name[(int) TREE_CODE (t)];
326 fprintf (di->stream, "%-16s ", code_name);
329 /* Figure out what kind of node this is. */
330 code = TREE_CODE (t);
331 code_class = TREE_CODE_CLASS (code);
333 /* Although BINFOs are TREE_VECs, we dump them specially so as to be
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");
348 dump_child ("type", BINFO_TYPE (t));
349 dump_child ("base", BINFO_BASETYPES (t));
355 /* We can knock off a bunch of expression nodes in exactly the same
357 if (IS_EXPR_CODE_CLASS (code_class))
359 /* If we're dumping children, dump them now. */
362 queue_and_dump_type (di, t, 1);
367 dump_child ("op 0", TREE_OPERAND (t, 0));
372 dump_child ("op 0", TREE_OPERAND (t, 0));
373 dump_child ("op 1", TREE_OPERAND (t, 1));
377 /* These nodes are handled explicitly below. */
381 my_friendly_abort (19990726);
385 else if (code_class == 'd')
387 /* All declarations have names. */
389 dump_child ("name", DECL_NAME (t));
393 queue_and_dump_type (di, t, 1);
394 queue_and_dump_index (di, "scpe", DECL_CONTEXT (t), 0);
396 /* And a source position. */
397 if (DECL_SOURCE_FILE (t))
399 const char *filename = rindex (DECL_SOURCE_FILE (t), '/');
401 filename = DECL_SOURCE_FILE (t);
403 /* Skip the slash. */
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;
411 /* And any declaration can be compiler-generated. */
412 if (DECL_ARTIFICIAL (t))
413 dump_string (di, "artificial");
415 dump_child ("chan", TREE_CHAIN (t));
417 else if (code_class == 't')
419 /* All types have qualifiers. */
420 int quals = CP_TYPE_QUALS (t);
421 if (quals != TYPE_UNQUALIFIED)
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' : ' ');
430 /* All types have associated declarations. */
431 dump_child ("name", TYPE_NAME (t));
435 /* All types have a main variant. */
436 if (TYPE_MAIN_VARIANT (t) != t)
437 dump_child ("unql", TYPE_MAIN_VARIANT (t));
440 dump_child ("size", TYPE_SIZE (t));
443 /* All types have alignments. */
444 dump_int (di, "algn", TYPE_ALIGN (t));
446 else if (code_class == 'c' && dump_children_p)
447 /* All constants can have types. */
448 queue_and_dump_type (di, t, 1);
450 /* Now handle the various kinds of nodes. */
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");
464 dump_string_field (di, "strg", IDENTIFIER_POINTER (t));
465 dump_int (di, "lngt", IDENTIFIER_LENGTH (t));
472 dump_child ("purp", TREE_PURPOSE (t));
473 dump_child ("valu", TREE_VALUE (t));
474 dump_child ("chan", TREE_CHAIN (t));
479 dump_int (di, "lngt", IDENTIFIER_LENGTH (t));
481 for (i = 0; i < TREE_VEC_LENGTH (t); ++i)
484 sprintf (buffer, "%u", i);
485 queue_and_dump_index (di, buffer, TREE_VEC_ELT (t, i), 1);
491 dump_int (di, "prec", TYPE_PRECISION (t));
492 if (TREE_UNSIGNED (t))
493 dump_string (di, "unsigned");
496 dump_child ("min", TYPE_MIN_VALUE (t));
497 dump_child ("max", TYPE_MAX_VALUE (t));
500 if (code == ENUMERAL_TYPE && dump_children_p)
501 dump_child ("csts", TYPE_VALUES (t));
505 dump_int (di, "prec", TYPE_PRECISION (t));
511 if (TYPE_PTRMEM_P (t))
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);
520 dump_child ("ptd", TREE_TYPE (t));
526 dump_child ("refd", TREE_TYPE (t));
531 dump_child ("clas", TYPE_METHOD_BASETYPE (t));
537 dump_child ("retn", TREE_TYPE (t));
538 dump_child ("prms", TYPE_ARG_TYPES (t));
545 dump_child ("elts", TREE_TYPE (t));
546 dump_child ("domn", TYPE_DOMAIN (t));
552 if (TYPE_PTRMEMFUNC_P (t))
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);
562 if (CLASSTYPE_DECLARED_CLASS (t))
563 dump_string (di, "class");
564 else if (TREE_CODE (t) == RECORD_TYPE)
565 dump_string (di, "struct");
567 dump_string (di, "union");
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);
581 dump_child ("cnst", DECL_INITIAL (t));
590 if (TREE_CODE (t) == PARM_DECL)
591 dump_child ("argt", DECL_ARG_TYPE (t));
593 dump_child ("init", DECL_INITIAL (t));
594 dump_child ("size", DECL_SIZE (t));
596 dump_int (di, "algn", DECL_ALIGN (t));
598 if (TREE_CODE (t) == FIELD_DECL && dump_children_p)
599 dump_child ("bpos", DECL_FIELD_BITPOS (t));
606 queue_and_dump_index (di, "scpe", DECL_REAL_CONTEXT (t), 0);
607 dump_child ("mngl", DECL_ASSEMBLER_NAME (t));
608 dump_child ("args", DECL_ARGUMENTS (t));
610 if (DECL_EXTERNAL (t))
611 dump_string (di, "undefined");
613 dump_string(di, "extern");
615 dump_string (di, "static");
616 if (TREE_CODE (t) == FUNCTION_DECL)
618 if (DECL_FUNCTION_MEMBER_P (t))
619 dump_string (di, "member");
620 if (DECL_CONSTRUCTOR_P (t))
621 dump_string (di, "constructor");
622 if (DECL_DESTRUCTOR_P (t))
623 dump_string (di, "destructor");
624 if (DECL_OVERLOADED_OPERATOR_P (t))
625 dump_string (di, "operator");
626 if (DECL_CONV_FN_P (t))
627 dump_string (di, "conversion");
629 dump_child ("body", DECL_SAVED_TREE (t));
633 dump_int (di, "dlta", THUNK_DELTA (t));
634 dump_child ("init", DECL_INITIAL (t));
639 /* The fake `::std' namespace does not have DECL_LANG_SPECIFIC,
640 and therefore many other macros do not work on it. */
644 dump_child ("dcls", cp_namespace_decls (t));
649 dump_child ("spcs", DECL_TEMPLATE_SPECIALIZATIONS (t));
655 dump_child ("crnt", OVL_CURRENT (t));
656 dump_child ("chan", OVL_CHAIN (t));
662 if (ASM_VOLATILE_P (t))
663 dump_string (di, "volatile");
666 dump_child ("strg", ASM_STRING (t));
667 dump_child ("outs", ASM_OUTPUTS (t));
668 dump_child ("ins", ASM_INPUTS (t));
669 dump_child ("clbr", ASM_CLOBBERS (t));
671 dump_next_stmt (di, t);
677 dump_next_stmt (di, t);
681 /* Note that a case label is not like other statments; there is
682 no way to get the line-number of a case label. */
685 dump_child ("low", CASE_LOW (t));
686 dump_child ("high", CASE_HIGH (t));
688 dump_next_stmt (di, t);
694 dump_child ("body", COMPOUND_BODY (t));
695 dump_next_stmt (di, t);
701 dump_child ("decl", DECL_STMT_DECL (t));
702 dump_next_stmt (di, t);
709 dump_child ("body", DO_BODY (t));
710 dump_child ("cond", DO_COND (t));
712 dump_next_stmt (di, t);
718 dump_child ("expr", EXPR_STMT_EXPR (t));
719 dump_next_stmt (di, t);
726 dump_child ("init", FOR_INIT_STMT (t));
727 dump_child ("cond", FOR_COND (t));
728 dump_child ("expr", FOR_EXPR (t));
729 dump_child ("body", FOR_BODY (t));
731 dump_next_stmt (di, t);
737 dump_child ("dest", GOTO_DESTINATION (t));
738 dump_next_stmt (di, t);
745 dump_child ("cond", IF_COND (t));
746 dump_child ("then", THEN_CLAUSE (t));
747 dump_child ("else", ELSE_CLAUSE (t));
749 dump_next_stmt (di, t);
755 dump_child ("labl", LABEL_STMT_LABEL (t));
756 dump_next_stmt (di, t);
762 dump_child ("expr", RETURN_EXPR (t));
763 dump_next_stmt (di, t);
770 dump_child ("cond", SWITCH_COND (t));
771 dump_child ("body", SWITCH_BODY (t));
773 dump_next_stmt (di, t);
780 dump_child ("body", TRY_STMTS (t));
781 dump_child ("hdlr", TRY_HANDLERS (t));
783 dump_next_stmt (di, t);
790 dump_child ("cond", WHILE_COND (t));
791 dump_child ("body", WHILE_BODY (t));
793 dump_next_stmt (di, t);
799 dump_child ("clnp", TREE_OPERAND (t, 0));
800 dump_next_stmt (di, t);
803 case START_CATCH_STMT:
806 queue_and_dump_type (di, TREE_TYPE (t), /*dump_children_p=*/1);
807 dump_next_stmt (di, t);
814 dump_child ("decl", CLEANUP_DECL (t));
815 dump_child ("expr", CLEANUP_EXPR (t));
817 dump_next_stmt (di, t);
822 if (SCOPE_BEGIN_P (t))
823 dump_string (di, "begn");
825 dump_string (di, "end");
826 if (SCOPE_NULLIFIED_P (t))
827 dump_string (di, "null");
828 dump_next_stmt (di, t);
832 if (TREE_INT_CST_HIGH (t))
833 dump_int (di, "high", TREE_INT_CST_HIGH (t));
834 dump_int (di, "low", TREE_INT_CST_LOW (t));
838 fprintf (di->stream, "strg: %-7s ", TREE_STRING_POINTER (t));
839 dump_int (di, "lngt", TREE_STRING_LENGTH (t));
845 dump_child ("clas", PTRMEM_CST_CLASS (t));
846 dump_child ("mbr", PTRMEM_CST_MEMBER (t));
854 /* These nodes are unary, but do not have code class `1'. */
856 dump_child ("op 0", TREE_OPERAND (t, 0));
859 case TRUTH_ANDIF_EXPR:
860 case TRUTH_ORIF_EXPR:
867 /* These nodes are binary, but do not have code class `2'. */
870 dump_child ("op 0", TREE_OPERAND (t, 0));
871 dump_child ("op 1", TREE_OPERAND (t, 1));
878 dump_child ("fn", TREE_OPERAND (t, 0));
879 dump_child ("args", TREE_OPERAND (t, 1));
885 dump_child ("elts", TREE_OPERAND (t, 1));
890 dump_child ("stmt", STMT_EXPR_STMT (t));
896 dump_child ("decl", TREE_OPERAND (t, 0));
897 dump_child ("init", TREE_OPERAND (t, 1));
898 dump_child ("clnp", TREE_OPERAND (t, 2));
899 /* There really are two possible places the initializer can
900 be. After RTL expansion, the second operand is moved to
901 the position of the fourth operand, and the second
902 operand becomes NULL. */
903 dump_child ("init", TREE_OPERAND (t, 3));
908 dump_int (di, "ctor", AGGR_INIT_VIA_CTOR_P (t));
911 dump_child ("fn", TREE_OPERAND (t, 0));
912 dump_child ("args", TREE_OPERAND (t, 1));
913 dump_child ("decl", TREE_OPERAND (t, 2));
918 /* There are no additional fields to print. */
923 /* Terminate the line. */
924 fprintf (di->stream, "\n");
927 /* Dump T, and all its children, on STREAM. */
930 dump_node (t, stream)
936 dump_queue_p next_dq;
938 /* Initialize the dump-information structure. */
945 di.nodes = splay_tree_new (splay_tree_compare_pointers, 0,
946 (splay_tree_delete_value_fn) &free);
948 /* Queue up the first node. */
949 queue (&di, t, DUMP_CHILDREN);
951 /* Until the queue is empty, keep dumping nodes. */
953 dequeue_and_dump (&di);
956 for (dq = di.free_list; dq; dq = next_dq)
961 splay_tree_delete (di.nodes);
964 /* Dump T, and all its children, to FILE. */
967 dump_node_to_file (t, file)
973 f = fopen (file, "w");
975 cp_error ("could not open `%s'", file);