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));
605 queue_and_dump_index (di, "scpe", DECL_REAL_CONTEXT (t), 0);
606 dump_child ("mngl", DECL_ASSEMBLER_NAME (t));
607 dump_child ("args", DECL_ARGUMENTS (t));
610 dump_string(di, "extern");
612 dump_string (di, "static");
613 if (DECL_FUNCTION_MEMBER_P (t))
614 dump_string (di, "member");
615 if (DECL_CONSTRUCTOR_P (t))
616 dump_string (di, "constructor");
617 if (DECL_DESTRUCTOR_P (t))
618 dump_string (di, "destructor");
619 if (DECL_OVERLOADED_OPERATOR_P (t))
620 dump_string (di, "operator");
621 if (DECL_CONV_FN_P (t))
622 dump_string (di, "conversion");
624 dump_child ("body", DECL_SAVED_TREE (t));
628 /* The fake `::std' namespace does not have DECL_LANG_SPECIFIC,
629 and therefore many other macros do not work on it. */
633 dump_child ("dcls", cp_namespace_decls (t));
638 dump_child ("spcs", DECL_TEMPLATE_SPECIALIZATIONS (t));
644 dump_child ("crnt", OVL_CURRENT (t));
645 dump_child ("chan", OVL_CHAIN (t));
651 if (ASM_VOLATILE_P (t))
652 dump_string (di, "volatile");
655 dump_child ("strg", ASM_STRING (t));
656 dump_child ("outs", ASM_OUTPUTS (t));
657 dump_child ("ins", ASM_INPUTS (t));
658 dump_child ("clbr", ASM_CLOBBERS (t));
660 dump_next_stmt (di, t);
666 dump_next_stmt (di, t);
670 /* Note that a case label is not like other statments; there is
671 no way to get the line-number of a case label. */
674 dump_child ("low", CASE_LOW (t));
675 dump_child ("high", CASE_HIGH (t));
677 dump_next_stmt (di, t);
683 dump_child ("body", COMPOUND_BODY (t));
684 dump_next_stmt (di, t);
690 dump_child ("decl", DECL_STMT_DECL (t));
691 dump_next_stmt (di, t);
698 dump_child ("body", DO_BODY (t));
699 dump_child ("cond", DO_COND (t));
701 dump_next_stmt (di, t);
707 dump_child ("expr", EXPR_STMT_EXPR (t));
708 dump_next_stmt (di, t);
715 dump_child ("init", FOR_INIT_STMT (t));
716 dump_child ("cond", FOR_COND (t));
717 dump_child ("expr", FOR_EXPR (t));
718 dump_child ("body", FOR_BODY (t));
720 dump_next_stmt (di, t);
726 dump_child ("dest", GOTO_DESTINATION (t));
727 dump_next_stmt (di, t);
734 dump_child ("cond", IF_COND (t));
735 dump_child ("then", THEN_CLAUSE (t));
736 dump_child ("else", ELSE_CLAUSE (t));
738 dump_next_stmt (di, t);
744 dump_child ("labl", LABEL_STMT_LABEL (t));
745 dump_next_stmt (di, t);
751 dump_child ("expr", RETURN_EXPR (t));
752 dump_next_stmt (di, t);
759 dump_child ("cond", SWITCH_COND (t));
760 dump_child ("body", SWITCH_BODY (t));
762 dump_next_stmt (di, t);
769 dump_child ("body", TRY_STMTS (t));
770 dump_child ("hdlr", TRY_HANDLERS (t));
772 dump_next_stmt (di, t);
779 dump_child ("cond", WHILE_COND (t));
780 dump_child ("body", WHILE_BODY (t));
782 dump_next_stmt (di, t);
788 dump_child ("clnp", TREE_OPERAND (t, 0));
789 dump_next_stmt (di, t);
792 case START_CATCH_STMT:
795 queue_and_dump_type (di, TREE_TYPE (t), /*dump_children_p=*/1);
796 dump_next_stmt (di, t);
803 dump_child ("decl", CLEANUP_DECL (t));
804 dump_child ("expr", CLEANUP_EXPR (t));
806 dump_next_stmt (di, t);
811 if (SCOPE_BEGIN_P (t))
812 dump_string (di, "begn");
814 dump_string (di, "end");
815 if (SCOPE_NULLIFIED_P (t))
816 dump_string (di, "null");
817 dump_next_stmt (di, t);
821 if (TREE_INT_CST_HIGH (t))
822 dump_int (di, "high", TREE_INT_CST_HIGH (t));
823 dump_int (di, "low", TREE_INT_CST_LOW (t));
827 fprintf (di->stream, "strg: %-7s ", TREE_STRING_POINTER (t));
828 dump_int (di, "lngt", TREE_STRING_LENGTH (t));
834 dump_child ("clas", PTRMEM_CST_CLASS (t));
835 dump_child ("mbr", PTRMEM_CST_MEMBER (t));
843 /* These nodes are unary, but do not have code class `1'. */
845 dump_child ("op 0", TREE_OPERAND (t, 0));
848 case TRUTH_ANDIF_EXPR:
849 case TRUTH_ORIF_EXPR:
856 /* These nodes are binary, but do not have code class `2'. */
859 dump_child ("op 0", TREE_OPERAND (t, 0));
860 dump_child ("op 1", TREE_OPERAND (t, 1));
867 dump_child ("fn", TREE_OPERAND (t, 0));
868 dump_child ("args", TREE_OPERAND (t, 1));
874 dump_child ("elts", TREE_OPERAND (t, 1));
879 dump_child ("stmt", STMT_EXPR_STMT (t));
885 dump_child ("decl", TREE_OPERAND (t, 0));
886 dump_child ("init", TREE_OPERAND (t, 1));
887 dump_child ("clnp", TREE_OPERAND (t, 2));
888 /* There really are two possible places the initializer can
889 be. After RTL expansion, the second operand is moved to
890 the position of the fourth operand, and the second
891 operand becomes NULL. */
892 dump_child ("init", TREE_OPERAND (t, 3));
897 dump_int (di, "ctor", AGGR_INIT_VIA_CTOR_P (t));
900 dump_child ("fn", TREE_OPERAND (t, 0));
901 dump_child ("args", TREE_OPERAND (t, 1));
902 dump_child ("decl", TREE_OPERAND (t, 2));
907 /* There are no additional fields to print. */
912 /* Terminate the line. */
913 fprintf (di->stream, "\n");
916 /* Dump T, and all its children, on STREAM. */
919 dump_node (t, stream)
925 dump_queue_p next_dq;
927 /* Initialize the dump-information structure. */
934 di.nodes = splay_tree_new (splay_tree_compare_pointers, 0,
935 (splay_tree_delete_value_fn) &free);
937 /* Queue up the first node. */
938 queue (&di, t, DUMP_CHILDREN);
940 /* Until the queue is empty, keep dumping nodes. */
942 dequeue_and_dump (&di);
945 for (dq = di.free_list; dq; dq = next_dq)
950 splay_tree_delete (di.nodes);
953 /* Dump T, and all its children, to FILE. */
956 dump_node_to_file (t, file)
962 f = fopen (file, "w");
964 cp_error ("could not open `%s'", file);