2004-07-28 Eric Christopher <echristo@redhat.com>
[official-gcc.git] / gcc / tree-pretty-print.c
blobd1479e4869d3e6d1049756bf3e6ce1f5b5e4d2b8
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
168 pp_printf (buffer, "<D%u>", DECL_UID (node));
172 /* Dump a function declaration. NODE is the FUNCTION_TYPE. BUFFER, SPC and
173 FLAGS are as in dump_generic_node. */
175 static void
176 dump_function_declaration (pretty_printer *buffer, tree node,
177 int spc, int flags)
179 bool wrote_arg = false;
180 tree arg;
182 pp_space (buffer);
183 pp_character (buffer, '(');
185 /* Print the argument types. The last element in the list is a VOID_TYPE.
186 The following avoids printing the last element. */
187 arg = TYPE_ARG_TYPES (node);
188 while (arg && TREE_CHAIN (arg) && arg != error_mark_node)
190 wrote_arg = true;
191 dump_generic_node (buffer, TREE_VALUE (arg), spc, flags, false);
192 arg = TREE_CHAIN (arg);
193 if (TREE_CHAIN (arg) && TREE_CODE (TREE_CHAIN (arg)) == TREE_LIST)
195 pp_character (buffer, ',');
196 pp_space (buffer);
200 if (!wrote_arg)
201 pp_string (buffer, "void");
203 pp_character (buffer, ')');
206 /* Dump the node NODE on the pretty_printer BUFFER, SPC spaces of indent.
207 FLAGS specifies details to show in the dump (see TDF_* in tree.h). If
208 IS_STMT is true, the object printed is considered to be a statement
209 and it is terminated by ';' if appropriate. */
212 dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
213 bool is_stmt)
215 tree type;
216 tree op0, op1;
217 const char *str;
218 bool is_expr;
220 if (node == NULL_TREE)
221 return spc;
223 is_expr = EXPR_P (node);
225 if (TREE_CODE (node) != ERROR_MARK
226 && is_gimple_stmt (node)
227 && (flags & TDF_VOPS)
228 && stmt_ann (node))
229 dump_vops (buffer, node, spc, flags);
231 if (dumping_stmts
232 && (flags & TDF_LINENO)
233 && EXPR_HAS_LOCATION (node))
235 expanded_location xloc = expand_location (EXPR_LOCATION (node));
236 pp_character (buffer, '[');
237 if (xloc.file)
239 pp_string (buffer, xloc.file);
240 pp_string (buffer, " : ");
242 pp_decimal_int (buffer, xloc.line);
243 pp_string (buffer, "] ");
246 switch (TREE_CODE (node))
248 case ERROR_MARK:
249 pp_string (buffer, "<<< error >>>");
250 break;
252 case IDENTIFIER_NODE:
253 pp_tree_identifier (buffer, node);
254 break;
256 case TREE_LIST:
257 while (node && node != error_mark_node)
259 if (TREE_PURPOSE (node))
261 dump_generic_node (buffer, TREE_PURPOSE (node), spc, flags, false);
262 pp_space (buffer);
264 dump_generic_node (buffer, TREE_VALUE (node), spc, flags, false);
265 node = TREE_CHAIN (node);
266 if (node && TREE_CODE (node) == TREE_LIST)
268 pp_character (buffer, ',');
269 pp_space (buffer);
272 break;
274 case TREE_VEC:
275 dump_generic_node (buffer, BINFO_TYPE (node), spc, flags, false);
276 break;
278 case BLOCK:
279 NIY;
280 break;
282 case VOID_TYPE:
283 case INTEGER_TYPE:
284 case REAL_TYPE:
285 case COMPLEX_TYPE:
286 case VECTOR_TYPE:
287 case ENUMERAL_TYPE:
288 case BOOLEAN_TYPE:
289 case CHAR_TYPE:
291 unsigned int quals = TYPE_QUALS (node);
292 char class;
294 if (quals & TYPE_QUAL_CONST)
295 pp_string (buffer, "const ");
296 else if (quals & TYPE_QUAL_VOLATILE)
297 pp_string (buffer, "volatile ");
298 else if (quals & TYPE_QUAL_RESTRICT)
299 pp_string (buffer, "restrict ");
301 class = TREE_CODE_CLASS (TREE_CODE (node));
303 if (class == 'd')
305 if (DECL_NAME (node))
306 dump_decl_name (buffer, node, flags);
307 else
308 pp_string (buffer, "<unnamed type decl>");
310 else if (class == 't')
312 if (TYPE_NAME (node))
314 if (TREE_CODE (TYPE_NAME (node)) == IDENTIFIER_NODE)
315 pp_tree_identifier (buffer, TYPE_NAME (node));
316 else if (TREE_CODE (TYPE_NAME (node)) == TYPE_DECL
317 && DECL_NAME (TYPE_NAME (node)))
318 dump_decl_name (buffer, TYPE_NAME (node), flags);
319 else
320 pp_string (buffer, "<unnamed type>");
322 else
323 pp_string (buffer, "<unnamed type>");
325 break;
328 case POINTER_TYPE:
329 case REFERENCE_TYPE:
330 str = (TREE_CODE (node) == POINTER_TYPE ? "*" : "&");
332 if (TREE_CODE (TREE_TYPE (node)) == FUNCTION_TYPE)
334 tree fnode = TREE_TYPE (node);
336 dump_generic_node (buffer, TREE_TYPE (fnode), spc, flags, false);
337 pp_space (buffer);
338 pp_character (buffer, '(');
339 pp_string (buffer, str);
340 if (TYPE_NAME (node) && DECL_NAME (TYPE_NAME (node)))
341 dump_decl_name (buffer, TYPE_NAME (node), flags);
342 else
343 pp_printf (buffer, "<T%x>", TYPE_UID (node));
345 pp_character (buffer, ')');
346 dump_function_declaration (buffer, fnode, spc, flags);
348 else
350 unsigned int quals = TYPE_QUALS (node);
352 dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
353 pp_space (buffer);
354 pp_string (buffer, str);
356 if (quals & TYPE_QUAL_CONST)
357 pp_string (buffer, " const");
358 else if (quals & TYPE_QUAL_VOLATILE)
359 pp_string (buffer, "volatile");
360 else if (quals & TYPE_QUAL_RESTRICT)
361 pp_string (buffer, " restrict");
363 break;
365 case OFFSET_TYPE:
366 NIY;
367 break;
369 case METHOD_TYPE:
370 dump_decl_name (buffer, TYPE_NAME (TYPE_METHOD_BASETYPE (node)), flags);
371 pp_string (buffer, "::");
372 break;
374 case FILE_TYPE:
375 NIY;
376 break;
378 case ARRAY_TYPE:
380 tree tmp;
382 /* Print the innermost component type. */
383 for (tmp = TREE_TYPE (node); TREE_CODE (tmp) == ARRAY_TYPE;
384 tmp = TREE_TYPE (tmp))
386 dump_generic_node (buffer, tmp, spc, flags, false);
388 /* Print the dimensions. */
389 for (tmp = node; TREE_CODE (tmp) == ARRAY_TYPE;
390 tmp = TREE_TYPE (tmp))
392 tree domain = TYPE_DOMAIN (tmp);
394 pp_character (buffer, '[');
395 if (domain)
397 if (TYPE_MIN_VALUE (domain)
398 && !integer_zerop (TYPE_MIN_VALUE (domain)))
400 dump_generic_node (buffer, TYPE_MIN_VALUE (domain),
401 spc, flags, false);
402 pp_string (buffer, " .. ");
405 if (TYPE_MAX_VALUE (domain))
406 dump_generic_node (buffer, TYPE_MAX_VALUE (domain),
407 spc, flags, false);
409 else
410 pp_string (buffer, "<unknown>");
412 pp_character (buffer, ']');
414 break;
417 case SET_TYPE:
418 NIY;
419 break;
421 case RECORD_TYPE:
422 case UNION_TYPE:
423 case QUAL_UNION_TYPE:
424 /* Print the name of the structure. */
425 if (TREE_CODE (node) == RECORD_TYPE)
426 pp_string (buffer, "struct ");
427 else if (TREE_CODE (node) == UNION_TYPE)
428 pp_string (buffer, "union ");
430 if (TYPE_NAME (node))
431 dump_generic_node (buffer, TYPE_NAME (node), spc, flags, false);
432 else
433 print_struct_decl (buffer, node, spc, flags);
434 break;
436 case LANG_TYPE:
437 NIY;
438 break;
440 case INTEGER_CST:
441 if (TREE_CODE (TREE_TYPE (node)) == POINTER_TYPE)
443 /* In the case of a pointer, one may want to divide by the
444 size of the pointed-to type. Unfortunately, this not
445 straightforward. The C front-end maps expressions
447 (int *) 5
448 int *p; (p + 5)
450 in such a way that the two INTEGER_CST nodes for "5" have
451 different values but identical types. In the latter
452 case, the 5 is multiplied by sizeof (int) in c-common.c
453 (pointer_int_sum) to convert it to a byte address, and
454 yet the type of the node is left unchanged. Argh. What
455 is consistent though is that the number value corresponds
456 to bytes (UNITS) offset.
458 NB: Neither of the following divisors can be trivially
459 used to recover the original literal:
461 TREE_INT_CST_LOW (TYPE_SIZE_UNIT (TREE_TYPE (node)))
462 TYPE_PRECISION (TREE_TYPE (TREE_TYPE (node))) */
463 pp_wide_integer (buffer, TREE_INT_CST_LOW (node));
464 pp_string (buffer, "B"); /* pseudo-unit */
466 else if (! host_integerp (node, 0))
468 tree val = node;
470 if (tree_int_cst_sgn (val) < 0)
472 pp_character (buffer, '-');
473 val = build_int_2 (-TREE_INT_CST_LOW (val),
474 ~TREE_INT_CST_HIGH (val)
475 + !TREE_INT_CST_LOW (val));
477 /* Would "%x%0*x" or "%x%*0x" get zero-padding on all
478 systems? */
480 static char format[10]; /* "%x%09999x\0" */
481 if (!format[0])
482 sprintf (format, "%%x%%0%dx", HOST_BITS_PER_INT / 4);
483 sprintf (pp_buffer (buffer)->digit_buffer, format,
484 TREE_INT_CST_HIGH (val),
485 TREE_INT_CST_LOW (val));
486 pp_string (buffer, pp_buffer (buffer)->digit_buffer);
489 else
490 pp_wide_integer (buffer, TREE_INT_CST_LOW (node));
491 break;
493 case REAL_CST:
494 /* Code copied from print_node. */
496 REAL_VALUE_TYPE d;
497 if (TREE_OVERFLOW (node))
498 pp_string (buffer, " overflow");
500 #if !defined(REAL_IS_NOT_DOUBLE) || defined(REAL_ARITHMETIC)
501 d = TREE_REAL_CST (node);
502 if (REAL_VALUE_ISINF (d))
503 pp_string (buffer, " Inf");
504 else if (REAL_VALUE_ISNAN (d))
505 pp_string (buffer, " Nan");
506 else
508 char string[100];
509 real_to_decimal (string, &d, sizeof (string), 0, 1);
510 pp_string (buffer, string);
512 #else
514 HOST_WIDE_INT i;
515 unsigned char *p = (unsigned char *) &TREE_REAL_CST (node);
516 pp_string (buffer, "0x");
517 for (i = 0; i < sizeof TREE_REAL_CST (node); i++)
518 output_formatted_integer (buffer, "%02x", *p++);
520 #endif
521 break;
524 case COMPLEX_CST:
525 pp_string (buffer, "__complex__ (");
526 dump_generic_node (buffer, TREE_REALPART (node), spc, flags, false);
527 pp_string (buffer, ", ");
528 dump_generic_node (buffer, TREE_IMAGPART (node), spc, flags, false);
529 pp_string (buffer, ")");
530 break;
532 case STRING_CST:
533 pp_string (buffer, "\"");
534 pretty_print_string (buffer, TREE_STRING_POINTER (node));
535 pp_string (buffer, "\"");
536 break;
538 case VECTOR_CST:
540 tree elt;
541 pp_string (buffer, "{ ");
542 for (elt = TREE_VECTOR_CST_ELTS (node); elt; elt = TREE_CHAIN (elt))
544 dump_generic_node (buffer, TREE_VALUE (elt), spc, flags, false);
545 if (TREE_CHAIN (elt))
546 pp_string (buffer, ", ");
548 pp_string (buffer, " }");
550 break;
552 case FUNCTION_TYPE:
553 break;
555 case FUNCTION_DECL:
556 case CONST_DECL:
557 dump_decl_name (buffer, node, flags);
558 break;
560 case LABEL_DECL:
561 if (DECL_NAME (node))
562 dump_decl_name (buffer, node, flags);
563 else if (LABEL_DECL_UID (node) != -1)
564 pp_printf (buffer, "<L" HOST_WIDE_INT_PRINT_DEC ">",
565 LABEL_DECL_UID (node));
566 else
567 pp_printf (buffer, "<D%u>", DECL_UID (node));
568 break;
570 case TYPE_DECL:
571 if (DECL_IS_BUILTIN (node))
573 /* Don't print the declaration of built-in types. */
574 break;
576 if (DECL_NAME (node))
577 dump_decl_name (buffer, node, flags);
578 else
580 if ((TREE_CODE (TREE_TYPE (node)) == RECORD_TYPE
581 || TREE_CODE (TREE_TYPE (node)) == UNION_TYPE)
582 && TYPE_METHODS (TREE_TYPE (node)))
584 /* The type is a c++ class: all structures have at least
585 4 methods. */
586 pp_string (buffer, "class ");
587 dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
589 else
591 pp_string (buffer,
592 (TREE_CODE (TREE_TYPE (node)) == UNION_TYPE
593 ? "union" : "struct "));
594 dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
597 break;
599 case VAR_DECL:
600 case PARM_DECL:
601 case FIELD_DECL:
602 case NAMESPACE_DECL:
603 dump_decl_name (buffer, node, flags);
604 break;
606 case RESULT_DECL:
607 pp_string (buffer, "<retval>");
608 break;
610 case COMPONENT_REF:
611 op0 = TREE_OPERAND (node, 0);
612 str = ".";
613 if (TREE_CODE (op0) == INDIRECT_REF)
615 op0 = TREE_OPERAND (op0, 0);
616 str = "->";
618 if (op_prio (op0) < op_prio (node))
619 pp_character (buffer, '(');
620 dump_generic_node (buffer, op0, spc, flags, false);
621 if (op_prio (op0) < op_prio (node))
622 pp_character (buffer, ')');
623 pp_string (buffer, str);
624 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
626 op0 = component_ref_field_offset (node);
627 if (op0 && TREE_CODE (op0) != INTEGER_CST)
629 pp_string (buffer, "{off: ");
630 dump_generic_node (buffer, op0, spc, flags, false);
631 pp_character (buffer, '}');
633 break;
635 case BIT_FIELD_REF:
636 pp_string (buffer, "BIT_FIELD_REF <");
637 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
638 pp_string (buffer, ", ");
639 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
640 pp_string (buffer, ", ");
641 dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
642 pp_string (buffer, ">");
643 break;
645 case ARRAY_REF:
646 case ARRAY_RANGE_REF:
647 op0 = TREE_OPERAND (node, 0);
648 if (op_prio (op0) < op_prio (node))
649 pp_character (buffer, '(');
650 dump_generic_node (buffer, op0, spc, flags, false);
651 if (op_prio (op0) < op_prio (node))
652 pp_character (buffer, ')');
653 pp_character (buffer, '[');
654 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
655 if (TREE_CODE (node) == ARRAY_RANGE_REF)
656 pp_string (buffer, " ...");
657 pp_character (buffer, ']');
659 op0 = array_ref_low_bound (node);
660 op1 = array_ref_element_size (node);
662 if (!integer_zerop (op0)
663 || (TYPE_SIZE_UNIT (TREE_TYPE (node))
664 && !operand_equal_p (op1, TYPE_SIZE_UNIT (TREE_TYPE (node)), 0)))
666 pp_string (buffer, "{lb: ");
667 dump_generic_node (buffer, op0, spc, flags, false);
668 pp_string (buffer, " sz: ");
669 dump_generic_node (buffer, op1, spc, flags, false);
670 pp_character (buffer, '}');
672 break;
674 case CONSTRUCTOR:
676 tree lnode;
677 bool is_struct_init = FALSE;
678 pp_character (buffer, '{');
679 lnode = CONSTRUCTOR_ELTS (node);
680 if (TREE_CODE (TREE_TYPE (node)) == RECORD_TYPE
681 || TREE_CODE (TREE_TYPE (node)) == UNION_TYPE)
682 is_struct_init = TRUE;
683 while (lnode && lnode != error_mark_node)
685 tree val;
686 if (TREE_PURPOSE (lnode) && is_struct_init)
688 pp_character (buffer, '.');
689 dump_generic_node (buffer, TREE_PURPOSE (lnode), spc, flags, false);
690 pp_string (buffer, "=");
692 val = TREE_VALUE (lnode);
693 if (val && TREE_CODE (val) == ADDR_EXPR)
694 if (TREE_CODE (TREE_OPERAND (val, 0)) == FUNCTION_DECL)
695 val = TREE_OPERAND (val, 0);
696 if (val && TREE_CODE (val) == FUNCTION_DECL)
698 dump_decl_name (buffer, val, flags);
700 else
702 dump_generic_node (buffer, TREE_VALUE (lnode), spc, flags, false);
704 lnode = TREE_CHAIN (lnode);
705 if (lnode && TREE_CODE (lnode) == TREE_LIST)
707 pp_character (buffer, ',');
708 pp_space (buffer);
711 pp_character (buffer, '}');
713 break;
715 case COMPOUND_EXPR:
717 tree *tp;
718 if (flags & TDF_SLIM)
720 pp_string (buffer, "<COMPOUND_EXPR>");
721 break;
724 dump_generic_node (buffer, TREE_OPERAND (node, 0),
725 spc, flags, dumping_stmts);
726 if (dumping_stmts)
727 newline_and_indent (buffer, spc);
728 else
730 pp_character (buffer, ',');
731 pp_space (buffer);
734 for (tp = &TREE_OPERAND (node, 1);
735 TREE_CODE (*tp) == COMPOUND_EXPR;
736 tp = &TREE_OPERAND (*tp, 1))
738 dump_generic_node (buffer, TREE_OPERAND (*tp, 0),
739 spc, flags, dumping_stmts);
740 if (dumping_stmts)
741 newline_and_indent (buffer, spc);
742 else
744 pp_character (buffer, ',');
745 pp_space (buffer);
749 dump_generic_node (buffer, *tp, spc, flags, dumping_stmts);
751 break;
753 case STATEMENT_LIST:
755 tree_stmt_iterator si;
756 bool first = true;
758 if ((flags & TDF_SLIM) || !dumping_stmts)
760 pp_string (buffer, "<STATEMENT_LIST>");
761 break;
764 for (si = tsi_start (node); !tsi_end_p (si); tsi_next (&si))
766 if (!first)
767 newline_and_indent (buffer, spc);
768 else
769 first = false;
770 dump_generic_node (buffer, tsi_stmt (si), spc, flags, true);
773 break;
775 case MODIFY_EXPR:
776 case INIT_EXPR:
777 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
778 pp_space (buffer);
779 pp_character (buffer, '=');
780 pp_space (buffer);
781 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
782 break;
784 case TARGET_EXPR:
785 pp_string (buffer, "TARGET_EXPR <");
786 dump_generic_node (buffer, TARGET_EXPR_SLOT (node), spc, flags, false);
787 pp_character (buffer, ',');
788 pp_space (buffer);
789 dump_generic_node (buffer, TARGET_EXPR_INITIAL (node), spc, flags, false);
790 pp_character (buffer, '>');
791 break;
793 case DECL_EXPR:
794 print_declaration (buffer, DECL_EXPR_DECL (node), spc, flags);
795 is_stmt = false;
796 break;
798 case COND_EXPR:
799 if (TREE_TYPE (node) == NULL || TREE_TYPE (node) == void_type_node)
801 pp_string (buffer, "if (");
802 dump_generic_node (buffer, COND_EXPR_COND (node), spc, flags, false);
803 pp_character (buffer, ')');
804 /* The lowered cond_exprs should always be printed in full. */
805 if (COND_EXPR_THEN (node)
806 && TREE_CODE (COND_EXPR_THEN (node)) == GOTO_EXPR
807 && COND_EXPR_ELSE (node)
808 && TREE_CODE (COND_EXPR_ELSE (node)) == GOTO_EXPR)
810 pp_space (buffer);
811 dump_generic_node (buffer, COND_EXPR_THEN (node), 0, flags, true);
812 pp_string (buffer, " else ");
813 dump_generic_node (buffer, COND_EXPR_ELSE (node), 0, flags, true);
815 else if (!(flags & TDF_SLIM))
817 /* Output COND_EXPR_THEN. */
818 if (COND_EXPR_THEN (node))
820 newline_and_indent (buffer, spc+2);
821 pp_character (buffer, '{');
822 newline_and_indent (buffer, spc+4);
823 dump_generic_node (buffer, COND_EXPR_THEN (node), spc+4,
824 flags, true);
825 newline_and_indent (buffer, spc+2);
826 pp_character (buffer, '}');
829 /* Output COND_EXPR_ELSE. */
830 if (COND_EXPR_ELSE (node))
832 newline_and_indent (buffer, spc);
833 pp_string (buffer, "else");
834 newline_and_indent (buffer, spc+2);
835 pp_character (buffer, '{');
836 newline_and_indent (buffer, spc+4);
837 dump_generic_node (buffer, COND_EXPR_ELSE (node), spc+4,
838 flags, true);
839 newline_and_indent (buffer, spc+2);
840 pp_character (buffer, '}');
843 is_expr = false;
845 else
847 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
848 pp_space (buffer);
849 pp_character (buffer, '?');
850 pp_space (buffer);
851 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
852 pp_space (buffer);
853 pp_character (buffer, ':');
854 pp_space (buffer);
855 dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
857 break;
859 case BIND_EXPR:
860 pp_character (buffer, '{');
861 if (!(flags & TDF_SLIM))
863 if (BIND_EXPR_VARS (node))
865 pp_newline (buffer);
867 for (op0 = BIND_EXPR_VARS (node); op0; op0 = TREE_CHAIN (op0))
869 print_declaration (buffer, op0, spc+2, flags);
870 pp_newline (buffer);
874 newline_and_indent (buffer, spc+2);
875 dump_generic_node (buffer, BIND_EXPR_BODY (node), spc+2, flags, true);
876 newline_and_indent (buffer, spc);
877 pp_character (buffer, '}');
879 is_expr = false;
880 break;
882 case CALL_EXPR:
883 print_call_name (buffer, node);
885 /* Print parameters. */
886 pp_space (buffer);
887 pp_character (buffer, '(');
888 op1 = TREE_OPERAND (node, 1);
889 if (op1)
890 dump_generic_node (buffer, op1, spc, flags, false);
891 pp_character (buffer, ')');
893 op1 = TREE_OPERAND (node, 2);
894 if (op1)
896 pp_string (buffer, " [static-chain: ");
897 dump_generic_node (buffer, op1, spc, flags, false);
898 pp_character (buffer, ']');
901 if (CALL_EXPR_HAS_RETURN_SLOT_ADDR (node))
902 pp_string (buffer, " [return slot addr]");
903 if (CALL_EXPR_TAILCALL (node))
904 pp_string (buffer, " [tail call]");
905 break;
907 case WITH_CLEANUP_EXPR:
908 NIY;
909 break;
911 case CLEANUP_POINT_EXPR:
912 pp_string (buffer, "<<cleanup_point ");
913 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
914 pp_string (buffer, ">>");
915 break;
917 case PLACEHOLDER_EXPR:
918 pp_string (buffer, "<PLACEHOLDER_EXPR ");
919 dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
920 pp_character (buffer, '>');
921 break;
923 /* Binary arithmetic and logic expressions. */
924 case MULT_EXPR:
925 case PLUS_EXPR:
926 case MINUS_EXPR:
927 case TRUNC_DIV_EXPR:
928 case CEIL_DIV_EXPR:
929 case FLOOR_DIV_EXPR:
930 case ROUND_DIV_EXPR:
931 case TRUNC_MOD_EXPR:
932 case CEIL_MOD_EXPR:
933 case FLOOR_MOD_EXPR:
934 case ROUND_MOD_EXPR:
935 case RDIV_EXPR:
936 case EXACT_DIV_EXPR:
937 case LSHIFT_EXPR:
938 case RSHIFT_EXPR:
939 case LROTATE_EXPR:
940 case RROTATE_EXPR:
941 case BIT_IOR_EXPR:
942 case BIT_XOR_EXPR:
943 case BIT_AND_EXPR:
944 case TRUTH_ANDIF_EXPR:
945 case TRUTH_ORIF_EXPR:
946 case TRUTH_AND_EXPR:
947 case TRUTH_OR_EXPR:
948 case TRUTH_XOR_EXPR:
949 case LT_EXPR:
950 case LE_EXPR:
951 case GT_EXPR:
952 case GE_EXPR:
953 case EQ_EXPR:
954 case NE_EXPR:
955 case UNLT_EXPR:
956 case UNLE_EXPR:
957 case UNGT_EXPR:
958 case UNGE_EXPR:
959 case UNEQ_EXPR:
960 case LTGT_EXPR:
961 case ORDERED_EXPR:
962 case UNORDERED_EXPR:
964 const char *op = op_symbol (node);
965 op0 = TREE_OPERAND (node, 0);
966 op1 = TREE_OPERAND (node, 1);
968 /* When the operands are expressions with less priority,
969 keep semantics of the tree representation. */
970 if (op_prio (op0) < op_prio (node))
972 pp_character (buffer, '(');
973 dump_generic_node (buffer, op0, spc, flags, false);
974 pp_character (buffer, ')');
976 else
977 dump_generic_node (buffer, op0, spc, flags, false);
979 pp_space (buffer);
980 pp_string (buffer, op);
981 pp_space (buffer);
983 /* When the operands are expressions with less priority,
984 keep semantics of the tree representation. */
985 if (op_prio (op1) < op_prio (node))
987 pp_character (buffer, '(');
988 dump_generic_node (buffer, op1, spc, flags, false);
989 pp_character (buffer, ')');
991 else
992 dump_generic_node (buffer, op1, spc, flags, false);
994 break;
996 /* Unary arithmetic and logic expressions. */
997 case NEGATE_EXPR:
998 case BIT_NOT_EXPR:
999 case TRUTH_NOT_EXPR:
1000 case ADDR_EXPR:
1001 case PREDECREMENT_EXPR:
1002 case PREINCREMENT_EXPR:
1003 case INDIRECT_REF:
1004 if (TREE_CODE (node) == ADDR_EXPR
1005 && (TREE_CODE (TREE_OPERAND (node, 0)) == STRING_CST
1006 || TREE_CODE (TREE_OPERAND (node, 0)) == FUNCTION_DECL))
1007 ; /* Do not output '&' for strings and function pointers. */
1008 else
1009 pp_string (buffer, op_symbol (node));
1011 if (op_prio (TREE_OPERAND (node, 0)) < op_prio (node))
1013 pp_character (buffer, '(');
1014 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1015 pp_character (buffer, ')');
1017 else
1018 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1019 break;
1021 case POSTDECREMENT_EXPR:
1022 case POSTINCREMENT_EXPR:
1023 if (op_prio (TREE_OPERAND (node, 0)) < op_prio (node))
1025 pp_character (buffer, '(');
1026 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1027 pp_character (buffer, ')');
1029 else
1030 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1031 pp_string (buffer, op_symbol (node));
1032 break;
1034 case MIN_EXPR:
1035 pp_string (buffer, "MIN_EXPR <");
1036 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1037 pp_string (buffer, ", ");
1038 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1039 pp_character (buffer, '>');
1040 break;
1042 case MAX_EXPR:
1043 pp_string (buffer, "MAX_EXPR <");
1044 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1045 pp_string (buffer, ", ");
1046 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1047 pp_character (buffer, '>');
1048 break;
1050 case ABS_EXPR:
1051 pp_string (buffer, "ABS_EXPR <");
1052 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1053 pp_character (buffer, '>');
1054 break;
1056 case RANGE_EXPR:
1057 NIY;
1058 break;
1060 case FIX_TRUNC_EXPR:
1061 case FIX_CEIL_EXPR:
1062 case FIX_FLOOR_EXPR:
1063 case FIX_ROUND_EXPR:
1064 case FLOAT_EXPR:
1065 case CONVERT_EXPR:
1066 case NOP_EXPR:
1067 type = TREE_TYPE (node);
1068 op0 = TREE_OPERAND (node, 0);
1069 if (type != TREE_TYPE (op0))
1071 pp_character (buffer, '(');
1072 dump_generic_node (buffer, type, spc, flags, false);
1073 pp_string (buffer, ")");
1075 if (op_prio (op0) < op_prio (node))
1076 pp_character (buffer, '(');
1077 dump_generic_node (buffer, op0, spc, flags, false);
1078 if (op_prio (op0) < op_prio (node))
1079 pp_character (buffer, ')');
1080 break;
1082 case VIEW_CONVERT_EXPR:
1083 pp_string (buffer, "VIEW_CONVERT_EXPR<");
1084 dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
1085 pp_string (buffer, ">(");
1086 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1087 pp_character (buffer, ')');
1088 break;
1090 case NON_LVALUE_EXPR:
1091 pp_string (buffer, "NON_LVALUE_EXPR <");
1092 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1093 pp_character (buffer, '>');
1094 break;
1096 case SAVE_EXPR:
1097 pp_string (buffer, "SAVE_EXPR <");
1098 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1099 pp_character (buffer, '>');
1100 break;
1102 case ENTRY_VALUE_EXPR:
1103 NIY;
1104 break;
1106 case COMPLEX_EXPR:
1107 pp_string (buffer, "COMPLEX_EXPR <");
1108 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1109 pp_string (buffer, ", ");
1110 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1111 pp_string (buffer, ">");
1112 break;
1114 case CONJ_EXPR:
1115 pp_string (buffer, "CONJ_EXPR <");
1116 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1117 pp_string (buffer, ">");
1118 break;
1120 case REALPART_EXPR:
1121 pp_string (buffer, "REALPART_EXPR <");
1122 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1123 pp_string (buffer, ">");
1124 break;
1126 case IMAGPART_EXPR:
1127 pp_string (buffer, "IMAGPART_EXPR <");
1128 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1129 pp_string (buffer, ">");
1130 break;
1132 case VA_ARG_EXPR:
1133 pp_string (buffer, "VA_ARG_EXPR <");
1134 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1135 pp_string (buffer, ">");
1136 break;
1138 case TRY_FINALLY_EXPR:
1139 case TRY_CATCH_EXPR:
1140 pp_string (buffer, "try");
1141 newline_and_indent (buffer, spc+2);
1142 pp_string (buffer, "{");
1143 newline_and_indent (buffer, spc+4);
1144 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc+4, flags, true);
1145 newline_and_indent (buffer, spc+2);
1146 pp_string (buffer, "}");
1147 newline_and_indent (buffer, spc);
1148 pp_string (buffer,
1149 (TREE_CODE (node) == TRY_CATCH_EXPR) ? "catch" : "finally");
1150 newline_and_indent (buffer, spc+2);
1151 pp_string (buffer, "{");
1152 newline_and_indent (buffer, spc+4);
1153 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc+4, flags, true);
1154 newline_and_indent (buffer, spc+2);
1155 pp_string (buffer, "}");
1156 is_expr = false;
1157 break;
1159 case CATCH_EXPR:
1160 pp_string (buffer, "catch (");
1161 dump_generic_node (buffer, CATCH_TYPES (node), spc+2, flags, false);
1162 pp_string (buffer, ")");
1163 newline_and_indent (buffer, spc+2);
1164 pp_string (buffer, "{");
1165 newline_and_indent (buffer, spc+4);
1166 dump_generic_node (buffer, CATCH_BODY (node), spc+4, flags, true);
1167 newline_and_indent (buffer, spc+2);
1168 pp_string (buffer, "}");
1169 is_expr = false;
1170 break;
1172 case EH_FILTER_EXPR:
1173 pp_string (buffer, "<<<eh_filter (");
1174 dump_generic_node (buffer, EH_FILTER_TYPES (node), spc+2, flags, false);
1175 pp_string (buffer, ")>>>");
1176 newline_and_indent (buffer, spc+2);
1177 pp_string (buffer, "{");
1178 newline_and_indent (buffer, spc+4);
1179 dump_generic_node (buffer, EH_FILTER_FAILURE (node), spc+4, flags, true);
1180 newline_and_indent (buffer, spc+2);
1181 pp_string (buffer, "}");
1182 is_expr = false;
1183 break;
1185 case LABEL_EXPR:
1186 op0 = TREE_OPERAND (node, 0);
1187 /* If this is for break or continue, don't bother printing it. */
1188 if (DECL_NAME (op0))
1190 const char *name = IDENTIFIER_POINTER (DECL_NAME (op0));
1191 if (strcmp (name, "break") == 0
1192 || strcmp (name, "continue") == 0)
1193 break;
1195 dump_generic_node (buffer, op0, spc, flags, false);
1196 pp_character (buffer, ':');
1197 if (DECL_NONLOCAL (op0))
1198 pp_string (buffer, " [non-local]");
1199 break;
1201 case LABELED_BLOCK_EXPR:
1202 op0 = LABELED_BLOCK_LABEL (node);
1203 /* If this is for break or continue, don't bother printing it. */
1204 if (DECL_NAME (op0))
1206 const char *name = IDENTIFIER_POINTER (DECL_NAME (op0));
1207 if (strcmp (name, "break") == 0
1208 || strcmp (name, "continue") == 0)
1210 dump_generic_node (buffer, LABELED_BLOCK_BODY (node), spc, flags, false);
1211 break;
1214 dump_generic_node (buffer, LABELED_BLOCK_LABEL (node), spc, flags, false);
1215 pp_string (buffer, ": {");
1216 if (!(flags & TDF_SLIM))
1217 newline_and_indent (buffer, spc+2);
1218 dump_generic_node (buffer, LABELED_BLOCK_BODY (node), spc+2, flags, true);
1219 if (!flags)
1220 newline_and_indent (buffer, spc);
1221 pp_character (buffer, '}');
1222 is_expr = false;
1223 break;
1225 case EXIT_BLOCK_EXPR:
1226 op0 = LABELED_BLOCK_LABEL (EXIT_BLOCK_LABELED_BLOCK (node));
1227 /* If this is for a break or continue, print it accordingly. */
1228 if (DECL_NAME (op0))
1230 const char *name = IDENTIFIER_POINTER (DECL_NAME (op0));
1231 if (strcmp (name, "break") == 0
1232 || strcmp (name, "continue") == 0)
1234 pp_string (buffer, name);
1235 break;
1238 pp_string (buffer, "<<<exit block ");
1239 dump_generic_node (buffer, op0, spc, flags, false);
1240 pp_string (buffer, ">>>");
1241 break;
1243 case EXC_PTR_EXPR:
1244 pp_string (buffer, "<<<exception object>>>");
1245 break;
1247 case FILTER_EXPR:
1248 pp_string (buffer, "<<<filter object>>>");
1249 break;
1251 case LOOP_EXPR:
1252 pp_string (buffer, "while (1)");
1253 if (!(flags & TDF_SLIM))
1255 newline_and_indent (buffer, spc+2);
1256 pp_character (buffer, '{');
1257 newline_and_indent (buffer, spc+4);
1258 dump_generic_node (buffer, LOOP_EXPR_BODY (node), spc+4, flags, true);
1259 newline_and_indent (buffer, spc+2);
1260 pp_character (buffer, '}');
1262 is_expr = false;
1263 break;
1265 case RETURN_EXPR:
1266 pp_string (buffer, "return");
1267 op0 = TREE_OPERAND (node, 0);
1268 if (op0)
1270 pp_space (buffer);
1271 if (TREE_CODE (op0) == MODIFY_EXPR)
1272 dump_generic_node (buffer, TREE_OPERAND (op0, 1), spc, flags, false);
1273 else
1274 dump_generic_node (buffer, op0, spc, flags, false);
1276 break;
1278 case EXIT_EXPR:
1279 pp_string (buffer, "if (");
1280 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1281 pp_string (buffer, ") break");
1282 break;
1284 case SWITCH_EXPR:
1285 pp_string (buffer, "switch (");
1286 dump_generic_node (buffer, SWITCH_COND (node), spc, flags, false);
1287 pp_character (buffer, ')');
1288 if (!(flags & TDF_SLIM))
1290 newline_and_indent (buffer, spc+2);
1291 pp_character (buffer, '{');
1292 if (SWITCH_BODY (node))
1294 newline_and_indent (buffer, spc+4);
1295 dump_generic_node (buffer, SWITCH_BODY (node), spc+4, flags, true);
1297 else
1299 tree vec = SWITCH_LABELS (node);
1300 size_t i, n = TREE_VEC_LENGTH (vec);
1301 for (i = 0; i < n; ++i)
1303 tree elt = TREE_VEC_ELT (vec, i);
1304 newline_and_indent (buffer, spc+4);
1305 dump_generic_node (buffer, elt, spc+4, flags, false);
1306 pp_string (buffer, " goto ");
1307 dump_generic_node (buffer, CASE_LABEL (elt), spc+4, flags, true);
1308 pp_semicolon (buffer);
1311 newline_and_indent (buffer, spc+2);
1312 pp_character (buffer, '}');
1314 is_expr = false;
1315 break;
1317 case GOTO_EXPR:
1318 op0 = GOTO_DESTINATION (node);
1319 if (TREE_CODE (op0) != SSA_NAME
1320 && DECL_P (op0)
1321 && DECL_NAME (op0))
1323 const char *name = IDENTIFIER_POINTER (DECL_NAME (op0));
1324 if (strcmp (name, "break") == 0
1325 || strcmp (name, "continue") == 0)
1327 pp_string (buffer, name);
1328 break;
1331 pp_string (buffer, "goto ");
1332 dump_generic_node (buffer, op0, spc, flags, false);
1333 break;
1335 case RESX_EXPR:
1336 pp_string (buffer, "resx");
1337 /* ??? Any sensible way to present the eh region? */
1338 break;
1340 case ASM_EXPR:
1341 pp_string (buffer, "__asm__");
1342 if (ASM_VOLATILE_P (node))
1343 pp_string (buffer, " __volatile__");
1344 pp_character (buffer, '(');
1345 dump_generic_node (buffer, ASM_STRING (node), spc, flags, false);
1346 pp_character (buffer, ':');
1347 dump_generic_node (buffer, ASM_OUTPUTS (node), spc, flags, false);
1348 pp_character (buffer, ':');
1349 dump_generic_node (buffer, ASM_INPUTS (node), spc, flags, false);
1350 if (ASM_CLOBBERS (node))
1352 pp_character (buffer, ':');
1353 dump_generic_node (buffer, ASM_CLOBBERS (node), spc, flags, false);
1355 pp_string (buffer, ")");
1356 break;
1358 case CASE_LABEL_EXPR:
1359 if (CASE_LOW (node) && CASE_HIGH (node))
1361 pp_string (buffer, "case ");
1362 dump_generic_node (buffer, CASE_LOW (node), spc, flags, false);
1363 pp_string (buffer, " ... ");
1364 dump_generic_node (buffer, CASE_HIGH (node), spc, flags, false);
1366 else if (CASE_LOW (node))
1368 pp_string (buffer, "case ");
1369 dump_generic_node (buffer, CASE_LOW (node), spc, flags, false);
1371 else
1372 pp_string (buffer, "default ");
1373 pp_character (buffer, ':');
1374 break;
1376 case OBJ_TYPE_REF:
1377 pp_string (buffer, "OBJ_TYPE_REF(");
1378 dump_generic_node (buffer, OBJ_TYPE_REF_EXPR (node), spc, flags, false);
1379 pp_character (buffer, ';');
1380 dump_generic_node (buffer, OBJ_TYPE_REF_OBJECT (node), spc, flags, false);
1381 pp_character (buffer, '-');
1382 pp_character (buffer, '>');
1383 dump_generic_node (buffer, OBJ_TYPE_REF_TOKEN (node), spc, flags, false);
1384 pp_character (buffer, ')');
1385 break;
1387 case PHI_NODE:
1389 int i;
1391 dump_generic_node (buffer, PHI_RESULT (node), spc, flags, false);
1392 pp_string (buffer, " = PHI <");
1393 for (i = 0; i < PHI_NUM_ARGS (node); i++)
1395 dump_generic_node (buffer, PHI_ARG_DEF (node, i), spc, flags, false);
1396 pp_string (buffer, "(");
1397 pp_decimal_int (buffer, PHI_ARG_EDGE (node, i)->src->index);
1398 pp_string (buffer, ")");
1399 if (i < PHI_NUM_ARGS (node) - 1)
1400 pp_string (buffer, ", ");
1402 pp_string (buffer, ">;");
1404 break;
1406 case SSA_NAME:
1407 dump_generic_node (buffer, SSA_NAME_VAR (node), spc, flags, false);
1408 pp_string (buffer, "_");
1409 pp_decimal_int (buffer, SSA_NAME_VERSION (node));
1410 break;
1412 case WITH_SIZE_EXPR:
1413 pp_string (buffer, "WITH_SIZE_EXPR <");
1414 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1415 pp_string (buffer, ", ");
1416 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1417 pp_string (buffer, ">");
1418 break;
1420 case VALUE_HANDLE:
1421 pp_printf (buffer, "VH.%d", VALUE_HANDLE_ID (node));
1422 break;
1424 case SCEV_KNOWN:
1425 pp_string (buffer, "scev_known");
1426 break;
1428 case SCEV_NOT_KNOWN:
1429 pp_string (buffer, "scev_not_known");
1430 break;
1432 case POLYNOMIAL_CHREC:
1433 pp_string (buffer, "{");
1434 dump_generic_node (buffer, CHREC_LEFT (node), spc, flags, false);
1435 pp_string (buffer, ", +, ");
1436 dump_generic_node (buffer, CHREC_RIGHT (node), spc, flags, false);
1437 pp_string (buffer, "}_");
1438 dump_generic_node (buffer, CHREC_VAR (node), spc, flags, false);
1439 is_stmt = false;
1440 break;
1442 default:
1443 NIY;
1446 if (is_stmt && is_expr)
1447 pp_semicolon (buffer);
1448 pp_write_text_to_stream (buffer);
1450 return spc;
1453 /* Print the declaration of a variable. */
1455 static void
1456 print_declaration (pretty_printer *buffer, tree t, int spc, int flags)
1458 INDENT (spc);
1460 if (TREE_CODE (t) == TYPE_DECL)
1461 pp_string (buffer, "typedef ");
1463 if (DECL_REGISTER (t))
1464 pp_string (buffer, "register ");
1466 if (TREE_PUBLIC (t) && DECL_EXTERNAL (t))
1467 pp_string (buffer, "extern ");
1468 else if (TREE_STATIC (t))
1469 pp_string (buffer, "static ");
1471 /* Print the type and name. */
1472 if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
1474 tree tmp;
1476 /* Print array's type. */
1477 tmp = TREE_TYPE (t);
1478 while (TREE_CODE (TREE_TYPE (tmp)) == ARRAY_TYPE)
1479 tmp = TREE_TYPE (tmp);
1480 dump_generic_node (buffer, TREE_TYPE (tmp), spc, flags, false);
1482 /* Print variable's name. */
1483 pp_space (buffer);
1484 dump_generic_node (buffer, t, spc, flags, false);
1486 /* Print the dimensions. */
1487 tmp = TREE_TYPE (t);
1488 while (TREE_CODE (tmp) == ARRAY_TYPE)
1490 pp_character (buffer, '[');
1491 if (TYPE_DOMAIN (tmp))
1493 if (TREE_CODE (TYPE_SIZE (tmp)) == INTEGER_CST)
1494 pp_wide_integer (buffer,
1495 TREE_INT_CST_LOW (TYPE_SIZE (tmp)) /
1496 TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (tmp))));
1497 else
1498 dump_generic_node (buffer, TYPE_SIZE_UNIT (tmp), spc, flags,
1499 false);
1501 pp_character (buffer, ']');
1502 tmp = TREE_TYPE (tmp);
1505 else if (TREE_CODE (t) == FUNCTION_DECL)
1507 dump_generic_node (buffer, TREE_TYPE (TREE_TYPE (t)), spc, flags, false);
1508 pp_space (buffer);
1509 dump_decl_name (buffer, t, flags);
1510 dump_function_declaration (buffer, TREE_TYPE (t), spc, flags);
1512 else
1514 /* Print type declaration. */
1515 dump_generic_node (buffer, TREE_TYPE (t), spc, flags, false);
1517 /* Print variable's name. */
1518 pp_space (buffer);
1519 dump_generic_node (buffer, t, spc, flags, false);
1522 /* The initial value of a function serves to determine wether the function
1523 is declared or defined. So the following does not apply to function
1524 nodes. */
1525 if (TREE_CODE (t) != FUNCTION_DECL)
1527 /* Print the initial value. */
1528 if (DECL_INITIAL (t))
1530 pp_space (buffer);
1531 pp_character (buffer, '=');
1532 pp_space (buffer);
1533 dump_generic_node (buffer, DECL_INITIAL (t), spc, flags, false);
1537 pp_character (buffer, ';');
1541 /* Prints a structure: name, fields, and methods.
1542 FIXME: Still incomplete. */
1544 static void
1545 print_struct_decl (pretty_printer *buffer, tree node, int spc, int flags)
1547 /* Print the name of the structure. */
1548 if (TYPE_NAME (node))
1550 INDENT (spc);
1551 if (TREE_CODE (node) == RECORD_TYPE)
1552 pp_string (buffer, "struct ");
1553 else if ((TREE_CODE (node) == UNION_TYPE
1554 || TREE_CODE (node) == QUAL_UNION_TYPE))
1555 pp_string (buffer, "union ");
1557 dump_generic_node (buffer, TYPE_NAME (node), spc, 0, false);
1560 /* Print the contents of the structure. */
1561 pp_newline (buffer);
1562 INDENT (spc);
1563 pp_character (buffer, '{');
1564 pp_newline (buffer);
1566 /* Print the fields of the structure. */
1568 tree tmp;
1569 tmp = TYPE_FIELDS (node);
1570 while (tmp)
1572 /* Avoid to print recursively the structure. */
1573 /* FIXME : Not implemented correctly...,
1574 what about the case when we have a cycle in the contain graph? ...
1575 Maybe this could be solved by looking at the scope in which the
1576 structure was declared. */
1577 if (TREE_TYPE (tmp) != node
1578 || (TREE_CODE (TREE_TYPE (tmp)) == POINTER_TYPE
1579 && TREE_TYPE (TREE_TYPE (tmp)) != node))
1581 print_declaration (buffer, tmp, spc+2, flags);
1582 pp_newline (buffer);
1584 tmp = TREE_CHAIN (tmp);
1587 INDENT (spc);
1588 pp_character (buffer, '}');
1591 /* Return the priority of the operator OP.
1593 From lowest to highest precedence with either left-to-right (L-R)
1594 or right-to-left (R-L) associativity]:
1596 1 [L-R] ,
1597 2 [R-L] = += -= *= /= %= &= ^= |= <<= >>=
1598 3 [R-L] ?:
1599 4 [L-R] ||
1600 5 [L-R] &&
1601 6 [L-R] |
1602 7 [L-R] ^
1603 8 [L-R] &
1604 9 [L-R] == !=
1605 10 [L-R] < <= > >=
1606 11 [L-R] << >>
1607 12 [L-R] + -
1608 13 [L-R] * / %
1609 14 [R-L] ! ~ ++ -- + - * & (type) sizeof
1610 15 [L-R] fn() [] -> .
1612 unary +, - and * have higher precedence than the corresponding binary
1613 operators. */
1615 static int
1616 op_prio (tree op)
1618 if (op == NULL)
1619 return 9999;
1621 switch (TREE_CODE (op))
1623 case TREE_LIST:
1624 case COMPOUND_EXPR:
1625 case BIND_EXPR:
1626 return 1;
1628 case MODIFY_EXPR:
1629 case INIT_EXPR:
1630 return 2;
1632 case COND_EXPR:
1633 return 3;
1635 case TRUTH_OR_EXPR:
1636 case TRUTH_ORIF_EXPR:
1637 return 4;
1639 case TRUTH_AND_EXPR:
1640 case TRUTH_ANDIF_EXPR:
1641 return 5;
1643 case BIT_IOR_EXPR:
1644 return 6;
1646 case BIT_XOR_EXPR:
1647 case TRUTH_XOR_EXPR:
1648 return 7;
1650 case BIT_AND_EXPR:
1651 return 8;
1653 case EQ_EXPR:
1654 case NE_EXPR:
1655 return 9;
1657 case UNLT_EXPR:
1658 case UNLE_EXPR:
1659 case UNGT_EXPR:
1660 case UNGE_EXPR:
1661 case UNEQ_EXPR:
1662 case LTGT_EXPR:
1663 case ORDERED_EXPR:
1664 case UNORDERED_EXPR:
1665 case LT_EXPR:
1666 case LE_EXPR:
1667 case GT_EXPR:
1668 case GE_EXPR:
1669 return 10;
1671 case LSHIFT_EXPR:
1672 case RSHIFT_EXPR:
1673 case LROTATE_EXPR:
1674 case RROTATE_EXPR:
1675 return 11;
1677 case PLUS_EXPR:
1678 case MINUS_EXPR:
1679 return 12;
1681 case MULT_EXPR:
1682 case TRUNC_DIV_EXPR:
1683 case CEIL_DIV_EXPR:
1684 case FLOOR_DIV_EXPR:
1685 case ROUND_DIV_EXPR:
1686 case RDIV_EXPR:
1687 case EXACT_DIV_EXPR:
1688 case TRUNC_MOD_EXPR:
1689 case CEIL_MOD_EXPR:
1690 case FLOOR_MOD_EXPR:
1691 case ROUND_MOD_EXPR:
1692 return 13;
1694 case TRUTH_NOT_EXPR:
1695 case BIT_NOT_EXPR:
1696 case POSTINCREMENT_EXPR:
1697 case POSTDECREMENT_EXPR:
1698 case PREINCREMENT_EXPR:
1699 case PREDECREMENT_EXPR:
1700 case NEGATE_EXPR:
1701 case INDIRECT_REF:
1702 case ADDR_EXPR:
1703 case FLOAT_EXPR:
1704 case NOP_EXPR:
1705 case CONVERT_EXPR:
1706 case FIX_TRUNC_EXPR:
1707 case FIX_CEIL_EXPR:
1708 case FIX_FLOOR_EXPR:
1709 case FIX_ROUND_EXPR:
1710 case TARGET_EXPR:
1711 return 14;
1713 case CALL_EXPR:
1714 case ARRAY_REF:
1715 case ARRAY_RANGE_REF:
1716 case COMPONENT_REF:
1717 return 15;
1719 /* Special expressions. */
1720 case MIN_EXPR:
1721 case MAX_EXPR:
1722 case ABS_EXPR:
1723 case REALPART_EXPR:
1724 case IMAGPART_EXPR:
1725 return 16;
1727 case SAVE_EXPR:
1728 case NON_LVALUE_EXPR:
1729 return op_prio (TREE_OPERAND (op, 0));
1731 default:
1732 /* Return an arbitrarily high precedence to avoid surrounding single
1733 VAR_DECLs in ()s. */
1734 return 9999;
1739 /* Return the symbol associated with operator OP. */
1741 static const char *
1742 op_symbol (tree op)
1744 if (op == NULL)
1745 abort ();
1747 switch (TREE_CODE (op))
1749 case MODIFY_EXPR:
1750 return "=";
1752 case TRUTH_OR_EXPR:
1753 case TRUTH_ORIF_EXPR:
1754 return "||";
1756 case TRUTH_AND_EXPR:
1757 case TRUTH_ANDIF_EXPR:
1758 return "&&";
1760 case BIT_IOR_EXPR:
1761 return "|";
1763 case TRUTH_XOR_EXPR:
1764 case BIT_XOR_EXPR:
1765 return "^";
1767 case ADDR_EXPR:
1768 case BIT_AND_EXPR:
1769 return "&";
1771 case ORDERED_EXPR:
1772 return "ord";
1773 case UNORDERED_EXPR:
1774 return "unord";
1776 case EQ_EXPR:
1777 return "==";
1778 case UNEQ_EXPR:
1779 return "u==";
1781 case NE_EXPR:
1782 return "!=";
1784 case LT_EXPR:
1785 return "<";
1786 case UNLT_EXPR:
1787 return "u<";
1789 case LE_EXPR:
1790 return "<=";
1791 case UNLE_EXPR:
1792 return "u<=";
1794 case GT_EXPR:
1795 return ">";
1796 case UNGT_EXPR:
1797 return "u>";
1799 case GE_EXPR:
1800 return ">=";
1801 case UNGE_EXPR:
1802 return "u>=";
1804 case LTGT_EXPR:
1805 return "<>";
1807 case LSHIFT_EXPR:
1808 return "<<";
1810 case RSHIFT_EXPR:
1811 return ">>";
1813 case PLUS_EXPR:
1814 return "+";
1816 case NEGATE_EXPR:
1817 case MINUS_EXPR:
1818 return "-";
1820 case BIT_NOT_EXPR:
1821 return "~";
1823 case TRUTH_NOT_EXPR:
1824 return "!";
1826 case MULT_EXPR:
1827 case INDIRECT_REF:
1828 return "*";
1830 case TRUNC_DIV_EXPR:
1831 case CEIL_DIV_EXPR:
1832 case FLOOR_DIV_EXPR:
1833 case ROUND_DIV_EXPR:
1834 case RDIV_EXPR:
1835 case EXACT_DIV_EXPR:
1836 return "/";
1838 case TRUNC_MOD_EXPR:
1839 case CEIL_MOD_EXPR:
1840 case FLOOR_MOD_EXPR:
1841 case ROUND_MOD_EXPR:
1842 return "%";
1844 case PREDECREMENT_EXPR:
1845 return " --";
1847 case PREINCREMENT_EXPR:
1848 return " ++";
1850 case POSTDECREMENT_EXPR:
1851 return "-- ";
1853 case POSTINCREMENT_EXPR:
1854 return "++ ";
1856 default:
1857 return "<<< ??? >>>";
1861 /* Prints the name of a CALL_EXPR. */
1863 static void
1864 print_call_name (pretty_printer *buffer, tree node)
1866 tree op0;
1868 if (TREE_CODE (node) != CALL_EXPR)
1869 abort ();
1871 op0 = TREE_OPERAND (node, 0);
1873 if (TREE_CODE (op0) == NON_LVALUE_EXPR)
1874 op0 = TREE_OPERAND (op0, 0);
1876 switch (TREE_CODE (op0))
1878 case VAR_DECL:
1879 case PARM_DECL:
1880 PRINT_FUNCTION_NAME (op0);
1881 break;
1883 case ADDR_EXPR:
1884 case INDIRECT_REF:
1885 case NOP_EXPR:
1886 dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
1887 break;
1889 case COND_EXPR:
1890 pp_string (buffer, "(");
1891 dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
1892 pp_string (buffer, ") ? ");
1893 dump_generic_node (buffer, TREE_OPERAND (op0, 1), 0, 0, false);
1894 pp_string (buffer, " : ");
1895 dump_generic_node (buffer, TREE_OPERAND (op0, 2), 0, 0, false);
1896 break;
1898 case COMPONENT_REF:
1899 /* The function is a pointer contained in a structure. */
1900 if (TREE_CODE (TREE_OPERAND (op0, 0)) == INDIRECT_REF ||
1901 TREE_CODE (TREE_OPERAND (op0, 0)) == VAR_DECL)
1902 PRINT_FUNCTION_NAME (TREE_OPERAND (op0, 1));
1903 else
1904 dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
1905 /* else
1906 We can have several levels of structures and a function
1907 pointer inside. This is not implemented yet... */
1908 /* NIY;*/
1909 break;
1911 case ARRAY_REF:
1912 if (TREE_CODE (TREE_OPERAND (op0, 0)) == VAR_DECL)
1913 PRINT_FUNCTION_NAME (TREE_OPERAND (op0, 0));
1914 else
1915 dump_generic_node (buffer, op0, 0, 0, false);
1916 break;
1918 case SSA_NAME:
1919 case OBJ_TYPE_REF:
1920 dump_generic_node (buffer, op0, 0, 0, false);
1921 break;
1923 default:
1924 NIY;
1928 /* Parses the string STR and replaces new-lines by '\n', tabs by '\t', ... */
1930 static void
1931 pretty_print_string (pretty_printer *buffer, const char *str)
1933 if (str == NULL)
1934 return;
1936 while (*str)
1938 switch (str[0])
1940 case '\b':
1941 pp_string (buffer, "\\b");
1942 break;
1944 case '\f':
1945 pp_string (buffer, "\\f");
1946 break;
1948 case '\n':
1949 pp_string (buffer, "\\n");
1950 break;
1952 case '\r':
1953 pp_string (buffer, "\\r");
1954 break;
1956 case '\t':
1957 pp_string (buffer, "\\t");
1958 break;
1960 case '\v':
1961 pp_string (buffer, "\\v");
1962 break;
1964 case '\\':
1965 pp_string (buffer, "\\\\");
1966 break;
1968 case '\"':
1969 pp_string (buffer, "\\\"");
1970 break;
1972 case '\'':
1973 pp_string (buffer, "\\'");
1974 break;
1976 case '\0':
1977 pp_string (buffer, "\\0");
1978 break;
1980 case '\1':
1981 pp_string (buffer, "\\1");
1982 break;
1984 case '\2':
1985 pp_string (buffer, "\\2");
1986 break;
1988 case '\3':
1989 pp_string (buffer, "\\3");
1990 break;
1992 case '\4':
1993 pp_string (buffer, "\\4");
1994 break;
1996 case '\5':
1997 pp_string (buffer, "\\5");
1998 break;
2000 case '\6':
2001 pp_string (buffer, "\\6");
2002 break;
2004 case '\7':
2005 pp_string (buffer, "\\7");
2006 break;
2008 default:
2009 pp_character (buffer, str[0]);
2010 break;
2012 str++;
2016 static void
2017 maybe_init_pretty_print (FILE *file)
2019 if (!initialized)
2021 pp_construct (&buffer, /* prefix */NULL, /* line-width */0);
2022 pp_needs_newline (&buffer) = true;
2023 initialized = 1;
2026 buffer.buffer->stream = file;
2029 static void
2030 newline_and_indent (pretty_printer *buffer, int spc)
2032 pp_newline (buffer);
2033 INDENT (spc);
2036 static void
2037 dump_vops (pretty_printer *buffer, tree stmt, int spc, int flags)
2039 size_t i;
2040 stmt_ann_t ann = stmt_ann (stmt);
2041 v_may_def_optype v_may_defs = V_MAY_DEF_OPS (ann);
2042 v_must_def_optype v_must_defs = V_MUST_DEF_OPS (ann);
2043 vuse_optype vuses = VUSE_OPS (ann);
2045 for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++)
2047 pp_string (buffer, "# ");
2048 dump_generic_node (buffer, V_MAY_DEF_RESULT (v_may_defs, i),
2049 spc + 2, flags, false);
2050 pp_string (buffer, " = V_MAY_DEF <");
2051 dump_generic_node (buffer, V_MAY_DEF_OP (v_may_defs, i),
2052 spc + 2, flags, false);
2053 pp_string (buffer, ">;");
2054 newline_and_indent (buffer, spc);
2057 for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++)
2059 tree v_must_def = V_MUST_DEF_OP (v_must_defs, i);
2060 pp_string (buffer, "# V_MUST_DEF <");
2061 dump_generic_node (buffer, v_must_def, spc + 2, flags, false);
2062 pp_string (buffer, ">;");
2063 newline_and_indent (buffer, spc);
2066 for (i = 0; i < NUM_VUSES (vuses); i++)
2068 tree vuse = VUSE_OP (vuses, i);
2069 pp_string (buffer, "# VUSE <");
2070 dump_generic_node (buffer, vuse, spc + 2, flags, false);
2071 pp_string (buffer, ">;");
2072 newline_and_indent (buffer, spc);
2076 /* Dumps basic block BB to FILE with details described by FLAGS and
2077 indented by INDENT spaces. */
2079 void
2080 dump_generic_bb (FILE *file, basic_block bb, int indent, int flags)
2082 maybe_init_pretty_print (file);
2083 dumping_stmts = true;
2084 dump_generic_bb_buff (&buffer, bb, indent, flags);
2085 pp_flush (&buffer);
2088 /* Dumps header of basic block BB to buffer BUFFER indented by INDENT
2089 spaces and details described by flags. */
2091 static void
2092 dump_bb_header (pretty_printer *buffer, basic_block bb, int indent, int flags)
2094 edge e;
2095 tree stmt;
2097 if (flags & TDF_BLOCKS)
2099 INDENT (indent);
2100 pp_string (buffer, "# BLOCK ");
2101 pp_decimal_int (buffer, bb->index);
2103 if (flags & TDF_LINENO)
2105 block_stmt_iterator bsi;
2107 for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
2108 if (get_lineno (bsi_stmt (bsi)) != -1)
2110 pp_string (buffer, ", starting at line ");
2111 pp_decimal_int (buffer, get_lineno (bsi_stmt (bsi)));
2112 break;
2115 newline_and_indent (buffer, indent);
2117 pp_string (buffer, "# PRED:");
2118 pp_write_text_to_stream (buffer);
2119 for (e = bb->pred; e; e = e->pred_next)
2120 if (flags & TDF_SLIM)
2122 pp_string (buffer, " ");
2123 if (e->src == ENTRY_BLOCK_PTR)
2124 pp_string (buffer, "ENTRY");
2125 else
2126 pp_decimal_int (buffer, e->src->index);
2128 else
2129 dump_edge_info (buffer->buffer->stream, e, 0);
2130 pp_newline (buffer);
2132 else
2134 stmt = first_stmt (bb);
2135 if (!stmt || TREE_CODE (stmt) != LABEL_EXPR)
2137 INDENT (indent - 2);
2138 pp_string (buffer, "<bb ");
2139 pp_decimal_int (buffer, bb->index);
2140 pp_string (buffer, ">:");
2141 pp_newline (buffer);
2146 /* Dumps end of basic block BB to buffer BUFFER indented by INDENT
2147 spaces. */
2149 static void
2150 dump_bb_end (pretty_printer *buffer, basic_block bb, int indent, int flags)
2152 edge e;
2154 INDENT (indent);
2155 pp_string (buffer, "# SUCC:");
2156 pp_write_text_to_stream (buffer);
2157 for (e = bb->succ; e; e = e->succ_next)
2158 if (flags & TDF_SLIM)
2160 pp_string (buffer, " ");
2161 if (e->dest == EXIT_BLOCK_PTR)
2162 pp_string (buffer, "EXIT");
2163 else
2164 pp_decimal_int (buffer, e->dest->index);
2166 else
2167 dump_edge_info (buffer->buffer->stream, e, 1);
2168 pp_newline (buffer);
2171 /* Dumps phi nodes of basic block BB to buffer BUFFER with details described by
2172 FLAGS indented by INDENT spaces. */
2174 static void
2175 dump_phi_nodes (pretty_printer *buffer, basic_block bb, int indent, int flags)
2177 tree phi = phi_nodes (bb);
2178 if (!phi)
2179 return;
2181 for (; phi; phi = PHI_CHAIN (phi))
2183 if (is_gimple_reg (PHI_RESULT (phi)) || (flags & TDF_VOPS))
2185 INDENT (indent);
2186 pp_string (buffer, "# ");
2187 dump_generic_node (buffer, phi, indent, flags, false);
2188 pp_newline (buffer);
2193 /* Dump jump to basic block BB that is represented implicitly in the cfg
2194 to BUFFER. */
2196 static void
2197 pp_cfg_jump (pretty_printer *buffer, basic_block bb)
2199 tree stmt;
2201 stmt = first_stmt (bb);
2203 pp_string (buffer, "goto <bb ");
2204 pp_decimal_int (buffer, bb->index);
2205 pp_string (buffer, ">");
2206 if (stmt && TREE_CODE (stmt) == LABEL_EXPR)
2208 pp_string (buffer, " (");
2209 dump_generic_node (buffer, LABEL_EXPR_LABEL (stmt), 0, 0, false);
2210 pp_string (buffer, ")");
2212 pp_semicolon (buffer);
2215 /* Dump edges represented implicitly in basic block BB to BUFFER, indented
2216 by INDENT spaces, with details given by FLAGS. */
2218 static void
2219 dump_implicit_edges (pretty_printer *buffer, basic_block bb, int indent,
2220 int flags)
2222 edge e;
2224 /* If there is a fallthru edge, we may need to add an artificial goto to the
2225 dump. */
2226 for (e = bb->succ; e; e = e->succ_next)
2227 if (e->flags & EDGE_FALLTHRU)
2228 break;
2229 if (e && e->dest != bb->next_bb)
2231 INDENT (indent);
2233 if ((flags & TDF_LINENO)
2234 #ifdef USE_MAPPED_LOCATION
2235 && e->goto_locus != UNKNOWN_LOCATION
2236 #else
2237 && e->goto_locus
2238 #endif
2241 expanded_location goto_xloc;
2242 #ifdef USE_MAPPED_LOCATION
2243 goto_xloc = expand_location (e->goto_locus);
2244 #else
2245 goto_xloc = *e->goto_locus;
2246 #endif
2247 pp_character (buffer, '[');
2248 if (goto_xloc.file)
2250 pp_string (buffer, goto_xloc.file);
2251 pp_string (buffer, " : ");
2253 pp_decimal_int (buffer, goto_xloc.line);
2254 pp_string (buffer, "] ");
2257 pp_cfg_jump (buffer, e->dest);
2258 pp_newline (buffer);
2262 /* Dumps basic block BB to buffer BUFFER with details described by FLAGS and
2263 indented by INDENT spaces. */
2265 static void
2266 dump_generic_bb_buff (pretty_printer *buffer, basic_block bb,
2267 int indent, int flags)
2269 block_stmt_iterator bsi;
2270 tree stmt;
2271 int label_indent = indent - 2;
2273 if (label_indent < 0)
2274 label_indent = 0;
2276 dump_bb_header (buffer, bb, indent, flags);
2278 if (bb_ann (bb))
2279 dump_phi_nodes (buffer, bb, indent, flags);
2281 for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
2283 int curr_indent;
2285 stmt = bsi_stmt (bsi);
2287 curr_indent = TREE_CODE (stmt) == LABEL_EXPR ? label_indent : indent;
2289 INDENT (curr_indent);
2290 dump_generic_node (buffer, stmt, curr_indent, flags, true);
2291 pp_newline (buffer);
2294 dump_implicit_edges (buffer, bb, indent, flags);
2296 if (flags & TDF_BLOCKS)
2297 dump_bb_end (buffer, bb, indent, flags);