1 /* Tree-dumping functionality for intermediate representation.
2 Copyright (C) 1999-2014 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"
26 #include "splay-tree.h"
27 #include "filenames.h"
28 #include "tree-dump.h"
29 #include "langhooks.h"
30 #include "tree-iterator.h"
31 #include "tree-pretty-print.h"
34 #include "wide-int-print.h"
36 static unsigned int queue (dump_info_p
, const_tree
, int);
37 static void dump_index (dump_info_p
, unsigned int);
38 static void dequeue_and_dump (dump_info_p
);
39 static void dump_new_line (dump_info_p
);
40 static void dump_maybe_newline (dump_info_p
);
42 /* Add T to the end of the queue of nodes to dump. Returns the index
46 queue (dump_info_p di
, const_tree t
, int flags
)
52 /* Assign the next available index to T. */
55 /* Obtain a new queue node. */
59 di
->free_list
= dq
->next
;
62 dq
= XNEW (struct dump_queue
);
64 /* Create a new entry in the splay-tree. */
65 dni
= XNEW (struct dump_node_info
);
67 dni
->binfo_p
= ((flags
& DUMP_BINFO
) != 0);
68 dq
->node
= splay_tree_insert (di
->nodes
, (splay_tree_key
) t
,
69 (splay_tree_value
) dni
);
71 /* Add it to the end of the queue. */
76 di
->queue_end
->next
= dq
;
79 /* Return the index. */
84 dump_index (dump_info_p di
, unsigned int index
)
86 fprintf (di
->stream
, "@%-6u ", index
);
90 /* If T has not already been output, queue it for subsequent output.
91 FIELD is a string to print before printing the index. Then, the
92 index of T is printed. */
95 queue_and_dump_index (dump_info_p di
, const char *field
, const_tree t
, int flags
)
100 /* If there's no node, just return. This makes for fewer checks in
105 /* See if we've already queued or dumped this node. */
106 n
= splay_tree_lookup (di
->nodes
, (splay_tree_key
) t
);
108 index
= ((dump_node_info_p
) n
->value
)->index
;
110 /* If we haven't, add it to the queue. */
111 index
= queue (di
, t
, flags
);
113 /* Print the index of the node. */
114 dump_maybe_newline (di
);
115 fprintf (di
->stream
, "%-4s: ", field
);
117 dump_index (di
, index
);
120 /* Dump the type of T. */
123 queue_and_dump_type (dump_info_p di
, const_tree t
)
125 queue_and_dump_index (di
, "type", TREE_TYPE (t
), DUMP_NONE
);
128 /* Dump column control */
129 #define SOL_COLUMN 25 /* Start of line column. */
130 #define EOL_COLUMN 55 /* End of line column. */
131 #define COLUMN_ALIGNMENT 15 /* Alignment. */
133 /* Insert a new line in the dump output, and indent to an appropriate
134 place to start printing more fields. */
137 dump_new_line (dump_info_p di
)
139 fprintf (di
->stream
, "\n%*s", SOL_COLUMN
, "");
140 di
->column
= SOL_COLUMN
;
143 /* If necessary, insert a new line. */
146 dump_maybe_newline (dump_info_p di
)
150 /* See if we need a new line. */
151 if (di
->column
> EOL_COLUMN
)
153 /* See if we need any padding. */
154 else if ((extra
= (di
->column
- SOL_COLUMN
) % COLUMN_ALIGNMENT
) != 0)
156 fprintf (di
->stream
, "%*s", COLUMN_ALIGNMENT
- extra
, "");
157 di
->column
+= COLUMN_ALIGNMENT
- extra
;
161 /* Dump FUNCTION_DECL FN as tree dump PHASE. */
164 dump_function (int phase
, tree fn
)
169 stream
= dump_begin (phase
, &flags
);
172 dump_function_to_file (fn
, stream
, flags
);
173 dump_end (phase
, stream
);
177 /* Dump pointer PTR using FIELD to identify it. */
180 dump_pointer (dump_info_p di
, const char *field
, void *ptr
)
182 dump_maybe_newline (di
);
183 fprintf (di
->stream
, "%-4s: %-8" HOST_WIDE_INT_PRINT
"x ", field
,
184 (unsigned HOST_WIDE_INT
) (uintptr_t) ptr
);
188 /* Dump integer I using FIELD to identify it. */
191 dump_int (dump_info_p di
, const char *field
, int i
)
193 dump_maybe_newline (di
);
194 fprintf (di
->stream
, "%-4s: %-7d ", field
, i
);
198 /* Dump the floating point value R, using FIELD to identify it. */
201 dump_real (dump_info_p di
, const char *field
, const REAL_VALUE_TYPE
*r
)
204 real_to_decimal (buf
, r
, sizeof (buf
), 0, true);
205 dump_maybe_newline (di
);
206 fprintf (di
->stream
, "%-4s: %s ", field
, buf
);
207 di
->column
+= strlen (buf
) + 7;
210 /* Dump the fixed-point value F, using FIELD to identify it. */
213 dump_fixed (dump_info_p di
, const char *field
, const FIXED_VALUE_TYPE
*f
)
216 fixed_to_decimal (buf
, f
, sizeof (buf
));
217 dump_maybe_newline (di
);
218 fprintf (di
->stream
, "%-4s: %s ", field
, buf
);
219 di
->column
+= strlen (buf
) + 7;
223 /* Dump the string S. */
226 dump_string (dump_info_p di
, const char *string
)
228 dump_maybe_newline (di
);
229 fprintf (di
->stream
, "%-13s ", string
);
230 if (strlen (string
) > 13)
231 di
->column
+= strlen (string
) + 1;
236 /* Dump the string field S. */
239 dump_string_field (dump_info_p di
, const char *field
, const char *string
)
241 dump_maybe_newline (di
);
242 fprintf (di
->stream
, "%-4s: %-7s ", field
, string
);
243 if (strlen (string
) > 7)
244 di
->column
+= 6 + strlen (string
) + 1;
249 /* Dump the next node in the queue. */
252 dequeue_and_dump (dump_info_p di
)
256 dump_node_info_p dni
;
260 enum tree_code_class code_class
;
261 const char* code_name
;
263 /* Get the next node from the queue. */
267 dni
= (dump_node_info_p
) stn
->value
;
270 /* Remove the node from the queue, and put it on the free list. */
271 di
->queue
= dq
->next
;
274 dq
->next
= di
->free_list
;
277 /* Print the node index. */
278 dump_index (di
, index
);
279 /* And the type of node this is. */
283 code_name
= get_tree_code_name (TREE_CODE (t
));
284 fprintf (di
->stream
, "%-16s ", code_name
);
287 /* Figure out what kind of node this is. */
288 code
= TREE_CODE (t
);
289 code_class
= TREE_CODE_CLASS (code
);
291 /* Although BINFOs are TREE_VECs, we dump them specially so as to be
297 vec
<tree
, va_gc
> *accesses
= BINFO_BASE_ACCESSES (t
);
299 dump_child ("type", BINFO_TYPE (t
));
301 if (BINFO_VIRTUAL_P (t
))
302 dump_string_field (di
, "spec", "virt");
304 dump_int (di
, "bases", BINFO_N_BASE_BINFOS (t
));
305 for (ix
= 0; BINFO_BASE_ITERATE (t
, ix
, base
); ix
++)
307 tree access
= (accesses
? (*accesses
)[ix
] : access_public_node
);
308 const char *string
= NULL
;
310 if (access
== access_public_node
)
312 else if (access
== access_protected_node
)
314 else if (access
== access_private_node
)
319 dump_string_field (di
, "accs", string
);
320 queue_and_dump_index (di
, "binf", base
, DUMP_BINFO
);
326 /* We can knock off a bunch of expression nodes in exactly the same
328 if (IS_EXPR_CODE_CLASS (code_class
))
330 /* If we're dumping children, dump them now. */
331 queue_and_dump_type (di
, t
);
336 dump_child ("op 0", TREE_OPERAND (t
, 0));
341 dump_child ("op 0", TREE_OPERAND (t
, 0));
342 dump_child ("op 1", TREE_OPERAND (t
, 1));
349 /* These nodes are handled explicitly below. */
358 expanded_location xloc
;
359 /* All declarations have names. */
361 dump_child ("name", DECL_NAME (t
));
362 if (DECL_ASSEMBLER_NAME_SET_P (t
)
363 && DECL_ASSEMBLER_NAME (t
) != DECL_NAME (t
))
364 dump_child ("mngl", DECL_ASSEMBLER_NAME (t
));
365 if (DECL_ABSTRACT_ORIGIN (t
))
366 dump_child ("orig", DECL_ABSTRACT_ORIGIN (t
));
368 queue_and_dump_type (di
, t
);
369 dump_child ("scpe", DECL_CONTEXT (t
));
370 /* And a source position. */
371 xloc
= expand_location (DECL_SOURCE_LOCATION (t
));
374 const char *filename
= lbasename (xloc
.file
);
376 dump_maybe_newline (di
);
377 fprintf (di
->stream
, "srcp: %s:%-6d ", filename
,
379 di
->column
+= 6 + strlen (filename
) + 8;
381 /* And any declaration can be compiler-generated. */
382 if (CODE_CONTAINS_STRUCT (TREE_CODE (t
), TS_DECL_COMMON
)
383 && DECL_ARTIFICIAL (t
))
384 dump_string_field (di
, "note", "artificial");
385 if (DECL_CHAIN (t
) && !dump_flag (di
, TDF_SLIM
, NULL
))
386 dump_child ("chain", DECL_CHAIN (t
));
388 else if (code_class
== tcc_type
)
390 /* All types have qualifiers. */
391 int quals
= lang_hooks
.tree_dump
.type_quals (t
);
393 if (quals
!= TYPE_UNQUALIFIED
)
395 fprintf (di
->stream
, "qual: %c%c%c ",
396 (quals
& TYPE_QUAL_CONST
) ? 'c' : ' ',
397 (quals
& TYPE_QUAL_VOLATILE
) ? 'v' : ' ',
398 (quals
& TYPE_QUAL_RESTRICT
) ? 'r' : ' ');
402 /* All types have associated declarations. */
403 dump_child ("name", TYPE_NAME (t
));
405 /* All types have a main variant. */
406 if (TYPE_MAIN_VARIANT (t
) != t
)
407 dump_child ("unql", TYPE_MAIN_VARIANT (t
));
410 dump_child ("size", TYPE_SIZE (t
));
412 /* All types have alignments. */
413 dump_int (di
, "algn", TYPE_ALIGN (t
));
415 else if (code_class
== tcc_constant
)
416 /* All constants can have types. */
417 queue_and_dump_type (di
, t
);
419 /* Give the language-specific code a chance to print something. If
420 it's completely taken care of things, don't bother printing
421 anything more ourselves. */
422 if (lang_hooks
.tree_dump
.dump_tree (di
, t
))
425 /* Now handle the various kinds of nodes. */
430 case IDENTIFIER_NODE
:
431 dump_string_field (di
, "strg", IDENTIFIER_POINTER (t
));
432 dump_int (di
, "lngt", IDENTIFIER_LENGTH (t
));
436 dump_child ("purp", TREE_PURPOSE (t
));
437 dump_child ("valu", TREE_VALUE (t
));
438 dump_child ("chan", TREE_CHAIN (t
));
443 tree_stmt_iterator it
;
444 for (i
= 0, it
= tsi_start (t
); !tsi_end_p (it
); tsi_next (&it
), i
++)
447 sprintf (buffer
, "%u", i
);
448 dump_child (buffer
, tsi_stmt (it
));
454 dump_int (di
, "lngt", TREE_VEC_LENGTH (t
));
455 for (i
= 0; i
< TREE_VEC_LENGTH (t
); ++i
)
458 sprintf (buffer
, "%u", i
);
459 dump_child (buffer
, TREE_VEC_ELT (t
, i
));
465 dump_int (di
, "prec", TYPE_PRECISION (t
));
466 dump_string_field (di
, "sign", TYPE_UNSIGNED (t
) ? "unsigned": "signed");
467 dump_child ("min", TYPE_MIN_VALUE (t
));
468 dump_child ("max", TYPE_MAX_VALUE (t
));
470 if (code
== ENUMERAL_TYPE
)
471 dump_child ("csts", TYPE_VALUES (t
));
475 dump_int (di
, "prec", TYPE_PRECISION (t
));
478 case FIXED_POINT_TYPE
:
479 dump_int (di
, "prec", TYPE_PRECISION (t
));
480 dump_string_field (di
, "sign", TYPE_UNSIGNED (t
) ? "unsigned": "signed");
481 dump_string_field (di
, "saturating",
482 TYPE_SATURATING (t
) ? "saturating": "non-saturating");
486 dump_child ("ptd", TREE_TYPE (t
));
490 dump_child ("refd", TREE_TYPE (t
));
494 dump_child ("clas", TYPE_METHOD_BASETYPE (t
));
498 dump_child ("retn", TREE_TYPE (t
));
499 dump_child ("prms", TYPE_ARG_TYPES (t
));
503 dump_child ("elts", TREE_TYPE (t
));
504 dump_child ("domn", TYPE_DOMAIN (t
));
509 if (TREE_CODE (t
) == RECORD_TYPE
)
510 dump_string_field (di
, "tag", "struct");
512 dump_string_field (di
, "tag", "union");
514 dump_child ("flds", TYPE_FIELDS (t
));
515 dump_child ("fncs", TYPE_METHODS (t
));
516 queue_and_dump_index (di
, "binf", TYPE_BINFO (t
),
521 dump_child ("cnst", DECL_INITIAL (t
));
524 case DEBUG_EXPR_DECL
:
525 dump_int (di
, "-uid", DEBUG_TEMP_UID (t
));
532 if (TREE_CODE (t
) == PARM_DECL
)
533 dump_child ("argt", DECL_ARG_TYPE (t
));
535 dump_child ("init", DECL_INITIAL (t
));
536 dump_child ("size", DECL_SIZE (t
));
537 dump_int (di
, "algn", DECL_ALIGN (t
));
539 if (TREE_CODE (t
) == FIELD_DECL
)
541 if (DECL_FIELD_OFFSET (t
))
542 dump_child ("bpos", bit_position (t
));
544 else if (TREE_CODE (t
) == VAR_DECL
545 || TREE_CODE (t
) == PARM_DECL
)
547 dump_int (di
, "used", TREE_USED (t
));
548 if (DECL_REGISTER (t
))
549 dump_string_field (di
, "spec", "register");
554 dump_child ("args", DECL_ARGUMENTS (t
));
555 if (DECL_EXTERNAL (t
))
556 dump_string_field (di
, "body", "undefined");
558 dump_string_field (di
, "link", "extern");
560 dump_string_field (di
, "link", "static");
561 if (DECL_SAVED_TREE (t
) && !dump_flag (di
, TDF_SLIM
, t
))
562 dump_child ("body", DECL_SAVED_TREE (t
));
566 fprintf (di
->stream
, "int: ");
567 print_decs (t
, di
->stream
);
571 fprintf (di
->stream
, "strg: %-7s ", TREE_STRING_POINTER (t
));
572 dump_int (di
, "lngt", TREE_STRING_LENGTH (t
));
576 dump_real (di
, "valu", TREE_REAL_CST_PTR (t
));
580 dump_fixed (di
, "valu", TREE_FIXED_CST_PTR (t
));
586 case CLEANUP_POINT_EXPR
:
590 /* These nodes are unary, but do not have code class `1'. */
591 dump_child ("op 0", TREE_OPERAND (t
, 0));
594 case TRUTH_ANDIF_EXPR
:
595 case TRUTH_ORIF_EXPR
:
599 case PREDECREMENT_EXPR
:
600 case PREINCREMENT_EXPR
:
601 case POSTDECREMENT_EXPR
:
602 case POSTINCREMENT_EXPR
:
603 /* These nodes are binary, but do not have code class `2'. */
604 dump_child ("op 0", TREE_OPERAND (t
, 0));
605 dump_child ("op 1", TREE_OPERAND (t
, 1));
610 dump_child ("op 0", TREE_OPERAND (t
, 0));
611 dump_child ("op 1", TREE_OPERAND (t
, 1));
612 dump_child ("op 2", TREE_OPERAND (t
, 2));
616 case ARRAY_RANGE_REF
:
617 dump_child ("op 0", TREE_OPERAND (t
, 0));
618 dump_child ("op 1", TREE_OPERAND (t
, 1));
619 dump_child ("op 2", TREE_OPERAND (t
, 2));
620 dump_child ("op 3", TREE_OPERAND (t
, 3));
624 dump_child ("op 0", TREE_OPERAND (t
, 0));
625 dump_child ("op 1", TREE_OPERAND (t
, 1));
626 dump_child ("op 2", TREE_OPERAND (t
, 2));
629 case TRY_FINALLY_EXPR
:
630 dump_child ("op 0", TREE_OPERAND (t
, 0));
631 dump_child ("op 1", TREE_OPERAND (t
, 1));
638 call_expr_arg_iterator iter
;
639 dump_child ("fn", CALL_EXPR_FN (t
));
640 FOR_EACH_CALL_EXPR_ARG (arg
, iter
, t
)
643 sprintf (buffer
, "%u", i
);
644 dump_child (buffer
, arg
);
652 unsigned HOST_WIDE_INT cnt
;
654 dump_int (di
, "lngt", vec_safe_length (CONSTRUCTOR_ELTS (t
)));
655 FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (t
), cnt
, index
, value
)
657 dump_child ("idx", index
);
658 dump_child ("val", value
);
664 dump_child ("vars", TREE_OPERAND (t
, 0));
665 dump_child ("body", TREE_OPERAND (t
, 1));
669 dump_child ("body", TREE_OPERAND (t
, 0));
673 dump_child ("cond", TREE_OPERAND (t
, 0));
677 dump_child ("expr", TREE_OPERAND (t
, 0));
681 dump_child ("decl", TREE_OPERAND (t
, 0));
682 dump_child ("init", TREE_OPERAND (t
, 1));
683 dump_child ("clnp", TREE_OPERAND (t
, 2));
684 /* There really are two possible places the initializer can be.
685 After RTL expansion, the second operand is moved to the
686 position of the fourth operand, and the second operand
688 dump_child ("init", TREE_OPERAND (t
, 3));
691 case CASE_LABEL_EXPR
:
692 dump_child ("name", CASE_LABEL (t
));
695 dump_child ("low ", CASE_LOW (t
));
697 dump_child ("high", CASE_HIGH (t
));
701 dump_child ("name", TREE_OPERAND (t
,0));
704 dump_child ("labl", TREE_OPERAND (t
, 0));
707 dump_child ("cond", TREE_OPERAND (t
, 0));
708 dump_child ("body", TREE_OPERAND (t
, 1));
709 if (TREE_OPERAND (t
, 2))
711 dump_child ("labl", TREE_OPERAND (t
,2));
717 fprintf (di
->stream
, "%s\n", omp_clause_code_name
[OMP_CLAUSE_CODE (t
)]);
718 for (i
= 0; i
< omp_clause_num_ops
[OMP_CLAUSE_CODE (t
)]; i
++)
719 dump_child ("op: ", OMP_CLAUSE_OPERAND (t
, i
));
723 /* There are no additional fields to print. */
728 if (dump_flag (di
, TDF_ADDRESS
, NULL
))
729 dump_pointer (di
, "addr", (void *)t
);
731 /* Terminate the line. */
732 fprintf (di
->stream
, "\n");
735 /* Return nonzero if FLAG has been specified for the dump, and NODE
736 is not the root node of the dump. */
738 int dump_flag (dump_info_p di
, int flag
, const_tree node
)
740 return (di
->flags
& flag
) && (node
!= di
->node
);
743 /* Dump T, and all its children, on STREAM. */
746 dump_node (const_tree t
, int flags
, FILE *stream
)
750 dump_queue_p next_dq
;
752 /* Initialize the dump-information structure. */
761 di
.nodes
= splay_tree_new (splay_tree_compare_pointers
, 0,
762 (splay_tree_delete_value_fn
) &free
);
764 /* Queue up the first node. */
765 queue (&di
, t
, DUMP_NONE
);
767 /* Until the queue is empty, keep dumping nodes. */
769 dequeue_and_dump (&di
);
772 for (dq
= di
.free_list
; dq
; dq
= next_dq
)
777 splay_tree_delete (di
.nodes
);