* c-tree.h (default_function_array_conversion): Declare.
[official-gcc.git] / gcc / tree-pretty-print.c
bloba079f3efb2ac8290f54b5df3024d655ade32d6e1
1 /* Pretty formatting of GENERIC trees in C syntax.
2 Copyright (C) 2001, 2002, 2003, 2004, 2005 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 "tree.h"
27 #include "diagnostic.h"
28 #include "real.h"
29 #include "hashtab.h"
30 #include "tree-flow.h"
31 #include "langhooks.h"
32 #include "tree-iterator.h"
33 #include "tree-chrec.h"
35 /* Local functions, macros and variables. */
36 static int op_prio (tree);
37 static const char *op_symbol (tree);
38 static void pretty_print_string (pretty_printer *, const char*);
39 static void print_call_name (pretty_printer *, tree);
40 static void newline_and_indent (pretty_printer *, int);
41 static void maybe_init_pretty_print (FILE *);
42 static void print_declaration (pretty_printer *, tree, int, int);
43 static void print_struct_decl (pretty_printer *, tree, int, int);
44 static void do_niy (pretty_printer *, tree);
45 static void dump_vops (pretty_printer *, tree, int, int);
46 static void dump_generic_bb_buff (pretty_printer *, basic_block, int, int);
48 #define INDENT(SPACE) do { \
49 int i; for (i = 0; i<SPACE; i++) pp_space (buffer); } while (0)
51 #define NIY do_niy(buffer,node)
53 #define PRINT_FUNCTION_NAME(NODE) pp_printf \
54 (buffer, "%s", TREE_CODE (NODE) == NOP_EXPR ? \
55 lang_hooks.decl_printable_name (TREE_OPERAND (NODE, 0), 1) : \
56 lang_hooks.decl_printable_name (NODE, 1))
58 static pretty_printer buffer;
59 static int initialized = 0;
60 static bool dumping_stmts;
62 /* Try to print something for an unknown tree code. */
64 static void
65 do_niy (pretty_printer *buffer, tree node)
67 int i, len;
69 pp_string (buffer, "<<< Unknown tree: ");
70 pp_string (buffer, tree_code_name[(int) TREE_CODE (node)]);
72 if (EXPR_P (node))
74 len = TREE_CODE_LENGTH (TREE_CODE (node));
75 for (i = 0; i < len; ++i)
77 newline_and_indent (buffer, 2);
78 dump_generic_node (buffer, TREE_OPERAND (node, i), 2, 0, false);
82 pp_string (buffer, " >>>\n");
85 void
86 debug_generic_expr (tree t)
88 print_generic_expr (stderr, t, TDF_VOPS|TDF_UID);
89 fprintf (stderr, "\n");
92 void
93 debug_generic_stmt (tree t)
95 print_generic_stmt (stderr, t, TDF_VOPS|TDF_UID);
96 fprintf (stderr, "\n");
99 /* Prints declaration DECL to the FILE with details specified by FLAGS. */
100 void
101 print_generic_decl (FILE *file, tree decl, int flags)
103 maybe_init_pretty_print (file);
104 dumping_stmts = true;
105 print_declaration (&buffer, decl, 2, flags);
106 pp_write_text_to_stream (&buffer);
109 /* Print tree T, and its successors, on file FILE. FLAGS specifies details
110 to show in the dump. See TDF_* in tree.h. */
112 void
113 print_generic_stmt (FILE *file, tree t, int flags)
115 maybe_init_pretty_print (file);
116 dumping_stmts = true;
117 dump_generic_node (&buffer, t, 0, flags, true);
118 pp_flush (&buffer);
121 /* Print tree T, and its successors, on file FILE. FLAGS specifies details
122 to show in the dump. See TDF_* in tree.h. The output is indented by
123 INDENT spaces. */
125 void
126 print_generic_stmt_indented (FILE *file, tree t, int flags, int indent)
128 int i;
130 maybe_init_pretty_print (file);
131 dumping_stmts = true;
133 for (i = 0; i < indent; i++)
134 pp_space (&buffer);
135 dump_generic_node (&buffer, t, indent, flags, true);
136 pp_flush (&buffer);
139 /* Print a single expression T on file FILE. FLAGS specifies details to show
140 in the dump. See TDF_* in tree.h. */
142 void
143 print_generic_expr (FILE *file, tree t, int flags)
145 maybe_init_pretty_print (file);
146 dumping_stmts = false;
147 dump_generic_node (&buffer, t, 0, flags, false);
150 /* Dump the name of a _DECL node and its DECL_UID if TDF_UID is set
151 in FLAGS. */
153 static void
154 dump_decl_name (pretty_printer *buffer, tree node, int flags)
156 if (DECL_NAME (node))
157 pp_tree_identifier (buffer, DECL_NAME (node));
159 if ((flags & TDF_UID)
160 || DECL_NAME (node) == NULL_TREE)
162 if (TREE_CODE (node) == LABEL_DECL
163 && LABEL_DECL_UID (node) != -1)
164 pp_printf (buffer, "L." HOST_WIDE_INT_PRINT_DEC,
165 LABEL_DECL_UID (node));
166 else
168 char c = TREE_CODE (node) == CONST_DECL ? 'C' : 'D';
169 pp_printf (buffer, "%c.%u", c, DECL_UID (node));
174 /* Like the above, but used for pretty printing function calls. */
176 static void
177 dump_function_name (pretty_printer *buffer, tree node)
179 if (DECL_NAME (node))
180 PRINT_FUNCTION_NAME (node);
181 else
182 dump_decl_name (buffer, node, 0);
185 /* Dump a function declaration. NODE is the FUNCTION_TYPE. BUFFER, SPC and
186 FLAGS are as in dump_generic_node. */
188 static void
189 dump_function_declaration (pretty_printer *buffer, tree node,
190 int spc, int flags)
192 bool wrote_arg = false;
193 tree arg;
195 pp_space (buffer);
196 pp_character (buffer, '(');
198 /* Print the argument types. The last element in the list is a VOID_TYPE.
199 The following avoids printing the last element. */
200 arg = TYPE_ARG_TYPES (node);
201 while (arg && TREE_CHAIN (arg) && arg != error_mark_node)
203 wrote_arg = true;
204 dump_generic_node (buffer, TREE_VALUE (arg), spc, flags, false);
205 arg = TREE_CHAIN (arg);
206 if (TREE_CHAIN (arg) && TREE_CODE (TREE_CHAIN (arg)) == TREE_LIST)
208 pp_character (buffer, ',');
209 pp_space (buffer);
213 if (!wrote_arg)
214 pp_string (buffer, "void");
216 pp_character (buffer, ')');
219 /* Dump the domain associated with an array. */
221 static void
222 dump_array_domain (pretty_printer *buffer, tree domain, int spc, int flags)
224 pp_character (buffer, '[');
225 if (domain)
227 tree min = TYPE_MIN_VALUE (domain);
228 tree max = TYPE_MAX_VALUE (domain);
230 if (min && max
231 && integer_zerop (min)
232 && host_integerp (max, 0))
233 pp_wide_integer (buffer, TREE_INT_CST_LOW (max) + 1);
234 else
236 if (min)
237 dump_generic_node (buffer, min, spc, flags, false);
238 pp_character (buffer, ':');
239 if (max)
240 dump_generic_node (buffer, max, spc, flags, false);
243 else
244 pp_string (buffer, "<unknown>");
245 pp_character (buffer, ']');
248 /* Dump the node NODE on the pretty_printer BUFFER, SPC spaces of indent.
249 FLAGS specifies details to show in the dump (see TDF_* in tree.h). If
250 IS_STMT is true, the object printed is considered to be a statement
251 and it is terminated by ';' if appropriate. */
254 dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
255 bool is_stmt)
257 tree type;
258 tree op0, op1;
259 const char *str;
260 bool is_expr;
262 if (node == NULL_TREE)
263 return spc;
265 is_expr = EXPR_P (node);
267 if (TREE_CODE (node) != ERROR_MARK
268 && is_gimple_stmt (node)
269 && (flags & TDF_VOPS)
270 && stmt_ann (node))
271 dump_vops (buffer, node, spc, flags);
273 if (is_stmt && (flags & TDF_STMTADDR))
274 pp_printf (buffer, "<&%p> ", (void *)node);
276 if (dumping_stmts
277 && (flags & TDF_LINENO)
278 && EXPR_HAS_LOCATION (node))
280 expanded_location xloc = expand_location (EXPR_LOCATION (node));
281 pp_character (buffer, '[');
282 if (xloc.file)
284 pp_string (buffer, xloc.file);
285 pp_string (buffer, " : ");
287 pp_decimal_int (buffer, xloc.line);
288 pp_string (buffer, "] ");
291 switch (TREE_CODE (node))
293 case ERROR_MARK:
294 pp_string (buffer, "<<< error >>>");
295 break;
297 case IDENTIFIER_NODE:
298 pp_tree_identifier (buffer, node);
299 break;
301 case TREE_LIST:
302 while (node && node != error_mark_node)
304 if (TREE_PURPOSE (node))
306 dump_generic_node (buffer, TREE_PURPOSE (node), spc, flags, false);
307 pp_space (buffer);
309 dump_generic_node (buffer, TREE_VALUE (node), spc, flags, false);
310 node = TREE_CHAIN (node);
311 if (node && TREE_CODE (node) == TREE_LIST)
313 pp_character (buffer, ',');
314 pp_space (buffer);
317 break;
319 case TREE_BINFO:
320 dump_generic_node (buffer, BINFO_TYPE (node), spc, flags, false);
322 case TREE_VEC:
324 size_t i;
325 if (TREE_VEC_LENGTH (node) > 0)
327 size_t len = TREE_VEC_LENGTH (node);
328 for (i = 0; i < len - 1; i++)
330 dump_generic_node (buffer, TREE_VEC_ELT (node, i), spc, flags,
331 false);
332 pp_character (buffer, ',');
333 pp_space (buffer);
335 dump_generic_node (buffer, TREE_VEC_ELT (node, len - 1), spc,
336 flags, false);
339 break;
341 case BLOCK:
342 NIY;
343 break;
345 case VOID_TYPE:
346 case INTEGER_TYPE:
347 case REAL_TYPE:
348 case COMPLEX_TYPE:
349 case VECTOR_TYPE:
350 case ENUMERAL_TYPE:
351 case BOOLEAN_TYPE:
352 case CHAR_TYPE:
354 unsigned int quals = TYPE_QUALS (node);
355 enum tree_code_class class;
357 if (quals & TYPE_QUAL_CONST)
358 pp_string (buffer, "const ");
359 else if (quals & TYPE_QUAL_VOLATILE)
360 pp_string (buffer, "volatile ");
361 else if (quals & TYPE_QUAL_RESTRICT)
362 pp_string (buffer, "restrict ");
364 class = TREE_CODE_CLASS (TREE_CODE (node));
366 if (class == tcc_declaration)
368 if (DECL_NAME (node))
369 dump_decl_name (buffer, node, flags);
370 else
371 pp_string (buffer, "<unnamed type decl>");
373 else if (class == tcc_type)
375 if (TYPE_NAME (node))
377 if (TREE_CODE (TYPE_NAME (node)) == IDENTIFIER_NODE)
378 pp_tree_identifier (buffer, TYPE_NAME (node));
379 else if (TREE_CODE (TYPE_NAME (node)) == TYPE_DECL
380 && DECL_NAME (TYPE_NAME (node)))
381 dump_decl_name (buffer, TYPE_NAME (node), flags);
382 else
383 pp_string (buffer, "<unnamed type>");
385 else if (TREE_CODE (node) == VECTOR_TYPE)
387 pp_string (buffer, "vector ");
388 dump_generic_node (buffer, TREE_TYPE (node),
389 spc, flags, false);
391 else
392 pp_string (buffer, "<unnamed type>");
394 break;
397 case POINTER_TYPE:
398 case REFERENCE_TYPE:
399 str = (TREE_CODE (node) == POINTER_TYPE ? "*" : "&");
401 if (TREE_CODE (TREE_TYPE (node)) == FUNCTION_TYPE)
403 tree fnode = TREE_TYPE (node);
405 dump_generic_node (buffer, TREE_TYPE (fnode), spc, flags, false);
406 pp_space (buffer);
407 pp_character (buffer, '(');
408 pp_string (buffer, str);
409 if (TYPE_NAME (node) && DECL_NAME (TYPE_NAME (node)))
410 dump_decl_name (buffer, TYPE_NAME (node), flags);
411 else
412 pp_printf (buffer, "<T%x>", TYPE_UID (node));
414 pp_character (buffer, ')');
415 dump_function_declaration (buffer, fnode, spc, flags);
417 else
419 unsigned int quals = TYPE_QUALS (node);
421 dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
422 pp_space (buffer);
423 pp_string (buffer, str);
425 if (quals & TYPE_QUAL_CONST)
426 pp_string (buffer, " const");
427 else if (quals & TYPE_QUAL_VOLATILE)
428 pp_string (buffer, "volatile");
429 else if (quals & TYPE_QUAL_RESTRICT)
430 pp_string (buffer, " restrict");
432 if (TYPE_REF_CAN_ALIAS_ALL (node))
433 pp_string (buffer, " {ref-all}");
435 break;
437 case OFFSET_TYPE:
438 NIY;
439 break;
441 case METHOD_TYPE:
442 dump_decl_name (buffer, TYPE_NAME (TYPE_METHOD_BASETYPE (node)), flags);
443 pp_string (buffer, "::");
444 break;
446 case TARGET_MEM_REF:
448 const char *sep = "";
449 tree tmp;
451 pp_string (buffer, "MEM[");
453 tmp = TMR_SYMBOL (node);
454 if (tmp)
456 pp_string (buffer, sep);
457 sep = ", ";
458 pp_string (buffer, "symbol: ");
459 dump_generic_node (buffer, tmp, spc, flags, false);
461 tmp = TMR_BASE (node);
462 if (tmp)
464 pp_string (buffer, sep);
465 sep = ", ";
466 pp_string (buffer, "base: ");
467 dump_generic_node (buffer, tmp, spc, flags, false);
469 tmp = TMR_INDEX (node);
470 if (tmp)
472 pp_string (buffer, sep);
473 sep = ", ";
474 pp_string (buffer, "index: ");
475 dump_generic_node (buffer, tmp, spc, flags, false);
477 tmp = TMR_STEP (node);
478 if (tmp)
480 pp_string (buffer, sep);
481 sep = ", ";
482 pp_string (buffer, "step: ");
483 dump_generic_node (buffer, tmp, spc, flags, false);
485 tmp = TMR_OFFSET (node);
486 if (tmp)
488 pp_string (buffer, sep);
489 sep = ", ";
490 pp_string (buffer, "offset: ");
491 dump_generic_node (buffer, tmp, spc, flags, false);
493 pp_string (buffer, "]");
494 if (flags & TDF_DETAILS)
496 pp_string (buffer, "{");
497 dump_generic_node (buffer, TMR_ORIGINAL (node), spc, flags,
498 false);
499 pp_string (buffer, "}");
502 break;
504 case ARRAY_TYPE:
506 tree tmp;
508 /* Print the innermost component type. */
509 for (tmp = TREE_TYPE (node); TREE_CODE (tmp) == ARRAY_TYPE;
510 tmp = TREE_TYPE (tmp))
512 dump_generic_node (buffer, tmp, spc, flags, false);
514 /* Print the dimensions. */
515 for (tmp = node; TREE_CODE (tmp) == ARRAY_TYPE; tmp = TREE_TYPE (tmp))
516 dump_array_domain (buffer, TYPE_DOMAIN (tmp), spc, flags);
517 break;
520 case RECORD_TYPE:
521 case UNION_TYPE:
522 case QUAL_UNION_TYPE:
523 /* Print the name of the structure. */
524 if (TREE_CODE (node) == RECORD_TYPE)
525 pp_string (buffer, "struct ");
526 else if (TREE_CODE (node) == UNION_TYPE)
527 pp_string (buffer, "union ");
529 if (TYPE_NAME (node))
530 dump_generic_node (buffer, TYPE_NAME (node), spc, flags, false);
531 else
532 print_struct_decl (buffer, node, spc, flags);
533 break;
535 case LANG_TYPE:
536 NIY;
537 break;
539 case INTEGER_CST:
540 if (TREE_CODE (TREE_TYPE (node)) == POINTER_TYPE)
542 /* In the case of a pointer, one may want to divide by the
543 size of the pointed-to type. Unfortunately, this not
544 straightforward. The C front-end maps expressions
546 (int *) 5
547 int *p; (p + 5)
549 in such a way that the two INTEGER_CST nodes for "5" have
550 different values but identical types. In the latter
551 case, the 5 is multiplied by sizeof (int) in c-common.c
552 (pointer_int_sum) to convert it to a byte address, and
553 yet the type of the node is left unchanged. Argh. What
554 is consistent though is that the number value corresponds
555 to bytes (UNITS) offset.
557 NB: Neither of the following divisors can be trivially
558 used to recover the original literal:
560 TREE_INT_CST_LOW (TYPE_SIZE_UNIT (TREE_TYPE (node)))
561 TYPE_PRECISION (TREE_TYPE (TREE_TYPE (node))) */
562 pp_wide_integer (buffer, TREE_INT_CST_LOW (node));
563 pp_string (buffer, "B"); /* pseudo-unit */
565 else if (! host_integerp (node, 0))
567 tree val = node;
569 if (tree_int_cst_sgn (val) < 0)
571 pp_character (buffer, '-');
572 val = build_int_cst_wide (NULL_TREE,
573 -TREE_INT_CST_LOW (val),
574 ~TREE_INT_CST_HIGH (val)
575 + !TREE_INT_CST_LOW (val));
577 /* Would "%x%0*x" or "%x%*0x" get zero-padding on all
578 systems? */
580 static char format[10]; /* "%x%09999x\0" */
581 if (!format[0])
582 sprintf (format, "%%x%%0%dx", HOST_BITS_PER_INT / 4);
583 sprintf (pp_buffer (buffer)->digit_buffer, format,
584 TREE_INT_CST_HIGH (val),
585 TREE_INT_CST_LOW (val));
586 pp_string (buffer, pp_buffer (buffer)->digit_buffer);
589 else
590 pp_wide_integer (buffer, TREE_INT_CST_LOW (node));
591 break;
593 case REAL_CST:
594 /* Code copied from print_node. */
596 REAL_VALUE_TYPE d;
597 if (TREE_OVERFLOW (node))
598 pp_string (buffer, " overflow");
600 #if !defined(REAL_IS_NOT_DOUBLE) || defined(REAL_ARITHMETIC)
601 d = TREE_REAL_CST (node);
602 if (REAL_VALUE_ISINF (d))
603 pp_string (buffer, " Inf");
604 else if (REAL_VALUE_ISNAN (d))
605 pp_string (buffer, " Nan");
606 else
608 char string[100];
609 real_to_decimal (string, &d, sizeof (string), 0, 1);
610 pp_string (buffer, string);
612 #else
614 HOST_WIDE_INT i;
615 unsigned char *p = (unsigned char *) &TREE_REAL_CST (node);
616 pp_string (buffer, "0x");
617 for (i = 0; i < sizeof TREE_REAL_CST (node); i++)
618 output_formatted_integer (buffer, "%02x", *p++);
620 #endif
621 break;
624 case COMPLEX_CST:
625 pp_string (buffer, "__complex__ (");
626 dump_generic_node (buffer, TREE_REALPART (node), spc, flags, false);
627 pp_string (buffer, ", ");
628 dump_generic_node (buffer, TREE_IMAGPART (node), spc, flags, false);
629 pp_string (buffer, ")");
630 break;
632 case STRING_CST:
633 pp_string (buffer, "\"");
634 pretty_print_string (buffer, TREE_STRING_POINTER (node));
635 pp_string (buffer, "\"");
636 break;
638 case VECTOR_CST:
640 tree elt;
641 pp_string (buffer, "{ ");
642 for (elt = TREE_VECTOR_CST_ELTS (node); elt; elt = TREE_CHAIN (elt))
644 dump_generic_node (buffer, TREE_VALUE (elt), spc, flags, false);
645 if (TREE_CHAIN (elt))
646 pp_string (buffer, ", ");
648 pp_string (buffer, " }");
650 break;
652 case FUNCTION_TYPE:
653 break;
655 case FUNCTION_DECL:
656 case CONST_DECL:
657 dump_decl_name (buffer, node, flags);
658 break;
660 case LABEL_DECL:
661 if (DECL_NAME (node))
662 dump_decl_name (buffer, node, flags);
663 else if (LABEL_DECL_UID (node) != -1)
664 pp_printf (buffer, "<L" HOST_WIDE_INT_PRINT_DEC ">",
665 LABEL_DECL_UID (node));
666 else
667 pp_printf (buffer, "<D%u>", DECL_UID (node));
668 break;
670 case TYPE_DECL:
671 if (DECL_IS_BUILTIN (node))
673 /* Don't print the declaration of built-in types. */
674 break;
676 if (DECL_NAME (node))
677 dump_decl_name (buffer, node, flags);
678 else
680 if ((TREE_CODE (TREE_TYPE (node)) == RECORD_TYPE
681 || TREE_CODE (TREE_TYPE (node)) == UNION_TYPE)
682 && TYPE_METHODS (TREE_TYPE (node)))
684 /* The type is a c++ class: all structures have at least
685 4 methods. */
686 pp_string (buffer, "class ");
687 dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
689 else
691 pp_string (buffer,
692 (TREE_CODE (TREE_TYPE (node)) == UNION_TYPE
693 ? "union" : "struct "));
694 dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
697 break;
699 case VAR_DECL:
700 case PARM_DECL:
701 case FIELD_DECL:
702 case NAMESPACE_DECL:
703 dump_decl_name (buffer, node, flags);
704 break;
706 case RESULT_DECL:
707 pp_string (buffer, "<retval>");
708 break;
710 case COMPONENT_REF:
711 op0 = TREE_OPERAND (node, 0);
712 str = ".";
713 if (TREE_CODE (op0) == INDIRECT_REF)
715 op0 = TREE_OPERAND (op0, 0);
716 str = "->";
718 if (op_prio (op0) < op_prio (node))
719 pp_character (buffer, '(');
720 dump_generic_node (buffer, op0, spc, flags, false);
721 if (op_prio (op0) < op_prio (node))
722 pp_character (buffer, ')');
723 pp_string (buffer, str);
724 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
726 if (TREE_CODE (op0) != VALUE_HANDLE)
728 op0 = component_ref_field_offset (node);
729 if (op0 && TREE_CODE (op0) != INTEGER_CST)
731 pp_string (buffer, "{off: ");
732 dump_generic_node (buffer, op0, spc, flags, false);
733 pp_character (buffer, '}');
736 break;
738 case BIT_FIELD_REF:
739 pp_string (buffer, "BIT_FIELD_REF <");
740 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
741 pp_string (buffer, ", ");
742 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
743 pp_string (buffer, ", ");
744 dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
745 pp_string (buffer, ">");
746 break;
748 case ARRAY_REF:
749 case ARRAY_RANGE_REF:
750 op0 = TREE_OPERAND (node, 0);
751 if (op_prio (op0) < op_prio (node))
752 pp_character (buffer, '(');
753 dump_generic_node (buffer, op0, spc, flags, false);
754 if (op_prio (op0) < op_prio (node))
755 pp_character (buffer, ')');
756 pp_character (buffer, '[');
757 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
758 if (TREE_CODE (node) == ARRAY_RANGE_REF)
759 pp_string (buffer, " ...");
760 pp_character (buffer, ']');
762 op0 = array_ref_low_bound (node);
763 op1 = array_ref_element_size (node);
765 if (!integer_zerop (op0)
766 || (TYPE_SIZE_UNIT (TREE_TYPE (node))
767 && !operand_equal_p (op1, TYPE_SIZE_UNIT (TREE_TYPE (node)), 0)))
769 pp_string (buffer, "{lb: ");
770 dump_generic_node (buffer, op0, spc, flags, false);
771 pp_string (buffer, " sz: ");
772 dump_generic_node (buffer, op1, spc, flags, false);
773 pp_character (buffer, '}');
775 break;
777 case CONSTRUCTOR:
779 tree lnode;
780 bool is_struct_init = FALSE;
781 pp_character (buffer, '{');
782 lnode = CONSTRUCTOR_ELTS (node);
783 if (TREE_CODE (TREE_TYPE (node)) == RECORD_TYPE
784 || TREE_CODE (TREE_TYPE (node)) == UNION_TYPE)
785 is_struct_init = TRUE;
786 while (lnode && lnode != error_mark_node)
788 tree val;
789 if (TREE_PURPOSE (lnode) && is_struct_init)
791 pp_character (buffer, '.');
792 dump_generic_node (buffer, TREE_PURPOSE (lnode), spc, flags, false);
793 pp_string (buffer, "=");
795 val = TREE_VALUE (lnode);
796 if (val && TREE_CODE (val) == ADDR_EXPR)
797 if (TREE_CODE (TREE_OPERAND (val, 0)) == FUNCTION_DECL)
798 val = TREE_OPERAND (val, 0);
799 if (val && TREE_CODE (val) == FUNCTION_DECL)
801 dump_decl_name (buffer, val, flags);
803 else
805 dump_generic_node (buffer, TREE_VALUE (lnode), spc, flags, false);
807 lnode = TREE_CHAIN (lnode);
808 if (lnode && TREE_CODE (lnode) == TREE_LIST)
810 pp_character (buffer, ',');
811 pp_space (buffer);
814 pp_character (buffer, '}');
816 break;
818 case COMPOUND_EXPR:
820 tree *tp;
821 if (flags & TDF_SLIM)
823 pp_string (buffer, "<COMPOUND_EXPR>");
824 break;
827 dump_generic_node (buffer, TREE_OPERAND (node, 0),
828 spc, flags, dumping_stmts);
829 if (dumping_stmts)
830 newline_and_indent (buffer, spc);
831 else
833 pp_character (buffer, ',');
834 pp_space (buffer);
837 for (tp = &TREE_OPERAND (node, 1);
838 TREE_CODE (*tp) == COMPOUND_EXPR;
839 tp = &TREE_OPERAND (*tp, 1))
841 dump_generic_node (buffer, TREE_OPERAND (*tp, 0),
842 spc, flags, dumping_stmts);
843 if (dumping_stmts)
844 newline_and_indent (buffer, spc);
845 else
847 pp_character (buffer, ',');
848 pp_space (buffer);
852 dump_generic_node (buffer, *tp, spc, flags, dumping_stmts);
854 break;
856 case STATEMENT_LIST:
858 tree_stmt_iterator si;
859 bool first = true;
861 if ((flags & TDF_SLIM) || !dumping_stmts)
863 pp_string (buffer, "<STATEMENT_LIST>");
864 break;
867 for (si = tsi_start (node); !tsi_end_p (si); tsi_next (&si))
869 if (!first)
870 newline_and_indent (buffer, spc);
871 else
872 first = false;
873 dump_generic_node (buffer, tsi_stmt (si), spc, flags, true);
876 break;
878 case MODIFY_EXPR:
879 case INIT_EXPR:
880 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
881 pp_space (buffer);
882 pp_character (buffer, '=');
883 pp_space (buffer);
884 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
885 break;
887 case TARGET_EXPR:
888 pp_string (buffer, "TARGET_EXPR <");
889 dump_generic_node (buffer, TARGET_EXPR_SLOT (node), spc, flags, false);
890 pp_character (buffer, ',');
891 pp_space (buffer);
892 dump_generic_node (buffer, TARGET_EXPR_INITIAL (node), spc, flags, false);
893 pp_character (buffer, '>');
894 break;
896 case DECL_EXPR:
897 print_declaration (buffer, DECL_EXPR_DECL (node), spc, flags);
898 is_stmt = false;
899 break;
901 case COND_EXPR:
902 if (TREE_TYPE (node) == NULL || TREE_TYPE (node) == void_type_node)
904 pp_string (buffer, "if (");
905 dump_generic_node (buffer, COND_EXPR_COND (node), spc, flags, false);
906 pp_character (buffer, ')');
907 /* The lowered cond_exprs should always be printed in full. */
908 if (COND_EXPR_THEN (node)
909 && (IS_EMPTY_STMT (COND_EXPR_THEN (node))
910 || TREE_CODE (COND_EXPR_THEN (node)) == GOTO_EXPR)
911 && COND_EXPR_ELSE (node)
912 && (IS_EMPTY_STMT (COND_EXPR_ELSE (node))
913 || TREE_CODE (COND_EXPR_ELSE (node)) == GOTO_EXPR))
915 pp_space (buffer);
916 dump_generic_node (buffer, COND_EXPR_THEN (node), 0, flags, true);
917 pp_string (buffer, " else ");
918 dump_generic_node (buffer, COND_EXPR_ELSE (node), 0, flags, true);
920 else if (!(flags & TDF_SLIM))
922 /* Output COND_EXPR_THEN. */
923 if (COND_EXPR_THEN (node))
925 newline_and_indent (buffer, spc+2);
926 pp_character (buffer, '{');
927 newline_and_indent (buffer, spc+4);
928 dump_generic_node (buffer, COND_EXPR_THEN (node), spc+4,
929 flags, true);
930 newline_and_indent (buffer, spc+2);
931 pp_character (buffer, '}');
934 /* Output COND_EXPR_ELSE. */
935 if (COND_EXPR_ELSE (node))
937 newline_and_indent (buffer, spc);
938 pp_string (buffer, "else");
939 newline_and_indent (buffer, spc+2);
940 pp_character (buffer, '{');
941 newline_and_indent (buffer, spc+4);
942 dump_generic_node (buffer, COND_EXPR_ELSE (node), spc+4,
943 flags, true);
944 newline_and_indent (buffer, spc+2);
945 pp_character (buffer, '}');
948 is_expr = false;
950 else
952 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
953 pp_space (buffer);
954 pp_character (buffer, '?');
955 pp_space (buffer);
956 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
957 pp_space (buffer);
958 pp_character (buffer, ':');
959 pp_space (buffer);
960 dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
962 break;
964 case BIND_EXPR:
965 pp_character (buffer, '{');
966 if (!(flags & TDF_SLIM))
968 if (BIND_EXPR_VARS (node))
970 pp_newline (buffer);
972 for (op0 = BIND_EXPR_VARS (node); op0; op0 = TREE_CHAIN (op0))
974 print_declaration (buffer, op0, spc+2, flags);
975 pp_newline (buffer);
979 newline_and_indent (buffer, spc+2);
980 dump_generic_node (buffer, BIND_EXPR_BODY (node), spc+2, flags, true);
981 newline_and_indent (buffer, spc);
982 pp_character (buffer, '}');
984 is_expr = false;
985 break;
987 case CALL_EXPR:
988 print_call_name (buffer, node);
990 /* Print parameters. */
991 pp_space (buffer);
992 pp_character (buffer, '(');
993 op1 = TREE_OPERAND (node, 1);
994 if (op1)
995 dump_generic_node (buffer, op1, spc, flags, false);
996 pp_character (buffer, ')');
998 op1 = TREE_OPERAND (node, 2);
999 if (op1)
1001 pp_string (buffer, " [static-chain: ");
1002 dump_generic_node (buffer, op1, spc, flags, false);
1003 pp_character (buffer, ']');
1006 if (CALL_EXPR_HAS_RETURN_SLOT_ADDR (node))
1007 pp_string (buffer, " [return slot addr]");
1008 if (CALL_EXPR_TAILCALL (node))
1009 pp_string (buffer, " [tail call]");
1010 break;
1012 case WITH_CLEANUP_EXPR:
1013 NIY;
1014 break;
1016 case CLEANUP_POINT_EXPR:
1017 pp_string (buffer, "<<cleanup_point ");
1018 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1019 pp_string (buffer, ">>");
1020 break;
1022 case PLACEHOLDER_EXPR:
1023 pp_string (buffer, "<PLACEHOLDER_EXPR ");
1024 dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
1025 pp_character (buffer, '>');
1026 break;
1028 /* Binary arithmetic and logic expressions. */
1029 case MULT_EXPR:
1030 case PLUS_EXPR:
1031 case MINUS_EXPR:
1032 case TRUNC_DIV_EXPR:
1033 case CEIL_DIV_EXPR:
1034 case FLOOR_DIV_EXPR:
1035 case ROUND_DIV_EXPR:
1036 case TRUNC_MOD_EXPR:
1037 case CEIL_MOD_EXPR:
1038 case FLOOR_MOD_EXPR:
1039 case ROUND_MOD_EXPR:
1040 case RDIV_EXPR:
1041 case EXACT_DIV_EXPR:
1042 case LSHIFT_EXPR:
1043 case RSHIFT_EXPR:
1044 case LROTATE_EXPR:
1045 case RROTATE_EXPR:
1046 case BIT_IOR_EXPR:
1047 case BIT_XOR_EXPR:
1048 case BIT_AND_EXPR:
1049 case TRUTH_ANDIF_EXPR:
1050 case TRUTH_ORIF_EXPR:
1051 case TRUTH_AND_EXPR:
1052 case TRUTH_OR_EXPR:
1053 case TRUTH_XOR_EXPR:
1054 case LT_EXPR:
1055 case LE_EXPR:
1056 case GT_EXPR:
1057 case GE_EXPR:
1058 case EQ_EXPR:
1059 case NE_EXPR:
1060 case UNLT_EXPR:
1061 case UNLE_EXPR:
1062 case UNGT_EXPR:
1063 case UNGE_EXPR:
1064 case UNEQ_EXPR:
1065 case LTGT_EXPR:
1066 case ORDERED_EXPR:
1067 case UNORDERED_EXPR:
1069 const char *op = op_symbol (node);
1070 op0 = TREE_OPERAND (node, 0);
1071 op1 = TREE_OPERAND (node, 1);
1073 /* When the operands are expressions with less priority,
1074 keep semantics of the tree representation. */
1075 if (op_prio (op0) < op_prio (node))
1077 pp_character (buffer, '(');
1078 dump_generic_node (buffer, op0, spc, flags, false);
1079 pp_character (buffer, ')');
1081 else
1082 dump_generic_node (buffer, op0, spc, flags, false);
1084 pp_space (buffer);
1085 pp_string (buffer, op);
1086 pp_space (buffer);
1088 /* When the operands are expressions with less priority,
1089 keep semantics of the tree representation. */
1090 if (op_prio (op1) < op_prio (node))
1092 pp_character (buffer, '(');
1093 dump_generic_node (buffer, op1, spc, flags, false);
1094 pp_character (buffer, ')');
1096 else
1097 dump_generic_node (buffer, op1, spc, flags, false);
1099 break;
1101 /* Unary arithmetic and logic expressions. */
1102 case NEGATE_EXPR:
1103 case BIT_NOT_EXPR:
1104 case TRUTH_NOT_EXPR:
1105 case ADDR_EXPR:
1106 case PREDECREMENT_EXPR:
1107 case PREINCREMENT_EXPR:
1108 case ALIGN_INDIRECT_REF:
1109 case MISALIGNED_INDIRECT_REF:
1110 case INDIRECT_REF:
1111 if (TREE_CODE (node) == ADDR_EXPR
1112 && (TREE_CODE (TREE_OPERAND (node, 0)) == STRING_CST
1113 || TREE_CODE (TREE_OPERAND (node, 0)) == FUNCTION_DECL))
1114 ; /* Do not output '&' for strings and function pointers. */
1115 else
1116 pp_string (buffer, op_symbol (node));
1118 if (op_prio (TREE_OPERAND (node, 0)) < op_prio (node))
1120 pp_character (buffer, '(');
1121 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1122 pp_character (buffer, ')');
1124 else
1125 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1127 if (TREE_CODE (node) == MISALIGNED_INDIRECT_REF)
1129 pp_string (buffer, "{misalignment: ");
1130 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1131 pp_character (buffer, '}');
1133 break;
1135 case POSTDECREMENT_EXPR:
1136 case POSTINCREMENT_EXPR:
1137 if (op_prio (TREE_OPERAND (node, 0)) < op_prio (node))
1139 pp_character (buffer, '(');
1140 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1141 pp_character (buffer, ')');
1143 else
1144 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1145 pp_string (buffer, op_symbol (node));
1146 break;
1148 case MIN_EXPR:
1149 pp_string (buffer, "MIN_EXPR <");
1150 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1151 pp_string (buffer, ", ");
1152 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1153 pp_character (buffer, '>');
1154 break;
1156 case MAX_EXPR:
1157 pp_string (buffer, "MAX_EXPR <");
1158 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1159 pp_string (buffer, ", ");
1160 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1161 pp_character (buffer, '>');
1162 break;
1164 case ABS_EXPR:
1165 pp_string (buffer, "ABS_EXPR <");
1166 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1167 pp_character (buffer, '>');
1168 break;
1170 case RANGE_EXPR:
1171 NIY;
1172 break;
1174 case FIX_TRUNC_EXPR:
1175 case FIX_CEIL_EXPR:
1176 case FIX_FLOOR_EXPR:
1177 case FIX_ROUND_EXPR:
1178 case FLOAT_EXPR:
1179 case CONVERT_EXPR:
1180 case NOP_EXPR:
1181 type = TREE_TYPE (node);
1182 op0 = TREE_OPERAND (node, 0);
1183 if (type != TREE_TYPE (op0))
1185 pp_character (buffer, '(');
1186 dump_generic_node (buffer, type, spc, flags, false);
1187 pp_string (buffer, ") ");
1189 if (op_prio (op0) < op_prio (node))
1190 pp_character (buffer, '(');
1191 dump_generic_node (buffer, op0, spc, flags, false);
1192 if (op_prio (op0) < op_prio (node))
1193 pp_character (buffer, ')');
1194 break;
1196 case VIEW_CONVERT_EXPR:
1197 pp_string (buffer, "VIEW_CONVERT_EXPR<");
1198 dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
1199 pp_string (buffer, ">(");
1200 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1201 pp_character (buffer, ')');
1202 break;
1204 case NON_LVALUE_EXPR:
1205 pp_string (buffer, "NON_LVALUE_EXPR <");
1206 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1207 pp_character (buffer, '>');
1208 break;
1210 case SAVE_EXPR:
1211 pp_string (buffer, "SAVE_EXPR <");
1212 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1213 pp_character (buffer, '>');
1214 break;
1216 case COMPLEX_EXPR:
1217 pp_string (buffer, "COMPLEX_EXPR <");
1218 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1219 pp_string (buffer, ", ");
1220 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1221 pp_string (buffer, ">");
1222 break;
1224 case CONJ_EXPR:
1225 pp_string (buffer, "CONJ_EXPR <");
1226 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1227 pp_string (buffer, ">");
1228 break;
1230 case REALPART_EXPR:
1231 pp_string (buffer, "REALPART_EXPR <");
1232 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1233 pp_string (buffer, ">");
1234 break;
1236 case IMAGPART_EXPR:
1237 pp_string (buffer, "IMAGPART_EXPR <");
1238 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1239 pp_string (buffer, ">");
1240 break;
1242 case VA_ARG_EXPR:
1243 pp_string (buffer, "VA_ARG_EXPR <");
1244 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1245 pp_string (buffer, ">");
1246 break;
1248 case TRY_FINALLY_EXPR:
1249 case TRY_CATCH_EXPR:
1250 pp_string (buffer, "try");
1251 newline_and_indent (buffer, spc+2);
1252 pp_string (buffer, "{");
1253 newline_and_indent (buffer, spc+4);
1254 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc+4, flags, true);
1255 newline_and_indent (buffer, spc+2);
1256 pp_string (buffer, "}");
1257 newline_and_indent (buffer, spc);
1258 pp_string (buffer,
1259 (TREE_CODE (node) == TRY_CATCH_EXPR) ? "catch" : "finally");
1260 newline_and_indent (buffer, spc+2);
1261 pp_string (buffer, "{");
1262 newline_and_indent (buffer, spc+4);
1263 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc+4, flags, true);
1264 newline_and_indent (buffer, spc+2);
1265 pp_string (buffer, "}");
1266 is_expr = false;
1267 break;
1269 case CATCH_EXPR:
1270 pp_string (buffer, "catch (");
1271 dump_generic_node (buffer, CATCH_TYPES (node), spc+2, flags, false);
1272 pp_string (buffer, ")");
1273 newline_and_indent (buffer, spc+2);
1274 pp_string (buffer, "{");
1275 newline_and_indent (buffer, spc+4);
1276 dump_generic_node (buffer, CATCH_BODY (node), spc+4, flags, true);
1277 newline_and_indent (buffer, spc+2);
1278 pp_string (buffer, "}");
1279 is_expr = false;
1280 break;
1282 case EH_FILTER_EXPR:
1283 pp_string (buffer, "<<<eh_filter (");
1284 dump_generic_node (buffer, EH_FILTER_TYPES (node), spc+2, flags, false);
1285 pp_string (buffer, ")>>>");
1286 newline_and_indent (buffer, spc+2);
1287 pp_string (buffer, "{");
1288 newline_and_indent (buffer, spc+4);
1289 dump_generic_node (buffer, EH_FILTER_FAILURE (node), spc+4, flags, true);
1290 newline_and_indent (buffer, spc+2);
1291 pp_string (buffer, "}");
1292 is_expr = false;
1293 break;
1295 case LABEL_EXPR:
1296 op0 = TREE_OPERAND (node, 0);
1297 /* If this is for break or continue, don't bother printing it. */
1298 if (DECL_NAME (op0))
1300 const char *name = IDENTIFIER_POINTER (DECL_NAME (op0));
1301 if (strcmp (name, "break") == 0
1302 || strcmp (name, "continue") == 0)
1303 break;
1305 dump_generic_node (buffer, op0, spc, flags, false);
1306 pp_character (buffer, ':');
1307 if (DECL_NONLOCAL (op0))
1308 pp_string (buffer, " [non-local]");
1309 break;
1311 case EXC_PTR_EXPR:
1312 pp_string (buffer, "<<<exception object>>>");
1313 break;
1315 case FILTER_EXPR:
1316 pp_string (buffer, "<<<filter object>>>");
1317 break;
1319 case LOOP_EXPR:
1320 pp_string (buffer, "while (1)");
1321 if (!(flags & TDF_SLIM))
1323 newline_and_indent (buffer, spc+2);
1324 pp_character (buffer, '{');
1325 newline_and_indent (buffer, spc+4);
1326 dump_generic_node (buffer, LOOP_EXPR_BODY (node), spc+4, flags, true);
1327 newline_and_indent (buffer, spc+2);
1328 pp_character (buffer, '}');
1330 is_expr = false;
1331 break;
1333 case RETURN_EXPR:
1334 pp_string (buffer, "return");
1335 op0 = TREE_OPERAND (node, 0);
1336 if (op0)
1338 pp_space (buffer);
1339 if (TREE_CODE (op0) == MODIFY_EXPR)
1340 dump_generic_node (buffer, TREE_OPERAND (op0, 1), spc, flags, false);
1341 else
1342 dump_generic_node (buffer, op0, spc, flags, false);
1344 break;
1346 case EXIT_EXPR:
1347 pp_string (buffer, "if (");
1348 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1349 pp_string (buffer, ") break");
1350 break;
1352 case SWITCH_EXPR:
1353 pp_string (buffer, "switch (");
1354 dump_generic_node (buffer, SWITCH_COND (node), spc, flags, false);
1355 pp_character (buffer, ')');
1356 if (!(flags & TDF_SLIM))
1358 newline_and_indent (buffer, spc+2);
1359 pp_character (buffer, '{');
1360 if (SWITCH_BODY (node))
1362 newline_and_indent (buffer, spc+4);
1363 dump_generic_node (buffer, SWITCH_BODY (node), spc+4, flags, true);
1365 else
1367 tree vec = SWITCH_LABELS (node);
1368 size_t i, n = TREE_VEC_LENGTH (vec);
1369 for (i = 0; i < n; ++i)
1371 tree elt = TREE_VEC_ELT (vec, i);
1372 newline_and_indent (buffer, spc+4);
1373 dump_generic_node (buffer, elt, spc+4, flags, false);
1374 pp_string (buffer, " goto ");
1375 dump_generic_node (buffer, CASE_LABEL (elt), spc+4, flags, true);
1376 pp_semicolon (buffer);
1379 newline_and_indent (buffer, spc+2);
1380 pp_character (buffer, '}');
1382 is_expr = false;
1383 break;
1385 case GOTO_EXPR:
1386 op0 = GOTO_DESTINATION (node);
1387 if (TREE_CODE (op0) != SSA_NAME && DECL_P (op0) && DECL_NAME (op0))
1389 const char *name = IDENTIFIER_POINTER (DECL_NAME (op0));
1390 if (strcmp (name, "break") == 0
1391 || strcmp (name, "continue") == 0)
1393 pp_string (buffer, name);
1394 break;
1397 pp_string (buffer, "goto ");
1398 dump_generic_node (buffer, op0, spc, flags, false);
1399 break;
1401 case RESX_EXPR:
1402 pp_string (buffer, "resx");
1403 /* ??? Any sensible way to present the eh region? */
1404 break;
1406 case ASM_EXPR:
1407 pp_string (buffer, "__asm__");
1408 if (ASM_VOLATILE_P (node))
1409 pp_string (buffer, " __volatile__");
1410 pp_character (buffer, '(');
1411 dump_generic_node (buffer, ASM_STRING (node), spc, flags, false);
1412 pp_character (buffer, ':');
1413 dump_generic_node (buffer, ASM_OUTPUTS (node), spc, flags, false);
1414 pp_character (buffer, ':');
1415 dump_generic_node (buffer, ASM_INPUTS (node), spc, flags, false);
1416 if (ASM_CLOBBERS (node))
1418 pp_character (buffer, ':');
1419 dump_generic_node (buffer, ASM_CLOBBERS (node), spc, flags, false);
1421 pp_string (buffer, ")");
1422 break;
1424 case CASE_LABEL_EXPR:
1425 if (CASE_LOW (node) && CASE_HIGH (node))
1427 pp_string (buffer, "case ");
1428 dump_generic_node (buffer, CASE_LOW (node), spc, flags, false);
1429 pp_string (buffer, " ... ");
1430 dump_generic_node (buffer, CASE_HIGH (node), spc, flags, false);
1432 else if (CASE_LOW (node))
1434 pp_string (buffer, "case ");
1435 dump_generic_node (buffer, CASE_LOW (node), spc, flags, false);
1437 else
1438 pp_string (buffer, "default ");
1439 pp_character (buffer, ':');
1440 break;
1442 case OBJ_TYPE_REF:
1443 pp_string (buffer, "OBJ_TYPE_REF(");
1444 dump_generic_node (buffer, OBJ_TYPE_REF_EXPR (node), spc, flags, false);
1445 pp_character (buffer, ';');
1446 dump_generic_node (buffer, OBJ_TYPE_REF_OBJECT (node), spc, flags, false);
1447 pp_character (buffer, '-');
1448 pp_character (buffer, '>');
1449 dump_generic_node (buffer, OBJ_TYPE_REF_TOKEN (node), spc, flags, false);
1450 pp_character (buffer, ')');
1451 break;
1453 case PHI_NODE:
1455 int i;
1457 dump_generic_node (buffer, PHI_RESULT (node), spc, flags, false);
1458 pp_string (buffer, " = PHI <");
1459 for (i = 0; i < PHI_NUM_ARGS (node); i++)
1461 dump_generic_node (buffer, PHI_ARG_DEF (node, i), spc, flags, false);
1462 pp_string (buffer, "(");
1463 pp_decimal_int (buffer, PHI_ARG_EDGE (node, i)->src->index);
1464 pp_string (buffer, ")");
1465 if (i < PHI_NUM_ARGS (node) - 1)
1466 pp_string (buffer, ", ");
1468 pp_string (buffer, ">;");
1470 break;
1472 case SSA_NAME:
1473 dump_generic_node (buffer, SSA_NAME_VAR (node), spc, flags, false);
1474 pp_string (buffer, "_");
1475 pp_decimal_int (buffer, SSA_NAME_VERSION (node));
1476 if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (node))
1477 pp_string (buffer, "(ab)");
1478 break;
1480 case WITH_SIZE_EXPR:
1481 pp_string (buffer, "WITH_SIZE_EXPR <");
1482 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1483 pp_string (buffer, ", ");
1484 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1485 pp_string (buffer, ">");
1486 break;
1488 case VALUE_HANDLE:
1489 pp_printf (buffer, "VH.%d", VALUE_HANDLE_ID (node));
1490 break;
1492 case ASSERT_EXPR:
1493 pp_string (buffer, "ASSERT_EXPR <");
1494 dump_generic_node (buffer, ASSERT_EXPR_VAR (node), spc, flags, false);
1495 pp_string (buffer, ", ");
1496 dump_generic_node (buffer, ASSERT_EXPR_COND (node), spc, flags, false);
1497 pp_string (buffer, ">");
1498 break;
1500 case SCEV_KNOWN:
1501 pp_string (buffer, "scev_known");
1502 break;
1504 case SCEV_NOT_KNOWN:
1505 pp_string (buffer, "scev_not_known");
1506 break;
1508 case POLYNOMIAL_CHREC:
1509 pp_string (buffer, "{");
1510 dump_generic_node (buffer, CHREC_LEFT (node), spc, flags, false);
1511 pp_string (buffer, ", +, ");
1512 dump_generic_node (buffer, CHREC_RIGHT (node), spc, flags, false);
1513 pp_string (buffer, "}_");
1514 dump_generic_node (buffer, CHREC_VAR (node), spc, flags, false);
1515 is_stmt = false;
1516 break;
1518 case REALIGN_LOAD_EXPR:
1519 pp_string (buffer, "REALIGN_LOAD <");
1520 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1521 pp_string (buffer, ", ");
1522 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1523 pp_string (buffer, ", ");
1524 dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
1525 pp_string (buffer, ">");
1526 break;
1528 case VEC_COND_EXPR:
1529 pp_string (buffer, " VEC_COND_EXPR < ");
1530 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1531 pp_string (buffer, " , ");
1532 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1533 pp_string (buffer, " , ");
1534 dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
1535 pp_string (buffer, " > ");
1536 break;
1538 default:
1539 NIY;
1542 if (is_stmt && is_expr)
1543 pp_semicolon (buffer);
1544 pp_write_text_to_stream (buffer);
1546 return spc;
1549 /* Print the declaration of a variable. */
1551 static void
1552 print_declaration (pretty_printer *buffer, tree t, int spc, int flags)
1554 INDENT (spc);
1556 if (TREE_CODE (t) == TYPE_DECL)
1557 pp_string (buffer, "typedef ");
1559 if (DECL_REGISTER (t))
1560 pp_string (buffer, "register ");
1562 if (TREE_PUBLIC (t) && DECL_EXTERNAL (t))
1563 pp_string (buffer, "extern ");
1564 else if (TREE_STATIC (t))
1565 pp_string (buffer, "static ");
1567 /* Print the type and name. */
1568 if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
1570 tree tmp;
1572 /* Print array's type. */
1573 tmp = TREE_TYPE (t);
1574 while (TREE_CODE (TREE_TYPE (tmp)) == ARRAY_TYPE)
1575 tmp = TREE_TYPE (tmp);
1576 dump_generic_node (buffer, TREE_TYPE (tmp), spc, flags, false);
1578 /* Print variable's name. */
1579 pp_space (buffer);
1580 dump_generic_node (buffer, t, spc, flags, false);
1582 /* Print the dimensions. */
1583 tmp = TREE_TYPE (t);
1584 while (TREE_CODE (tmp) == ARRAY_TYPE)
1586 dump_array_domain (buffer, TYPE_DOMAIN (tmp), spc, flags);
1587 tmp = TREE_TYPE (tmp);
1590 else if (TREE_CODE (t) == FUNCTION_DECL)
1592 dump_generic_node (buffer, TREE_TYPE (TREE_TYPE (t)), spc, flags, false);
1593 pp_space (buffer);
1594 dump_decl_name (buffer, t, flags);
1595 dump_function_declaration (buffer, TREE_TYPE (t), spc, flags);
1597 else
1599 /* Print type declaration. */
1600 dump_generic_node (buffer, TREE_TYPE (t), spc, flags, false);
1602 /* Print variable's name. */
1603 pp_space (buffer);
1604 dump_generic_node (buffer, t, spc, flags, false);
1607 if (TREE_CODE (t) == VAR_DECL && DECL_HARD_REGISTER (t))
1609 pp_string (buffer, " __asm__ ");
1610 pp_character (buffer, '(');
1611 dump_generic_node (buffer, DECL_ASSEMBLER_NAME (t), spc, flags, false);
1612 pp_character (buffer, ')');
1615 /* The initial value of a function serves to determine wether the function
1616 is declared or defined. So the following does not apply to function
1617 nodes. */
1618 if (TREE_CODE (t) != FUNCTION_DECL)
1620 /* Print the initial value. */
1621 if (DECL_INITIAL (t))
1623 pp_space (buffer);
1624 pp_character (buffer, '=');
1625 pp_space (buffer);
1626 dump_generic_node (buffer, DECL_INITIAL (t), spc, flags, false);
1630 pp_character (buffer, ';');
1634 /* Prints a structure: name, fields, and methods.
1635 FIXME: Still incomplete. */
1637 static void
1638 print_struct_decl (pretty_printer *buffer, tree node, int spc, int flags)
1640 /* Print the name of the structure. */
1641 if (TYPE_NAME (node))
1643 INDENT (spc);
1644 if (TREE_CODE (node) == RECORD_TYPE)
1645 pp_string (buffer, "struct ");
1646 else if ((TREE_CODE (node) == UNION_TYPE
1647 || TREE_CODE (node) == QUAL_UNION_TYPE))
1648 pp_string (buffer, "union ");
1650 dump_generic_node (buffer, TYPE_NAME (node), spc, 0, false);
1653 /* Print the contents of the structure. */
1654 pp_newline (buffer);
1655 INDENT (spc);
1656 pp_character (buffer, '{');
1657 pp_newline (buffer);
1659 /* Print the fields of the structure. */
1661 tree tmp;
1662 tmp = TYPE_FIELDS (node);
1663 while (tmp)
1665 /* Avoid to print recursively the structure. */
1666 /* FIXME : Not implemented correctly...,
1667 what about the case when we have a cycle in the contain graph? ...
1668 Maybe this could be solved by looking at the scope in which the
1669 structure was declared. */
1670 if (TREE_TYPE (tmp) != node
1671 || (TREE_CODE (TREE_TYPE (tmp)) == POINTER_TYPE
1672 && TREE_TYPE (TREE_TYPE (tmp)) != node))
1674 print_declaration (buffer, tmp, spc+2, flags);
1675 pp_newline (buffer);
1677 tmp = TREE_CHAIN (tmp);
1680 INDENT (spc);
1681 pp_character (buffer, '}');
1684 /* Return the priority of the operator OP.
1686 From lowest to highest precedence with either left-to-right (L-R)
1687 or right-to-left (R-L) associativity]:
1689 1 [L-R] ,
1690 2 [R-L] = += -= *= /= %= &= ^= |= <<= >>=
1691 3 [R-L] ?:
1692 4 [L-R] ||
1693 5 [L-R] &&
1694 6 [L-R] |
1695 7 [L-R] ^
1696 8 [L-R] &
1697 9 [L-R] == !=
1698 10 [L-R] < <= > >=
1699 11 [L-R] << >>
1700 12 [L-R] + -
1701 13 [L-R] * / %
1702 14 [R-L] ! ~ ++ -- + - * & (type) sizeof
1703 15 [L-R] fn() [] -> .
1705 unary +, - and * have higher precedence than the corresponding binary
1706 operators. */
1708 static int
1709 op_prio (tree op)
1711 if (op == NULL)
1712 return 9999;
1714 switch (TREE_CODE (op))
1716 case TREE_LIST:
1717 case COMPOUND_EXPR:
1718 case BIND_EXPR:
1719 return 1;
1721 case MODIFY_EXPR:
1722 case INIT_EXPR:
1723 return 2;
1725 case COND_EXPR:
1726 return 3;
1728 case TRUTH_OR_EXPR:
1729 case TRUTH_ORIF_EXPR:
1730 return 4;
1732 case TRUTH_AND_EXPR:
1733 case TRUTH_ANDIF_EXPR:
1734 return 5;
1736 case BIT_IOR_EXPR:
1737 return 6;
1739 case BIT_XOR_EXPR:
1740 case TRUTH_XOR_EXPR:
1741 return 7;
1743 case BIT_AND_EXPR:
1744 return 8;
1746 case EQ_EXPR:
1747 case NE_EXPR:
1748 return 9;
1750 case UNLT_EXPR:
1751 case UNLE_EXPR:
1752 case UNGT_EXPR:
1753 case UNGE_EXPR:
1754 case UNEQ_EXPR:
1755 case LTGT_EXPR:
1756 case ORDERED_EXPR:
1757 case UNORDERED_EXPR:
1758 case LT_EXPR:
1759 case LE_EXPR:
1760 case GT_EXPR:
1761 case GE_EXPR:
1762 return 10;
1764 case LSHIFT_EXPR:
1765 case RSHIFT_EXPR:
1766 case LROTATE_EXPR:
1767 case RROTATE_EXPR:
1768 return 11;
1770 case PLUS_EXPR:
1771 case MINUS_EXPR:
1772 return 12;
1774 case MULT_EXPR:
1775 case TRUNC_DIV_EXPR:
1776 case CEIL_DIV_EXPR:
1777 case FLOOR_DIV_EXPR:
1778 case ROUND_DIV_EXPR:
1779 case RDIV_EXPR:
1780 case EXACT_DIV_EXPR:
1781 case TRUNC_MOD_EXPR:
1782 case CEIL_MOD_EXPR:
1783 case FLOOR_MOD_EXPR:
1784 case ROUND_MOD_EXPR:
1785 return 13;
1787 case TRUTH_NOT_EXPR:
1788 case BIT_NOT_EXPR:
1789 case POSTINCREMENT_EXPR:
1790 case POSTDECREMENT_EXPR:
1791 case PREINCREMENT_EXPR:
1792 case PREDECREMENT_EXPR:
1793 case NEGATE_EXPR:
1794 case ALIGN_INDIRECT_REF:
1795 case MISALIGNED_INDIRECT_REF:
1796 case INDIRECT_REF:
1797 case ADDR_EXPR:
1798 case FLOAT_EXPR:
1799 case NOP_EXPR:
1800 case CONVERT_EXPR:
1801 case FIX_TRUNC_EXPR:
1802 case FIX_CEIL_EXPR:
1803 case FIX_FLOOR_EXPR:
1804 case FIX_ROUND_EXPR:
1805 case TARGET_EXPR:
1806 return 14;
1808 case CALL_EXPR:
1809 case ARRAY_REF:
1810 case ARRAY_RANGE_REF:
1811 case COMPONENT_REF:
1812 return 15;
1814 /* Special expressions. */
1815 case MIN_EXPR:
1816 case MAX_EXPR:
1817 case ABS_EXPR:
1818 case REALPART_EXPR:
1819 case IMAGPART_EXPR:
1820 return 16;
1822 case SAVE_EXPR:
1823 case NON_LVALUE_EXPR:
1824 return op_prio (TREE_OPERAND (op, 0));
1826 default:
1827 /* Return an arbitrarily high precedence to avoid surrounding single
1828 VAR_DECLs in ()s. */
1829 return 9999;
1834 /* Return the symbol associated with operator OP. */
1836 static const char *
1837 op_symbol (tree op)
1839 gcc_assert (op);
1841 switch (TREE_CODE (op))
1843 case MODIFY_EXPR:
1844 return "=";
1846 case TRUTH_OR_EXPR:
1847 case TRUTH_ORIF_EXPR:
1848 return "||";
1850 case TRUTH_AND_EXPR:
1851 case TRUTH_ANDIF_EXPR:
1852 return "&&";
1854 case BIT_IOR_EXPR:
1855 return "|";
1857 case TRUTH_XOR_EXPR:
1858 case BIT_XOR_EXPR:
1859 return "^";
1861 case ADDR_EXPR:
1862 case BIT_AND_EXPR:
1863 return "&";
1865 case ORDERED_EXPR:
1866 return "ord";
1867 case UNORDERED_EXPR:
1868 return "unord";
1870 case EQ_EXPR:
1871 return "==";
1872 case UNEQ_EXPR:
1873 return "u==";
1875 case NE_EXPR:
1876 return "!=";
1878 case LT_EXPR:
1879 return "<";
1880 case UNLT_EXPR:
1881 return "u<";
1883 case LE_EXPR:
1884 return "<=";
1885 case UNLE_EXPR:
1886 return "u<=";
1888 case GT_EXPR:
1889 return ">";
1890 case UNGT_EXPR:
1891 return "u>";
1893 case GE_EXPR:
1894 return ">=";
1895 case UNGE_EXPR:
1896 return "u>=";
1898 case LTGT_EXPR:
1899 return "<>";
1901 case LSHIFT_EXPR:
1902 return "<<";
1904 case RSHIFT_EXPR:
1905 return ">>";
1907 case PLUS_EXPR:
1908 return "+";
1910 case NEGATE_EXPR:
1911 case MINUS_EXPR:
1912 return "-";
1914 case BIT_NOT_EXPR:
1915 return "~";
1917 case TRUTH_NOT_EXPR:
1918 return "!";
1920 case MULT_EXPR:
1921 case INDIRECT_REF:
1922 return "*";
1924 case ALIGN_INDIRECT_REF:
1925 return "A*";
1927 case MISALIGNED_INDIRECT_REF:
1928 return "M*";
1930 case TRUNC_DIV_EXPR:
1931 case RDIV_EXPR:
1932 return "/";
1934 case CEIL_DIV_EXPR:
1935 return "/[cl]";
1937 case FLOOR_DIV_EXPR:
1938 return "/[fl]";
1940 case ROUND_DIV_EXPR:
1941 return "/[rd]";
1943 case EXACT_DIV_EXPR:
1944 return "/[ex]";
1946 case TRUNC_MOD_EXPR:
1947 return "%";
1949 case CEIL_MOD_EXPR:
1950 return "%[cl]";
1952 case FLOOR_MOD_EXPR:
1953 return "%[fl]";
1955 case ROUND_MOD_EXPR:
1956 return "%[rd]";
1958 case PREDECREMENT_EXPR:
1959 return " --";
1961 case PREINCREMENT_EXPR:
1962 return " ++";
1964 case POSTDECREMENT_EXPR:
1965 return "-- ";
1967 case POSTINCREMENT_EXPR:
1968 return "++ ";
1970 default:
1971 return "<<< ??? >>>";
1975 /* Prints the name of a CALL_EXPR. */
1977 static void
1978 print_call_name (pretty_printer *buffer, tree node)
1980 tree op0;
1982 gcc_assert (TREE_CODE (node) == CALL_EXPR);
1984 op0 = TREE_OPERAND (node, 0);
1986 if (TREE_CODE (op0) == NON_LVALUE_EXPR)
1987 op0 = TREE_OPERAND (op0, 0);
1989 switch (TREE_CODE (op0))
1991 case VAR_DECL:
1992 case PARM_DECL:
1993 dump_function_name (buffer, op0);
1994 break;
1996 case ADDR_EXPR:
1997 case INDIRECT_REF:
1998 case NOP_EXPR:
1999 dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
2000 break;
2002 case COND_EXPR:
2003 pp_string (buffer, "(");
2004 dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
2005 pp_string (buffer, ") ? ");
2006 dump_generic_node (buffer, TREE_OPERAND (op0, 1), 0, 0, false);
2007 pp_string (buffer, " : ");
2008 dump_generic_node (buffer, TREE_OPERAND (op0, 2), 0, 0, false);
2009 break;
2011 case COMPONENT_REF:
2012 /* The function is a pointer contained in a structure. */
2013 if (TREE_CODE (TREE_OPERAND (op0, 0)) == INDIRECT_REF ||
2014 TREE_CODE (TREE_OPERAND (op0, 0)) == VAR_DECL)
2015 dump_function_name (buffer, TREE_OPERAND (op0, 1));
2016 else
2017 dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
2018 /* else
2019 We can have several levels of structures and a function
2020 pointer inside. This is not implemented yet... */
2021 /* NIY;*/
2022 break;
2024 case ARRAY_REF:
2025 if (TREE_CODE (TREE_OPERAND (op0, 0)) == VAR_DECL)
2026 dump_function_name (buffer, TREE_OPERAND (op0, 0));
2027 else
2028 dump_generic_node (buffer, op0, 0, 0, false);
2029 break;
2031 case SSA_NAME:
2032 case OBJ_TYPE_REF:
2033 dump_generic_node (buffer, op0, 0, 0, false);
2034 break;
2036 default:
2037 NIY;
2041 /* Parses the string STR and replaces new-lines by '\n', tabs by '\t', ... */
2043 static void
2044 pretty_print_string (pretty_printer *buffer, const char *str)
2046 if (str == NULL)
2047 return;
2049 while (*str)
2051 switch (str[0])
2053 case '\b':
2054 pp_string (buffer, "\\b");
2055 break;
2057 case '\f':
2058 pp_string (buffer, "\\f");
2059 break;
2061 case '\n':
2062 pp_string (buffer, "\\n");
2063 break;
2065 case '\r':
2066 pp_string (buffer, "\\r");
2067 break;
2069 case '\t':
2070 pp_string (buffer, "\\t");
2071 break;
2073 case '\v':
2074 pp_string (buffer, "\\v");
2075 break;
2077 case '\\':
2078 pp_string (buffer, "\\\\");
2079 break;
2081 case '\"':
2082 pp_string (buffer, "\\\"");
2083 break;
2085 case '\'':
2086 pp_string (buffer, "\\'");
2087 break;
2089 case '\0':
2090 pp_string (buffer, "\\0");
2091 break;
2093 case '\1':
2094 pp_string (buffer, "\\1");
2095 break;
2097 case '\2':
2098 pp_string (buffer, "\\2");
2099 break;
2101 case '\3':
2102 pp_string (buffer, "\\3");
2103 break;
2105 case '\4':
2106 pp_string (buffer, "\\4");
2107 break;
2109 case '\5':
2110 pp_string (buffer, "\\5");
2111 break;
2113 case '\6':
2114 pp_string (buffer, "\\6");
2115 break;
2117 case '\7':
2118 pp_string (buffer, "\\7");
2119 break;
2121 default:
2122 pp_character (buffer, str[0]);
2123 break;
2125 str++;
2129 static void
2130 maybe_init_pretty_print (FILE *file)
2132 if (!initialized)
2134 pp_construct (&buffer, /* prefix */NULL, /* line-width */0);
2135 pp_needs_newline (&buffer) = true;
2136 initialized = 1;
2139 buffer.buffer->stream = file;
2142 static void
2143 newline_and_indent (pretty_printer *buffer, int spc)
2145 pp_newline (buffer);
2146 INDENT (spc);
2149 static void
2150 dump_vops (pretty_printer *buffer, tree stmt, int spc, int flags)
2152 tree use;
2153 use_operand_p use_p;
2154 def_operand_p def_p;
2155 use_operand_p kill_p;
2156 ssa_op_iter iter;
2158 if (!ssa_operands_active ())
2159 return;
2161 FOR_EACH_SSA_MAYDEF_OPERAND (def_p, use_p, stmt, iter)
2163 pp_string (buffer, "# ");
2164 dump_generic_node (buffer, DEF_FROM_PTR (def_p),
2165 spc + 2, flags, false);
2166 pp_string (buffer, " = V_MAY_DEF <");
2167 dump_generic_node (buffer, USE_FROM_PTR (use_p),
2168 spc + 2, flags, false);
2169 pp_string (buffer, ">;");
2170 newline_and_indent (buffer, spc);
2173 FOR_EACH_SSA_MUSTDEF_OPERAND (def_p, kill_p, stmt, iter)
2175 pp_string (buffer, "# ");
2176 dump_generic_node (buffer, DEF_FROM_PTR (def_p),
2177 spc + 2, flags, false);
2178 pp_string (buffer, " = V_MUST_DEF <");
2179 dump_generic_node (buffer, USE_FROM_PTR (kill_p),
2180 spc + 2, flags, false);
2181 pp_string (buffer, ">;");
2182 newline_and_indent (buffer, spc);
2185 FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_VUSE)
2187 pp_string (buffer, "# VUSE <");
2188 dump_generic_node (buffer, use, spc + 2, flags, false);
2189 pp_string (buffer, ">;");
2190 newline_and_indent (buffer, spc);
2194 /* Dumps basic block BB to FILE with details described by FLAGS and
2195 indented by INDENT spaces. */
2197 void
2198 dump_generic_bb (FILE *file, basic_block bb, int indent, int flags)
2200 maybe_init_pretty_print (file);
2201 dumping_stmts = true;
2202 dump_generic_bb_buff (&buffer, bb, indent, flags);
2203 pp_flush (&buffer);
2206 /* Dumps header of basic block BB to buffer BUFFER indented by INDENT
2207 spaces and details described by flags. */
2209 static void
2210 dump_bb_header (pretty_printer *buffer, basic_block bb, int indent, int flags)
2212 edge e;
2213 tree stmt;
2214 edge_iterator ei;
2216 if (flags & TDF_BLOCKS)
2218 INDENT (indent);
2219 pp_string (buffer, "# BLOCK ");
2220 pp_decimal_int (buffer, bb->index);
2222 if (flags & TDF_LINENO)
2224 block_stmt_iterator bsi;
2226 for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
2227 if (get_lineno (bsi_stmt (bsi)) != -1)
2229 pp_string (buffer, ", starting at line ");
2230 pp_decimal_int (buffer, get_lineno (bsi_stmt (bsi)));
2231 break;
2234 newline_and_indent (buffer, indent);
2236 pp_string (buffer, "# PRED:");
2237 pp_write_text_to_stream (buffer);
2238 FOR_EACH_EDGE (e, ei, bb->preds)
2239 if (flags & TDF_SLIM)
2241 pp_string (buffer, " ");
2242 if (e->src == ENTRY_BLOCK_PTR)
2243 pp_string (buffer, "ENTRY");
2244 else
2245 pp_decimal_int (buffer, e->src->index);
2247 else
2248 dump_edge_info (buffer->buffer->stream, e, 0);
2249 pp_newline (buffer);
2251 else
2253 stmt = first_stmt (bb);
2254 if (!stmt || TREE_CODE (stmt) != LABEL_EXPR)
2256 INDENT (indent - 2);
2257 pp_string (buffer, "<bb ");
2258 pp_decimal_int (buffer, bb->index);
2259 pp_string (buffer, ">:");
2260 pp_newline (buffer);
2263 pp_write_text_to_stream (buffer);
2264 check_bb_profile (bb, buffer->buffer->stream);
2267 /* Dumps end of basic block BB to buffer BUFFER indented by INDENT
2268 spaces. */
2270 static void
2271 dump_bb_end (pretty_printer *buffer, basic_block bb, int indent, int flags)
2273 edge e;
2274 edge_iterator ei;
2276 INDENT (indent);
2277 pp_string (buffer, "# SUCC:");
2278 pp_write_text_to_stream (buffer);
2279 FOR_EACH_EDGE (e, ei, bb->succs)
2280 if (flags & TDF_SLIM)
2282 pp_string (buffer, " ");
2283 if (e->dest == EXIT_BLOCK_PTR)
2284 pp_string (buffer, "EXIT");
2285 else
2286 pp_decimal_int (buffer, e->dest->index);
2288 else
2289 dump_edge_info (buffer->buffer->stream, e, 1);
2290 pp_newline (buffer);
2293 /* Dumps phi nodes of basic block BB to buffer BUFFER with details described by
2294 FLAGS indented by INDENT spaces. */
2296 static void
2297 dump_phi_nodes (pretty_printer *buffer, basic_block bb, int indent, int flags)
2299 tree phi = phi_nodes (bb);
2300 if (!phi)
2301 return;
2303 for (; phi; phi = PHI_CHAIN (phi))
2305 if (is_gimple_reg (PHI_RESULT (phi)) || (flags & TDF_VOPS))
2307 INDENT (indent);
2308 pp_string (buffer, "# ");
2309 dump_generic_node (buffer, phi, indent, flags, false);
2310 pp_newline (buffer);
2315 /* Dump jump to basic block BB that is represented implicitly in the cfg
2316 to BUFFER. */
2318 static void
2319 pp_cfg_jump (pretty_printer *buffer, basic_block bb)
2321 tree stmt;
2323 stmt = first_stmt (bb);
2325 pp_string (buffer, "goto <bb ");
2326 pp_decimal_int (buffer, bb->index);
2327 pp_string (buffer, ">");
2328 if (stmt && TREE_CODE (stmt) == LABEL_EXPR)
2330 pp_string (buffer, " (");
2331 dump_generic_node (buffer, LABEL_EXPR_LABEL (stmt), 0, 0, false);
2332 pp_string (buffer, ")");
2334 pp_semicolon (buffer);
2337 /* Dump edges represented implicitly in basic block BB to BUFFER, indented
2338 by INDENT spaces, with details given by FLAGS. */
2340 static void
2341 dump_implicit_edges (pretty_printer *buffer, basic_block bb, int indent,
2342 int flags)
2344 edge e;
2345 edge_iterator ei;
2347 /* If there is a fallthru edge, we may need to add an artificial goto to the
2348 dump. */
2349 FOR_EACH_EDGE (e, ei, bb->succs)
2350 if (e->flags & EDGE_FALLTHRU)
2351 break;
2352 if (e && e->dest != bb->next_bb)
2354 INDENT (indent);
2356 if ((flags & TDF_LINENO)
2357 #ifdef USE_MAPPED_LOCATION
2358 && e->goto_locus != UNKNOWN_LOCATION
2359 #else
2360 && e->goto_locus
2361 #endif
2364 expanded_location goto_xloc;
2365 #ifdef USE_MAPPED_LOCATION
2366 goto_xloc = expand_location (e->goto_locus);
2367 #else
2368 goto_xloc = *e->goto_locus;
2369 #endif
2370 pp_character (buffer, '[');
2371 if (goto_xloc.file)
2373 pp_string (buffer, goto_xloc.file);
2374 pp_string (buffer, " : ");
2376 pp_decimal_int (buffer, goto_xloc.line);
2377 pp_string (buffer, "] ");
2380 pp_cfg_jump (buffer, e->dest);
2381 pp_newline (buffer);
2385 /* Dumps basic block BB to buffer BUFFER with details described by FLAGS and
2386 indented by INDENT spaces. */
2388 static void
2389 dump_generic_bb_buff (pretty_printer *buffer, basic_block bb,
2390 int indent, int flags)
2392 block_stmt_iterator bsi;
2393 tree stmt;
2394 int label_indent = indent - 2;
2396 if (label_indent < 0)
2397 label_indent = 0;
2399 dump_bb_header (buffer, bb, indent, flags);
2401 dump_phi_nodes (buffer, bb, indent, flags);
2403 for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
2405 int curr_indent;
2407 stmt = bsi_stmt (bsi);
2409 curr_indent = TREE_CODE (stmt) == LABEL_EXPR ? label_indent : indent;
2411 INDENT (curr_indent);
2412 dump_generic_node (buffer, stmt, curr_indent, flags, true);
2413 pp_newline (buffer);
2416 dump_implicit_edges (buffer, bb, indent, flags);
2418 if (flags & TDF_BLOCKS)
2419 dump_bb_end (buffer, bb, indent, flags);