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));
611 dump_string(di, "extern");
613 dump_string (di, "static");
614 if (TREE_CODE (t) == FUNCTION_DECL)
616 if (DECL_FUNCTION_MEMBER_P (t))
617 dump_string (di, "member");
618 if (DECL_CONSTRUCTOR_P (t))
619 dump_string (di, "constructor");
620 if (DECL_DESTRUCTOR_P (t))
621 dump_string (di, "destructor");
622 if (DECL_OVERLOADED_OPERATOR_P (t))
623 dump_string (di, "operator");
624 if (DECL_CONV_FN_P (t))
625 dump_string (di, "conversion");
627 dump_child ("body", DECL_SAVED_TREE (t));
631 dump_int (di, "dlta", THUNK_DELTA (t));
632 dump_child ("init", DECL_INITIAL (t));
637 /* The fake `::std' namespace does not have DECL_LANG_SPECIFIC,
638 and therefore many other macros do not work on it. */
642 dump_child ("dcls", cp_namespace_decls (t));
647 dump_child ("spcs", DECL_TEMPLATE_SPECIALIZATIONS (t));
653 dump_child ("crnt", OVL_CURRENT (t));
654 dump_child ("chan", OVL_CHAIN (t));
660 if (ASM_VOLATILE_P (t))
661 dump_string (di, "volatile");
664 dump_child ("strg", ASM_STRING (t));
665 dump_child ("outs", ASM_OUTPUTS (t));
666 dump_child ("ins", ASM_INPUTS (t));
667 dump_child ("clbr", ASM_CLOBBERS (t));
669 dump_next_stmt (di, t);
675 dump_next_stmt (di, t);
679 /* Note that a case label is not like other statments; there is
680 no way to get the line-number of a case label. */
683 dump_child ("low", CASE_LOW (t));
684 dump_child ("high", CASE_HIGH (t));
686 dump_next_stmt (di, t);
692 dump_child ("body", COMPOUND_BODY (t));
693 dump_next_stmt (di, t);
699 dump_child ("decl", DECL_STMT_DECL (t));
700 dump_next_stmt (di, t);
707 dump_child ("body", DO_BODY (t));
708 dump_child ("cond", DO_COND (t));
710 dump_next_stmt (di, t);
716 dump_child ("expr", EXPR_STMT_EXPR (t));
717 dump_next_stmt (di, t);
724 dump_child ("init", FOR_INIT_STMT (t));
725 dump_child ("cond", FOR_COND (t));
726 dump_child ("expr", FOR_EXPR (t));
727 dump_child ("body", FOR_BODY (t));
729 dump_next_stmt (di, t);
735 dump_child ("dest", GOTO_DESTINATION (t));
736 dump_next_stmt (di, t);
743 dump_child ("cond", IF_COND (t));
744 dump_child ("then", THEN_CLAUSE (t));
745 dump_child ("else", ELSE_CLAUSE (t));
747 dump_next_stmt (di, t);
753 dump_child ("labl", LABEL_STMT_LABEL (t));
754 dump_next_stmt (di, t);
760 dump_child ("expr", RETURN_EXPR (t));
761 dump_next_stmt (di, t);
768 dump_child ("cond", SWITCH_COND (t));
769 dump_child ("body", SWITCH_BODY (t));
771 dump_next_stmt (di, t);
778 dump_child ("body", TRY_STMTS (t));
779 dump_child ("hdlr", TRY_HANDLERS (t));
781 dump_next_stmt (di, t);
788 dump_child ("cond", WHILE_COND (t));
789 dump_child ("body", WHILE_BODY (t));
791 dump_next_stmt (di, t);
797 dump_child ("clnp", TREE_OPERAND (t, 0));
798 dump_next_stmt (di, t);
801 case START_CATCH_STMT:
804 queue_and_dump_type (di, TREE_TYPE (t), /*dump_children_p=*/1);
805 dump_next_stmt (di, t);
812 dump_child ("decl", CLEANUP_DECL (t));
813 dump_child ("expr", CLEANUP_EXPR (t));
815 dump_next_stmt (di, t);
820 if (SCOPE_BEGIN_P (t))
821 dump_string (di, "begn");
823 dump_string (di, "end");
824 if (SCOPE_NULLIFIED_P (t))
825 dump_string (di, "null");
826 dump_next_stmt (di, t);
830 if (TREE_INT_CST_HIGH (t))
831 dump_int (di, "high", TREE_INT_CST_HIGH (t));
832 dump_int (di, "low", TREE_INT_CST_LOW (t));
836 fprintf (di->stream, "strg: %-7s ", TREE_STRING_POINTER (t));
837 dump_int (di, "lngt", TREE_STRING_LENGTH (t));
843 dump_child ("clas", PTRMEM_CST_CLASS (t));
844 dump_child ("mbr", PTRMEM_CST_MEMBER (t));
852 /* These nodes are unary, but do not have code class `1'. */
854 dump_child ("op 0", TREE_OPERAND (t, 0));
857 case TRUTH_ANDIF_EXPR:
858 case TRUTH_ORIF_EXPR:
865 /* These nodes are binary, but do not have code class `2'. */
868 dump_child ("op 0", TREE_OPERAND (t, 0));
869 dump_child ("op 1", TREE_OPERAND (t, 1));
876 dump_child ("fn", TREE_OPERAND (t, 0));
877 dump_child ("args", TREE_OPERAND (t, 1));
883 dump_child ("elts", TREE_OPERAND (t, 1));
888 dump_child ("stmt", STMT_EXPR_STMT (t));
894 dump_child ("decl", TREE_OPERAND (t, 0));
895 dump_child ("init", TREE_OPERAND (t, 1));
896 dump_child ("clnp", TREE_OPERAND (t, 2));
897 /* There really are two possible places the initializer can
898 be. After RTL expansion, the second operand is moved to
899 the position of the fourth operand, and the second
900 operand becomes NULL. */
901 dump_child ("init", TREE_OPERAND (t, 3));
906 dump_int (di, "ctor", AGGR_INIT_VIA_CTOR_P (t));
909 dump_child ("fn", TREE_OPERAND (t, 0));
910 dump_child ("args", TREE_OPERAND (t, 1));
911 dump_child ("decl", TREE_OPERAND (t, 2));
916 /* There are no additional fields to print. */
921 /* Terminate the line. */
922 fprintf (di->stream, "\n");
925 /* Dump T, and all its children, on STREAM. */
928 dump_node (t, stream)
934 dump_queue_p next_dq;
936 /* Initialize the dump-information structure. */
943 di.nodes = splay_tree_new (splay_tree_compare_pointers, 0,
944 (splay_tree_delete_value_fn) &free);
946 /* Queue up the first node. */
947 queue (&di, t, DUMP_CHILDREN);
949 /* Until the queue is empty, keep dumping nodes. */
951 dequeue_and_dump (&di);
954 for (dq = di.free_list; dq; dq = next_dq)
959 splay_tree_delete (di.nodes);
962 /* Dump T, and all its children, to FILE. */
965 dump_node_to_file (t, file)
971 f = fopen (file, "w");
973 cp_error ("could not open `%s'", file);