1 /* Tree-dumping functionality for intermediate representation.
2 Copyright (C) 1999-2013 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"
33 static unsigned int queue (dump_info_p
, const_tree
, int);
34 static void dump_index (dump_info_p
, unsigned int);
35 static void dequeue_and_dump (dump_info_p
);
36 static void dump_new_line (dump_info_p
);
37 static void dump_maybe_newline (dump_info_p
);
39 /* Add T to the end of the queue of nodes to dump. Returns the index
43 queue (dump_info_p di
, const_tree t
, int flags
)
49 /* Assign the next available index to T. */
52 /* Obtain a new queue node. */
56 di
->free_list
= dq
->next
;
59 dq
= XNEW (struct dump_queue
);
61 /* Create a new entry in the splay-tree. */
62 dni
= XNEW (struct dump_node_info
);
64 dni
->binfo_p
= ((flags
& DUMP_BINFO
) != 0);
65 dq
->node
= splay_tree_insert (di
->nodes
, (splay_tree_key
) t
,
66 (splay_tree_value
) dni
);
68 /* Add it to the end of the queue. */
73 di
->queue_end
->next
= dq
;
76 /* Return the index. */
81 dump_index (dump_info_p di
, unsigned int index
)
83 fprintf (di
->stream
, "@%-6u ", index
);
87 /* If T has not already been output, queue it for subsequent output.
88 FIELD is a string to print before printing the index. Then, the
89 index of T is printed. */
92 queue_and_dump_index (dump_info_p di
, const char *field
, const_tree t
, int flags
)
97 /* If there's no node, just return. This makes for fewer checks in
102 /* See if we've already queued or dumped this node. */
103 n
= splay_tree_lookup (di
->nodes
, (splay_tree_key
) t
);
105 index
= ((dump_node_info_p
) n
->value
)->index
;
107 /* If we haven't, add it to the queue. */
108 index
= queue (di
, t
, flags
);
110 /* Print the index of the node. */
111 dump_maybe_newline (di
);
112 fprintf (di
->stream
, "%-4s: ", field
);
114 dump_index (di
, index
);
117 /* Dump the type of T. */
120 queue_and_dump_type (dump_info_p di
, const_tree t
)
122 queue_and_dump_index (di
, "type", TREE_TYPE (t
), DUMP_NONE
);
125 /* Dump column control */
126 #define SOL_COLUMN 25 /* Start of line column. */
127 #define EOL_COLUMN 55 /* End of line column. */
128 #define COLUMN_ALIGNMENT 15 /* Alignment. */
130 /* Insert a new line in the dump output, and indent to an appropriate
131 place to start printing more fields. */
134 dump_new_line (dump_info_p di
)
136 fprintf (di
->stream
, "\n%*s", SOL_COLUMN
, "");
137 di
->column
= SOL_COLUMN
;
140 /* If necessary, insert a new line. */
143 dump_maybe_newline (dump_info_p di
)
147 /* See if we need a new line. */
148 if (di
->column
> EOL_COLUMN
)
150 /* See if we need any padding. */
151 else if ((extra
= (di
->column
- SOL_COLUMN
) % COLUMN_ALIGNMENT
) != 0)
153 fprintf (di
->stream
, "%*s", COLUMN_ALIGNMENT
- extra
, "");
154 di
->column
+= COLUMN_ALIGNMENT
- extra
;
158 /* Dump FUNCTION_DECL FN as tree dump PHASE. */
161 dump_function (int phase
, tree fn
)
166 stream
= dump_begin (phase
, &flags
);
169 dump_function_to_file (fn
, stream
, flags
);
170 dump_end (phase
, stream
);
174 /* Dump pointer PTR using FIELD to identify it. */
177 dump_pointer (dump_info_p di
, const char *field
, void *ptr
)
179 dump_maybe_newline (di
);
180 fprintf (di
->stream
, "%-4s: %-8" HOST_WIDE_INT_PRINT
"x ", field
,
181 (unsigned HOST_WIDE_INT
) (uintptr_t) ptr
);
185 /* Dump integer I using FIELD to identify it. */
188 dump_int (dump_info_p di
, const char *field
, int i
)
190 dump_maybe_newline (di
);
191 fprintf (di
->stream
, "%-4s: %-7d ", field
, i
);
195 /* Dump the floating point value R, using FIELD to identify it. */
198 dump_real (dump_info_p di
, const char *field
, const REAL_VALUE_TYPE
*r
)
201 real_to_decimal (buf
, r
, sizeof (buf
), 0, true);
202 dump_maybe_newline (di
);
203 fprintf (di
->stream
, "%-4s: %s ", field
, buf
);
204 di
->column
+= strlen (buf
) + 7;
207 /* Dump the fixed-point value F, using FIELD to identify it. */
210 dump_fixed (dump_info_p di
, const char *field
, const FIXED_VALUE_TYPE
*f
)
213 fixed_to_decimal (buf
, f
, sizeof (buf
));
214 dump_maybe_newline (di
);
215 fprintf (di
->stream
, "%-4s: %s ", field
, buf
);
216 di
->column
+= strlen (buf
) + 7;
220 /* Dump the string S. */
223 dump_string (dump_info_p di
, const char *string
)
225 dump_maybe_newline (di
);
226 fprintf (di
->stream
, "%-13s ", string
);
227 if (strlen (string
) > 13)
228 di
->column
+= strlen (string
) + 1;
233 /* Dump the string field S. */
236 dump_string_field (dump_info_p di
, const char *field
, const char *string
)
238 dump_maybe_newline (di
);
239 fprintf (di
->stream
, "%-4s: %-7s ", field
, string
);
240 if (strlen (string
) > 7)
241 di
->column
+= 6 + strlen (string
) + 1;
246 /* Dump the next node in the queue. */
249 dequeue_and_dump (dump_info_p di
)
253 dump_node_info_p dni
;
257 enum tree_code_class code_class
;
258 const char* code_name
;
260 /* Get the next node from the queue. */
264 dni
= (dump_node_info_p
) stn
->value
;
267 /* Remove the node from the queue, and put it on the free list. */
268 di
->queue
= dq
->next
;
271 dq
->next
= di
->free_list
;
274 /* Print the node index. */
275 dump_index (di
, index
);
276 /* And the type of node this is. */
280 code_name
= tree_code_name
[(int) TREE_CODE (t
)];
281 fprintf (di
->stream
, "%-16s ", code_name
);
284 /* Figure out what kind of node this is. */
285 code
= TREE_CODE (t
);
286 code_class
= TREE_CODE_CLASS (code
);
288 /* Although BINFOs are TREE_VECs, we dump them specially so as to be
294 vec
<tree
, va_gc
> *accesses
= BINFO_BASE_ACCESSES (t
);
296 dump_child ("type", BINFO_TYPE (t
));
298 if (BINFO_VIRTUAL_P (t
))
299 dump_string_field (di
, "spec", "virt");
301 dump_int (di
, "bases", BINFO_N_BASE_BINFOS (t
));
302 for (ix
= 0; BINFO_BASE_ITERATE (t
, ix
, base
); ix
++)
304 tree access
= (accesses
? (*accesses
)[ix
] : access_public_node
);
305 const char *string
= NULL
;
307 if (access
== access_public_node
)
309 else if (access
== access_protected_node
)
311 else if (access
== access_private_node
)
316 dump_string_field (di
, "accs", string
);
317 queue_and_dump_index (di
, "binf", base
, DUMP_BINFO
);
323 /* We can knock off a bunch of expression nodes in exactly the same
325 if (IS_EXPR_CODE_CLASS (code_class
))
327 /* If we're dumping children, dump them now. */
328 queue_and_dump_type (di
, t
);
333 dump_child ("op 0", TREE_OPERAND (t
, 0));
338 dump_child ("op 0", TREE_OPERAND (t
, 0));
339 dump_child ("op 1", TREE_OPERAND (t
, 1));
346 /* These nodes are handled explicitly below. */
355 expanded_location xloc
;
356 /* All declarations have names. */
358 dump_child ("name", DECL_NAME (t
));
359 if (DECL_ASSEMBLER_NAME_SET_P (t
)
360 && DECL_ASSEMBLER_NAME (t
) != DECL_NAME (t
))
361 dump_child ("mngl", DECL_ASSEMBLER_NAME (t
));
362 if (DECL_ABSTRACT_ORIGIN (t
))
363 dump_child ("orig", DECL_ABSTRACT_ORIGIN (t
));
365 queue_and_dump_type (di
, t
);
366 dump_child ("scpe", DECL_CONTEXT (t
));
367 /* And a source position. */
368 xloc
= expand_location (DECL_SOURCE_LOCATION (t
));
371 const char *filename
= lbasename (xloc
.file
);
373 dump_maybe_newline (di
);
374 fprintf (di
->stream
, "srcp: %s:%-6d ", filename
,
376 di
->column
+= 6 + strlen (filename
) + 8;
378 /* And any declaration can be compiler-generated. */
379 if (CODE_CONTAINS_STRUCT (TREE_CODE (t
), TS_DECL_COMMON
)
380 && DECL_ARTIFICIAL (t
))
381 dump_string_field (di
, "note", "artificial");
382 if (DECL_CHAIN (t
) && !dump_flag (di
, TDF_SLIM
, NULL
))
383 dump_child ("chain", DECL_CHAIN (t
));
385 else if (code_class
== tcc_type
)
387 /* All types have qualifiers. */
388 int quals
= lang_hooks
.tree_dump
.type_quals (t
);
390 if (quals
!= TYPE_UNQUALIFIED
)
392 fprintf (di
->stream
, "qual: %c%c%c ",
393 (quals
& TYPE_QUAL_CONST
) ? 'c' : ' ',
394 (quals
& TYPE_QUAL_VOLATILE
) ? 'v' : ' ',
395 (quals
& TYPE_QUAL_RESTRICT
) ? 'r' : ' ');
399 /* All types have associated declarations. */
400 dump_child ("name", TYPE_NAME (t
));
402 /* All types have a main variant. */
403 if (TYPE_MAIN_VARIANT (t
) != t
)
404 dump_child ("unql", TYPE_MAIN_VARIANT (t
));
407 dump_child ("size", TYPE_SIZE (t
));
409 /* All types have alignments. */
410 dump_int (di
, "algn", TYPE_ALIGN (t
));
412 else if (code_class
== tcc_constant
)
413 /* All constants can have types. */
414 queue_and_dump_type (di
, t
);
416 /* Give the language-specific code a chance to print something. If
417 it's completely taken care of things, don't bother printing
418 anything more ourselves. */
419 if (lang_hooks
.tree_dump
.dump_tree (di
, t
))
422 /* Now handle the various kinds of nodes. */
427 case IDENTIFIER_NODE
:
428 dump_string_field (di
, "strg", IDENTIFIER_POINTER (t
));
429 dump_int (di
, "lngt", IDENTIFIER_LENGTH (t
));
433 dump_child ("purp", TREE_PURPOSE (t
));
434 dump_child ("valu", TREE_VALUE (t
));
435 dump_child ("chan", TREE_CHAIN (t
));
440 tree_stmt_iterator it
;
441 for (i
= 0, it
= tsi_start (t
); !tsi_end_p (it
); tsi_next (&it
), i
++)
444 sprintf (buffer
, "%u", i
);
445 dump_child (buffer
, tsi_stmt (it
));
451 dump_int (di
, "lngt", TREE_VEC_LENGTH (t
));
452 for (i
= 0; i
< TREE_VEC_LENGTH (t
); ++i
)
455 sprintf (buffer
, "%u", i
);
456 dump_child (buffer
, TREE_VEC_ELT (t
, i
));
462 dump_int (di
, "prec", TYPE_PRECISION (t
));
463 dump_string_field (di
, "sign", TYPE_UNSIGNED (t
) ? "unsigned": "signed");
464 dump_child ("min", TYPE_MIN_VALUE (t
));
465 dump_child ("max", TYPE_MAX_VALUE (t
));
467 if (code
== ENUMERAL_TYPE
)
468 dump_child ("csts", TYPE_VALUES (t
));
472 dump_int (di
, "prec", TYPE_PRECISION (t
));
475 case FIXED_POINT_TYPE
:
476 dump_int (di
, "prec", TYPE_PRECISION (t
));
477 dump_string_field (di
, "sign", TYPE_UNSIGNED (t
) ? "unsigned": "signed");
478 dump_string_field (di
, "saturating",
479 TYPE_SATURATING (t
) ? "saturating": "non-saturating");
483 dump_child ("ptd", TREE_TYPE (t
));
487 dump_child ("refd", TREE_TYPE (t
));
491 dump_child ("clas", TYPE_METHOD_BASETYPE (t
));
495 dump_child ("retn", TREE_TYPE (t
));
496 dump_child ("prms", TYPE_ARG_TYPES (t
));
500 dump_child ("elts", TREE_TYPE (t
));
501 dump_child ("domn", TYPE_DOMAIN (t
));
506 if (TREE_CODE (t
) == RECORD_TYPE
)
507 dump_string_field (di
, "tag", "struct");
509 dump_string_field (di
, "tag", "union");
511 dump_child ("flds", TYPE_FIELDS (t
));
512 dump_child ("fncs", TYPE_METHODS (t
));
513 queue_and_dump_index (di
, "binf", TYPE_BINFO (t
),
518 dump_child ("cnst", DECL_INITIAL (t
));
521 case DEBUG_EXPR_DECL
:
522 dump_int (di
, "-uid", DEBUG_TEMP_UID (t
));
529 if (TREE_CODE (t
) == PARM_DECL
)
530 dump_child ("argt", DECL_ARG_TYPE (t
));
532 dump_child ("init", DECL_INITIAL (t
));
533 dump_child ("size", DECL_SIZE (t
));
534 dump_int (di
, "algn", DECL_ALIGN (t
));
536 if (TREE_CODE (t
) == FIELD_DECL
)
538 if (DECL_FIELD_OFFSET (t
))
539 dump_child ("bpos", bit_position (t
));
541 else if (TREE_CODE (t
) == VAR_DECL
542 || TREE_CODE (t
) == PARM_DECL
)
544 dump_int (di
, "used", TREE_USED (t
));
545 if (DECL_REGISTER (t
))
546 dump_string_field (di
, "spec", "register");
551 dump_child ("args", DECL_ARGUMENTS (t
));
552 if (DECL_EXTERNAL (t
))
553 dump_string_field (di
, "body", "undefined");
555 dump_string_field (di
, "link", "extern");
557 dump_string_field (di
, "link", "static");
558 if (DECL_SAVED_TREE (t
) && !dump_flag (di
, TDF_SLIM
, t
))
559 dump_child ("body", DECL_SAVED_TREE (t
));
563 if (TREE_INT_CST_HIGH (t
))
564 dump_int (di
, "high", TREE_INT_CST_HIGH (t
));
565 dump_int (di
, "low", TREE_INT_CST_LOW (t
));
569 fprintf (di
->stream
, "strg: %-7s ", TREE_STRING_POINTER (t
));
570 dump_int (di
, "lngt", TREE_STRING_LENGTH (t
));
574 dump_real (di
, "valu", TREE_REAL_CST_PTR (t
));
578 dump_fixed (di
, "valu", TREE_FIXED_CST_PTR (t
));
584 case CLEANUP_POINT_EXPR
:
588 /* These nodes are unary, but do not have code class `1'. */
589 dump_child ("op 0", TREE_OPERAND (t
, 0));
592 case TRUTH_ANDIF_EXPR
:
593 case TRUTH_ORIF_EXPR
:
597 case PREDECREMENT_EXPR
:
598 case PREINCREMENT_EXPR
:
599 case POSTDECREMENT_EXPR
:
600 case POSTINCREMENT_EXPR
:
601 /* These nodes are binary, but do not have code class `2'. */
602 dump_child ("op 0", TREE_OPERAND (t
, 0));
603 dump_child ("op 1", TREE_OPERAND (t
, 1));
608 dump_child ("op 0", TREE_OPERAND (t
, 0));
609 dump_child ("op 1", TREE_OPERAND (t
, 1));
610 dump_child ("op 2", TREE_OPERAND (t
, 2));
614 case ARRAY_RANGE_REF
:
615 dump_child ("op 0", TREE_OPERAND (t
, 0));
616 dump_child ("op 1", TREE_OPERAND (t
, 1));
617 dump_child ("op 2", TREE_OPERAND (t
, 2));
618 dump_child ("op 3", TREE_OPERAND (t
, 3));
622 dump_child ("op 0", TREE_OPERAND (t
, 0));
623 dump_child ("op 1", TREE_OPERAND (t
, 1));
624 dump_child ("op 2", TREE_OPERAND (t
, 2));
627 case TRY_FINALLY_EXPR
:
628 dump_child ("op 0", TREE_OPERAND (t
, 0));
629 dump_child ("op 1", TREE_OPERAND (t
, 1));
636 call_expr_arg_iterator iter
;
637 dump_child ("fn", CALL_EXPR_FN (t
));
638 FOR_EACH_CALL_EXPR_ARG (arg
, iter
, t
)
641 sprintf (buffer
, "%u", i
);
642 dump_child (buffer
, arg
);
650 unsigned HOST_WIDE_INT cnt
;
652 dump_int (di
, "lngt", vec_safe_length (CONSTRUCTOR_ELTS (t
)));
653 FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (t
), cnt
, index
, value
)
655 dump_child ("idx", index
);
656 dump_child ("val", value
);
662 dump_child ("vars", TREE_OPERAND (t
, 0));
663 dump_child ("body", TREE_OPERAND (t
, 1));
667 dump_child ("body", TREE_OPERAND (t
, 0));
671 dump_child ("cond", TREE_OPERAND (t
, 0));
675 dump_child ("expr", TREE_OPERAND (t
, 0));
679 dump_child ("decl", TREE_OPERAND (t
, 0));
680 dump_child ("init", TREE_OPERAND (t
, 1));
681 dump_child ("clnp", TREE_OPERAND (t
, 2));
682 /* There really are two possible places the initializer can be.
683 After RTL expansion, the second operand is moved to the
684 position of the fourth operand, and the second operand
686 dump_child ("init", TREE_OPERAND (t
, 3));
689 case CASE_LABEL_EXPR
:
690 dump_child ("name", CASE_LABEL (t
));
693 dump_child ("low ", CASE_LOW (t
));
695 dump_child ("high", CASE_HIGH (t
));
699 dump_child ("name", TREE_OPERAND (t
,0));
702 dump_child ("labl", TREE_OPERAND (t
, 0));
705 dump_child ("cond", TREE_OPERAND (t
, 0));
706 dump_child ("body", TREE_OPERAND (t
, 1));
707 if (TREE_OPERAND (t
, 2))
709 dump_child ("labl", TREE_OPERAND (t
,2));
715 fprintf (di
->stream
, "%s\n", omp_clause_code_name
[OMP_CLAUSE_CODE (t
)]);
716 for (i
= 0; i
< omp_clause_num_ops
[OMP_CLAUSE_CODE (t
)]; i
++)
717 dump_child ("op: ", OMP_CLAUSE_OPERAND (t
, i
));
721 /* There are no additional fields to print. */
726 if (dump_flag (di
, TDF_ADDRESS
, NULL
))
727 dump_pointer (di
, "addr", (void *)t
);
729 /* Terminate the line. */
730 fprintf (di
->stream
, "\n");
733 /* Return nonzero if FLAG has been specified for the dump, and NODE
734 is not the root node of the dump. */
736 int dump_flag (dump_info_p di
, int flag
, const_tree node
)
738 return (di
->flags
& flag
) && (node
!= di
->node
);
741 /* Dump T, and all its children, on STREAM. */
744 dump_node (const_tree t
, int flags
, FILE *stream
)
748 dump_queue_p next_dq
;
750 /* Initialize the dump-information structure. */
759 di
.nodes
= splay_tree_new (splay_tree_compare_pointers
, 0,
760 (splay_tree_delete_value_fn
) &free
);
762 /* Queue up the first node. */
763 queue (&di
, t
, DUMP_NONE
);
765 /* Until the queue is empty, keep dumping nodes. */
767 dequeue_and_dump (&di
);
770 for (dq
= di
.free_list
; dq
; dq
= next_dq
)
775 splay_tree_delete (di
.nodes
);