* basic-block.h (ei_safe_edge): New function.
[official-gcc.git] / gcc / tree-pretty-print.c
blob0e60099437b2bf44dcb06dce45db055d081b5763
1 /* Pretty formatting of GENERIC trees in C syntax.
2 Copyright (C) 2001, 2002, 2003 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 (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (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 /* Dump a function declaration. NODE is the FUNCTION_TYPE. BUFFER, SPC and
176 FLAGS are as in dump_generic_node. */
178 static void
179 dump_function_declaration (pretty_printer *buffer, tree node,
180 int spc, int flags)
182 bool wrote_arg = false;
183 tree arg;
185 pp_space (buffer);
186 pp_character (buffer, '(');
188 /* Print the argument types. The last element in the list is a VOID_TYPE.
189 The following avoids printing the last element. */
190 arg = TYPE_ARG_TYPES (node);
191 while (arg && TREE_CHAIN (arg) && arg != error_mark_node)
193 wrote_arg = true;
194 dump_generic_node (buffer, TREE_VALUE (arg), spc, flags, false);
195 arg = TREE_CHAIN (arg);
196 if (TREE_CHAIN (arg) && TREE_CODE (TREE_CHAIN (arg)) == TREE_LIST)
198 pp_character (buffer, ',');
199 pp_space (buffer);
203 if (!wrote_arg)
204 pp_string (buffer, "void");
206 pp_character (buffer, ')');
209 /* Dump the node NODE on the pretty_printer BUFFER, SPC spaces of indent.
210 FLAGS specifies details to show in the dump (see TDF_* in tree.h). If
211 IS_STMT is true, the object printed is considered to be a statement
212 and it is terminated by ';' if appropriate. */
215 dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
216 bool is_stmt)
218 tree type;
219 tree op0, op1;
220 const char *str;
221 bool is_expr;
223 if (node == NULL_TREE)
224 return spc;
226 is_expr = EXPR_P (node);
228 if (TREE_CODE (node) != ERROR_MARK
229 && is_gimple_stmt (node)
230 && (flags & TDF_VOPS)
231 && stmt_ann (node))
232 dump_vops (buffer, node, spc, flags);
234 if (dumping_stmts
235 && (flags & TDF_LINENO)
236 && EXPR_HAS_LOCATION (node))
238 expanded_location xloc = expand_location (EXPR_LOCATION (node));
239 pp_character (buffer, '[');
240 if (xloc.file)
242 pp_string (buffer, xloc.file);
243 pp_string (buffer, " : ");
245 pp_decimal_int (buffer, xloc.line);
246 pp_string (buffer, "] ");
249 switch (TREE_CODE (node))
251 case ERROR_MARK:
252 pp_string (buffer, "<<< error >>>");
253 break;
255 case IDENTIFIER_NODE:
256 pp_tree_identifier (buffer, node);
257 break;
259 case TREE_LIST:
260 while (node && node != error_mark_node)
262 if (TREE_PURPOSE (node))
264 dump_generic_node (buffer, TREE_PURPOSE (node), spc, flags, false);
265 pp_space (buffer);
267 dump_generic_node (buffer, TREE_VALUE (node), spc, flags, false);
268 node = TREE_CHAIN (node);
269 if (node && TREE_CODE (node) == TREE_LIST)
271 pp_character (buffer, ',');
272 pp_space (buffer);
275 break;
277 case TREE_VEC:
278 dump_generic_node (buffer, BINFO_TYPE (node), spc, flags, false);
279 break;
281 case BLOCK:
282 NIY;
283 break;
285 case VOID_TYPE:
286 case INTEGER_TYPE:
287 case REAL_TYPE:
288 case COMPLEX_TYPE:
289 case VECTOR_TYPE:
290 case ENUMERAL_TYPE:
291 case BOOLEAN_TYPE:
292 case CHAR_TYPE:
294 unsigned int quals = TYPE_QUALS (node);
295 char class;
297 if (quals & TYPE_QUAL_CONST)
298 pp_string (buffer, "const ");
299 else if (quals & TYPE_QUAL_VOLATILE)
300 pp_string (buffer, "volatile ");
301 else if (quals & TYPE_QUAL_RESTRICT)
302 pp_string (buffer, "restrict ");
304 class = TREE_CODE_CLASS (TREE_CODE (node));
306 if (class == 'd')
308 if (DECL_NAME (node))
309 dump_decl_name (buffer, node, flags);
310 else
311 pp_string (buffer, "<unnamed type decl>");
313 else if (class == 't')
315 if (TYPE_NAME (node))
317 if (TREE_CODE (TYPE_NAME (node)) == IDENTIFIER_NODE)
318 pp_tree_identifier (buffer, TYPE_NAME (node));
319 else if (TREE_CODE (TYPE_NAME (node)) == TYPE_DECL
320 && DECL_NAME (TYPE_NAME (node)))
321 dump_decl_name (buffer, TYPE_NAME (node), flags);
322 else
323 pp_string (buffer, "<unnamed type>");
325 else
326 pp_string (buffer, "<unnamed type>");
328 break;
331 case POINTER_TYPE:
332 case REFERENCE_TYPE:
333 str = (TREE_CODE (node) == POINTER_TYPE ? "*" : "&");
335 if (TREE_CODE (TREE_TYPE (node)) == FUNCTION_TYPE)
337 tree fnode = TREE_TYPE (node);
339 dump_generic_node (buffer, TREE_TYPE (fnode), spc, flags, false);
340 pp_space (buffer);
341 pp_character (buffer, '(');
342 pp_string (buffer, str);
343 if (TYPE_NAME (node) && DECL_NAME (TYPE_NAME (node)))
344 dump_decl_name (buffer, TYPE_NAME (node), flags);
345 else
346 pp_printf (buffer, "<T%x>", TYPE_UID (node));
348 pp_character (buffer, ')');
349 dump_function_declaration (buffer, fnode, spc, flags);
351 else
353 unsigned int quals = TYPE_QUALS (node);
355 dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
356 pp_space (buffer);
357 pp_string (buffer, str);
359 if (quals & TYPE_QUAL_CONST)
360 pp_string (buffer, " const");
361 else if (quals & TYPE_QUAL_VOLATILE)
362 pp_string (buffer, "volatile");
363 else if (quals & TYPE_QUAL_RESTRICT)
364 pp_string (buffer, " restrict");
366 break;
368 case OFFSET_TYPE:
369 NIY;
370 break;
372 case METHOD_TYPE:
373 dump_decl_name (buffer, TYPE_NAME (TYPE_METHOD_BASETYPE (node)), flags);
374 pp_string (buffer, "::");
375 break;
377 case FILE_TYPE:
378 NIY;
379 break;
381 case ARRAY_TYPE:
383 tree tmp;
385 /* Print the innermost component type. */
386 for (tmp = TREE_TYPE (node); TREE_CODE (tmp) == ARRAY_TYPE;
387 tmp = TREE_TYPE (tmp))
389 dump_generic_node (buffer, tmp, spc, flags, false);
391 /* Print the dimensions. */
392 for (tmp = node; TREE_CODE (tmp) == ARRAY_TYPE;
393 tmp = TREE_TYPE (tmp))
395 tree domain = TYPE_DOMAIN (tmp);
397 pp_character (buffer, '[');
398 if (domain)
400 if (TYPE_MIN_VALUE (domain)
401 && !integer_zerop (TYPE_MIN_VALUE (domain)))
403 dump_generic_node (buffer, TYPE_MIN_VALUE (domain),
404 spc, flags, false);
405 pp_string (buffer, " .. ");
408 if (TYPE_MAX_VALUE (domain))
409 dump_generic_node (buffer, TYPE_MAX_VALUE (domain),
410 spc, flags, false);
412 else
413 pp_string (buffer, "<unknown>");
415 pp_character (buffer, ']');
417 break;
420 case SET_TYPE:
421 NIY;
422 break;
424 case RECORD_TYPE:
425 case UNION_TYPE:
426 case QUAL_UNION_TYPE:
427 /* Print the name of the structure. */
428 if (TREE_CODE (node) == RECORD_TYPE)
429 pp_string (buffer, "struct ");
430 else if (TREE_CODE (node) == UNION_TYPE)
431 pp_string (buffer, "union ");
433 if (TYPE_NAME (node))
434 dump_generic_node (buffer, TYPE_NAME (node), spc, flags, false);
435 else
436 print_struct_decl (buffer, node, spc, flags);
437 break;
439 case LANG_TYPE:
440 NIY;
441 break;
443 case INTEGER_CST:
444 if (TREE_CODE (TREE_TYPE (node)) == POINTER_TYPE)
446 /* In the case of a pointer, one may want to divide by the
447 size of the pointed-to type. Unfortunately, this not
448 straightforward. The C front-end maps expressions
450 (int *) 5
451 int *p; (p + 5)
453 in such a way that the two INTEGER_CST nodes for "5" have
454 different values but identical types. In the latter
455 case, the 5 is multiplied by sizeof (int) in c-common.c
456 (pointer_int_sum) to convert it to a byte address, and
457 yet the type of the node is left unchanged. Argh. What
458 is consistent though is that the number value corresponds
459 to bytes (UNITS) offset.
461 NB: Neither of the following divisors can be trivially
462 used to recover the original literal:
464 TREE_INT_CST_LOW (TYPE_SIZE_UNIT (TREE_TYPE (node)))
465 TYPE_PRECISION (TREE_TYPE (TREE_TYPE (node))) */
466 pp_wide_integer (buffer, TREE_INT_CST_LOW (node));
467 pp_string (buffer, "B"); /* pseudo-unit */
469 else if (! host_integerp (node, 0))
471 tree val = node;
473 if (tree_int_cst_sgn (val) < 0)
475 pp_character (buffer, '-');
476 val = build_int_cst_wide (NULL_TREE,
477 -TREE_INT_CST_LOW (val),
478 ~TREE_INT_CST_HIGH (val)
479 + !TREE_INT_CST_LOW (val));
481 /* Would "%x%0*x" or "%x%*0x" get zero-padding on all
482 systems? */
484 static char format[10]; /* "%x%09999x\0" */
485 if (!format[0])
486 sprintf (format, "%%x%%0%dx", HOST_BITS_PER_INT / 4);
487 sprintf (pp_buffer (buffer)->digit_buffer, format,
488 TREE_INT_CST_HIGH (val),
489 TREE_INT_CST_LOW (val));
490 pp_string (buffer, pp_buffer (buffer)->digit_buffer);
493 else
494 pp_wide_integer (buffer, TREE_INT_CST_LOW (node));
495 break;
497 case REAL_CST:
498 /* Code copied from print_node. */
500 REAL_VALUE_TYPE d;
501 if (TREE_OVERFLOW (node))
502 pp_string (buffer, " overflow");
504 #if !defined(REAL_IS_NOT_DOUBLE) || defined(REAL_ARITHMETIC)
505 d = TREE_REAL_CST (node);
506 if (REAL_VALUE_ISINF (d))
507 pp_string (buffer, " Inf");
508 else if (REAL_VALUE_ISNAN (d))
509 pp_string (buffer, " Nan");
510 else
512 char string[100];
513 real_to_decimal (string, &d, sizeof (string), 0, 1);
514 pp_string (buffer, string);
516 #else
518 HOST_WIDE_INT i;
519 unsigned char *p = (unsigned char *) &TREE_REAL_CST (node);
520 pp_string (buffer, "0x");
521 for (i = 0; i < sizeof TREE_REAL_CST (node); i++)
522 output_formatted_integer (buffer, "%02x", *p++);
524 #endif
525 break;
528 case COMPLEX_CST:
529 pp_string (buffer, "__complex__ (");
530 dump_generic_node (buffer, TREE_REALPART (node), spc, flags, false);
531 pp_string (buffer, ", ");
532 dump_generic_node (buffer, TREE_IMAGPART (node), spc, flags, false);
533 pp_string (buffer, ")");
534 break;
536 case STRING_CST:
537 pp_string (buffer, "\"");
538 pretty_print_string (buffer, TREE_STRING_POINTER (node));
539 pp_string (buffer, "\"");
540 break;
542 case VECTOR_CST:
544 tree elt;
545 pp_string (buffer, "{ ");
546 for (elt = TREE_VECTOR_CST_ELTS (node); elt; elt = TREE_CHAIN (elt))
548 dump_generic_node (buffer, TREE_VALUE (elt), spc, flags, false);
549 if (TREE_CHAIN (elt))
550 pp_string (buffer, ", ");
552 pp_string (buffer, " }");
554 break;
556 case FUNCTION_TYPE:
557 break;
559 case FUNCTION_DECL:
560 case CONST_DECL:
561 dump_decl_name (buffer, node, flags);
562 break;
564 case LABEL_DECL:
565 if (DECL_NAME (node))
566 dump_decl_name (buffer, node, flags);
567 else if (LABEL_DECL_UID (node) != -1)
568 pp_printf (buffer, "<L" HOST_WIDE_INT_PRINT_DEC ">",
569 LABEL_DECL_UID (node));
570 else
571 pp_printf (buffer, "<D%u>", DECL_UID (node));
572 break;
574 case TYPE_DECL:
575 if (DECL_IS_BUILTIN (node))
577 /* Don't print the declaration of built-in types. */
578 break;
580 if (DECL_NAME (node))
581 dump_decl_name (buffer, node, flags);
582 else
584 if ((TREE_CODE (TREE_TYPE (node)) == RECORD_TYPE
585 || TREE_CODE (TREE_TYPE (node)) == UNION_TYPE)
586 && TYPE_METHODS (TREE_TYPE (node)))
588 /* The type is a c++ class: all structures have at least
589 4 methods. */
590 pp_string (buffer, "class ");
591 dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
593 else
595 pp_string (buffer,
596 (TREE_CODE (TREE_TYPE (node)) == UNION_TYPE
597 ? "union" : "struct "));
598 dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
601 break;
603 case VAR_DECL:
604 case PARM_DECL:
605 case FIELD_DECL:
606 case NAMESPACE_DECL:
607 dump_decl_name (buffer, node, flags);
608 break;
610 case RESULT_DECL:
611 pp_string (buffer, "<retval>");
612 break;
614 case COMPONENT_REF:
615 op0 = TREE_OPERAND (node, 0);
616 str = ".";
617 if (TREE_CODE (op0) == INDIRECT_REF)
619 op0 = TREE_OPERAND (op0, 0);
620 str = "->";
622 if (op_prio (op0) < op_prio (node))
623 pp_character (buffer, '(');
624 dump_generic_node (buffer, op0, spc, flags, false);
625 if (op_prio (op0) < op_prio (node))
626 pp_character (buffer, ')');
627 pp_string (buffer, str);
628 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
630 if (TREE_CODE (op0) != VALUE_HANDLE)
632 op0 = component_ref_field_offset (node);
633 if (op0 && TREE_CODE (op0) != INTEGER_CST)
635 pp_string (buffer, "{off: ");
636 dump_generic_node (buffer, op0, spc, flags, false);
637 pp_character (buffer, '}');
640 break;
642 case BIT_FIELD_REF:
643 pp_string (buffer, "BIT_FIELD_REF <");
644 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
645 pp_string (buffer, ", ");
646 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
647 pp_string (buffer, ", ");
648 dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
649 pp_string (buffer, ">");
650 break;
652 case ARRAY_REF:
653 case ARRAY_RANGE_REF:
654 op0 = TREE_OPERAND (node, 0);
655 if (op_prio (op0) < op_prio (node))
656 pp_character (buffer, '(');
657 dump_generic_node (buffer, op0, spc, flags, false);
658 if (op_prio (op0) < op_prio (node))
659 pp_character (buffer, ')');
660 pp_character (buffer, '[');
661 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
662 if (TREE_CODE (node) == ARRAY_RANGE_REF)
663 pp_string (buffer, " ...");
664 pp_character (buffer, ']');
666 op0 = array_ref_low_bound (node);
667 op1 = array_ref_element_size (node);
669 if (!integer_zerop (op0)
670 || (TYPE_SIZE_UNIT (TREE_TYPE (node))
671 && !operand_equal_p (op1, TYPE_SIZE_UNIT (TREE_TYPE (node)), 0)))
673 pp_string (buffer, "{lb: ");
674 dump_generic_node (buffer, op0, spc, flags, false);
675 pp_string (buffer, " sz: ");
676 dump_generic_node (buffer, op1, spc, flags, false);
677 pp_character (buffer, '}');
679 break;
681 case CONSTRUCTOR:
683 tree lnode;
684 bool is_struct_init = FALSE;
685 pp_character (buffer, '{');
686 lnode = CONSTRUCTOR_ELTS (node);
687 if (TREE_CODE (TREE_TYPE (node)) == RECORD_TYPE
688 || TREE_CODE (TREE_TYPE (node)) == UNION_TYPE)
689 is_struct_init = TRUE;
690 while (lnode && lnode != error_mark_node)
692 tree val;
693 if (TREE_PURPOSE (lnode) && is_struct_init)
695 pp_character (buffer, '.');
696 dump_generic_node (buffer, TREE_PURPOSE (lnode), spc, flags, false);
697 pp_string (buffer, "=");
699 val = TREE_VALUE (lnode);
700 if (val && TREE_CODE (val) == ADDR_EXPR)
701 if (TREE_CODE (TREE_OPERAND (val, 0)) == FUNCTION_DECL)
702 val = TREE_OPERAND (val, 0);
703 if (val && TREE_CODE (val) == FUNCTION_DECL)
705 dump_decl_name (buffer, val, flags);
707 else
709 dump_generic_node (buffer, TREE_VALUE (lnode), spc, flags, false);
711 lnode = TREE_CHAIN (lnode);
712 if (lnode && TREE_CODE (lnode) == TREE_LIST)
714 pp_character (buffer, ',');
715 pp_space (buffer);
718 pp_character (buffer, '}');
720 break;
722 case COMPOUND_EXPR:
724 tree *tp;
725 if (flags & TDF_SLIM)
727 pp_string (buffer, "<COMPOUND_EXPR>");
728 break;
731 dump_generic_node (buffer, TREE_OPERAND (node, 0),
732 spc, flags, dumping_stmts);
733 if (dumping_stmts)
734 newline_and_indent (buffer, spc);
735 else
737 pp_character (buffer, ',');
738 pp_space (buffer);
741 for (tp = &TREE_OPERAND (node, 1);
742 TREE_CODE (*tp) == COMPOUND_EXPR;
743 tp = &TREE_OPERAND (*tp, 1))
745 dump_generic_node (buffer, TREE_OPERAND (*tp, 0),
746 spc, flags, dumping_stmts);
747 if (dumping_stmts)
748 newline_and_indent (buffer, spc);
749 else
751 pp_character (buffer, ',');
752 pp_space (buffer);
756 dump_generic_node (buffer, *tp, spc, flags, dumping_stmts);
758 break;
760 case STATEMENT_LIST:
762 tree_stmt_iterator si;
763 bool first = true;
765 if ((flags & TDF_SLIM) || !dumping_stmts)
767 pp_string (buffer, "<STATEMENT_LIST>");
768 break;
771 for (si = tsi_start (node); !tsi_end_p (si); tsi_next (&si))
773 if (!first)
774 newline_and_indent (buffer, spc);
775 else
776 first = false;
777 dump_generic_node (buffer, tsi_stmt (si), spc, flags, true);
780 break;
782 case MODIFY_EXPR:
783 case INIT_EXPR:
784 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
785 pp_space (buffer);
786 pp_character (buffer, '=');
787 pp_space (buffer);
788 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
789 break;
791 case TARGET_EXPR:
792 pp_string (buffer, "TARGET_EXPR <");
793 dump_generic_node (buffer, TARGET_EXPR_SLOT (node), spc, flags, false);
794 pp_character (buffer, ',');
795 pp_space (buffer);
796 dump_generic_node (buffer, TARGET_EXPR_INITIAL (node), spc, flags, false);
797 pp_character (buffer, '>');
798 break;
800 case DECL_EXPR:
801 print_declaration (buffer, DECL_EXPR_DECL (node), spc, flags);
802 is_stmt = false;
803 break;
805 case COND_EXPR:
806 if (TREE_TYPE (node) == NULL || TREE_TYPE (node) == void_type_node)
808 pp_string (buffer, "if (");
809 dump_generic_node (buffer, COND_EXPR_COND (node), spc, flags, false);
810 pp_character (buffer, ')');
811 /* The lowered cond_exprs should always be printed in full. */
812 if (COND_EXPR_THEN (node)
813 && TREE_CODE (COND_EXPR_THEN (node)) == GOTO_EXPR
814 && COND_EXPR_ELSE (node)
815 && TREE_CODE (COND_EXPR_ELSE (node)) == GOTO_EXPR)
817 pp_space (buffer);
818 dump_generic_node (buffer, COND_EXPR_THEN (node), 0, flags, true);
819 pp_string (buffer, " else ");
820 dump_generic_node (buffer, COND_EXPR_ELSE (node), 0, flags, true);
822 else if (!(flags & TDF_SLIM))
824 /* Output COND_EXPR_THEN. */
825 if (COND_EXPR_THEN (node))
827 newline_and_indent (buffer, spc+2);
828 pp_character (buffer, '{');
829 newline_and_indent (buffer, spc+4);
830 dump_generic_node (buffer, COND_EXPR_THEN (node), spc+4,
831 flags, true);
832 newline_and_indent (buffer, spc+2);
833 pp_character (buffer, '}');
836 /* Output COND_EXPR_ELSE. */
837 if (COND_EXPR_ELSE (node))
839 newline_and_indent (buffer, spc);
840 pp_string (buffer, "else");
841 newline_and_indent (buffer, spc+2);
842 pp_character (buffer, '{');
843 newline_and_indent (buffer, spc+4);
844 dump_generic_node (buffer, COND_EXPR_ELSE (node), spc+4,
845 flags, true);
846 newline_and_indent (buffer, spc+2);
847 pp_character (buffer, '}');
850 is_expr = false;
852 else
854 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
855 pp_space (buffer);
856 pp_character (buffer, '?');
857 pp_space (buffer);
858 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
859 pp_space (buffer);
860 pp_character (buffer, ':');
861 pp_space (buffer);
862 dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
864 break;
866 case BIND_EXPR:
867 pp_character (buffer, '{');
868 if (!(flags & TDF_SLIM))
870 if (BIND_EXPR_VARS (node))
872 pp_newline (buffer);
874 for (op0 = BIND_EXPR_VARS (node); op0; op0 = TREE_CHAIN (op0))
876 print_declaration (buffer, op0, spc+2, flags);
877 pp_newline (buffer);
881 newline_and_indent (buffer, spc+2);
882 dump_generic_node (buffer, BIND_EXPR_BODY (node), spc+2, flags, true);
883 newline_and_indent (buffer, spc);
884 pp_character (buffer, '}');
886 is_expr = false;
887 break;
889 case CALL_EXPR:
890 print_call_name (buffer, node);
892 /* Print parameters. */
893 pp_space (buffer);
894 pp_character (buffer, '(');
895 op1 = TREE_OPERAND (node, 1);
896 if (op1)
897 dump_generic_node (buffer, op1, spc, flags, false);
898 pp_character (buffer, ')');
900 op1 = TREE_OPERAND (node, 2);
901 if (op1)
903 pp_string (buffer, " [static-chain: ");
904 dump_generic_node (buffer, op1, spc, flags, false);
905 pp_character (buffer, ']');
908 if (CALL_EXPR_HAS_RETURN_SLOT_ADDR (node))
909 pp_string (buffer, " [return slot addr]");
910 if (CALL_EXPR_TAILCALL (node))
911 pp_string (buffer, " [tail call]");
912 break;
914 case WITH_CLEANUP_EXPR:
915 NIY;
916 break;
918 case CLEANUP_POINT_EXPR:
919 pp_string (buffer, "<<cleanup_point ");
920 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
921 pp_string (buffer, ">>");
922 break;
924 case PLACEHOLDER_EXPR:
925 pp_string (buffer, "<PLACEHOLDER_EXPR ");
926 dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
927 pp_character (buffer, '>');
928 break;
930 /* Binary arithmetic and logic expressions. */
931 case MULT_EXPR:
932 case PLUS_EXPR:
933 case MINUS_EXPR:
934 case TRUNC_DIV_EXPR:
935 case CEIL_DIV_EXPR:
936 case FLOOR_DIV_EXPR:
937 case ROUND_DIV_EXPR:
938 case TRUNC_MOD_EXPR:
939 case CEIL_MOD_EXPR:
940 case FLOOR_MOD_EXPR:
941 case ROUND_MOD_EXPR:
942 case RDIV_EXPR:
943 case EXACT_DIV_EXPR:
944 case LSHIFT_EXPR:
945 case RSHIFT_EXPR:
946 case LROTATE_EXPR:
947 case RROTATE_EXPR:
948 case BIT_IOR_EXPR:
949 case BIT_XOR_EXPR:
950 case BIT_AND_EXPR:
951 case TRUTH_ANDIF_EXPR:
952 case TRUTH_ORIF_EXPR:
953 case TRUTH_AND_EXPR:
954 case TRUTH_OR_EXPR:
955 case TRUTH_XOR_EXPR:
956 case LT_EXPR:
957 case LE_EXPR:
958 case GT_EXPR:
959 case GE_EXPR:
960 case EQ_EXPR:
961 case NE_EXPR:
962 case UNLT_EXPR:
963 case UNLE_EXPR:
964 case UNGT_EXPR:
965 case UNGE_EXPR:
966 case UNEQ_EXPR:
967 case LTGT_EXPR:
968 case ORDERED_EXPR:
969 case UNORDERED_EXPR:
971 const char *op = op_symbol (node);
972 op0 = TREE_OPERAND (node, 0);
973 op1 = TREE_OPERAND (node, 1);
975 /* When the operands are expressions with less priority,
976 keep semantics of the tree representation. */
977 if (op_prio (op0) < op_prio (node))
979 pp_character (buffer, '(');
980 dump_generic_node (buffer, op0, spc, flags, false);
981 pp_character (buffer, ')');
983 else
984 dump_generic_node (buffer, op0, spc, flags, false);
986 pp_space (buffer);
987 pp_string (buffer, op);
988 pp_space (buffer);
990 /* When the operands are expressions with less priority,
991 keep semantics of the tree representation. */
992 if (op_prio (op1) < op_prio (node))
994 pp_character (buffer, '(');
995 dump_generic_node (buffer, op1, spc, flags, false);
996 pp_character (buffer, ')');
998 else
999 dump_generic_node (buffer, op1, spc, flags, false);
1001 break;
1003 /* Unary arithmetic and logic expressions. */
1004 case NEGATE_EXPR:
1005 case BIT_NOT_EXPR:
1006 case TRUTH_NOT_EXPR:
1007 case ADDR_EXPR:
1008 case PREDECREMENT_EXPR:
1009 case PREINCREMENT_EXPR:
1010 case INDIRECT_REF:
1011 if (TREE_CODE (node) == ADDR_EXPR
1012 && (TREE_CODE (TREE_OPERAND (node, 0)) == STRING_CST
1013 || TREE_CODE (TREE_OPERAND (node, 0)) == FUNCTION_DECL))
1014 ; /* Do not output '&' for strings and function pointers. */
1015 else
1016 pp_string (buffer, op_symbol (node));
1018 if (op_prio (TREE_OPERAND (node, 0)) < op_prio (node))
1020 pp_character (buffer, '(');
1021 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1022 pp_character (buffer, ')');
1024 else
1025 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1026 break;
1028 case POSTDECREMENT_EXPR:
1029 case POSTINCREMENT_EXPR:
1030 if (op_prio (TREE_OPERAND (node, 0)) < op_prio (node))
1032 pp_character (buffer, '(');
1033 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1034 pp_character (buffer, ')');
1036 else
1037 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1038 pp_string (buffer, op_symbol (node));
1039 break;
1041 case MIN_EXPR:
1042 pp_string (buffer, "MIN_EXPR <");
1043 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1044 pp_string (buffer, ", ");
1045 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1046 pp_character (buffer, '>');
1047 break;
1049 case MAX_EXPR:
1050 pp_string (buffer, "MAX_EXPR <");
1051 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1052 pp_string (buffer, ", ");
1053 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1054 pp_character (buffer, '>');
1055 break;
1057 case ABS_EXPR:
1058 pp_string (buffer, "ABS_EXPR <");
1059 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1060 pp_character (buffer, '>');
1061 break;
1063 case RANGE_EXPR:
1064 NIY;
1065 break;
1067 case FIX_TRUNC_EXPR:
1068 case FIX_CEIL_EXPR:
1069 case FIX_FLOOR_EXPR:
1070 case FIX_ROUND_EXPR:
1071 case FLOAT_EXPR:
1072 case CONVERT_EXPR:
1073 case NOP_EXPR:
1074 type = TREE_TYPE (node);
1075 op0 = TREE_OPERAND (node, 0);
1076 if (type != TREE_TYPE (op0))
1078 pp_character (buffer, '(');
1079 dump_generic_node (buffer, type, spc, flags, false);
1080 pp_string (buffer, ") ");
1082 if (op_prio (op0) < op_prio (node))
1083 pp_character (buffer, '(');
1084 dump_generic_node (buffer, op0, spc, flags, false);
1085 if (op_prio (op0) < op_prio (node))
1086 pp_character (buffer, ')');
1087 break;
1089 case VIEW_CONVERT_EXPR:
1090 pp_string (buffer, "VIEW_CONVERT_EXPR<");
1091 dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
1092 pp_string (buffer, ">(");
1093 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1094 pp_character (buffer, ')');
1095 break;
1097 case NON_LVALUE_EXPR:
1098 pp_string (buffer, "NON_LVALUE_EXPR <");
1099 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1100 pp_character (buffer, '>');
1101 break;
1103 case SAVE_EXPR:
1104 pp_string (buffer, "SAVE_EXPR <");
1105 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1106 pp_character (buffer, '>');
1107 break;
1109 case COMPLEX_EXPR:
1110 pp_string (buffer, "COMPLEX_EXPR <");
1111 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1112 pp_string (buffer, ", ");
1113 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1114 pp_string (buffer, ">");
1115 break;
1117 case CONJ_EXPR:
1118 pp_string (buffer, "CONJ_EXPR <");
1119 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1120 pp_string (buffer, ">");
1121 break;
1123 case REALPART_EXPR:
1124 pp_string (buffer, "REALPART_EXPR <");
1125 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1126 pp_string (buffer, ">");
1127 break;
1129 case IMAGPART_EXPR:
1130 pp_string (buffer, "IMAGPART_EXPR <");
1131 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1132 pp_string (buffer, ">");
1133 break;
1135 case VA_ARG_EXPR:
1136 pp_string (buffer, "VA_ARG_EXPR <");
1137 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1138 pp_string (buffer, ">");
1139 break;
1141 case TRY_FINALLY_EXPR:
1142 case TRY_CATCH_EXPR:
1143 pp_string (buffer, "try");
1144 newline_and_indent (buffer, spc+2);
1145 pp_string (buffer, "{");
1146 newline_and_indent (buffer, spc+4);
1147 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc+4, flags, true);
1148 newline_and_indent (buffer, spc+2);
1149 pp_string (buffer, "}");
1150 newline_and_indent (buffer, spc);
1151 pp_string (buffer,
1152 (TREE_CODE (node) == TRY_CATCH_EXPR) ? "catch" : "finally");
1153 newline_and_indent (buffer, spc+2);
1154 pp_string (buffer, "{");
1155 newline_and_indent (buffer, spc+4);
1156 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc+4, flags, true);
1157 newline_and_indent (buffer, spc+2);
1158 pp_string (buffer, "}");
1159 is_expr = false;
1160 break;
1162 case CATCH_EXPR:
1163 pp_string (buffer, "catch (");
1164 dump_generic_node (buffer, CATCH_TYPES (node), spc+2, flags, false);
1165 pp_string (buffer, ")");
1166 newline_and_indent (buffer, spc+2);
1167 pp_string (buffer, "{");
1168 newline_and_indent (buffer, spc+4);
1169 dump_generic_node (buffer, CATCH_BODY (node), spc+4, flags, true);
1170 newline_and_indent (buffer, spc+2);
1171 pp_string (buffer, "}");
1172 is_expr = false;
1173 break;
1175 case EH_FILTER_EXPR:
1176 pp_string (buffer, "<<<eh_filter (");
1177 dump_generic_node (buffer, EH_FILTER_TYPES (node), spc+2, flags, false);
1178 pp_string (buffer, ")>>>");
1179 newline_and_indent (buffer, spc+2);
1180 pp_string (buffer, "{");
1181 newline_and_indent (buffer, spc+4);
1182 dump_generic_node (buffer, EH_FILTER_FAILURE (node), spc+4, flags, true);
1183 newline_and_indent (buffer, spc+2);
1184 pp_string (buffer, "}");
1185 is_expr = false;
1186 break;
1188 case LABEL_EXPR:
1189 op0 = TREE_OPERAND (node, 0);
1190 /* If this is for break or continue, don't bother printing it. */
1191 if (DECL_NAME (op0))
1193 const char *name = IDENTIFIER_POINTER (DECL_NAME (op0));
1194 if (strcmp (name, "break") == 0
1195 || strcmp (name, "continue") == 0)
1196 break;
1198 dump_generic_node (buffer, op0, spc, flags, false);
1199 pp_character (buffer, ':');
1200 if (DECL_NONLOCAL (op0))
1201 pp_string (buffer, " [non-local]");
1202 break;
1204 case LABELED_BLOCK_EXPR:
1205 op0 = LABELED_BLOCK_LABEL (node);
1206 /* If this is for break or continue, don't bother printing it. */
1207 if (DECL_NAME (op0))
1209 const char *name = IDENTIFIER_POINTER (DECL_NAME (op0));
1210 if (strcmp (name, "break") == 0
1211 || strcmp (name, "continue") == 0)
1213 dump_generic_node (buffer, LABELED_BLOCK_BODY (node), spc, flags, false);
1214 break;
1217 dump_generic_node (buffer, LABELED_BLOCK_LABEL (node), spc, flags, false);
1218 pp_string (buffer, ": {");
1219 if (!(flags & TDF_SLIM))
1220 newline_and_indent (buffer, spc+2);
1221 dump_generic_node (buffer, LABELED_BLOCK_BODY (node), spc+2, flags, true);
1222 if (!flags)
1223 newline_and_indent (buffer, spc);
1224 pp_character (buffer, '}');
1225 is_expr = false;
1226 break;
1228 case EXIT_BLOCK_EXPR:
1229 op0 = LABELED_BLOCK_LABEL (EXIT_BLOCK_LABELED_BLOCK (node));
1230 /* If this is for a break or continue, print it accordingly. */
1231 if (DECL_NAME (op0))
1233 const char *name = IDENTIFIER_POINTER (DECL_NAME (op0));
1234 if (strcmp (name, "break") == 0
1235 || strcmp (name, "continue") == 0)
1237 pp_string (buffer, name);
1238 break;
1241 pp_string (buffer, "<<<exit block ");
1242 dump_generic_node (buffer, op0, spc, flags, false);
1243 pp_string (buffer, ">>>");
1244 break;
1246 case EXC_PTR_EXPR:
1247 pp_string (buffer, "<<<exception object>>>");
1248 break;
1250 case FILTER_EXPR:
1251 pp_string (buffer, "<<<filter object>>>");
1252 break;
1254 case LOOP_EXPR:
1255 pp_string (buffer, "while (1)");
1256 if (!(flags & TDF_SLIM))
1258 newline_and_indent (buffer, spc+2);
1259 pp_character (buffer, '{');
1260 newline_and_indent (buffer, spc+4);
1261 dump_generic_node (buffer, LOOP_EXPR_BODY (node), spc+4, flags, true);
1262 newline_and_indent (buffer, spc+2);
1263 pp_character (buffer, '}');
1265 is_expr = false;
1266 break;
1268 case RETURN_EXPR:
1269 pp_string (buffer, "return");
1270 op0 = TREE_OPERAND (node, 0);
1271 if (op0)
1273 pp_space (buffer);
1274 if (TREE_CODE (op0) == MODIFY_EXPR)
1275 dump_generic_node (buffer, TREE_OPERAND (op0, 1), spc, flags, false);
1276 else
1277 dump_generic_node (buffer, op0, spc, flags, false);
1279 break;
1281 case EXIT_EXPR:
1282 pp_string (buffer, "if (");
1283 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1284 pp_string (buffer, ") break");
1285 break;
1287 case SWITCH_EXPR:
1288 pp_string (buffer, "switch (");
1289 dump_generic_node (buffer, SWITCH_COND (node), spc, flags, false);
1290 pp_character (buffer, ')');
1291 if (!(flags & TDF_SLIM))
1293 newline_and_indent (buffer, spc+2);
1294 pp_character (buffer, '{');
1295 if (SWITCH_BODY (node))
1297 newline_and_indent (buffer, spc+4);
1298 dump_generic_node (buffer, SWITCH_BODY (node), spc+4, flags, true);
1300 else
1302 tree vec = SWITCH_LABELS (node);
1303 size_t i, n = TREE_VEC_LENGTH (vec);
1304 for (i = 0; i < n; ++i)
1306 tree elt = TREE_VEC_ELT (vec, i);
1307 newline_and_indent (buffer, spc+4);
1308 dump_generic_node (buffer, elt, spc+4, flags, false);
1309 pp_string (buffer, " goto ");
1310 dump_generic_node (buffer, CASE_LABEL (elt), spc+4, flags, true);
1311 pp_semicolon (buffer);
1314 newline_and_indent (buffer, spc+2);
1315 pp_character (buffer, '}');
1317 is_expr = false;
1318 break;
1320 case GOTO_EXPR:
1321 op0 = GOTO_DESTINATION (node);
1322 if (TREE_CODE (op0) != SSA_NAME
1323 && DECL_P (op0)
1324 && DECL_NAME (op0))
1326 const char *name = IDENTIFIER_POINTER (DECL_NAME (op0));
1327 if (strcmp (name, "break") == 0
1328 || strcmp (name, "continue") == 0)
1330 pp_string (buffer, name);
1331 break;
1334 pp_string (buffer, "goto ");
1335 dump_generic_node (buffer, op0, spc, flags, false);
1336 break;
1338 case RESX_EXPR:
1339 pp_string (buffer, "resx");
1340 /* ??? Any sensible way to present the eh region? */
1341 break;
1343 case ASM_EXPR:
1344 pp_string (buffer, "__asm__");
1345 if (ASM_VOLATILE_P (node))
1346 pp_string (buffer, " __volatile__");
1347 pp_character (buffer, '(');
1348 dump_generic_node (buffer, ASM_STRING (node), spc, flags, false);
1349 pp_character (buffer, ':');
1350 dump_generic_node (buffer, ASM_OUTPUTS (node), spc, flags, false);
1351 pp_character (buffer, ':');
1352 dump_generic_node (buffer, ASM_INPUTS (node), spc, flags, false);
1353 if (ASM_CLOBBERS (node))
1355 pp_character (buffer, ':');
1356 dump_generic_node (buffer, ASM_CLOBBERS (node), spc, flags, false);
1358 pp_string (buffer, ")");
1359 break;
1361 case CASE_LABEL_EXPR:
1362 if (CASE_LOW (node) && CASE_HIGH (node))
1364 pp_string (buffer, "case ");
1365 dump_generic_node (buffer, CASE_LOW (node), spc, flags, false);
1366 pp_string (buffer, " ... ");
1367 dump_generic_node (buffer, CASE_HIGH (node), spc, flags, false);
1369 else if (CASE_LOW (node))
1371 pp_string (buffer, "case ");
1372 dump_generic_node (buffer, CASE_LOW (node), spc, flags, false);
1374 else
1375 pp_string (buffer, "default ");
1376 pp_character (buffer, ':');
1377 break;
1379 case OBJ_TYPE_REF:
1380 pp_string (buffer, "OBJ_TYPE_REF(");
1381 dump_generic_node (buffer, OBJ_TYPE_REF_EXPR (node), spc, flags, false);
1382 pp_character (buffer, ';');
1383 dump_generic_node (buffer, OBJ_TYPE_REF_OBJECT (node), spc, flags, false);
1384 pp_character (buffer, '-');
1385 pp_character (buffer, '>');
1386 dump_generic_node (buffer, OBJ_TYPE_REF_TOKEN (node), spc, flags, false);
1387 pp_character (buffer, ')');
1388 break;
1390 case PHI_NODE:
1392 int i;
1394 dump_generic_node (buffer, PHI_RESULT (node), spc, flags, false);
1395 pp_string (buffer, " = PHI <");
1396 for (i = 0; i < PHI_NUM_ARGS (node); i++)
1398 dump_generic_node (buffer, PHI_ARG_DEF (node, i), spc, flags, false);
1399 pp_string (buffer, "(");
1400 pp_decimal_int (buffer, PHI_ARG_EDGE (node, i)->src->index);
1401 pp_string (buffer, ")");
1402 if (i < PHI_NUM_ARGS (node) - 1)
1403 pp_string (buffer, ", ");
1405 pp_string (buffer, ">;");
1407 break;
1409 case SSA_NAME:
1410 dump_generic_node (buffer, SSA_NAME_VAR (node), spc, flags, false);
1411 pp_string (buffer, "_");
1412 pp_decimal_int (buffer, SSA_NAME_VERSION (node));
1413 break;
1415 case WITH_SIZE_EXPR:
1416 pp_string (buffer, "WITH_SIZE_EXPR <");
1417 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1418 pp_string (buffer, ", ");
1419 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1420 pp_string (buffer, ">");
1421 break;
1423 case VALUE_HANDLE:
1424 pp_printf (buffer, "VH.%d", VALUE_HANDLE_ID (node));
1425 break;
1427 case SCEV_KNOWN:
1428 pp_string (buffer, "scev_known");
1429 break;
1431 case SCEV_NOT_KNOWN:
1432 pp_string (buffer, "scev_not_known");
1433 break;
1435 case POLYNOMIAL_CHREC:
1436 pp_string (buffer, "{");
1437 dump_generic_node (buffer, CHREC_LEFT (node), spc, flags, false);
1438 pp_string (buffer, ", +, ");
1439 dump_generic_node (buffer, CHREC_RIGHT (node), spc, flags, false);
1440 pp_string (buffer, "}_");
1441 dump_generic_node (buffer, CHREC_VAR (node), spc, flags, false);
1442 is_stmt = false;
1443 break;
1445 default:
1446 NIY;
1449 if (is_stmt && is_expr)
1450 pp_semicolon (buffer);
1451 pp_write_text_to_stream (buffer);
1453 return spc;
1456 /* Print the declaration of a variable. */
1458 static void
1459 print_declaration (pretty_printer *buffer, tree t, int spc, int flags)
1461 INDENT (spc);
1463 if (TREE_CODE (t) == TYPE_DECL)
1464 pp_string (buffer, "typedef ");
1466 if (DECL_REGISTER (t))
1467 pp_string (buffer, "register ");
1469 if (TREE_PUBLIC (t) && DECL_EXTERNAL (t))
1470 pp_string (buffer, "extern ");
1471 else if (TREE_STATIC (t))
1472 pp_string (buffer, "static ");
1474 /* Print the type and name. */
1475 if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
1477 tree tmp;
1479 /* Print array's type. */
1480 tmp = TREE_TYPE (t);
1481 while (TREE_CODE (TREE_TYPE (tmp)) == ARRAY_TYPE)
1482 tmp = TREE_TYPE (tmp);
1483 dump_generic_node (buffer, TREE_TYPE (tmp), spc, flags, false);
1485 /* Print variable's name. */
1486 pp_space (buffer);
1487 dump_generic_node (buffer, t, spc, flags, false);
1489 /* Print the dimensions. */
1490 tmp = TREE_TYPE (t);
1491 while (TREE_CODE (tmp) == ARRAY_TYPE)
1493 pp_character (buffer, '[');
1494 if (TYPE_DOMAIN (tmp))
1496 if (TREE_CODE (TYPE_SIZE (tmp)) == INTEGER_CST)
1497 pp_wide_integer (buffer,
1498 TREE_INT_CST_LOW (TYPE_SIZE (tmp)) /
1499 TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (tmp))));
1500 else
1501 dump_generic_node (buffer, TYPE_SIZE_UNIT (tmp), spc, flags,
1502 false);
1504 pp_character (buffer, ']');
1505 tmp = TREE_TYPE (tmp);
1508 else if (TREE_CODE (t) == FUNCTION_DECL)
1510 dump_generic_node (buffer, TREE_TYPE (TREE_TYPE (t)), spc, flags, false);
1511 pp_space (buffer);
1512 dump_decl_name (buffer, t, flags);
1513 dump_function_declaration (buffer, TREE_TYPE (t), spc, flags);
1515 else
1517 /* Print type declaration. */
1518 dump_generic_node (buffer, TREE_TYPE (t), spc, flags, false);
1520 /* Print variable's name. */
1521 pp_space (buffer);
1522 dump_generic_node (buffer, t, spc, flags, false);
1525 /* The initial value of a function serves to determine wether the function
1526 is declared or defined. So the following does not apply to function
1527 nodes. */
1528 if (TREE_CODE (t) != FUNCTION_DECL)
1530 /* Print the initial value. */
1531 if (DECL_INITIAL (t))
1533 pp_space (buffer);
1534 pp_character (buffer, '=');
1535 pp_space (buffer);
1536 dump_generic_node (buffer, DECL_INITIAL (t), spc, flags, false);
1540 pp_character (buffer, ';');
1544 /* Prints a structure: name, fields, and methods.
1545 FIXME: Still incomplete. */
1547 static void
1548 print_struct_decl (pretty_printer *buffer, tree node, int spc, int flags)
1550 /* Print the name of the structure. */
1551 if (TYPE_NAME (node))
1553 INDENT (spc);
1554 if (TREE_CODE (node) == RECORD_TYPE)
1555 pp_string (buffer, "struct ");
1556 else if ((TREE_CODE (node) == UNION_TYPE
1557 || TREE_CODE (node) == QUAL_UNION_TYPE))
1558 pp_string (buffer, "union ");
1560 dump_generic_node (buffer, TYPE_NAME (node), spc, 0, false);
1563 /* Print the contents of the structure. */
1564 pp_newline (buffer);
1565 INDENT (spc);
1566 pp_character (buffer, '{');
1567 pp_newline (buffer);
1569 /* Print the fields of the structure. */
1571 tree tmp;
1572 tmp = TYPE_FIELDS (node);
1573 while (tmp)
1575 /* Avoid to print recursively the structure. */
1576 /* FIXME : Not implemented correctly...,
1577 what about the case when we have a cycle in the contain graph? ...
1578 Maybe this could be solved by looking at the scope in which the
1579 structure was declared. */
1580 if (TREE_TYPE (tmp) != node
1581 || (TREE_CODE (TREE_TYPE (tmp)) == POINTER_TYPE
1582 && TREE_TYPE (TREE_TYPE (tmp)) != node))
1584 print_declaration (buffer, tmp, spc+2, flags);
1585 pp_newline (buffer);
1587 tmp = TREE_CHAIN (tmp);
1590 INDENT (spc);
1591 pp_character (buffer, '}');
1594 /* Return the priority of the operator OP.
1596 From lowest to highest precedence with either left-to-right (L-R)
1597 or right-to-left (R-L) associativity]:
1599 1 [L-R] ,
1600 2 [R-L] = += -= *= /= %= &= ^= |= <<= >>=
1601 3 [R-L] ?:
1602 4 [L-R] ||
1603 5 [L-R] &&
1604 6 [L-R] |
1605 7 [L-R] ^
1606 8 [L-R] &
1607 9 [L-R] == !=
1608 10 [L-R] < <= > >=
1609 11 [L-R] << >>
1610 12 [L-R] + -
1611 13 [L-R] * / %
1612 14 [R-L] ! ~ ++ -- + - * & (type) sizeof
1613 15 [L-R] fn() [] -> .
1615 unary +, - and * have higher precedence than the corresponding binary
1616 operators. */
1618 static int
1619 op_prio (tree op)
1621 if (op == NULL)
1622 return 9999;
1624 switch (TREE_CODE (op))
1626 case TREE_LIST:
1627 case COMPOUND_EXPR:
1628 case BIND_EXPR:
1629 return 1;
1631 case MODIFY_EXPR:
1632 case INIT_EXPR:
1633 return 2;
1635 case COND_EXPR:
1636 return 3;
1638 case TRUTH_OR_EXPR:
1639 case TRUTH_ORIF_EXPR:
1640 return 4;
1642 case TRUTH_AND_EXPR:
1643 case TRUTH_ANDIF_EXPR:
1644 return 5;
1646 case BIT_IOR_EXPR:
1647 return 6;
1649 case BIT_XOR_EXPR:
1650 case TRUTH_XOR_EXPR:
1651 return 7;
1653 case BIT_AND_EXPR:
1654 return 8;
1656 case EQ_EXPR:
1657 case NE_EXPR:
1658 return 9;
1660 case UNLT_EXPR:
1661 case UNLE_EXPR:
1662 case UNGT_EXPR:
1663 case UNGE_EXPR:
1664 case UNEQ_EXPR:
1665 case LTGT_EXPR:
1666 case ORDERED_EXPR:
1667 case UNORDERED_EXPR:
1668 case LT_EXPR:
1669 case LE_EXPR:
1670 case GT_EXPR:
1671 case GE_EXPR:
1672 return 10;
1674 case LSHIFT_EXPR:
1675 case RSHIFT_EXPR:
1676 case LROTATE_EXPR:
1677 case RROTATE_EXPR:
1678 return 11;
1680 case PLUS_EXPR:
1681 case MINUS_EXPR:
1682 return 12;
1684 case MULT_EXPR:
1685 case TRUNC_DIV_EXPR:
1686 case CEIL_DIV_EXPR:
1687 case FLOOR_DIV_EXPR:
1688 case ROUND_DIV_EXPR:
1689 case RDIV_EXPR:
1690 case EXACT_DIV_EXPR:
1691 case TRUNC_MOD_EXPR:
1692 case CEIL_MOD_EXPR:
1693 case FLOOR_MOD_EXPR:
1694 case ROUND_MOD_EXPR:
1695 return 13;
1697 case TRUTH_NOT_EXPR:
1698 case BIT_NOT_EXPR:
1699 case POSTINCREMENT_EXPR:
1700 case POSTDECREMENT_EXPR:
1701 case PREINCREMENT_EXPR:
1702 case PREDECREMENT_EXPR:
1703 case NEGATE_EXPR:
1704 case INDIRECT_REF:
1705 case ADDR_EXPR:
1706 case FLOAT_EXPR:
1707 case NOP_EXPR:
1708 case CONVERT_EXPR:
1709 case FIX_TRUNC_EXPR:
1710 case FIX_CEIL_EXPR:
1711 case FIX_FLOOR_EXPR:
1712 case FIX_ROUND_EXPR:
1713 case TARGET_EXPR:
1714 return 14;
1716 case CALL_EXPR:
1717 case ARRAY_REF:
1718 case ARRAY_RANGE_REF:
1719 case COMPONENT_REF:
1720 return 15;
1722 /* Special expressions. */
1723 case MIN_EXPR:
1724 case MAX_EXPR:
1725 case ABS_EXPR:
1726 case REALPART_EXPR:
1727 case IMAGPART_EXPR:
1728 return 16;
1730 case SAVE_EXPR:
1731 case NON_LVALUE_EXPR:
1732 return op_prio (TREE_OPERAND (op, 0));
1734 default:
1735 /* Return an arbitrarily high precedence to avoid surrounding single
1736 VAR_DECLs in ()s. */
1737 return 9999;
1742 /* Return the symbol associated with operator OP. */
1744 static const char *
1745 op_symbol (tree op)
1747 gcc_assert (op);
1749 switch (TREE_CODE (op))
1751 case MODIFY_EXPR:
1752 return "=";
1754 case TRUTH_OR_EXPR:
1755 case TRUTH_ORIF_EXPR:
1756 return "||";
1758 case TRUTH_AND_EXPR:
1759 case TRUTH_ANDIF_EXPR:
1760 return "&&";
1762 case BIT_IOR_EXPR:
1763 return "|";
1765 case TRUTH_XOR_EXPR:
1766 case BIT_XOR_EXPR:
1767 return "^";
1769 case ADDR_EXPR:
1770 case BIT_AND_EXPR:
1771 return "&";
1773 case ORDERED_EXPR:
1774 return "ord";
1775 case UNORDERED_EXPR:
1776 return "unord";
1778 case EQ_EXPR:
1779 return "==";
1780 case UNEQ_EXPR:
1781 return "u==";
1783 case NE_EXPR:
1784 return "!=";
1786 case LT_EXPR:
1787 return "<";
1788 case UNLT_EXPR:
1789 return "u<";
1791 case LE_EXPR:
1792 return "<=";
1793 case UNLE_EXPR:
1794 return "u<=";
1796 case GT_EXPR:
1797 return ">";
1798 case UNGT_EXPR:
1799 return "u>";
1801 case GE_EXPR:
1802 return ">=";
1803 case UNGE_EXPR:
1804 return "u>=";
1806 case LTGT_EXPR:
1807 return "<>";
1809 case LSHIFT_EXPR:
1810 return "<<";
1812 case RSHIFT_EXPR:
1813 return ">>";
1815 case PLUS_EXPR:
1816 return "+";
1818 case NEGATE_EXPR:
1819 case MINUS_EXPR:
1820 return "-";
1822 case BIT_NOT_EXPR:
1823 return "~";
1825 case TRUTH_NOT_EXPR:
1826 return "!";
1828 case MULT_EXPR:
1829 case INDIRECT_REF:
1830 return "*";
1832 case TRUNC_DIV_EXPR:
1833 case RDIV_EXPR:
1834 return "/";
1836 case CEIL_DIV_EXPR:
1837 return "/[cl]";
1839 case FLOOR_DIV_EXPR:
1840 return "/[fl]";
1842 case ROUND_DIV_EXPR:
1843 return "/[rd]";
1845 case EXACT_DIV_EXPR:
1846 return "/[ex]";
1848 case TRUNC_MOD_EXPR:
1849 return "%";
1851 case CEIL_MOD_EXPR:
1852 return "%[cl]";
1854 case FLOOR_MOD_EXPR:
1855 return "%[fl]";
1857 case ROUND_MOD_EXPR:
1858 return "%[rd]";
1860 case PREDECREMENT_EXPR:
1861 return " --";
1863 case PREINCREMENT_EXPR:
1864 return " ++";
1866 case POSTDECREMENT_EXPR:
1867 return "-- ";
1869 case POSTINCREMENT_EXPR:
1870 return "++ ";
1872 default:
1873 return "<<< ??? >>>";
1877 /* Prints the name of a CALL_EXPR. */
1879 static void
1880 print_call_name (pretty_printer *buffer, tree node)
1882 tree op0;
1884 gcc_assert (TREE_CODE (node) == CALL_EXPR);
1886 op0 = TREE_OPERAND (node, 0);
1888 if (TREE_CODE (op0) == NON_LVALUE_EXPR)
1889 op0 = TREE_OPERAND (op0, 0);
1891 switch (TREE_CODE (op0))
1893 case VAR_DECL:
1894 case PARM_DECL:
1895 PRINT_FUNCTION_NAME (op0);
1896 break;
1898 case ADDR_EXPR:
1899 case INDIRECT_REF:
1900 case NOP_EXPR:
1901 dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
1902 break;
1904 case COND_EXPR:
1905 pp_string (buffer, "(");
1906 dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
1907 pp_string (buffer, ") ? ");
1908 dump_generic_node (buffer, TREE_OPERAND (op0, 1), 0, 0, false);
1909 pp_string (buffer, " : ");
1910 dump_generic_node (buffer, TREE_OPERAND (op0, 2), 0, 0, false);
1911 break;
1913 case COMPONENT_REF:
1914 /* The function is a pointer contained in a structure. */
1915 if (TREE_CODE (TREE_OPERAND (op0, 0)) == INDIRECT_REF ||
1916 TREE_CODE (TREE_OPERAND (op0, 0)) == VAR_DECL)
1917 PRINT_FUNCTION_NAME (TREE_OPERAND (op0, 1));
1918 else
1919 dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
1920 /* else
1921 We can have several levels of structures and a function
1922 pointer inside. This is not implemented yet... */
1923 /* NIY;*/
1924 break;
1926 case ARRAY_REF:
1927 if (TREE_CODE (TREE_OPERAND (op0, 0)) == VAR_DECL)
1928 PRINT_FUNCTION_NAME (TREE_OPERAND (op0, 0));
1929 else
1930 dump_generic_node (buffer, op0, 0, 0, false);
1931 break;
1933 case SSA_NAME:
1934 case OBJ_TYPE_REF:
1935 dump_generic_node (buffer, op0, 0, 0, false);
1936 break;
1938 default:
1939 NIY;
1943 /* Parses the string STR and replaces new-lines by '\n', tabs by '\t', ... */
1945 static void
1946 pretty_print_string (pretty_printer *buffer, const char *str)
1948 if (str == NULL)
1949 return;
1951 while (*str)
1953 switch (str[0])
1955 case '\b':
1956 pp_string (buffer, "\\b");
1957 break;
1959 case '\f':
1960 pp_string (buffer, "\\f");
1961 break;
1963 case '\n':
1964 pp_string (buffer, "\\n");
1965 break;
1967 case '\r':
1968 pp_string (buffer, "\\r");
1969 break;
1971 case '\t':
1972 pp_string (buffer, "\\t");
1973 break;
1975 case '\v':
1976 pp_string (buffer, "\\v");
1977 break;
1979 case '\\':
1980 pp_string (buffer, "\\\\");
1981 break;
1983 case '\"':
1984 pp_string (buffer, "\\\"");
1985 break;
1987 case '\'':
1988 pp_string (buffer, "\\'");
1989 break;
1991 case '\0':
1992 pp_string (buffer, "\\0");
1993 break;
1995 case '\1':
1996 pp_string (buffer, "\\1");
1997 break;
1999 case '\2':
2000 pp_string (buffer, "\\2");
2001 break;
2003 case '\3':
2004 pp_string (buffer, "\\3");
2005 break;
2007 case '\4':
2008 pp_string (buffer, "\\4");
2009 break;
2011 case '\5':
2012 pp_string (buffer, "\\5");
2013 break;
2015 case '\6':
2016 pp_string (buffer, "\\6");
2017 break;
2019 case '\7':
2020 pp_string (buffer, "\\7");
2021 break;
2023 default:
2024 pp_character (buffer, str[0]);
2025 break;
2027 str++;
2031 static void
2032 maybe_init_pretty_print (FILE *file)
2034 if (!initialized)
2036 pp_construct (&buffer, /* prefix */NULL, /* line-width */0);
2037 pp_needs_newline (&buffer) = true;
2038 initialized = 1;
2041 buffer.buffer->stream = file;
2044 static void
2045 newline_and_indent (pretty_printer *buffer, int spc)
2047 pp_newline (buffer);
2048 INDENT (spc);
2051 static void
2052 dump_vops (pretty_printer *buffer, tree stmt, int spc, int flags)
2054 tree use, def;
2055 use_operand_p use_p;
2056 def_operand_p def_p;
2057 ssa_op_iter iter;
2059 FOR_EACH_SSA_MAYDEF_OPERAND (def_p, use_p, stmt, iter)
2061 pp_string (buffer, "# ");
2062 dump_generic_node (buffer, DEF_FROM_PTR (def_p),
2063 spc + 2, flags, false);
2064 pp_string (buffer, " = V_MAY_DEF <");
2065 dump_generic_node (buffer, USE_FROM_PTR (use_p),
2066 spc + 2, flags, false);
2067 pp_string (buffer, ">;");
2068 newline_and_indent (buffer, spc);
2071 FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_VMUSTDEF)
2073 pp_string (buffer, "# V_MUST_DEF <");
2074 dump_generic_node (buffer, def, spc + 2, flags, false);
2075 pp_string (buffer, ">;");
2076 newline_and_indent (buffer, spc);
2079 FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_VUSE)
2081 pp_string (buffer, "# VUSE <");
2082 dump_generic_node (buffer, use, spc + 2, flags, false);
2083 pp_string (buffer, ">;");
2084 newline_and_indent (buffer, spc);
2088 /* Dumps basic block BB to FILE with details described by FLAGS and
2089 indented by INDENT spaces. */
2091 void
2092 dump_generic_bb (FILE *file, basic_block bb, int indent, int flags)
2094 maybe_init_pretty_print (file);
2095 dumping_stmts = true;
2096 dump_generic_bb_buff (&buffer, bb, indent, flags);
2097 pp_flush (&buffer);
2100 /* Dumps header of basic block BB to buffer BUFFER indented by INDENT
2101 spaces and details described by flags. */
2103 static void
2104 dump_bb_header (pretty_printer *buffer, basic_block bb, int indent, int flags)
2106 edge e;
2107 tree stmt;
2108 edge_iterator ei;
2110 if (flags & TDF_BLOCKS)
2112 INDENT (indent);
2113 pp_string (buffer, "# BLOCK ");
2114 pp_decimal_int (buffer, bb->index);
2116 if (flags & TDF_LINENO)
2118 block_stmt_iterator bsi;
2120 for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
2121 if (get_lineno (bsi_stmt (bsi)) != -1)
2123 pp_string (buffer, ", starting at line ");
2124 pp_decimal_int (buffer, get_lineno (bsi_stmt (bsi)));
2125 break;
2128 newline_and_indent (buffer, indent);
2130 pp_string (buffer, "# PRED:");
2131 pp_write_text_to_stream (buffer);
2132 FOR_EACH_EDGE (e, ei, bb->preds)
2134 if (flags & TDF_SLIM)
2136 pp_string (buffer, " ");
2137 if (e->src == ENTRY_BLOCK_PTR)
2138 pp_string (buffer, "ENTRY");
2139 else
2140 pp_decimal_int (buffer, e->src->index);
2142 else
2143 dump_edge_info (buffer->buffer->stream, e, 0);
2145 pp_newline (buffer);
2147 else
2149 stmt = first_stmt (bb);
2150 if (!stmt || TREE_CODE (stmt) != LABEL_EXPR)
2152 INDENT (indent - 2);
2153 pp_string (buffer, "<bb ");
2154 pp_decimal_int (buffer, bb->index);
2155 pp_string (buffer, ">:");
2156 pp_newline (buffer);
2159 pp_write_text_to_stream (buffer);
2160 check_bb_profile (bb, buffer->buffer->stream);
2163 /* Dumps end of basic block BB to buffer BUFFER indented by INDENT
2164 spaces. */
2166 static void
2167 dump_bb_end (pretty_printer *buffer, basic_block bb, int indent, int flags)
2169 edge e;
2170 edge_iterator ei;
2172 INDENT (indent);
2173 pp_string (buffer, "# SUCC:");
2174 pp_write_text_to_stream (buffer);
2176 FOR_EACH_EDGE (e, ei, bb->succs)
2178 if (flags & TDF_SLIM)
2180 pp_string (buffer, " ");
2181 if (e->dest == EXIT_BLOCK_PTR)
2182 pp_string (buffer, "EXIT");
2183 else
2184 pp_decimal_int (buffer, e->dest->index);
2186 else
2187 dump_edge_info (buffer->buffer->stream, e, 1);
2189 pp_newline (buffer);
2192 /* Dumps phi nodes of basic block BB to buffer BUFFER with details described by
2193 FLAGS indented by INDENT spaces. */
2195 static void
2196 dump_phi_nodes (pretty_printer *buffer, basic_block bb, int indent, int flags)
2198 tree phi = phi_nodes (bb);
2199 if (!phi)
2200 return;
2202 for (; phi; phi = PHI_CHAIN (phi))
2204 if (is_gimple_reg (PHI_RESULT (phi)) || (flags & TDF_VOPS))
2206 INDENT (indent);
2207 pp_string (buffer, "# ");
2208 dump_generic_node (buffer, phi, indent, flags, false);
2209 pp_newline (buffer);
2214 /* Dump jump to basic block BB that is represented implicitly in the cfg
2215 to BUFFER. */
2217 static void
2218 pp_cfg_jump (pretty_printer *buffer, basic_block bb)
2220 tree stmt;
2222 stmt = first_stmt (bb);
2224 pp_string (buffer, "goto <bb ");
2225 pp_decimal_int (buffer, bb->index);
2226 pp_string (buffer, ">");
2227 if (stmt && TREE_CODE (stmt) == LABEL_EXPR)
2229 pp_string (buffer, " (");
2230 dump_generic_node (buffer, LABEL_EXPR_LABEL (stmt), 0, 0, false);
2231 pp_string (buffer, ")");
2233 pp_semicolon (buffer);
2236 /* Dump edges represented implicitly in basic block BB to BUFFER, indented
2237 by INDENT spaces, with details given by FLAGS. */
2239 static void
2240 dump_implicit_edges (pretty_printer *buffer, basic_block bb, int indent,
2241 int flags)
2243 edge e;
2244 edge_iterator ei;
2246 /* If there is a fallthru edge, we may need to add an artificial goto to the
2247 dump. */
2248 FOR_EACH_EDGE (e, ei, bb->succs)
2250 if (e->flags & EDGE_FALLTHRU)
2251 break;
2253 if (e && e->dest != bb->next_bb)
2255 INDENT (indent);
2257 if ((flags & TDF_LINENO)
2258 #ifdef USE_MAPPED_LOCATION
2259 && e->goto_locus != UNKNOWN_LOCATION
2260 #else
2261 && e->goto_locus
2262 #endif
2265 expanded_location goto_xloc;
2266 #ifdef USE_MAPPED_LOCATION
2267 goto_xloc = expand_location (e->goto_locus);
2268 #else
2269 goto_xloc = *e->goto_locus;
2270 #endif
2271 pp_character (buffer, '[');
2272 if (goto_xloc.file)
2274 pp_string (buffer, goto_xloc.file);
2275 pp_string (buffer, " : ");
2277 pp_decimal_int (buffer, goto_xloc.line);
2278 pp_string (buffer, "] ");
2281 pp_cfg_jump (buffer, e->dest);
2282 pp_newline (buffer);
2286 /* Dumps basic block BB to buffer BUFFER with details described by FLAGS and
2287 indented by INDENT spaces. */
2289 static void
2290 dump_generic_bb_buff (pretty_printer *buffer, basic_block bb,
2291 int indent, int flags)
2293 block_stmt_iterator bsi;
2294 tree stmt;
2295 int label_indent = indent - 2;
2297 if (label_indent < 0)
2298 label_indent = 0;
2300 dump_bb_header (buffer, bb, indent, flags);
2302 if (bb_ann (bb))
2303 dump_phi_nodes (buffer, bb, indent, flags);
2305 for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
2307 int curr_indent;
2309 stmt = bsi_stmt (bsi);
2311 curr_indent = TREE_CODE (stmt) == LABEL_EXPR ? label_indent : indent;
2313 INDENT (curr_indent);
2314 dump_generic_node (buffer, stmt, curr_indent, flags, true);
2315 pp_newline (buffer);
2318 dump_implicit_edges (buffer, bb, indent, flags);
2320 if (flags & TDF_BLOCKS)
2321 dump_bb_end (buffer, bb, indent, flags);