PR target/4198
[official-gcc.git] / gcc / tree-pretty-print.c
blob743e1592e4de08c0dd42e227b414f0920fec86d7
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 "errors.h"
27 #include "tree.h"
28 #include "diagnostic.h"
29 #include "real.h"
30 #include "hashtab.h"
31 #include "tree-flow.h"
32 #include "langhooks.h"
33 #include "tree-iterator.h"
34 #include "tree-chrec.h"
36 /* Local functions, macros and variables. */
37 static int op_prio (tree);
38 static const char *op_symbol (tree);
39 static void pretty_print_string (pretty_printer *, const char*);
40 static void print_call_name (pretty_printer *, tree);
41 static void newline_and_indent (pretty_printer *, int);
42 static void maybe_init_pretty_print (FILE *);
43 static void print_declaration (pretty_printer *, tree, int, int);
44 static void print_struct_decl (pretty_printer *, tree, int, int);
45 static void do_niy (pretty_printer *, tree);
46 static void dump_vops (pretty_printer *, tree, int, int);
47 static void dump_generic_bb_buff (pretty_printer *, basic_block, int, int);
49 #define INDENT(SPACE) do { \
50 int i; for (i = 0; i<SPACE; i++) pp_space (buffer); } while (0)
52 #define NIY do_niy(buffer,node)
54 #define PRINT_FUNCTION_NAME(NODE) pp_printf \
55 (buffer, "%s", TREE_CODE (NODE) == NOP_EXPR ? \
56 lang_hooks.decl_printable_name (TREE_OPERAND (NODE, 0), 1) : \
57 lang_hooks.decl_printable_name (NODE, 1))
59 static pretty_printer buffer;
60 static int initialized = 0;
61 static bool dumping_stmts;
63 /* Try to print something for an unknown tree code. */
65 static void
66 do_niy (pretty_printer *buffer, tree node)
68 int i, len;
70 pp_string (buffer, "<<< Unknown tree: ");
71 pp_string (buffer, tree_code_name[(int) TREE_CODE (node)]);
73 if (EXPR_P (node))
75 len = TREE_CODE_LENGTH (TREE_CODE (node));
76 for (i = 0; i < len; ++i)
78 newline_and_indent (buffer, 2);
79 dump_generic_node (buffer, TREE_OPERAND (node, i), 2, 0, false);
83 pp_string (buffer, " >>>\n");
86 void
87 debug_generic_expr (tree t)
89 print_generic_expr (stderr, t, TDF_VOPS|TDF_UID);
90 fprintf (stderr, "\n");
93 void
94 debug_generic_stmt (tree t)
96 print_generic_stmt (stderr, t, TDF_VOPS|TDF_UID);
97 fprintf (stderr, "\n");
100 /* Prints declaration DECL to the FILE with details specified by FLAGS. */
101 void
102 print_generic_decl (FILE *file, tree decl, int flags)
104 maybe_init_pretty_print (file);
105 dumping_stmts = true;
106 print_declaration (&buffer, decl, 2, flags);
107 pp_write_text_to_stream (&buffer);
110 /* Print tree T, and its successors, on file FILE. FLAGS specifies details
111 to show in the dump. See TDF_* in tree.h. */
113 void
114 print_generic_stmt (FILE *file, tree t, int flags)
116 maybe_init_pretty_print (file);
117 dumping_stmts = true;
118 dump_generic_node (&buffer, t, 0, flags, true);
119 pp_flush (&buffer);
122 /* Print tree T, and its successors, on file FILE. FLAGS specifies details
123 to show in the dump. See TDF_* in tree.h. The output is indented by
124 INDENT spaces. */
126 void
127 print_generic_stmt_indented (FILE *file, tree t, int flags, int indent)
129 int i;
131 maybe_init_pretty_print (file);
132 dumping_stmts = true;
134 for (i = 0; i < indent; i++)
135 pp_space (&buffer);
136 dump_generic_node (&buffer, t, indent, flags, true);
137 pp_flush (&buffer);
140 /* Print a single expression T on file FILE. FLAGS specifies details to show
141 in the dump. See TDF_* in tree.h. */
143 void
144 print_generic_expr (FILE *file, tree t, int flags)
146 maybe_init_pretty_print (file);
147 dumping_stmts = false;
148 dump_generic_node (&buffer, t, 0, flags, false);
151 /* Dump the name of a _DECL node and its DECL_UID if TDF_UID is set
152 in FLAGS. */
154 static void
155 dump_decl_name (pretty_printer *buffer, tree node, int flags)
157 if (DECL_NAME (node))
158 pp_tree_identifier (buffer, DECL_NAME (node));
160 if ((flags & TDF_UID)
161 || DECL_NAME (node) == NULL_TREE)
163 if (TREE_CODE (node) == LABEL_DECL
164 && LABEL_DECL_UID (node) != -1)
165 pp_printf (buffer, "L." HOST_WIDE_INT_PRINT_DEC,
166 LABEL_DECL_UID (node));
167 else
169 char c = TREE_CODE (node) == CONST_DECL ? 'C' : 'D';
170 pp_printf (buffer, "%c.%u", c, DECL_UID (node));
175 /* Like the above, but used for pretty printing function calls. */
177 static void
178 dump_function_name (pretty_printer *buffer, tree node)
180 if (DECL_NAME (node))
181 PRINT_FUNCTION_NAME (node);
182 else
183 dump_decl_name (buffer, node, 0);
186 /* Dump a function declaration. NODE is the FUNCTION_TYPE. BUFFER, SPC and
187 FLAGS are as in dump_generic_node. */
189 static void
190 dump_function_declaration (pretty_printer *buffer, tree node,
191 int spc, int flags)
193 bool wrote_arg = false;
194 tree arg;
196 pp_space (buffer);
197 pp_character (buffer, '(');
199 /* Print the argument types. The last element in the list is a VOID_TYPE.
200 The following avoids printing the last element. */
201 arg = TYPE_ARG_TYPES (node);
202 while (arg && TREE_CHAIN (arg) && arg != error_mark_node)
204 wrote_arg = true;
205 dump_generic_node (buffer, TREE_VALUE (arg), spc, flags, false);
206 arg = TREE_CHAIN (arg);
207 if (TREE_CHAIN (arg) && TREE_CODE (TREE_CHAIN (arg)) == TREE_LIST)
209 pp_character (buffer, ',');
210 pp_space (buffer);
214 if (!wrote_arg)
215 pp_string (buffer, "void");
217 pp_character (buffer, ')');
220 /* Dump the domain associated with an array. */
222 static void
223 dump_array_domain (pretty_printer *buffer, tree domain, int spc, int flags)
225 pp_character (buffer, '[');
226 if (domain)
228 tree min = TYPE_MIN_VALUE (domain);
229 tree max = TYPE_MAX_VALUE (domain);
231 if (min && max
232 && integer_zerop (min)
233 && host_integerp (max, 0))
234 pp_wide_integer (buffer, TREE_INT_CST_LOW (max) + 1);
235 else
237 if (min)
238 dump_generic_node (buffer, min, spc, flags, false);
239 pp_character (buffer, ':');
240 if (max)
241 dump_generic_node (buffer, max, spc, flags, false);
244 else
245 pp_string (buffer, "<unknown>");
246 pp_character (buffer, ']');
249 /* Dump the node NODE on the pretty_printer BUFFER, SPC spaces of indent.
250 FLAGS specifies details to show in the dump (see TDF_* in tree.h). If
251 IS_STMT is true, the object printed is considered to be a statement
252 and it is terminated by ';' if appropriate. */
255 dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
256 bool is_stmt)
258 tree type;
259 tree op0, op1;
260 const char *str;
261 bool is_expr;
263 if (node == NULL_TREE)
264 return spc;
266 is_expr = EXPR_P (node);
268 if (TREE_CODE (node) != ERROR_MARK
269 && is_gimple_stmt (node)
270 && (flags & TDF_VOPS)
271 && stmt_ann (node))
272 dump_vops (buffer, node, spc, flags);
274 if (dumping_stmts
275 && (flags & TDF_LINENO)
276 && EXPR_HAS_LOCATION (node))
278 expanded_location xloc = expand_location (EXPR_LOCATION (node));
279 pp_character (buffer, '[');
280 if (xloc.file)
282 pp_string (buffer, xloc.file);
283 pp_string (buffer, " : ");
285 pp_decimal_int (buffer, xloc.line);
286 pp_string (buffer, "] ");
289 switch (TREE_CODE (node))
291 case ERROR_MARK:
292 pp_string (buffer, "<<< error >>>");
293 break;
295 case IDENTIFIER_NODE:
296 pp_tree_identifier (buffer, node);
297 break;
299 case TREE_LIST:
300 while (node && node != error_mark_node)
302 if (TREE_PURPOSE (node))
304 dump_generic_node (buffer, TREE_PURPOSE (node), spc, flags, false);
305 pp_space (buffer);
307 dump_generic_node (buffer, TREE_VALUE (node), spc, flags, false);
308 node = TREE_CHAIN (node);
309 if (node && TREE_CODE (node) == TREE_LIST)
311 pp_character (buffer, ',');
312 pp_space (buffer);
315 break;
317 case TREE_BINFO:
318 dump_generic_node (buffer, BINFO_TYPE (node), spc, flags, false);
320 case TREE_VEC:
322 size_t i;
323 if (TREE_VEC_LENGTH (node) > 0)
325 size_t len = TREE_VEC_LENGTH (node);
326 for (i = 0; i < len - 1; i++)
328 dump_generic_node (buffer, TREE_VEC_ELT (node, i), spc, flags,
329 false);
330 pp_character (buffer, ',');
331 pp_space (buffer);
333 dump_generic_node (buffer, TREE_VEC_ELT (node, len - 1), spc,
334 flags, false);
337 break;
339 case BLOCK:
340 NIY;
341 break;
343 case VOID_TYPE:
344 case INTEGER_TYPE:
345 case REAL_TYPE:
346 case COMPLEX_TYPE:
347 case VECTOR_TYPE:
348 case ENUMERAL_TYPE:
349 case BOOLEAN_TYPE:
350 case CHAR_TYPE:
352 unsigned int quals = TYPE_QUALS (node);
353 enum tree_code_class class;
355 if (quals & TYPE_QUAL_CONST)
356 pp_string (buffer, "const ");
357 else if (quals & TYPE_QUAL_VOLATILE)
358 pp_string (buffer, "volatile ");
359 else if (quals & TYPE_QUAL_RESTRICT)
360 pp_string (buffer, "restrict ");
362 class = TREE_CODE_CLASS (TREE_CODE (node));
364 if (class == tcc_declaration)
366 if (DECL_NAME (node))
367 dump_decl_name (buffer, node, flags);
368 else
369 pp_string (buffer, "<unnamed type decl>");
371 else if (class == tcc_type)
373 if (TYPE_NAME (node))
375 if (TREE_CODE (TYPE_NAME (node)) == IDENTIFIER_NODE)
376 pp_tree_identifier (buffer, TYPE_NAME (node));
377 else if (TREE_CODE (TYPE_NAME (node)) == TYPE_DECL
378 && DECL_NAME (TYPE_NAME (node)))
379 dump_decl_name (buffer, TYPE_NAME (node), flags);
380 else
381 pp_string (buffer, "<unnamed type>");
383 else if (TREE_CODE (node) == VECTOR_TYPE)
385 pp_string (buffer, "vector ");
386 dump_generic_node (buffer, TREE_TYPE (node),
387 spc, flags, false);
389 else
390 pp_string (buffer, "<unnamed type>");
392 break;
395 case POINTER_TYPE:
396 case REFERENCE_TYPE:
397 str = (TREE_CODE (node) == POINTER_TYPE ? "*" : "&");
399 if (TREE_CODE (TREE_TYPE (node)) == FUNCTION_TYPE)
401 tree fnode = TREE_TYPE (node);
403 dump_generic_node (buffer, TREE_TYPE (fnode), spc, flags, false);
404 pp_space (buffer);
405 pp_character (buffer, '(');
406 pp_string (buffer, str);
407 if (TYPE_NAME (node) && DECL_NAME (TYPE_NAME (node)))
408 dump_decl_name (buffer, TYPE_NAME (node), flags);
409 else
410 pp_printf (buffer, "<T%x>", TYPE_UID (node));
412 pp_character (buffer, ')');
413 dump_function_declaration (buffer, fnode, spc, flags);
415 else
417 unsigned int quals = TYPE_QUALS (node);
419 dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
420 pp_space (buffer);
421 pp_string (buffer, str);
423 if (quals & TYPE_QUAL_CONST)
424 pp_string (buffer, " const");
425 else if (quals & TYPE_QUAL_VOLATILE)
426 pp_string (buffer, "volatile");
427 else if (quals & TYPE_QUAL_RESTRICT)
428 pp_string (buffer, " restrict");
430 if (TYPE_REF_CAN_ALIAS_ALL (node))
431 pp_string (buffer, " {ref-all}");
433 break;
435 case OFFSET_TYPE:
436 NIY;
437 break;
439 case METHOD_TYPE:
440 dump_decl_name (buffer, TYPE_NAME (TYPE_METHOD_BASETYPE (node)), flags);
441 pp_string (buffer, "::");
442 break;
444 case ARRAY_TYPE:
446 tree tmp;
448 /* Print the innermost component type. */
449 for (tmp = TREE_TYPE (node); TREE_CODE (tmp) == ARRAY_TYPE;
450 tmp = TREE_TYPE (tmp))
452 dump_generic_node (buffer, tmp, spc, flags, false);
454 /* Print the dimensions. */
455 for (tmp = node; TREE_CODE (tmp) == ARRAY_TYPE; tmp = TREE_TYPE (tmp))
456 dump_array_domain (buffer, TYPE_DOMAIN (tmp), spc, flags);
457 break;
460 case RECORD_TYPE:
461 case UNION_TYPE:
462 case QUAL_UNION_TYPE:
463 /* Print the name of the structure. */
464 if (TREE_CODE (node) == RECORD_TYPE)
465 pp_string (buffer, "struct ");
466 else if (TREE_CODE (node) == UNION_TYPE)
467 pp_string (buffer, "union ");
469 if (TYPE_NAME (node))
470 dump_generic_node (buffer, TYPE_NAME (node), spc, flags, false);
471 else
472 print_struct_decl (buffer, node, spc, flags);
473 break;
475 case LANG_TYPE:
476 NIY;
477 break;
479 case INTEGER_CST:
480 if (TREE_CODE (TREE_TYPE (node)) == POINTER_TYPE)
482 /* In the case of a pointer, one may want to divide by the
483 size of the pointed-to type. Unfortunately, this not
484 straightforward. The C front-end maps expressions
486 (int *) 5
487 int *p; (p + 5)
489 in such a way that the two INTEGER_CST nodes for "5" have
490 different values but identical types. In the latter
491 case, the 5 is multiplied by sizeof (int) in c-common.c
492 (pointer_int_sum) to convert it to a byte address, and
493 yet the type of the node is left unchanged. Argh. What
494 is consistent though is that the number value corresponds
495 to bytes (UNITS) offset.
497 NB: Neither of the following divisors can be trivially
498 used to recover the original literal:
500 TREE_INT_CST_LOW (TYPE_SIZE_UNIT (TREE_TYPE (node)))
501 TYPE_PRECISION (TREE_TYPE (TREE_TYPE (node))) */
502 pp_wide_integer (buffer, TREE_INT_CST_LOW (node));
503 pp_string (buffer, "B"); /* pseudo-unit */
505 else if (! host_integerp (node, 0))
507 tree val = node;
509 if (tree_int_cst_sgn (val) < 0)
511 pp_character (buffer, '-');
512 val = build_int_cst_wide (NULL_TREE,
513 -TREE_INT_CST_LOW (val),
514 ~TREE_INT_CST_HIGH (val)
515 + !TREE_INT_CST_LOW (val));
517 /* Would "%x%0*x" or "%x%*0x" get zero-padding on all
518 systems? */
520 static char format[10]; /* "%x%09999x\0" */
521 if (!format[0])
522 sprintf (format, "%%x%%0%dx", HOST_BITS_PER_INT / 4);
523 sprintf (pp_buffer (buffer)->digit_buffer, format,
524 TREE_INT_CST_HIGH (val),
525 TREE_INT_CST_LOW (val));
526 pp_string (buffer, pp_buffer (buffer)->digit_buffer);
529 else
530 pp_wide_integer (buffer, TREE_INT_CST_LOW (node));
531 break;
533 case REAL_CST:
534 /* Code copied from print_node. */
536 REAL_VALUE_TYPE d;
537 if (TREE_OVERFLOW (node))
538 pp_string (buffer, " overflow");
540 #if !defined(REAL_IS_NOT_DOUBLE) || defined(REAL_ARITHMETIC)
541 d = TREE_REAL_CST (node);
542 if (REAL_VALUE_ISINF (d))
543 pp_string (buffer, " Inf");
544 else if (REAL_VALUE_ISNAN (d))
545 pp_string (buffer, " Nan");
546 else
548 char string[100];
549 real_to_decimal (string, &d, sizeof (string), 0, 1);
550 pp_string (buffer, string);
552 #else
554 HOST_WIDE_INT i;
555 unsigned char *p = (unsigned char *) &TREE_REAL_CST (node);
556 pp_string (buffer, "0x");
557 for (i = 0; i < sizeof TREE_REAL_CST (node); i++)
558 output_formatted_integer (buffer, "%02x", *p++);
560 #endif
561 break;
564 case COMPLEX_CST:
565 pp_string (buffer, "__complex__ (");
566 dump_generic_node (buffer, TREE_REALPART (node), spc, flags, false);
567 pp_string (buffer, ", ");
568 dump_generic_node (buffer, TREE_IMAGPART (node), spc, flags, false);
569 pp_string (buffer, ")");
570 break;
572 case STRING_CST:
573 pp_string (buffer, "\"");
574 pretty_print_string (buffer, TREE_STRING_POINTER (node));
575 pp_string (buffer, "\"");
576 break;
578 case VECTOR_CST:
580 tree elt;
581 pp_string (buffer, "{ ");
582 for (elt = TREE_VECTOR_CST_ELTS (node); elt; elt = TREE_CHAIN (elt))
584 dump_generic_node (buffer, TREE_VALUE (elt), spc, flags, false);
585 if (TREE_CHAIN (elt))
586 pp_string (buffer, ", ");
588 pp_string (buffer, " }");
590 break;
592 case FUNCTION_TYPE:
593 break;
595 case FUNCTION_DECL:
596 case CONST_DECL:
597 dump_decl_name (buffer, node, flags);
598 break;
600 case LABEL_DECL:
601 if (DECL_NAME (node))
602 dump_decl_name (buffer, node, flags);
603 else if (LABEL_DECL_UID (node) != -1)
604 pp_printf (buffer, "<L" HOST_WIDE_INT_PRINT_DEC ">",
605 LABEL_DECL_UID (node));
606 else
607 pp_printf (buffer, "<D%u>", DECL_UID (node));
608 break;
610 case TYPE_DECL:
611 if (DECL_IS_BUILTIN (node))
613 /* Don't print the declaration of built-in types. */
614 break;
616 if (DECL_NAME (node))
617 dump_decl_name (buffer, node, flags);
618 else
620 if ((TREE_CODE (TREE_TYPE (node)) == RECORD_TYPE
621 || TREE_CODE (TREE_TYPE (node)) == UNION_TYPE)
622 && TYPE_METHODS (TREE_TYPE (node)))
624 /* The type is a c++ class: all structures have at least
625 4 methods. */
626 pp_string (buffer, "class ");
627 dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
629 else
631 pp_string (buffer,
632 (TREE_CODE (TREE_TYPE (node)) == UNION_TYPE
633 ? "union" : "struct "));
634 dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
637 break;
639 case VAR_DECL:
640 case PARM_DECL:
641 case FIELD_DECL:
642 case NAMESPACE_DECL:
643 dump_decl_name (buffer, node, flags);
644 break;
646 case RESULT_DECL:
647 pp_string (buffer, "<retval>");
648 break;
650 case COMPONENT_REF:
651 op0 = TREE_OPERAND (node, 0);
652 str = ".";
653 if (TREE_CODE (op0) == INDIRECT_REF)
655 op0 = TREE_OPERAND (op0, 0);
656 str = "->";
658 if (op_prio (op0) < op_prio (node))
659 pp_character (buffer, '(');
660 dump_generic_node (buffer, op0, spc, flags, false);
661 if (op_prio (op0) < op_prio (node))
662 pp_character (buffer, ')');
663 pp_string (buffer, str);
664 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
666 if (TREE_CODE (op0) != VALUE_HANDLE)
668 op0 = component_ref_field_offset (node);
669 if (op0 && TREE_CODE (op0) != INTEGER_CST)
671 pp_string (buffer, "{off: ");
672 dump_generic_node (buffer, op0, spc, flags, false);
673 pp_character (buffer, '}');
676 break;
678 case BIT_FIELD_REF:
679 pp_string (buffer, "BIT_FIELD_REF <");
680 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
681 pp_string (buffer, ", ");
682 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
683 pp_string (buffer, ", ");
684 dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
685 pp_string (buffer, ">");
686 break;
688 case ARRAY_REF:
689 case ARRAY_RANGE_REF:
690 op0 = TREE_OPERAND (node, 0);
691 if (op_prio (op0) < op_prio (node))
692 pp_character (buffer, '(');
693 dump_generic_node (buffer, op0, spc, flags, false);
694 if (op_prio (op0) < op_prio (node))
695 pp_character (buffer, ')');
696 pp_character (buffer, '[');
697 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
698 if (TREE_CODE (node) == ARRAY_RANGE_REF)
699 pp_string (buffer, " ...");
700 pp_character (buffer, ']');
702 op0 = array_ref_low_bound (node);
703 op1 = array_ref_element_size (node);
705 if (!integer_zerop (op0)
706 || (TYPE_SIZE_UNIT (TREE_TYPE (node))
707 && !operand_equal_p (op1, TYPE_SIZE_UNIT (TREE_TYPE (node)), 0)))
709 pp_string (buffer, "{lb: ");
710 dump_generic_node (buffer, op0, spc, flags, false);
711 pp_string (buffer, " sz: ");
712 dump_generic_node (buffer, op1, spc, flags, false);
713 pp_character (buffer, '}');
715 break;
717 case CONSTRUCTOR:
719 tree lnode;
720 bool is_struct_init = FALSE;
721 pp_character (buffer, '{');
722 lnode = CONSTRUCTOR_ELTS (node);
723 if (TREE_CODE (TREE_TYPE (node)) == RECORD_TYPE
724 || TREE_CODE (TREE_TYPE (node)) == UNION_TYPE)
725 is_struct_init = TRUE;
726 while (lnode && lnode != error_mark_node)
728 tree val;
729 if (TREE_PURPOSE (lnode) && is_struct_init)
731 pp_character (buffer, '.');
732 dump_generic_node (buffer, TREE_PURPOSE (lnode), spc, flags, false);
733 pp_string (buffer, "=");
735 val = TREE_VALUE (lnode);
736 if (val && TREE_CODE (val) == ADDR_EXPR)
737 if (TREE_CODE (TREE_OPERAND (val, 0)) == FUNCTION_DECL)
738 val = TREE_OPERAND (val, 0);
739 if (val && TREE_CODE (val) == FUNCTION_DECL)
741 dump_decl_name (buffer, val, flags);
743 else
745 dump_generic_node (buffer, TREE_VALUE (lnode), spc, flags, false);
747 lnode = TREE_CHAIN (lnode);
748 if (lnode && TREE_CODE (lnode) == TREE_LIST)
750 pp_character (buffer, ',');
751 pp_space (buffer);
754 pp_character (buffer, '}');
756 break;
758 case COMPOUND_EXPR:
760 tree *tp;
761 if (flags & TDF_SLIM)
763 pp_string (buffer, "<COMPOUND_EXPR>");
764 break;
767 dump_generic_node (buffer, TREE_OPERAND (node, 0),
768 spc, flags, dumping_stmts);
769 if (dumping_stmts)
770 newline_and_indent (buffer, spc);
771 else
773 pp_character (buffer, ',');
774 pp_space (buffer);
777 for (tp = &TREE_OPERAND (node, 1);
778 TREE_CODE (*tp) == COMPOUND_EXPR;
779 tp = &TREE_OPERAND (*tp, 1))
781 dump_generic_node (buffer, TREE_OPERAND (*tp, 0),
782 spc, flags, dumping_stmts);
783 if (dumping_stmts)
784 newline_and_indent (buffer, spc);
785 else
787 pp_character (buffer, ',');
788 pp_space (buffer);
792 dump_generic_node (buffer, *tp, spc, flags, dumping_stmts);
794 break;
796 case STATEMENT_LIST:
798 tree_stmt_iterator si;
799 bool first = true;
801 if ((flags & TDF_SLIM) || !dumping_stmts)
803 pp_string (buffer, "<STATEMENT_LIST>");
804 break;
807 for (si = tsi_start (node); !tsi_end_p (si); tsi_next (&si))
809 if (!first)
810 newline_and_indent (buffer, spc);
811 else
812 first = false;
813 dump_generic_node (buffer, tsi_stmt (si), spc, flags, true);
816 break;
818 case MODIFY_EXPR:
819 case INIT_EXPR:
820 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
821 pp_space (buffer);
822 pp_character (buffer, '=');
823 pp_space (buffer);
824 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
825 break;
827 case TARGET_EXPR:
828 pp_string (buffer, "TARGET_EXPR <");
829 dump_generic_node (buffer, TARGET_EXPR_SLOT (node), spc, flags, false);
830 pp_character (buffer, ',');
831 pp_space (buffer);
832 dump_generic_node (buffer, TARGET_EXPR_INITIAL (node), spc, flags, false);
833 pp_character (buffer, '>');
834 break;
836 case DECL_EXPR:
837 print_declaration (buffer, DECL_EXPR_DECL (node), spc, flags);
838 is_stmt = false;
839 break;
841 case COND_EXPR:
842 if (TREE_TYPE (node) == NULL || TREE_TYPE (node) == void_type_node)
844 pp_string (buffer, "if (");
845 dump_generic_node (buffer, COND_EXPR_COND (node), spc, flags, false);
846 pp_character (buffer, ')');
847 /* The lowered cond_exprs should always be printed in full. */
848 if (COND_EXPR_THEN (node)
849 && (IS_EMPTY_STMT (COND_EXPR_THEN (node))
850 || TREE_CODE (COND_EXPR_THEN (node)) == GOTO_EXPR)
851 && COND_EXPR_ELSE (node)
852 && (IS_EMPTY_STMT (COND_EXPR_ELSE (node))
853 || TREE_CODE (COND_EXPR_ELSE (node)) == GOTO_EXPR))
855 pp_space (buffer);
856 dump_generic_node (buffer, COND_EXPR_THEN (node), 0, flags, true);
857 pp_string (buffer, " else ");
858 dump_generic_node (buffer, COND_EXPR_ELSE (node), 0, flags, true);
860 else if (!(flags & TDF_SLIM))
862 /* Output COND_EXPR_THEN. */
863 if (COND_EXPR_THEN (node))
865 newline_and_indent (buffer, spc+2);
866 pp_character (buffer, '{');
867 newline_and_indent (buffer, spc+4);
868 dump_generic_node (buffer, COND_EXPR_THEN (node), spc+4,
869 flags, true);
870 newline_and_indent (buffer, spc+2);
871 pp_character (buffer, '}');
874 /* Output COND_EXPR_ELSE. */
875 if (COND_EXPR_ELSE (node))
877 newline_and_indent (buffer, spc);
878 pp_string (buffer, "else");
879 newline_and_indent (buffer, spc+2);
880 pp_character (buffer, '{');
881 newline_and_indent (buffer, spc+4);
882 dump_generic_node (buffer, COND_EXPR_ELSE (node), spc+4,
883 flags, true);
884 newline_and_indent (buffer, spc+2);
885 pp_character (buffer, '}');
888 is_expr = false;
890 else
892 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
893 pp_space (buffer);
894 pp_character (buffer, '?');
895 pp_space (buffer);
896 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
897 pp_space (buffer);
898 pp_character (buffer, ':');
899 pp_space (buffer);
900 dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
902 break;
904 case BIND_EXPR:
905 pp_character (buffer, '{');
906 if (!(flags & TDF_SLIM))
908 if (BIND_EXPR_VARS (node))
910 pp_newline (buffer);
912 for (op0 = BIND_EXPR_VARS (node); op0; op0 = TREE_CHAIN (op0))
914 print_declaration (buffer, op0, spc+2, flags);
915 pp_newline (buffer);
919 newline_and_indent (buffer, spc+2);
920 dump_generic_node (buffer, BIND_EXPR_BODY (node), spc+2, flags, true);
921 newline_and_indent (buffer, spc);
922 pp_character (buffer, '}');
924 is_expr = false;
925 break;
927 case CALL_EXPR:
928 print_call_name (buffer, node);
930 /* Print parameters. */
931 pp_space (buffer);
932 pp_character (buffer, '(');
933 op1 = TREE_OPERAND (node, 1);
934 if (op1)
935 dump_generic_node (buffer, op1, spc, flags, false);
936 pp_character (buffer, ')');
938 op1 = TREE_OPERAND (node, 2);
939 if (op1)
941 pp_string (buffer, " [static-chain: ");
942 dump_generic_node (buffer, op1, spc, flags, false);
943 pp_character (buffer, ']');
946 if (CALL_EXPR_HAS_RETURN_SLOT_ADDR (node))
947 pp_string (buffer, " [return slot addr]");
948 if (CALL_EXPR_TAILCALL (node))
949 pp_string (buffer, " [tail call]");
950 break;
952 case WITH_CLEANUP_EXPR:
953 NIY;
954 break;
956 case CLEANUP_POINT_EXPR:
957 pp_string (buffer, "<<cleanup_point ");
958 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
959 pp_string (buffer, ">>");
960 break;
962 case PLACEHOLDER_EXPR:
963 pp_string (buffer, "<PLACEHOLDER_EXPR ");
964 dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
965 pp_character (buffer, '>');
966 break;
968 /* Binary arithmetic and logic expressions. */
969 case MULT_EXPR:
970 case PLUS_EXPR:
971 case MINUS_EXPR:
972 case TRUNC_DIV_EXPR:
973 case CEIL_DIV_EXPR:
974 case FLOOR_DIV_EXPR:
975 case ROUND_DIV_EXPR:
976 case TRUNC_MOD_EXPR:
977 case CEIL_MOD_EXPR:
978 case FLOOR_MOD_EXPR:
979 case ROUND_MOD_EXPR:
980 case RDIV_EXPR:
981 case EXACT_DIV_EXPR:
982 case LSHIFT_EXPR:
983 case RSHIFT_EXPR:
984 case LROTATE_EXPR:
985 case RROTATE_EXPR:
986 case BIT_IOR_EXPR:
987 case BIT_XOR_EXPR:
988 case BIT_AND_EXPR:
989 case TRUTH_ANDIF_EXPR:
990 case TRUTH_ORIF_EXPR:
991 case TRUTH_AND_EXPR:
992 case TRUTH_OR_EXPR:
993 case TRUTH_XOR_EXPR:
994 case LT_EXPR:
995 case LE_EXPR:
996 case GT_EXPR:
997 case GE_EXPR:
998 case EQ_EXPR:
999 case NE_EXPR:
1000 case UNLT_EXPR:
1001 case UNLE_EXPR:
1002 case UNGT_EXPR:
1003 case UNGE_EXPR:
1004 case UNEQ_EXPR:
1005 case LTGT_EXPR:
1006 case ORDERED_EXPR:
1007 case UNORDERED_EXPR:
1009 const char *op = op_symbol (node);
1010 op0 = TREE_OPERAND (node, 0);
1011 op1 = TREE_OPERAND (node, 1);
1013 /* When the operands are expressions with less priority,
1014 keep semantics of the tree representation. */
1015 if (op_prio (op0) < op_prio (node))
1017 pp_character (buffer, '(');
1018 dump_generic_node (buffer, op0, spc, flags, false);
1019 pp_character (buffer, ')');
1021 else
1022 dump_generic_node (buffer, op0, spc, flags, false);
1024 pp_space (buffer);
1025 pp_string (buffer, op);
1026 pp_space (buffer);
1028 /* When the operands are expressions with less priority,
1029 keep semantics of the tree representation. */
1030 if (op_prio (op1) < op_prio (node))
1032 pp_character (buffer, '(');
1033 dump_generic_node (buffer, op1, spc, flags, false);
1034 pp_character (buffer, ')');
1036 else
1037 dump_generic_node (buffer, op1, spc, flags, false);
1039 break;
1041 /* Unary arithmetic and logic expressions. */
1042 case NEGATE_EXPR:
1043 case BIT_NOT_EXPR:
1044 case TRUTH_NOT_EXPR:
1045 case ADDR_EXPR:
1046 case PREDECREMENT_EXPR:
1047 case PREINCREMENT_EXPR:
1048 case ALIGN_INDIRECT_REF:
1049 case MISALIGNED_INDIRECT_REF:
1050 case INDIRECT_REF:
1051 if (TREE_CODE (node) == ADDR_EXPR
1052 && (TREE_CODE (TREE_OPERAND (node, 0)) == STRING_CST
1053 || TREE_CODE (TREE_OPERAND (node, 0)) == FUNCTION_DECL))
1054 ; /* Do not output '&' for strings and function pointers. */
1055 else
1056 pp_string (buffer, op_symbol (node));
1058 if (op_prio (TREE_OPERAND (node, 0)) < op_prio (node))
1060 pp_character (buffer, '(');
1061 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1062 pp_character (buffer, ')');
1064 else
1065 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1067 if (TREE_CODE (node) == MISALIGNED_INDIRECT_REF)
1069 pp_string (buffer, "{misalignment: ");
1070 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1071 pp_character (buffer, '}');
1073 break;
1075 case POSTDECREMENT_EXPR:
1076 case POSTINCREMENT_EXPR:
1077 if (op_prio (TREE_OPERAND (node, 0)) < op_prio (node))
1079 pp_character (buffer, '(');
1080 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1081 pp_character (buffer, ')');
1083 else
1084 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1085 pp_string (buffer, op_symbol (node));
1086 break;
1088 case MIN_EXPR:
1089 pp_string (buffer, "MIN_EXPR <");
1090 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1091 pp_string (buffer, ", ");
1092 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1093 pp_character (buffer, '>');
1094 break;
1096 case MAX_EXPR:
1097 pp_string (buffer, "MAX_EXPR <");
1098 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1099 pp_string (buffer, ", ");
1100 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1101 pp_character (buffer, '>');
1102 break;
1104 case ABS_EXPR:
1105 pp_string (buffer, "ABS_EXPR <");
1106 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1107 pp_character (buffer, '>');
1108 break;
1110 case RANGE_EXPR:
1111 NIY;
1112 break;
1114 case FIX_TRUNC_EXPR:
1115 case FIX_CEIL_EXPR:
1116 case FIX_FLOOR_EXPR:
1117 case FIX_ROUND_EXPR:
1118 case FLOAT_EXPR:
1119 case CONVERT_EXPR:
1120 case NOP_EXPR:
1121 type = TREE_TYPE (node);
1122 op0 = TREE_OPERAND (node, 0);
1123 if (type != TREE_TYPE (op0))
1125 pp_character (buffer, '(');
1126 dump_generic_node (buffer, type, spc, flags, false);
1127 pp_string (buffer, ") ");
1129 if (op_prio (op0) < op_prio (node))
1130 pp_character (buffer, '(');
1131 dump_generic_node (buffer, op0, spc, flags, false);
1132 if (op_prio (op0) < op_prio (node))
1133 pp_character (buffer, ')');
1134 break;
1136 case VIEW_CONVERT_EXPR:
1137 pp_string (buffer, "VIEW_CONVERT_EXPR<");
1138 dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
1139 pp_string (buffer, ">(");
1140 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1141 pp_character (buffer, ')');
1142 break;
1144 case NON_LVALUE_EXPR:
1145 pp_string (buffer, "NON_LVALUE_EXPR <");
1146 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1147 pp_character (buffer, '>');
1148 break;
1150 case SAVE_EXPR:
1151 pp_string (buffer, "SAVE_EXPR <");
1152 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1153 pp_character (buffer, '>');
1154 break;
1156 case COMPLEX_EXPR:
1157 pp_string (buffer, "COMPLEX_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_string (buffer, ">");
1162 break;
1164 case CONJ_EXPR:
1165 pp_string (buffer, "CONJ_EXPR <");
1166 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1167 pp_string (buffer, ">");
1168 break;
1170 case REALPART_EXPR:
1171 pp_string (buffer, "REALPART_EXPR <");
1172 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1173 pp_string (buffer, ">");
1174 break;
1176 case IMAGPART_EXPR:
1177 pp_string (buffer, "IMAGPART_EXPR <");
1178 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1179 pp_string (buffer, ">");
1180 break;
1182 case VA_ARG_EXPR:
1183 pp_string (buffer, "VA_ARG_EXPR <");
1184 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1185 pp_string (buffer, ">");
1186 break;
1188 case TRY_FINALLY_EXPR:
1189 case TRY_CATCH_EXPR:
1190 pp_string (buffer, "try");
1191 newline_and_indent (buffer, spc+2);
1192 pp_string (buffer, "{");
1193 newline_and_indent (buffer, spc+4);
1194 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc+4, flags, true);
1195 newline_and_indent (buffer, spc+2);
1196 pp_string (buffer, "}");
1197 newline_and_indent (buffer, spc);
1198 pp_string (buffer,
1199 (TREE_CODE (node) == TRY_CATCH_EXPR) ? "catch" : "finally");
1200 newline_and_indent (buffer, spc+2);
1201 pp_string (buffer, "{");
1202 newline_and_indent (buffer, spc+4);
1203 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc+4, flags, true);
1204 newline_and_indent (buffer, spc+2);
1205 pp_string (buffer, "}");
1206 is_expr = false;
1207 break;
1209 case CATCH_EXPR:
1210 pp_string (buffer, "catch (");
1211 dump_generic_node (buffer, CATCH_TYPES (node), spc+2, flags, false);
1212 pp_string (buffer, ")");
1213 newline_and_indent (buffer, spc+2);
1214 pp_string (buffer, "{");
1215 newline_and_indent (buffer, spc+4);
1216 dump_generic_node (buffer, CATCH_BODY (node), spc+4, flags, true);
1217 newline_and_indent (buffer, spc+2);
1218 pp_string (buffer, "}");
1219 is_expr = false;
1220 break;
1222 case EH_FILTER_EXPR:
1223 pp_string (buffer, "<<<eh_filter (");
1224 dump_generic_node (buffer, EH_FILTER_TYPES (node), spc+2, flags, false);
1225 pp_string (buffer, ")>>>");
1226 newline_and_indent (buffer, spc+2);
1227 pp_string (buffer, "{");
1228 newline_and_indent (buffer, spc+4);
1229 dump_generic_node (buffer, EH_FILTER_FAILURE (node), spc+4, flags, true);
1230 newline_and_indent (buffer, spc+2);
1231 pp_string (buffer, "}");
1232 is_expr = false;
1233 break;
1235 case LABEL_EXPR:
1236 op0 = TREE_OPERAND (node, 0);
1237 /* If this is for break or continue, don't bother printing it. */
1238 if (DECL_NAME (op0))
1240 const char *name = IDENTIFIER_POINTER (DECL_NAME (op0));
1241 if (strcmp (name, "break") == 0
1242 || strcmp (name, "continue") == 0)
1243 break;
1245 dump_generic_node (buffer, op0, spc, flags, false);
1246 pp_character (buffer, ':');
1247 if (DECL_NONLOCAL (op0))
1248 pp_string (buffer, " [non-local]");
1249 break;
1251 case EXC_PTR_EXPR:
1252 pp_string (buffer, "<<<exception object>>>");
1253 break;
1255 case FILTER_EXPR:
1256 pp_string (buffer, "<<<filter object>>>");
1257 break;
1259 case LOOP_EXPR:
1260 pp_string (buffer, "while (1)");
1261 if (!(flags & TDF_SLIM))
1263 newline_and_indent (buffer, spc+2);
1264 pp_character (buffer, '{');
1265 newline_and_indent (buffer, spc+4);
1266 dump_generic_node (buffer, LOOP_EXPR_BODY (node), spc+4, flags, true);
1267 newline_and_indent (buffer, spc+2);
1268 pp_character (buffer, '}');
1270 is_expr = false;
1271 break;
1273 case RETURN_EXPR:
1274 pp_string (buffer, "return");
1275 op0 = TREE_OPERAND (node, 0);
1276 if (op0)
1278 pp_space (buffer);
1279 if (TREE_CODE (op0) == MODIFY_EXPR)
1280 dump_generic_node (buffer, TREE_OPERAND (op0, 1), spc, flags, false);
1281 else
1282 dump_generic_node (buffer, op0, spc, flags, false);
1284 break;
1286 case EXIT_EXPR:
1287 pp_string (buffer, "if (");
1288 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1289 pp_string (buffer, ") break");
1290 break;
1292 case SWITCH_EXPR:
1293 pp_string (buffer, "switch (");
1294 dump_generic_node (buffer, SWITCH_COND (node), spc, flags, false);
1295 pp_character (buffer, ')');
1296 if (!(flags & TDF_SLIM))
1298 newline_and_indent (buffer, spc+2);
1299 pp_character (buffer, '{');
1300 if (SWITCH_BODY (node))
1302 newline_and_indent (buffer, spc+4);
1303 dump_generic_node (buffer, SWITCH_BODY (node), spc+4, flags, true);
1305 else
1307 tree vec = SWITCH_LABELS (node);
1308 size_t i, n = TREE_VEC_LENGTH (vec);
1309 for (i = 0; i < n; ++i)
1311 tree elt = TREE_VEC_ELT (vec, i);
1312 newline_and_indent (buffer, spc+4);
1313 dump_generic_node (buffer, elt, spc+4, flags, false);
1314 pp_string (buffer, " goto ");
1315 dump_generic_node (buffer, CASE_LABEL (elt), spc+4, flags, true);
1316 pp_semicolon (buffer);
1319 newline_and_indent (buffer, spc+2);
1320 pp_character (buffer, '}');
1322 is_expr = false;
1323 break;
1325 case GOTO_EXPR:
1326 op0 = GOTO_DESTINATION (node);
1327 if (TREE_CODE (op0) != SSA_NAME && DECL_P (op0) && DECL_NAME (op0))
1329 const char *name = IDENTIFIER_POINTER (DECL_NAME (op0));
1330 if (strcmp (name, "break") == 0
1331 || strcmp (name, "continue") == 0)
1333 pp_string (buffer, name);
1334 break;
1337 pp_string (buffer, "goto ");
1338 dump_generic_node (buffer, op0, spc, flags, false);
1339 break;
1341 case RESX_EXPR:
1342 pp_string (buffer, "resx");
1343 /* ??? Any sensible way to present the eh region? */
1344 break;
1346 case ASM_EXPR:
1347 pp_string (buffer, "__asm__");
1348 if (ASM_VOLATILE_P (node))
1349 pp_string (buffer, " __volatile__");
1350 pp_character (buffer, '(');
1351 dump_generic_node (buffer, ASM_STRING (node), spc, flags, false);
1352 pp_character (buffer, ':');
1353 dump_generic_node (buffer, ASM_OUTPUTS (node), spc, flags, false);
1354 pp_character (buffer, ':');
1355 dump_generic_node (buffer, ASM_INPUTS (node), spc, flags, false);
1356 if (ASM_CLOBBERS (node))
1358 pp_character (buffer, ':');
1359 dump_generic_node (buffer, ASM_CLOBBERS (node), spc, flags, false);
1361 pp_string (buffer, ")");
1362 break;
1364 case CASE_LABEL_EXPR:
1365 if (CASE_LOW (node) && CASE_HIGH (node))
1367 pp_string (buffer, "case ");
1368 dump_generic_node (buffer, CASE_LOW (node), spc, flags, false);
1369 pp_string (buffer, " ... ");
1370 dump_generic_node (buffer, CASE_HIGH (node), spc, flags, false);
1372 else if (CASE_LOW (node))
1374 pp_string (buffer, "case ");
1375 dump_generic_node (buffer, CASE_LOW (node), spc, flags, false);
1377 else
1378 pp_string (buffer, "default ");
1379 pp_character (buffer, ':');
1380 break;
1382 case OBJ_TYPE_REF:
1383 pp_string (buffer, "OBJ_TYPE_REF(");
1384 dump_generic_node (buffer, OBJ_TYPE_REF_EXPR (node), spc, flags, false);
1385 pp_character (buffer, ';');
1386 dump_generic_node (buffer, OBJ_TYPE_REF_OBJECT (node), spc, flags, false);
1387 pp_character (buffer, '-');
1388 pp_character (buffer, '>');
1389 dump_generic_node (buffer, OBJ_TYPE_REF_TOKEN (node), spc, flags, false);
1390 pp_character (buffer, ')');
1391 break;
1393 case PHI_NODE:
1395 int i;
1397 dump_generic_node (buffer, PHI_RESULT (node), spc, flags, false);
1398 pp_string (buffer, " = PHI <");
1399 for (i = 0; i < PHI_NUM_ARGS (node); i++)
1401 dump_generic_node (buffer, PHI_ARG_DEF (node, i), spc, flags, false);
1402 pp_string (buffer, "(");
1403 pp_decimal_int (buffer, PHI_ARG_EDGE (node, i)->src->index);
1404 pp_string (buffer, ")");
1405 if (i < PHI_NUM_ARGS (node) - 1)
1406 pp_string (buffer, ", ");
1408 pp_string (buffer, ">;");
1410 break;
1412 case SSA_NAME:
1413 dump_generic_node (buffer, SSA_NAME_VAR (node), spc, flags, false);
1414 pp_string (buffer, "_");
1415 pp_decimal_int (buffer, SSA_NAME_VERSION (node));
1416 break;
1418 case WITH_SIZE_EXPR:
1419 pp_string (buffer, "WITH_SIZE_EXPR <");
1420 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1421 pp_string (buffer, ", ");
1422 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1423 pp_string (buffer, ">");
1424 break;
1426 case VALUE_HANDLE:
1427 pp_printf (buffer, "VH.%d", VALUE_HANDLE_ID (node));
1428 break;
1430 case SCEV_KNOWN:
1431 pp_string (buffer, "scev_known");
1432 break;
1434 case SCEV_NOT_KNOWN:
1435 pp_string (buffer, "scev_not_known");
1436 break;
1438 case POLYNOMIAL_CHREC:
1439 pp_string (buffer, "{");
1440 dump_generic_node (buffer, CHREC_LEFT (node), spc, flags, false);
1441 pp_string (buffer, ", +, ");
1442 dump_generic_node (buffer, CHREC_RIGHT (node), spc, flags, false);
1443 pp_string (buffer, "}_");
1444 dump_generic_node (buffer, CHREC_VAR (node), spc, flags, false);
1445 is_stmt = false;
1446 break;
1448 case REALIGN_LOAD_EXPR:
1449 pp_string (buffer, "REALIGN_LOAD <");
1450 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1451 pp_string (buffer, ", ");
1452 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1453 pp_string (buffer, ", ");
1454 dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
1455 pp_string (buffer, ">");
1456 break;
1458 case VEC_COND_EXPR:
1459 pp_string (buffer, " VEC_COND_EXPR < ");
1460 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1461 pp_string (buffer, " , ");
1462 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1463 pp_string (buffer, " , ");
1464 dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
1465 pp_string (buffer, " > ");
1466 break;
1468 default:
1469 NIY;
1472 if (is_stmt && is_expr)
1473 pp_semicolon (buffer);
1474 pp_write_text_to_stream (buffer);
1476 return spc;
1479 /* Print the declaration of a variable. */
1481 static void
1482 print_declaration (pretty_printer *buffer, tree t, int spc, int flags)
1484 INDENT (spc);
1486 if (TREE_CODE (t) == TYPE_DECL)
1487 pp_string (buffer, "typedef ");
1489 if (DECL_REGISTER (t))
1490 pp_string (buffer, "register ");
1492 if (TREE_PUBLIC (t) && DECL_EXTERNAL (t))
1493 pp_string (buffer, "extern ");
1494 else if (TREE_STATIC (t))
1495 pp_string (buffer, "static ");
1497 /* Print the type and name. */
1498 if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
1500 tree tmp;
1502 /* Print array's type. */
1503 tmp = TREE_TYPE (t);
1504 while (TREE_CODE (TREE_TYPE (tmp)) == ARRAY_TYPE)
1505 tmp = TREE_TYPE (tmp);
1506 dump_generic_node (buffer, TREE_TYPE (tmp), spc, flags, false);
1508 /* Print variable's name. */
1509 pp_space (buffer);
1510 dump_generic_node (buffer, t, spc, flags, false);
1512 /* Print the dimensions. */
1513 tmp = TREE_TYPE (t);
1514 while (TREE_CODE (tmp) == ARRAY_TYPE)
1516 dump_array_domain (buffer, TYPE_DOMAIN (tmp), spc, flags);
1517 tmp = TREE_TYPE (tmp);
1520 else if (TREE_CODE (t) == FUNCTION_DECL)
1522 dump_generic_node (buffer, TREE_TYPE (TREE_TYPE (t)), spc, flags, false);
1523 pp_space (buffer);
1524 dump_decl_name (buffer, t, flags);
1525 dump_function_declaration (buffer, TREE_TYPE (t), spc, flags);
1527 else
1529 /* Print type declaration. */
1530 dump_generic_node (buffer, TREE_TYPE (t), spc, flags, false);
1532 /* Print variable's name. */
1533 pp_space (buffer);
1534 dump_generic_node (buffer, t, spc, flags, false);
1537 if (TREE_CODE (t) == VAR_DECL && DECL_HARD_REGISTER (t))
1539 pp_string (buffer, " __asm__ ");
1540 pp_character (buffer, '(');
1541 dump_generic_node (buffer, DECL_ASSEMBLER_NAME (t), spc, flags, false);
1542 pp_character (buffer, ')');
1545 /* The initial value of a function serves to determine wether the function
1546 is declared or defined. So the following does not apply to function
1547 nodes. */
1548 if (TREE_CODE (t) != FUNCTION_DECL)
1550 /* Print the initial value. */
1551 if (DECL_INITIAL (t))
1553 pp_space (buffer);
1554 pp_character (buffer, '=');
1555 pp_space (buffer);
1556 dump_generic_node (buffer, DECL_INITIAL (t), spc, flags, false);
1560 pp_character (buffer, ';');
1564 /* Prints a structure: name, fields, and methods.
1565 FIXME: Still incomplete. */
1567 static void
1568 print_struct_decl (pretty_printer *buffer, tree node, int spc, int flags)
1570 /* Print the name of the structure. */
1571 if (TYPE_NAME (node))
1573 INDENT (spc);
1574 if (TREE_CODE (node) == RECORD_TYPE)
1575 pp_string (buffer, "struct ");
1576 else if ((TREE_CODE (node) == UNION_TYPE
1577 || TREE_CODE (node) == QUAL_UNION_TYPE))
1578 pp_string (buffer, "union ");
1580 dump_generic_node (buffer, TYPE_NAME (node), spc, 0, false);
1583 /* Print the contents of the structure. */
1584 pp_newline (buffer);
1585 INDENT (spc);
1586 pp_character (buffer, '{');
1587 pp_newline (buffer);
1589 /* Print the fields of the structure. */
1591 tree tmp;
1592 tmp = TYPE_FIELDS (node);
1593 while (tmp)
1595 /* Avoid to print recursively the structure. */
1596 /* FIXME : Not implemented correctly...,
1597 what about the case when we have a cycle in the contain graph? ...
1598 Maybe this could be solved by looking at the scope in which the
1599 structure was declared. */
1600 if (TREE_TYPE (tmp) != node
1601 || (TREE_CODE (TREE_TYPE (tmp)) == POINTER_TYPE
1602 && TREE_TYPE (TREE_TYPE (tmp)) != node))
1604 print_declaration (buffer, tmp, spc+2, flags);
1605 pp_newline (buffer);
1607 tmp = TREE_CHAIN (tmp);
1610 INDENT (spc);
1611 pp_character (buffer, '}');
1614 /* Return the priority of the operator OP.
1616 From lowest to highest precedence with either left-to-right (L-R)
1617 or right-to-left (R-L) associativity]:
1619 1 [L-R] ,
1620 2 [R-L] = += -= *= /= %= &= ^= |= <<= >>=
1621 3 [R-L] ?:
1622 4 [L-R] ||
1623 5 [L-R] &&
1624 6 [L-R] |
1625 7 [L-R] ^
1626 8 [L-R] &
1627 9 [L-R] == !=
1628 10 [L-R] < <= > >=
1629 11 [L-R] << >>
1630 12 [L-R] + -
1631 13 [L-R] * / %
1632 14 [R-L] ! ~ ++ -- + - * & (type) sizeof
1633 15 [L-R] fn() [] -> .
1635 unary +, - and * have higher precedence than the corresponding binary
1636 operators. */
1638 static int
1639 op_prio (tree op)
1641 if (op == NULL)
1642 return 9999;
1644 switch (TREE_CODE (op))
1646 case TREE_LIST:
1647 case COMPOUND_EXPR:
1648 case BIND_EXPR:
1649 return 1;
1651 case MODIFY_EXPR:
1652 case INIT_EXPR:
1653 return 2;
1655 case COND_EXPR:
1656 return 3;
1658 case TRUTH_OR_EXPR:
1659 case TRUTH_ORIF_EXPR:
1660 return 4;
1662 case TRUTH_AND_EXPR:
1663 case TRUTH_ANDIF_EXPR:
1664 return 5;
1666 case BIT_IOR_EXPR:
1667 return 6;
1669 case BIT_XOR_EXPR:
1670 case TRUTH_XOR_EXPR:
1671 return 7;
1673 case BIT_AND_EXPR:
1674 return 8;
1676 case EQ_EXPR:
1677 case NE_EXPR:
1678 return 9;
1680 case UNLT_EXPR:
1681 case UNLE_EXPR:
1682 case UNGT_EXPR:
1683 case UNGE_EXPR:
1684 case UNEQ_EXPR:
1685 case LTGT_EXPR:
1686 case ORDERED_EXPR:
1687 case UNORDERED_EXPR:
1688 case LT_EXPR:
1689 case LE_EXPR:
1690 case GT_EXPR:
1691 case GE_EXPR:
1692 return 10;
1694 case LSHIFT_EXPR:
1695 case RSHIFT_EXPR:
1696 case LROTATE_EXPR:
1697 case RROTATE_EXPR:
1698 return 11;
1700 case PLUS_EXPR:
1701 case MINUS_EXPR:
1702 return 12;
1704 case MULT_EXPR:
1705 case TRUNC_DIV_EXPR:
1706 case CEIL_DIV_EXPR:
1707 case FLOOR_DIV_EXPR:
1708 case ROUND_DIV_EXPR:
1709 case RDIV_EXPR:
1710 case EXACT_DIV_EXPR:
1711 case TRUNC_MOD_EXPR:
1712 case CEIL_MOD_EXPR:
1713 case FLOOR_MOD_EXPR:
1714 case ROUND_MOD_EXPR:
1715 return 13;
1717 case TRUTH_NOT_EXPR:
1718 case BIT_NOT_EXPR:
1719 case POSTINCREMENT_EXPR:
1720 case POSTDECREMENT_EXPR:
1721 case PREINCREMENT_EXPR:
1722 case PREDECREMENT_EXPR:
1723 case NEGATE_EXPR:
1724 case ALIGN_INDIRECT_REF:
1725 case MISALIGNED_INDIRECT_REF:
1726 case INDIRECT_REF:
1727 case ADDR_EXPR:
1728 case FLOAT_EXPR:
1729 case NOP_EXPR:
1730 case CONVERT_EXPR:
1731 case FIX_TRUNC_EXPR:
1732 case FIX_CEIL_EXPR:
1733 case FIX_FLOOR_EXPR:
1734 case FIX_ROUND_EXPR:
1735 case TARGET_EXPR:
1736 return 14;
1738 case CALL_EXPR:
1739 case ARRAY_REF:
1740 case ARRAY_RANGE_REF:
1741 case COMPONENT_REF:
1742 return 15;
1744 /* Special expressions. */
1745 case MIN_EXPR:
1746 case MAX_EXPR:
1747 case ABS_EXPR:
1748 case REALPART_EXPR:
1749 case IMAGPART_EXPR:
1750 return 16;
1752 case SAVE_EXPR:
1753 case NON_LVALUE_EXPR:
1754 return op_prio (TREE_OPERAND (op, 0));
1756 default:
1757 /* Return an arbitrarily high precedence to avoid surrounding single
1758 VAR_DECLs in ()s. */
1759 return 9999;
1764 /* Return the symbol associated with operator OP. */
1766 static const char *
1767 op_symbol (tree op)
1769 gcc_assert (op);
1771 switch (TREE_CODE (op))
1773 case MODIFY_EXPR:
1774 return "=";
1776 case TRUTH_OR_EXPR:
1777 case TRUTH_ORIF_EXPR:
1778 return "||";
1780 case TRUTH_AND_EXPR:
1781 case TRUTH_ANDIF_EXPR:
1782 return "&&";
1784 case BIT_IOR_EXPR:
1785 return "|";
1787 case TRUTH_XOR_EXPR:
1788 case BIT_XOR_EXPR:
1789 return "^";
1791 case ADDR_EXPR:
1792 case BIT_AND_EXPR:
1793 return "&";
1795 case ORDERED_EXPR:
1796 return "ord";
1797 case UNORDERED_EXPR:
1798 return "unord";
1800 case EQ_EXPR:
1801 return "==";
1802 case UNEQ_EXPR:
1803 return "u==";
1805 case NE_EXPR:
1806 return "!=";
1808 case LT_EXPR:
1809 return "<";
1810 case UNLT_EXPR:
1811 return "u<";
1813 case LE_EXPR:
1814 return "<=";
1815 case UNLE_EXPR:
1816 return "u<=";
1818 case GT_EXPR:
1819 return ">";
1820 case UNGT_EXPR:
1821 return "u>";
1823 case GE_EXPR:
1824 return ">=";
1825 case UNGE_EXPR:
1826 return "u>=";
1828 case LTGT_EXPR:
1829 return "<>";
1831 case LSHIFT_EXPR:
1832 return "<<";
1834 case RSHIFT_EXPR:
1835 return ">>";
1837 case PLUS_EXPR:
1838 return "+";
1840 case NEGATE_EXPR:
1841 case MINUS_EXPR:
1842 return "-";
1844 case BIT_NOT_EXPR:
1845 return "~";
1847 case TRUTH_NOT_EXPR:
1848 return "!";
1850 case MULT_EXPR:
1851 case INDIRECT_REF:
1852 return "*";
1854 case ALIGN_INDIRECT_REF:
1855 return "A*";
1857 case MISALIGNED_INDIRECT_REF:
1858 return "M*";
1860 case TRUNC_DIV_EXPR:
1861 case RDIV_EXPR:
1862 return "/";
1864 case CEIL_DIV_EXPR:
1865 return "/[cl]";
1867 case FLOOR_DIV_EXPR:
1868 return "/[fl]";
1870 case ROUND_DIV_EXPR:
1871 return "/[rd]";
1873 case EXACT_DIV_EXPR:
1874 return "/[ex]";
1876 case TRUNC_MOD_EXPR:
1877 return "%";
1879 case CEIL_MOD_EXPR:
1880 return "%[cl]";
1882 case FLOOR_MOD_EXPR:
1883 return "%[fl]";
1885 case ROUND_MOD_EXPR:
1886 return "%[rd]";
1888 case PREDECREMENT_EXPR:
1889 return " --";
1891 case PREINCREMENT_EXPR:
1892 return " ++";
1894 case POSTDECREMENT_EXPR:
1895 return "-- ";
1897 case POSTINCREMENT_EXPR:
1898 return "++ ";
1900 default:
1901 return "<<< ??? >>>";
1905 /* Prints the name of a CALL_EXPR. */
1907 static void
1908 print_call_name (pretty_printer *buffer, tree node)
1910 tree op0;
1912 gcc_assert (TREE_CODE (node) == CALL_EXPR);
1914 op0 = TREE_OPERAND (node, 0);
1916 if (TREE_CODE (op0) == NON_LVALUE_EXPR)
1917 op0 = TREE_OPERAND (op0, 0);
1919 switch (TREE_CODE (op0))
1921 case VAR_DECL:
1922 case PARM_DECL:
1923 dump_function_name (buffer, op0);
1924 break;
1926 case ADDR_EXPR:
1927 case INDIRECT_REF:
1928 case NOP_EXPR:
1929 dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
1930 break;
1932 case COND_EXPR:
1933 pp_string (buffer, "(");
1934 dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
1935 pp_string (buffer, ") ? ");
1936 dump_generic_node (buffer, TREE_OPERAND (op0, 1), 0, 0, false);
1937 pp_string (buffer, " : ");
1938 dump_generic_node (buffer, TREE_OPERAND (op0, 2), 0, 0, false);
1939 break;
1941 case COMPONENT_REF:
1942 /* The function is a pointer contained in a structure. */
1943 if (TREE_CODE (TREE_OPERAND (op0, 0)) == INDIRECT_REF ||
1944 TREE_CODE (TREE_OPERAND (op0, 0)) == VAR_DECL)
1945 dump_function_name (buffer, TREE_OPERAND (op0, 1));
1946 else
1947 dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
1948 /* else
1949 We can have several levels of structures and a function
1950 pointer inside. This is not implemented yet... */
1951 /* NIY;*/
1952 break;
1954 case ARRAY_REF:
1955 if (TREE_CODE (TREE_OPERAND (op0, 0)) == VAR_DECL)
1956 dump_function_name (buffer, TREE_OPERAND (op0, 0));
1957 else
1958 dump_generic_node (buffer, op0, 0, 0, false);
1959 break;
1961 case SSA_NAME:
1962 case OBJ_TYPE_REF:
1963 dump_generic_node (buffer, op0, 0, 0, false);
1964 break;
1966 default:
1967 NIY;
1971 /* Parses the string STR and replaces new-lines by '\n', tabs by '\t', ... */
1973 static void
1974 pretty_print_string (pretty_printer *buffer, const char *str)
1976 if (str == NULL)
1977 return;
1979 while (*str)
1981 switch (str[0])
1983 case '\b':
1984 pp_string (buffer, "\\b");
1985 break;
1987 case '\f':
1988 pp_string (buffer, "\\f");
1989 break;
1991 case '\n':
1992 pp_string (buffer, "\\n");
1993 break;
1995 case '\r':
1996 pp_string (buffer, "\\r");
1997 break;
1999 case '\t':
2000 pp_string (buffer, "\\t");
2001 break;
2003 case '\v':
2004 pp_string (buffer, "\\v");
2005 break;
2007 case '\\':
2008 pp_string (buffer, "\\\\");
2009 break;
2011 case '\"':
2012 pp_string (buffer, "\\\"");
2013 break;
2015 case '\'':
2016 pp_string (buffer, "\\'");
2017 break;
2019 case '\0':
2020 pp_string (buffer, "\\0");
2021 break;
2023 case '\1':
2024 pp_string (buffer, "\\1");
2025 break;
2027 case '\2':
2028 pp_string (buffer, "\\2");
2029 break;
2031 case '\3':
2032 pp_string (buffer, "\\3");
2033 break;
2035 case '\4':
2036 pp_string (buffer, "\\4");
2037 break;
2039 case '\5':
2040 pp_string (buffer, "\\5");
2041 break;
2043 case '\6':
2044 pp_string (buffer, "\\6");
2045 break;
2047 case '\7':
2048 pp_string (buffer, "\\7");
2049 break;
2051 default:
2052 pp_character (buffer, str[0]);
2053 break;
2055 str++;
2059 static void
2060 maybe_init_pretty_print (FILE *file)
2062 if (!initialized)
2064 pp_construct (&buffer, /* prefix */NULL, /* line-width */0);
2065 pp_needs_newline (&buffer) = true;
2066 initialized = 1;
2069 buffer.buffer->stream = file;
2072 static void
2073 newline_and_indent (pretty_printer *buffer, int spc)
2075 pp_newline (buffer);
2076 INDENT (spc);
2079 static void
2080 dump_vops (pretty_printer *buffer, tree stmt, int spc, int flags)
2082 tree use;
2083 use_operand_p use_p;
2084 def_operand_p def_p;
2085 use_operand_p kill_p;
2086 ssa_op_iter iter;
2088 FOR_EACH_SSA_MAYDEF_OPERAND (def_p, use_p, stmt, iter)
2090 pp_string (buffer, "# ");
2091 dump_generic_node (buffer, DEF_FROM_PTR (def_p),
2092 spc + 2, flags, false);
2093 pp_string (buffer, " = V_MAY_DEF <");
2094 dump_generic_node (buffer, USE_FROM_PTR (use_p),
2095 spc + 2, flags, false);
2096 pp_string (buffer, ">;");
2097 newline_and_indent (buffer, spc);
2100 FOR_EACH_SSA_MUSTDEF_OPERAND (def_p, kill_p, stmt, iter)
2102 pp_string (buffer, "# ");
2103 dump_generic_node (buffer, DEF_FROM_PTR (def_p),
2104 spc + 2, flags, false);
2105 pp_string (buffer, " = V_MUST_DEF <");
2106 dump_generic_node (buffer, USE_FROM_PTR (kill_p),
2107 spc + 2, flags, false);
2108 pp_string (buffer, ">;");
2109 newline_and_indent (buffer, spc);
2112 FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_VUSE)
2114 pp_string (buffer, "# VUSE <");
2115 dump_generic_node (buffer, use, spc + 2, flags, false);
2116 pp_string (buffer, ">;");
2117 newline_and_indent (buffer, spc);
2121 /* Dumps basic block BB to FILE with details described by FLAGS and
2122 indented by INDENT spaces. */
2124 void
2125 dump_generic_bb (FILE *file, basic_block bb, int indent, int flags)
2127 maybe_init_pretty_print (file);
2128 dumping_stmts = true;
2129 dump_generic_bb_buff (&buffer, bb, indent, flags);
2130 pp_flush (&buffer);
2133 /* Dumps header of basic block BB to buffer BUFFER indented by INDENT
2134 spaces and details described by flags. */
2136 static void
2137 dump_bb_header (pretty_printer *buffer, basic_block bb, int indent, int flags)
2139 edge e;
2140 tree stmt;
2141 edge_iterator ei;
2143 if (flags & TDF_BLOCKS)
2145 INDENT (indent);
2146 pp_string (buffer, "# BLOCK ");
2147 pp_decimal_int (buffer, bb->index);
2149 if (flags & TDF_LINENO)
2151 block_stmt_iterator bsi;
2153 for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
2154 if (get_lineno (bsi_stmt (bsi)) != -1)
2156 pp_string (buffer, ", starting at line ");
2157 pp_decimal_int (buffer, get_lineno (bsi_stmt (bsi)));
2158 break;
2161 newline_and_indent (buffer, indent);
2163 pp_string (buffer, "# PRED:");
2164 pp_write_text_to_stream (buffer);
2165 FOR_EACH_EDGE (e, ei, bb->preds)
2166 if (flags & TDF_SLIM)
2168 pp_string (buffer, " ");
2169 if (e->src == ENTRY_BLOCK_PTR)
2170 pp_string (buffer, "ENTRY");
2171 else
2172 pp_decimal_int (buffer, e->src->index);
2174 else
2175 dump_edge_info (buffer->buffer->stream, e, 0);
2176 pp_newline (buffer);
2178 else
2180 stmt = first_stmt (bb);
2181 if (!stmt || TREE_CODE (stmt) != LABEL_EXPR)
2183 INDENT (indent - 2);
2184 pp_string (buffer, "<bb ");
2185 pp_decimal_int (buffer, bb->index);
2186 pp_string (buffer, ">:");
2187 pp_newline (buffer);
2190 pp_write_text_to_stream (buffer);
2191 check_bb_profile (bb, buffer->buffer->stream);
2194 /* Dumps end of basic block BB to buffer BUFFER indented by INDENT
2195 spaces. */
2197 static void
2198 dump_bb_end (pretty_printer *buffer, basic_block bb, int indent, int flags)
2200 edge e;
2201 edge_iterator ei;
2203 INDENT (indent);
2204 pp_string (buffer, "# SUCC:");
2205 pp_write_text_to_stream (buffer);
2206 FOR_EACH_EDGE (e, ei, bb->succs)
2207 if (flags & TDF_SLIM)
2209 pp_string (buffer, " ");
2210 if (e->dest == EXIT_BLOCK_PTR)
2211 pp_string (buffer, "EXIT");
2212 else
2213 pp_decimal_int (buffer, e->dest->index);
2215 else
2216 dump_edge_info (buffer->buffer->stream, e, 1);
2217 pp_newline (buffer);
2220 /* Dumps phi nodes of basic block BB to buffer BUFFER with details described by
2221 FLAGS indented by INDENT spaces. */
2223 static void
2224 dump_phi_nodes (pretty_printer *buffer, basic_block bb, int indent, int flags)
2226 tree phi = phi_nodes (bb);
2227 if (!phi)
2228 return;
2230 for (; phi; phi = PHI_CHAIN (phi))
2232 if (is_gimple_reg (PHI_RESULT (phi)) || (flags & TDF_VOPS))
2234 INDENT (indent);
2235 pp_string (buffer, "# ");
2236 dump_generic_node (buffer, phi, indent, flags, false);
2237 pp_newline (buffer);
2242 /* Dump jump to basic block BB that is represented implicitly in the cfg
2243 to BUFFER. */
2245 static void
2246 pp_cfg_jump (pretty_printer *buffer, basic_block bb)
2248 tree stmt;
2250 stmt = first_stmt (bb);
2252 pp_string (buffer, "goto <bb ");
2253 pp_decimal_int (buffer, bb->index);
2254 pp_string (buffer, ">");
2255 if (stmt && TREE_CODE (stmt) == LABEL_EXPR)
2257 pp_string (buffer, " (");
2258 dump_generic_node (buffer, LABEL_EXPR_LABEL (stmt), 0, 0, false);
2259 pp_string (buffer, ")");
2261 pp_semicolon (buffer);
2264 /* Dump edges represented implicitly in basic block BB to BUFFER, indented
2265 by INDENT spaces, with details given by FLAGS. */
2267 static void
2268 dump_implicit_edges (pretty_printer *buffer, basic_block bb, int indent,
2269 int flags)
2271 edge e;
2272 edge_iterator ei;
2274 /* If there is a fallthru edge, we may need to add an artificial goto to the
2275 dump. */
2276 FOR_EACH_EDGE (e, ei, bb->succs)
2277 if (e->flags & EDGE_FALLTHRU)
2278 break;
2279 if (e && e->dest != bb->next_bb)
2281 INDENT (indent);
2283 if ((flags & TDF_LINENO)
2284 #ifdef USE_MAPPED_LOCATION
2285 && e->goto_locus != UNKNOWN_LOCATION
2286 #else
2287 && e->goto_locus
2288 #endif
2291 expanded_location goto_xloc;
2292 #ifdef USE_MAPPED_LOCATION
2293 goto_xloc = expand_location (e->goto_locus);
2294 #else
2295 goto_xloc = *e->goto_locus;
2296 #endif
2297 pp_character (buffer, '[');
2298 if (goto_xloc.file)
2300 pp_string (buffer, goto_xloc.file);
2301 pp_string (buffer, " : ");
2303 pp_decimal_int (buffer, goto_xloc.line);
2304 pp_string (buffer, "] ");
2307 pp_cfg_jump (buffer, e->dest);
2308 pp_newline (buffer);
2312 /* Dumps basic block BB to buffer BUFFER with details described by FLAGS and
2313 indented by INDENT spaces. */
2315 static void
2316 dump_generic_bb_buff (pretty_printer *buffer, basic_block bb,
2317 int indent, int flags)
2319 block_stmt_iterator bsi;
2320 tree stmt;
2321 int label_indent = indent - 2;
2323 if (label_indent < 0)
2324 label_indent = 0;
2326 dump_bb_header (buffer, bb, indent, flags);
2328 if (bb_ann (bb))
2329 dump_phi_nodes (buffer, bb, indent, flags);
2331 for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
2333 int curr_indent;
2335 stmt = bsi_stmt (bsi);
2337 curr_indent = TREE_CODE (stmt) == LABEL_EXPR ? label_indent : indent;
2339 INDENT (curr_indent);
2340 dump_generic_node (buffer, stmt, curr_indent, flags, true);
2341 pp_newline (buffer);
2344 dump_implicit_edges (buffer, bb, indent, flags);
2346 if (flags & TDF_BLOCKS)
2347 dump_bb_end (buffer, bb, indent, flags);