* c-opts.c (check_deps_environment_vars): If spec != NULL, set
[official-gcc.git] / gcc / tree-pretty-print.c
blobe1e0c63db50f88ee222a3d8beef73d637e7d4ca7
1 /* Pretty formatting of GENERIC trees in C syntax.
2 Copyright (C) 2001, 2002, 2003, 2004 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 = first_rtl_op (TREE_CODE (node));
76 for (i = 0; i < len; ++i)
78 newline_and_indent (buffer, 2);
79 dump_generic_node (buffer, TREE_OPERAND (node, i), 2, 0, false);
83 pp_string (buffer, " >>>\n");
86 void
87 debug_generic_expr (tree t)
89 print_generic_expr (stderr, t, TDF_VOPS|TDF_UID);
90 fprintf (stderr, "\n");
93 void
94 debug_generic_stmt (tree t)
96 print_generic_stmt (stderr, t, TDF_VOPS|TDF_UID);
97 fprintf (stderr, "\n");
100 /* Prints declaration DECL to the FILE with details specified by FLAGS. */
101 void
102 print_generic_decl (FILE *file, tree decl, int flags)
104 maybe_init_pretty_print (file);
105 dumping_stmts = true;
106 print_declaration (&buffer, decl, 2, flags);
107 pp_write_text_to_stream (&buffer);
110 /* Print tree T, and its successors, on file FILE. FLAGS specifies details
111 to show in the dump. See TDF_* in tree.h. */
113 void
114 print_generic_stmt (FILE *file, tree t, int flags)
116 maybe_init_pretty_print (file);
117 dumping_stmts = true;
118 dump_generic_node (&buffer, t, 0, flags, true);
119 pp_flush (&buffer);
122 /* Print tree T, and its successors, on file FILE. FLAGS specifies details
123 to show in the dump. See TDF_* in tree.h. The output is indented by
124 INDENT spaces. */
126 void
127 print_generic_stmt_indented (FILE *file, tree t, int flags, int indent)
129 int i;
131 maybe_init_pretty_print (file);
132 dumping_stmts = true;
134 for (i = 0; i < indent; i++)
135 pp_space (&buffer);
136 dump_generic_node (&buffer, t, indent, flags, true);
137 pp_flush (&buffer);
140 /* Print a single expression T on file FILE. FLAGS specifies details to show
141 in the dump. See TDF_* in tree.h. */
143 void
144 print_generic_expr (FILE *file, tree t, int flags)
146 maybe_init_pretty_print (file);
147 dumping_stmts = false;
148 dump_generic_node (&buffer, t, 0, flags, false);
151 /* Dump the name of a _DECL node and its DECL_UID if TDF_UID is set
152 in FLAGS. */
154 static void
155 dump_decl_name (pretty_printer *buffer, tree node, int flags)
157 if (DECL_NAME (node))
158 pp_tree_identifier (buffer, DECL_NAME (node));
160 if ((flags & TDF_UID)
161 || DECL_NAME (node) == NULL_TREE)
163 if (TREE_CODE (node) == LABEL_DECL
164 && LABEL_DECL_UID (node) != -1)
165 pp_printf (buffer, "L." HOST_WIDE_INT_PRINT_DEC,
166 LABEL_DECL_UID (node));
167 else
169 char c = TREE_CODE (node) == CONST_DECL ? 'C' : 'D';
170 pp_printf (buffer, "%c.%u", c, DECL_UID (node));
175 /* 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 node NODE on the pretty_printer BUFFER, SPC spaces of indent.
221 FLAGS specifies details to show in the dump (see TDF_* in tree.h). If
222 IS_STMT is true, the object printed is considered to be a statement
223 and it is terminated by ';' if appropriate. */
226 dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
227 bool is_stmt)
229 tree type;
230 tree op0, op1;
231 const char *str;
232 bool is_expr;
234 if (node == NULL_TREE)
235 return spc;
237 is_expr = EXPR_P (node);
239 if (TREE_CODE (node) != ERROR_MARK
240 && is_gimple_stmt (node)
241 && (flags & TDF_VOPS)
242 && stmt_ann (node))
243 dump_vops (buffer, node, spc, flags);
245 if (dumping_stmts
246 && (flags & TDF_LINENO)
247 && EXPR_HAS_LOCATION (node))
249 expanded_location xloc = expand_location (EXPR_LOCATION (node));
250 pp_character (buffer, '[');
251 if (xloc.file)
253 pp_string (buffer, xloc.file);
254 pp_string (buffer, " : ");
256 pp_decimal_int (buffer, xloc.line);
257 pp_string (buffer, "] ");
260 switch (TREE_CODE (node))
262 case ERROR_MARK:
263 pp_string (buffer, "<<< error >>>");
264 break;
266 case IDENTIFIER_NODE:
267 pp_tree_identifier (buffer, node);
268 break;
270 case TREE_LIST:
271 while (node && node != error_mark_node)
273 if (TREE_PURPOSE (node))
275 dump_generic_node (buffer, TREE_PURPOSE (node), spc, flags, false);
276 pp_space (buffer);
278 dump_generic_node (buffer, TREE_VALUE (node), spc, flags, false);
279 node = TREE_CHAIN (node);
280 if (node && TREE_CODE (node) == TREE_LIST)
282 pp_character (buffer, ',');
283 pp_space (buffer);
286 break;
288 case TREE_BINFO:
289 dump_generic_node (buffer, BINFO_TYPE (node), spc, flags, false);
291 case TREE_VEC:
293 size_t i;
294 if (TREE_VEC_LENGTH (node) > 0)
296 size_t len = TREE_VEC_LENGTH (node);
297 for (i = 0; i < len - 1; i++)
299 dump_generic_node (buffer, TREE_VEC_ELT (node, i), spc, flags,
300 false);
301 pp_character (buffer, ',');
302 pp_space (buffer);
304 dump_generic_node (buffer, TREE_VEC_ELT (node, len - 1), spc,
305 flags, false);
308 break;
310 case BLOCK:
311 NIY;
312 break;
314 case VOID_TYPE:
315 case INTEGER_TYPE:
316 case REAL_TYPE:
317 case COMPLEX_TYPE:
318 case VECTOR_TYPE:
319 case ENUMERAL_TYPE:
320 case BOOLEAN_TYPE:
321 case CHAR_TYPE:
323 unsigned int quals = TYPE_QUALS (node);
324 enum tree_code_class class;
326 if (quals & TYPE_QUAL_CONST)
327 pp_string (buffer, "const ");
328 else if (quals & TYPE_QUAL_VOLATILE)
329 pp_string (buffer, "volatile ");
330 else if (quals & TYPE_QUAL_RESTRICT)
331 pp_string (buffer, "restrict ");
333 class = TREE_CODE_CLASS (TREE_CODE (node));
335 if (class == tcc_declaration)
337 if (DECL_NAME (node))
338 dump_decl_name (buffer, node, flags);
339 else
340 pp_string (buffer, "<unnamed type decl>");
342 else if (class == tcc_type)
344 if (TYPE_NAME (node))
346 if (TREE_CODE (TYPE_NAME (node)) == IDENTIFIER_NODE)
347 pp_tree_identifier (buffer, TYPE_NAME (node));
348 else if (TREE_CODE (TYPE_NAME (node)) == TYPE_DECL
349 && DECL_NAME (TYPE_NAME (node)))
350 dump_decl_name (buffer, TYPE_NAME (node), flags);
351 else
352 pp_string (buffer, "<unnamed type>");
354 else if (TREE_CODE (node) == VECTOR_TYPE)
356 pp_string (buffer, "vector ");
357 dump_generic_node (buffer, TREE_TYPE (node),
358 spc, flags, false);
360 else
361 pp_string (buffer, "<unnamed type>");
363 break;
366 case POINTER_TYPE:
367 case REFERENCE_TYPE:
368 str = (TREE_CODE (node) == POINTER_TYPE ? "*" : "&");
370 if (TREE_CODE (TREE_TYPE (node)) == FUNCTION_TYPE)
372 tree fnode = TREE_TYPE (node);
374 dump_generic_node (buffer, TREE_TYPE (fnode), spc, flags, false);
375 pp_space (buffer);
376 pp_character (buffer, '(');
377 pp_string (buffer, str);
378 if (TYPE_NAME (node) && DECL_NAME (TYPE_NAME (node)))
379 dump_decl_name (buffer, TYPE_NAME (node), flags);
380 else
381 pp_printf (buffer, "<T%x>", TYPE_UID (node));
383 pp_character (buffer, ')');
384 dump_function_declaration (buffer, fnode, spc, flags);
386 else
388 unsigned int quals = TYPE_QUALS (node);
390 dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
391 pp_space (buffer);
392 pp_string (buffer, str);
394 if (quals & TYPE_QUAL_CONST)
395 pp_string (buffer, " const");
396 else if (quals & TYPE_QUAL_VOLATILE)
397 pp_string (buffer, "volatile");
398 else if (quals & TYPE_QUAL_RESTRICT)
399 pp_string (buffer, " restrict");
401 if (TYPE_REF_CAN_ALIAS_ALL (node))
402 pp_string (buffer, " {ref-all}");
404 break;
406 case OFFSET_TYPE:
407 NIY;
408 break;
410 case METHOD_TYPE:
411 dump_decl_name (buffer, TYPE_NAME (TYPE_METHOD_BASETYPE (node)), flags);
412 pp_string (buffer, "::");
413 break;
415 case FILE_TYPE:
416 NIY;
417 break;
419 case ARRAY_TYPE:
421 tree tmp;
423 /* Print the innermost component type. */
424 for (tmp = TREE_TYPE (node); TREE_CODE (tmp) == ARRAY_TYPE;
425 tmp = TREE_TYPE (tmp))
427 dump_generic_node (buffer, tmp, spc, flags, false);
429 /* Print the dimensions. */
430 for (tmp = node; TREE_CODE (tmp) == ARRAY_TYPE;
431 tmp = TREE_TYPE (tmp))
433 tree domain = TYPE_DOMAIN (tmp);
435 pp_character (buffer, '[');
436 if (domain)
438 if (TYPE_MIN_VALUE (domain)
439 && !integer_zerop (TYPE_MIN_VALUE (domain)))
441 dump_generic_node (buffer, TYPE_MIN_VALUE (domain),
442 spc, flags, false);
443 pp_string (buffer, " .. ");
446 if (TYPE_MAX_VALUE (domain))
447 dump_generic_node (buffer, TYPE_MAX_VALUE (domain),
448 spc, flags, false);
450 else
451 pp_string (buffer, "<unknown>");
453 pp_character (buffer, ']');
455 break;
458 case SET_TYPE:
459 NIY;
460 break;
462 case RECORD_TYPE:
463 case UNION_TYPE:
464 case QUAL_UNION_TYPE:
465 /* Print the name of the structure. */
466 if (TREE_CODE (node) == RECORD_TYPE)
467 pp_string (buffer, "struct ");
468 else if (TREE_CODE (node) == UNION_TYPE)
469 pp_string (buffer, "union ");
471 if (TYPE_NAME (node))
472 dump_generic_node (buffer, TYPE_NAME (node), spc, flags, false);
473 else
474 print_struct_decl (buffer, node, spc, flags);
475 break;
477 case LANG_TYPE:
478 NIY;
479 break;
481 case INTEGER_CST:
482 if (TREE_CODE (TREE_TYPE (node)) == POINTER_TYPE)
484 /* In the case of a pointer, one may want to divide by the
485 size of the pointed-to type. Unfortunately, this not
486 straightforward. The C front-end maps expressions
488 (int *) 5
489 int *p; (p + 5)
491 in such a way that the two INTEGER_CST nodes for "5" have
492 different values but identical types. In the latter
493 case, the 5 is multiplied by sizeof (int) in c-common.c
494 (pointer_int_sum) to convert it to a byte address, and
495 yet the type of the node is left unchanged. Argh. What
496 is consistent though is that the number value corresponds
497 to bytes (UNITS) offset.
499 NB: Neither of the following divisors can be trivially
500 used to recover the original literal:
502 TREE_INT_CST_LOW (TYPE_SIZE_UNIT (TREE_TYPE (node)))
503 TYPE_PRECISION (TREE_TYPE (TREE_TYPE (node))) */
504 pp_wide_integer (buffer, TREE_INT_CST_LOW (node));
505 pp_string (buffer, "B"); /* pseudo-unit */
507 else if (! host_integerp (node, 0))
509 tree val = node;
511 if (tree_int_cst_sgn (val) < 0)
513 pp_character (buffer, '-');
514 val = build_int_cst_wide (NULL_TREE,
515 -TREE_INT_CST_LOW (val),
516 ~TREE_INT_CST_HIGH (val)
517 + !TREE_INT_CST_LOW (val));
519 /* Would "%x%0*x" or "%x%*0x" get zero-padding on all
520 systems? */
522 static char format[10]; /* "%x%09999x\0" */
523 if (!format[0])
524 sprintf (format, "%%x%%0%dx", HOST_BITS_PER_INT / 4);
525 sprintf (pp_buffer (buffer)->digit_buffer, format,
526 TREE_INT_CST_HIGH (val),
527 TREE_INT_CST_LOW (val));
528 pp_string (buffer, pp_buffer (buffer)->digit_buffer);
531 else
532 pp_wide_integer (buffer, TREE_INT_CST_LOW (node));
533 break;
535 case REAL_CST:
536 /* Code copied from print_node. */
538 REAL_VALUE_TYPE d;
539 if (TREE_OVERFLOW (node))
540 pp_string (buffer, " overflow");
542 #if !defined(REAL_IS_NOT_DOUBLE) || defined(REAL_ARITHMETIC)
543 d = TREE_REAL_CST (node);
544 if (REAL_VALUE_ISINF (d))
545 pp_string (buffer, " Inf");
546 else if (REAL_VALUE_ISNAN (d))
547 pp_string (buffer, " Nan");
548 else
550 char string[100];
551 real_to_decimal (string, &d, sizeof (string), 0, 1);
552 pp_string (buffer, string);
554 #else
556 HOST_WIDE_INT i;
557 unsigned char *p = (unsigned char *) &TREE_REAL_CST (node);
558 pp_string (buffer, "0x");
559 for (i = 0; i < sizeof TREE_REAL_CST (node); i++)
560 output_formatted_integer (buffer, "%02x", *p++);
562 #endif
563 break;
566 case COMPLEX_CST:
567 pp_string (buffer, "__complex__ (");
568 dump_generic_node (buffer, TREE_REALPART (node), spc, flags, false);
569 pp_string (buffer, ", ");
570 dump_generic_node (buffer, TREE_IMAGPART (node), spc, flags, false);
571 pp_string (buffer, ")");
572 break;
574 case STRING_CST:
575 pp_string (buffer, "\"");
576 pretty_print_string (buffer, TREE_STRING_POINTER (node));
577 pp_string (buffer, "\"");
578 break;
580 case VECTOR_CST:
582 tree elt;
583 pp_string (buffer, "{ ");
584 for (elt = TREE_VECTOR_CST_ELTS (node); elt; elt = TREE_CHAIN (elt))
586 dump_generic_node (buffer, TREE_VALUE (elt), spc, flags, false);
587 if (TREE_CHAIN (elt))
588 pp_string (buffer, ", ");
590 pp_string (buffer, " }");
592 break;
594 case FUNCTION_TYPE:
595 break;
597 case FUNCTION_DECL:
598 case CONST_DECL:
599 dump_decl_name (buffer, node, flags);
600 break;
602 case LABEL_DECL:
603 if (DECL_NAME (node))
604 dump_decl_name (buffer, node, flags);
605 else if (LABEL_DECL_UID (node) != -1)
606 pp_printf (buffer, "<L" HOST_WIDE_INT_PRINT_DEC ">",
607 LABEL_DECL_UID (node));
608 else
609 pp_printf (buffer, "<D%u>", DECL_UID (node));
610 break;
612 case TYPE_DECL:
613 if (DECL_IS_BUILTIN (node))
615 /* Don't print the declaration of built-in types. */
616 break;
618 if (DECL_NAME (node))
619 dump_decl_name (buffer, node, flags);
620 else
622 if ((TREE_CODE (TREE_TYPE (node)) == RECORD_TYPE
623 || TREE_CODE (TREE_TYPE (node)) == UNION_TYPE)
624 && TYPE_METHODS (TREE_TYPE (node)))
626 /* The type is a c++ class: all structures have at least
627 4 methods. */
628 pp_string (buffer, "class ");
629 dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
631 else
633 pp_string (buffer,
634 (TREE_CODE (TREE_TYPE (node)) == UNION_TYPE
635 ? "union" : "struct "));
636 dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
639 break;
641 case VAR_DECL:
642 case PARM_DECL:
643 case FIELD_DECL:
644 case NAMESPACE_DECL:
645 dump_decl_name (buffer, node, flags);
646 break;
648 case RESULT_DECL:
649 pp_string (buffer, "<retval>");
650 break;
652 case COMPONENT_REF:
653 op0 = TREE_OPERAND (node, 0);
654 str = ".";
655 if (TREE_CODE (op0) == INDIRECT_REF)
657 op0 = TREE_OPERAND (op0, 0);
658 str = "->";
660 if (op_prio (op0) < op_prio (node))
661 pp_character (buffer, '(');
662 dump_generic_node (buffer, op0, spc, flags, false);
663 if (op_prio (op0) < op_prio (node))
664 pp_character (buffer, ')');
665 pp_string (buffer, str);
666 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
668 if (TREE_CODE (op0) != VALUE_HANDLE)
670 op0 = component_ref_field_offset (node);
671 if (op0 && TREE_CODE (op0) != INTEGER_CST)
673 pp_string (buffer, "{off: ");
674 dump_generic_node (buffer, op0, spc, flags, false);
675 pp_character (buffer, '}');
678 break;
680 case BIT_FIELD_REF:
681 pp_string (buffer, "BIT_FIELD_REF <");
682 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
683 pp_string (buffer, ", ");
684 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
685 pp_string (buffer, ", ");
686 dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
687 pp_string (buffer, ">");
688 break;
690 case ARRAY_REF:
691 case ARRAY_RANGE_REF:
692 op0 = TREE_OPERAND (node, 0);
693 if (op_prio (op0) < op_prio (node))
694 pp_character (buffer, '(');
695 dump_generic_node (buffer, op0, spc, flags, false);
696 if (op_prio (op0) < op_prio (node))
697 pp_character (buffer, ')');
698 pp_character (buffer, '[');
699 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
700 if (TREE_CODE (node) == ARRAY_RANGE_REF)
701 pp_string (buffer, " ...");
702 pp_character (buffer, ']');
704 op0 = array_ref_low_bound (node);
705 op1 = array_ref_element_size (node);
707 if (!integer_zerop (op0)
708 || (TYPE_SIZE_UNIT (TREE_TYPE (node))
709 && !operand_equal_p (op1, TYPE_SIZE_UNIT (TREE_TYPE (node)), 0)))
711 pp_string (buffer, "{lb: ");
712 dump_generic_node (buffer, op0, spc, flags, false);
713 pp_string (buffer, " sz: ");
714 dump_generic_node (buffer, op1, spc, flags, false);
715 pp_character (buffer, '}');
717 break;
719 case CONSTRUCTOR:
721 tree lnode;
722 bool is_struct_init = FALSE;
723 pp_character (buffer, '{');
724 lnode = CONSTRUCTOR_ELTS (node);
725 if (TREE_CODE (TREE_TYPE (node)) == RECORD_TYPE
726 || TREE_CODE (TREE_TYPE (node)) == UNION_TYPE)
727 is_struct_init = TRUE;
728 while (lnode && lnode != error_mark_node)
730 tree val;
731 if (TREE_PURPOSE (lnode) && is_struct_init)
733 pp_character (buffer, '.');
734 dump_generic_node (buffer, TREE_PURPOSE (lnode), spc, flags, false);
735 pp_string (buffer, "=");
737 val = TREE_VALUE (lnode);
738 if (val && TREE_CODE (val) == ADDR_EXPR)
739 if (TREE_CODE (TREE_OPERAND (val, 0)) == FUNCTION_DECL)
740 val = TREE_OPERAND (val, 0);
741 if (val && TREE_CODE (val) == FUNCTION_DECL)
743 dump_decl_name (buffer, val, flags);
745 else
747 dump_generic_node (buffer, TREE_VALUE (lnode), spc, flags, false);
749 lnode = TREE_CHAIN (lnode);
750 if (lnode && TREE_CODE (lnode) == TREE_LIST)
752 pp_character (buffer, ',');
753 pp_space (buffer);
756 pp_character (buffer, '}');
758 break;
760 case COMPOUND_EXPR:
762 tree *tp;
763 if (flags & TDF_SLIM)
765 pp_string (buffer, "<COMPOUND_EXPR>");
766 break;
769 dump_generic_node (buffer, TREE_OPERAND (node, 0),
770 spc, flags, dumping_stmts);
771 if (dumping_stmts)
772 newline_and_indent (buffer, spc);
773 else
775 pp_character (buffer, ',');
776 pp_space (buffer);
779 for (tp = &TREE_OPERAND (node, 1);
780 TREE_CODE (*tp) == COMPOUND_EXPR;
781 tp = &TREE_OPERAND (*tp, 1))
783 dump_generic_node (buffer, TREE_OPERAND (*tp, 0),
784 spc, flags, dumping_stmts);
785 if (dumping_stmts)
786 newline_and_indent (buffer, spc);
787 else
789 pp_character (buffer, ',');
790 pp_space (buffer);
794 dump_generic_node (buffer, *tp, spc, flags, dumping_stmts);
796 break;
798 case STATEMENT_LIST:
800 tree_stmt_iterator si;
801 bool first = true;
803 if ((flags & TDF_SLIM) || !dumping_stmts)
805 pp_string (buffer, "<STATEMENT_LIST>");
806 break;
809 for (si = tsi_start (node); !tsi_end_p (si); tsi_next (&si))
811 if (!first)
812 newline_and_indent (buffer, spc);
813 else
814 first = false;
815 dump_generic_node (buffer, tsi_stmt (si), spc, flags, true);
818 break;
820 case MODIFY_EXPR:
821 case INIT_EXPR:
822 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
823 pp_space (buffer);
824 pp_character (buffer, '=');
825 pp_space (buffer);
826 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
827 break;
829 case TARGET_EXPR:
830 pp_string (buffer, "TARGET_EXPR <");
831 dump_generic_node (buffer, TARGET_EXPR_SLOT (node), spc, flags, false);
832 pp_character (buffer, ',');
833 pp_space (buffer);
834 dump_generic_node (buffer, TARGET_EXPR_INITIAL (node), spc, flags, false);
835 pp_character (buffer, '>');
836 break;
838 case DECL_EXPR:
839 print_declaration (buffer, DECL_EXPR_DECL (node), spc, flags);
840 is_stmt = false;
841 break;
843 case COND_EXPR:
844 if (TREE_TYPE (node) == NULL || TREE_TYPE (node) == void_type_node)
846 pp_string (buffer, "if (");
847 dump_generic_node (buffer, COND_EXPR_COND (node), spc, flags, false);
848 pp_character (buffer, ')');
849 /* The lowered cond_exprs should always be printed in full. */
850 if (COND_EXPR_THEN (node)
851 && (IS_EMPTY_STMT (COND_EXPR_THEN (node))
852 || TREE_CODE (COND_EXPR_THEN (node)) == GOTO_EXPR)
853 && COND_EXPR_ELSE (node)
854 && (IS_EMPTY_STMT (COND_EXPR_ELSE (node))
855 || TREE_CODE (COND_EXPR_ELSE (node)) == GOTO_EXPR))
857 pp_space (buffer);
858 dump_generic_node (buffer, COND_EXPR_THEN (node), 0, flags, true);
859 pp_string (buffer, " else ");
860 dump_generic_node (buffer, COND_EXPR_ELSE (node), 0, flags, true);
862 else if (!(flags & TDF_SLIM))
864 /* Output COND_EXPR_THEN. */
865 if (COND_EXPR_THEN (node))
867 newline_and_indent (buffer, spc+2);
868 pp_character (buffer, '{');
869 newline_and_indent (buffer, spc+4);
870 dump_generic_node (buffer, COND_EXPR_THEN (node), spc+4,
871 flags, true);
872 newline_and_indent (buffer, spc+2);
873 pp_character (buffer, '}');
876 /* Output COND_EXPR_ELSE. */
877 if (COND_EXPR_ELSE (node))
879 newline_and_indent (buffer, spc);
880 pp_string (buffer, "else");
881 newline_and_indent (buffer, spc+2);
882 pp_character (buffer, '{');
883 newline_and_indent (buffer, spc+4);
884 dump_generic_node (buffer, COND_EXPR_ELSE (node), spc+4,
885 flags, true);
886 newline_and_indent (buffer, spc+2);
887 pp_character (buffer, '}');
890 is_expr = false;
892 else
894 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
895 pp_space (buffer);
896 pp_character (buffer, '?');
897 pp_space (buffer);
898 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
899 pp_space (buffer);
900 pp_character (buffer, ':');
901 pp_space (buffer);
902 dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
904 break;
906 case BIND_EXPR:
907 pp_character (buffer, '{');
908 if (!(flags & TDF_SLIM))
910 if (BIND_EXPR_VARS (node))
912 pp_newline (buffer);
914 for (op0 = BIND_EXPR_VARS (node); op0; op0 = TREE_CHAIN (op0))
916 print_declaration (buffer, op0, spc+2, flags);
917 pp_newline (buffer);
921 newline_and_indent (buffer, spc+2);
922 dump_generic_node (buffer, BIND_EXPR_BODY (node), spc+2, flags, true);
923 newline_and_indent (buffer, spc);
924 pp_character (buffer, '}');
926 is_expr = false;
927 break;
929 case CALL_EXPR:
930 print_call_name (buffer, node);
932 /* Print parameters. */
933 pp_space (buffer);
934 pp_character (buffer, '(');
935 op1 = TREE_OPERAND (node, 1);
936 if (op1)
937 dump_generic_node (buffer, op1, spc, flags, false);
938 pp_character (buffer, ')');
940 op1 = TREE_OPERAND (node, 2);
941 if (op1)
943 pp_string (buffer, " [static-chain: ");
944 dump_generic_node (buffer, op1, spc, flags, false);
945 pp_character (buffer, ']');
948 if (CALL_EXPR_HAS_RETURN_SLOT_ADDR (node))
949 pp_string (buffer, " [return slot addr]");
950 if (CALL_EXPR_TAILCALL (node))
951 pp_string (buffer, " [tail call]");
952 break;
954 case WITH_CLEANUP_EXPR:
955 NIY;
956 break;
958 case CLEANUP_POINT_EXPR:
959 pp_string (buffer, "<<cleanup_point ");
960 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
961 pp_string (buffer, ">>");
962 break;
964 case PLACEHOLDER_EXPR:
965 pp_string (buffer, "<PLACEHOLDER_EXPR ");
966 dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
967 pp_character (buffer, '>');
968 break;
970 /* Binary arithmetic and logic expressions. */
971 case MULT_EXPR:
972 case PLUS_EXPR:
973 case MINUS_EXPR:
974 case TRUNC_DIV_EXPR:
975 case CEIL_DIV_EXPR:
976 case FLOOR_DIV_EXPR:
977 case ROUND_DIV_EXPR:
978 case TRUNC_MOD_EXPR:
979 case CEIL_MOD_EXPR:
980 case FLOOR_MOD_EXPR:
981 case ROUND_MOD_EXPR:
982 case RDIV_EXPR:
983 case EXACT_DIV_EXPR:
984 case LSHIFT_EXPR:
985 case RSHIFT_EXPR:
986 case LROTATE_EXPR:
987 case RROTATE_EXPR:
988 case BIT_IOR_EXPR:
989 case BIT_XOR_EXPR:
990 case BIT_AND_EXPR:
991 case TRUTH_ANDIF_EXPR:
992 case TRUTH_ORIF_EXPR:
993 case TRUTH_AND_EXPR:
994 case TRUTH_OR_EXPR:
995 case TRUTH_XOR_EXPR:
996 case LT_EXPR:
997 case LE_EXPR:
998 case GT_EXPR:
999 case GE_EXPR:
1000 case EQ_EXPR:
1001 case NE_EXPR:
1002 case UNLT_EXPR:
1003 case UNLE_EXPR:
1004 case UNGT_EXPR:
1005 case UNGE_EXPR:
1006 case UNEQ_EXPR:
1007 case LTGT_EXPR:
1008 case ORDERED_EXPR:
1009 case UNORDERED_EXPR:
1011 const char *op = op_symbol (node);
1012 op0 = TREE_OPERAND (node, 0);
1013 op1 = TREE_OPERAND (node, 1);
1015 /* When the operands are expressions with less priority,
1016 keep semantics of the tree representation. */
1017 if (op_prio (op0) < op_prio (node))
1019 pp_character (buffer, '(');
1020 dump_generic_node (buffer, op0, spc, flags, false);
1021 pp_character (buffer, ')');
1023 else
1024 dump_generic_node (buffer, op0, spc, flags, false);
1026 pp_space (buffer);
1027 pp_string (buffer, op);
1028 pp_space (buffer);
1030 /* When the operands are expressions with less priority,
1031 keep semantics of the tree representation. */
1032 if (op_prio (op1) < op_prio (node))
1034 pp_character (buffer, '(');
1035 dump_generic_node (buffer, op1, spc, flags, false);
1036 pp_character (buffer, ')');
1038 else
1039 dump_generic_node (buffer, op1, spc, flags, false);
1041 break;
1043 /* Unary arithmetic and logic expressions. */
1044 case NEGATE_EXPR:
1045 case BIT_NOT_EXPR:
1046 case TRUTH_NOT_EXPR:
1047 case ADDR_EXPR:
1048 case PREDECREMENT_EXPR:
1049 case PREINCREMENT_EXPR:
1050 case ALIGN_INDIRECT_REF:
1051 case MISALIGNED_INDIRECT_REF:
1052 case INDIRECT_REF:
1053 if (TREE_CODE (node) == ADDR_EXPR
1054 && (TREE_CODE (TREE_OPERAND (node, 0)) == STRING_CST
1055 || TREE_CODE (TREE_OPERAND (node, 0)) == FUNCTION_DECL))
1056 ; /* Do not output '&' for strings and function pointers. */
1057 else
1058 pp_string (buffer, op_symbol (node));
1060 if (op_prio (TREE_OPERAND (node, 0)) < op_prio (node))
1062 pp_character (buffer, '(');
1063 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1064 pp_character (buffer, ')');
1066 else
1067 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1069 if (TREE_CODE (node) == MISALIGNED_INDIRECT_REF)
1071 pp_string (buffer, "{misalignment: ");
1072 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1073 pp_character (buffer, '}');
1075 break;
1077 case POSTDECREMENT_EXPR:
1078 case POSTINCREMENT_EXPR:
1079 if (op_prio (TREE_OPERAND (node, 0)) < op_prio (node))
1081 pp_character (buffer, '(');
1082 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1083 pp_character (buffer, ')');
1085 else
1086 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1087 pp_string (buffer, op_symbol (node));
1088 break;
1090 case MIN_EXPR:
1091 pp_string (buffer, "MIN_EXPR <");
1092 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1093 pp_string (buffer, ", ");
1094 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1095 pp_character (buffer, '>');
1096 break;
1098 case MAX_EXPR:
1099 pp_string (buffer, "MAX_EXPR <");
1100 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1101 pp_string (buffer, ", ");
1102 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1103 pp_character (buffer, '>');
1104 break;
1106 case ABS_EXPR:
1107 pp_string (buffer, "ABS_EXPR <");
1108 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1109 pp_character (buffer, '>');
1110 break;
1112 case RANGE_EXPR:
1113 NIY;
1114 break;
1116 case FIX_TRUNC_EXPR:
1117 case FIX_CEIL_EXPR:
1118 case FIX_FLOOR_EXPR:
1119 case FIX_ROUND_EXPR:
1120 case FLOAT_EXPR:
1121 case CONVERT_EXPR:
1122 case NOP_EXPR:
1123 type = TREE_TYPE (node);
1124 op0 = TREE_OPERAND (node, 0);
1125 if (type != TREE_TYPE (op0))
1127 pp_character (buffer, '(');
1128 dump_generic_node (buffer, type, spc, flags, false);
1129 pp_string (buffer, ") ");
1131 if (op_prio (op0) < op_prio (node))
1132 pp_character (buffer, '(');
1133 dump_generic_node (buffer, op0, spc, flags, false);
1134 if (op_prio (op0) < op_prio (node))
1135 pp_character (buffer, ')');
1136 break;
1138 case VIEW_CONVERT_EXPR:
1139 pp_string (buffer, "VIEW_CONVERT_EXPR<");
1140 dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
1141 pp_string (buffer, ">(");
1142 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1143 pp_character (buffer, ')');
1144 break;
1146 case NON_LVALUE_EXPR:
1147 pp_string (buffer, "NON_LVALUE_EXPR <");
1148 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1149 pp_character (buffer, '>');
1150 break;
1152 case SAVE_EXPR:
1153 pp_string (buffer, "SAVE_EXPR <");
1154 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1155 pp_character (buffer, '>');
1156 break;
1158 case COMPLEX_EXPR:
1159 pp_string (buffer, "COMPLEX_EXPR <");
1160 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1161 pp_string (buffer, ", ");
1162 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1163 pp_string (buffer, ">");
1164 break;
1166 case CONJ_EXPR:
1167 pp_string (buffer, "CONJ_EXPR <");
1168 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1169 pp_string (buffer, ">");
1170 break;
1172 case REALPART_EXPR:
1173 pp_string (buffer, "REALPART_EXPR <");
1174 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1175 pp_string (buffer, ">");
1176 break;
1178 case IMAGPART_EXPR:
1179 pp_string (buffer, "IMAGPART_EXPR <");
1180 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1181 pp_string (buffer, ">");
1182 break;
1184 case VA_ARG_EXPR:
1185 pp_string (buffer, "VA_ARG_EXPR <");
1186 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1187 pp_string (buffer, ">");
1188 break;
1190 case TRY_FINALLY_EXPR:
1191 case TRY_CATCH_EXPR:
1192 pp_string (buffer, "try");
1193 newline_and_indent (buffer, spc+2);
1194 pp_string (buffer, "{");
1195 newline_and_indent (buffer, spc+4);
1196 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc+4, flags, true);
1197 newline_and_indent (buffer, spc+2);
1198 pp_string (buffer, "}");
1199 newline_and_indent (buffer, spc);
1200 pp_string (buffer,
1201 (TREE_CODE (node) == TRY_CATCH_EXPR) ? "catch" : "finally");
1202 newline_and_indent (buffer, spc+2);
1203 pp_string (buffer, "{");
1204 newline_and_indent (buffer, spc+4);
1205 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc+4, flags, true);
1206 newline_and_indent (buffer, spc+2);
1207 pp_string (buffer, "}");
1208 is_expr = false;
1209 break;
1211 case CATCH_EXPR:
1212 pp_string (buffer, "catch (");
1213 dump_generic_node (buffer, CATCH_TYPES (node), spc+2, flags, false);
1214 pp_string (buffer, ")");
1215 newline_and_indent (buffer, spc+2);
1216 pp_string (buffer, "{");
1217 newline_and_indent (buffer, spc+4);
1218 dump_generic_node (buffer, CATCH_BODY (node), spc+4, flags, true);
1219 newline_and_indent (buffer, spc+2);
1220 pp_string (buffer, "}");
1221 is_expr = false;
1222 break;
1224 case EH_FILTER_EXPR:
1225 pp_string (buffer, "<<<eh_filter (");
1226 dump_generic_node (buffer, EH_FILTER_TYPES (node), spc+2, flags, false);
1227 pp_string (buffer, ")>>>");
1228 newline_and_indent (buffer, spc+2);
1229 pp_string (buffer, "{");
1230 newline_and_indent (buffer, spc+4);
1231 dump_generic_node (buffer, EH_FILTER_FAILURE (node), spc+4, flags, true);
1232 newline_and_indent (buffer, spc+2);
1233 pp_string (buffer, "}");
1234 is_expr = false;
1235 break;
1237 case LABEL_EXPR:
1238 op0 = TREE_OPERAND (node, 0);
1239 /* If this is for break or continue, don't bother printing it. */
1240 if (DECL_NAME (op0))
1242 const char *name = IDENTIFIER_POINTER (DECL_NAME (op0));
1243 if (strcmp (name, "break") == 0
1244 || strcmp (name, "continue") == 0)
1245 break;
1247 dump_generic_node (buffer, op0, spc, flags, false);
1248 pp_character (buffer, ':');
1249 if (DECL_NONLOCAL (op0))
1250 pp_string (buffer, " [non-local]");
1251 break;
1253 case EXC_PTR_EXPR:
1254 pp_string (buffer, "<<<exception object>>>");
1255 break;
1257 case FILTER_EXPR:
1258 pp_string (buffer, "<<<filter object>>>");
1259 break;
1261 case LOOP_EXPR:
1262 pp_string (buffer, "while (1)");
1263 if (!(flags & TDF_SLIM))
1265 newline_and_indent (buffer, spc+2);
1266 pp_character (buffer, '{');
1267 newline_and_indent (buffer, spc+4);
1268 dump_generic_node (buffer, LOOP_EXPR_BODY (node), spc+4, flags, true);
1269 newline_and_indent (buffer, spc+2);
1270 pp_character (buffer, '}');
1272 is_expr = false;
1273 break;
1275 case RETURN_EXPR:
1276 pp_string (buffer, "return");
1277 op0 = TREE_OPERAND (node, 0);
1278 if (op0)
1280 pp_space (buffer);
1281 if (TREE_CODE (op0) == MODIFY_EXPR)
1282 dump_generic_node (buffer, TREE_OPERAND (op0, 1), spc, flags, false);
1283 else
1284 dump_generic_node (buffer, op0, spc, flags, false);
1286 break;
1288 case EXIT_EXPR:
1289 pp_string (buffer, "if (");
1290 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1291 pp_string (buffer, ") break");
1292 break;
1294 case SWITCH_EXPR:
1295 pp_string (buffer, "switch (");
1296 dump_generic_node (buffer, SWITCH_COND (node), spc, flags, false);
1297 pp_character (buffer, ')');
1298 if (!(flags & TDF_SLIM))
1300 newline_and_indent (buffer, spc+2);
1301 pp_character (buffer, '{');
1302 if (SWITCH_BODY (node))
1304 newline_and_indent (buffer, spc+4);
1305 dump_generic_node (buffer, SWITCH_BODY (node), spc+4, flags, true);
1307 else
1309 tree vec = SWITCH_LABELS (node);
1310 size_t i, n = TREE_VEC_LENGTH (vec);
1311 for (i = 0; i < n; ++i)
1313 tree elt = TREE_VEC_ELT (vec, i);
1314 newline_and_indent (buffer, spc+4);
1315 dump_generic_node (buffer, elt, spc+4, flags, false);
1316 pp_string (buffer, " goto ");
1317 dump_generic_node (buffer, CASE_LABEL (elt), spc+4, flags, true);
1318 pp_semicolon (buffer);
1321 newline_and_indent (buffer, spc+2);
1322 pp_character (buffer, '}');
1324 is_expr = false;
1325 break;
1327 case GOTO_EXPR:
1328 op0 = GOTO_DESTINATION (node);
1329 if (TREE_CODE (op0) != SSA_NAME && DECL_P (op0) && DECL_NAME (op0))
1331 const char *name = IDENTIFIER_POINTER (DECL_NAME (op0));
1332 if (strcmp (name, "break") == 0
1333 || strcmp (name, "continue") == 0)
1335 pp_string (buffer, name);
1336 break;
1339 pp_string (buffer, "goto ");
1340 dump_generic_node (buffer, op0, spc, flags, false);
1341 break;
1343 case RESX_EXPR:
1344 pp_string (buffer, "resx");
1345 /* ??? Any sensible way to present the eh region? */
1346 break;
1348 case ASM_EXPR:
1349 pp_string (buffer, "__asm__");
1350 if (ASM_VOLATILE_P (node))
1351 pp_string (buffer, " __volatile__");
1352 pp_character (buffer, '(');
1353 dump_generic_node (buffer, ASM_STRING (node), spc, flags, false);
1354 pp_character (buffer, ':');
1355 dump_generic_node (buffer, ASM_OUTPUTS (node), spc, flags, false);
1356 pp_character (buffer, ':');
1357 dump_generic_node (buffer, ASM_INPUTS (node), spc, flags, false);
1358 if (ASM_CLOBBERS (node))
1360 pp_character (buffer, ':');
1361 dump_generic_node (buffer, ASM_CLOBBERS (node), spc, flags, false);
1363 pp_string (buffer, ")");
1364 break;
1366 case CASE_LABEL_EXPR:
1367 if (CASE_LOW (node) && CASE_HIGH (node))
1369 pp_string (buffer, "case ");
1370 dump_generic_node (buffer, CASE_LOW (node), spc, flags, false);
1371 pp_string (buffer, " ... ");
1372 dump_generic_node (buffer, CASE_HIGH (node), spc, flags, false);
1374 else if (CASE_LOW (node))
1376 pp_string (buffer, "case ");
1377 dump_generic_node (buffer, CASE_LOW (node), spc, flags, false);
1379 else
1380 pp_string (buffer, "default ");
1381 pp_character (buffer, ':');
1382 break;
1384 case OBJ_TYPE_REF:
1385 pp_string (buffer, "OBJ_TYPE_REF(");
1386 dump_generic_node (buffer, OBJ_TYPE_REF_EXPR (node), spc, flags, false);
1387 pp_character (buffer, ';');
1388 dump_generic_node (buffer, OBJ_TYPE_REF_OBJECT (node), spc, flags, false);
1389 pp_character (buffer, '-');
1390 pp_character (buffer, '>');
1391 dump_generic_node (buffer, OBJ_TYPE_REF_TOKEN (node), spc, flags, false);
1392 pp_character (buffer, ')');
1393 break;
1395 case PHI_NODE:
1397 int i;
1399 dump_generic_node (buffer, PHI_RESULT (node), spc, flags, false);
1400 pp_string (buffer, " = PHI <");
1401 for (i = 0; i < PHI_NUM_ARGS (node); i++)
1403 dump_generic_node (buffer, PHI_ARG_DEF (node, i), spc, flags, false);
1404 pp_string (buffer, "(");
1405 pp_decimal_int (buffer, PHI_ARG_EDGE (node, i)->src->index);
1406 pp_string (buffer, ")");
1407 if (i < PHI_NUM_ARGS (node) - 1)
1408 pp_string (buffer, ", ");
1410 pp_string (buffer, ">;");
1412 break;
1414 case SSA_NAME:
1415 dump_generic_node (buffer, SSA_NAME_VAR (node), spc, flags, false);
1416 pp_string (buffer, "_");
1417 pp_decimal_int (buffer, SSA_NAME_VERSION (node));
1418 break;
1420 case WITH_SIZE_EXPR:
1421 pp_string (buffer, "WITH_SIZE_EXPR <");
1422 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1423 pp_string (buffer, ", ");
1424 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1425 pp_string (buffer, ">");
1426 break;
1428 case VALUE_HANDLE:
1429 pp_printf (buffer, "VH.%d", VALUE_HANDLE_ID (node));
1430 break;
1432 case SCEV_KNOWN:
1433 pp_string (buffer, "scev_known");
1434 break;
1436 case SCEV_NOT_KNOWN:
1437 pp_string (buffer, "scev_not_known");
1438 break;
1440 case POLYNOMIAL_CHREC:
1441 pp_string (buffer, "{");
1442 dump_generic_node (buffer, CHREC_LEFT (node), spc, flags, false);
1443 pp_string (buffer, ", +, ");
1444 dump_generic_node (buffer, CHREC_RIGHT (node), spc, flags, false);
1445 pp_string (buffer, "}_");
1446 dump_generic_node (buffer, CHREC_VAR (node), spc, flags, false);
1447 is_stmt = false;
1448 break;
1450 case REALIGN_LOAD_EXPR:
1451 pp_string (buffer, "REALIGN_LOAD <");
1452 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1453 pp_string (buffer, ", ");
1454 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1455 pp_string (buffer, ", ");
1456 dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
1457 pp_string (buffer, ">");
1458 break;
1460 case VEC_COND_EXPR:
1461 pp_string (buffer, " VEC_COND_EXPR < ");
1462 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1463 pp_string (buffer, " , ");
1464 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1465 pp_string (buffer, " , ");
1466 dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
1467 pp_string (buffer, " > ");
1468 break;
1470 default:
1471 NIY;
1474 if (is_stmt && is_expr)
1475 pp_semicolon (buffer);
1476 pp_write_text_to_stream (buffer);
1478 return spc;
1481 /* Print the declaration of a variable. */
1483 static void
1484 print_declaration (pretty_printer *buffer, tree t, int spc, int flags)
1486 INDENT (spc);
1488 if (TREE_CODE (t) == TYPE_DECL)
1489 pp_string (buffer, "typedef ");
1491 if (DECL_REGISTER (t))
1492 pp_string (buffer, "register ");
1494 if (TREE_PUBLIC (t) && DECL_EXTERNAL (t))
1495 pp_string (buffer, "extern ");
1496 else if (TREE_STATIC (t))
1497 pp_string (buffer, "static ");
1499 /* Print the type and name. */
1500 if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
1502 tree tmp;
1504 /* Print array's type. */
1505 tmp = TREE_TYPE (t);
1506 while (TREE_CODE (TREE_TYPE (tmp)) == ARRAY_TYPE)
1507 tmp = TREE_TYPE (tmp);
1508 dump_generic_node (buffer, TREE_TYPE (tmp), spc, flags, false);
1510 /* Print variable's name. */
1511 pp_space (buffer);
1512 dump_generic_node (buffer, t, spc, flags, false);
1514 /* Print the dimensions. */
1515 tmp = TREE_TYPE (t);
1516 while (TREE_CODE (tmp) == ARRAY_TYPE)
1518 pp_character (buffer, '[');
1519 if (TYPE_DOMAIN (tmp))
1521 if (TYPE_MIN_VALUE (TYPE_DOMAIN (tmp))
1522 && !integer_zerop (TYPE_MIN_VALUE (TYPE_DOMAIN (tmp))))
1524 dump_generic_node (buffer,
1525 TYPE_MIN_VALUE (TYPE_DOMAIN (tmp)),
1526 spc, flags, false);
1527 pp_string (buffer, " .. ");
1530 if (TYPE_MAX_VALUE (TYPE_DOMAIN (tmp)))
1531 dump_generic_node (buffer, TYPE_MAX_VALUE (TYPE_DOMAIN (tmp)),
1532 spc, flags, false);
1534 pp_character (buffer, ']');
1535 tmp = TREE_TYPE (tmp);
1538 else if (TREE_CODE (t) == FUNCTION_DECL)
1540 dump_generic_node (buffer, TREE_TYPE (TREE_TYPE (t)), spc, flags, false);
1541 pp_space (buffer);
1542 dump_decl_name (buffer, t, flags);
1543 dump_function_declaration (buffer, TREE_TYPE (t), spc, flags);
1545 else
1547 /* Print type declaration. */
1548 dump_generic_node (buffer, TREE_TYPE (t), spc, flags, false);
1550 /* Print variable's name. */
1551 pp_space (buffer);
1552 dump_generic_node (buffer, t, spc, flags, false);
1555 if (TREE_CODE (t) == VAR_DECL && DECL_HARD_REGISTER (t))
1557 pp_string (buffer, " __asm__ ");
1558 pp_character (buffer, '(');
1559 dump_generic_node (buffer, DECL_ASSEMBLER_NAME (t), spc, flags, false);
1560 pp_character (buffer, ')');
1563 /* The initial value of a function serves to determine wether the function
1564 is declared or defined. So the following does not apply to function
1565 nodes. */
1566 if (TREE_CODE (t) != FUNCTION_DECL)
1568 /* Print the initial value. */
1569 if (DECL_INITIAL (t))
1571 pp_space (buffer);
1572 pp_character (buffer, '=');
1573 pp_space (buffer);
1574 dump_generic_node (buffer, DECL_INITIAL (t), spc, flags, false);
1578 pp_character (buffer, ';');
1582 /* Prints a structure: name, fields, and methods.
1583 FIXME: Still incomplete. */
1585 static void
1586 print_struct_decl (pretty_printer *buffer, tree node, int spc, int flags)
1588 /* Print the name of the structure. */
1589 if (TYPE_NAME (node))
1591 INDENT (spc);
1592 if (TREE_CODE (node) == RECORD_TYPE)
1593 pp_string (buffer, "struct ");
1594 else if ((TREE_CODE (node) == UNION_TYPE
1595 || TREE_CODE (node) == QUAL_UNION_TYPE))
1596 pp_string (buffer, "union ");
1598 dump_generic_node (buffer, TYPE_NAME (node), spc, 0, false);
1601 /* Print the contents of the structure. */
1602 pp_newline (buffer);
1603 INDENT (spc);
1604 pp_character (buffer, '{');
1605 pp_newline (buffer);
1607 /* Print the fields of the structure. */
1609 tree tmp;
1610 tmp = TYPE_FIELDS (node);
1611 while (tmp)
1613 /* Avoid to print recursively the structure. */
1614 /* FIXME : Not implemented correctly...,
1615 what about the case when we have a cycle in the contain graph? ...
1616 Maybe this could be solved by looking at the scope in which the
1617 structure was declared. */
1618 if (TREE_TYPE (tmp) != node
1619 || (TREE_CODE (TREE_TYPE (tmp)) == POINTER_TYPE
1620 && TREE_TYPE (TREE_TYPE (tmp)) != node))
1622 print_declaration (buffer, tmp, spc+2, flags);
1623 pp_newline (buffer);
1625 tmp = TREE_CHAIN (tmp);
1628 INDENT (spc);
1629 pp_character (buffer, '}');
1632 /* Return the priority of the operator OP.
1634 From lowest to highest precedence with either left-to-right (L-R)
1635 or right-to-left (R-L) associativity]:
1637 1 [L-R] ,
1638 2 [R-L] = += -= *= /= %= &= ^= |= <<= >>=
1639 3 [R-L] ?:
1640 4 [L-R] ||
1641 5 [L-R] &&
1642 6 [L-R] |
1643 7 [L-R] ^
1644 8 [L-R] &
1645 9 [L-R] == !=
1646 10 [L-R] < <= > >=
1647 11 [L-R] << >>
1648 12 [L-R] + -
1649 13 [L-R] * / %
1650 14 [R-L] ! ~ ++ -- + - * & (type) sizeof
1651 15 [L-R] fn() [] -> .
1653 unary +, - and * have higher precedence than the corresponding binary
1654 operators. */
1656 static int
1657 op_prio (tree op)
1659 if (op == NULL)
1660 return 9999;
1662 switch (TREE_CODE (op))
1664 case TREE_LIST:
1665 case COMPOUND_EXPR:
1666 case BIND_EXPR:
1667 return 1;
1669 case MODIFY_EXPR:
1670 case INIT_EXPR:
1671 return 2;
1673 case COND_EXPR:
1674 return 3;
1676 case TRUTH_OR_EXPR:
1677 case TRUTH_ORIF_EXPR:
1678 return 4;
1680 case TRUTH_AND_EXPR:
1681 case TRUTH_ANDIF_EXPR:
1682 return 5;
1684 case BIT_IOR_EXPR:
1685 return 6;
1687 case BIT_XOR_EXPR:
1688 case TRUTH_XOR_EXPR:
1689 return 7;
1691 case BIT_AND_EXPR:
1692 return 8;
1694 case EQ_EXPR:
1695 case NE_EXPR:
1696 return 9;
1698 case UNLT_EXPR:
1699 case UNLE_EXPR:
1700 case UNGT_EXPR:
1701 case UNGE_EXPR:
1702 case UNEQ_EXPR:
1703 case LTGT_EXPR:
1704 case ORDERED_EXPR:
1705 case UNORDERED_EXPR:
1706 case LT_EXPR:
1707 case LE_EXPR:
1708 case GT_EXPR:
1709 case GE_EXPR:
1710 return 10;
1712 case LSHIFT_EXPR:
1713 case RSHIFT_EXPR:
1714 case LROTATE_EXPR:
1715 case RROTATE_EXPR:
1716 return 11;
1718 case PLUS_EXPR:
1719 case MINUS_EXPR:
1720 return 12;
1722 case MULT_EXPR:
1723 case TRUNC_DIV_EXPR:
1724 case CEIL_DIV_EXPR:
1725 case FLOOR_DIV_EXPR:
1726 case ROUND_DIV_EXPR:
1727 case RDIV_EXPR:
1728 case EXACT_DIV_EXPR:
1729 case TRUNC_MOD_EXPR:
1730 case CEIL_MOD_EXPR:
1731 case FLOOR_MOD_EXPR:
1732 case ROUND_MOD_EXPR:
1733 return 13;
1735 case TRUTH_NOT_EXPR:
1736 case BIT_NOT_EXPR:
1737 case POSTINCREMENT_EXPR:
1738 case POSTDECREMENT_EXPR:
1739 case PREINCREMENT_EXPR:
1740 case PREDECREMENT_EXPR:
1741 case NEGATE_EXPR:
1742 case ALIGN_INDIRECT_REF:
1743 case MISALIGNED_INDIRECT_REF:
1744 case INDIRECT_REF:
1745 case ADDR_EXPR:
1746 case FLOAT_EXPR:
1747 case NOP_EXPR:
1748 case CONVERT_EXPR:
1749 case FIX_TRUNC_EXPR:
1750 case FIX_CEIL_EXPR:
1751 case FIX_FLOOR_EXPR:
1752 case FIX_ROUND_EXPR:
1753 case TARGET_EXPR:
1754 return 14;
1756 case CALL_EXPR:
1757 case ARRAY_REF:
1758 case ARRAY_RANGE_REF:
1759 case COMPONENT_REF:
1760 return 15;
1762 /* Special expressions. */
1763 case MIN_EXPR:
1764 case MAX_EXPR:
1765 case ABS_EXPR:
1766 case REALPART_EXPR:
1767 case IMAGPART_EXPR:
1768 return 16;
1770 case SAVE_EXPR:
1771 case NON_LVALUE_EXPR:
1772 return op_prio (TREE_OPERAND (op, 0));
1774 default:
1775 /* Return an arbitrarily high precedence to avoid surrounding single
1776 VAR_DECLs in ()s. */
1777 return 9999;
1782 /* Return the symbol associated with operator OP. */
1784 static const char *
1785 op_symbol (tree op)
1787 gcc_assert (op);
1789 switch (TREE_CODE (op))
1791 case MODIFY_EXPR:
1792 return "=";
1794 case TRUTH_OR_EXPR:
1795 case TRUTH_ORIF_EXPR:
1796 return "||";
1798 case TRUTH_AND_EXPR:
1799 case TRUTH_ANDIF_EXPR:
1800 return "&&";
1802 case BIT_IOR_EXPR:
1803 return "|";
1805 case TRUTH_XOR_EXPR:
1806 case BIT_XOR_EXPR:
1807 return "^";
1809 case ADDR_EXPR:
1810 case BIT_AND_EXPR:
1811 return "&";
1813 case ORDERED_EXPR:
1814 return "ord";
1815 case UNORDERED_EXPR:
1816 return "unord";
1818 case EQ_EXPR:
1819 return "==";
1820 case UNEQ_EXPR:
1821 return "u==";
1823 case NE_EXPR:
1824 return "!=";
1826 case LT_EXPR:
1827 return "<";
1828 case UNLT_EXPR:
1829 return "u<";
1831 case LE_EXPR:
1832 return "<=";
1833 case UNLE_EXPR:
1834 return "u<=";
1836 case GT_EXPR:
1837 return ">";
1838 case UNGT_EXPR:
1839 return "u>";
1841 case GE_EXPR:
1842 return ">=";
1843 case UNGE_EXPR:
1844 return "u>=";
1846 case LTGT_EXPR:
1847 return "<>";
1849 case LSHIFT_EXPR:
1850 return "<<";
1852 case RSHIFT_EXPR:
1853 return ">>";
1855 case PLUS_EXPR:
1856 return "+";
1858 case NEGATE_EXPR:
1859 case MINUS_EXPR:
1860 return "-";
1862 case BIT_NOT_EXPR:
1863 return "~";
1865 case TRUTH_NOT_EXPR:
1866 return "!";
1868 case MULT_EXPR:
1869 case INDIRECT_REF:
1870 return "*";
1872 case ALIGN_INDIRECT_REF:
1873 return "A*";
1875 case MISALIGNED_INDIRECT_REF:
1876 return "M*";
1878 case TRUNC_DIV_EXPR:
1879 case RDIV_EXPR:
1880 return "/";
1882 case CEIL_DIV_EXPR:
1883 return "/[cl]";
1885 case FLOOR_DIV_EXPR:
1886 return "/[fl]";
1888 case ROUND_DIV_EXPR:
1889 return "/[rd]";
1891 case EXACT_DIV_EXPR:
1892 return "/[ex]";
1894 case TRUNC_MOD_EXPR:
1895 return "%";
1897 case CEIL_MOD_EXPR:
1898 return "%[cl]";
1900 case FLOOR_MOD_EXPR:
1901 return "%[fl]";
1903 case ROUND_MOD_EXPR:
1904 return "%[rd]";
1906 case PREDECREMENT_EXPR:
1907 return " --";
1909 case PREINCREMENT_EXPR:
1910 return " ++";
1912 case POSTDECREMENT_EXPR:
1913 return "-- ";
1915 case POSTINCREMENT_EXPR:
1916 return "++ ";
1918 default:
1919 return "<<< ??? >>>";
1923 /* Prints the name of a CALL_EXPR. */
1925 static void
1926 print_call_name (pretty_printer *buffer, tree node)
1928 tree op0;
1930 gcc_assert (TREE_CODE (node) == CALL_EXPR);
1932 op0 = TREE_OPERAND (node, 0);
1934 if (TREE_CODE (op0) == NON_LVALUE_EXPR)
1935 op0 = TREE_OPERAND (op0, 0);
1937 switch (TREE_CODE (op0))
1939 case VAR_DECL:
1940 case PARM_DECL:
1941 dump_function_name (buffer, op0);
1942 break;
1944 case ADDR_EXPR:
1945 case INDIRECT_REF:
1946 case NOP_EXPR:
1947 dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
1948 break;
1950 case COND_EXPR:
1951 pp_string (buffer, "(");
1952 dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
1953 pp_string (buffer, ") ? ");
1954 dump_generic_node (buffer, TREE_OPERAND (op0, 1), 0, 0, false);
1955 pp_string (buffer, " : ");
1956 dump_generic_node (buffer, TREE_OPERAND (op0, 2), 0, 0, false);
1957 break;
1959 case COMPONENT_REF:
1960 /* The function is a pointer contained in a structure. */
1961 if (TREE_CODE (TREE_OPERAND (op0, 0)) == INDIRECT_REF ||
1962 TREE_CODE (TREE_OPERAND (op0, 0)) == VAR_DECL)
1963 dump_function_name (buffer, TREE_OPERAND (op0, 1));
1964 else
1965 dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
1966 /* else
1967 We can have several levels of structures and a function
1968 pointer inside. This is not implemented yet... */
1969 /* NIY;*/
1970 break;
1972 case ARRAY_REF:
1973 if (TREE_CODE (TREE_OPERAND (op0, 0)) == VAR_DECL)
1974 dump_function_name (buffer, TREE_OPERAND (op0, 0));
1975 else
1976 dump_generic_node (buffer, op0, 0, 0, false);
1977 break;
1979 case SSA_NAME:
1980 case OBJ_TYPE_REF:
1981 dump_generic_node (buffer, op0, 0, 0, false);
1982 break;
1984 default:
1985 NIY;
1989 /* Parses the string STR and replaces new-lines by '\n', tabs by '\t', ... */
1991 static void
1992 pretty_print_string (pretty_printer *buffer, const char *str)
1994 if (str == NULL)
1995 return;
1997 while (*str)
1999 switch (str[0])
2001 case '\b':
2002 pp_string (buffer, "\\b");
2003 break;
2005 case '\f':
2006 pp_string (buffer, "\\f");
2007 break;
2009 case '\n':
2010 pp_string (buffer, "\\n");
2011 break;
2013 case '\r':
2014 pp_string (buffer, "\\r");
2015 break;
2017 case '\t':
2018 pp_string (buffer, "\\t");
2019 break;
2021 case '\v':
2022 pp_string (buffer, "\\v");
2023 break;
2025 case '\\':
2026 pp_string (buffer, "\\\\");
2027 break;
2029 case '\"':
2030 pp_string (buffer, "\\\"");
2031 break;
2033 case '\'':
2034 pp_string (buffer, "\\'");
2035 break;
2037 case '\0':
2038 pp_string (buffer, "\\0");
2039 break;
2041 case '\1':
2042 pp_string (buffer, "\\1");
2043 break;
2045 case '\2':
2046 pp_string (buffer, "\\2");
2047 break;
2049 case '\3':
2050 pp_string (buffer, "\\3");
2051 break;
2053 case '\4':
2054 pp_string (buffer, "\\4");
2055 break;
2057 case '\5':
2058 pp_string (buffer, "\\5");
2059 break;
2061 case '\6':
2062 pp_string (buffer, "\\6");
2063 break;
2065 case '\7':
2066 pp_string (buffer, "\\7");
2067 break;
2069 default:
2070 pp_character (buffer, str[0]);
2071 break;
2073 str++;
2077 static void
2078 maybe_init_pretty_print (FILE *file)
2080 if (!initialized)
2082 pp_construct (&buffer, /* prefix */NULL, /* line-width */0);
2083 pp_needs_newline (&buffer) = true;
2084 initialized = 1;
2087 buffer.buffer->stream = file;
2090 static void
2091 newline_and_indent (pretty_printer *buffer, int spc)
2093 pp_newline (buffer);
2094 INDENT (spc);
2097 static void
2098 dump_vops (pretty_printer *buffer, tree stmt, int spc, int flags)
2100 tree use;
2101 use_operand_p use_p;
2102 def_operand_p def_p;
2103 use_operand_p kill_p;
2104 ssa_op_iter iter;
2106 FOR_EACH_SSA_MAYDEF_OPERAND (def_p, use_p, stmt, iter)
2108 pp_string (buffer, "# ");
2109 dump_generic_node (buffer, DEF_FROM_PTR (def_p),
2110 spc + 2, flags, false);
2111 pp_string (buffer, " = V_MAY_DEF <");
2112 dump_generic_node (buffer, USE_FROM_PTR (use_p),
2113 spc + 2, flags, false);
2114 pp_string (buffer, ">;");
2115 newline_and_indent (buffer, spc);
2118 FOR_EACH_SSA_MUSTDEF_OPERAND (def_p, kill_p, stmt, iter)
2120 pp_string (buffer, "# ");
2121 dump_generic_node (buffer, DEF_FROM_PTR (def_p),
2122 spc + 2, flags, false);
2123 pp_string (buffer, " = V_MUST_DEF <");
2124 dump_generic_node (buffer, USE_FROM_PTR (kill_p),
2125 spc + 2, flags, false);
2126 pp_string (buffer, ">;");
2127 newline_and_indent (buffer, spc);
2130 FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_VUSE)
2132 pp_string (buffer, "# VUSE <");
2133 dump_generic_node (buffer, use, spc + 2, flags, false);
2134 pp_string (buffer, ">;");
2135 newline_and_indent (buffer, spc);
2139 /* Dumps basic block BB to FILE with details described by FLAGS and
2140 indented by INDENT spaces. */
2142 void
2143 dump_generic_bb (FILE *file, basic_block bb, int indent, int flags)
2145 maybe_init_pretty_print (file);
2146 dumping_stmts = true;
2147 dump_generic_bb_buff (&buffer, bb, indent, flags);
2148 pp_flush (&buffer);
2151 /* Dumps header of basic block BB to buffer BUFFER indented by INDENT
2152 spaces and details described by flags. */
2154 static void
2155 dump_bb_header (pretty_printer *buffer, basic_block bb, int indent, int flags)
2157 edge e;
2158 tree stmt;
2159 edge_iterator ei;
2161 if (flags & TDF_BLOCKS)
2163 INDENT (indent);
2164 pp_string (buffer, "# BLOCK ");
2165 pp_decimal_int (buffer, bb->index);
2167 if (flags & TDF_LINENO)
2169 block_stmt_iterator bsi;
2171 for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
2172 if (get_lineno (bsi_stmt (bsi)) != -1)
2174 pp_string (buffer, ", starting at line ");
2175 pp_decimal_int (buffer, get_lineno (bsi_stmt (bsi)));
2176 break;
2179 newline_and_indent (buffer, indent);
2181 pp_string (buffer, "# PRED:");
2182 pp_write_text_to_stream (buffer);
2183 FOR_EACH_EDGE (e, ei, bb->preds)
2184 if (flags & TDF_SLIM)
2186 pp_string (buffer, " ");
2187 if (e->src == ENTRY_BLOCK_PTR)
2188 pp_string (buffer, "ENTRY");
2189 else
2190 pp_decimal_int (buffer, e->src->index);
2192 else
2193 dump_edge_info (buffer->buffer->stream, e, 0);
2194 pp_newline (buffer);
2196 else
2198 stmt = first_stmt (bb);
2199 if (!stmt || TREE_CODE (stmt) != LABEL_EXPR)
2201 INDENT (indent - 2);
2202 pp_string (buffer, "<bb ");
2203 pp_decimal_int (buffer, bb->index);
2204 pp_string (buffer, ">:");
2205 pp_newline (buffer);
2208 pp_write_text_to_stream (buffer);
2209 check_bb_profile (bb, buffer->buffer->stream);
2212 /* Dumps end of basic block BB to buffer BUFFER indented by INDENT
2213 spaces. */
2215 static void
2216 dump_bb_end (pretty_printer *buffer, basic_block bb, int indent, int flags)
2218 edge e;
2219 edge_iterator ei;
2221 INDENT (indent);
2222 pp_string (buffer, "# SUCC:");
2223 pp_write_text_to_stream (buffer);
2224 FOR_EACH_EDGE (e, ei, bb->succs)
2225 if (flags & TDF_SLIM)
2227 pp_string (buffer, " ");
2228 if (e->dest == EXIT_BLOCK_PTR)
2229 pp_string (buffer, "EXIT");
2230 else
2231 pp_decimal_int (buffer, e->dest->index);
2233 else
2234 dump_edge_info (buffer->buffer->stream, e, 1);
2235 pp_newline (buffer);
2238 /* Dumps phi nodes of basic block BB to buffer BUFFER with details described by
2239 FLAGS indented by INDENT spaces. */
2241 static void
2242 dump_phi_nodes (pretty_printer *buffer, basic_block bb, int indent, int flags)
2244 tree phi = phi_nodes (bb);
2245 if (!phi)
2246 return;
2248 for (; phi; phi = PHI_CHAIN (phi))
2250 if (is_gimple_reg (PHI_RESULT (phi)) || (flags & TDF_VOPS))
2252 INDENT (indent);
2253 pp_string (buffer, "# ");
2254 dump_generic_node (buffer, phi, indent, flags, false);
2255 pp_newline (buffer);
2260 /* Dump jump to basic block BB that is represented implicitly in the cfg
2261 to BUFFER. */
2263 static void
2264 pp_cfg_jump (pretty_printer *buffer, basic_block bb)
2266 tree stmt;
2268 stmt = first_stmt (bb);
2270 pp_string (buffer, "goto <bb ");
2271 pp_decimal_int (buffer, bb->index);
2272 pp_string (buffer, ">");
2273 if (stmt && TREE_CODE (stmt) == LABEL_EXPR)
2275 pp_string (buffer, " (");
2276 dump_generic_node (buffer, LABEL_EXPR_LABEL (stmt), 0, 0, false);
2277 pp_string (buffer, ")");
2279 pp_semicolon (buffer);
2282 /* Dump edges represented implicitly in basic block BB to BUFFER, indented
2283 by INDENT spaces, with details given by FLAGS. */
2285 static void
2286 dump_implicit_edges (pretty_printer *buffer, basic_block bb, int indent,
2287 int flags)
2289 edge e;
2290 edge_iterator ei;
2292 /* If there is a fallthru edge, we may need to add an artificial goto to the
2293 dump. */
2294 FOR_EACH_EDGE (e, ei, bb->succs)
2295 if (e->flags & EDGE_FALLTHRU)
2296 break;
2297 if (e && e->dest != bb->next_bb)
2299 INDENT (indent);
2301 if ((flags & TDF_LINENO)
2302 #ifdef USE_MAPPED_LOCATION
2303 && e->goto_locus != UNKNOWN_LOCATION
2304 #else
2305 && e->goto_locus
2306 #endif
2309 expanded_location goto_xloc;
2310 #ifdef USE_MAPPED_LOCATION
2311 goto_xloc = expand_location (e->goto_locus);
2312 #else
2313 goto_xloc = *e->goto_locus;
2314 #endif
2315 pp_character (buffer, '[');
2316 if (goto_xloc.file)
2318 pp_string (buffer, goto_xloc.file);
2319 pp_string (buffer, " : ");
2321 pp_decimal_int (buffer, goto_xloc.line);
2322 pp_string (buffer, "] ");
2325 pp_cfg_jump (buffer, e->dest);
2326 pp_newline (buffer);
2330 /* Dumps basic block BB to buffer BUFFER with details described by FLAGS and
2331 indented by INDENT spaces. */
2333 static void
2334 dump_generic_bb_buff (pretty_printer *buffer, basic_block bb,
2335 int indent, int flags)
2337 block_stmt_iterator bsi;
2338 tree stmt;
2339 int label_indent = indent - 2;
2341 if (label_indent < 0)
2342 label_indent = 0;
2344 dump_bb_header (buffer, bb, indent, flags);
2346 if (bb_ann (bb))
2347 dump_phi_nodes (buffer, bb, indent, flags);
2349 for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
2351 int curr_indent;
2353 stmt = bsi_stmt (bsi);
2355 curr_indent = TREE_CODE (stmt) == LABEL_EXPR ? label_indent : indent;
2357 INDENT (curr_indent);
2358 dump_generic_node (buffer, stmt, curr_indent, flags, true);
2359 pp_newline (buffer);
2362 dump_implicit_edges (buffer, bb, indent, flags);
2364 if (flags & TDF_BLOCKS)
2365 dump_bb_end (buffer, bb, indent, flags);