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 "splay-tree.h"
29 #include "filenames.h"
30 #include "tree-dump.h"
31 #include "langhooks.h"
32 #include "tree-iterator.h"
33 #include "tree-pretty-print.h"
35 #include "wide-int-print.h"
37 static unsigned int queue (dump_info_p
, const_tree
, int);
38 static void dump_index (dump_info_p
, unsigned int);
39 static void dequeue_and_dump (dump_info_p
);
40 static void dump_new_line (dump_info_p
);
41 static void dump_maybe_newline (dump_info_p
);
43 /* Add T to the end of the queue of nodes to dump. Returns the index
47 queue (dump_info_p di
, const_tree t
, int flags
)
53 /* Assign the next available index to T. */
56 /* Obtain a new queue node. */
60 di
->free_list
= dq
->next
;
63 dq
= XNEW (struct dump_queue
);
65 /* Create a new entry in the splay-tree. */
66 dni
= XNEW (struct dump_node_info
);
68 dni
->binfo_p
= ((flags
& DUMP_BINFO
) != 0);
69 dq
->node
= splay_tree_insert (di
->nodes
, (splay_tree_key
) t
,
70 (splay_tree_value
) dni
);
72 /* Add it to the end of the queue. */
77 di
->queue_end
->next
= dq
;
80 /* Return the index. */
85 dump_index (dump_info_p di
, unsigned int index
)
87 fprintf (di
->stream
, "@%-6u ", index
);
91 /* If T has not already been output, queue it for subsequent output.
92 FIELD is a string to print before printing the index. Then, the
93 index of T is printed. */
96 queue_and_dump_index (dump_info_p di
, const char *field
, const_tree t
, int flags
)
101 /* If there's no node, just return. This makes for fewer checks in
106 /* See if we've already queued or dumped this node. */
107 n
= splay_tree_lookup (di
->nodes
, (splay_tree_key
) t
);
109 index
= ((dump_node_info_p
) n
->value
)->index
;
111 /* If we haven't, add it to the queue. */
112 index
= queue (di
, t
, flags
);
114 /* Print the index of the node. */
115 dump_maybe_newline (di
);
116 fprintf (di
->stream
, "%-4s: ", field
);
118 dump_index (di
, index
);
121 /* Dump the type of T. */
124 queue_and_dump_type (dump_info_p di
, const_tree t
)
126 queue_and_dump_index (di
, "type", TREE_TYPE (t
), DUMP_NONE
);
129 /* Dump column control */
130 #define SOL_COLUMN 25 /* Start of line column. */
131 #define EOL_COLUMN 55 /* End of line column. */
132 #define COLUMN_ALIGNMENT 15 /* Alignment. */
134 /* Insert a new line in the dump output, and indent to an appropriate
135 place to start printing more fields. */
138 dump_new_line (dump_info_p di
)
140 fprintf (di
->stream
, "\n%*s", SOL_COLUMN
, "");
141 di
->column
= SOL_COLUMN
;
144 /* If necessary, insert a new line. */
147 dump_maybe_newline (dump_info_p di
)
151 /* See if we need a new line. */
152 if (di
->column
> EOL_COLUMN
)
154 /* See if we need any padding. */
155 else if ((extra
= (di
->column
- SOL_COLUMN
) % COLUMN_ALIGNMENT
) != 0)
157 fprintf (di
->stream
, "%*s", COLUMN_ALIGNMENT
- extra
, "");
158 di
->column
+= COLUMN_ALIGNMENT
- extra
;
162 /* Dump FUNCTION_DECL FN as tree dump PHASE. */
165 dump_function (int phase
, tree fn
)
170 stream
= dump_begin (phase
, &flags
);
173 dump_function_to_file (fn
, stream
, flags
);
174 dump_end (phase
, stream
);
178 /* Dump pointer PTR using FIELD to identify it. */
181 dump_pointer (dump_info_p di
, const char *field
, void *ptr
)
183 dump_maybe_newline (di
);
184 fprintf (di
->stream
, "%-4s: %-8" HOST_WIDE_INT_PRINT
"x ", field
,
185 (unsigned HOST_WIDE_INT
) (uintptr_t) ptr
);
189 /* Dump integer I using FIELD to identify it. */
192 dump_int (dump_info_p di
, const char *field
, int i
)
194 dump_maybe_newline (di
);
195 fprintf (di
->stream
, "%-4s: %-7d ", field
, i
);
199 /* Dump the floating point value R, using FIELD to identify it. */
202 dump_real (dump_info_p di
, const char *field
, const REAL_VALUE_TYPE
*r
)
205 real_to_decimal (buf
, r
, sizeof (buf
), 0, true);
206 dump_maybe_newline (di
);
207 fprintf (di
->stream
, "%-4s: %s ", field
, buf
);
208 di
->column
+= strlen (buf
) + 7;
211 /* Dump the fixed-point value F, using FIELD to identify it. */
214 dump_fixed (dump_info_p di
, const char *field
, const FIXED_VALUE_TYPE
*f
)
217 fixed_to_decimal (buf
, f
, sizeof (buf
));
218 dump_maybe_newline (di
);
219 fprintf (di
->stream
, "%-4s: %s ", field
, buf
);
220 di
->column
+= strlen (buf
) + 7;
224 /* Dump the string S. */
227 dump_string (dump_info_p di
, const char *string
)
229 dump_maybe_newline (di
);
230 fprintf (di
->stream
, "%-13s ", string
);
231 if (strlen (string
) > 13)
232 di
->column
+= strlen (string
) + 1;
237 /* Dump the string field S. */
240 dump_string_field (dump_info_p di
, const char *field
, const char *string
)
242 dump_maybe_newline (di
);
243 fprintf (di
->stream
, "%-4s: %-7s ", field
, string
);
244 if (strlen (string
) > 7)
245 di
->column
+= 6 + strlen (string
) + 1;
250 /* Dump the next node in the queue. */
253 dequeue_and_dump (dump_info_p di
)
257 dump_node_info_p dni
;
261 enum tree_code_class code_class
;
262 const char* code_name
;
264 /* Get the next node from the queue. */
268 dni
= (dump_node_info_p
) stn
->value
;
271 /* Remove the node from the queue, and put it on the free list. */
272 di
->queue
= dq
->next
;
275 dq
->next
= di
->free_list
;
278 /* Print the node index. */
279 dump_index (di
, index
);
280 /* And the type of node this is. */
284 code_name
= get_tree_code_name (TREE_CODE (t
));
285 fprintf (di
->stream
, "%-16s ", code_name
);
288 /* Figure out what kind of node this is. */
289 code
= TREE_CODE (t
);
290 code_class
= TREE_CODE_CLASS (code
);
292 /* Although BINFOs are TREE_VECs, we dump them specially so as to be
298 vec
<tree
, va_gc
> *accesses
= BINFO_BASE_ACCESSES (t
);
300 dump_child ("type", BINFO_TYPE (t
));
302 if (BINFO_VIRTUAL_P (t
))
303 dump_string_field (di
, "spec", "virt");
305 dump_int (di
, "bases", BINFO_N_BASE_BINFOS (t
));
306 for (ix
= 0; BINFO_BASE_ITERATE (t
, ix
, base
); ix
++)
308 tree access
= (accesses
? (*accesses
)[ix
] : access_public_node
);
309 const char *string
= NULL
;
311 if (access
== access_public_node
)
313 else if (access
== access_protected_node
)
315 else if (access
== access_private_node
)
320 dump_string_field (di
, "accs", string
);
321 queue_and_dump_index (di
, "binf", base
, DUMP_BINFO
);
327 /* We can knock off a bunch of expression nodes in exactly the same
329 if (IS_EXPR_CODE_CLASS (code_class
))
331 /* If we're dumping children, dump them now. */
332 queue_and_dump_type (di
, t
);
337 dump_child ("op 0", TREE_OPERAND (t
, 0));
342 dump_child ("op 0", TREE_OPERAND (t
, 0));
343 dump_child ("op 1", TREE_OPERAND (t
, 1));
350 /* These nodes are handled explicitly below. */
359 expanded_location xloc
;
360 /* All declarations have names. */
362 dump_child ("name", DECL_NAME (t
));
363 if (DECL_ASSEMBLER_NAME_SET_P (t
)
364 && DECL_ASSEMBLER_NAME (t
) != DECL_NAME (t
))
365 dump_child ("mngl", DECL_ASSEMBLER_NAME (t
));
366 if (DECL_ABSTRACT_ORIGIN (t
))
367 dump_child ("orig", DECL_ABSTRACT_ORIGIN (t
));
369 queue_and_dump_type (di
, t
);
370 dump_child ("scpe", DECL_CONTEXT (t
));
371 /* And a source position. */
372 xloc
= expand_location (DECL_SOURCE_LOCATION (t
));
375 const char *filename
= lbasename (xloc
.file
);
377 dump_maybe_newline (di
);
378 fprintf (di
->stream
, "srcp: %s:%-6d ", filename
,
380 di
->column
+= 6 + strlen (filename
) + 8;
382 /* And any declaration can be compiler-generated. */
383 if (CODE_CONTAINS_STRUCT (TREE_CODE (t
), TS_DECL_COMMON
)
384 && DECL_ARTIFICIAL (t
))
385 dump_string_field (di
, "note", "artificial");
386 if (DECL_CHAIN (t
) && !dump_flag (di
, TDF_SLIM
, NULL
))
387 dump_child ("chain", DECL_CHAIN (t
));
389 else if (code_class
== tcc_type
)
391 /* All types have qualifiers. */
392 int quals
= lang_hooks
.tree_dump
.type_quals (t
);
394 if (quals
!= TYPE_UNQUALIFIED
)
396 fprintf (di
->stream
, "qual: %c%c%c ",
397 (quals
& TYPE_QUAL_CONST
) ? 'c' : ' ',
398 (quals
& TYPE_QUAL_VOLATILE
) ? 'v' : ' ',
399 (quals
& TYPE_QUAL_RESTRICT
) ? 'r' : ' ');
403 /* All types have associated declarations. */
404 dump_child ("name", TYPE_NAME (t
));
406 /* All types have a main variant. */
407 if (TYPE_MAIN_VARIANT (t
) != t
)
408 dump_child ("unql", TYPE_MAIN_VARIANT (t
));
411 dump_child ("size", TYPE_SIZE (t
));
413 /* All types have alignments. */
414 dump_int (di
, "algn", TYPE_ALIGN (t
));
416 else if (code_class
== tcc_constant
)
417 /* All constants can have types. */
418 queue_and_dump_type (di
, t
);
420 /* Give the language-specific code a chance to print something. If
421 it's completely taken care of things, don't bother printing
422 anything more ourselves. */
423 if (lang_hooks
.tree_dump
.dump_tree (di
, t
))
426 /* Now handle the various kinds of nodes. */
431 case IDENTIFIER_NODE
:
432 dump_string_field (di
, "strg", IDENTIFIER_POINTER (t
));
433 dump_int (di
, "lngt", IDENTIFIER_LENGTH (t
));
437 dump_child ("purp", TREE_PURPOSE (t
));
438 dump_child ("valu", TREE_VALUE (t
));
439 dump_child ("chan", TREE_CHAIN (t
));
444 tree_stmt_iterator it
;
445 for (i
= 0, it
= tsi_start (t
); !tsi_end_p (it
); tsi_next (&it
), i
++)
448 sprintf (buffer
, "%u", i
);
449 dump_child (buffer
, tsi_stmt (it
));
455 dump_int (di
, "lngt", TREE_VEC_LENGTH (t
));
456 for (i
= 0; i
< TREE_VEC_LENGTH (t
); ++i
)
459 sprintf (buffer
, "%u", i
);
460 dump_child (buffer
, TREE_VEC_ELT (t
, i
));
466 dump_int (di
, "prec", TYPE_PRECISION (t
));
467 dump_string_field (di
, "sign", TYPE_UNSIGNED (t
) ? "unsigned": "signed");
468 dump_child ("min", TYPE_MIN_VALUE (t
));
469 dump_child ("max", TYPE_MAX_VALUE (t
));
471 if (code
== ENUMERAL_TYPE
)
472 dump_child ("csts", TYPE_VALUES (t
));
476 dump_int (di
, "prec", TYPE_PRECISION (t
));
479 case FIXED_POINT_TYPE
:
480 dump_int (di
, "prec", TYPE_PRECISION (t
));
481 dump_string_field (di
, "sign", TYPE_UNSIGNED (t
) ? "unsigned": "signed");
482 dump_string_field (di
, "saturating",
483 TYPE_SATURATING (t
) ? "saturating": "non-saturating");
487 dump_child ("ptd", TREE_TYPE (t
));
491 dump_child ("refd", TREE_TYPE (t
));
495 dump_child ("clas", TYPE_METHOD_BASETYPE (t
));
499 dump_child ("retn", TREE_TYPE (t
));
500 dump_child ("prms", TYPE_ARG_TYPES (t
));
504 dump_child ("elts", TREE_TYPE (t
));
505 dump_child ("domn", TYPE_DOMAIN (t
));
510 if (TREE_CODE (t
) == RECORD_TYPE
)
511 dump_string_field (di
, "tag", "struct");
513 dump_string_field (di
, "tag", "union");
515 dump_child ("flds", TYPE_FIELDS (t
));
516 dump_child ("fncs", TYPE_METHODS (t
));
517 queue_and_dump_index (di
, "binf", TYPE_BINFO (t
),
522 dump_child ("cnst", DECL_INITIAL (t
));
525 case DEBUG_EXPR_DECL
:
526 dump_int (di
, "-uid", DEBUG_TEMP_UID (t
));
533 if (TREE_CODE (t
) == PARM_DECL
)
534 dump_child ("argt", DECL_ARG_TYPE (t
));
536 dump_child ("init", DECL_INITIAL (t
));
537 dump_child ("size", DECL_SIZE (t
));
538 dump_int (di
, "algn", DECL_ALIGN (t
));
540 if (TREE_CODE (t
) == FIELD_DECL
)
542 if (DECL_FIELD_OFFSET (t
))
543 dump_child ("bpos", bit_position (t
));
545 else if (TREE_CODE (t
) == VAR_DECL
546 || TREE_CODE (t
) == PARM_DECL
)
548 dump_int (di
, "used", TREE_USED (t
));
549 if (DECL_REGISTER (t
))
550 dump_string_field (di
, "spec", "register");
555 dump_child ("args", DECL_ARGUMENTS (t
));
556 if (DECL_EXTERNAL (t
))
557 dump_string_field (di
, "body", "undefined");
559 dump_string_field (di
, "link", "extern");
561 dump_string_field (di
, "link", "static");
562 if (DECL_SAVED_TREE (t
) && !dump_flag (di
, TDF_SLIM
, t
))
563 dump_child ("body", DECL_SAVED_TREE (t
));
567 fprintf (di
->stream
, "int: ");
568 print_decs (t
, di
->stream
);
572 fprintf (di
->stream
, "strg: %-7s ", TREE_STRING_POINTER (t
));
573 dump_int (di
, "lngt", TREE_STRING_LENGTH (t
));
577 dump_real (di
, "valu", TREE_REAL_CST_PTR (t
));
581 dump_fixed (di
, "valu", TREE_FIXED_CST_PTR (t
));
587 case CLEANUP_POINT_EXPR
:
591 /* These nodes are unary, but do not have code class `1'. */
592 dump_child ("op 0", TREE_OPERAND (t
, 0));
595 case TRUTH_ANDIF_EXPR
:
596 case TRUTH_ORIF_EXPR
:
600 case PREDECREMENT_EXPR
:
601 case PREINCREMENT_EXPR
:
602 case POSTDECREMENT_EXPR
:
603 case POSTINCREMENT_EXPR
:
604 /* These nodes are binary, but do not have code class `2'. */
605 dump_child ("op 0", TREE_OPERAND (t
, 0));
606 dump_child ("op 1", TREE_OPERAND (t
, 1));
611 dump_child ("op 0", TREE_OPERAND (t
, 0));
612 dump_child ("op 1", TREE_OPERAND (t
, 1));
613 dump_child ("op 2", TREE_OPERAND (t
, 2));
617 case ARRAY_RANGE_REF
:
618 dump_child ("op 0", TREE_OPERAND (t
, 0));
619 dump_child ("op 1", TREE_OPERAND (t
, 1));
620 dump_child ("op 2", TREE_OPERAND (t
, 2));
621 dump_child ("op 3", TREE_OPERAND (t
, 3));
625 dump_child ("op 0", TREE_OPERAND (t
, 0));
626 dump_child ("op 1", TREE_OPERAND (t
, 1));
627 dump_child ("op 2", TREE_OPERAND (t
, 2));
630 case TRY_FINALLY_EXPR
:
631 dump_child ("op 0", TREE_OPERAND (t
, 0));
632 dump_child ("op 1", TREE_OPERAND (t
, 1));
639 call_expr_arg_iterator iter
;
640 dump_child ("fn", CALL_EXPR_FN (t
));
641 FOR_EACH_CALL_EXPR_ARG (arg
, iter
, t
)
644 sprintf (buffer
, "%u", i
);
645 dump_child (buffer
, arg
);
653 unsigned HOST_WIDE_INT cnt
;
655 dump_int (di
, "lngt", vec_safe_length (CONSTRUCTOR_ELTS (t
)));
656 FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (t
), cnt
, index
, value
)
658 dump_child ("idx", index
);
659 dump_child ("val", value
);
665 dump_child ("vars", TREE_OPERAND (t
, 0));
666 dump_child ("body", TREE_OPERAND (t
, 1));
670 dump_child ("body", TREE_OPERAND (t
, 0));
674 dump_child ("cond", TREE_OPERAND (t
, 0));
678 dump_child ("expr", TREE_OPERAND (t
, 0));
682 dump_child ("decl", TREE_OPERAND (t
, 0));
683 dump_child ("init", TREE_OPERAND (t
, 1));
684 dump_child ("clnp", TREE_OPERAND (t
, 2));
685 /* There really are two possible places the initializer can be.
686 After RTL expansion, the second operand is moved to the
687 position of the fourth operand, and the second operand
689 dump_child ("init", TREE_OPERAND (t
, 3));
692 case CASE_LABEL_EXPR
:
693 dump_child ("name", CASE_LABEL (t
));
696 dump_child ("low ", CASE_LOW (t
));
698 dump_child ("high", CASE_HIGH (t
));
702 dump_child ("name", TREE_OPERAND (t
,0));
705 dump_child ("labl", TREE_OPERAND (t
, 0));
708 dump_child ("cond", TREE_OPERAND (t
, 0));
709 dump_child ("body", TREE_OPERAND (t
, 1));
710 if (TREE_OPERAND (t
, 2))
712 dump_child ("labl", TREE_OPERAND (t
,2));
718 fprintf (di
->stream
, "%s\n", omp_clause_code_name
[OMP_CLAUSE_CODE (t
)]);
719 for (i
= 0; i
< omp_clause_num_ops
[OMP_CLAUSE_CODE (t
)]; i
++)
720 dump_child ("op: ", OMP_CLAUSE_OPERAND (t
, i
));
724 /* There are no additional fields to print. */
729 if (dump_flag (di
, TDF_ADDRESS
, NULL
))
730 dump_pointer (di
, "addr", (void *)t
);
732 /* Terminate the line. */
733 fprintf (di
->stream
, "\n");
736 /* Return nonzero if FLAG has been specified for the dump, and NODE
737 is not the root node of the dump. */
739 int dump_flag (dump_info_p di
, int flag
, const_tree node
)
741 return (di
->flags
& flag
) && (node
!= di
->node
);
744 /* Dump T, and all its children, on STREAM. */
747 dump_node (const_tree t
, int flags
, FILE *stream
)
751 dump_queue_p next_dq
;
753 /* Initialize the dump-information structure. */
762 di
.nodes
= splay_tree_new (splay_tree_compare_pointers
, 0,
763 (splay_tree_delete_value_fn
) &free
);
765 /* Queue up the first node. */
766 queue (&di
, t
, DUMP_NONE
);
768 /* Until the queue is empty, keep dumping nodes. */
770 dequeue_and_dump (&di
);
773 for (dq
= di
.free_list
; dq
; dq
= next_dq
)
778 splay_tree_delete (di
.nodes
);