1 /* Tree-dumping functionality for intermediate representation.
2 Copyright (C) 1999, 2000 Free Software Foundation, Inc.
3 Written by Mark Mitchell <mark@codesourcery.com>
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING. If not, write to the Free
19 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
26 #include "splay-tree.h"
27 #include "diagnostic.h"
31 /* A callback function used dump language-specific parts of tree
32 nodes. Returns non-zero if it does not want the usual dumping of
33 the second argument. */
35 dump_tree_fn lang_dump_tree;
37 static unsigned int queue PARAMS ((dump_info_p, tree, int));
38 static void dump_index PARAMS ((dump_info_p, unsigned int));
39 static void dequeue_and_dump PARAMS ((dump_info_p));
40 static void dump_new_line PARAMS ((dump_info_p));
41 static void dump_maybe_newline PARAMS ((dump_info_p));
42 static void dump_string_field PARAMS ((dump_info_p, const char *, const char *));
44 /* Add T to the end of the queue of nodes to dump. Returns the index
57 /* Assign the next available index to T. */
60 /* Obtain a new queue node. */
64 di->free_list = dq->next;
67 dq = (dump_queue_p) xmalloc (sizeof (struct dump_queue));
69 /* Create a new entry in the splay-tree. */
70 dni = (dump_node_info_p) xmalloc (sizeof (struct dump_node_info));
72 dni->binfo_p = ((flags & DUMP_BINFO) != 0);
73 dq->node = splay_tree_insert (di->nodes, (splay_tree_key) t,
74 (splay_tree_value) dni);
76 /* Add it to the end of the queue. */
81 di->queue_end->next = dq;
84 /* Return the index. */
89 dump_index (di, index)
93 fprintf (di->stream, "@%-6u ", index);
97 /* If T has not already been output, queue it for subsequent output.
98 FIELD is a string to print before printing the index. Then, the
99 index of T is printed. */
102 queue_and_dump_index (di, field, t, flags)
111 /* If there's no node, just return. This makes for fewer checks in
116 /* See if we've already queued or dumped this node. */
117 n = splay_tree_lookup (di->nodes, (splay_tree_key) t);
119 index = ((dump_node_info_p) n->value)->index;
121 /* If we haven't, add it to the queue. */
122 index = queue (di, t, flags);
124 /* Print the index of the node. */
125 dump_maybe_newline (di);
126 fprintf (di->stream, "%-4s: ", field);
128 dump_index (di, index);
131 /* Dump the type of T. */
134 queue_and_dump_type (di, t)
138 queue_and_dump_index (di, "type", TREE_TYPE (t), DUMP_NONE);
141 /* Dump column control */
142 #define SOL_COLUMN 25 /* Start of line column. */
143 #define EOL_COLUMN 55 /* End of line column. */
144 #define COLUMN_ALIGNMENT 15 /* Alignment. */
146 /* Insert a new line in the dump output, and indent to an appropriate
147 place to start printing more fields. */
153 fprintf (di->stream, "\n%*s", SOL_COLUMN, "");
154 di->column = SOL_COLUMN;
157 /* If necessary, insert a new line. */
160 dump_maybe_newline (di)
165 /* See if we need a new line. */
166 if (di->column > EOL_COLUMN)
168 /* See if we need any padding. */
169 else if ((extra = (di->column - SOL_COLUMN) % COLUMN_ALIGNMENT) != 0)
171 fprintf (di->stream, "%*s", COLUMN_ALIGNMENT - extra, "");
172 di->column += COLUMN_ALIGNMENT - extra;
176 /* Dump pointer PTR using FIELD to identify it. */
179 dump_pointer (di, field, ptr)
184 dump_maybe_newline (di);
185 fprintf (di->stream, "%-4s: %-8lx ", field, (long) ptr);
189 /* Dump integer I using FIELD to identify it. */
192 dump_int (di, field, i)
197 dump_maybe_newline (di);
198 fprintf (di->stream, "%-4s: %-7d ", field, i);
202 /* Dump the string S. */
205 dump_string (di, string)
209 dump_maybe_newline (di);
210 fprintf (di->stream, "%-13s ", string);
211 if (strlen (string) > 13)
212 di->column += strlen (string) + 1;
217 /* Dump the string field S. */
220 dump_string_field (di, field, string)
225 dump_maybe_newline (di);
226 fprintf (di->stream, "%-4s: %-7s ", field, string);
227 if (strlen (string) > 7)
228 di->column += 6 + strlen (string) + 1;
233 /* Dump information common to statements from STMT. */
240 dump_int (di, "line", STMT_LINENO (t));
243 /* Dump the next statement after STMT. */
246 dump_next_stmt (di, t)
250 dump_child ("next", TREE_CHAIN (t));
253 /* Dump the next node in the queue. */
256 dequeue_and_dump (di)
261 dump_node_info_p dni;
266 const char* code_name;
268 /* Get the next node from the queue. */
272 dni = (dump_node_info_p) stn->value;
275 /* Remove the node from the queue, and put it on the free list. */
276 di->queue = dq->next;
279 dq->next = di->free_list;
282 /* Print the node index. */
283 dump_index (di, index);
284 /* And the type of node this is. */
288 code_name = tree_code_name[(int) TREE_CODE (t)];
289 fprintf (di->stream, "%-16s ", code_name);
292 /* Figure out what kind of node this is. */
293 code = TREE_CODE (t);
294 code_class = TREE_CODE_CLASS (code);
296 /* Although BINFOs are TREE_VECs, we dump them specially so as to be
300 if (TREE_VIA_PUBLIC (t))
301 dump_string (di, "pub");
302 else if (TREE_VIA_PROTECTED (t))
303 dump_string (di, "prot");
304 else if (TREE_VIA_PRIVATE (t))
305 dump_string (di, "priv");
306 if (TREE_VIA_VIRTUAL (t))
307 dump_string (di, "virt");
309 dump_child ("type", BINFO_TYPE (t));
310 dump_child ("base", BINFO_BASETYPES (t));
315 /* We can knock off a bunch of expression nodes in exactly the same
317 if (IS_EXPR_CODE_CLASS (code_class))
319 /* If we're dumping children, dump them now. */
320 queue_and_dump_type (di, t);
325 dump_child ("op 0", TREE_OPERAND (t, 0));
330 dump_child ("op 0", TREE_OPERAND (t, 0));
331 dump_child ("op 1", TREE_OPERAND (t, 1));
335 /* These nodes are handled explicitly below. */
344 /* All declarations have names. */
346 dump_child ("name", DECL_NAME (t));
347 if (DECL_ASSEMBLER_NAME_SET_P (t)
348 && DECL_ASSEMBLER_NAME (t) != DECL_NAME (t))
349 dump_child ("mngl", DECL_ASSEMBLER_NAME (t));
351 queue_and_dump_type (di, t);
352 dump_child ("scpe", DECL_CONTEXT (t));
353 /* And a source position. */
354 if (DECL_SOURCE_FILE (t))
356 const char *filename = strrchr (DECL_SOURCE_FILE (t), '/');
358 filename = DECL_SOURCE_FILE (t);
360 /* Skip the slash. */
363 dump_maybe_newline (di);
364 fprintf (di->stream, "srcp: %s:%-6d ", filename,
365 DECL_SOURCE_LINE (t));
366 di->column += 6 + strlen (filename) + 8;
368 /* And any declaration can be compiler-generated. */
369 if (DECL_ARTIFICIAL (t))
370 dump_string (di, "artificial");
371 if (TREE_CHAIN (t) && !dump_flag (di, TDF_SLIM, NULL))
372 dump_child ("chan", TREE_CHAIN (t));
374 else if (code_class == 't')
376 /* All types have qualifiers. */
377 int quals = C_TYPE_QUALS (t);
378 if (quals != TYPE_UNQUALIFIED)
380 fprintf (di->stream, "qual: %c%c%c ",
381 (quals & TYPE_QUAL_CONST) ? 'c' : ' ',
382 (quals & TYPE_QUAL_VOLATILE) ? 'v' : ' ',
383 (quals & TYPE_QUAL_RESTRICT) ? 'r' : ' ');
387 /* All types have associated declarations. */
388 dump_child ("name", TYPE_NAME (t));
390 /* All types have a main variant. */
391 if (TYPE_MAIN_VARIANT (t) != t)
392 dump_child ("unql", TYPE_MAIN_VARIANT (t));
395 dump_child ("size", TYPE_SIZE (t));
397 /* All types have alignments. */
398 dump_int (di, "algn", TYPE_ALIGN (t));
400 else if (code_class == 'c')
401 /* All constants can have types. */
402 queue_and_dump_type (di, t);
404 /* Give the language-specific code a chance to print something. If
405 it's completely taken care of things, don't bother printing
406 anything more ourselves. */
407 if (lang_dump_tree && (*lang_dump_tree) (di, t))
410 /* Now handle the various kinds of nodes. */
415 case IDENTIFIER_NODE:
416 dump_string_field (di, "strg", IDENTIFIER_POINTER (t));
417 dump_int (di, "lngt", IDENTIFIER_LENGTH (t));
421 dump_child ("purp", TREE_PURPOSE (t));
422 dump_child ("valu", TREE_VALUE (t));
423 dump_child ("chan", TREE_CHAIN (t));
427 dump_int (di, "lngt", TREE_VEC_LENGTH (t));
428 for (i = 0; i < TREE_VEC_LENGTH (t); ++i)
431 sprintf (buffer, "%u", i);
432 dump_child (buffer, TREE_VEC_ELT (t, i));
438 dump_int (di, "prec", TYPE_PRECISION (t));
439 if (TREE_UNSIGNED (t))
440 dump_string (di, "unsigned");
441 dump_child ("min", TYPE_MIN_VALUE (t));
442 dump_child ("max", TYPE_MAX_VALUE (t));
444 if (code == ENUMERAL_TYPE)
445 dump_child ("csts", TYPE_VALUES (t));
449 dump_int (di, "prec", TYPE_PRECISION (t));
453 dump_child ("ptd", TREE_TYPE (t));
457 dump_child ("refd", TREE_TYPE (t));
461 dump_child ("clas", TYPE_METHOD_BASETYPE (t));
465 dump_child ("retn", TREE_TYPE (t));
466 dump_child ("prms", TYPE_ARG_TYPES (t));
470 dump_child ("elts", TREE_TYPE (t));
471 dump_child ("domn", TYPE_DOMAIN (t));
476 if (TREE_CODE (t) == RECORD_TYPE)
477 dump_string (di, "struct");
479 dump_string (di, "union");
481 dump_child ("flds", TYPE_FIELDS (t));
482 dump_child ("fncs", TYPE_METHODS (t));
483 queue_and_dump_index (di, "binf", TYPE_BINFO (t),
488 dump_child ("cnst", DECL_INITIAL (t));
495 if (TREE_CODE (t) == PARM_DECL)
496 dump_child ("argt", DECL_ARG_TYPE (t));
498 dump_child ("init", DECL_INITIAL (t));
499 dump_child ("size", DECL_SIZE (t));
500 dump_int (di, "algn", DECL_ALIGN (t));
502 if (TREE_CODE (t) == FIELD_DECL)
504 if (DECL_C_BIT_FIELD (t))
505 dump_string (di, "bitfield");
506 if (DECL_FIELD_OFFSET (t))
507 dump_child ("bpos", bit_position (t));
509 else if (TREE_CODE (t) == VAR_DECL
510 || TREE_CODE (t) == PARM_DECL)
512 dump_int (di, "used", TREE_USED (t));
513 if (DECL_REGISTER (t))
514 dump_string (di, "register");
519 dump_child ("args", DECL_ARGUMENTS (t));
520 if (DECL_EXTERNAL (t))
521 dump_string (di, "undefined");
523 dump_string (di, "extern");
525 dump_string (di, "static");
526 if (DECL_LANG_SPECIFIC (t) && !dump_flag (di, TDF_SLIM, t))
527 dump_child ("body", DECL_SAVED_TREE (t));
532 if (ASM_VOLATILE_P (t))
533 dump_string (di, "volatile");
534 dump_child ("strg", ASM_STRING (t));
535 dump_child ("outs", ASM_OUTPUTS (t));
536 dump_child ("ins", ASM_INPUTS (t));
537 dump_child ("clbr", ASM_CLOBBERS (t));
538 dump_next_stmt (di, t);
544 dump_next_stmt (di, t);
548 /* Note that a case label is not like other statments; there is
549 no way to get the line-number of a case label. */
550 dump_child ("low", CASE_LOW (t));
551 dump_child ("high", CASE_HIGH (t));
552 dump_next_stmt (di, t);
557 dump_child ("body", COMPOUND_BODY (t));
558 dump_next_stmt (di, t);
563 dump_child ("decl", DECL_STMT_DECL (t));
564 dump_next_stmt (di, t);
569 dump_child ("body", DO_BODY (t));
570 dump_child ("cond", DO_COND (t));
571 dump_next_stmt (di, t);
576 dump_child ("expr", EXPR_STMT_EXPR (t));
577 dump_next_stmt (di, t);
582 dump_child ("init", FOR_INIT_STMT (t));
583 dump_child ("cond", FOR_COND (t));
584 dump_child ("expr", FOR_EXPR (t));
585 dump_child ("body", FOR_BODY (t));
586 dump_next_stmt (di, t);
591 dump_child ("dest", GOTO_DESTINATION (t));
592 dump_next_stmt (di, t);
597 dump_child ("cond", IF_COND (t));
598 dump_child ("then", THEN_CLAUSE (t));
599 dump_child ("else", ELSE_CLAUSE (t));
600 dump_next_stmt (di, t);
605 dump_child ("labl", LABEL_STMT_LABEL (t));
606 dump_next_stmt (di, t);
611 dump_child ("expr", RETURN_EXPR (t));
612 dump_next_stmt (di, t);
617 dump_child ("cond", SWITCH_COND (t));
618 dump_child ("body", SWITCH_BODY (t));
619 dump_next_stmt (di, t);
624 dump_child ("cond", WHILE_COND (t));
625 dump_child ("body", WHILE_BODY (t));
626 dump_next_stmt (di, t);
631 if (SCOPE_BEGIN_P (t))
632 dump_string (di, "begn");
634 dump_string (di, "end");
635 if (SCOPE_NULLIFIED_P (t))
636 dump_string (di, "null");
637 if (!SCOPE_NO_CLEANUPS_P (t))
638 dump_string (di, "clnp");
639 dump_next_stmt (di, t);
643 if (TREE_INT_CST_HIGH (t))
644 dump_int (di, "high", TREE_INT_CST_HIGH (t));
645 dump_int (di, "low", TREE_INT_CST_LOW (t));
649 fprintf (di->stream, "strg: %-7s ", TREE_STRING_POINTER (t));
650 dump_int (di, "lngt", TREE_STRING_LENGTH (t));
656 case CLEANUP_POINT_EXPR:
658 /* These nodes are unary, but do not have code class `1'. */
659 dump_child ("op 0", TREE_OPERAND (t, 0));
662 case TRUTH_ANDIF_EXPR:
663 case TRUTH_ORIF_EXPR:
669 case PREDECREMENT_EXPR:
670 case PREINCREMENT_EXPR:
671 case POSTDECREMENT_EXPR:
672 case POSTINCREMENT_EXPR:
673 /* These nodes are binary, but do not have code class `2'. */
674 dump_child ("op 0", TREE_OPERAND (t, 0));
675 dump_child ("op 1", TREE_OPERAND (t, 1));
679 dump_child ("op 0", TREE_OPERAND (t, 0));
680 dump_child ("op 1", TREE_OPERAND (t, 1));
681 dump_child ("op 2", TREE_OPERAND (t, 2));
685 dump_child ("fn", TREE_OPERAND (t, 0));
686 dump_child ("args", TREE_OPERAND (t, 1));
690 dump_child ("elts", TREE_OPERAND (t, 1));
694 dump_child ("stmt", STMT_EXPR_STMT (t));
698 dump_child ("vars", TREE_OPERAND (t, 0));
699 dump_child ("body", TREE_OPERAND (t, 1));
703 dump_child ("body", TREE_OPERAND (t, 0));
707 dump_child ("cond", TREE_OPERAND (t, 0));
711 dump_child ("decl", TREE_OPERAND (t, 0));
712 dump_child ("init", TREE_OPERAND (t, 1));
713 dump_child ("clnp", TREE_OPERAND (t, 2));
714 /* There really are two possible places the initializer can be.
715 After RTL expansion, the second operand is moved to the
716 position of the fourth operand, and the second operand
718 dump_child ("init", TREE_OPERAND (t, 3));
721 case EXPR_WITH_FILE_LOCATION:
722 dump_child ("expr", EXPR_WFL_NODE (t));
726 /* There are no additional fields to print. */
731 if (dump_flag (di, TDF_ADDRESS, NULL))
732 dump_pointer (di, "addr", (void *)t);
734 /* Terminate the line. */
735 fprintf (di->stream, "\n");
738 /* Return non-zero if FLAG has been specified for the dump, and NODE
739 is not the root node of the dump. */
741 int dump_flag (di, flag, node)
746 return (di->flags & flag) && (node != di->node);
749 /* Dump T, and all its children, on STREAM. */
752 dump_node (t, flags, stream)
759 dump_queue_p next_dq;
761 /* Initialize the dump-information structure. */
770 di.nodes = splay_tree_new (splay_tree_compare_pointers, 0,
771 (splay_tree_delete_value_fn) &free);
773 /* Queue up the first node. */
774 queue (&di, t, DUMP_NONE);
776 /* Until the queue is empty, keep dumping nodes. */
778 dequeue_and_dump (&di);
781 for (dq = di.free_list; dq; dq = next_dq)
786 splay_tree_delete (di.nodes);
789 /* Define a tree dump switch. */
790 struct dump_file_info
792 const char *suffix; /* suffix to give output file. */
793 const char *swtch; /* command line switch */
794 int flags; /* user flags */
795 int state; /* state of play */
798 /* Table of tree dump switches. This must be consistent with the
799 TREE_DUMP_INDEX enumeration in c-common.h */
800 static struct dump_file_info dump_files[TDI_end] =
802 {".tu", "dump-translation-unit", 0, 0},
803 {".class", "dump-class-hierarchy", 0, 0},
804 {".original", "dump-tree-original", 0, 0},
805 {".optimized", "dump-tree-optimized", 0, 0},
806 {".inlined", "dump-tree-inlined", 0, 0},
809 /* Define a name->number mapping for a dump flag value. */
810 struct dump_option_value_info
812 const char *const name; /* the name of the value */
813 const int value; /* the value of the name */
816 /* Table of dump options. This must be consistent with the TDF_* flags
818 static const struct dump_option_value_info dump_options[] =
820 {"address", TDF_ADDRESS},
826 /* Begin a tree dump for PHASE. Stores any user supplied flag in
827 *FLAG_PTR and returns a stream to write to. If the dump is not
828 enabled, returns NULL.
829 Multiple calls will reopen and append to the dump file. */
832 dump_begin (phase, flag_ptr)
833 enum tree_dump_index phase;
839 if (!dump_files[phase].state)
842 name = concat (dump_base_name, dump_files[phase].suffix, NULL);
843 stream = fopen (name, dump_files[phase].state < 0 ? "w" : "a");
845 error ("could not open dump file `%s'", name);
847 dump_files[phase].state = 1;
850 *flag_ptr = dump_files[phase].flags;
855 /* Returns non-zero if tree dump PHASE is enabled. */
858 dump_enabled_p (phase)
859 enum tree_dump_index phase;
861 return dump_files[phase].state;
864 /* Returns the switch name of PHASE. */
867 dump_flag_name (phase)
868 enum tree_dump_index phase;
870 return dump_files[phase].swtch;
873 /* Finish a tree dump for PHASE. STREAM is the stream created by
877 dump_end (phase, stream)
878 enum tree_dump_index phase ATTRIBUTE_UNUSED;
884 /* Parse ARG as a dump switch. Return non-zero if it is, and store the
885 relevant details in the dump_files array. */
892 const char *option_value;
894 for (ix = 0; ix != TDI_end; ix++)
895 if ((option_value = skip_leading_substring (arg, dump_files[ix].swtch)))
897 const char *ptr = option_value;
902 const struct dump_option_value_info *option_ptr;
908 end_ptr = strchr (ptr, '-');
910 end_ptr = ptr + strlen (ptr);
911 length = end_ptr - ptr;
913 for (option_ptr = dump_options; option_ptr->name;
915 if (strlen (option_ptr->name) == length
916 && !memcmp (option_ptr->name, ptr, length))
918 flags |= option_ptr->value;
921 warning ("ignoring unknown option `%.*s' in `-f%s'",
922 length, ptr, dump_files[ix].swtch);
927 dump_files[ix].state = -1;
928 dump_files[ix].flags = flags;