1 /* Tree-dumping functionality for intermediate representation.
2 Copyright (C) 1999-2015 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 3, 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 COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
23 #include "coretypes.h"
28 #include "double-int.h"
36 #include "fixed-value.h"
37 #include "splay-tree.h"
38 #include "filenames.h"
39 #include "tree-dump.h"
40 #include "langhooks.h"
41 #include "tree-iterator.h"
42 #include "tree-pretty-print.h"
44 #include "wide-int-print.h"
46 static unsigned int queue (dump_info_p
, const_tree
, int);
47 static void dump_index (dump_info_p
, unsigned int);
48 static void dequeue_and_dump (dump_info_p
);
49 static void dump_new_line (dump_info_p
);
50 static void dump_maybe_newline (dump_info_p
);
52 /* Add T to the end of the queue of nodes to dump. Returns the index
56 queue (dump_info_p di
, const_tree t
, int flags
)
62 /* Assign the next available index to T. */
65 /* Obtain a new queue node. */
69 di
->free_list
= dq
->next
;
72 dq
= XNEW (struct dump_queue
);
74 /* Create a new entry in the splay-tree. */
75 dni
= XNEW (struct dump_node_info
);
77 dni
->binfo_p
= ((flags
& DUMP_BINFO
) != 0);
78 dq
->node
= splay_tree_insert (di
->nodes
, (splay_tree_key
) t
,
79 (splay_tree_value
) dni
);
81 /* Add it to the end of the queue. */
86 di
->queue_end
->next
= dq
;
89 /* Return the index. */
94 dump_index (dump_info_p di
, unsigned int index
)
96 fprintf (di
->stream
, "@%-6u ", index
);
100 /* If T has not already been output, queue it for subsequent output.
101 FIELD is a string to print before printing the index. Then, the
102 index of T is printed. */
105 queue_and_dump_index (dump_info_p di
, const char *field
, const_tree t
, int flags
)
110 /* If there's no node, just return. This makes for fewer checks in
115 /* See if we've already queued or dumped this node. */
116 n
= splay_tree_lookup (di
->nodes
, (splay_tree_key
) t
);
118 index
= ((dump_node_info_p
) n
->value
)->index
;
120 /* If we haven't, add it to the queue. */
121 index
= queue (di
, t
, flags
);
123 /* Print the index of the node. */
124 dump_maybe_newline (di
);
125 fprintf (di
->stream
, "%-4s: ", field
);
127 dump_index (di
, index
);
130 /* Dump the type of T. */
133 queue_and_dump_type (dump_info_p di
, const_tree t
)
135 queue_and_dump_index (di
, "type", TREE_TYPE (t
), DUMP_NONE
);
138 /* Dump column control */
139 #define SOL_COLUMN 25 /* Start of line column. */
140 #define EOL_COLUMN 55 /* End of line column. */
141 #define COLUMN_ALIGNMENT 15 /* Alignment. */
143 /* Insert a new line in the dump output, and indent to an appropriate
144 place to start printing more fields. */
147 dump_new_line (dump_info_p di
)
149 fprintf (di
->stream
, "\n%*s", SOL_COLUMN
, "");
150 di
->column
= SOL_COLUMN
;
153 /* If necessary, insert a new line. */
156 dump_maybe_newline (dump_info_p di
)
160 /* See if we need a new line. */
161 if (di
->column
> EOL_COLUMN
)
163 /* See if we need any padding. */
164 else if ((extra
= (di
->column
- SOL_COLUMN
) % COLUMN_ALIGNMENT
) != 0)
166 fprintf (di
->stream
, "%*s", COLUMN_ALIGNMENT
- extra
, "");
167 di
->column
+= COLUMN_ALIGNMENT
- extra
;
171 /* Dump FUNCTION_DECL FN as tree dump PHASE. */
174 dump_function (int phase
, tree fn
)
179 stream
= dump_begin (phase
, &flags
);
182 dump_function_to_file (fn
, stream
, flags
);
183 dump_end (phase
, stream
);
187 /* Dump pointer PTR using FIELD to identify it. */
190 dump_pointer (dump_info_p di
, const char *field
, void *ptr
)
192 dump_maybe_newline (di
);
193 fprintf (di
->stream
, "%-4s: %-8" HOST_WIDE_INT_PRINT
"x ", field
,
194 (unsigned HOST_WIDE_INT
) (uintptr_t) ptr
);
198 /* Dump integer I using FIELD to identify it. */
201 dump_int (dump_info_p di
, const char *field
, int i
)
203 dump_maybe_newline (di
);
204 fprintf (di
->stream
, "%-4s: %-7d ", field
, i
);
208 /* Dump the floating point value R, using FIELD to identify it. */
211 dump_real (dump_info_p di
, const char *field
, const REAL_VALUE_TYPE
*r
)
214 real_to_decimal (buf
, r
, sizeof (buf
), 0, true);
215 dump_maybe_newline (di
);
216 fprintf (di
->stream
, "%-4s: %s ", field
, buf
);
217 di
->column
+= strlen (buf
) + 7;
220 /* Dump the fixed-point value F, using FIELD to identify it. */
223 dump_fixed (dump_info_p di
, const char *field
, const FIXED_VALUE_TYPE
*f
)
226 fixed_to_decimal (buf
, f
, sizeof (buf
));
227 dump_maybe_newline (di
);
228 fprintf (di
->stream
, "%-4s: %s ", field
, buf
);
229 di
->column
+= strlen (buf
) + 7;
233 /* Dump the string S. */
236 dump_string (dump_info_p di
, const char *string
)
238 dump_maybe_newline (di
);
239 fprintf (di
->stream
, "%-13s ", string
);
240 if (strlen (string
) > 13)
241 di
->column
+= strlen (string
) + 1;
246 /* Dump the string field S. */
249 dump_string_field (dump_info_p di
, const char *field
, const char *string
)
251 dump_maybe_newline (di
);
252 fprintf (di
->stream
, "%-4s: %-7s ", field
, string
);
253 if (strlen (string
) > 7)
254 di
->column
+= 6 + strlen (string
) + 1;
259 /* Dump the next node in the queue. */
262 dequeue_and_dump (dump_info_p di
)
266 dump_node_info_p dni
;
270 enum tree_code_class code_class
;
271 const char* code_name
;
273 /* Get the next node from the queue. */
277 dni
= (dump_node_info_p
) stn
->value
;
280 /* Remove the node from the queue, and put it on the free list. */
281 di
->queue
= dq
->next
;
284 dq
->next
= di
->free_list
;
287 /* Print the node index. */
288 dump_index (di
, index
);
289 /* And the type of node this is. */
293 code_name
= get_tree_code_name (TREE_CODE (t
));
294 fprintf (di
->stream
, "%-16s ", code_name
);
297 /* Figure out what kind of node this is. */
298 code
= TREE_CODE (t
);
299 code_class
= TREE_CODE_CLASS (code
);
301 /* Although BINFOs are TREE_VECs, we dump them specially so as to be
307 vec
<tree
, va_gc
> *accesses
= BINFO_BASE_ACCESSES (t
);
309 dump_child ("type", BINFO_TYPE (t
));
311 if (BINFO_VIRTUAL_P (t
))
312 dump_string_field (di
, "spec", "virt");
314 dump_int (di
, "bases", BINFO_N_BASE_BINFOS (t
));
315 for (ix
= 0; BINFO_BASE_ITERATE (t
, ix
, base
); ix
++)
317 tree access
= (accesses
? (*accesses
)[ix
] : access_public_node
);
318 const char *string
= NULL
;
320 if (access
== access_public_node
)
322 else if (access
== access_protected_node
)
324 else if (access
== access_private_node
)
329 dump_string_field (di
, "accs", string
);
330 queue_and_dump_index (di
, "binf", base
, DUMP_BINFO
);
336 /* We can knock off a bunch of expression nodes in exactly the same
338 if (IS_EXPR_CODE_CLASS (code_class
))
340 /* If we're dumping children, dump them now. */
341 queue_and_dump_type (di
, t
);
346 dump_child ("op 0", TREE_OPERAND (t
, 0));
351 dump_child ("op 0", TREE_OPERAND (t
, 0));
352 dump_child ("op 1", TREE_OPERAND (t
, 1));
359 /* These nodes are handled explicitly below. */
368 expanded_location xloc
;
369 /* All declarations have names. */
371 dump_child ("name", DECL_NAME (t
));
372 if (DECL_ASSEMBLER_NAME_SET_P (t
)
373 && DECL_ASSEMBLER_NAME (t
) != DECL_NAME (t
))
374 dump_child ("mngl", DECL_ASSEMBLER_NAME (t
));
375 if (DECL_ABSTRACT_ORIGIN (t
))
376 dump_child ("orig", DECL_ABSTRACT_ORIGIN (t
));
378 queue_and_dump_type (di
, t
);
379 dump_child ("scpe", DECL_CONTEXT (t
));
380 /* And a source position. */
381 xloc
= expand_location (DECL_SOURCE_LOCATION (t
));
384 const char *filename
= lbasename (xloc
.file
);
386 dump_maybe_newline (di
);
387 fprintf (di
->stream
, "srcp: %s:%-6d ", filename
,
389 di
->column
+= 6 + strlen (filename
) + 8;
391 /* And any declaration can be compiler-generated. */
392 if (CODE_CONTAINS_STRUCT (TREE_CODE (t
), TS_DECL_COMMON
)
393 && DECL_ARTIFICIAL (t
))
394 dump_string_field (di
, "note", "artificial");
395 if (DECL_CHAIN (t
) && !dump_flag (di
, TDF_SLIM
, NULL
))
396 dump_child ("chain", DECL_CHAIN (t
));
398 else if (code_class
== tcc_type
)
400 /* All types have qualifiers. */
401 int quals
= lang_hooks
.tree_dump
.type_quals (t
);
403 if (quals
!= TYPE_UNQUALIFIED
)
405 fprintf (di
->stream
, "qual: %c%c%c ",
406 (quals
& TYPE_QUAL_CONST
) ? 'c' : ' ',
407 (quals
& TYPE_QUAL_VOLATILE
) ? 'v' : ' ',
408 (quals
& TYPE_QUAL_RESTRICT
) ? 'r' : ' ');
412 /* All types have associated declarations. */
413 dump_child ("name", TYPE_NAME (t
));
415 /* All types have a main variant. */
416 if (TYPE_MAIN_VARIANT (t
) != t
)
417 dump_child ("unql", TYPE_MAIN_VARIANT (t
));
420 dump_child ("size", TYPE_SIZE (t
));
422 /* All types have alignments. */
423 dump_int (di
, "algn", TYPE_ALIGN (t
));
425 else if (code_class
== tcc_constant
)
426 /* All constants can have types. */
427 queue_and_dump_type (di
, t
);
429 /* Give the language-specific code a chance to print something. If
430 it's completely taken care of things, don't bother printing
431 anything more ourselves. */
432 if (lang_hooks
.tree_dump
.dump_tree (di
, t
))
435 /* Now handle the various kinds of nodes. */
440 case IDENTIFIER_NODE
:
441 dump_string_field (di
, "strg", IDENTIFIER_POINTER (t
));
442 dump_int (di
, "lngt", IDENTIFIER_LENGTH (t
));
446 dump_child ("purp", TREE_PURPOSE (t
));
447 dump_child ("valu", TREE_VALUE (t
));
448 dump_child ("chan", TREE_CHAIN (t
));
453 tree_stmt_iterator it
;
454 for (i
= 0, it
= tsi_start (t
); !tsi_end_p (it
); tsi_next (&it
), i
++)
457 sprintf (buffer
, "%u", i
);
458 dump_child (buffer
, tsi_stmt (it
));
464 dump_int (di
, "lngt", TREE_VEC_LENGTH (t
));
465 for (i
= 0; i
< TREE_VEC_LENGTH (t
); ++i
)
468 sprintf (buffer
, "%u", i
);
469 dump_child (buffer
, TREE_VEC_ELT (t
, i
));
475 dump_int (di
, "prec", TYPE_PRECISION (t
));
476 dump_string_field (di
, "sign", TYPE_UNSIGNED (t
) ? "unsigned": "signed");
477 dump_child ("min", TYPE_MIN_VALUE (t
));
478 dump_child ("max", TYPE_MAX_VALUE (t
));
480 if (code
== ENUMERAL_TYPE
)
481 dump_child ("csts", TYPE_VALUES (t
));
485 dump_int (di
, "prec", TYPE_PRECISION (t
));
488 case FIXED_POINT_TYPE
:
489 dump_int (di
, "prec", TYPE_PRECISION (t
));
490 dump_string_field (di
, "sign", TYPE_UNSIGNED (t
) ? "unsigned": "signed");
491 dump_string_field (di
, "saturating",
492 TYPE_SATURATING (t
) ? "saturating": "non-saturating");
496 dump_child ("ptd", TREE_TYPE (t
));
500 dump_child ("refd", TREE_TYPE (t
));
504 dump_child ("clas", TYPE_METHOD_BASETYPE (t
));
508 dump_child ("retn", TREE_TYPE (t
));
509 dump_child ("prms", TYPE_ARG_TYPES (t
));
513 dump_child ("elts", TREE_TYPE (t
));
514 dump_child ("domn", TYPE_DOMAIN (t
));
519 if (TREE_CODE (t
) == RECORD_TYPE
)
520 dump_string_field (di
, "tag", "struct");
522 dump_string_field (di
, "tag", "union");
524 dump_child ("flds", TYPE_FIELDS (t
));
525 dump_child ("fncs", TYPE_METHODS (t
));
526 queue_and_dump_index (di
, "binf", TYPE_BINFO (t
),
531 dump_child ("cnst", DECL_INITIAL (t
));
534 case DEBUG_EXPR_DECL
:
535 dump_int (di
, "-uid", DEBUG_TEMP_UID (t
));
542 if (TREE_CODE (t
) == PARM_DECL
)
543 dump_child ("argt", DECL_ARG_TYPE (t
));
545 dump_child ("init", DECL_INITIAL (t
));
546 dump_child ("size", DECL_SIZE (t
));
547 dump_int (di
, "algn", DECL_ALIGN (t
));
549 if (TREE_CODE (t
) == FIELD_DECL
)
551 if (DECL_FIELD_OFFSET (t
))
552 dump_child ("bpos", bit_position (t
));
554 else if (TREE_CODE (t
) == VAR_DECL
555 || TREE_CODE (t
) == PARM_DECL
)
557 dump_int (di
, "used", TREE_USED (t
));
558 if (DECL_REGISTER (t
))
559 dump_string_field (di
, "spec", "register");
564 dump_child ("args", DECL_ARGUMENTS (t
));
565 if (DECL_EXTERNAL (t
))
566 dump_string_field (di
, "body", "undefined");
568 dump_string_field (di
, "link", "extern");
570 dump_string_field (di
, "link", "static");
571 if (DECL_SAVED_TREE (t
) && !dump_flag (di
, TDF_SLIM
, t
))
572 dump_child ("body", DECL_SAVED_TREE (t
));
576 fprintf (di
->stream
, "int: ");
577 print_decs (t
, di
->stream
);
581 fprintf (di
->stream
, "strg: %-7s ", TREE_STRING_POINTER (t
));
582 dump_int (di
, "lngt", TREE_STRING_LENGTH (t
));
586 dump_real (di
, "valu", TREE_REAL_CST_PTR (t
));
590 dump_fixed (di
, "valu", TREE_FIXED_CST_PTR (t
));
596 case CLEANUP_POINT_EXPR
:
600 /* These nodes are unary, but do not have code class `1'. */
601 dump_child ("op 0", TREE_OPERAND (t
, 0));
604 case TRUTH_ANDIF_EXPR
:
605 case TRUTH_ORIF_EXPR
:
609 case PREDECREMENT_EXPR
:
610 case PREINCREMENT_EXPR
:
611 case POSTDECREMENT_EXPR
:
612 case POSTINCREMENT_EXPR
:
613 /* These nodes are binary, but do not have code class `2'. */
614 dump_child ("op 0", TREE_OPERAND (t
, 0));
615 dump_child ("op 1", TREE_OPERAND (t
, 1));
620 dump_child ("op 0", TREE_OPERAND (t
, 0));
621 dump_child ("op 1", TREE_OPERAND (t
, 1));
622 dump_child ("op 2", TREE_OPERAND (t
, 2));
626 case ARRAY_RANGE_REF
:
627 dump_child ("op 0", TREE_OPERAND (t
, 0));
628 dump_child ("op 1", TREE_OPERAND (t
, 1));
629 dump_child ("op 2", TREE_OPERAND (t
, 2));
630 dump_child ("op 3", TREE_OPERAND (t
, 3));
634 dump_child ("op 0", TREE_OPERAND (t
, 0));
635 dump_child ("op 1", TREE_OPERAND (t
, 1));
636 dump_child ("op 2", TREE_OPERAND (t
, 2));
639 case TRY_FINALLY_EXPR
:
640 dump_child ("op 0", TREE_OPERAND (t
, 0));
641 dump_child ("op 1", TREE_OPERAND (t
, 1));
648 call_expr_arg_iterator iter
;
649 dump_child ("fn", CALL_EXPR_FN (t
));
650 FOR_EACH_CALL_EXPR_ARG (arg
, iter
, t
)
653 sprintf (buffer
, "%u", i
);
654 dump_child (buffer
, arg
);
662 unsigned HOST_WIDE_INT cnt
;
664 dump_int (di
, "lngt", vec_safe_length (CONSTRUCTOR_ELTS (t
)));
665 FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (t
), cnt
, index
, value
)
667 dump_child ("idx", index
);
668 dump_child ("val", value
);
674 dump_child ("vars", TREE_OPERAND (t
, 0));
675 dump_child ("body", TREE_OPERAND (t
, 1));
679 dump_child ("body", TREE_OPERAND (t
, 0));
683 dump_child ("cond", TREE_OPERAND (t
, 0));
687 dump_child ("expr", TREE_OPERAND (t
, 0));
691 dump_child ("decl", TREE_OPERAND (t
, 0));
692 dump_child ("init", TREE_OPERAND (t
, 1));
693 dump_child ("clnp", TREE_OPERAND (t
, 2));
694 /* There really are two possible places the initializer can be.
695 After RTL expansion, the second operand is moved to the
696 position of the fourth operand, and the second operand
698 dump_child ("init", TREE_OPERAND (t
, 3));
701 case CASE_LABEL_EXPR
:
702 dump_child ("name", CASE_LABEL (t
));
705 dump_child ("low ", CASE_LOW (t
));
707 dump_child ("high", CASE_HIGH (t
));
711 dump_child ("name", TREE_OPERAND (t
,0));
714 dump_child ("labl", TREE_OPERAND (t
, 0));
717 dump_child ("cond", TREE_OPERAND (t
, 0));
718 dump_child ("body", TREE_OPERAND (t
, 1));
719 if (TREE_OPERAND (t
, 2))
721 dump_child ("labl", TREE_OPERAND (t
,2));
727 fprintf (di
->stream
, "%s\n", omp_clause_code_name
[OMP_CLAUSE_CODE (t
)]);
728 for (i
= 0; i
< omp_clause_num_ops
[OMP_CLAUSE_CODE (t
)]; i
++)
729 dump_child ("op: ", OMP_CLAUSE_OPERAND (t
, i
));
733 /* There are no additional fields to print. */
738 if (dump_flag (di
, TDF_ADDRESS
, NULL
))
739 dump_pointer (di
, "addr", (void *)t
);
741 /* Terminate the line. */
742 fprintf (di
->stream
, "\n");
745 /* Return nonzero if FLAG has been specified for the dump, and NODE
746 is not the root node of the dump. */
748 int dump_flag (dump_info_p di
, int flag
, const_tree node
)
750 return (di
->flags
& flag
) && (node
!= di
->node
);
753 /* Dump T, and all its children, on STREAM. */
756 dump_node (const_tree t
, int flags
, FILE *stream
)
760 dump_queue_p next_dq
;
762 /* Initialize the dump-information structure. */
771 di
.nodes
= splay_tree_new (splay_tree_compare_pointers
, 0,
772 (splay_tree_delete_value_fn
) &free
);
774 /* Queue up the first node. */
775 queue (&di
, t
, DUMP_NONE
);
777 /* Until the queue is empty, keep dumping nodes. */
779 dequeue_and_dump (&di
);
782 for (dq
= di
.free_list
; dq
; dq
= next_dq
)
787 splay_tree_delete (di
.nodes
);