1 /* Tree-dumping functionality for intermediate representation.
2 Copyright (C) 1999-2016 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"
25 #include "tree-pretty-print.h"
26 #include "tree-dump.h"
27 #include "langhooks.h"
28 #include "tree-iterator.h"
31 static unsigned int queue (dump_info_p
, const_tree
, int);
32 static void dump_index (dump_info_p
, unsigned int);
33 static void dequeue_and_dump (dump_info_p
);
34 static void dump_new_line (dump_info_p
);
35 static void dump_maybe_newline (dump_info_p
);
37 /* Add T to the end of the queue of nodes to dump. Returns the index
41 queue (dump_info_p di
, const_tree t
, int flags
)
47 /* Assign the next available index to T. */
50 /* Obtain a new queue node. */
54 di
->free_list
= dq
->next
;
57 dq
= XNEW (struct dump_queue
);
59 /* Create a new entry in the splay-tree. */
60 dni
= XNEW (struct dump_node_info
);
62 dni
->binfo_p
= ((flags
& DUMP_BINFO
) != 0);
63 dq
->node
= splay_tree_insert (di
->nodes
, (splay_tree_key
) t
,
64 (splay_tree_value
) dni
);
66 /* Add it to the end of the queue. */
71 di
->queue_end
->next
= dq
;
74 /* Return the index. */
79 dump_index (dump_info_p di
, unsigned int index
)
81 fprintf (di
->stream
, "@%-6u ", index
);
85 /* If T has not already been output, queue it for subsequent output.
86 FIELD is a string to print before printing the index. Then, the
87 index of T is printed. */
90 queue_and_dump_index (dump_info_p di
, const char *field
, const_tree t
, int flags
)
95 /* If there's no node, just return. This makes for fewer checks in
100 /* See if we've already queued or dumped this node. */
101 n
= splay_tree_lookup (di
->nodes
, (splay_tree_key
) t
);
103 index
= ((dump_node_info_p
) n
->value
)->index
;
105 /* If we haven't, add it to the queue. */
106 index
= queue (di
, t
, flags
);
108 /* Print the index of the node. */
109 dump_maybe_newline (di
);
110 fprintf (di
->stream
, "%-4s: ", field
);
112 dump_index (di
, index
);
115 /* Dump the type of T. */
118 queue_and_dump_type (dump_info_p di
, const_tree t
)
120 queue_and_dump_index (di
, "type", TREE_TYPE (t
), DUMP_NONE
);
123 /* Dump column control */
124 #define SOL_COLUMN 25 /* Start of line column. */
125 #define EOL_COLUMN 55 /* End of line column. */
126 #define COLUMN_ALIGNMENT 15 /* Alignment. */
128 /* Insert a new line in the dump output, and indent to an appropriate
129 place to start printing more fields. */
132 dump_new_line (dump_info_p di
)
134 fprintf (di
->stream
, "\n%*s", SOL_COLUMN
, "");
135 di
->column
= SOL_COLUMN
;
138 /* If necessary, insert a new line. */
141 dump_maybe_newline (dump_info_p di
)
145 /* See if we need a new line. */
146 if (di
->column
> EOL_COLUMN
)
148 /* See if we need any padding. */
149 else if ((extra
= (di
->column
- SOL_COLUMN
) % COLUMN_ALIGNMENT
) != 0)
151 fprintf (di
->stream
, "%*s", COLUMN_ALIGNMENT
- extra
, "");
152 di
->column
+= COLUMN_ALIGNMENT
- extra
;
156 /* Dump FUNCTION_DECL FN as tree dump PHASE. */
159 dump_function (int phase
, tree fn
)
164 stream
= dump_begin (phase
, &flags
);
167 dump_function_to_file (fn
, stream
, flags
);
168 dump_end (phase
, stream
);
172 /* Dump pointer PTR using FIELD to identify it. */
175 dump_pointer (dump_info_p di
, const char *field
, void *ptr
)
177 dump_maybe_newline (di
);
178 fprintf (di
->stream
, "%-4s: %-8" HOST_WIDE_INT_PRINT
"x ", field
,
179 (unsigned HOST_WIDE_INT
) (uintptr_t) ptr
);
183 /* Dump integer I using FIELD to identify it. */
186 dump_int (dump_info_p di
, const char *field
, int i
)
188 dump_maybe_newline (di
);
189 fprintf (di
->stream
, "%-4s: %-7d ", field
, i
);
193 /* Dump the floating point value R, using FIELD to identify it. */
196 dump_real (dump_info_p di
, const char *field
, const REAL_VALUE_TYPE
*r
)
199 real_to_decimal (buf
, r
, sizeof (buf
), 0, true);
200 dump_maybe_newline (di
);
201 fprintf (di
->stream
, "%-4s: %s ", field
, buf
);
202 di
->column
+= strlen (buf
) + 7;
205 /* Dump the fixed-point value F, using FIELD to identify it. */
208 dump_fixed (dump_info_p di
, const char *field
, const FIXED_VALUE_TYPE
*f
)
211 fixed_to_decimal (buf
, f
, sizeof (buf
));
212 dump_maybe_newline (di
);
213 fprintf (di
->stream
, "%-4s: %s ", field
, buf
);
214 di
->column
+= strlen (buf
) + 7;
218 /* Dump the string S. */
221 dump_string (dump_info_p di
, const char *string
)
223 dump_maybe_newline (di
);
224 fprintf (di
->stream
, "%-13s ", string
);
225 if (strlen (string
) > 13)
226 di
->column
+= strlen (string
) + 1;
231 /* Dump the string field S. */
234 dump_string_field (dump_info_p di
, const char *field
, const char *string
)
236 dump_maybe_newline (di
);
237 fprintf (di
->stream
, "%-4s: %-7s ", field
, string
);
238 if (strlen (string
) > 7)
239 di
->column
+= 6 + strlen (string
) + 1;
244 /* Dump the next node in the queue. */
247 dequeue_and_dump (dump_info_p di
)
251 dump_node_info_p dni
;
255 enum tree_code_class code_class
;
256 const char* code_name
;
258 /* Get the next node from the queue. */
262 dni
= (dump_node_info_p
) stn
->value
;
265 /* Remove the node from the queue, and put it on the free list. */
266 di
->queue
= dq
->next
;
269 dq
->next
= di
->free_list
;
272 /* Print the node index. */
273 dump_index (di
, index
);
274 /* And the type of node this is. */
278 code_name
= get_tree_code_name (TREE_CODE (t
));
279 fprintf (di
->stream
, "%-16s ", code_name
);
282 /* Figure out what kind of node this is. */
283 code
= TREE_CODE (t
);
284 code_class
= TREE_CODE_CLASS (code
);
286 /* Although BINFOs are TREE_VECs, we dump them specially so as to be
292 vec
<tree
, va_gc
> *accesses
= BINFO_BASE_ACCESSES (t
);
294 dump_child ("type", BINFO_TYPE (t
));
296 if (BINFO_VIRTUAL_P (t
))
297 dump_string_field (di
, "spec", "virt");
299 dump_int (di
, "bases", BINFO_N_BASE_BINFOS (t
));
300 for (ix
= 0; BINFO_BASE_ITERATE (t
, ix
, base
); ix
++)
302 tree access
= (accesses
? (*accesses
)[ix
] : access_public_node
);
303 const char *string
= NULL
;
305 if (access
== access_public_node
)
307 else if (access
== access_protected_node
)
309 else if (access
== access_private_node
)
314 dump_string_field (di
, "accs", string
);
315 queue_and_dump_index (di
, "binf", base
, DUMP_BINFO
);
321 /* We can knock off a bunch of expression nodes in exactly the same
323 if (IS_EXPR_CODE_CLASS (code_class
))
325 /* If we're dumping children, dump them now. */
326 queue_and_dump_type (di
, t
);
331 dump_child ("op 0", TREE_OPERAND (t
, 0));
336 dump_child ("op 0", TREE_OPERAND (t
, 0));
337 dump_child ("op 1", TREE_OPERAND (t
, 1));
344 /* These nodes are handled explicitly below. */
353 expanded_location xloc
;
354 /* All declarations have names. */
356 dump_child ("name", DECL_NAME (t
));
357 if (DECL_ASSEMBLER_NAME_SET_P (t
)
358 && DECL_ASSEMBLER_NAME (t
) != DECL_NAME (t
))
359 dump_child ("mngl", DECL_ASSEMBLER_NAME (t
));
360 if (DECL_ABSTRACT_ORIGIN (t
))
361 dump_child ("orig", DECL_ABSTRACT_ORIGIN (t
));
363 queue_and_dump_type (di
, t
);
364 dump_child ("scpe", DECL_CONTEXT (t
));
365 /* And a source position. */
366 xloc
= expand_location (DECL_SOURCE_LOCATION (t
));
369 const char *filename
= lbasename (xloc
.file
);
371 dump_maybe_newline (di
);
372 fprintf (di
->stream
, "srcp: %s:%-6d ", filename
,
374 di
->column
+= 6 + strlen (filename
) + 8;
376 /* And any declaration can be compiler-generated. */
377 if (CODE_CONTAINS_STRUCT (TREE_CODE (t
), TS_DECL_COMMON
)
378 && DECL_ARTIFICIAL (t
))
379 dump_string_field (di
, "note", "artificial");
380 if (DECL_CHAIN (t
) && !dump_flag (di
, TDF_SLIM
, NULL
))
381 dump_child ("chain", DECL_CHAIN (t
));
383 else if (code_class
== tcc_type
)
385 /* All types have qualifiers. */
386 int quals
= lang_hooks
.tree_dump
.type_quals (t
);
388 if (quals
!= TYPE_UNQUALIFIED
)
390 fprintf (di
->stream
, "qual: %c%c%c ",
391 (quals
& TYPE_QUAL_CONST
) ? 'c' : ' ',
392 (quals
& TYPE_QUAL_VOLATILE
) ? 'v' : ' ',
393 (quals
& TYPE_QUAL_RESTRICT
) ? 'r' : ' ');
397 /* All types have associated declarations. */
398 dump_child ("name", TYPE_NAME (t
));
400 /* All types have a main variant. */
401 if (TYPE_MAIN_VARIANT (t
) != t
)
402 dump_child ("unql", TYPE_MAIN_VARIANT (t
));
405 dump_child ("size", TYPE_SIZE (t
));
407 /* All types have alignments. */
408 dump_int (di
, "algn", TYPE_ALIGN (t
));
410 else if (code_class
== tcc_constant
)
411 /* All constants can have types. */
412 queue_and_dump_type (di
, t
);
414 /* Give the language-specific code a chance to print something. If
415 it's completely taken care of things, don't bother printing
416 anything more ourselves. */
417 if (lang_hooks
.tree_dump
.dump_tree (di
, t
))
420 /* Now handle the various kinds of nodes. */
425 case IDENTIFIER_NODE
:
426 dump_string_field (di
, "strg", IDENTIFIER_POINTER (t
));
427 dump_int (di
, "lngt", IDENTIFIER_LENGTH (t
));
431 dump_child ("purp", TREE_PURPOSE (t
));
432 dump_child ("valu", TREE_VALUE (t
));
433 dump_child ("chan", TREE_CHAIN (t
));
438 tree_stmt_iterator it
;
439 for (i
= 0, it
= tsi_start (t
); !tsi_end_p (it
); tsi_next (&it
), i
++)
442 sprintf (buffer
, "%u", i
);
443 dump_child (buffer
, tsi_stmt (it
));
449 dump_int (di
, "lngt", TREE_VEC_LENGTH (t
));
450 for (i
= 0; i
< TREE_VEC_LENGTH (t
); ++i
)
453 sprintf (buffer
, "%u", i
);
454 dump_child (buffer
, TREE_VEC_ELT (t
, i
));
460 dump_int (di
, "prec", TYPE_PRECISION (t
));
461 dump_string_field (di
, "sign", TYPE_UNSIGNED (t
) ? "unsigned": "signed");
462 dump_child ("min", TYPE_MIN_VALUE (t
));
463 dump_child ("max", TYPE_MAX_VALUE (t
));
465 if (code
== ENUMERAL_TYPE
)
466 dump_child ("csts", TYPE_VALUES (t
));
470 dump_int (di
, "prec", TYPE_PRECISION (t
));
473 case FIXED_POINT_TYPE
:
474 dump_int (di
, "prec", TYPE_PRECISION (t
));
475 dump_string_field (di
, "sign", TYPE_UNSIGNED (t
) ? "unsigned": "signed");
476 dump_string_field (di
, "saturating",
477 TYPE_SATURATING (t
) ? "saturating": "non-saturating");
481 dump_child ("ptd", TREE_TYPE (t
));
485 dump_child ("refd", TREE_TYPE (t
));
489 dump_child ("clas", TYPE_METHOD_BASETYPE (t
));
493 dump_child ("retn", TREE_TYPE (t
));
494 dump_child ("prms", TYPE_ARG_TYPES (t
));
498 dump_child ("elts", TREE_TYPE (t
));
499 dump_child ("domn", TYPE_DOMAIN (t
));
504 if (TREE_CODE (t
) == RECORD_TYPE
)
505 dump_string_field (di
, "tag", "struct");
507 dump_string_field (di
, "tag", "union");
509 dump_child ("flds", TYPE_FIELDS (t
));
510 dump_child ("fncs", TYPE_METHODS (t
));
511 queue_and_dump_index (di
, "binf", TYPE_BINFO (t
),
516 dump_child ("cnst", DECL_INITIAL (t
));
519 case DEBUG_EXPR_DECL
:
520 dump_int (di
, "-uid", DEBUG_TEMP_UID (t
));
527 if (TREE_CODE (t
) == PARM_DECL
)
528 dump_child ("argt", DECL_ARG_TYPE (t
));
530 dump_child ("init", DECL_INITIAL (t
));
531 dump_child ("size", DECL_SIZE (t
));
532 dump_int (di
, "algn", DECL_ALIGN (t
));
534 if (TREE_CODE (t
) == FIELD_DECL
)
536 if (DECL_FIELD_OFFSET (t
))
537 dump_child ("bpos", bit_position (t
));
539 else if (TREE_CODE (t
) == VAR_DECL
540 || TREE_CODE (t
) == PARM_DECL
)
542 dump_int (di
, "used", TREE_USED (t
));
543 if (DECL_REGISTER (t
))
544 dump_string_field (di
, "spec", "register");
549 dump_child ("args", DECL_ARGUMENTS (t
));
550 if (DECL_EXTERNAL (t
))
551 dump_string_field (di
, "body", "undefined");
553 dump_string_field (di
, "link", "extern");
555 dump_string_field (di
, "link", "static");
556 if (DECL_SAVED_TREE (t
) && !dump_flag (di
, TDF_SLIM
, t
))
557 dump_child ("body", DECL_SAVED_TREE (t
));
561 fprintf (di
->stream
, "int: ");
562 print_decs (t
, di
->stream
);
566 fprintf (di
->stream
, "strg: %-7s ", TREE_STRING_POINTER (t
));
567 dump_int (di
, "lngt", TREE_STRING_LENGTH (t
));
571 dump_real (di
, "valu", TREE_REAL_CST_PTR (t
));
575 dump_fixed (di
, "valu", TREE_FIXED_CST_PTR (t
));
581 case CLEANUP_POINT_EXPR
:
585 /* These nodes are unary, but do not have code class `1'. */
586 dump_child ("op 0", TREE_OPERAND (t
, 0));
589 case TRUTH_ANDIF_EXPR
:
590 case TRUTH_ORIF_EXPR
:
594 case PREDECREMENT_EXPR
:
595 case PREINCREMENT_EXPR
:
596 case POSTDECREMENT_EXPR
:
597 case POSTINCREMENT_EXPR
:
598 /* These nodes are binary, but do not have code class `2'. */
599 dump_child ("op 0", TREE_OPERAND (t
, 0));
600 dump_child ("op 1", TREE_OPERAND (t
, 1));
605 dump_child ("op 0", TREE_OPERAND (t
, 0));
606 dump_child ("op 1", TREE_OPERAND (t
, 1));
607 dump_child ("op 2", TREE_OPERAND (t
, 2));
611 case ARRAY_RANGE_REF
:
612 dump_child ("op 0", TREE_OPERAND (t
, 0));
613 dump_child ("op 1", TREE_OPERAND (t
, 1));
614 dump_child ("op 2", TREE_OPERAND (t
, 2));
615 dump_child ("op 3", TREE_OPERAND (t
, 3));
619 dump_child ("op 0", TREE_OPERAND (t
, 0));
620 dump_child ("op 1", TREE_OPERAND (t
, 1));
621 dump_child ("op 2", TREE_OPERAND (t
, 2));
624 case TRY_FINALLY_EXPR
:
625 dump_child ("op 0", TREE_OPERAND (t
, 0));
626 dump_child ("op 1", TREE_OPERAND (t
, 1));
633 call_expr_arg_iterator iter
;
634 dump_child ("fn", CALL_EXPR_FN (t
));
635 FOR_EACH_CALL_EXPR_ARG (arg
, iter
, t
)
638 sprintf (buffer
, "%u", i
);
639 dump_child (buffer
, arg
);
647 unsigned HOST_WIDE_INT cnt
;
649 dump_int (di
, "lngt", vec_safe_length (CONSTRUCTOR_ELTS (t
)));
650 FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (t
), cnt
, index
, value
)
652 dump_child ("idx", index
);
653 dump_child ("val", value
);
659 dump_child ("vars", TREE_OPERAND (t
, 0));
660 dump_child ("body", TREE_OPERAND (t
, 1));
664 dump_child ("body", TREE_OPERAND (t
, 0));
668 dump_child ("cond", TREE_OPERAND (t
, 0));
672 dump_child ("expr", TREE_OPERAND (t
, 0));
676 dump_child ("decl", TREE_OPERAND (t
, 0));
677 dump_child ("init", TREE_OPERAND (t
, 1));
678 dump_child ("clnp", TREE_OPERAND (t
, 2));
679 /* There really are two possible places the initializer can be.
680 After RTL expansion, the second operand is moved to the
681 position of the fourth operand, and the second operand
683 dump_child ("init", TREE_OPERAND (t
, 3));
686 case CASE_LABEL_EXPR
:
687 dump_child ("name", CASE_LABEL (t
));
690 dump_child ("low ", CASE_LOW (t
));
692 dump_child ("high", CASE_HIGH (t
));
696 dump_child ("name", TREE_OPERAND (t
,0));
699 dump_child ("labl", TREE_OPERAND (t
, 0));
702 dump_child ("cond", TREE_OPERAND (t
, 0));
703 dump_child ("body", TREE_OPERAND (t
, 1));
704 if (TREE_OPERAND (t
, 2))
706 dump_child ("labl", TREE_OPERAND (t
,2));
712 fprintf (di
->stream
, "%s\n", omp_clause_code_name
[OMP_CLAUSE_CODE (t
)]);
713 for (i
= 0; i
< omp_clause_num_ops
[OMP_CLAUSE_CODE (t
)]; i
++)
714 dump_child ("op: ", OMP_CLAUSE_OPERAND (t
, i
));
718 /* There are no additional fields to print. */
723 if (dump_flag (di
, TDF_ADDRESS
, NULL
))
724 dump_pointer (di
, "addr", (void *)t
);
726 /* Terminate the line. */
727 fprintf (di
->stream
, "\n");
730 /* Return nonzero if FLAG has been specified for the dump, and NODE
731 is not the root node of the dump. */
733 int dump_flag (dump_info_p di
, int flag
, const_tree node
)
735 return (di
->flags
& flag
) && (node
!= di
->node
);
738 /* Dump T, and all its children, on STREAM. */
741 dump_node (const_tree t
, int flags
, FILE *stream
)
745 dump_queue_p next_dq
;
747 /* Initialize the dump-information structure. */
756 di
.nodes
= splay_tree_new (splay_tree_compare_pointers
, 0,
757 (splay_tree_delete_value_fn
) &free
);
759 /* Queue up the first node. */
760 queue (&di
, t
, DUMP_NONE
);
762 /* Until the queue is empty, keep dumping nodes. */
764 dequeue_and_dump (&di
);
767 for (dq
= di
.free_list
; dq
; dq
= next_dq
)
772 splay_tree_delete (di
.nodes
);