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. */
29 #include "splay-tree.h"
31 /* Flags used with queue functions. */
33 #define DUMP_CHILDREN 1
36 /* Information about a node to be dumped. */
38 typedef struct dump_node_info
40 /* The index for the node. */
42 /* Nonzero if we should dump the children of the node. */
43 unsigned int dump_children_p : 1;
44 /* Nonzero if the node is a binfo. */
45 unsigned int binfo_p : 1;
48 /* A dump_queue is a link in the queue of things to be dumped. */
50 typedef struct dump_queue
52 /* The queued tree node. */
54 /* The next node in the queue. */
55 struct dump_queue *next;
58 /* A dump_info gives information about how we should perform the dump
59 and about the current state of the dump. */
61 typedef struct dump_info
63 /* The stream on which to dump the information. */
65 /* The next unused node index. */
67 /* The next column. */
69 /* The first node in the queue of nodes to be written out. */
71 /* The last node in the queue. */
72 dump_queue_p queue_end;
73 /* Free queue nodes. */
74 dump_queue_p free_list;
75 /* The tree nodes which we have already written out. The
76 keys are the addresses of the nodes; the values are the integer
77 indices we assigned them. */
81 static unsigned int queue PROTO ((dump_info_p, tree, int));
82 static void dump_index PROTO ((dump_info_p, unsigned int));
83 static void queue_and_dump_index PROTO ((dump_info_p, const char *, tree, int));
84 static void queue_and_dump_type PROTO ((dump_info_p, tree, int));
85 static void dequeue_and_dump PROTO ((dump_info_p));
86 static void dump_new_line PROTO ((dump_info_p));
87 static void dump_maybe_newline PROTO ((dump_info_p));
88 static void dump_int PROTO ((dump_info_p, const char *, int));
89 static void dump_string PROTO ((dump_info_p, const char *));
90 static void dump_string_field PROTO ((dump_info_p, const char *, const char *));
91 static void dump_node PROTO ((tree, FILE *));
92 static void dump_stmt PROTO ((dump_info_p, tree));
94 /* Add T to the end of the queue of nodes to dump. If DUMP_CHILDREN_P
95 is non-zero, then its children should be dumped as well. Returns
96 the index assigned to T. */
105 dump_node_info_p dni;
108 /* Assign the next available index to T. */
111 /* Obtain a new queue node. */
115 di->free_list = dq->next;
118 dq = (dump_queue_p) xmalloc (sizeof (struct dump_queue));
120 /* Create a new entry in the splay-tree. */
121 dni = (dump_node_info_p) xmalloc (sizeof (struct dump_node_info));
123 dni->dump_children_p = ((flags & DUMP_CHILDREN) != 0);
124 dni->binfo_p = ((flags & DUMP_BINFO) != 0);
125 dq->node = splay_tree_insert (di->nodes, (splay_tree_key) t,
126 (splay_tree_value) dni);
128 /* Add it to the end of the queue. */
133 di->queue_end->next = dq;
136 /* Return the index. */
141 dump_index (di, index)
145 fprintf (di->stream, "@%-6u ", index);
149 /* If T has not already been output, queue it for subsequent output.
150 FIELD is a string to print before printing the index. Then, the
151 index of T is printed. */
154 queue_and_dump_index (di, field, t, flags)
163 /* If there's no node, just return. This makes for fewer checks in
168 /* See if we've already queued or dumped this node. */
169 n = splay_tree_lookup (di->nodes, (splay_tree_key) t);
171 index = ((dump_node_info_p) n->value)->index;
173 /* If we haven't, add it to the queue. */
174 index = queue (di, t, flags);
176 /* Print the index of the node. */
177 dump_maybe_newline (di);
178 fprintf (di->stream, "%-4s: ", field);
180 dump_index (di, index);
183 /* Dump the type of T. */
186 queue_and_dump_type (di, t, dump_children_p)
191 queue_and_dump_index (di, "type", TREE_TYPE (t), dump_children_p);
194 /* Insert a new line in the dump output, and indent to an appropriate
195 place to start printing more fields. */
201 fprintf (di->stream, "\n%25s", "");
205 /* If necessary, insert a new line. */
208 dump_maybe_newline (di)
211 /* See if we need a new line. */
214 /* See if we need any padding. */
215 else if ((di->column - 25) % 14 != 0)
217 fprintf (di->stream, "%*s", 14 - ((di->column - 25) % 14), "");
218 di->column += 14 - (di->column - 25) % 14;
222 /* Dump I using FIELD to identity it. */
225 dump_int (di, field, i)
230 dump_maybe_newline (di);
231 fprintf (di->stream, "%-4s: %-7d ", field, i);
235 /* Dump the string S. */
238 dump_string (di, string)
242 dump_maybe_newline (di);
243 fprintf (di->stream, "%-13s ", string);
244 if (strlen (string) > 13)
245 di->column += strlen (string) + 1;
250 /* Dump the string field S. */
253 dump_string_field (di, field, string)
258 dump_maybe_newline (di);
259 fprintf (di->stream, "%-4s: %-7s ", field, string);
260 if (strlen (string) > 7)
261 di->column += 6 + strlen (string) + 1;
266 /* Dump information common to statements from STMT. */
273 dump_int (di, "line", STMT_LINENO (t));
276 /* Dump the CHILD and its children. */
277 #define dump_child(field, child) \
278 queue_and_dump_index (di, field, child, DUMP_CHILDREN)
280 /* Dump the next node in the queue. */
283 dequeue_and_dump (di)
288 dump_node_info_p dni;
294 const char* code_name;
296 /* Get the next node from the queue. */
300 dni = (dump_node_info_p) stn->value;
302 dump_children_p = dni->dump_children_p;
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");
340 dump_child ("type", BINFO_TYPE (t));
341 dump_child ("base", BINFO_BASETYPES (t));
347 /* We can knock off a bunch of expression nodes in exactly the same
349 if (IS_EXPR_CODE_CLASS (code_class))
351 /* If we're dumping children, dump them now. */
354 queue_and_dump_type (di, t, 1);
359 dump_child ("op 0", TREE_OPERAND (t, 0));
364 dump_child ("op 0", TREE_OPERAND (t, 0));
365 dump_child ("op 1", TREE_OPERAND (t, 1));
369 /* These nodes are handled explicitly below. */
373 my_friendly_abort (19990726);
377 else if (code_class == 'd')
379 /* All declarations have names. */
381 dump_child ("name", DECL_NAME (t));
385 queue_and_dump_type (di, t, 1);
386 queue_and_dump_index (di, "scpe", DECL_CONTEXT (t), 0);
388 /* And a source position. */
389 if (DECL_SOURCE_FILE (t))
391 const char *filename = rindex (DECL_SOURCE_FILE (t), '/');
393 filename = DECL_SOURCE_FILE (t);
395 /* Skip the slash. */
398 dump_maybe_newline (di);
399 fprintf (di->stream, "srcp: %s:%-6d ", filename,
400 DECL_SOURCE_LINE (t));
401 di->column += 6 + strlen (filename) + 8;
403 /* And any declaration can be compiler-generated. */
404 if (DECL_ARTIFICIAL (t))
405 dump_string (di, "artificial");
407 dump_child ("chan", TREE_CHAIN (t));
409 else if (code_class == 't')
411 /* All types have qualifiers. */
412 int quals = CP_TYPE_QUALS (t);
413 if (quals != TYPE_UNQUALIFIED)
415 fprintf (di->stream, "qual: %c%c%c ",
416 (quals & TYPE_QUAL_CONST) ? 'c' : ' ',
417 (quals & TYPE_QUAL_VOLATILE) ? 'v' : ' ',
418 (quals & TYPE_QUAL_RESTRICT) ? 'r' : ' ');
422 /* All types have associated declarations. */
423 dump_child ("name", TYPE_NAME (t));
427 /* All types have a main variant. */
428 if (TYPE_MAIN_VARIANT (t) != t)
429 dump_child ("unql", TYPE_MAIN_VARIANT (t));
432 dump_child ("size", TYPE_SIZE (t));
435 /* All types have alignments. */
436 dump_int (di, "algn", TYPE_ALIGN (t));
439 /* Now handle the various kinds of nodes. */
444 case IDENTIFIER_NODE:
445 if (IDENTIFIER_OPNAME_P (t))
446 dump_string (di, "operator");
447 else if (IDENTIFIER_TYPENAME_P (t))
448 queue_and_dump_index (di, "tynm", TREE_TYPE (t), 0);
449 else if (t == anonymous_namespace_name)
450 dump_string (di, "unnamed");
453 dump_string_field (di, "strg", IDENTIFIER_POINTER (t));
454 dump_int (di, "lngt", IDENTIFIER_LENGTH (t));
461 dump_child ("purp", TREE_PURPOSE (t));
462 dump_child ("valu", TREE_VALUE (t));
463 dump_child ("chan", TREE_CHAIN (t));
468 dump_int (di, "lngt", IDENTIFIER_LENGTH (t));
470 for (i = 0; i < TREE_VEC_LENGTH (t); ++i)
473 sprintf (buffer, "%u", i);
474 queue_and_dump_index (di, buffer, TREE_VEC_ELT (t, i), 1);
480 dump_int (di, "prec", TYPE_PRECISION (t));
481 if (TREE_UNSIGNED (t))
482 dump_string (di, "unsigned");
485 dump_child ("min", TYPE_MIN_VALUE (t));
486 dump_child ("max", TYPE_MAX_VALUE (t));
489 if (code == ENUMERAL_TYPE && dump_children_p)
490 dump_child ("csts", TYPE_VALUES (t));
494 dump_int (di, "prec", TYPE_PRECISION (t));
500 if (TYPE_PTRMEM_P (t))
502 dump_string (di, "ptrmem");
503 queue_and_dump_index (di, "ptd",
504 TYPE_PTRMEM_POINTED_TO_TYPE (t), 1);
505 queue_and_dump_index (di, "cls",
506 TYPE_PTRMEM_CLASS_TYPE (t), 1);
509 dump_child ("ptd", TREE_TYPE (t));
515 dump_child ("refd", TREE_TYPE (t));
520 dump_child ("clas", TYPE_METHOD_BASETYPE (t));
526 dump_child ("retn", TREE_TYPE (t));
527 dump_child ("prms", TYPE_ARG_TYPES (t));
534 dump_child ("elts", TREE_TYPE (t));
535 dump_child ("domn", TYPE_DOMAIN (t));
541 if (TYPE_PTRMEMFUNC_P (t))
543 dump_string (di, "ptrmem");
544 queue_and_dump_index (di, "ptd",
545 TYPE_PTRMEM_POINTED_TO_TYPE (t), 1);
546 queue_and_dump_index (di, "cls",
547 TYPE_PTRMEM_CLASS_TYPE (t), 1);
551 if (CLASSTYPE_DECLARED_CLASS (t))
552 dump_string (di, "class");
553 else if (TREE_CODE (t) == RECORD_TYPE)
554 dump_string (di, "struct");
556 dump_string (di, "union");
560 dump_child ("flds", TYPE_FIELDS (t));
561 dump_child ("fncs", TYPE_METHODS (t));
562 queue_and_dump_index (di, "binf", TYPE_BINFO (t),
563 DUMP_CHILDREN | DUMP_BINFO);
570 dump_child ("cnst", DECL_INITIAL (t));
578 dump_child ("init", DECL_INITIAL (t));
579 dump_child ("size", DECL_SIZE (t));
581 dump_int (di, "algn", DECL_ALIGN (t));
583 if (TREE_CODE (t) == FIELD_DECL && dump_children_p)
584 dump_child ("bpos", DECL_FIELD_BITPOS (t));
590 queue_and_dump_index (di, "scpe", DECL_REAL_CONTEXT (t), 0);
591 dump_child ("mngl", DECL_ASSEMBLER_NAME (t));
592 dump_child ("args", DECL_ARGUMENTS (t));
595 dump_string(di, "extern");
597 dump_string (di, "static");
598 if (DECL_FUNCTION_MEMBER_P (t))
599 dump_string (di, "member");
600 if (DECL_CONSTRUCTOR_P (t))
601 dump_string (di, "constructor");
602 if (DECL_DESTRUCTOR_P (t))
603 dump_string (di, "destructor");
604 if (DECL_OVERLOADED_OPERATOR_P (t))
605 dump_string (di, "operator");
606 if (DECL_CONV_FN_P (t))
607 dump_string (di, "conversion");
609 dump_child ("body", DECL_INITIAL (t));
613 /* The fake `::std' namespace does not have DECL_LANG_SPECIFIC,
614 and therefore many other macros do not work on it. */
618 dump_child ("dcls", cp_namespace_decls (t));
624 dump_child ("crnt", OVL_CURRENT (t));
625 dump_child ("chan", OVL_CHAIN (t));
631 if (ASM_VOLATILE_P (t))
632 dump_string (di, "volatile");
635 dump_child ("strg", ASM_STRING (t));
636 dump_child ("outs", ASM_OUTPUTS (t));
637 dump_child ("ins", ASM_INPUTS (t));
638 dump_child ("clbr", ASM_CLOBBERS (t));
648 /* Note that a case label is not like other statments; there is
649 no way to get the line-number of a case label. */
652 dump_child ("low", CASE_LOW (t));
653 dump_child ("high", CASE_HIGH (t));
660 dump_child ("body", COMPOUND_BODY (t));
666 dump_child ("decl", DECL_STMT_DECL (t));
673 dump_child ("body", DO_BODY (t));
674 dump_child ("cond", DO_COND (t));
681 dump_child ("expr", EXPR_STMT_EXPR (t));
688 dump_child ("init", FOR_INIT_STMT (t));
689 dump_child ("cond", FOR_COND (t));
690 dump_child ("expr", FOR_EXPR (t));
691 dump_child ("body", FOR_BODY (t));
698 dump_child ("dest", GOTO_DESTINATION (t));
705 dump_child ("cond", IF_COND (t));
706 dump_child ("then", THEN_CLAUSE (t));
707 dump_child ("else", ELSE_CLAUSE (t));
714 dump_child ("expr", RETURN_EXPR (t));
721 dump_child ("cond", SWITCH_COND (t));
722 dump_child ("body", SWITCH_BODY (t));
730 dump_child ("body", TRY_STMTS (t));
731 dump_child ("hdlr", TRY_HANDLERS (t));
739 dump_child ("cond", WHILE_COND (t));
740 dump_child ("body", WHILE_BODY (t));
745 if (TREE_INT_CST_HIGH (t))
746 dump_int (di, "high", TREE_INT_CST_HIGH (t));
747 dump_int (di, "low", TREE_INT_CST_LOW (t));
751 fprintf (di->stream, "strg: %-7s ", TREE_STRING_POINTER (t));
752 dump_int (di, "lngt", TREE_STRING_LENGTH (t));
758 dump_child ("clas", PTRMEM_CST_CLASS (t));
759 dump_child ("mbr", PTRMEM_CST_MEMBER (t));
767 /* These nodes are unary, but do not have code class `1'. */
769 dump_child ("op 0", TREE_OPERAND (t, 0));
772 case TRUTH_ANDIF_EXPR:
773 case TRUTH_ORIF_EXPR:
778 /* These nodes are binary, but do not have code class `2'. */
781 dump_child ("op 0", TREE_OPERAND (t, 0));
782 dump_child ("op 1", TREE_OPERAND (t, 1));
789 dump_child ("fn", TREE_OPERAND (t, 0));
790 dump_child ("args", TREE_OPERAND (t, 1));
796 dump_child ("elts", TREE_OPERAND (t, 1));
800 /* There are no additional fields to print. */
805 /* Terminate the line. */
806 fprintf (di->stream, "\n");
809 /* Dump T, and all its children, on STREAM. */
812 dump_node (t, stream)
818 dump_queue_p next_dq;
820 /* Initialize the dump-information structure. */
827 di.nodes = splay_tree_new (splay_tree_compare_pointers, 0,
828 (splay_tree_delete_value_fn) &free);
830 /* Queue up the first node. */
831 queue (&di, t, DUMP_CHILDREN);
833 /* Until the queue is empty, keep dumping nodes. */
835 dequeue_and_dump (&di);
838 for (dq = di.free_list; dq; dq = next_dq)
843 splay_tree_delete (di.nodes);
846 /* Dump T, and all its children, to FILE. */
849 dump_node_to_file (t, file)
855 f = fopen (file, "w");
857 cp_error ("could not open `%s'", file);