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"
34 static unsigned int queue (dump_info_p
, const_tree
, int);
35 static void dump_index (dump_info_p
, unsigned int);
36 static void dequeue_and_dump (dump_info_p
);
37 static void dump_new_line (dump_info_p
);
38 static void dump_maybe_newline (dump_info_p
);
40 /* Add T to the end of the queue of nodes to dump. Returns the index
44 queue (dump_info_p di
, const_tree t
, int flags
)
50 /* Assign the next available index to T. */
53 /* Obtain a new queue node. */
57 di
->free_list
= dq
->next
;
60 dq
= XNEW (struct dump_queue
);
62 /* Create a new entry in the splay-tree. */
63 dni
= XNEW (struct dump_node_info
);
65 dni
->binfo_p
= ((flags
& DUMP_BINFO
) != 0);
66 dq
->node
= splay_tree_insert (di
->nodes
, (splay_tree_key
) t
,
67 (splay_tree_value
) dni
);
69 /* Add it to the end of the queue. */
74 di
->queue_end
->next
= dq
;
77 /* Return the index. */
82 dump_index (dump_info_p di
, unsigned int index
)
84 fprintf (di
->stream
, "@%-6u ", index
);
88 /* If T has not already been output, queue it for subsequent output.
89 FIELD is a string to print before printing the index. Then, the
90 index of T is printed. */
93 queue_and_dump_index (dump_info_p di
, const char *field
, const_tree t
, int flags
)
98 /* If there's no node, just return. This makes for fewer checks in
103 /* See if we've already queued or dumped this node. */
104 n
= splay_tree_lookup (di
->nodes
, (splay_tree_key
) t
);
106 index
= ((dump_node_info_p
) n
->value
)->index
;
108 /* If we haven't, add it to the queue. */
109 index
= queue (di
, t
, flags
);
111 /* Print the index of the node. */
112 dump_maybe_newline (di
);
113 fprintf (di
->stream
, "%-4s: ", field
);
115 dump_index (di
, index
);
118 /* Dump the type of T. */
121 queue_and_dump_type (dump_info_p di
, const_tree t
)
123 queue_and_dump_index (di
, "type", TREE_TYPE (t
), DUMP_NONE
);
126 /* Dump column control */
127 #define SOL_COLUMN 25 /* Start of line column. */
128 #define EOL_COLUMN 55 /* End of line column. */
129 #define COLUMN_ALIGNMENT 15 /* Alignment. */
131 /* Insert a new line in the dump output, and indent to an appropriate
132 place to start printing more fields. */
135 dump_new_line (dump_info_p di
)
137 fprintf (di
->stream
, "\n%*s", SOL_COLUMN
, "");
138 di
->column
= SOL_COLUMN
;
141 /* If necessary, insert a new line. */
144 dump_maybe_newline (dump_info_p di
)
148 /* See if we need a new line. */
149 if (di
->column
> EOL_COLUMN
)
151 /* See if we need any padding. */
152 else if ((extra
= (di
->column
- SOL_COLUMN
) % COLUMN_ALIGNMENT
) != 0)
154 fprintf (di
->stream
, "%*s", COLUMN_ALIGNMENT
- extra
, "");
155 di
->column
+= COLUMN_ALIGNMENT
- extra
;
159 /* Dump FUNCTION_DECL FN as tree dump PHASE. */
162 dump_function (int phase
, tree fn
)
167 stream
= dump_begin (phase
, &flags
);
170 dump_function_to_file (fn
, stream
, flags
);
171 dump_end (phase
, stream
);
175 /* Dump pointer PTR using FIELD to identify it. */
178 dump_pointer (dump_info_p di
, const char *field
, void *ptr
)
180 dump_maybe_newline (di
);
181 fprintf (di
->stream
, "%-4s: %-8" HOST_WIDE_INT_PRINT
"x ", field
,
182 (unsigned HOST_WIDE_INT
) (uintptr_t) ptr
);
186 /* Dump integer I using FIELD to identify it. */
189 dump_int (dump_info_p di
, const char *field
, int i
)
191 dump_maybe_newline (di
);
192 fprintf (di
->stream
, "%-4s: %-7d ", field
, i
);
196 /* Dump the floating point value R, using FIELD to identify it. */
199 dump_real (dump_info_p di
, const char *field
, const REAL_VALUE_TYPE
*r
)
202 real_to_decimal (buf
, r
, sizeof (buf
), 0, true);
203 dump_maybe_newline (di
);
204 fprintf (di
->stream
, "%-4s: %s ", field
, buf
);
205 di
->column
+= strlen (buf
) + 7;
208 /* Dump the fixed-point value F, using FIELD to identify it. */
211 dump_fixed (dump_info_p di
, const char *field
, const FIXED_VALUE_TYPE
*f
)
214 fixed_to_decimal (buf
, f
, sizeof (buf
));
215 dump_maybe_newline (di
);
216 fprintf (di
->stream
, "%-4s: %s ", field
, buf
);
217 di
->column
+= strlen (buf
) + 7;
221 /* Dump the string S. */
224 dump_string (dump_info_p di
, const char *string
)
226 dump_maybe_newline (di
);
227 fprintf (di
->stream
, "%-13s ", string
);
228 if (strlen (string
) > 13)
229 di
->column
+= strlen (string
) + 1;
234 /* Dump the string field S. */
237 dump_string_field (dump_info_p di
, const char *field
, const char *string
)
239 dump_maybe_newline (di
);
240 fprintf (di
->stream
, "%-4s: %-7s ", field
, string
);
241 if (strlen (string
) > 7)
242 di
->column
+= 6 + strlen (string
) + 1;
247 /* Dump the next node in the queue. */
250 dequeue_and_dump (dump_info_p di
)
254 dump_node_info_p dni
;
258 enum tree_code_class code_class
;
259 const char* code_name
;
261 /* Get the next node from the queue. */
265 dni
= (dump_node_info_p
) stn
->value
;
268 /* Remove the node from the queue, and put it on the free list. */
269 di
->queue
= dq
->next
;
272 dq
->next
= di
->free_list
;
275 /* Print the node index. */
276 dump_index (di
, index
);
277 /* And the type of node this is. */
281 code_name
= get_tree_code_name (TREE_CODE (t
));
282 fprintf (di
->stream
, "%-16s ", code_name
);
285 /* Figure out what kind of node this is. */
286 code
= TREE_CODE (t
);
287 code_class
= TREE_CODE_CLASS (code
);
289 /* Although BINFOs are TREE_VECs, we dump them specially so as to be
295 vec
<tree
, va_gc
> *accesses
= BINFO_BASE_ACCESSES (t
);
297 dump_child ("type", BINFO_TYPE (t
));
299 if (BINFO_VIRTUAL_P (t
))
300 dump_string_field (di
, "spec", "virt");
302 dump_int (di
, "bases", BINFO_N_BASE_BINFOS (t
));
303 for (ix
= 0; BINFO_BASE_ITERATE (t
, ix
, base
); ix
++)
305 tree access
= (accesses
? (*accesses
)[ix
] : access_public_node
);
306 const char *string
= NULL
;
308 if (access
== access_public_node
)
310 else if (access
== access_protected_node
)
312 else if (access
== access_private_node
)
317 dump_string_field (di
, "accs", string
);
318 queue_and_dump_index (di
, "binf", base
, DUMP_BINFO
);
324 /* We can knock off a bunch of expression nodes in exactly the same
326 if (IS_EXPR_CODE_CLASS (code_class
))
328 /* If we're dumping children, dump them now. */
329 queue_and_dump_type (di
, t
);
334 dump_child ("op 0", TREE_OPERAND (t
, 0));
339 dump_child ("op 0", TREE_OPERAND (t
, 0));
340 dump_child ("op 1", TREE_OPERAND (t
, 1));
347 /* These nodes are handled explicitly below. */
356 expanded_location xloc
;
357 /* All declarations have names. */
359 dump_child ("name", DECL_NAME (t
));
360 if (DECL_ASSEMBLER_NAME_SET_P (t
)
361 && DECL_ASSEMBLER_NAME (t
) != DECL_NAME (t
))
362 dump_child ("mngl", DECL_ASSEMBLER_NAME (t
));
363 if (DECL_ABSTRACT_ORIGIN (t
))
364 dump_child ("orig", DECL_ABSTRACT_ORIGIN (t
));
366 queue_and_dump_type (di
, t
);
367 dump_child ("scpe", DECL_CONTEXT (t
));
368 /* And a source position. */
369 xloc
= expand_location (DECL_SOURCE_LOCATION (t
));
372 const char *filename
= lbasename (xloc
.file
);
374 dump_maybe_newline (di
);
375 fprintf (di
->stream
, "srcp: %s:%-6d ", filename
,
377 di
->column
+= 6 + strlen (filename
) + 8;
379 /* And any declaration can be compiler-generated. */
380 if (CODE_CONTAINS_STRUCT (TREE_CODE (t
), TS_DECL_COMMON
)
381 && DECL_ARTIFICIAL (t
))
382 dump_string_field (di
, "note", "artificial");
383 if (DECL_CHAIN (t
) && !dump_flag (di
, TDF_SLIM
, NULL
))
384 dump_child ("chain", DECL_CHAIN (t
));
386 else if (code_class
== tcc_type
)
388 /* All types have qualifiers. */
389 int quals
= lang_hooks
.tree_dump
.type_quals (t
);
391 if (quals
!= TYPE_UNQUALIFIED
)
393 fprintf (di
->stream
, "qual: %c%c%c ",
394 (quals
& TYPE_QUAL_CONST
) ? 'c' : ' ',
395 (quals
& TYPE_QUAL_VOLATILE
) ? 'v' : ' ',
396 (quals
& TYPE_QUAL_RESTRICT
) ? 'r' : ' ');
400 /* All types have associated declarations. */
401 dump_child ("name", TYPE_NAME (t
));
403 /* All types have a main variant. */
404 if (TYPE_MAIN_VARIANT (t
) != t
)
405 dump_child ("unql", TYPE_MAIN_VARIANT (t
));
408 dump_child ("size", TYPE_SIZE (t
));
410 /* All types have alignments. */
411 dump_int (di
, "algn", TYPE_ALIGN (t
));
413 else if (code_class
== tcc_constant
)
414 /* All constants can have types. */
415 queue_and_dump_type (di
, t
);
417 /* Give the language-specific code a chance to print something. If
418 it's completely taken care of things, don't bother printing
419 anything more ourselves. */
420 if (lang_hooks
.tree_dump
.dump_tree (di
, t
))
423 /* Now handle the various kinds of nodes. */
428 case IDENTIFIER_NODE
:
429 dump_string_field (di
, "strg", IDENTIFIER_POINTER (t
));
430 dump_int (di
, "lngt", IDENTIFIER_LENGTH (t
));
434 dump_child ("purp", TREE_PURPOSE (t
));
435 dump_child ("valu", TREE_VALUE (t
));
436 dump_child ("chan", TREE_CHAIN (t
));
441 tree_stmt_iterator it
;
442 for (i
= 0, it
= tsi_start (t
); !tsi_end_p (it
); tsi_next (&it
), i
++)
445 sprintf (buffer
, "%u", i
);
446 dump_child (buffer
, tsi_stmt (it
));
452 dump_int (di
, "lngt", TREE_VEC_LENGTH (t
));
453 for (i
= 0; i
< TREE_VEC_LENGTH (t
); ++i
)
456 sprintf (buffer
, "%u", i
);
457 dump_child (buffer
, TREE_VEC_ELT (t
, i
));
463 dump_int (di
, "prec", TYPE_PRECISION (t
));
464 dump_string_field (di
, "sign", TYPE_UNSIGNED (t
) ? "unsigned": "signed");
465 dump_child ("min", TYPE_MIN_VALUE (t
));
466 dump_child ("max", TYPE_MAX_VALUE (t
));
468 if (code
== ENUMERAL_TYPE
)
469 dump_child ("csts", TYPE_VALUES (t
));
473 dump_int (di
, "prec", TYPE_PRECISION (t
));
476 case FIXED_POINT_TYPE
:
477 dump_int (di
, "prec", TYPE_PRECISION (t
));
478 dump_string_field (di
, "sign", TYPE_UNSIGNED (t
) ? "unsigned": "signed");
479 dump_string_field (di
, "saturating",
480 TYPE_SATURATING (t
) ? "saturating": "non-saturating");
484 dump_child ("ptd", TREE_TYPE (t
));
488 dump_child ("refd", TREE_TYPE (t
));
492 dump_child ("clas", TYPE_METHOD_BASETYPE (t
));
496 dump_child ("retn", TREE_TYPE (t
));
497 dump_child ("prms", TYPE_ARG_TYPES (t
));
501 dump_child ("elts", TREE_TYPE (t
));
502 dump_child ("domn", TYPE_DOMAIN (t
));
507 if (TREE_CODE (t
) == RECORD_TYPE
)
508 dump_string_field (di
, "tag", "struct");
510 dump_string_field (di
, "tag", "union");
512 dump_child ("flds", TYPE_FIELDS (t
));
513 dump_child ("fncs", TYPE_METHODS (t
));
514 queue_and_dump_index (di
, "binf", TYPE_BINFO (t
),
519 dump_child ("cnst", DECL_INITIAL (t
));
522 case DEBUG_EXPR_DECL
:
523 dump_int (di
, "-uid", DEBUG_TEMP_UID (t
));
530 if (TREE_CODE (t
) == PARM_DECL
)
531 dump_child ("argt", DECL_ARG_TYPE (t
));
533 dump_child ("init", DECL_INITIAL (t
));
534 dump_child ("size", DECL_SIZE (t
));
535 dump_int (di
, "algn", DECL_ALIGN (t
));
537 if (TREE_CODE (t
) == FIELD_DECL
)
539 if (DECL_FIELD_OFFSET (t
))
540 dump_child ("bpos", bit_position (t
));
542 else if (TREE_CODE (t
) == VAR_DECL
543 || TREE_CODE (t
) == PARM_DECL
)
545 dump_int (di
, "used", TREE_USED (t
));
546 if (DECL_REGISTER (t
))
547 dump_string_field (di
, "spec", "register");
552 dump_child ("args", DECL_ARGUMENTS (t
));
553 if (DECL_EXTERNAL (t
))
554 dump_string_field (di
, "body", "undefined");
556 dump_string_field (di
, "link", "extern");
558 dump_string_field (di
, "link", "static");
559 if (DECL_SAVED_TREE (t
) && !dump_flag (di
, TDF_SLIM
, t
))
560 dump_child ("body", DECL_SAVED_TREE (t
));
564 if (TREE_INT_CST_HIGH (t
))
565 dump_int (di
, "high", TREE_INT_CST_HIGH (t
));
566 dump_int (di
, "low", TREE_INT_CST_LOW (t
));
570 fprintf (di
->stream
, "strg: %-7s ", TREE_STRING_POINTER (t
));
571 dump_int (di
, "lngt", TREE_STRING_LENGTH (t
));
575 dump_real (di
, "valu", TREE_REAL_CST_PTR (t
));
579 dump_fixed (di
, "valu", TREE_FIXED_CST_PTR (t
));
585 case CLEANUP_POINT_EXPR
:
589 /* These nodes are unary, but do not have code class `1'. */
590 dump_child ("op 0", TREE_OPERAND (t
, 0));
593 case TRUTH_ANDIF_EXPR
:
594 case TRUTH_ORIF_EXPR
:
598 case PREDECREMENT_EXPR
:
599 case PREINCREMENT_EXPR
:
600 case POSTDECREMENT_EXPR
:
601 case POSTINCREMENT_EXPR
:
602 /* These nodes are binary, but do not have code class `2'. */
603 dump_child ("op 0", TREE_OPERAND (t
, 0));
604 dump_child ("op 1", TREE_OPERAND (t
, 1));
609 dump_child ("op 0", TREE_OPERAND (t
, 0));
610 dump_child ("op 1", TREE_OPERAND (t
, 1));
611 dump_child ("op 2", TREE_OPERAND (t
, 2));
615 case ARRAY_RANGE_REF
:
616 dump_child ("op 0", TREE_OPERAND (t
, 0));
617 dump_child ("op 1", TREE_OPERAND (t
, 1));
618 dump_child ("op 2", TREE_OPERAND (t
, 2));
619 dump_child ("op 3", TREE_OPERAND (t
, 3));
623 dump_child ("op 0", TREE_OPERAND (t
, 0));
624 dump_child ("op 1", TREE_OPERAND (t
, 1));
625 dump_child ("op 2", TREE_OPERAND (t
, 2));
628 case TRY_FINALLY_EXPR
:
629 dump_child ("op 0", TREE_OPERAND (t
, 0));
630 dump_child ("op 1", TREE_OPERAND (t
, 1));
637 call_expr_arg_iterator iter
;
638 dump_child ("fn", CALL_EXPR_FN (t
));
639 FOR_EACH_CALL_EXPR_ARG (arg
, iter
, t
)
642 sprintf (buffer
, "%u", i
);
643 dump_child (buffer
, arg
);
651 unsigned HOST_WIDE_INT cnt
;
653 dump_int (di
, "lngt", vec_safe_length (CONSTRUCTOR_ELTS (t
)));
654 FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (t
), cnt
, index
, value
)
656 dump_child ("idx", index
);
657 dump_child ("val", value
);
663 dump_child ("vars", TREE_OPERAND (t
, 0));
664 dump_child ("body", TREE_OPERAND (t
, 1));
668 dump_child ("body", TREE_OPERAND (t
, 0));
672 dump_child ("cond", TREE_OPERAND (t
, 0));
676 dump_child ("expr", TREE_OPERAND (t
, 0));
680 dump_child ("decl", TREE_OPERAND (t
, 0));
681 dump_child ("init", TREE_OPERAND (t
, 1));
682 dump_child ("clnp", TREE_OPERAND (t
, 2));
683 /* There really are two possible places the initializer can be.
684 After RTL expansion, the second operand is moved to the
685 position of the fourth operand, and the second operand
687 dump_child ("init", TREE_OPERAND (t
, 3));
690 case CASE_LABEL_EXPR
:
691 dump_child ("name", CASE_LABEL (t
));
694 dump_child ("low ", CASE_LOW (t
));
696 dump_child ("high", CASE_HIGH (t
));
700 dump_child ("name", TREE_OPERAND (t
,0));
703 dump_child ("labl", TREE_OPERAND (t
, 0));
706 dump_child ("cond", TREE_OPERAND (t
, 0));
707 dump_child ("body", TREE_OPERAND (t
, 1));
708 if (TREE_OPERAND (t
, 2))
710 dump_child ("labl", TREE_OPERAND (t
,2));
716 fprintf (di
->stream
, "%s\n", omp_clause_code_name
[OMP_CLAUSE_CODE (t
)]);
717 for (i
= 0; i
< omp_clause_num_ops
[OMP_CLAUSE_CODE (t
)]; i
++)
718 dump_child ("op: ", OMP_CLAUSE_OPERAND (t
, i
));
722 /* There are no additional fields to print. */
727 if (dump_flag (di
, TDF_ADDRESS
, NULL
))
728 dump_pointer (di
, "addr", (void *)t
);
730 /* Terminate the line. */
731 fprintf (di
->stream
, "\n");
734 /* Return nonzero if FLAG has been specified for the dump, and NODE
735 is not the root node of the dump. */
737 int dump_flag (dump_info_p di
, int flag
, const_tree node
)
739 return (di
->flags
& flag
) && (node
!= di
->node
);
742 /* Dump T, and all its children, on STREAM. */
745 dump_node (const_tree t
, int flags
, FILE *stream
)
749 dump_queue_p next_dq
;
751 /* Initialize the dump-information structure. */
760 di
.nodes
= splay_tree_new (splay_tree_compare_pointers
, 0,
761 (splay_tree_delete_value_fn
) &free
);
763 /* Queue up the first node. */
764 queue (&di
, t
, DUMP_NONE
);
766 /* Until the queue is empty, keep dumping nodes. */
768 dequeue_and_dump (&di
);
771 for (dq
= di
.free_list
; dq
; dq
= next_dq
)
776 splay_tree_delete (di
.nodes
);