* Makefile.in (tree-update-ssa.o): Add.
[official-gcc.git] / gcc / tree-pretty-print.c
blob82c81d8fa22d51e40d98909de375e1512ef4f7d9
1 /* Pretty formatting of GENERIC trees in C syntax.
2 Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
3 Adapted from c-pretty-print.c by Diego Novillo <dnovillo@redhat.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 2, or (at your option) any later
10 version.
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
15 for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING. If not, write to the Free
19 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
20 02111-1307, USA. */
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tm.h"
26 #include "errors.h"
27 #include "tree.h"
28 #include "diagnostic.h"
29 #include "real.h"
30 #include "hashtab.h"
31 #include "tree-flow.h"
32 #include "langhooks.h"
33 #include "tree-iterator.h"
34 #include "tree-chrec.h"
36 /* Local functions, macros and variables. */
37 static int op_prio (tree);
38 static const char *op_symbol (tree);
39 static void pretty_print_string (pretty_printer *, const char*);
40 static void print_call_name (pretty_printer *, tree);
41 static void newline_and_indent (pretty_printer *, int);
42 static void maybe_init_pretty_print (FILE *);
43 static void print_declaration (pretty_printer *, tree, int, int);
44 static void print_struct_decl (pretty_printer *, tree, int, int);
45 static void do_niy (pretty_printer *, tree);
46 static void dump_vops (pretty_printer *, tree, int, int);
47 static void dump_generic_bb_buff (pretty_printer *, basic_block, int, int);
49 #define INDENT(SPACE) do { \
50 int i; for (i = 0; i<SPACE; i++) pp_space (buffer); } while (0)
52 #define NIY do_niy(buffer,node)
54 #define PRINT_FUNCTION_NAME(NODE) pp_printf \
55 (buffer, "%s", TREE_CODE (NODE) == NOP_EXPR ? \
56 lang_hooks.decl_printable_name (TREE_OPERAND (NODE, 0), 1) : \
57 lang_hooks.decl_printable_name (NODE, 1))
59 static pretty_printer buffer;
60 static int initialized = 0;
61 static bool dumping_stmts;
63 /* Try to print something for an unknown tree code. */
65 static void
66 do_niy (pretty_printer *buffer, tree node)
68 int i, len;
70 pp_string (buffer, "<<< Unknown tree: ");
71 pp_string (buffer, tree_code_name[(int) TREE_CODE (node)]);
73 if (EXPR_P (node))
75 len = first_rtl_op (TREE_CODE (node));
76 for (i = 0; i < len; ++i)
78 newline_and_indent (buffer, 2);
79 dump_generic_node (buffer, TREE_OPERAND (node, i), 2, 0, false);
83 pp_string (buffer, " >>>\n");
86 void
87 debug_generic_expr (tree t)
89 print_generic_expr (stderr, t, TDF_VOPS|TDF_UID);
90 fprintf (stderr, "\n");
93 void
94 debug_generic_stmt (tree t)
96 print_generic_stmt (stderr, t, TDF_VOPS|TDF_UID);
97 fprintf (stderr, "\n");
100 /* Prints declaration DECL to the FILE with details specified by FLAGS. */
101 void
102 print_generic_decl (FILE *file, tree decl, int flags)
104 maybe_init_pretty_print (file);
105 dumping_stmts = true;
106 print_declaration (&buffer, decl, 2, flags);
107 pp_write_text_to_stream (&buffer);
110 /* Print tree T, and its successors, on file FILE. FLAGS specifies details
111 to show in the dump. See TDF_* in tree.h. */
113 void
114 print_generic_stmt (FILE *file, tree t, int flags)
116 maybe_init_pretty_print (file);
117 dumping_stmts = true;
118 dump_generic_node (&buffer, t, 0, flags, true);
119 pp_flush (&buffer);
122 /* Print tree T, and its successors, on file FILE. FLAGS specifies details
123 to show in the dump. See TDF_* in tree.h. The output is indented by
124 INDENT spaces. */
126 void
127 print_generic_stmt_indented (FILE *file, tree t, int flags, int indent)
129 int i;
131 maybe_init_pretty_print (file);
132 dumping_stmts = true;
134 for (i = 0; i < indent; i++)
135 pp_space (&buffer);
136 dump_generic_node (&buffer, t, indent, flags, true);
137 pp_flush (&buffer);
140 /* Print a single expression T on file FILE. FLAGS specifies details to show
141 in the dump. See TDF_* in tree.h. */
143 void
144 print_generic_expr (FILE *file, tree t, int flags)
146 maybe_init_pretty_print (file);
147 dumping_stmts = false;
148 dump_generic_node (&buffer, t, 0, flags, false);
151 /* Dump the name of a _DECL node and its DECL_UID if TDF_UID is set
152 in FLAGS. */
154 static void
155 dump_decl_name (pretty_printer *buffer, tree node, int flags)
157 if (DECL_NAME (node))
158 pp_tree_identifier (buffer, DECL_NAME (node));
160 if ((flags & TDF_UID)
161 || DECL_NAME (node) == NULL_TREE)
163 if (TREE_CODE (node) == LABEL_DECL
164 && LABEL_DECL_UID (node) != -1)
165 pp_printf (buffer, "L." HOST_WIDE_INT_PRINT_DEC,
166 LABEL_DECL_UID (node));
167 else
169 char c = TREE_CODE (node) == CONST_DECL ? 'C' : 'D';
170 pp_printf (buffer, "%c.%u", c, DECL_UID (node));
175 /* Like the above, but used for pretty printing function calls. */
177 static void
178 dump_function_name (pretty_printer *buffer, tree node)
180 if (DECL_NAME (node))
181 PRINT_FUNCTION_NAME (node);
182 else
183 dump_decl_name (buffer, node, 0);
186 /* Dump a function declaration. NODE is the FUNCTION_TYPE. BUFFER, SPC and
187 FLAGS are as in dump_generic_node. */
189 static void
190 dump_function_declaration (pretty_printer *buffer, tree node,
191 int spc, int flags)
193 bool wrote_arg = false;
194 tree arg;
196 pp_space (buffer);
197 pp_character (buffer, '(');
199 /* Print the argument types. The last element in the list is a VOID_TYPE.
200 The following avoids printing the last element. */
201 arg = TYPE_ARG_TYPES (node);
202 while (arg && TREE_CHAIN (arg) && arg != error_mark_node)
204 wrote_arg = true;
205 dump_generic_node (buffer, TREE_VALUE (arg), spc, flags, false);
206 arg = TREE_CHAIN (arg);
207 if (TREE_CHAIN (arg) && TREE_CODE (TREE_CHAIN (arg)) == TREE_LIST)
209 pp_character (buffer, ',');
210 pp_space (buffer);
214 if (!wrote_arg)
215 pp_string (buffer, "void");
217 pp_character (buffer, ')');
220 /* Dump the node NODE on the pretty_printer BUFFER, SPC spaces of indent.
221 FLAGS specifies details to show in the dump (see TDF_* in tree.h). If
222 IS_STMT is true, the object printed is considered to be a statement
223 and it is terminated by ';' if appropriate. */
226 dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
227 bool is_stmt)
229 tree type;
230 tree op0, op1;
231 const char *str;
232 bool is_expr;
234 if (node == NULL_TREE)
235 return spc;
237 is_expr = EXPR_P (node);
239 if (TREE_CODE (node) != ERROR_MARK
240 && is_gimple_stmt (node)
241 && (flags & TDF_VOPS)
242 && stmt_ann (node))
243 dump_vops (buffer, node, spc, flags);
245 if (is_stmt && (flags & TDF_STMTADDR))
246 pp_printf (buffer, "<&0x%x> ", (unsigned int)(size_t) node);
248 if (dumping_stmts
249 && (flags & TDF_LINENO)
250 && EXPR_HAS_LOCATION (node))
252 expanded_location xloc = expand_location (EXPR_LOCATION (node));
253 pp_character (buffer, '[');
254 if (xloc.file)
256 pp_string (buffer, xloc.file);
257 pp_string (buffer, " : ");
259 pp_decimal_int (buffer, xloc.line);
260 pp_string (buffer, "] ");
263 switch (TREE_CODE (node))
265 case ERROR_MARK:
266 pp_string (buffer, "<<< error >>>");
267 break;
269 case IDENTIFIER_NODE:
270 pp_tree_identifier (buffer, node);
271 break;
273 case TREE_LIST:
274 while (node && node != error_mark_node)
276 if (TREE_PURPOSE (node))
278 dump_generic_node (buffer, TREE_PURPOSE (node), spc, flags, false);
279 pp_space (buffer);
281 dump_generic_node (buffer, TREE_VALUE (node), spc, flags, false);
282 node = TREE_CHAIN (node);
283 if (node && TREE_CODE (node) == TREE_LIST)
285 pp_character (buffer, ',');
286 pp_space (buffer);
289 break;
291 case TREE_BINFO:
292 dump_generic_node (buffer, BINFO_TYPE (node), spc, flags, false);
294 case TREE_VEC:
296 size_t i;
297 if (TREE_VEC_LENGTH (node) > 0)
299 size_t len = TREE_VEC_LENGTH (node);
300 for (i = 0; i < len - 1; i++)
302 dump_generic_node (buffer, TREE_VEC_ELT (node, i), spc, flags,
303 false);
304 pp_character (buffer, ',');
305 pp_space (buffer);
307 dump_generic_node (buffer, TREE_VEC_ELT (node, len - 1), spc,
308 flags, false);
311 break;
313 case BLOCK:
314 NIY;
315 break;
317 case VOID_TYPE:
318 case INTEGER_TYPE:
319 case REAL_TYPE:
320 case COMPLEX_TYPE:
321 case VECTOR_TYPE:
322 case ENUMERAL_TYPE:
323 case BOOLEAN_TYPE:
324 case CHAR_TYPE:
326 unsigned int quals = TYPE_QUALS (node);
327 enum tree_code_class class;
329 if (quals & TYPE_QUAL_CONST)
330 pp_string (buffer, "const ");
331 else if (quals & TYPE_QUAL_VOLATILE)
332 pp_string (buffer, "volatile ");
333 else if (quals & TYPE_QUAL_RESTRICT)
334 pp_string (buffer, "restrict ");
336 class = TREE_CODE_CLASS (TREE_CODE (node));
338 if (class == tcc_declaration)
340 if (DECL_NAME (node))
341 dump_decl_name (buffer, node, flags);
342 else
343 pp_string (buffer, "<unnamed type decl>");
345 else if (class == tcc_type)
347 if (TYPE_NAME (node))
349 if (TREE_CODE (TYPE_NAME (node)) == IDENTIFIER_NODE)
350 pp_tree_identifier (buffer, TYPE_NAME (node));
351 else if (TREE_CODE (TYPE_NAME (node)) == TYPE_DECL
352 && DECL_NAME (TYPE_NAME (node)))
353 dump_decl_name (buffer, TYPE_NAME (node), flags);
354 else
355 pp_string (buffer, "<unnamed type>");
357 else if (TREE_CODE (node) == VECTOR_TYPE)
359 pp_string (buffer, "vector ");
360 dump_generic_node (buffer, TREE_TYPE (node),
361 spc, flags, false);
363 else
364 pp_string (buffer, "<unnamed type>");
366 break;
369 case POINTER_TYPE:
370 case REFERENCE_TYPE:
371 str = (TREE_CODE (node) == POINTER_TYPE ? "*" : "&");
373 if (TREE_CODE (TREE_TYPE (node)) == FUNCTION_TYPE)
375 tree fnode = TREE_TYPE (node);
377 dump_generic_node (buffer, TREE_TYPE (fnode), spc, flags, false);
378 pp_space (buffer);
379 pp_character (buffer, '(');
380 pp_string (buffer, str);
381 if (TYPE_NAME (node) && DECL_NAME (TYPE_NAME (node)))
382 dump_decl_name (buffer, TYPE_NAME (node), flags);
383 else
384 pp_printf (buffer, "<T%x>", TYPE_UID (node));
386 pp_character (buffer, ')');
387 dump_function_declaration (buffer, fnode, spc, flags);
389 else
391 unsigned int quals = TYPE_QUALS (node);
393 dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
394 pp_space (buffer);
395 pp_string (buffer, str);
397 if (quals & TYPE_QUAL_CONST)
398 pp_string (buffer, " const");
399 else if (quals & TYPE_QUAL_VOLATILE)
400 pp_string (buffer, "volatile");
401 else if (quals & TYPE_QUAL_RESTRICT)
402 pp_string (buffer, " restrict");
404 break;
406 case OFFSET_TYPE:
407 NIY;
408 break;
410 case METHOD_TYPE:
411 dump_decl_name (buffer, TYPE_NAME (TYPE_METHOD_BASETYPE (node)), flags);
412 pp_string (buffer, "::");
413 break;
415 case FILE_TYPE:
416 NIY;
417 break;
419 case ARRAY_TYPE:
421 tree tmp;
423 /* Print the innermost component type. */
424 for (tmp = TREE_TYPE (node); TREE_CODE (tmp) == ARRAY_TYPE;
425 tmp = TREE_TYPE (tmp))
427 dump_generic_node (buffer, tmp, spc, flags, false);
429 /* Print the dimensions. */
430 for (tmp = node; TREE_CODE (tmp) == ARRAY_TYPE;
431 tmp = TREE_TYPE (tmp))
433 tree domain = TYPE_DOMAIN (tmp);
435 pp_character (buffer, '[');
436 if (domain)
438 if (TYPE_MIN_VALUE (domain)
439 && !integer_zerop (TYPE_MIN_VALUE (domain)))
441 dump_generic_node (buffer, TYPE_MIN_VALUE (domain),
442 spc, flags, false);
443 pp_string (buffer, " .. ");
446 if (TYPE_MAX_VALUE (domain))
447 dump_generic_node (buffer, TYPE_MAX_VALUE (domain),
448 spc, flags, false);
450 else
451 pp_string (buffer, "<unknown>");
453 pp_character (buffer, ']');
455 break;
458 case SET_TYPE:
459 NIY;
460 break;
462 case RECORD_TYPE:
463 case UNION_TYPE:
464 case QUAL_UNION_TYPE:
465 /* Print the name of the structure. */
466 if (TREE_CODE (node) == RECORD_TYPE)
467 pp_string (buffer, "struct ");
468 else if (TREE_CODE (node) == UNION_TYPE)
469 pp_string (buffer, "union ");
471 if (TYPE_NAME (node))
472 dump_generic_node (buffer, TYPE_NAME (node), spc, flags, false);
473 else
474 print_struct_decl (buffer, node, spc, flags);
475 break;
477 case LANG_TYPE:
478 NIY;
479 break;
481 case INTEGER_CST:
482 if (TREE_CODE (TREE_TYPE (node)) == POINTER_TYPE)
484 /* In the case of a pointer, one may want to divide by the
485 size of the pointed-to type. Unfortunately, this not
486 straightforward. The C front-end maps expressions
488 (int *) 5
489 int *p; (p + 5)
491 in such a way that the two INTEGER_CST nodes for "5" have
492 different values but identical types. In the latter
493 case, the 5 is multiplied by sizeof (int) in c-common.c
494 (pointer_int_sum) to convert it to a byte address, and
495 yet the type of the node is left unchanged. Argh. What
496 is consistent though is that the number value corresponds
497 to bytes (UNITS) offset.
499 NB: Neither of the following divisors can be trivially
500 used to recover the original literal:
502 TREE_INT_CST_LOW (TYPE_SIZE_UNIT (TREE_TYPE (node)))
503 TYPE_PRECISION (TREE_TYPE (TREE_TYPE (node))) */
504 pp_wide_integer (buffer, TREE_INT_CST_LOW (node));
505 pp_string (buffer, "B"); /* pseudo-unit */
507 else if (! host_integerp (node, 0))
509 tree val = node;
511 if (tree_int_cst_sgn (val) < 0)
513 pp_character (buffer, '-');
514 val = build_int_cst_wide (NULL_TREE,
515 -TREE_INT_CST_LOW (val),
516 ~TREE_INT_CST_HIGH (val)
517 + !TREE_INT_CST_LOW (val));
519 /* Would "%x%0*x" or "%x%*0x" get zero-padding on all
520 systems? */
522 static char format[10]; /* "%x%09999x\0" */
523 if (!format[0])
524 sprintf (format, "%%x%%0%dx", HOST_BITS_PER_INT / 4);
525 sprintf (pp_buffer (buffer)->digit_buffer, format,
526 TREE_INT_CST_HIGH (val),
527 TREE_INT_CST_LOW (val));
528 pp_string (buffer, pp_buffer (buffer)->digit_buffer);
531 else
532 pp_wide_integer (buffer, TREE_INT_CST_LOW (node));
533 break;
535 case REAL_CST:
536 /* Code copied from print_node. */
538 REAL_VALUE_TYPE d;
539 if (TREE_OVERFLOW (node))
540 pp_string (buffer, " overflow");
542 #if !defined(REAL_IS_NOT_DOUBLE) || defined(REAL_ARITHMETIC)
543 d = TREE_REAL_CST (node);
544 if (REAL_VALUE_ISINF (d))
545 pp_string (buffer, " Inf");
546 else if (REAL_VALUE_ISNAN (d))
547 pp_string (buffer, " Nan");
548 else
550 char string[100];
551 real_to_decimal (string, &d, sizeof (string), 0, 1);
552 pp_string (buffer, string);
554 #else
556 HOST_WIDE_INT i;
557 unsigned char *p = (unsigned char *) &TREE_REAL_CST (node);
558 pp_string (buffer, "0x");
559 for (i = 0; i < sizeof TREE_REAL_CST (node); i++)
560 output_formatted_integer (buffer, "%02x", *p++);
562 #endif
563 break;
566 case COMPLEX_CST:
567 pp_string (buffer, "__complex__ (");
568 dump_generic_node (buffer, TREE_REALPART (node), spc, flags, false);
569 pp_string (buffer, ", ");
570 dump_generic_node (buffer, TREE_IMAGPART (node), spc, flags, false);
571 pp_string (buffer, ")");
572 break;
574 case STRING_CST:
575 pp_string (buffer, "\"");
576 pretty_print_string (buffer, TREE_STRING_POINTER (node));
577 pp_string (buffer, "\"");
578 break;
580 case VECTOR_CST:
582 tree elt;
583 pp_string (buffer, "{ ");
584 for (elt = TREE_VECTOR_CST_ELTS (node); elt; elt = TREE_CHAIN (elt))
586 dump_generic_node (buffer, TREE_VALUE (elt), spc, flags, false);
587 if (TREE_CHAIN (elt))
588 pp_string (buffer, ", ");
590 pp_string (buffer, " }");
592 break;
594 case FUNCTION_TYPE:
595 break;
597 case FUNCTION_DECL:
598 case CONST_DECL:
599 dump_decl_name (buffer, node, flags);
600 break;
602 case LABEL_DECL:
603 if (DECL_NAME (node))
604 dump_decl_name (buffer, node, flags);
605 else if (LABEL_DECL_UID (node) != -1)
606 pp_printf (buffer, "<L" HOST_WIDE_INT_PRINT_DEC ">",
607 LABEL_DECL_UID (node));
608 else
609 pp_printf (buffer, "<D%u>", DECL_UID (node));
610 break;
612 case TYPE_DECL:
613 if (DECL_IS_BUILTIN (node))
615 /* Don't print the declaration of built-in types. */
616 break;
618 if (DECL_NAME (node))
619 dump_decl_name (buffer, node, flags);
620 else
622 if ((TREE_CODE (TREE_TYPE (node)) == RECORD_TYPE
623 || TREE_CODE (TREE_TYPE (node)) == UNION_TYPE)
624 && TYPE_METHODS (TREE_TYPE (node)))
626 /* The type is a c++ class: all structures have at least
627 4 methods. */
628 pp_string (buffer, "class ");
629 dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
631 else
633 pp_string (buffer,
634 (TREE_CODE (TREE_TYPE (node)) == UNION_TYPE
635 ? "union" : "struct "));
636 dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
639 break;
641 case VAR_DECL:
642 case PARM_DECL:
643 case FIELD_DECL:
644 case NAMESPACE_DECL:
645 dump_decl_name (buffer, node, flags);
646 break;
648 case RESULT_DECL:
649 pp_string (buffer, "<retval>");
650 break;
652 case COMPONENT_REF:
653 op0 = TREE_OPERAND (node, 0);
654 str = ".";
655 if (TREE_CODE (op0) == INDIRECT_REF)
657 op0 = TREE_OPERAND (op0, 0);
658 str = "->";
660 if (op_prio (op0) < op_prio (node))
661 pp_character (buffer, '(');
662 dump_generic_node (buffer, op0, spc, flags, false);
663 if (op_prio (op0) < op_prio (node))
664 pp_character (buffer, ')');
665 pp_string (buffer, str);
666 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
668 if (TREE_CODE (op0) != VALUE_HANDLE)
670 op0 = component_ref_field_offset (node);
671 if (op0 && TREE_CODE (op0) != INTEGER_CST)
673 pp_string (buffer, "{off: ");
674 dump_generic_node (buffer, op0, spc, flags, false);
675 pp_character (buffer, '}');
678 break;
680 case BIT_FIELD_REF:
681 pp_string (buffer, "BIT_FIELD_REF <");
682 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
683 pp_string (buffer, ", ");
684 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
685 pp_string (buffer, ", ");
686 dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
687 pp_string (buffer, ">");
688 break;
690 case ARRAY_REF:
691 case ARRAY_RANGE_REF:
692 op0 = TREE_OPERAND (node, 0);
693 if (op_prio (op0) < op_prio (node))
694 pp_character (buffer, '(');
695 dump_generic_node (buffer, op0, spc, flags, false);
696 if (op_prio (op0) < op_prio (node))
697 pp_character (buffer, ')');
698 pp_character (buffer, '[');
699 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
700 if (TREE_CODE (node) == ARRAY_RANGE_REF)
701 pp_string (buffer, " ...");
702 pp_character (buffer, ']');
704 op0 = array_ref_low_bound (node);
705 op1 = array_ref_element_size (node);
707 if (!integer_zerop (op0)
708 || (TYPE_SIZE_UNIT (TREE_TYPE (node))
709 && !operand_equal_p (op1, TYPE_SIZE_UNIT (TREE_TYPE (node)), 0)))
711 pp_string (buffer, "{lb: ");
712 dump_generic_node (buffer, op0, spc, flags, false);
713 pp_string (buffer, " sz: ");
714 dump_generic_node (buffer, op1, spc, flags, false);
715 pp_character (buffer, '}');
717 break;
719 case CONSTRUCTOR:
721 tree lnode;
722 bool is_struct_init = FALSE;
723 pp_character (buffer, '{');
724 lnode = CONSTRUCTOR_ELTS (node);
725 if (TREE_CODE (TREE_TYPE (node)) == RECORD_TYPE
726 || TREE_CODE (TREE_TYPE (node)) == UNION_TYPE)
727 is_struct_init = TRUE;
728 while (lnode && lnode != error_mark_node)
730 tree val;
731 if (TREE_PURPOSE (lnode) && is_struct_init)
733 pp_character (buffer, '.');
734 dump_generic_node (buffer, TREE_PURPOSE (lnode), spc, flags, false);
735 pp_string (buffer, "=");
737 val = TREE_VALUE (lnode);
738 if (val && TREE_CODE (val) == ADDR_EXPR)
739 if (TREE_CODE (TREE_OPERAND (val, 0)) == FUNCTION_DECL)
740 val = TREE_OPERAND (val, 0);
741 if (val && TREE_CODE (val) == FUNCTION_DECL)
743 dump_decl_name (buffer, val, flags);
745 else
747 dump_generic_node (buffer, TREE_VALUE (lnode), spc, flags, false);
749 lnode = TREE_CHAIN (lnode);
750 if (lnode && TREE_CODE (lnode) == TREE_LIST)
752 pp_character (buffer, ',');
753 pp_space (buffer);
756 pp_character (buffer, '}');
758 break;
760 case COMPOUND_EXPR:
762 tree *tp;
763 if (flags & TDF_SLIM)
765 pp_string (buffer, "<COMPOUND_EXPR>");
766 break;
769 dump_generic_node (buffer, TREE_OPERAND (node, 0),
770 spc, flags, dumping_stmts);
771 if (dumping_stmts)
772 newline_and_indent (buffer, spc);
773 else
775 pp_character (buffer, ',');
776 pp_space (buffer);
779 for (tp = &TREE_OPERAND (node, 1);
780 TREE_CODE (*tp) == COMPOUND_EXPR;
781 tp = &TREE_OPERAND (*tp, 1))
783 dump_generic_node (buffer, TREE_OPERAND (*tp, 0),
784 spc, flags, dumping_stmts);
785 if (dumping_stmts)
786 newline_and_indent (buffer, spc);
787 else
789 pp_character (buffer, ',');
790 pp_space (buffer);
794 dump_generic_node (buffer, *tp, spc, flags, dumping_stmts);
796 break;
798 case STATEMENT_LIST:
800 tree_stmt_iterator si;
801 bool first = true;
803 if ((flags & TDF_SLIM) || !dumping_stmts)
805 pp_string (buffer, "<STATEMENT_LIST>");
806 break;
809 for (si = tsi_start (node); !tsi_end_p (si); tsi_next (&si))
811 if (!first)
812 newline_and_indent (buffer, spc);
813 else
814 first = false;
815 dump_generic_node (buffer, tsi_stmt (si), spc, flags, true);
818 break;
820 case MODIFY_EXPR:
821 case INIT_EXPR:
822 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
823 pp_space (buffer);
824 pp_character (buffer, '=');
825 pp_space (buffer);
826 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
827 break;
829 case TARGET_EXPR:
830 pp_string (buffer, "TARGET_EXPR <");
831 dump_generic_node (buffer, TARGET_EXPR_SLOT (node), spc, flags, false);
832 pp_character (buffer, ',');
833 pp_space (buffer);
834 dump_generic_node (buffer, TARGET_EXPR_INITIAL (node), spc, flags, false);
835 pp_character (buffer, '>');
836 break;
838 case DECL_EXPR:
839 print_declaration (buffer, DECL_EXPR_DECL (node), spc, flags);
840 is_stmt = false;
841 break;
843 case COND_EXPR:
844 if (TREE_TYPE (node) == NULL || TREE_TYPE (node) == void_type_node)
846 pp_string (buffer, "if (");
847 dump_generic_node (buffer, COND_EXPR_COND (node), spc, flags, false);
848 pp_character (buffer, ')');
849 /* The lowered cond_exprs should always be printed in full. */
850 if (COND_EXPR_THEN (node)
851 && (IS_EMPTY_STMT (COND_EXPR_THEN (node))
852 || TREE_CODE (COND_EXPR_THEN (node)) == GOTO_EXPR)
853 && COND_EXPR_ELSE (node)
854 && (IS_EMPTY_STMT (COND_EXPR_ELSE (node))
855 || TREE_CODE (COND_EXPR_ELSE (node)) == GOTO_EXPR))
857 pp_space (buffer);
858 dump_generic_node (buffer, COND_EXPR_THEN (node), 0, flags, true);
859 pp_string (buffer, " else ");
860 dump_generic_node (buffer, COND_EXPR_ELSE (node), 0, flags, true);
862 else if (!(flags & TDF_SLIM))
864 /* Output COND_EXPR_THEN. */
865 if (COND_EXPR_THEN (node))
867 newline_and_indent (buffer, spc+2);
868 pp_character (buffer, '{');
869 newline_and_indent (buffer, spc+4);
870 dump_generic_node (buffer, COND_EXPR_THEN (node), spc+4,
871 flags, true);
872 newline_and_indent (buffer, spc+2);
873 pp_character (buffer, '}');
876 /* Output COND_EXPR_ELSE. */
877 if (COND_EXPR_ELSE (node))
879 newline_and_indent (buffer, spc);
880 pp_string (buffer, "else");
881 newline_and_indent (buffer, spc+2);
882 pp_character (buffer, '{');
883 newline_and_indent (buffer, spc+4);
884 dump_generic_node (buffer, COND_EXPR_ELSE (node), spc+4,
885 flags, true);
886 newline_and_indent (buffer, spc+2);
887 pp_character (buffer, '}');
890 is_expr = false;
892 else
894 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
895 pp_space (buffer);
896 pp_character (buffer, '?');
897 pp_space (buffer);
898 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
899 pp_space (buffer);
900 pp_character (buffer, ':');
901 pp_space (buffer);
902 dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
904 break;
906 case BIND_EXPR:
907 pp_character (buffer, '{');
908 if (!(flags & TDF_SLIM))
910 if (BIND_EXPR_VARS (node))
912 pp_newline (buffer);
914 for (op0 = BIND_EXPR_VARS (node); op0; op0 = TREE_CHAIN (op0))
916 print_declaration (buffer, op0, spc+2, flags);
917 pp_newline (buffer);
921 newline_and_indent (buffer, spc+2);
922 dump_generic_node (buffer, BIND_EXPR_BODY (node), spc+2, flags, true);
923 newline_and_indent (buffer, spc);
924 pp_character (buffer, '}');
926 is_expr = false;
927 break;
929 case CALL_EXPR:
930 print_call_name (buffer, node);
932 /* Print parameters. */
933 pp_space (buffer);
934 pp_character (buffer, '(');
935 op1 = TREE_OPERAND (node, 1);
936 if (op1)
937 dump_generic_node (buffer, op1, spc, flags, false);
938 pp_character (buffer, ')');
940 op1 = TREE_OPERAND (node, 2);
941 if (op1)
943 pp_string (buffer, " [static-chain: ");
944 dump_generic_node (buffer, op1, spc, flags, false);
945 pp_character (buffer, ']');
948 if (CALL_EXPR_HAS_RETURN_SLOT_ADDR (node))
949 pp_string (buffer, " [return slot addr]");
950 if (CALL_EXPR_TAILCALL (node))
951 pp_string (buffer, " [tail call]");
952 break;
954 case WITH_CLEANUP_EXPR:
955 NIY;
956 break;
958 case CLEANUP_POINT_EXPR:
959 pp_string (buffer, "<<cleanup_point ");
960 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
961 pp_string (buffer, ">>");
962 break;
964 case PLACEHOLDER_EXPR:
965 pp_string (buffer, "<PLACEHOLDER_EXPR ");
966 dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
967 pp_character (buffer, '>');
968 break;
970 /* Binary arithmetic and logic expressions. */
971 case MULT_EXPR:
972 case PLUS_EXPR:
973 case MINUS_EXPR:
974 case TRUNC_DIV_EXPR:
975 case CEIL_DIV_EXPR:
976 case FLOOR_DIV_EXPR:
977 case ROUND_DIV_EXPR:
978 case TRUNC_MOD_EXPR:
979 case CEIL_MOD_EXPR:
980 case FLOOR_MOD_EXPR:
981 case ROUND_MOD_EXPR:
982 case RDIV_EXPR:
983 case EXACT_DIV_EXPR:
984 case LSHIFT_EXPR:
985 case RSHIFT_EXPR:
986 case LROTATE_EXPR:
987 case RROTATE_EXPR:
988 case BIT_IOR_EXPR:
989 case BIT_XOR_EXPR:
990 case BIT_AND_EXPR:
991 case TRUTH_ANDIF_EXPR:
992 case TRUTH_ORIF_EXPR:
993 case TRUTH_AND_EXPR:
994 case TRUTH_OR_EXPR:
995 case TRUTH_XOR_EXPR:
996 case LT_EXPR:
997 case LE_EXPR:
998 case GT_EXPR:
999 case GE_EXPR:
1000 case EQ_EXPR:
1001 case NE_EXPR:
1002 case UNLT_EXPR:
1003 case UNLE_EXPR:
1004 case UNGT_EXPR:
1005 case UNGE_EXPR:
1006 case UNEQ_EXPR:
1007 case LTGT_EXPR:
1008 case ORDERED_EXPR:
1009 case UNORDERED_EXPR:
1011 const char *op = op_symbol (node);
1012 op0 = TREE_OPERAND (node, 0);
1013 op1 = TREE_OPERAND (node, 1);
1015 /* When the operands are expressions with less priority,
1016 keep semantics of the tree representation. */
1017 if (op_prio (op0) < op_prio (node))
1019 pp_character (buffer, '(');
1020 dump_generic_node (buffer, op0, spc, flags, false);
1021 pp_character (buffer, ')');
1023 else
1024 dump_generic_node (buffer, op0, spc, flags, false);
1026 pp_space (buffer);
1027 pp_string (buffer, op);
1028 pp_space (buffer);
1030 /* When the operands are expressions with less priority,
1031 keep semantics of the tree representation. */
1032 if (op_prio (op1) < op_prio (node))
1034 pp_character (buffer, '(');
1035 dump_generic_node (buffer, op1, spc, flags, false);
1036 pp_character (buffer, ')');
1038 else
1039 dump_generic_node (buffer, op1, spc, flags, false);
1041 break;
1043 /* Unary arithmetic and logic expressions. */
1044 case NEGATE_EXPR:
1045 case BIT_NOT_EXPR:
1046 case TRUTH_NOT_EXPR:
1047 case ADDR_EXPR:
1048 case PREDECREMENT_EXPR:
1049 case PREINCREMENT_EXPR:
1050 case ALIGN_INDIRECT_REF:
1051 case MISALIGNED_INDIRECT_REF:
1052 case INDIRECT_REF:
1053 if (TREE_CODE (node) == ADDR_EXPR
1054 && (TREE_CODE (TREE_OPERAND (node, 0)) == STRING_CST
1055 || TREE_CODE (TREE_OPERAND (node, 0)) == FUNCTION_DECL))
1056 ; /* Do not output '&' for strings and function pointers. */
1057 else
1058 pp_string (buffer, op_symbol (node));
1060 if (op_prio (TREE_OPERAND (node, 0)) < op_prio (node))
1062 pp_character (buffer, '(');
1063 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1064 pp_character (buffer, ')');
1066 else
1067 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1069 if (TREE_CODE (node) == MISALIGNED_INDIRECT_REF)
1071 pp_string (buffer, "{misalignment: ");
1072 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1073 pp_character (buffer, '}');
1075 break;
1077 case POSTDECREMENT_EXPR:
1078 case POSTINCREMENT_EXPR:
1079 if (op_prio (TREE_OPERAND (node, 0)) < op_prio (node))
1081 pp_character (buffer, '(');
1082 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1083 pp_character (buffer, ')');
1085 else
1086 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1087 pp_string (buffer, op_symbol (node));
1088 break;
1090 case MIN_EXPR:
1091 pp_string (buffer, "MIN_EXPR <");
1092 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1093 pp_string (buffer, ", ");
1094 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1095 pp_character (buffer, '>');
1096 break;
1098 case MAX_EXPR:
1099 pp_string (buffer, "MAX_EXPR <");
1100 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1101 pp_string (buffer, ", ");
1102 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1103 pp_character (buffer, '>');
1104 break;
1106 case ABS_EXPR:
1107 pp_string (buffer, "ABS_EXPR <");
1108 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1109 pp_character (buffer, '>');
1110 break;
1112 case RANGE_EXPR:
1113 NIY;
1114 break;
1116 case FIX_TRUNC_EXPR:
1117 case FIX_CEIL_EXPR:
1118 case FIX_FLOOR_EXPR:
1119 case FIX_ROUND_EXPR:
1120 case FLOAT_EXPR:
1121 case CONVERT_EXPR:
1122 case NOP_EXPR:
1123 type = TREE_TYPE (node);
1124 op0 = TREE_OPERAND (node, 0);
1125 if (type != TREE_TYPE (op0))
1127 pp_character (buffer, '(');
1128 dump_generic_node (buffer, type, spc, flags, false);
1129 pp_string (buffer, ") ");
1131 if (op_prio (op0) < op_prio (node))
1132 pp_character (buffer, '(');
1133 dump_generic_node (buffer, op0, spc, flags, false);
1134 if (op_prio (op0) < op_prio (node))
1135 pp_character (buffer, ')');
1136 break;
1138 case VIEW_CONVERT_EXPR:
1139 pp_string (buffer, "VIEW_CONVERT_EXPR<");
1140 dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
1141 pp_string (buffer, ">(");
1142 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1143 pp_character (buffer, ')');
1144 break;
1146 case NON_LVALUE_EXPR:
1147 pp_string (buffer, "NON_LVALUE_EXPR <");
1148 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1149 pp_character (buffer, '>');
1150 break;
1152 case SAVE_EXPR:
1153 pp_string (buffer, "SAVE_EXPR <");
1154 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1155 pp_character (buffer, '>');
1156 break;
1158 case COMPLEX_EXPR:
1159 pp_string (buffer, "COMPLEX_EXPR <");
1160 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1161 pp_string (buffer, ", ");
1162 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1163 pp_string (buffer, ">");
1164 break;
1166 case CONJ_EXPR:
1167 pp_string (buffer, "CONJ_EXPR <");
1168 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1169 pp_string (buffer, ">");
1170 break;
1172 case REALPART_EXPR:
1173 pp_string (buffer, "REALPART_EXPR <");
1174 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1175 pp_string (buffer, ">");
1176 break;
1178 case IMAGPART_EXPR:
1179 pp_string (buffer, "IMAGPART_EXPR <");
1180 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1181 pp_string (buffer, ">");
1182 break;
1184 case VA_ARG_EXPR:
1185 pp_string (buffer, "VA_ARG_EXPR <");
1186 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1187 pp_string (buffer, ">");
1188 break;
1190 case TRY_FINALLY_EXPR:
1191 case TRY_CATCH_EXPR:
1192 pp_string (buffer, "try");
1193 newline_and_indent (buffer, spc+2);
1194 pp_string (buffer, "{");
1195 newline_and_indent (buffer, spc+4);
1196 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc+4, flags, true);
1197 newline_and_indent (buffer, spc+2);
1198 pp_string (buffer, "}");
1199 newline_and_indent (buffer, spc);
1200 pp_string (buffer,
1201 (TREE_CODE (node) == TRY_CATCH_EXPR) ? "catch" : "finally");
1202 newline_and_indent (buffer, spc+2);
1203 pp_string (buffer, "{");
1204 newline_and_indent (buffer, spc+4);
1205 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc+4, flags, true);
1206 newline_and_indent (buffer, spc+2);
1207 pp_string (buffer, "}");
1208 is_expr = false;
1209 break;
1211 case CATCH_EXPR:
1212 pp_string (buffer, "catch (");
1213 dump_generic_node (buffer, CATCH_TYPES (node), spc+2, flags, false);
1214 pp_string (buffer, ")");
1215 newline_and_indent (buffer, spc+2);
1216 pp_string (buffer, "{");
1217 newline_and_indent (buffer, spc+4);
1218 dump_generic_node (buffer, CATCH_BODY (node), spc+4, flags, true);
1219 newline_and_indent (buffer, spc+2);
1220 pp_string (buffer, "}");
1221 is_expr = false;
1222 break;
1224 case EH_FILTER_EXPR:
1225 pp_string (buffer, "<<<eh_filter (");
1226 dump_generic_node (buffer, EH_FILTER_TYPES (node), spc+2, flags, false);
1227 pp_string (buffer, ")>>>");
1228 newline_and_indent (buffer, spc+2);
1229 pp_string (buffer, "{");
1230 newline_and_indent (buffer, spc+4);
1231 dump_generic_node (buffer, EH_FILTER_FAILURE (node), spc+4, flags, true);
1232 newline_and_indent (buffer, spc+2);
1233 pp_string (buffer, "}");
1234 is_expr = false;
1235 break;
1237 case LABEL_EXPR:
1238 op0 = TREE_OPERAND (node, 0);
1239 /* If this is for break or continue, don't bother printing it. */
1240 if (DECL_NAME (op0))
1242 const char *name = IDENTIFIER_POINTER (DECL_NAME (op0));
1243 if (strcmp (name, "break") == 0
1244 || strcmp (name, "continue") == 0)
1245 break;
1247 dump_generic_node (buffer, op0, spc, flags, false);
1248 pp_character (buffer, ':');
1249 if (DECL_NONLOCAL (op0))
1250 pp_string (buffer, " [non-local]");
1251 break;
1253 case LABELED_BLOCK_EXPR:
1254 op0 = LABELED_BLOCK_LABEL (node);
1255 /* If this is for break or continue, don't bother printing it. */
1256 if (DECL_NAME (op0))
1258 const char *name = IDENTIFIER_POINTER (DECL_NAME (op0));
1259 if (strcmp (name, "break") == 0
1260 || strcmp (name, "continue") == 0)
1262 dump_generic_node (buffer, LABELED_BLOCK_BODY (node), spc, flags, false);
1263 break;
1266 dump_generic_node (buffer, LABELED_BLOCK_LABEL (node), spc, flags, false);
1267 pp_string (buffer, ": {");
1268 if (!(flags & TDF_SLIM))
1269 newline_and_indent (buffer, spc+2);
1270 dump_generic_node (buffer, LABELED_BLOCK_BODY (node), spc+2, flags, true);
1271 if (!flags)
1272 newline_and_indent (buffer, spc);
1273 pp_character (buffer, '}');
1274 is_expr = false;
1275 break;
1277 case EXIT_BLOCK_EXPR:
1278 op0 = LABELED_BLOCK_LABEL (EXIT_BLOCK_LABELED_BLOCK (node));
1279 /* If this is for a break or continue, print it accordingly. */
1280 if (DECL_NAME (op0))
1282 const char *name = IDENTIFIER_POINTER (DECL_NAME (op0));
1283 if (strcmp (name, "break") == 0
1284 || strcmp (name, "continue") == 0)
1286 pp_string (buffer, name);
1287 break;
1290 pp_string (buffer, "<<<exit block ");
1291 dump_generic_node (buffer, op0, spc, flags, false);
1292 pp_string (buffer, ">>>");
1293 break;
1295 case EXC_PTR_EXPR:
1296 pp_string (buffer, "<<<exception object>>>");
1297 break;
1299 case FILTER_EXPR:
1300 pp_string (buffer, "<<<filter object>>>");
1301 break;
1303 case LOOP_EXPR:
1304 pp_string (buffer, "while (1)");
1305 if (!(flags & TDF_SLIM))
1307 newline_and_indent (buffer, spc+2);
1308 pp_character (buffer, '{');
1309 newline_and_indent (buffer, spc+4);
1310 dump_generic_node (buffer, LOOP_EXPR_BODY (node), spc+4, flags, true);
1311 newline_and_indent (buffer, spc+2);
1312 pp_character (buffer, '}');
1314 is_expr = false;
1315 break;
1317 case RETURN_EXPR:
1318 pp_string (buffer, "return");
1319 op0 = TREE_OPERAND (node, 0);
1320 if (op0)
1322 pp_space (buffer);
1323 if (TREE_CODE (op0) == MODIFY_EXPR)
1324 dump_generic_node (buffer, TREE_OPERAND (op0, 1), spc, flags, false);
1325 else
1326 dump_generic_node (buffer, op0, spc, flags, false);
1328 break;
1330 case EXIT_EXPR:
1331 pp_string (buffer, "if (");
1332 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1333 pp_string (buffer, ") break");
1334 break;
1336 case SWITCH_EXPR:
1337 pp_string (buffer, "switch (");
1338 dump_generic_node (buffer, SWITCH_COND (node), spc, flags, false);
1339 pp_character (buffer, ')');
1340 if (!(flags & TDF_SLIM))
1342 newline_and_indent (buffer, spc+2);
1343 pp_character (buffer, '{');
1344 if (SWITCH_BODY (node))
1346 newline_and_indent (buffer, spc+4);
1347 dump_generic_node (buffer, SWITCH_BODY (node), spc+4, flags, true);
1349 else
1351 tree vec = SWITCH_LABELS (node);
1352 size_t i, n = TREE_VEC_LENGTH (vec);
1353 for (i = 0; i < n; ++i)
1355 tree elt = TREE_VEC_ELT (vec, i);
1356 newline_and_indent (buffer, spc+4);
1357 dump_generic_node (buffer, elt, spc+4, flags, false);
1358 pp_string (buffer, " goto ");
1359 dump_generic_node (buffer, CASE_LABEL (elt), spc+4, flags, true);
1360 pp_semicolon (buffer);
1363 newline_and_indent (buffer, spc+2);
1364 pp_character (buffer, '}');
1366 is_expr = false;
1367 break;
1369 case GOTO_EXPR:
1370 op0 = GOTO_DESTINATION (node);
1371 if (TREE_CODE (op0) != SSA_NAME && DECL_P (op0) && DECL_NAME (op0))
1373 const char *name = IDENTIFIER_POINTER (DECL_NAME (op0));
1374 if (strcmp (name, "break") == 0
1375 || strcmp (name, "continue") == 0)
1377 pp_string (buffer, name);
1378 break;
1381 pp_string (buffer, "goto ");
1382 dump_generic_node (buffer, op0, spc, flags, false);
1383 break;
1385 case RESX_EXPR:
1386 pp_string (buffer, "resx");
1387 /* ??? Any sensible way to present the eh region? */
1388 break;
1390 case ASM_EXPR:
1391 pp_string (buffer, "__asm__");
1392 if (ASM_VOLATILE_P (node))
1393 pp_string (buffer, " __volatile__");
1394 pp_character (buffer, '(');
1395 dump_generic_node (buffer, ASM_STRING (node), spc, flags, false);
1396 pp_character (buffer, ':');
1397 dump_generic_node (buffer, ASM_OUTPUTS (node), spc, flags, false);
1398 pp_character (buffer, ':');
1399 dump_generic_node (buffer, ASM_INPUTS (node), spc, flags, false);
1400 if (ASM_CLOBBERS (node))
1402 pp_character (buffer, ':');
1403 dump_generic_node (buffer, ASM_CLOBBERS (node), spc, flags, false);
1405 pp_string (buffer, ")");
1406 break;
1408 case CASE_LABEL_EXPR:
1409 if (CASE_LOW (node) && CASE_HIGH (node))
1411 pp_string (buffer, "case ");
1412 dump_generic_node (buffer, CASE_LOW (node), spc, flags, false);
1413 pp_string (buffer, " ... ");
1414 dump_generic_node (buffer, CASE_HIGH (node), spc, flags, false);
1416 else if (CASE_LOW (node))
1418 pp_string (buffer, "case ");
1419 dump_generic_node (buffer, CASE_LOW (node), spc, flags, false);
1421 else
1422 pp_string (buffer, "default ");
1423 pp_character (buffer, ':');
1424 break;
1426 case OBJ_TYPE_REF:
1427 pp_string (buffer, "OBJ_TYPE_REF(");
1428 dump_generic_node (buffer, OBJ_TYPE_REF_EXPR (node), spc, flags, false);
1429 pp_character (buffer, ';');
1430 dump_generic_node (buffer, OBJ_TYPE_REF_OBJECT (node), spc, flags, false);
1431 pp_character (buffer, '-');
1432 pp_character (buffer, '>');
1433 dump_generic_node (buffer, OBJ_TYPE_REF_TOKEN (node), spc, flags, false);
1434 pp_character (buffer, ')');
1435 break;
1437 case PHI_NODE:
1439 int i;
1441 dump_generic_node (buffer, PHI_RESULT (node), spc, flags, false);
1442 pp_string (buffer, " = PHI <");
1443 for (i = 0; i < PHI_NUM_ARGS (node); i++)
1445 dump_generic_node (buffer, PHI_ARG_DEF (node, i), spc, flags, false);
1446 pp_string (buffer, "(");
1447 pp_decimal_int (buffer, PHI_ARG_EDGE (node, i)->src->index);
1448 pp_string (buffer, ")");
1449 if (i < PHI_NUM_ARGS (node) - 1)
1450 pp_string (buffer, ", ");
1452 pp_string (buffer, ">;");
1454 break;
1456 case SSA_NAME:
1458 tree orig;
1460 dump_generic_node (buffer, SSA_NAME_VAR (node), spc, flags, false);
1461 pp_string (buffer, "_");
1462 pp_decimal_int (buffer, SSA_NAME_VERSION (node));
1463 orig = original_equivalent_name (node);
1465 if (orig != node)
1467 pp_string (buffer, "{eqto ");
1468 dump_generic_node (buffer, orig, spc, flags, false);
1469 pp_string (buffer, "}");
1472 break;
1474 case WITH_SIZE_EXPR:
1475 pp_string (buffer, "WITH_SIZE_EXPR <");
1476 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1477 pp_string (buffer, ", ");
1478 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1479 pp_string (buffer, ">");
1480 break;
1482 case VALUE_HANDLE:
1483 pp_printf (buffer, "VH.%d", VALUE_HANDLE_ID (node));
1484 break;
1486 case SCEV_KNOWN:
1487 pp_string (buffer, "scev_known");
1488 break;
1490 case SCEV_NOT_KNOWN:
1491 pp_string (buffer, "scev_not_known");
1492 break;
1494 case POLYNOMIAL_CHREC:
1495 pp_string (buffer, "{");
1496 dump_generic_node (buffer, CHREC_LEFT (node), spc, flags, false);
1497 pp_string (buffer, ", +, ");
1498 dump_generic_node (buffer, CHREC_RIGHT (node), spc, flags, false);
1499 pp_string (buffer, "}_");
1500 dump_generic_node (buffer, CHREC_VAR (node), spc, flags, false);
1501 is_stmt = false;
1502 break;
1504 case REALIGN_LOAD_EXPR:
1505 pp_string (buffer, "REALIGN_LOAD <");
1506 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1507 pp_string (buffer, ", ");
1508 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1509 pp_string (buffer, ", ");
1510 dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
1511 pp_string (buffer, ">");
1512 break;
1514 case VEC_COND_EXPR:
1515 pp_string (buffer, " VEC_COND_EXPR < ");
1516 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1517 pp_string (buffer, " , ");
1518 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1519 pp_string (buffer, " , ");
1520 dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
1521 pp_string (buffer, " > ");
1522 break;
1524 default:
1525 NIY;
1528 if (is_stmt && is_expr)
1529 pp_semicolon (buffer);
1530 pp_write_text_to_stream (buffer);
1532 return spc;
1535 /* Print the declaration of a variable. */
1537 static void
1538 print_declaration (pretty_printer *buffer, tree t, int spc, int flags)
1540 INDENT (spc);
1542 if (TREE_CODE (t) == TYPE_DECL)
1543 pp_string (buffer, "typedef ");
1545 if (DECL_REGISTER (t))
1546 pp_string (buffer, "register ");
1548 if (TREE_PUBLIC (t) && DECL_EXTERNAL (t))
1549 pp_string (buffer, "extern ");
1550 else if (TREE_STATIC (t))
1551 pp_string (buffer, "static ");
1553 /* Print the type and name. */
1554 if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
1556 tree tmp;
1558 /* Print array's type. */
1559 tmp = TREE_TYPE (t);
1560 while (TREE_CODE (TREE_TYPE (tmp)) == ARRAY_TYPE)
1561 tmp = TREE_TYPE (tmp);
1562 dump_generic_node (buffer, TREE_TYPE (tmp), spc, flags, false);
1564 /* Print variable's name. */
1565 pp_space (buffer);
1566 dump_generic_node (buffer, t, spc, flags, false);
1568 /* Print the dimensions. */
1569 tmp = TREE_TYPE (t);
1570 while (TREE_CODE (tmp) == ARRAY_TYPE)
1572 pp_character (buffer, '[');
1573 if (TYPE_DOMAIN (tmp))
1575 if (TREE_CODE (TYPE_SIZE (tmp)) == INTEGER_CST)
1576 pp_wide_integer (buffer,
1577 TREE_INT_CST_LOW (TYPE_SIZE (tmp)) /
1578 TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (tmp))));
1579 else
1580 dump_generic_node (buffer, TYPE_SIZE_UNIT (tmp), spc, flags,
1581 false);
1583 pp_character (buffer, ']');
1584 tmp = TREE_TYPE (tmp);
1587 else if (TREE_CODE (t) == FUNCTION_DECL)
1589 dump_generic_node (buffer, TREE_TYPE (TREE_TYPE (t)), spc, flags, false);
1590 pp_space (buffer);
1591 dump_decl_name (buffer, t, flags);
1592 dump_function_declaration (buffer, TREE_TYPE (t), spc, flags);
1594 else
1596 /* Print type declaration. */
1597 dump_generic_node (buffer, TREE_TYPE (t), spc, flags, false);
1599 /* Print variable's name. */
1600 pp_space (buffer);
1601 dump_generic_node (buffer, t, spc, flags, false);
1604 if (TREE_CODE (t) == VAR_DECL && DECL_HARD_REGISTER (t))
1606 pp_string (buffer, " __asm__ ");
1607 pp_character (buffer, '(');
1608 dump_generic_node (buffer, DECL_ASSEMBLER_NAME (t), spc, flags, false);
1609 pp_character (buffer, ')');
1612 /* The initial value of a function serves to determine wether the function
1613 is declared or defined. So the following does not apply to function
1614 nodes. */
1615 if (TREE_CODE (t) != FUNCTION_DECL)
1617 /* Print the initial value. */
1618 if (DECL_INITIAL (t))
1620 pp_space (buffer);
1621 pp_character (buffer, '=');
1622 pp_space (buffer);
1623 dump_generic_node (buffer, DECL_INITIAL (t), spc, flags, false);
1627 pp_character (buffer, ';');
1631 /* Prints a structure: name, fields, and methods.
1632 FIXME: Still incomplete. */
1634 static void
1635 print_struct_decl (pretty_printer *buffer, tree node, int spc, int flags)
1637 /* Print the name of the structure. */
1638 if (TYPE_NAME (node))
1640 INDENT (spc);
1641 if (TREE_CODE (node) == RECORD_TYPE)
1642 pp_string (buffer, "struct ");
1643 else if ((TREE_CODE (node) == UNION_TYPE
1644 || TREE_CODE (node) == QUAL_UNION_TYPE))
1645 pp_string (buffer, "union ");
1647 dump_generic_node (buffer, TYPE_NAME (node), spc, 0, false);
1650 /* Print the contents of the structure. */
1651 pp_newline (buffer);
1652 INDENT (spc);
1653 pp_character (buffer, '{');
1654 pp_newline (buffer);
1656 /* Print the fields of the structure. */
1658 tree tmp;
1659 tmp = TYPE_FIELDS (node);
1660 while (tmp)
1662 /* Avoid to print recursively the structure. */
1663 /* FIXME : Not implemented correctly...,
1664 what about the case when we have a cycle in the contain graph? ...
1665 Maybe this could be solved by looking at the scope in which the
1666 structure was declared. */
1667 if (TREE_TYPE (tmp) != node
1668 || (TREE_CODE (TREE_TYPE (tmp)) == POINTER_TYPE
1669 && TREE_TYPE (TREE_TYPE (tmp)) != node))
1671 print_declaration (buffer, tmp, spc+2, flags);
1672 pp_newline (buffer);
1674 tmp = TREE_CHAIN (tmp);
1677 INDENT (spc);
1678 pp_character (buffer, '}');
1681 /* Return the priority of the operator OP.
1683 From lowest to highest precedence with either left-to-right (L-R)
1684 or right-to-left (R-L) associativity]:
1686 1 [L-R] ,
1687 2 [R-L] = += -= *= /= %= &= ^= |= <<= >>=
1688 3 [R-L] ?:
1689 4 [L-R] ||
1690 5 [L-R] &&
1691 6 [L-R] |
1692 7 [L-R] ^
1693 8 [L-R] &
1694 9 [L-R] == !=
1695 10 [L-R] < <= > >=
1696 11 [L-R] << >>
1697 12 [L-R] + -
1698 13 [L-R] * / %
1699 14 [R-L] ! ~ ++ -- + - * & (type) sizeof
1700 15 [L-R] fn() [] -> .
1702 unary +, - and * have higher precedence than the corresponding binary
1703 operators. */
1705 static int
1706 op_prio (tree op)
1708 if (op == NULL)
1709 return 9999;
1711 switch (TREE_CODE (op))
1713 case TREE_LIST:
1714 case COMPOUND_EXPR:
1715 case BIND_EXPR:
1716 return 1;
1718 case MODIFY_EXPR:
1719 case INIT_EXPR:
1720 return 2;
1722 case COND_EXPR:
1723 return 3;
1725 case TRUTH_OR_EXPR:
1726 case TRUTH_ORIF_EXPR:
1727 return 4;
1729 case TRUTH_AND_EXPR:
1730 case TRUTH_ANDIF_EXPR:
1731 return 5;
1733 case BIT_IOR_EXPR:
1734 return 6;
1736 case BIT_XOR_EXPR:
1737 case TRUTH_XOR_EXPR:
1738 return 7;
1740 case BIT_AND_EXPR:
1741 return 8;
1743 case EQ_EXPR:
1744 case NE_EXPR:
1745 return 9;
1747 case UNLT_EXPR:
1748 case UNLE_EXPR:
1749 case UNGT_EXPR:
1750 case UNGE_EXPR:
1751 case UNEQ_EXPR:
1752 case LTGT_EXPR:
1753 case ORDERED_EXPR:
1754 case UNORDERED_EXPR:
1755 case LT_EXPR:
1756 case LE_EXPR:
1757 case GT_EXPR:
1758 case GE_EXPR:
1759 return 10;
1761 case LSHIFT_EXPR:
1762 case RSHIFT_EXPR:
1763 case LROTATE_EXPR:
1764 case RROTATE_EXPR:
1765 return 11;
1767 case PLUS_EXPR:
1768 case MINUS_EXPR:
1769 return 12;
1771 case MULT_EXPR:
1772 case TRUNC_DIV_EXPR:
1773 case CEIL_DIV_EXPR:
1774 case FLOOR_DIV_EXPR:
1775 case ROUND_DIV_EXPR:
1776 case RDIV_EXPR:
1777 case EXACT_DIV_EXPR:
1778 case TRUNC_MOD_EXPR:
1779 case CEIL_MOD_EXPR:
1780 case FLOOR_MOD_EXPR:
1781 case ROUND_MOD_EXPR:
1782 return 13;
1784 case TRUTH_NOT_EXPR:
1785 case BIT_NOT_EXPR:
1786 case POSTINCREMENT_EXPR:
1787 case POSTDECREMENT_EXPR:
1788 case PREINCREMENT_EXPR:
1789 case PREDECREMENT_EXPR:
1790 case NEGATE_EXPR:
1791 case ALIGN_INDIRECT_REF:
1792 case MISALIGNED_INDIRECT_REF:
1793 case INDIRECT_REF:
1794 case ADDR_EXPR:
1795 case FLOAT_EXPR:
1796 case NOP_EXPR:
1797 case CONVERT_EXPR:
1798 case FIX_TRUNC_EXPR:
1799 case FIX_CEIL_EXPR:
1800 case FIX_FLOOR_EXPR:
1801 case FIX_ROUND_EXPR:
1802 case TARGET_EXPR:
1803 return 14;
1805 case CALL_EXPR:
1806 case ARRAY_REF:
1807 case ARRAY_RANGE_REF:
1808 case COMPONENT_REF:
1809 return 15;
1811 /* Special expressions. */
1812 case MIN_EXPR:
1813 case MAX_EXPR:
1814 case ABS_EXPR:
1815 case REALPART_EXPR:
1816 case IMAGPART_EXPR:
1817 return 16;
1819 case SAVE_EXPR:
1820 case NON_LVALUE_EXPR:
1821 return op_prio (TREE_OPERAND (op, 0));
1823 default:
1824 /* Return an arbitrarily high precedence to avoid surrounding single
1825 VAR_DECLs in ()s. */
1826 return 9999;
1831 /* Return the symbol associated with operator OP. */
1833 static const char *
1834 op_symbol (tree op)
1836 gcc_assert (op);
1838 switch (TREE_CODE (op))
1840 case MODIFY_EXPR:
1841 return "=";
1843 case TRUTH_OR_EXPR:
1844 case TRUTH_ORIF_EXPR:
1845 return "||";
1847 case TRUTH_AND_EXPR:
1848 case TRUTH_ANDIF_EXPR:
1849 return "&&";
1851 case BIT_IOR_EXPR:
1852 return "|";
1854 case TRUTH_XOR_EXPR:
1855 case BIT_XOR_EXPR:
1856 return "^";
1858 case ADDR_EXPR:
1859 case BIT_AND_EXPR:
1860 return "&";
1862 case ORDERED_EXPR:
1863 return "ord";
1864 case UNORDERED_EXPR:
1865 return "unord";
1867 case EQ_EXPR:
1868 return "==";
1869 case UNEQ_EXPR:
1870 return "u==";
1872 case NE_EXPR:
1873 return "!=";
1875 case LT_EXPR:
1876 return "<";
1877 case UNLT_EXPR:
1878 return "u<";
1880 case LE_EXPR:
1881 return "<=";
1882 case UNLE_EXPR:
1883 return "u<=";
1885 case GT_EXPR:
1886 return ">";
1887 case UNGT_EXPR:
1888 return "u>";
1890 case GE_EXPR:
1891 return ">=";
1892 case UNGE_EXPR:
1893 return "u>=";
1895 case LTGT_EXPR:
1896 return "<>";
1898 case LSHIFT_EXPR:
1899 return "<<";
1901 case RSHIFT_EXPR:
1902 return ">>";
1904 case PLUS_EXPR:
1905 return "+";
1907 case NEGATE_EXPR:
1908 case MINUS_EXPR:
1909 return "-";
1911 case BIT_NOT_EXPR:
1912 return "~";
1914 case TRUTH_NOT_EXPR:
1915 return "!";
1917 case MULT_EXPR:
1918 case INDIRECT_REF:
1919 return "*";
1921 case ALIGN_INDIRECT_REF:
1922 return "A*";
1924 case MISALIGNED_INDIRECT_REF:
1925 return "M*";
1927 case TRUNC_DIV_EXPR:
1928 case RDIV_EXPR:
1929 return "/";
1931 case CEIL_DIV_EXPR:
1932 return "/[cl]";
1934 case FLOOR_DIV_EXPR:
1935 return "/[fl]";
1937 case ROUND_DIV_EXPR:
1938 return "/[rd]";
1940 case EXACT_DIV_EXPR:
1941 return "/[ex]";
1943 case TRUNC_MOD_EXPR:
1944 return "%";
1946 case CEIL_MOD_EXPR:
1947 return "%[cl]";
1949 case FLOOR_MOD_EXPR:
1950 return "%[fl]";
1952 case ROUND_MOD_EXPR:
1953 return "%[rd]";
1955 case PREDECREMENT_EXPR:
1956 return " --";
1958 case PREINCREMENT_EXPR:
1959 return " ++";
1961 case POSTDECREMENT_EXPR:
1962 return "-- ";
1964 case POSTINCREMENT_EXPR:
1965 return "++ ";
1967 default:
1968 return "<<< ??? >>>";
1972 /* Prints the name of a CALL_EXPR. */
1974 static void
1975 print_call_name (pretty_printer *buffer, tree node)
1977 tree op0;
1979 gcc_assert (TREE_CODE (node) == CALL_EXPR);
1981 op0 = TREE_OPERAND (node, 0);
1983 if (TREE_CODE (op0) == NON_LVALUE_EXPR)
1984 op0 = TREE_OPERAND (op0, 0);
1986 switch (TREE_CODE (op0))
1988 case VAR_DECL:
1989 case PARM_DECL:
1990 dump_function_name (buffer, op0);
1991 break;
1993 case ADDR_EXPR:
1994 case INDIRECT_REF:
1995 case NOP_EXPR:
1996 dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
1997 break;
1999 case COND_EXPR:
2000 pp_string (buffer, "(");
2001 dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
2002 pp_string (buffer, ") ? ");
2003 dump_generic_node (buffer, TREE_OPERAND (op0, 1), 0, 0, false);
2004 pp_string (buffer, " : ");
2005 dump_generic_node (buffer, TREE_OPERAND (op0, 2), 0, 0, false);
2006 break;
2008 case COMPONENT_REF:
2009 /* The function is a pointer contained in a structure. */
2010 if (TREE_CODE (TREE_OPERAND (op0, 0)) == INDIRECT_REF ||
2011 TREE_CODE (TREE_OPERAND (op0, 0)) == VAR_DECL)
2012 dump_function_name (buffer, TREE_OPERAND (op0, 1));
2013 else
2014 dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
2015 /* else
2016 We can have several levels of structures and a function
2017 pointer inside. This is not implemented yet... */
2018 /* NIY;*/
2019 break;
2021 case ARRAY_REF:
2022 if (TREE_CODE (TREE_OPERAND (op0, 0)) == VAR_DECL)
2023 dump_function_name (buffer, TREE_OPERAND (op0, 0));
2024 else
2025 dump_generic_node (buffer, op0, 0, 0, false);
2026 break;
2028 case SSA_NAME:
2029 case OBJ_TYPE_REF:
2030 dump_generic_node (buffer, op0, 0, 0, false);
2031 break;
2033 default:
2034 NIY;
2038 /* Parses the string STR and replaces new-lines by '\n', tabs by '\t', ... */
2040 static void
2041 pretty_print_string (pretty_printer *buffer, const char *str)
2043 if (str == NULL)
2044 return;
2046 while (*str)
2048 switch (str[0])
2050 case '\b':
2051 pp_string (buffer, "\\b");
2052 break;
2054 case '\f':
2055 pp_string (buffer, "\\f");
2056 break;
2058 case '\n':
2059 pp_string (buffer, "\\n");
2060 break;
2062 case '\r':
2063 pp_string (buffer, "\\r");
2064 break;
2066 case '\t':
2067 pp_string (buffer, "\\t");
2068 break;
2070 case '\v':
2071 pp_string (buffer, "\\v");
2072 break;
2074 case '\\':
2075 pp_string (buffer, "\\\\");
2076 break;
2078 case '\"':
2079 pp_string (buffer, "\\\"");
2080 break;
2082 case '\'':
2083 pp_string (buffer, "\\'");
2084 break;
2086 case '\0':
2087 pp_string (buffer, "\\0");
2088 break;
2090 case '\1':
2091 pp_string (buffer, "\\1");
2092 break;
2094 case '\2':
2095 pp_string (buffer, "\\2");
2096 break;
2098 case '\3':
2099 pp_string (buffer, "\\3");
2100 break;
2102 case '\4':
2103 pp_string (buffer, "\\4");
2104 break;
2106 case '\5':
2107 pp_string (buffer, "\\5");
2108 break;
2110 case '\6':
2111 pp_string (buffer, "\\6");
2112 break;
2114 case '\7':
2115 pp_string (buffer, "\\7");
2116 break;
2118 default:
2119 pp_character (buffer, str[0]);
2120 break;
2122 str++;
2126 static void
2127 maybe_init_pretty_print (FILE *file)
2129 if (!initialized)
2131 pp_construct (&buffer, /* prefix */NULL, /* line-width */0);
2132 pp_needs_newline (&buffer) = true;
2133 initialized = 1;
2136 buffer.buffer->stream = file;
2139 static void
2140 newline_and_indent (pretty_printer *buffer, int spc)
2142 pp_newline (buffer);
2143 INDENT (spc);
2146 static void
2147 dump_vops (pretty_printer *buffer, tree stmt, int spc, int flags)
2149 tree use, def;
2150 use_operand_p use_p;
2151 def_operand_p def_p;
2152 ssa_op_iter iter;
2154 FOR_EACH_SSA_MAYDEF_OPERAND (def_p, use_p, stmt, iter)
2156 pp_string (buffer, "# ");
2157 dump_generic_node (buffer, DEF_FROM_PTR (def_p),
2158 spc + 2, flags, false);
2159 pp_string (buffer, " = V_MAY_DEF <");
2160 dump_generic_node (buffer, USE_FROM_PTR (use_p),
2161 spc + 2, flags, false);
2162 pp_string (buffer, ">;");
2163 newline_and_indent (buffer, spc);
2166 FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_VMUSTDEF)
2168 pp_string (buffer, "# V_MUST_DEF <");
2169 dump_generic_node (buffer, def, spc + 2, flags, false);
2170 pp_string (buffer, ">;");
2171 newline_and_indent (buffer, spc);
2174 FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_VUSE)
2176 pp_string (buffer, "# VUSE <");
2177 dump_generic_node (buffer, use, spc + 2, flags, false);
2178 pp_string (buffer, ">;");
2179 newline_and_indent (buffer, spc);
2183 /* Dumps basic block BB to FILE with details described by FLAGS and
2184 indented by INDENT spaces. */
2186 void
2187 dump_generic_bb (FILE *file, basic_block bb, int indent, int flags)
2189 maybe_init_pretty_print (file);
2190 dumping_stmts = true;
2191 dump_generic_bb_buff (&buffer, bb, indent, flags);
2192 pp_flush (&buffer);
2195 /* Dumps header of basic block BB to buffer BUFFER indented by INDENT
2196 spaces and details described by flags. */
2198 static void
2199 dump_bb_header (pretty_printer *buffer, basic_block bb, int indent, int flags)
2201 edge e;
2202 tree stmt;
2203 edge_iterator ei;
2205 if (flags & TDF_BLOCKS)
2207 INDENT (indent);
2208 pp_string (buffer, "# BLOCK ");
2209 pp_decimal_int (buffer, bb->index);
2211 if (flags & TDF_LINENO)
2213 block_stmt_iterator bsi;
2215 for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
2216 if (get_lineno (bsi_stmt (bsi)) != -1)
2218 pp_string (buffer, ", starting at line ");
2219 pp_decimal_int (buffer, get_lineno (bsi_stmt (bsi)));
2220 break;
2223 newline_and_indent (buffer, indent);
2225 pp_string (buffer, "# PRED:");
2226 pp_write_text_to_stream (buffer);
2227 FOR_EACH_EDGE (e, ei, bb->preds)
2228 if (flags & TDF_SLIM)
2230 pp_string (buffer, " ");
2231 if (e->src == ENTRY_BLOCK_PTR)
2232 pp_string (buffer, "ENTRY");
2233 else
2234 pp_decimal_int (buffer, e->src->index);
2236 else
2237 dump_edge_info (buffer->buffer->stream, e, 0);
2238 pp_newline (buffer);
2240 else
2242 stmt = first_stmt (bb);
2243 if (!stmt || TREE_CODE (stmt) != LABEL_EXPR)
2245 INDENT (indent - 2);
2246 pp_string (buffer, "<bb ");
2247 pp_decimal_int (buffer, bb->index);
2248 pp_string (buffer, ">:");
2249 pp_newline (buffer);
2252 pp_write_text_to_stream (buffer);
2253 check_bb_profile (bb, buffer->buffer->stream);
2256 /* Dumps end of basic block BB to buffer BUFFER indented by INDENT
2257 spaces. */
2259 static void
2260 dump_bb_end (pretty_printer *buffer, basic_block bb, int indent, int flags)
2262 edge e;
2263 edge_iterator ei;
2265 INDENT (indent);
2266 pp_string (buffer, "# SUCC:");
2267 pp_write_text_to_stream (buffer);
2268 FOR_EACH_EDGE (e, ei, bb->succs)
2269 if (flags & TDF_SLIM)
2271 pp_string (buffer, " ");
2272 if (e->dest == EXIT_BLOCK_PTR)
2273 pp_string (buffer, "EXIT");
2274 else
2275 pp_decimal_int (buffer, e->dest->index);
2277 else
2278 dump_edge_info (buffer->buffer->stream, e, 1);
2279 pp_newline (buffer);
2282 /* Dumps phi nodes of basic block BB to buffer BUFFER with details described by
2283 FLAGS indented by INDENT spaces. */
2285 static void
2286 dump_phi_nodes (pretty_printer *buffer, basic_block bb, int indent, int flags)
2288 tree phi = phi_nodes (bb);
2289 if (!phi)
2290 return;
2292 for (; phi; phi = PHI_CHAIN (phi))
2294 if (is_gimple_reg (PHI_RESULT (phi)) || (flags & TDF_VOPS))
2296 INDENT (indent);
2297 pp_string (buffer, "# ");
2298 dump_generic_node (buffer, phi, indent, flags, false);
2299 pp_newline (buffer);
2304 /* Dump jump to basic block BB that is represented implicitly in the cfg
2305 to BUFFER. */
2307 static void
2308 pp_cfg_jump (pretty_printer *buffer, basic_block bb)
2310 tree stmt;
2312 stmt = first_stmt (bb);
2314 pp_string (buffer, "goto <bb ");
2315 pp_decimal_int (buffer, bb->index);
2316 pp_string (buffer, ">");
2317 if (stmt && TREE_CODE (stmt) == LABEL_EXPR)
2319 pp_string (buffer, " (");
2320 dump_generic_node (buffer, LABEL_EXPR_LABEL (stmt), 0, 0, false);
2321 pp_string (buffer, ")");
2323 pp_semicolon (buffer);
2326 /* Dump edges represented implicitly in basic block BB to BUFFER, indented
2327 by INDENT spaces, with details given by FLAGS. */
2329 static void
2330 dump_implicit_edges (pretty_printer *buffer, basic_block bb, int indent,
2331 int flags)
2333 edge e;
2334 edge_iterator ei;
2336 /* If there is a fallthru edge, we may need to add an artificial goto to the
2337 dump. */
2338 FOR_EACH_EDGE (e, ei, bb->succs)
2339 if (e->flags & EDGE_FALLTHRU)
2340 break;
2341 if (e && e->dest != bb->next_bb)
2343 INDENT (indent);
2345 if ((flags & TDF_LINENO)
2346 #ifdef USE_MAPPED_LOCATION
2347 && e->goto_locus != UNKNOWN_LOCATION
2348 #else
2349 && e->goto_locus
2350 #endif
2353 expanded_location goto_xloc;
2354 #ifdef USE_MAPPED_LOCATION
2355 goto_xloc = expand_location (e->goto_locus);
2356 #else
2357 goto_xloc = *e->goto_locus;
2358 #endif
2359 pp_character (buffer, '[');
2360 if (goto_xloc.file)
2362 pp_string (buffer, goto_xloc.file);
2363 pp_string (buffer, " : ");
2365 pp_decimal_int (buffer, goto_xloc.line);
2366 pp_string (buffer, "] ");
2369 pp_cfg_jump (buffer, e->dest);
2370 pp_newline (buffer);
2374 /* Dumps basic block BB to buffer BUFFER with details described by FLAGS and
2375 indented by INDENT spaces. */
2377 static void
2378 dump_generic_bb_buff (pretty_printer *buffer, basic_block bb,
2379 int indent, int flags)
2381 block_stmt_iterator bsi;
2382 tree stmt;
2383 int label_indent = indent - 2;
2385 if (label_indent < 0)
2386 label_indent = 0;
2388 dump_bb_header (buffer, bb, indent, flags);
2390 if (bb_ann (bb))
2391 dump_phi_nodes (buffer, bb, indent, flags);
2393 for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
2395 int curr_indent;
2397 stmt = bsi_stmt (bsi);
2399 curr_indent = TREE_CODE (stmt) == LABEL_EXPR ? label_indent : indent;
2401 INDENT (curr_indent);
2402 dump_generic_node (buffer, stmt, curr_indent, flags, true);
2403 pp_newline (buffer);
2406 dump_implicit_edges (buffer, bb, indent, flags);
2408 if (flags & TDF_BLOCKS)
2409 dump_bb_end (buffer, bb, indent, flags);