* ggc-zone.c (struct alloc_zone): Add statistics counters.
[official-gcc.git] / gcc / tree-pretty-print.c
bloba211a8235caaabb0a52897e87c16c598a65327aa
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_2 (-TREE_INT_CST_LOW (val),
477 ~TREE_INT_CST_HIGH (val)
478 + !TREE_INT_CST_LOW (val));
480 /* Would "%x%0*x" or "%x%*0x" get zero-padding on all
481 systems? */
483 static char format[10]; /* "%x%09999x\0" */
484 if (!format[0])
485 sprintf (format, "%%x%%0%dx", HOST_BITS_PER_INT / 4);
486 sprintf (pp_buffer (buffer)->digit_buffer, format,
487 TREE_INT_CST_HIGH (val),
488 TREE_INT_CST_LOW (val));
489 pp_string (buffer, pp_buffer (buffer)->digit_buffer);
492 else
493 pp_wide_integer (buffer, TREE_INT_CST_LOW (node));
494 break;
496 case REAL_CST:
497 /* Code copied from print_node. */
499 REAL_VALUE_TYPE d;
500 if (TREE_OVERFLOW (node))
501 pp_string (buffer, " overflow");
503 #if !defined(REAL_IS_NOT_DOUBLE) || defined(REAL_ARITHMETIC)
504 d = TREE_REAL_CST (node);
505 if (REAL_VALUE_ISINF (d))
506 pp_string (buffer, " Inf");
507 else if (REAL_VALUE_ISNAN (d))
508 pp_string (buffer, " Nan");
509 else
511 char string[100];
512 real_to_decimal (string, &d, sizeof (string), 0, 1);
513 pp_string (buffer, string);
515 #else
517 HOST_WIDE_INT i;
518 unsigned char *p = (unsigned char *) &TREE_REAL_CST (node);
519 pp_string (buffer, "0x");
520 for (i = 0; i < sizeof TREE_REAL_CST (node); i++)
521 output_formatted_integer (buffer, "%02x", *p++);
523 #endif
524 break;
527 case COMPLEX_CST:
528 pp_string (buffer, "__complex__ (");
529 dump_generic_node (buffer, TREE_REALPART (node), spc, flags, false);
530 pp_string (buffer, ", ");
531 dump_generic_node (buffer, TREE_IMAGPART (node), spc, flags, false);
532 pp_string (buffer, ")");
533 break;
535 case STRING_CST:
536 pp_string (buffer, "\"");
537 pretty_print_string (buffer, TREE_STRING_POINTER (node));
538 pp_string (buffer, "\"");
539 break;
541 case VECTOR_CST:
543 tree elt;
544 pp_string (buffer, "{ ");
545 for (elt = TREE_VECTOR_CST_ELTS (node); elt; elt = TREE_CHAIN (elt))
547 dump_generic_node (buffer, TREE_VALUE (elt), spc, flags, false);
548 if (TREE_CHAIN (elt))
549 pp_string (buffer, ", ");
551 pp_string (buffer, " }");
553 break;
555 case FUNCTION_TYPE:
556 break;
558 case FUNCTION_DECL:
559 case CONST_DECL:
560 dump_decl_name (buffer, node, flags);
561 break;
563 case LABEL_DECL:
564 if (DECL_NAME (node))
565 dump_decl_name (buffer, node, flags);
566 else if (LABEL_DECL_UID (node) != -1)
567 pp_printf (buffer, "<L" HOST_WIDE_INT_PRINT_DEC ">",
568 LABEL_DECL_UID (node));
569 else
570 pp_printf (buffer, "<D%u>", DECL_UID (node));
571 break;
573 case TYPE_DECL:
574 if (DECL_IS_BUILTIN (node))
576 /* Don't print the declaration of built-in types. */
577 break;
579 if (DECL_NAME (node))
580 dump_decl_name (buffer, node, flags);
581 else
583 if ((TREE_CODE (TREE_TYPE (node)) == RECORD_TYPE
584 || TREE_CODE (TREE_TYPE (node)) == UNION_TYPE)
585 && TYPE_METHODS (TREE_TYPE (node)))
587 /* The type is a c++ class: all structures have at least
588 4 methods. */
589 pp_string (buffer, "class ");
590 dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
592 else
594 pp_string (buffer,
595 (TREE_CODE (TREE_TYPE (node)) == UNION_TYPE
596 ? "union" : "struct "));
597 dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
600 break;
602 case VAR_DECL:
603 case PARM_DECL:
604 case FIELD_DECL:
605 case NAMESPACE_DECL:
606 dump_decl_name (buffer, node, flags);
607 break;
609 case RESULT_DECL:
610 pp_string (buffer, "<retval>");
611 break;
613 case COMPONENT_REF:
614 op0 = TREE_OPERAND (node, 0);
615 str = ".";
616 if (TREE_CODE (op0) == INDIRECT_REF)
618 op0 = TREE_OPERAND (op0, 0);
619 str = "->";
621 if (op_prio (op0) < op_prio (node))
622 pp_character (buffer, '(');
623 dump_generic_node (buffer, op0, spc, flags, false);
624 if (op_prio (op0) < op_prio (node))
625 pp_character (buffer, ')');
626 pp_string (buffer, str);
627 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
629 op0 = component_ref_field_offset (node);
630 if (op0 && TREE_CODE (op0) != INTEGER_CST)
632 pp_string (buffer, "{off: ");
633 dump_generic_node (buffer, op0, spc, flags, false);
634 pp_character (buffer, '}');
636 break;
638 case BIT_FIELD_REF:
639 pp_string (buffer, "BIT_FIELD_REF <");
640 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
641 pp_string (buffer, ", ");
642 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
643 pp_string (buffer, ", ");
644 dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
645 pp_string (buffer, ">");
646 break;
648 case ARRAY_REF:
649 case ARRAY_RANGE_REF:
650 op0 = TREE_OPERAND (node, 0);
651 if (op_prio (op0) < op_prio (node))
652 pp_character (buffer, '(');
653 dump_generic_node (buffer, op0, spc, flags, false);
654 if (op_prio (op0) < op_prio (node))
655 pp_character (buffer, ')');
656 pp_character (buffer, '[');
657 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
658 if (TREE_CODE (node) == ARRAY_RANGE_REF)
659 pp_string (buffer, " ...");
660 pp_character (buffer, ']');
662 op0 = array_ref_low_bound (node);
663 op1 = array_ref_element_size (node);
665 if (!integer_zerop (op0)
666 || (TYPE_SIZE_UNIT (TREE_TYPE (node))
667 && !operand_equal_p (op1, TYPE_SIZE_UNIT (TREE_TYPE (node)), 0)))
669 pp_string (buffer, "{lb: ");
670 dump_generic_node (buffer, op0, spc, flags, false);
671 pp_string (buffer, " sz: ");
672 dump_generic_node (buffer, op1, spc, flags, false);
673 pp_character (buffer, '}');
675 break;
677 case CONSTRUCTOR:
679 tree lnode;
680 bool is_struct_init = FALSE;
681 pp_character (buffer, '{');
682 lnode = CONSTRUCTOR_ELTS (node);
683 if (TREE_CODE (TREE_TYPE (node)) == RECORD_TYPE
684 || TREE_CODE (TREE_TYPE (node)) == UNION_TYPE)
685 is_struct_init = TRUE;
686 while (lnode && lnode != error_mark_node)
688 tree val;
689 if (TREE_PURPOSE (lnode) && is_struct_init)
691 pp_character (buffer, '.');
692 dump_generic_node (buffer, TREE_PURPOSE (lnode), spc, flags, false);
693 pp_string (buffer, "=");
695 val = TREE_VALUE (lnode);
696 if (val && TREE_CODE (val) == ADDR_EXPR)
697 if (TREE_CODE (TREE_OPERAND (val, 0)) == FUNCTION_DECL)
698 val = TREE_OPERAND (val, 0);
699 if (val && TREE_CODE (val) == FUNCTION_DECL)
701 dump_decl_name (buffer, val, flags);
703 else
705 dump_generic_node (buffer, TREE_VALUE (lnode), spc, flags, false);
707 lnode = TREE_CHAIN (lnode);
708 if (lnode && TREE_CODE (lnode) == TREE_LIST)
710 pp_character (buffer, ',');
711 pp_space (buffer);
714 pp_character (buffer, '}');
716 break;
718 case COMPOUND_EXPR:
720 tree *tp;
721 if (flags & TDF_SLIM)
723 pp_string (buffer, "<COMPOUND_EXPR>");
724 break;
727 dump_generic_node (buffer, TREE_OPERAND (node, 0),
728 spc, flags, dumping_stmts);
729 if (dumping_stmts)
730 newline_and_indent (buffer, spc);
731 else
733 pp_character (buffer, ',');
734 pp_space (buffer);
737 for (tp = &TREE_OPERAND (node, 1);
738 TREE_CODE (*tp) == COMPOUND_EXPR;
739 tp = &TREE_OPERAND (*tp, 1))
741 dump_generic_node (buffer, TREE_OPERAND (*tp, 0),
742 spc, flags, dumping_stmts);
743 if (dumping_stmts)
744 newline_and_indent (buffer, spc);
745 else
747 pp_character (buffer, ',');
748 pp_space (buffer);
752 dump_generic_node (buffer, *tp, spc, flags, dumping_stmts);
754 break;
756 case STATEMENT_LIST:
758 tree_stmt_iterator si;
759 bool first = true;
761 if ((flags & TDF_SLIM) || !dumping_stmts)
763 pp_string (buffer, "<STATEMENT_LIST>");
764 break;
767 for (si = tsi_start (node); !tsi_end_p (si); tsi_next (&si))
769 if (!first)
770 newline_and_indent (buffer, spc);
771 else
772 first = false;
773 dump_generic_node (buffer, tsi_stmt (si), spc, flags, true);
776 break;
778 case MODIFY_EXPR:
779 case INIT_EXPR:
780 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
781 pp_space (buffer);
782 pp_character (buffer, '=');
783 pp_space (buffer);
784 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
785 break;
787 case TARGET_EXPR:
788 pp_string (buffer, "TARGET_EXPR <");
789 dump_generic_node (buffer, TARGET_EXPR_SLOT (node), spc, flags, false);
790 pp_character (buffer, ',');
791 pp_space (buffer);
792 dump_generic_node (buffer, TARGET_EXPR_INITIAL (node), spc, flags, false);
793 pp_character (buffer, '>');
794 break;
796 case DECL_EXPR:
797 print_declaration (buffer, DECL_EXPR_DECL (node), spc, flags);
798 is_stmt = false;
799 break;
801 case COND_EXPR:
802 if (TREE_TYPE (node) == NULL || TREE_TYPE (node) == void_type_node)
804 pp_string (buffer, "if (");
805 dump_generic_node (buffer, COND_EXPR_COND (node), spc, flags, false);
806 pp_character (buffer, ')');
807 /* The lowered cond_exprs should always be printed in full. */
808 if (COND_EXPR_THEN (node)
809 && TREE_CODE (COND_EXPR_THEN (node)) == GOTO_EXPR
810 && COND_EXPR_ELSE (node)
811 && TREE_CODE (COND_EXPR_ELSE (node)) == GOTO_EXPR)
813 pp_space (buffer);
814 dump_generic_node (buffer, COND_EXPR_THEN (node), 0, flags, true);
815 pp_string (buffer, " else ");
816 dump_generic_node (buffer, COND_EXPR_ELSE (node), 0, flags, true);
818 else if (!(flags & TDF_SLIM))
820 /* Output COND_EXPR_THEN. */
821 if (COND_EXPR_THEN (node))
823 newline_and_indent (buffer, spc+2);
824 pp_character (buffer, '{');
825 newline_and_indent (buffer, spc+4);
826 dump_generic_node (buffer, COND_EXPR_THEN (node), spc+4,
827 flags, true);
828 newline_and_indent (buffer, spc+2);
829 pp_character (buffer, '}');
832 /* Output COND_EXPR_ELSE. */
833 if (COND_EXPR_ELSE (node))
835 newline_and_indent (buffer, spc);
836 pp_string (buffer, "else");
837 newline_and_indent (buffer, spc+2);
838 pp_character (buffer, '{');
839 newline_and_indent (buffer, spc+4);
840 dump_generic_node (buffer, COND_EXPR_ELSE (node), spc+4,
841 flags, true);
842 newline_and_indent (buffer, spc+2);
843 pp_character (buffer, '}');
846 is_expr = false;
848 else
850 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
851 pp_space (buffer);
852 pp_character (buffer, '?');
853 pp_space (buffer);
854 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
855 pp_space (buffer);
856 pp_character (buffer, ':');
857 pp_space (buffer);
858 dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
860 break;
862 case BIND_EXPR:
863 pp_character (buffer, '{');
864 if (!(flags & TDF_SLIM))
866 if (BIND_EXPR_VARS (node))
868 pp_newline (buffer);
870 for (op0 = BIND_EXPR_VARS (node); op0; op0 = TREE_CHAIN (op0))
872 print_declaration (buffer, op0, spc+2, flags);
873 pp_newline (buffer);
877 newline_and_indent (buffer, spc+2);
878 dump_generic_node (buffer, BIND_EXPR_BODY (node), spc+2, flags, true);
879 newline_and_indent (buffer, spc);
880 pp_character (buffer, '}');
882 is_expr = false;
883 break;
885 case CALL_EXPR:
886 print_call_name (buffer, node);
888 /* Print parameters. */
889 pp_space (buffer);
890 pp_character (buffer, '(');
891 op1 = TREE_OPERAND (node, 1);
892 if (op1)
893 dump_generic_node (buffer, op1, spc, flags, false);
894 pp_character (buffer, ')');
896 op1 = TREE_OPERAND (node, 2);
897 if (op1)
899 pp_string (buffer, " [static-chain: ");
900 dump_generic_node (buffer, op1, spc, flags, false);
901 pp_character (buffer, ']');
904 if (CALL_EXPR_HAS_RETURN_SLOT_ADDR (node))
905 pp_string (buffer, " [return slot addr]");
906 if (CALL_EXPR_TAILCALL (node))
907 pp_string (buffer, " [tail call]");
908 break;
910 case WITH_CLEANUP_EXPR:
911 NIY;
912 break;
914 case CLEANUP_POINT_EXPR:
915 pp_string (buffer, "<<cleanup_point ");
916 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
917 pp_string (buffer, ">>");
918 break;
920 case PLACEHOLDER_EXPR:
921 pp_string (buffer, "<PLACEHOLDER_EXPR ");
922 dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
923 pp_character (buffer, '>');
924 break;
926 /* Binary arithmetic and logic expressions. */
927 case MULT_EXPR:
928 case PLUS_EXPR:
929 case MINUS_EXPR:
930 case TRUNC_DIV_EXPR:
931 case CEIL_DIV_EXPR:
932 case FLOOR_DIV_EXPR:
933 case ROUND_DIV_EXPR:
934 case TRUNC_MOD_EXPR:
935 case CEIL_MOD_EXPR:
936 case FLOOR_MOD_EXPR:
937 case ROUND_MOD_EXPR:
938 case RDIV_EXPR:
939 case EXACT_DIV_EXPR:
940 case LSHIFT_EXPR:
941 case RSHIFT_EXPR:
942 case LROTATE_EXPR:
943 case RROTATE_EXPR:
944 case BIT_IOR_EXPR:
945 case BIT_XOR_EXPR:
946 case BIT_AND_EXPR:
947 case TRUTH_ANDIF_EXPR:
948 case TRUTH_ORIF_EXPR:
949 case TRUTH_AND_EXPR:
950 case TRUTH_OR_EXPR:
951 case TRUTH_XOR_EXPR:
952 case LT_EXPR:
953 case LE_EXPR:
954 case GT_EXPR:
955 case GE_EXPR:
956 case EQ_EXPR:
957 case NE_EXPR:
958 case UNLT_EXPR:
959 case UNLE_EXPR:
960 case UNGT_EXPR:
961 case UNGE_EXPR:
962 case UNEQ_EXPR:
963 case LTGT_EXPR:
964 case ORDERED_EXPR:
965 case UNORDERED_EXPR:
967 const char *op = op_symbol (node);
968 op0 = TREE_OPERAND (node, 0);
969 op1 = TREE_OPERAND (node, 1);
971 /* When the operands are expressions with less priority,
972 keep semantics of the tree representation. */
973 if (op_prio (op0) < op_prio (node))
975 pp_character (buffer, '(');
976 dump_generic_node (buffer, op0, spc, flags, false);
977 pp_character (buffer, ')');
979 else
980 dump_generic_node (buffer, op0, spc, flags, false);
982 pp_space (buffer);
983 pp_string (buffer, op);
984 pp_space (buffer);
986 /* When the operands are expressions with less priority,
987 keep semantics of the tree representation. */
988 if (op_prio (op1) < op_prio (node))
990 pp_character (buffer, '(');
991 dump_generic_node (buffer, op1, spc, flags, false);
992 pp_character (buffer, ')');
994 else
995 dump_generic_node (buffer, op1, spc, flags, false);
997 break;
999 /* Unary arithmetic and logic expressions. */
1000 case NEGATE_EXPR:
1001 case BIT_NOT_EXPR:
1002 case TRUTH_NOT_EXPR:
1003 case ADDR_EXPR:
1004 case PREDECREMENT_EXPR:
1005 case PREINCREMENT_EXPR:
1006 case INDIRECT_REF:
1007 if (TREE_CODE (node) == ADDR_EXPR
1008 && (TREE_CODE (TREE_OPERAND (node, 0)) == STRING_CST
1009 || TREE_CODE (TREE_OPERAND (node, 0)) == FUNCTION_DECL))
1010 ; /* Do not output '&' for strings and function pointers. */
1011 else
1012 pp_string (buffer, op_symbol (node));
1014 if (op_prio (TREE_OPERAND (node, 0)) < op_prio (node))
1016 pp_character (buffer, '(');
1017 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1018 pp_character (buffer, ')');
1020 else
1021 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1022 break;
1024 case POSTDECREMENT_EXPR:
1025 case POSTINCREMENT_EXPR:
1026 if (op_prio (TREE_OPERAND (node, 0)) < op_prio (node))
1028 pp_character (buffer, '(');
1029 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1030 pp_character (buffer, ')');
1032 else
1033 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1034 pp_string (buffer, op_symbol (node));
1035 break;
1037 case MIN_EXPR:
1038 pp_string (buffer, "MIN_EXPR <");
1039 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1040 pp_string (buffer, ", ");
1041 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1042 pp_character (buffer, '>');
1043 break;
1045 case MAX_EXPR:
1046 pp_string (buffer, "MAX_EXPR <");
1047 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1048 pp_string (buffer, ", ");
1049 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1050 pp_character (buffer, '>');
1051 break;
1053 case ABS_EXPR:
1054 pp_string (buffer, "ABS_EXPR <");
1055 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1056 pp_character (buffer, '>');
1057 break;
1059 case RANGE_EXPR:
1060 NIY;
1061 break;
1063 case FIX_TRUNC_EXPR:
1064 case FIX_CEIL_EXPR:
1065 case FIX_FLOOR_EXPR:
1066 case FIX_ROUND_EXPR:
1067 case FLOAT_EXPR:
1068 case CONVERT_EXPR:
1069 case NOP_EXPR:
1070 type = TREE_TYPE (node);
1071 op0 = TREE_OPERAND (node, 0);
1072 if (type != TREE_TYPE (op0))
1074 pp_character (buffer, '(');
1075 dump_generic_node (buffer, type, spc, flags, false);
1076 pp_string (buffer, ")");
1078 if (op_prio (op0) < op_prio (node))
1079 pp_character (buffer, '(');
1080 dump_generic_node (buffer, op0, spc, flags, false);
1081 if (op_prio (op0) < op_prio (node))
1082 pp_character (buffer, ')');
1083 break;
1085 case VIEW_CONVERT_EXPR:
1086 pp_string (buffer, "VIEW_CONVERT_EXPR<");
1087 dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
1088 pp_string (buffer, ">(");
1089 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1090 pp_character (buffer, ')');
1091 break;
1093 case NON_LVALUE_EXPR:
1094 pp_string (buffer, "NON_LVALUE_EXPR <");
1095 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1096 pp_character (buffer, '>');
1097 break;
1099 case SAVE_EXPR:
1100 pp_string (buffer, "SAVE_EXPR <");
1101 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1102 pp_character (buffer, '>');
1103 break;
1105 case COMPLEX_EXPR:
1106 pp_string (buffer, "COMPLEX_EXPR <");
1107 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1108 pp_string (buffer, ", ");
1109 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1110 pp_string (buffer, ">");
1111 break;
1113 case CONJ_EXPR:
1114 pp_string (buffer, "CONJ_EXPR <");
1115 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1116 pp_string (buffer, ">");
1117 break;
1119 case REALPART_EXPR:
1120 pp_string (buffer, "REALPART_EXPR <");
1121 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1122 pp_string (buffer, ">");
1123 break;
1125 case IMAGPART_EXPR:
1126 pp_string (buffer, "IMAGPART_EXPR <");
1127 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1128 pp_string (buffer, ">");
1129 break;
1131 case VA_ARG_EXPR:
1132 pp_string (buffer, "VA_ARG_EXPR <");
1133 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1134 pp_string (buffer, ">");
1135 break;
1137 case TRY_FINALLY_EXPR:
1138 case TRY_CATCH_EXPR:
1139 pp_string (buffer, "try");
1140 newline_and_indent (buffer, spc+2);
1141 pp_string (buffer, "{");
1142 newline_and_indent (buffer, spc+4);
1143 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc+4, flags, true);
1144 newline_and_indent (buffer, spc+2);
1145 pp_string (buffer, "}");
1146 newline_and_indent (buffer, spc);
1147 pp_string (buffer,
1148 (TREE_CODE (node) == TRY_CATCH_EXPR) ? "catch" : "finally");
1149 newline_and_indent (buffer, spc+2);
1150 pp_string (buffer, "{");
1151 newline_and_indent (buffer, spc+4);
1152 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc+4, flags, true);
1153 newline_and_indent (buffer, spc+2);
1154 pp_string (buffer, "}");
1155 is_expr = false;
1156 break;
1158 case CATCH_EXPR:
1159 pp_string (buffer, "catch (");
1160 dump_generic_node (buffer, CATCH_TYPES (node), spc+2, flags, false);
1161 pp_string (buffer, ")");
1162 newline_and_indent (buffer, spc+2);
1163 pp_string (buffer, "{");
1164 newline_and_indent (buffer, spc+4);
1165 dump_generic_node (buffer, CATCH_BODY (node), spc+4, flags, true);
1166 newline_and_indent (buffer, spc+2);
1167 pp_string (buffer, "}");
1168 is_expr = false;
1169 break;
1171 case EH_FILTER_EXPR:
1172 pp_string (buffer, "<<<eh_filter (");
1173 dump_generic_node (buffer, EH_FILTER_TYPES (node), spc+2, flags, false);
1174 pp_string (buffer, ")>>>");
1175 newline_and_indent (buffer, spc+2);
1176 pp_string (buffer, "{");
1177 newline_and_indent (buffer, spc+4);
1178 dump_generic_node (buffer, EH_FILTER_FAILURE (node), spc+4, flags, true);
1179 newline_and_indent (buffer, spc+2);
1180 pp_string (buffer, "}");
1181 is_expr = false;
1182 break;
1184 case LABEL_EXPR:
1185 op0 = TREE_OPERAND (node, 0);
1186 /* If this is for break or continue, don't bother printing it. */
1187 if (DECL_NAME (op0))
1189 const char *name = IDENTIFIER_POINTER (DECL_NAME (op0));
1190 if (strcmp (name, "break") == 0
1191 || strcmp (name, "continue") == 0)
1192 break;
1194 dump_generic_node (buffer, op0, spc, flags, false);
1195 pp_character (buffer, ':');
1196 if (DECL_NONLOCAL (op0))
1197 pp_string (buffer, " [non-local]");
1198 break;
1200 case LABELED_BLOCK_EXPR:
1201 op0 = LABELED_BLOCK_LABEL (node);
1202 /* If this is for break or continue, don't bother printing it. */
1203 if (DECL_NAME (op0))
1205 const char *name = IDENTIFIER_POINTER (DECL_NAME (op0));
1206 if (strcmp (name, "break") == 0
1207 || strcmp (name, "continue") == 0)
1209 dump_generic_node (buffer, LABELED_BLOCK_BODY (node), spc, flags, false);
1210 break;
1213 dump_generic_node (buffer, LABELED_BLOCK_LABEL (node), spc, flags, false);
1214 pp_string (buffer, ": {");
1215 if (!(flags & TDF_SLIM))
1216 newline_and_indent (buffer, spc+2);
1217 dump_generic_node (buffer, LABELED_BLOCK_BODY (node), spc+2, flags, true);
1218 if (!flags)
1219 newline_and_indent (buffer, spc);
1220 pp_character (buffer, '}');
1221 is_expr = false;
1222 break;
1224 case EXIT_BLOCK_EXPR:
1225 op0 = LABELED_BLOCK_LABEL (EXIT_BLOCK_LABELED_BLOCK (node));
1226 /* If this is for a break or continue, print it accordingly. */
1227 if (DECL_NAME (op0))
1229 const char *name = IDENTIFIER_POINTER (DECL_NAME (op0));
1230 if (strcmp (name, "break") == 0
1231 || strcmp (name, "continue") == 0)
1233 pp_string (buffer, name);
1234 break;
1237 pp_string (buffer, "<<<exit block ");
1238 dump_generic_node (buffer, op0, spc, flags, false);
1239 pp_string (buffer, ">>>");
1240 break;
1242 case EXC_PTR_EXPR:
1243 pp_string (buffer, "<<<exception object>>>");
1244 break;
1246 case FILTER_EXPR:
1247 pp_string (buffer, "<<<filter object>>>");
1248 break;
1250 case LOOP_EXPR:
1251 pp_string (buffer, "while (1)");
1252 if (!(flags & TDF_SLIM))
1254 newline_and_indent (buffer, spc+2);
1255 pp_character (buffer, '{');
1256 newline_and_indent (buffer, spc+4);
1257 dump_generic_node (buffer, LOOP_EXPR_BODY (node), spc+4, flags, true);
1258 newline_and_indent (buffer, spc+2);
1259 pp_character (buffer, '}');
1261 is_expr = false;
1262 break;
1264 case RETURN_EXPR:
1265 pp_string (buffer, "return");
1266 op0 = TREE_OPERAND (node, 0);
1267 if (op0)
1269 pp_space (buffer);
1270 if (TREE_CODE (op0) == MODIFY_EXPR)
1271 dump_generic_node (buffer, TREE_OPERAND (op0, 1), spc, flags, false);
1272 else
1273 dump_generic_node (buffer, op0, spc, flags, false);
1275 break;
1277 case EXIT_EXPR:
1278 pp_string (buffer, "if (");
1279 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1280 pp_string (buffer, ") break");
1281 break;
1283 case SWITCH_EXPR:
1284 pp_string (buffer, "switch (");
1285 dump_generic_node (buffer, SWITCH_COND (node), spc, flags, false);
1286 pp_character (buffer, ')');
1287 if (!(flags & TDF_SLIM))
1289 newline_and_indent (buffer, spc+2);
1290 pp_character (buffer, '{');
1291 if (SWITCH_BODY (node))
1293 newline_and_indent (buffer, spc+4);
1294 dump_generic_node (buffer, SWITCH_BODY (node), spc+4, flags, true);
1296 else
1298 tree vec = SWITCH_LABELS (node);
1299 size_t i, n = TREE_VEC_LENGTH (vec);
1300 for (i = 0; i < n; ++i)
1302 tree elt = TREE_VEC_ELT (vec, i);
1303 newline_and_indent (buffer, spc+4);
1304 dump_generic_node (buffer, elt, spc+4, flags, false);
1305 pp_string (buffer, " goto ");
1306 dump_generic_node (buffer, CASE_LABEL (elt), spc+4, flags, true);
1307 pp_semicolon (buffer);
1310 newline_and_indent (buffer, spc+2);
1311 pp_character (buffer, '}');
1313 is_expr = false;
1314 break;
1316 case GOTO_EXPR:
1317 op0 = GOTO_DESTINATION (node);
1318 if (TREE_CODE (op0) != SSA_NAME
1319 && DECL_P (op0)
1320 && DECL_NAME (op0))
1322 const char *name = IDENTIFIER_POINTER (DECL_NAME (op0));
1323 if (strcmp (name, "break") == 0
1324 || strcmp (name, "continue") == 0)
1326 pp_string (buffer, name);
1327 break;
1330 pp_string (buffer, "goto ");
1331 dump_generic_node (buffer, op0, spc, flags, false);
1332 break;
1334 case RESX_EXPR:
1335 pp_string (buffer, "resx");
1336 /* ??? Any sensible way to present the eh region? */
1337 break;
1339 case ASM_EXPR:
1340 pp_string (buffer, "__asm__");
1341 if (ASM_VOLATILE_P (node))
1342 pp_string (buffer, " __volatile__");
1343 pp_character (buffer, '(');
1344 dump_generic_node (buffer, ASM_STRING (node), spc, flags, false);
1345 pp_character (buffer, ':');
1346 dump_generic_node (buffer, ASM_OUTPUTS (node), spc, flags, false);
1347 pp_character (buffer, ':');
1348 dump_generic_node (buffer, ASM_INPUTS (node), spc, flags, false);
1349 if (ASM_CLOBBERS (node))
1351 pp_character (buffer, ':');
1352 dump_generic_node (buffer, ASM_CLOBBERS (node), spc, flags, false);
1354 pp_string (buffer, ")");
1355 break;
1357 case CASE_LABEL_EXPR:
1358 if (CASE_LOW (node) && CASE_HIGH (node))
1360 pp_string (buffer, "case ");
1361 dump_generic_node (buffer, CASE_LOW (node), spc, flags, false);
1362 pp_string (buffer, " ... ");
1363 dump_generic_node (buffer, CASE_HIGH (node), spc, flags, false);
1365 else if (CASE_LOW (node))
1367 pp_string (buffer, "case ");
1368 dump_generic_node (buffer, CASE_LOW (node), spc, flags, false);
1370 else
1371 pp_string (buffer, "default ");
1372 pp_character (buffer, ':');
1373 break;
1375 case OBJ_TYPE_REF:
1376 pp_string (buffer, "OBJ_TYPE_REF(");
1377 dump_generic_node (buffer, OBJ_TYPE_REF_EXPR (node), spc, flags, false);
1378 pp_character (buffer, ';');
1379 dump_generic_node (buffer, OBJ_TYPE_REF_OBJECT (node), spc, flags, false);
1380 pp_character (buffer, '-');
1381 pp_character (buffer, '>');
1382 dump_generic_node (buffer, OBJ_TYPE_REF_TOKEN (node), spc, flags, false);
1383 pp_character (buffer, ')');
1384 break;
1386 case PHI_NODE:
1388 int i;
1390 dump_generic_node (buffer, PHI_RESULT (node), spc, flags, false);
1391 pp_string (buffer, " = PHI <");
1392 for (i = 0; i < PHI_NUM_ARGS (node); i++)
1394 dump_generic_node (buffer, PHI_ARG_DEF (node, i), spc, flags, false);
1395 pp_string (buffer, "(");
1396 pp_decimal_int (buffer, PHI_ARG_EDGE (node, i)->src->index);
1397 pp_string (buffer, ")");
1398 if (i < PHI_NUM_ARGS (node) - 1)
1399 pp_string (buffer, ", ");
1401 pp_string (buffer, ">;");
1403 break;
1405 case SSA_NAME:
1406 dump_generic_node (buffer, SSA_NAME_VAR (node), spc, flags, false);
1407 pp_string (buffer, "_");
1408 pp_decimal_int (buffer, SSA_NAME_VERSION (node));
1409 break;
1411 case WITH_SIZE_EXPR:
1412 pp_string (buffer, "WITH_SIZE_EXPR <");
1413 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1414 pp_string (buffer, ", ");
1415 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1416 pp_string (buffer, ">");
1417 break;
1419 case VALUE_HANDLE:
1420 pp_printf (buffer, "VH.%d", VALUE_HANDLE_ID (node));
1421 break;
1423 case SCEV_KNOWN:
1424 pp_string (buffer, "scev_known");
1425 break;
1427 case SCEV_NOT_KNOWN:
1428 pp_string (buffer, "scev_not_known");
1429 break;
1431 case POLYNOMIAL_CHREC:
1432 pp_string (buffer, "{");
1433 dump_generic_node (buffer, CHREC_LEFT (node), spc, flags, false);
1434 pp_string (buffer, ", +, ");
1435 dump_generic_node (buffer, CHREC_RIGHT (node), spc, flags, false);
1436 pp_string (buffer, "}_");
1437 dump_generic_node (buffer, CHREC_VAR (node), spc, flags, false);
1438 is_stmt = false;
1439 break;
1441 default:
1442 NIY;
1445 if (is_stmt && is_expr)
1446 pp_semicolon (buffer);
1447 pp_write_text_to_stream (buffer);
1449 return spc;
1452 /* Print the declaration of a variable. */
1454 static void
1455 print_declaration (pretty_printer *buffer, tree t, int spc, int flags)
1457 INDENT (spc);
1459 if (TREE_CODE (t) == TYPE_DECL)
1460 pp_string (buffer, "typedef ");
1462 if (DECL_REGISTER (t))
1463 pp_string (buffer, "register ");
1465 if (TREE_PUBLIC (t) && DECL_EXTERNAL (t))
1466 pp_string (buffer, "extern ");
1467 else if (TREE_STATIC (t))
1468 pp_string (buffer, "static ");
1470 /* Print the type and name. */
1471 if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
1473 tree tmp;
1475 /* Print array's type. */
1476 tmp = TREE_TYPE (t);
1477 while (TREE_CODE (TREE_TYPE (tmp)) == ARRAY_TYPE)
1478 tmp = TREE_TYPE (tmp);
1479 dump_generic_node (buffer, TREE_TYPE (tmp), spc, flags, false);
1481 /* Print variable's name. */
1482 pp_space (buffer);
1483 dump_generic_node (buffer, t, spc, flags, false);
1485 /* Print the dimensions. */
1486 tmp = TREE_TYPE (t);
1487 while (TREE_CODE (tmp) == ARRAY_TYPE)
1489 pp_character (buffer, '[');
1490 if (TYPE_DOMAIN (tmp))
1492 if (TREE_CODE (TYPE_SIZE (tmp)) == INTEGER_CST)
1493 pp_wide_integer (buffer,
1494 TREE_INT_CST_LOW (TYPE_SIZE (tmp)) /
1495 TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (tmp))));
1496 else
1497 dump_generic_node (buffer, TYPE_SIZE_UNIT (tmp), spc, flags,
1498 false);
1500 pp_character (buffer, ']');
1501 tmp = TREE_TYPE (tmp);
1504 else if (TREE_CODE (t) == FUNCTION_DECL)
1506 dump_generic_node (buffer, TREE_TYPE (TREE_TYPE (t)), spc, flags, false);
1507 pp_space (buffer);
1508 dump_decl_name (buffer, t, flags);
1509 dump_function_declaration (buffer, TREE_TYPE (t), spc, flags);
1511 else
1513 /* Print type declaration. */
1514 dump_generic_node (buffer, TREE_TYPE (t), spc, flags, false);
1516 /* Print variable's name. */
1517 pp_space (buffer);
1518 dump_generic_node (buffer, t, spc, flags, false);
1521 /* The initial value of a function serves to determine wether the function
1522 is declared or defined. So the following does not apply to function
1523 nodes. */
1524 if (TREE_CODE (t) != FUNCTION_DECL)
1526 /* Print the initial value. */
1527 if (DECL_INITIAL (t))
1529 pp_space (buffer);
1530 pp_character (buffer, '=');
1531 pp_space (buffer);
1532 dump_generic_node (buffer, DECL_INITIAL (t), spc, flags, false);
1536 pp_character (buffer, ';');
1540 /* Prints a structure: name, fields, and methods.
1541 FIXME: Still incomplete. */
1543 static void
1544 print_struct_decl (pretty_printer *buffer, tree node, int spc, int flags)
1546 /* Print the name of the structure. */
1547 if (TYPE_NAME (node))
1549 INDENT (spc);
1550 if (TREE_CODE (node) == RECORD_TYPE)
1551 pp_string (buffer, "struct ");
1552 else if ((TREE_CODE (node) == UNION_TYPE
1553 || TREE_CODE (node) == QUAL_UNION_TYPE))
1554 pp_string (buffer, "union ");
1556 dump_generic_node (buffer, TYPE_NAME (node), spc, 0, false);
1559 /* Print the contents of the structure. */
1560 pp_newline (buffer);
1561 INDENT (spc);
1562 pp_character (buffer, '{');
1563 pp_newline (buffer);
1565 /* Print the fields of the structure. */
1567 tree tmp;
1568 tmp = TYPE_FIELDS (node);
1569 while (tmp)
1571 /* Avoid to print recursively the structure. */
1572 /* FIXME : Not implemented correctly...,
1573 what about the case when we have a cycle in the contain graph? ...
1574 Maybe this could be solved by looking at the scope in which the
1575 structure was declared. */
1576 if (TREE_TYPE (tmp) != node
1577 || (TREE_CODE (TREE_TYPE (tmp)) == POINTER_TYPE
1578 && TREE_TYPE (TREE_TYPE (tmp)) != node))
1580 print_declaration (buffer, tmp, spc+2, flags);
1581 pp_newline (buffer);
1583 tmp = TREE_CHAIN (tmp);
1586 INDENT (spc);
1587 pp_character (buffer, '}');
1590 /* Return the priority of the operator OP.
1592 From lowest to highest precedence with either left-to-right (L-R)
1593 or right-to-left (R-L) associativity]:
1595 1 [L-R] ,
1596 2 [R-L] = += -= *= /= %= &= ^= |= <<= >>=
1597 3 [R-L] ?:
1598 4 [L-R] ||
1599 5 [L-R] &&
1600 6 [L-R] |
1601 7 [L-R] ^
1602 8 [L-R] &
1603 9 [L-R] == !=
1604 10 [L-R] < <= > >=
1605 11 [L-R] << >>
1606 12 [L-R] + -
1607 13 [L-R] * / %
1608 14 [R-L] ! ~ ++ -- + - * & (type) sizeof
1609 15 [L-R] fn() [] -> .
1611 unary +, - and * have higher precedence than the corresponding binary
1612 operators. */
1614 static int
1615 op_prio (tree op)
1617 if (op == NULL)
1618 return 9999;
1620 switch (TREE_CODE (op))
1622 case TREE_LIST:
1623 case COMPOUND_EXPR:
1624 case BIND_EXPR:
1625 return 1;
1627 case MODIFY_EXPR:
1628 case INIT_EXPR:
1629 return 2;
1631 case COND_EXPR:
1632 return 3;
1634 case TRUTH_OR_EXPR:
1635 case TRUTH_ORIF_EXPR:
1636 return 4;
1638 case TRUTH_AND_EXPR:
1639 case TRUTH_ANDIF_EXPR:
1640 return 5;
1642 case BIT_IOR_EXPR:
1643 return 6;
1645 case BIT_XOR_EXPR:
1646 case TRUTH_XOR_EXPR:
1647 return 7;
1649 case BIT_AND_EXPR:
1650 return 8;
1652 case EQ_EXPR:
1653 case NE_EXPR:
1654 return 9;
1656 case UNLT_EXPR:
1657 case UNLE_EXPR:
1658 case UNGT_EXPR:
1659 case UNGE_EXPR:
1660 case UNEQ_EXPR:
1661 case LTGT_EXPR:
1662 case ORDERED_EXPR:
1663 case UNORDERED_EXPR:
1664 case LT_EXPR:
1665 case LE_EXPR:
1666 case GT_EXPR:
1667 case GE_EXPR:
1668 return 10;
1670 case LSHIFT_EXPR:
1671 case RSHIFT_EXPR:
1672 case LROTATE_EXPR:
1673 case RROTATE_EXPR:
1674 return 11;
1676 case PLUS_EXPR:
1677 case MINUS_EXPR:
1678 return 12;
1680 case MULT_EXPR:
1681 case TRUNC_DIV_EXPR:
1682 case CEIL_DIV_EXPR:
1683 case FLOOR_DIV_EXPR:
1684 case ROUND_DIV_EXPR:
1685 case RDIV_EXPR:
1686 case EXACT_DIV_EXPR:
1687 case TRUNC_MOD_EXPR:
1688 case CEIL_MOD_EXPR:
1689 case FLOOR_MOD_EXPR:
1690 case ROUND_MOD_EXPR:
1691 return 13;
1693 case TRUTH_NOT_EXPR:
1694 case BIT_NOT_EXPR:
1695 case POSTINCREMENT_EXPR:
1696 case POSTDECREMENT_EXPR:
1697 case PREINCREMENT_EXPR:
1698 case PREDECREMENT_EXPR:
1699 case NEGATE_EXPR:
1700 case INDIRECT_REF:
1701 case ADDR_EXPR:
1702 case FLOAT_EXPR:
1703 case NOP_EXPR:
1704 case CONVERT_EXPR:
1705 case FIX_TRUNC_EXPR:
1706 case FIX_CEIL_EXPR:
1707 case FIX_FLOOR_EXPR:
1708 case FIX_ROUND_EXPR:
1709 case TARGET_EXPR:
1710 return 14;
1712 case CALL_EXPR:
1713 case ARRAY_REF:
1714 case ARRAY_RANGE_REF:
1715 case COMPONENT_REF:
1716 return 15;
1718 /* Special expressions. */
1719 case MIN_EXPR:
1720 case MAX_EXPR:
1721 case ABS_EXPR:
1722 case REALPART_EXPR:
1723 case IMAGPART_EXPR:
1724 return 16;
1726 case SAVE_EXPR:
1727 case NON_LVALUE_EXPR:
1728 return op_prio (TREE_OPERAND (op, 0));
1730 default:
1731 /* Return an arbitrarily high precedence to avoid surrounding single
1732 VAR_DECLs in ()s. */
1733 return 9999;
1738 /* Return the symbol associated with operator OP. */
1740 static const char *
1741 op_symbol (tree op)
1743 if (op == NULL)
1744 abort ();
1746 switch (TREE_CODE (op))
1748 case MODIFY_EXPR:
1749 return "=";
1751 case TRUTH_OR_EXPR:
1752 case TRUTH_ORIF_EXPR:
1753 return "||";
1755 case TRUTH_AND_EXPR:
1756 case TRUTH_ANDIF_EXPR:
1757 return "&&";
1759 case BIT_IOR_EXPR:
1760 return "|";
1762 case TRUTH_XOR_EXPR:
1763 case BIT_XOR_EXPR:
1764 return "^";
1766 case ADDR_EXPR:
1767 case BIT_AND_EXPR:
1768 return "&";
1770 case ORDERED_EXPR:
1771 return "ord";
1772 case UNORDERED_EXPR:
1773 return "unord";
1775 case EQ_EXPR:
1776 return "==";
1777 case UNEQ_EXPR:
1778 return "u==";
1780 case NE_EXPR:
1781 return "!=";
1783 case LT_EXPR:
1784 return "<";
1785 case UNLT_EXPR:
1786 return "u<";
1788 case LE_EXPR:
1789 return "<=";
1790 case UNLE_EXPR:
1791 return "u<=";
1793 case GT_EXPR:
1794 return ">";
1795 case UNGT_EXPR:
1796 return "u>";
1798 case GE_EXPR:
1799 return ">=";
1800 case UNGE_EXPR:
1801 return "u>=";
1803 case LTGT_EXPR:
1804 return "<>";
1806 case LSHIFT_EXPR:
1807 return "<<";
1809 case RSHIFT_EXPR:
1810 return ">>";
1812 case PLUS_EXPR:
1813 return "+";
1815 case NEGATE_EXPR:
1816 case MINUS_EXPR:
1817 return "-";
1819 case BIT_NOT_EXPR:
1820 return "~";
1822 case TRUTH_NOT_EXPR:
1823 return "!";
1825 case MULT_EXPR:
1826 case INDIRECT_REF:
1827 return "*";
1829 case TRUNC_DIV_EXPR:
1830 case CEIL_DIV_EXPR:
1831 case FLOOR_DIV_EXPR:
1832 case ROUND_DIV_EXPR:
1833 case RDIV_EXPR:
1834 case EXACT_DIV_EXPR:
1835 return "/";
1837 case TRUNC_MOD_EXPR:
1838 case CEIL_MOD_EXPR:
1839 case FLOOR_MOD_EXPR:
1840 case ROUND_MOD_EXPR:
1841 return "%";
1843 case PREDECREMENT_EXPR:
1844 return " --";
1846 case PREINCREMENT_EXPR:
1847 return " ++";
1849 case POSTDECREMENT_EXPR:
1850 return "-- ";
1852 case POSTINCREMENT_EXPR:
1853 return "++ ";
1855 default:
1856 return "<<< ??? >>>";
1860 /* Prints the name of a CALL_EXPR. */
1862 static void
1863 print_call_name (pretty_printer *buffer, tree node)
1865 tree op0;
1867 if (TREE_CODE (node) != CALL_EXPR)
1868 abort ();
1870 op0 = TREE_OPERAND (node, 0);
1872 if (TREE_CODE (op0) == NON_LVALUE_EXPR)
1873 op0 = TREE_OPERAND (op0, 0);
1875 switch (TREE_CODE (op0))
1877 case VAR_DECL:
1878 case PARM_DECL:
1879 PRINT_FUNCTION_NAME (op0);
1880 break;
1882 case ADDR_EXPR:
1883 case INDIRECT_REF:
1884 case NOP_EXPR:
1885 dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
1886 break;
1888 case COND_EXPR:
1889 pp_string (buffer, "(");
1890 dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
1891 pp_string (buffer, ") ? ");
1892 dump_generic_node (buffer, TREE_OPERAND (op0, 1), 0, 0, false);
1893 pp_string (buffer, " : ");
1894 dump_generic_node (buffer, TREE_OPERAND (op0, 2), 0, 0, false);
1895 break;
1897 case COMPONENT_REF:
1898 /* The function is a pointer contained in a structure. */
1899 if (TREE_CODE (TREE_OPERAND (op0, 0)) == INDIRECT_REF ||
1900 TREE_CODE (TREE_OPERAND (op0, 0)) == VAR_DECL)
1901 PRINT_FUNCTION_NAME (TREE_OPERAND (op0, 1));
1902 else
1903 dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
1904 /* else
1905 We can have several levels of structures and a function
1906 pointer inside. This is not implemented yet... */
1907 /* NIY;*/
1908 break;
1910 case ARRAY_REF:
1911 if (TREE_CODE (TREE_OPERAND (op0, 0)) == VAR_DECL)
1912 PRINT_FUNCTION_NAME (TREE_OPERAND (op0, 0));
1913 else
1914 dump_generic_node (buffer, op0, 0, 0, false);
1915 break;
1917 case SSA_NAME:
1918 case OBJ_TYPE_REF:
1919 dump_generic_node (buffer, op0, 0, 0, false);
1920 break;
1922 default:
1923 NIY;
1927 /* Parses the string STR and replaces new-lines by '\n', tabs by '\t', ... */
1929 static void
1930 pretty_print_string (pretty_printer *buffer, const char *str)
1932 if (str == NULL)
1933 return;
1935 while (*str)
1937 switch (str[0])
1939 case '\b':
1940 pp_string (buffer, "\\b");
1941 break;
1943 case '\f':
1944 pp_string (buffer, "\\f");
1945 break;
1947 case '\n':
1948 pp_string (buffer, "\\n");
1949 break;
1951 case '\r':
1952 pp_string (buffer, "\\r");
1953 break;
1955 case '\t':
1956 pp_string (buffer, "\\t");
1957 break;
1959 case '\v':
1960 pp_string (buffer, "\\v");
1961 break;
1963 case '\\':
1964 pp_string (buffer, "\\\\");
1965 break;
1967 case '\"':
1968 pp_string (buffer, "\\\"");
1969 break;
1971 case '\'':
1972 pp_string (buffer, "\\'");
1973 break;
1975 case '\0':
1976 pp_string (buffer, "\\0");
1977 break;
1979 case '\1':
1980 pp_string (buffer, "\\1");
1981 break;
1983 case '\2':
1984 pp_string (buffer, "\\2");
1985 break;
1987 case '\3':
1988 pp_string (buffer, "\\3");
1989 break;
1991 case '\4':
1992 pp_string (buffer, "\\4");
1993 break;
1995 case '\5':
1996 pp_string (buffer, "\\5");
1997 break;
1999 case '\6':
2000 pp_string (buffer, "\\6");
2001 break;
2003 case '\7':
2004 pp_string (buffer, "\\7");
2005 break;
2007 default:
2008 pp_character (buffer, str[0]);
2009 break;
2011 str++;
2015 static void
2016 maybe_init_pretty_print (FILE *file)
2018 if (!initialized)
2020 pp_construct (&buffer, /* prefix */NULL, /* line-width */0);
2021 pp_needs_newline (&buffer) = true;
2022 initialized = 1;
2025 buffer.buffer->stream = file;
2028 static void
2029 newline_and_indent (pretty_printer *buffer, int spc)
2031 pp_newline (buffer);
2032 INDENT (spc);
2035 static void
2036 dump_vops (pretty_printer *buffer, tree stmt, int spc, int flags)
2038 size_t i;
2039 stmt_ann_t ann = stmt_ann (stmt);
2040 v_may_def_optype v_may_defs = V_MAY_DEF_OPS (ann);
2041 v_must_def_optype v_must_defs = V_MUST_DEF_OPS (ann);
2042 vuse_optype vuses = VUSE_OPS (ann);
2044 for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++)
2046 pp_string (buffer, "# ");
2047 dump_generic_node (buffer, V_MAY_DEF_RESULT (v_may_defs, i),
2048 spc + 2, flags, false);
2049 pp_string (buffer, " = V_MAY_DEF <");
2050 dump_generic_node (buffer, V_MAY_DEF_OP (v_may_defs, i),
2051 spc + 2, flags, false);
2052 pp_string (buffer, ">;");
2053 newline_and_indent (buffer, spc);
2056 for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++)
2058 tree v_must_def = V_MUST_DEF_OP (v_must_defs, i);
2059 pp_string (buffer, "# V_MUST_DEF <");
2060 dump_generic_node (buffer, v_must_def, spc + 2, flags, false);
2061 pp_string (buffer, ">;");
2062 newline_and_indent (buffer, spc);
2065 for (i = 0; i < NUM_VUSES (vuses); i++)
2067 tree vuse = VUSE_OP (vuses, i);
2068 pp_string (buffer, "# VUSE <");
2069 dump_generic_node (buffer, vuse, spc + 2, flags, false);
2070 pp_string (buffer, ">;");
2071 newline_and_indent (buffer, spc);
2075 /* Dumps basic block BB to FILE with details described by FLAGS and
2076 indented by INDENT spaces. */
2078 void
2079 dump_generic_bb (FILE *file, basic_block bb, int indent, int flags)
2081 maybe_init_pretty_print (file);
2082 dumping_stmts = true;
2083 dump_generic_bb_buff (&buffer, bb, indent, flags);
2084 pp_flush (&buffer);
2087 /* Dumps header of basic block BB to buffer BUFFER indented by INDENT
2088 spaces and details described by flags. */
2090 static void
2091 dump_bb_header (pretty_printer *buffer, basic_block bb, int indent, int flags)
2093 edge e;
2094 tree stmt;
2096 if (flags & TDF_BLOCKS)
2098 INDENT (indent);
2099 pp_string (buffer, "# BLOCK ");
2100 pp_decimal_int (buffer, bb->index);
2102 if (flags & TDF_LINENO)
2104 block_stmt_iterator bsi;
2106 for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
2107 if (get_lineno (bsi_stmt (bsi)) != -1)
2109 pp_string (buffer, ", starting at line ");
2110 pp_decimal_int (buffer, get_lineno (bsi_stmt (bsi)));
2111 break;
2114 newline_and_indent (buffer, indent);
2116 pp_string (buffer, "# PRED:");
2117 pp_write_text_to_stream (buffer);
2118 for (e = bb->pred; e; e = e->pred_next)
2119 if (flags & TDF_SLIM)
2121 pp_string (buffer, " ");
2122 if (e->src == ENTRY_BLOCK_PTR)
2123 pp_string (buffer, "ENTRY");
2124 else
2125 pp_decimal_int (buffer, e->src->index);
2127 else
2128 dump_edge_info (buffer->buffer->stream, e, 0);
2129 pp_newline (buffer);
2131 else
2133 stmt = first_stmt (bb);
2134 if (!stmt || TREE_CODE (stmt) != LABEL_EXPR)
2136 INDENT (indent - 2);
2137 pp_string (buffer, "<bb ");
2138 pp_decimal_int (buffer, bb->index);
2139 pp_string (buffer, ">:");
2140 pp_newline (buffer);
2143 pp_write_text_to_stream (buffer);
2144 check_bb_profile (bb, buffer->buffer->stream);
2147 /* Dumps end of basic block BB to buffer BUFFER indented by INDENT
2148 spaces. */
2150 static void
2151 dump_bb_end (pretty_printer *buffer, basic_block bb, int indent, int flags)
2153 edge e;
2155 INDENT (indent);
2156 pp_string (buffer, "# SUCC:");
2157 pp_write_text_to_stream (buffer);
2158 for (e = bb->succ; e; e = e->succ_next)
2159 if (flags & TDF_SLIM)
2161 pp_string (buffer, " ");
2162 if (e->dest == EXIT_BLOCK_PTR)
2163 pp_string (buffer, "EXIT");
2164 else
2165 pp_decimal_int (buffer, e->dest->index);
2167 else
2168 dump_edge_info (buffer->buffer->stream, e, 1);
2169 pp_newline (buffer);
2172 /* Dumps phi nodes of basic block BB to buffer BUFFER with details described by
2173 FLAGS indented by INDENT spaces. */
2175 static void
2176 dump_phi_nodes (pretty_printer *buffer, basic_block bb, int indent, int flags)
2178 tree phi = phi_nodes (bb);
2179 if (!phi)
2180 return;
2182 for (; phi; phi = PHI_CHAIN (phi))
2184 if (is_gimple_reg (PHI_RESULT (phi)) || (flags & TDF_VOPS))
2186 INDENT (indent);
2187 pp_string (buffer, "# ");
2188 dump_generic_node (buffer, phi, indent, flags, false);
2189 pp_newline (buffer);
2194 /* Dump jump to basic block BB that is represented implicitly in the cfg
2195 to BUFFER. */
2197 static void
2198 pp_cfg_jump (pretty_printer *buffer, basic_block bb)
2200 tree stmt;
2202 stmt = first_stmt (bb);
2204 pp_string (buffer, "goto <bb ");
2205 pp_decimal_int (buffer, bb->index);
2206 pp_string (buffer, ">");
2207 if (stmt && TREE_CODE (stmt) == LABEL_EXPR)
2209 pp_string (buffer, " (");
2210 dump_generic_node (buffer, LABEL_EXPR_LABEL (stmt), 0, 0, false);
2211 pp_string (buffer, ")");
2213 pp_semicolon (buffer);
2216 /* Dump edges represented implicitly in basic block BB to BUFFER, indented
2217 by INDENT spaces, with details given by FLAGS. */
2219 static void
2220 dump_implicit_edges (pretty_printer *buffer, basic_block bb, int indent,
2221 int flags)
2223 edge e;
2225 /* If there is a fallthru edge, we may need to add an artificial goto to the
2226 dump. */
2227 for (e = bb->succ; e; e = e->succ_next)
2228 if (e->flags & EDGE_FALLTHRU)
2229 break;
2230 if (e && e->dest != bb->next_bb)
2232 INDENT (indent);
2234 if ((flags & TDF_LINENO)
2235 #ifdef USE_MAPPED_LOCATION
2236 && e->goto_locus != UNKNOWN_LOCATION
2237 #else
2238 && e->goto_locus
2239 #endif
2242 expanded_location goto_xloc;
2243 #ifdef USE_MAPPED_LOCATION
2244 goto_xloc = expand_location (e->goto_locus);
2245 #else
2246 goto_xloc = *e->goto_locus;
2247 #endif
2248 pp_character (buffer, '[');
2249 if (goto_xloc.file)
2251 pp_string (buffer, goto_xloc.file);
2252 pp_string (buffer, " : ");
2254 pp_decimal_int (buffer, goto_xloc.line);
2255 pp_string (buffer, "] ");
2258 pp_cfg_jump (buffer, e->dest);
2259 pp_newline (buffer);
2263 /* Dumps basic block BB to buffer BUFFER with details described by FLAGS and
2264 indented by INDENT spaces. */
2266 static void
2267 dump_generic_bb_buff (pretty_printer *buffer, basic_block bb,
2268 int indent, int flags)
2270 block_stmt_iterator bsi;
2271 tree stmt;
2272 int label_indent = indent - 2;
2274 if (label_indent < 0)
2275 label_indent = 0;
2277 dump_bb_header (buffer, bb, indent, flags);
2279 if (bb_ann (bb))
2280 dump_phi_nodes (buffer, bb, indent, flags);
2282 for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
2284 int curr_indent;
2286 stmt = bsi_stmt (bsi);
2288 curr_indent = TREE_CODE (stmt) == LABEL_EXPR ? label_indent : indent;
2290 INDENT (curr_indent);
2291 dump_generic_node (buffer, stmt, curr_indent, flags, true);
2292 pp_newline (buffer);
2295 dump_implicit_edges (buffer, bb, indent, flags);
2297 if (flags & TDF_BLOCKS)
2298 dump_bb_end (buffer, bb, indent, flags);