2005-09-26 Daniel Berlin <dberlin@dberlin.org>
[official-gcc.git] / gcc / tree-pretty-print.c
blobd0fbd162afa8a1f9c89f9f185a3fa7f05bde770c
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, 51 Franklin Street, Fifth Floor, Boston, MA
20 02110-1301, USA. */
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tm.h"
26 #include "tree.h"
27 #include "diagnostic.h"
28 #include "real.h"
29 #include "hashtab.h"
30 #include "tree-flow.h"
31 #include "langhooks.h"
32 #include "tree-iterator.h"
33 #include "tree-chrec.h"
34 #include "tree-pass.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 && TREE_CODE (node) != PHI_NODE)
273 dump_vops (buffer, node, spc, flags);
275 if (is_stmt && (flags & TDF_STMTADDR))
276 pp_printf (buffer, "<&%p> ", (void *)node);
278 if (dumping_stmts
279 && (flags & TDF_LINENO)
280 && EXPR_HAS_LOCATION (node))
282 expanded_location xloc = expand_location (EXPR_LOCATION (node));
283 pp_character (buffer, '[');
284 if (xloc.file)
286 pp_string (buffer, xloc.file);
287 pp_string (buffer, " : ");
289 pp_decimal_int (buffer, xloc.line);
290 pp_string (buffer, "] ");
293 switch (TREE_CODE (node))
295 case ERROR_MARK:
296 pp_string (buffer, "<<< error >>>");
297 break;
299 case IDENTIFIER_NODE:
300 pp_tree_identifier (buffer, node);
301 break;
303 case TREE_LIST:
304 while (node && node != error_mark_node)
306 if (TREE_PURPOSE (node))
308 dump_generic_node (buffer, TREE_PURPOSE (node), spc, flags, false);
309 pp_space (buffer);
311 dump_generic_node (buffer, TREE_VALUE (node), spc, flags, false);
312 node = TREE_CHAIN (node);
313 if (node && TREE_CODE (node) == TREE_LIST)
315 pp_character (buffer, ',');
316 pp_space (buffer);
319 break;
321 case TREE_BINFO:
322 dump_generic_node (buffer, BINFO_TYPE (node), spc, flags, false);
324 case TREE_VEC:
326 size_t i;
327 if (TREE_VEC_LENGTH (node) > 0)
329 size_t len = TREE_VEC_LENGTH (node);
330 for (i = 0; i < len - 1; i++)
332 dump_generic_node (buffer, TREE_VEC_ELT (node, i), spc, flags,
333 false);
334 pp_character (buffer, ',');
335 pp_space (buffer);
337 dump_generic_node (buffer, TREE_VEC_ELT (node, len - 1), spc,
338 flags, false);
341 break;
343 case BLOCK:
344 NIY;
345 break;
347 case VOID_TYPE:
348 case INTEGER_TYPE:
349 case REAL_TYPE:
350 case COMPLEX_TYPE:
351 case VECTOR_TYPE:
352 case ENUMERAL_TYPE:
353 case BOOLEAN_TYPE:
354 case CHAR_TYPE:
356 unsigned int quals = TYPE_QUALS (node);
357 enum tree_code_class class;
359 if (quals & TYPE_QUAL_CONST)
360 pp_string (buffer, "const ");
361 else if (quals & TYPE_QUAL_VOLATILE)
362 pp_string (buffer, "volatile ");
363 else if (quals & TYPE_QUAL_RESTRICT)
364 pp_string (buffer, "restrict ");
366 class = TREE_CODE_CLASS (TREE_CODE (node));
368 if (class == tcc_declaration)
370 if (DECL_NAME (node))
371 dump_decl_name (buffer, node, flags);
372 else
373 pp_string (buffer, "<unnamed type decl>");
375 else if (class == tcc_type)
377 if (TYPE_NAME (node))
379 if (TREE_CODE (TYPE_NAME (node)) == IDENTIFIER_NODE)
380 pp_tree_identifier (buffer, TYPE_NAME (node));
381 else if (TREE_CODE (TYPE_NAME (node)) == TYPE_DECL
382 && DECL_NAME (TYPE_NAME (node)))
383 dump_decl_name (buffer, TYPE_NAME (node), flags);
384 else
385 pp_string (buffer, "<unnamed type>");
387 else if (TREE_CODE (node) == VECTOR_TYPE)
389 pp_string (buffer, "vector ");
390 dump_generic_node (buffer, TREE_TYPE (node),
391 spc, flags, false);
393 else
394 pp_string (buffer, "<unnamed type>");
396 break;
399 case POINTER_TYPE:
400 case REFERENCE_TYPE:
401 str = (TREE_CODE (node) == POINTER_TYPE ? "*" : "&");
403 if (TREE_CODE (TREE_TYPE (node)) == FUNCTION_TYPE)
405 tree fnode = TREE_TYPE (node);
407 dump_generic_node (buffer, TREE_TYPE (fnode), spc, flags, false);
408 pp_space (buffer);
409 pp_character (buffer, '(');
410 pp_string (buffer, str);
411 if (TYPE_NAME (node) && DECL_NAME (TYPE_NAME (node)))
412 dump_decl_name (buffer, TYPE_NAME (node), flags);
413 else
414 pp_printf (buffer, "<T%x>", TYPE_UID (node));
416 pp_character (buffer, ')');
417 dump_function_declaration (buffer, fnode, spc, flags);
419 else
421 unsigned int quals = TYPE_QUALS (node);
423 dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
424 pp_space (buffer);
425 pp_string (buffer, str);
427 if (quals & TYPE_QUAL_CONST)
428 pp_string (buffer, " const");
429 else if (quals & TYPE_QUAL_VOLATILE)
430 pp_string (buffer, "volatile");
431 else if (quals & TYPE_QUAL_RESTRICT)
432 pp_string (buffer, " restrict");
434 if (TYPE_REF_CAN_ALIAS_ALL (node))
435 pp_string (buffer, " {ref-all}");
437 break;
439 case OFFSET_TYPE:
440 NIY;
441 break;
443 case METHOD_TYPE:
444 dump_decl_name (buffer, TYPE_NAME (TYPE_METHOD_BASETYPE (node)), flags);
445 pp_string (buffer, "::");
446 break;
448 case TARGET_MEM_REF:
450 const char *sep = "";
451 tree tmp;
453 pp_string (buffer, "MEM[");
455 tmp = TMR_SYMBOL (node);
456 if (tmp)
458 pp_string (buffer, sep);
459 sep = ", ";
460 pp_string (buffer, "symbol: ");
461 dump_generic_node (buffer, tmp, spc, flags, false);
463 tmp = TMR_BASE (node);
464 if (tmp)
466 pp_string (buffer, sep);
467 sep = ", ";
468 pp_string (buffer, "base: ");
469 dump_generic_node (buffer, tmp, spc, flags, false);
471 tmp = TMR_INDEX (node);
472 if (tmp)
474 pp_string (buffer, sep);
475 sep = ", ";
476 pp_string (buffer, "index: ");
477 dump_generic_node (buffer, tmp, spc, flags, false);
479 tmp = TMR_STEP (node);
480 if (tmp)
482 pp_string (buffer, sep);
483 sep = ", ";
484 pp_string (buffer, "step: ");
485 dump_generic_node (buffer, tmp, spc, flags, false);
487 tmp = TMR_OFFSET (node);
488 if (tmp)
490 pp_string (buffer, sep);
491 sep = ", ";
492 pp_string (buffer, "offset: ");
493 dump_generic_node (buffer, tmp, spc, flags, false);
495 pp_string (buffer, "]");
496 if (flags & TDF_DETAILS)
498 pp_string (buffer, "{");
499 dump_generic_node (buffer, TMR_ORIGINAL (node), spc, flags,
500 false);
501 pp_string (buffer, "}");
504 break;
506 case ARRAY_TYPE:
508 tree tmp;
510 /* Print the innermost component type. */
511 for (tmp = TREE_TYPE (node); TREE_CODE (tmp) == ARRAY_TYPE;
512 tmp = TREE_TYPE (tmp))
514 dump_generic_node (buffer, tmp, spc, flags, false);
516 /* Print the dimensions. */
517 for (tmp = node; TREE_CODE (tmp) == ARRAY_TYPE; tmp = TREE_TYPE (tmp))
518 dump_array_domain (buffer, TYPE_DOMAIN (tmp), spc, flags);
519 break;
522 case RECORD_TYPE:
523 case UNION_TYPE:
524 case QUAL_UNION_TYPE:
525 /* Print the name of the structure. */
526 if (TREE_CODE (node) == RECORD_TYPE)
527 pp_string (buffer, "struct ");
528 else if (TREE_CODE (node) == UNION_TYPE)
529 pp_string (buffer, "union ");
531 if (TYPE_NAME (node))
532 dump_generic_node (buffer, TYPE_NAME (node), spc, flags, false);
533 else
534 print_struct_decl (buffer, node, spc, flags);
535 break;
537 case LANG_TYPE:
538 NIY;
539 break;
541 case INTEGER_CST:
542 if (TREE_CODE (TREE_TYPE (node)) == POINTER_TYPE)
544 /* In the case of a pointer, one may want to divide by the
545 size of the pointed-to type. Unfortunately, this not
546 straightforward. The C front-end maps expressions
548 (int *) 5
549 int *p; (p + 5)
551 in such a way that the two INTEGER_CST nodes for "5" have
552 different values but identical types. In the latter
553 case, the 5 is multiplied by sizeof (int) in c-common.c
554 (pointer_int_sum) to convert it to a byte address, and
555 yet the type of the node is left unchanged. Argh. What
556 is consistent though is that the number value corresponds
557 to bytes (UNITS) offset.
559 NB: Neither of the following divisors can be trivially
560 used to recover the original literal:
562 TREE_INT_CST_LOW (TYPE_SIZE_UNIT (TREE_TYPE (node)))
563 TYPE_PRECISION (TREE_TYPE (TREE_TYPE (node))) */
564 pp_wide_integer (buffer, TREE_INT_CST_LOW (node));
565 pp_string (buffer, "B"); /* pseudo-unit */
567 else if (! host_integerp (node, 0))
569 tree val = node;
571 if (tree_int_cst_sgn (val) < 0)
573 pp_character (buffer, '-');
574 val = build_int_cst_wide (NULL_TREE,
575 -TREE_INT_CST_LOW (val),
576 ~TREE_INT_CST_HIGH (val)
577 + !TREE_INT_CST_LOW (val));
579 /* Would "%x%0*x" or "%x%*0x" get zero-padding on all
580 systems? */
582 static char format[10]; /* "%x%09999x\0" */
583 if (!format[0])
584 sprintf (format, "%%x%%0%dx", HOST_BITS_PER_INT / 4);
585 sprintf (pp_buffer (buffer)->digit_buffer, format,
586 TREE_INT_CST_HIGH (val),
587 TREE_INT_CST_LOW (val));
588 pp_string (buffer, pp_buffer (buffer)->digit_buffer);
591 else
592 pp_wide_integer (buffer, TREE_INT_CST_LOW (node));
593 break;
595 case REAL_CST:
596 /* Code copied from print_node. */
598 REAL_VALUE_TYPE d;
599 if (TREE_OVERFLOW (node))
600 pp_string (buffer, " overflow");
602 #if !defined(REAL_IS_NOT_DOUBLE) || defined(REAL_ARITHMETIC)
603 d = TREE_REAL_CST (node);
604 if (REAL_VALUE_ISINF (d))
605 pp_string (buffer, " Inf");
606 else if (REAL_VALUE_ISNAN (d))
607 pp_string (buffer, " Nan");
608 else
610 char string[100];
611 real_to_decimal (string, &d, sizeof (string), 0, 1);
612 pp_string (buffer, string);
614 #else
616 HOST_WIDE_INT i;
617 unsigned char *p = (unsigned char *) &TREE_REAL_CST (node);
618 pp_string (buffer, "0x");
619 for (i = 0; i < sizeof TREE_REAL_CST (node); i++)
620 output_formatted_integer (buffer, "%02x", *p++);
622 #endif
623 break;
626 case COMPLEX_CST:
627 pp_string (buffer, "__complex__ (");
628 dump_generic_node (buffer, TREE_REALPART (node), spc, flags, false);
629 pp_string (buffer, ", ");
630 dump_generic_node (buffer, TREE_IMAGPART (node), spc, flags, false);
631 pp_string (buffer, ")");
632 break;
634 case STRING_CST:
635 pp_string (buffer, "\"");
636 pretty_print_string (buffer, TREE_STRING_POINTER (node));
637 pp_string (buffer, "\"");
638 break;
640 case VECTOR_CST:
642 tree elt;
643 pp_string (buffer, "{ ");
644 for (elt = TREE_VECTOR_CST_ELTS (node); elt; elt = TREE_CHAIN (elt))
646 dump_generic_node (buffer, TREE_VALUE (elt), spc, flags, false);
647 if (TREE_CHAIN (elt))
648 pp_string (buffer, ", ");
650 pp_string (buffer, " }");
652 break;
654 case FUNCTION_TYPE:
655 break;
657 case FUNCTION_DECL:
658 case CONST_DECL:
659 dump_decl_name (buffer, node, flags);
660 break;
662 case LABEL_DECL:
663 if (DECL_NAME (node))
664 dump_decl_name (buffer, node, flags);
665 else if (LABEL_DECL_UID (node) != -1)
666 pp_printf (buffer, "<L" HOST_WIDE_INT_PRINT_DEC ">",
667 LABEL_DECL_UID (node));
668 else
669 pp_printf (buffer, "<D%u>", DECL_UID (node));
670 break;
672 case TYPE_DECL:
673 if (DECL_IS_BUILTIN (node))
675 /* Don't print the declaration of built-in types. */
676 break;
678 if (DECL_NAME (node))
679 dump_decl_name (buffer, node, flags);
680 else
682 if ((TREE_CODE (TREE_TYPE (node)) == RECORD_TYPE
683 || TREE_CODE (TREE_TYPE (node)) == UNION_TYPE)
684 && TYPE_METHODS (TREE_TYPE (node)))
686 /* The type is a c++ class: all structures have at least
687 4 methods. */
688 pp_string (buffer, "class ");
689 dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
691 else
693 pp_string (buffer,
694 (TREE_CODE (TREE_TYPE (node)) == UNION_TYPE
695 ? "union" : "struct "));
696 dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
699 break;
701 case TYPE_MEMORY_TAG:
702 case NAME_MEMORY_TAG:
703 case STRUCT_FIELD_TAG:
704 case VAR_DECL:
705 case PARM_DECL:
706 case FIELD_DECL:
707 case NAMESPACE_DECL:
708 dump_decl_name (buffer, node, flags);
709 break;
711 case RESULT_DECL:
712 pp_string (buffer, "<retval>");
713 break;
715 case COMPONENT_REF:
716 op0 = TREE_OPERAND (node, 0);
717 str = ".";
718 if (TREE_CODE (op0) == INDIRECT_REF)
720 op0 = TREE_OPERAND (op0, 0);
721 str = "->";
723 if (op_prio (op0) < op_prio (node))
724 pp_character (buffer, '(');
725 dump_generic_node (buffer, op0, spc, flags, false);
726 if (op_prio (op0) < op_prio (node))
727 pp_character (buffer, ')');
728 pp_string (buffer, str);
729 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
731 if (TREE_CODE (op0) != VALUE_HANDLE)
733 op0 = component_ref_field_offset (node);
734 if (op0 && TREE_CODE (op0) != INTEGER_CST)
736 pp_string (buffer, "{off: ");
737 dump_generic_node (buffer, op0, spc, flags, false);
738 pp_character (buffer, '}');
741 break;
743 case BIT_FIELD_REF:
744 pp_string (buffer, "BIT_FIELD_REF <");
745 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
746 pp_string (buffer, ", ");
747 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
748 pp_string (buffer, ", ");
749 dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
750 pp_string (buffer, ">");
751 break;
753 case ARRAY_REF:
754 case ARRAY_RANGE_REF:
755 op0 = TREE_OPERAND (node, 0);
756 if (op_prio (op0) < op_prio (node))
757 pp_character (buffer, '(');
758 dump_generic_node (buffer, op0, spc, flags, false);
759 if (op_prio (op0) < op_prio (node))
760 pp_character (buffer, ')');
761 pp_character (buffer, '[');
762 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
763 if (TREE_CODE (node) == ARRAY_RANGE_REF)
764 pp_string (buffer, " ...");
765 pp_character (buffer, ']');
767 op0 = array_ref_low_bound (node);
768 op1 = array_ref_element_size (node);
770 if (!integer_zerop (op0)
771 || (TYPE_SIZE_UNIT (TREE_TYPE (node))
772 && !operand_equal_p (op1, TYPE_SIZE_UNIT (TREE_TYPE (node)), 0)))
774 pp_string (buffer, "{lb: ");
775 dump_generic_node (buffer, op0, spc, flags, false);
776 pp_string (buffer, " sz: ");
777 dump_generic_node (buffer, op1, spc, flags, false);
778 pp_character (buffer, '}');
780 break;
782 case CONSTRUCTOR:
784 unsigned HOST_WIDE_INT ix;
785 tree field, val;
786 bool is_struct_init = FALSE;
787 pp_character (buffer, '{');
788 if (TREE_CODE (TREE_TYPE (node)) == RECORD_TYPE
789 || TREE_CODE (TREE_TYPE (node)) == UNION_TYPE)
790 is_struct_init = TRUE;
791 FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (node), ix, field, val)
793 if (field && is_struct_init)
795 pp_character (buffer, '.');
796 dump_generic_node (buffer, field, spc, flags, false);
797 pp_string (buffer, "=");
799 if (val && TREE_CODE (val) == ADDR_EXPR)
800 if (TREE_CODE (TREE_OPERAND (val, 0)) == FUNCTION_DECL)
801 val = TREE_OPERAND (val, 0);
802 if (val && TREE_CODE (val) == FUNCTION_DECL)
803 dump_decl_name (buffer, val, flags);
804 else
805 dump_generic_node (buffer, val, spc, flags, false);
806 if (ix != VEC_length (constructor_elt, CONSTRUCTOR_ELTS (node)) - 1)
808 pp_character (buffer, ',');
809 pp_space (buffer);
812 pp_character (buffer, '}');
814 break;
816 case COMPOUND_EXPR:
818 tree *tp;
819 if (flags & TDF_SLIM)
821 pp_string (buffer, "<COMPOUND_EXPR>");
822 break;
825 dump_generic_node (buffer, TREE_OPERAND (node, 0),
826 spc, flags, dumping_stmts);
827 if (dumping_stmts)
828 newline_and_indent (buffer, spc);
829 else
831 pp_character (buffer, ',');
832 pp_space (buffer);
835 for (tp = &TREE_OPERAND (node, 1);
836 TREE_CODE (*tp) == COMPOUND_EXPR;
837 tp = &TREE_OPERAND (*tp, 1))
839 dump_generic_node (buffer, TREE_OPERAND (*tp, 0),
840 spc, flags, dumping_stmts);
841 if (dumping_stmts)
842 newline_and_indent (buffer, spc);
843 else
845 pp_character (buffer, ',');
846 pp_space (buffer);
850 dump_generic_node (buffer, *tp, spc, flags, dumping_stmts);
852 break;
854 case STATEMENT_LIST:
856 tree_stmt_iterator si;
857 bool first = true;
859 if ((flags & TDF_SLIM) || !dumping_stmts)
861 pp_string (buffer, "<STATEMENT_LIST>");
862 break;
865 for (si = tsi_start (node); !tsi_end_p (si); tsi_next (&si))
867 if (!first)
868 newline_and_indent (buffer, spc);
869 else
870 first = false;
871 dump_generic_node (buffer, tsi_stmt (si), spc, flags, true);
874 break;
876 case MODIFY_EXPR:
877 case INIT_EXPR:
878 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
879 pp_space (buffer);
880 pp_character (buffer, '=');
881 pp_space (buffer);
882 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
883 break;
885 case TARGET_EXPR:
886 pp_string (buffer, "TARGET_EXPR <");
887 dump_generic_node (buffer, TARGET_EXPR_SLOT (node), spc, flags, false);
888 pp_character (buffer, ',');
889 pp_space (buffer);
890 dump_generic_node (buffer, TARGET_EXPR_INITIAL (node), spc, flags, false);
891 pp_character (buffer, '>');
892 break;
894 case DECL_EXPR:
895 print_declaration (buffer, DECL_EXPR_DECL (node), spc, flags);
896 is_stmt = false;
897 break;
899 case COND_EXPR:
900 if (TREE_TYPE (node) == NULL || TREE_TYPE (node) == void_type_node)
902 pp_string (buffer, "if (");
903 dump_generic_node (buffer, COND_EXPR_COND (node), spc, flags, false);
904 pp_character (buffer, ')');
905 /* The lowered cond_exprs should always be printed in full. */
906 if (COND_EXPR_THEN (node)
907 && (IS_EMPTY_STMT (COND_EXPR_THEN (node))
908 || TREE_CODE (COND_EXPR_THEN (node)) == GOTO_EXPR)
909 && COND_EXPR_ELSE (node)
910 && (IS_EMPTY_STMT (COND_EXPR_ELSE (node))
911 || TREE_CODE (COND_EXPR_ELSE (node)) == GOTO_EXPR))
913 pp_space (buffer);
914 dump_generic_node (buffer, COND_EXPR_THEN (node), 0, flags, true);
915 pp_string (buffer, " else ");
916 dump_generic_node (buffer, COND_EXPR_ELSE (node), 0, flags, true);
918 else if (!(flags & TDF_SLIM))
920 /* Output COND_EXPR_THEN. */
921 if (COND_EXPR_THEN (node))
923 newline_and_indent (buffer, spc+2);
924 pp_character (buffer, '{');
925 newline_and_indent (buffer, spc+4);
926 dump_generic_node (buffer, COND_EXPR_THEN (node), spc+4,
927 flags, true);
928 newline_and_indent (buffer, spc+2);
929 pp_character (buffer, '}');
932 /* Output COND_EXPR_ELSE. */
933 if (COND_EXPR_ELSE (node))
935 newline_and_indent (buffer, spc);
936 pp_string (buffer, "else");
937 newline_and_indent (buffer, spc+2);
938 pp_character (buffer, '{');
939 newline_and_indent (buffer, spc+4);
940 dump_generic_node (buffer, COND_EXPR_ELSE (node), spc+4,
941 flags, true);
942 newline_and_indent (buffer, spc+2);
943 pp_character (buffer, '}');
946 is_expr = false;
948 else
950 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
951 pp_space (buffer);
952 pp_character (buffer, '?');
953 pp_space (buffer);
954 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
955 pp_space (buffer);
956 pp_character (buffer, ':');
957 pp_space (buffer);
958 dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
960 break;
962 case BIND_EXPR:
963 pp_character (buffer, '{');
964 if (!(flags & TDF_SLIM))
966 if (BIND_EXPR_VARS (node))
968 pp_newline (buffer);
970 for (op0 = BIND_EXPR_VARS (node); op0; op0 = TREE_CHAIN (op0))
972 print_declaration (buffer, op0, spc+2, flags);
973 pp_newline (buffer);
977 newline_and_indent (buffer, spc+2);
978 dump_generic_node (buffer, BIND_EXPR_BODY (node), spc+2, flags, true);
979 newline_and_indent (buffer, spc);
980 pp_character (buffer, '}');
982 is_expr = false;
983 break;
985 case CALL_EXPR:
986 print_call_name (buffer, node);
988 /* Print parameters. */
989 pp_space (buffer);
990 pp_character (buffer, '(');
991 op1 = TREE_OPERAND (node, 1);
992 if (op1)
993 dump_generic_node (buffer, op1, spc, flags, false);
994 pp_character (buffer, ')');
996 op1 = TREE_OPERAND (node, 2);
997 if (op1)
999 pp_string (buffer, " [static-chain: ");
1000 dump_generic_node (buffer, op1, spc, flags, false);
1001 pp_character (buffer, ']');
1004 if (CALL_EXPR_RETURN_SLOT_OPT (node))
1005 pp_string (buffer, " [return slot optimization]");
1006 if (CALL_EXPR_TAILCALL (node))
1007 pp_string (buffer, " [tail call]");
1008 break;
1010 case WITH_CLEANUP_EXPR:
1011 NIY;
1012 break;
1014 case CLEANUP_POINT_EXPR:
1015 pp_string (buffer, "<<cleanup_point ");
1016 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1017 pp_string (buffer, ">>");
1018 break;
1020 case PLACEHOLDER_EXPR:
1021 pp_string (buffer, "<PLACEHOLDER_EXPR ");
1022 dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
1023 pp_character (buffer, '>');
1024 break;
1026 /* Binary arithmetic and logic expressions. */
1027 case MULT_EXPR:
1028 case PLUS_EXPR:
1029 case MINUS_EXPR:
1030 case TRUNC_DIV_EXPR:
1031 case CEIL_DIV_EXPR:
1032 case FLOOR_DIV_EXPR:
1033 case ROUND_DIV_EXPR:
1034 case TRUNC_MOD_EXPR:
1035 case CEIL_MOD_EXPR:
1036 case FLOOR_MOD_EXPR:
1037 case ROUND_MOD_EXPR:
1038 case RDIV_EXPR:
1039 case EXACT_DIV_EXPR:
1040 case LSHIFT_EXPR:
1041 case RSHIFT_EXPR:
1042 case LROTATE_EXPR:
1043 case RROTATE_EXPR:
1044 case VEC_LSHIFT_EXPR:
1045 case VEC_RSHIFT_EXPR:
1046 case BIT_IOR_EXPR:
1047 case BIT_XOR_EXPR:
1048 case BIT_AND_EXPR:
1049 case TRUTH_ANDIF_EXPR:
1050 case TRUTH_ORIF_EXPR:
1051 case TRUTH_AND_EXPR:
1052 case TRUTH_OR_EXPR:
1053 case TRUTH_XOR_EXPR:
1054 case LT_EXPR:
1055 case LE_EXPR:
1056 case GT_EXPR:
1057 case GE_EXPR:
1058 case EQ_EXPR:
1059 case NE_EXPR:
1060 case UNLT_EXPR:
1061 case UNLE_EXPR:
1062 case UNGT_EXPR:
1063 case UNGE_EXPR:
1064 case UNEQ_EXPR:
1065 case LTGT_EXPR:
1066 case ORDERED_EXPR:
1067 case UNORDERED_EXPR:
1069 const char *op = op_symbol (node);
1070 op0 = TREE_OPERAND (node, 0);
1071 op1 = TREE_OPERAND (node, 1);
1073 /* When the operands are expressions with less priority,
1074 keep semantics of the tree representation. */
1075 if (op_prio (op0) < op_prio (node))
1077 pp_character (buffer, '(');
1078 dump_generic_node (buffer, op0, spc, flags, false);
1079 pp_character (buffer, ')');
1081 else
1082 dump_generic_node (buffer, op0, spc, flags, false);
1084 pp_space (buffer);
1085 pp_string (buffer, op);
1086 pp_space (buffer);
1088 /* When the operands are expressions with less priority,
1089 keep semantics of the tree representation. */
1090 if (op_prio (op1) < op_prio (node))
1092 pp_character (buffer, '(');
1093 dump_generic_node (buffer, op1, spc, flags, false);
1094 pp_character (buffer, ')');
1096 else
1097 dump_generic_node (buffer, op1, spc, flags, false);
1099 break;
1101 /* Unary arithmetic and logic expressions. */
1102 case NEGATE_EXPR:
1103 case BIT_NOT_EXPR:
1104 case TRUTH_NOT_EXPR:
1105 case ADDR_EXPR:
1106 case PREDECREMENT_EXPR:
1107 case PREINCREMENT_EXPR:
1108 case ALIGN_INDIRECT_REF:
1109 case MISALIGNED_INDIRECT_REF:
1110 case INDIRECT_REF:
1111 if (TREE_CODE (node) == ADDR_EXPR
1112 && (TREE_CODE (TREE_OPERAND (node, 0)) == STRING_CST
1113 || TREE_CODE (TREE_OPERAND (node, 0)) == FUNCTION_DECL))
1114 ; /* Do not output '&' for strings and function pointers. */
1115 else
1116 pp_string (buffer, op_symbol (node));
1118 if (op_prio (TREE_OPERAND (node, 0)) < op_prio (node))
1120 pp_character (buffer, '(');
1121 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1122 pp_character (buffer, ')');
1124 else
1125 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1127 if (TREE_CODE (node) == MISALIGNED_INDIRECT_REF)
1129 pp_string (buffer, "{misalignment: ");
1130 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1131 pp_character (buffer, '}');
1133 break;
1135 case POSTDECREMENT_EXPR:
1136 case POSTINCREMENT_EXPR:
1137 if (op_prio (TREE_OPERAND (node, 0)) < op_prio (node))
1139 pp_character (buffer, '(');
1140 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1141 pp_character (buffer, ')');
1143 else
1144 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1145 pp_string (buffer, op_symbol (node));
1146 break;
1148 case MIN_EXPR:
1149 pp_string (buffer, "MIN_EXPR <");
1150 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1151 pp_string (buffer, ", ");
1152 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1153 pp_character (buffer, '>');
1154 break;
1156 case MAX_EXPR:
1157 pp_string (buffer, "MAX_EXPR <");
1158 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1159 pp_string (buffer, ", ");
1160 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1161 pp_character (buffer, '>');
1162 break;
1164 case ABS_EXPR:
1165 pp_string (buffer, "ABS_EXPR <");
1166 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1167 pp_character (buffer, '>');
1168 break;
1170 case RANGE_EXPR:
1171 NIY;
1172 break;
1174 case FIX_TRUNC_EXPR:
1175 case FIX_CEIL_EXPR:
1176 case FIX_FLOOR_EXPR:
1177 case FIX_ROUND_EXPR:
1178 case FLOAT_EXPR:
1179 case CONVERT_EXPR:
1180 case NOP_EXPR:
1181 type = TREE_TYPE (node);
1182 op0 = TREE_OPERAND (node, 0);
1183 if (type != TREE_TYPE (op0))
1185 pp_character (buffer, '(');
1186 dump_generic_node (buffer, type, spc, flags, false);
1187 pp_string (buffer, ") ");
1189 if (op_prio (op0) < op_prio (node))
1190 pp_character (buffer, '(');
1191 dump_generic_node (buffer, op0, spc, flags, false);
1192 if (op_prio (op0) < op_prio (node))
1193 pp_character (buffer, ')');
1194 break;
1196 case VIEW_CONVERT_EXPR:
1197 pp_string (buffer, "VIEW_CONVERT_EXPR<");
1198 dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
1199 pp_string (buffer, ">(");
1200 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1201 pp_character (buffer, ')');
1202 break;
1204 case NON_LVALUE_EXPR:
1205 pp_string (buffer, "NON_LVALUE_EXPR <");
1206 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1207 pp_character (buffer, '>');
1208 break;
1210 case SAVE_EXPR:
1211 pp_string (buffer, "SAVE_EXPR <");
1212 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1213 pp_character (buffer, '>');
1214 break;
1216 case COMPLEX_EXPR:
1217 pp_string (buffer, "COMPLEX_EXPR <");
1218 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1219 pp_string (buffer, ", ");
1220 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1221 pp_string (buffer, ">");
1222 break;
1224 case CONJ_EXPR:
1225 pp_string (buffer, "CONJ_EXPR <");
1226 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1227 pp_string (buffer, ">");
1228 break;
1230 case REALPART_EXPR:
1231 pp_string (buffer, "REALPART_EXPR <");
1232 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1233 pp_string (buffer, ">");
1234 break;
1236 case IMAGPART_EXPR:
1237 pp_string (buffer, "IMAGPART_EXPR <");
1238 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1239 pp_string (buffer, ">");
1240 break;
1242 case VA_ARG_EXPR:
1243 pp_string (buffer, "VA_ARG_EXPR <");
1244 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1245 pp_string (buffer, ">");
1246 break;
1248 case TRY_FINALLY_EXPR:
1249 case TRY_CATCH_EXPR:
1250 pp_string (buffer, "try");
1251 newline_and_indent (buffer, spc+2);
1252 pp_string (buffer, "{");
1253 newline_and_indent (buffer, spc+4);
1254 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc+4, flags, true);
1255 newline_and_indent (buffer, spc+2);
1256 pp_string (buffer, "}");
1257 newline_and_indent (buffer, spc);
1258 pp_string (buffer,
1259 (TREE_CODE (node) == TRY_CATCH_EXPR) ? "catch" : "finally");
1260 newline_and_indent (buffer, spc+2);
1261 pp_string (buffer, "{");
1262 newline_and_indent (buffer, spc+4);
1263 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc+4, flags, true);
1264 newline_and_indent (buffer, spc+2);
1265 pp_string (buffer, "}");
1266 is_expr = false;
1267 break;
1269 case CATCH_EXPR:
1270 pp_string (buffer, "catch (");
1271 dump_generic_node (buffer, CATCH_TYPES (node), spc+2, flags, false);
1272 pp_string (buffer, ")");
1273 newline_and_indent (buffer, spc+2);
1274 pp_string (buffer, "{");
1275 newline_and_indent (buffer, spc+4);
1276 dump_generic_node (buffer, CATCH_BODY (node), spc+4, flags, true);
1277 newline_and_indent (buffer, spc+2);
1278 pp_string (buffer, "}");
1279 is_expr = false;
1280 break;
1282 case EH_FILTER_EXPR:
1283 pp_string (buffer, "<<<eh_filter (");
1284 dump_generic_node (buffer, EH_FILTER_TYPES (node), spc+2, flags, false);
1285 pp_string (buffer, ")>>>");
1286 newline_and_indent (buffer, spc+2);
1287 pp_string (buffer, "{");
1288 newline_and_indent (buffer, spc+4);
1289 dump_generic_node (buffer, EH_FILTER_FAILURE (node), spc+4, flags, true);
1290 newline_and_indent (buffer, spc+2);
1291 pp_string (buffer, "}");
1292 is_expr = false;
1293 break;
1295 case LABEL_EXPR:
1296 op0 = TREE_OPERAND (node, 0);
1297 /* If this is for break or continue, don't bother printing it. */
1298 if (DECL_NAME (op0))
1300 const char *name = IDENTIFIER_POINTER (DECL_NAME (op0));
1301 if (strcmp (name, "break") == 0
1302 || strcmp (name, "continue") == 0)
1303 break;
1305 dump_generic_node (buffer, op0, spc, flags, false);
1306 pp_character (buffer, ':');
1307 if (DECL_NONLOCAL (op0))
1308 pp_string (buffer, " [non-local]");
1309 break;
1311 case EXC_PTR_EXPR:
1312 pp_string (buffer, "<<<exception object>>>");
1313 break;
1315 case FILTER_EXPR:
1316 pp_string (buffer, "<<<filter object>>>");
1317 break;
1319 case LOOP_EXPR:
1320 pp_string (buffer, "while (1)");
1321 if (!(flags & TDF_SLIM))
1323 newline_and_indent (buffer, spc+2);
1324 pp_character (buffer, '{');
1325 newline_and_indent (buffer, spc+4);
1326 dump_generic_node (buffer, LOOP_EXPR_BODY (node), spc+4, flags, true);
1327 newline_and_indent (buffer, spc+2);
1328 pp_character (buffer, '}');
1330 is_expr = false;
1331 break;
1333 case RETURN_EXPR:
1334 pp_string (buffer, "return");
1335 op0 = TREE_OPERAND (node, 0);
1336 if (op0)
1338 pp_space (buffer);
1339 if (TREE_CODE (op0) == MODIFY_EXPR)
1340 dump_generic_node (buffer, TREE_OPERAND (op0, 1), spc, flags, false);
1341 else
1342 dump_generic_node (buffer, op0, spc, flags, false);
1344 break;
1346 case EXIT_EXPR:
1347 pp_string (buffer, "if (");
1348 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1349 pp_string (buffer, ") break");
1350 break;
1352 case SWITCH_EXPR:
1353 pp_string (buffer, "switch (");
1354 dump_generic_node (buffer, SWITCH_COND (node), spc, flags, false);
1355 pp_character (buffer, ')');
1356 if (!(flags & TDF_SLIM))
1358 newline_and_indent (buffer, spc+2);
1359 pp_character (buffer, '{');
1360 if (SWITCH_BODY (node))
1362 newline_and_indent (buffer, spc+4);
1363 dump_generic_node (buffer, SWITCH_BODY (node), spc+4, flags, true);
1365 else
1367 tree vec = SWITCH_LABELS (node);
1368 size_t i, n = TREE_VEC_LENGTH (vec);
1369 for (i = 0; i < n; ++i)
1371 tree elt = TREE_VEC_ELT (vec, i);
1372 newline_and_indent (buffer, spc+4);
1373 dump_generic_node (buffer, elt, spc+4, flags, false);
1374 pp_string (buffer, " goto ");
1375 dump_generic_node (buffer, CASE_LABEL (elt), spc+4, flags, true);
1376 pp_semicolon (buffer);
1379 newline_and_indent (buffer, spc+2);
1380 pp_character (buffer, '}');
1382 is_expr = false;
1383 break;
1385 case GOTO_EXPR:
1386 op0 = GOTO_DESTINATION (node);
1387 if (TREE_CODE (op0) != SSA_NAME && DECL_P (op0) && DECL_NAME (op0))
1389 const char *name = IDENTIFIER_POINTER (DECL_NAME (op0));
1390 if (strcmp (name, "break") == 0
1391 || strcmp (name, "continue") == 0)
1393 pp_string (buffer, name);
1394 break;
1397 pp_string (buffer, "goto ");
1398 dump_generic_node (buffer, op0, spc, flags, false);
1399 break;
1401 case RESX_EXPR:
1402 pp_string (buffer, "resx");
1403 /* ??? Any sensible way to present the eh region? */
1404 break;
1406 case ASM_EXPR:
1407 pp_string (buffer, "__asm__");
1408 if (ASM_VOLATILE_P (node))
1409 pp_string (buffer, " __volatile__");
1410 pp_character (buffer, '(');
1411 dump_generic_node (buffer, ASM_STRING (node), spc, flags, false);
1412 pp_character (buffer, ':');
1413 dump_generic_node (buffer, ASM_OUTPUTS (node), spc, flags, false);
1414 pp_character (buffer, ':');
1415 dump_generic_node (buffer, ASM_INPUTS (node), spc, flags, false);
1416 if (ASM_CLOBBERS (node))
1418 pp_character (buffer, ':');
1419 dump_generic_node (buffer, ASM_CLOBBERS (node), spc, flags, false);
1421 pp_string (buffer, ")");
1422 break;
1424 case CASE_LABEL_EXPR:
1425 if (CASE_LOW (node) && CASE_HIGH (node))
1427 pp_string (buffer, "case ");
1428 dump_generic_node (buffer, CASE_LOW (node), spc, flags, false);
1429 pp_string (buffer, " ... ");
1430 dump_generic_node (buffer, CASE_HIGH (node), spc, flags, false);
1432 else if (CASE_LOW (node))
1434 pp_string (buffer, "case ");
1435 dump_generic_node (buffer, CASE_LOW (node), spc, flags, false);
1437 else
1438 pp_string (buffer, "default ");
1439 pp_character (buffer, ':');
1440 break;
1442 case OBJ_TYPE_REF:
1443 pp_string (buffer, "OBJ_TYPE_REF(");
1444 dump_generic_node (buffer, OBJ_TYPE_REF_EXPR (node), spc, flags, false);
1445 pp_character (buffer, ';');
1446 dump_generic_node (buffer, OBJ_TYPE_REF_OBJECT (node), spc, flags, false);
1447 pp_character (buffer, '-');
1448 pp_character (buffer, '>');
1449 dump_generic_node (buffer, OBJ_TYPE_REF_TOKEN (node), spc, flags, false);
1450 pp_character (buffer, ')');
1451 break;
1453 case PHI_NODE:
1455 int i;
1457 dump_generic_node (buffer, PHI_RESULT (node), spc, flags, false);
1458 pp_string (buffer, " = PHI <");
1459 for (i = 0; i < PHI_NUM_ARGS (node); i++)
1461 dump_generic_node (buffer, PHI_ARG_DEF (node, i), spc, flags, false);
1462 pp_string (buffer, "(");
1463 pp_decimal_int (buffer, PHI_ARG_EDGE (node, i)->src->index);
1464 pp_string (buffer, ")");
1465 if (i < PHI_NUM_ARGS (node) - 1)
1466 pp_string (buffer, ", ");
1468 pp_string (buffer, ">;");
1470 break;
1472 case SSA_NAME:
1473 dump_generic_node (buffer, SSA_NAME_VAR (node), spc, flags, false);
1474 pp_string (buffer, "_");
1475 pp_decimal_int (buffer, SSA_NAME_VERSION (node));
1476 if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (node))
1477 pp_string (buffer, "(ab)");
1478 break;
1480 case WITH_SIZE_EXPR:
1481 pp_string (buffer, "WITH_SIZE_EXPR <");
1482 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1483 pp_string (buffer, ", ");
1484 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1485 pp_string (buffer, ">");
1486 break;
1488 case VALUE_HANDLE:
1489 pp_printf (buffer, "VH.%d", VALUE_HANDLE_ID (node));
1490 break;
1492 case ASSERT_EXPR:
1493 pp_string (buffer, "ASSERT_EXPR <");
1494 dump_generic_node (buffer, ASSERT_EXPR_VAR (node), spc, flags, false);
1495 pp_string (buffer, ", ");
1496 dump_generic_node (buffer, ASSERT_EXPR_COND (node), spc, flags, false);
1497 pp_string (buffer, ">");
1498 break;
1500 case SCEV_KNOWN:
1501 pp_string (buffer, "scev_known");
1502 break;
1504 case SCEV_NOT_KNOWN:
1505 pp_string (buffer, "scev_not_known");
1506 break;
1508 case POLYNOMIAL_CHREC:
1509 pp_string (buffer, "{");
1510 dump_generic_node (buffer, CHREC_LEFT (node), spc, flags, false);
1511 pp_string (buffer, ", +, ");
1512 dump_generic_node (buffer, CHREC_RIGHT (node), spc, flags, false);
1513 pp_string (buffer, "}_");
1514 dump_generic_node (buffer, CHREC_VAR (node), spc, flags, false);
1515 is_stmt = false;
1516 break;
1518 case REALIGN_LOAD_EXPR:
1519 pp_string (buffer, "REALIGN_LOAD <");
1520 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1521 pp_string (buffer, ", ");
1522 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1523 pp_string (buffer, ", ");
1524 dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
1525 pp_string (buffer, ">");
1526 break;
1528 case VEC_COND_EXPR:
1529 pp_string (buffer, " VEC_COND_EXPR < ");
1530 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1531 pp_string (buffer, " , ");
1532 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1533 pp_string (buffer, " , ");
1534 dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
1535 pp_string (buffer, " > ");
1536 break;
1538 case REDUC_MAX_EXPR:
1539 pp_string (buffer, " REDUC_MAX_EXPR < ");
1540 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1541 pp_string (buffer, " > ");
1542 break;
1544 case REDUC_MIN_EXPR:
1545 pp_string (buffer, " REDUC_MIN_EXPR < ");
1546 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1547 pp_string (buffer, " > ");
1548 break;
1550 case REDUC_PLUS_EXPR:
1551 pp_string (buffer, " REDUC_PLUS_EXPR < ");
1552 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1553 pp_string (buffer, " > ");
1554 break;
1556 default:
1557 NIY;
1560 if (is_stmt && is_expr)
1561 pp_semicolon (buffer);
1562 pp_write_text_to_stream (buffer);
1564 return spc;
1567 /* Print the declaration of a variable. */
1569 static void
1570 print_declaration (pretty_printer *buffer, tree t, int spc, int flags)
1572 INDENT (spc);
1574 if (TREE_CODE (t) == TYPE_DECL)
1575 pp_string (buffer, "typedef ");
1577 if (CODE_CONTAINS_STRUCT (TREE_CODE (t), TS_DECL_WRTL) && DECL_REGISTER (t))
1578 pp_string (buffer, "register ");
1580 if (TREE_PUBLIC (t) && DECL_EXTERNAL (t))
1581 pp_string (buffer, "extern ");
1582 else if (TREE_STATIC (t))
1583 pp_string (buffer, "static ");
1585 /* Print the type and name. */
1586 if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
1588 tree tmp;
1590 /* Print array's type. */
1591 tmp = TREE_TYPE (t);
1592 while (TREE_CODE (TREE_TYPE (tmp)) == ARRAY_TYPE)
1593 tmp = TREE_TYPE (tmp);
1594 dump_generic_node (buffer, TREE_TYPE (tmp), spc, flags, false);
1596 /* Print variable's name. */
1597 pp_space (buffer);
1598 dump_generic_node (buffer, t, spc, flags, false);
1600 /* Print the dimensions. */
1601 tmp = TREE_TYPE (t);
1602 while (TREE_CODE (tmp) == ARRAY_TYPE)
1604 dump_array_domain (buffer, TYPE_DOMAIN (tmp), spc, flags);
1605 tmp = TREE_TYPE (tmp);
1608 else if (TREE_CODE (t) == FUNCTION_DECL)
1610 dump_generic_node (buffer, TREE_TYPE (TREE_TYPE (t)), spc, flags, false);
1611 pp_space (buffer);
1612 dump_decl_name (buffer, t, flags);
1613 dump_function_declaration (buffer, TREE_TYPE (t), spc, flags);
1615 else
1617 /* Print type declaration. */
1618 dump_generic_node (buffer, TREE_TYPE (t), spc, flags, false);
1620 /* Print variable's name. */
1621 pp_space (buffer);
1622 dump_generic_node (buffer, t, spc, flags, false);
1625 if (TREE_CODE (t) == VAR_DECL && DECL_HARD_REGISTER (t))
1627 pp_string (buffer, " __asm__ ");
1628 pp_character (buffer, '(');
1629 dump_generic_node (buffer, DECL_ASSEMBLER_NAME (t), spc, flags, false);
1630 pp_character (buffer, ')');
1633 /* The initial value of a function serves to determine wether the function
1634 is declared or defined. So the following does not apply to function
1635 nodes. */
1636 if (TREE_CODE (t) != FUNCTION_DECL)
1638 /* Print the initial value. */
1639 if (DECL_INITIAL (t))
1641 pp_space (buffer);
1642 pp_character (buffer, '=');
1643 pp_space (buffer);
1644 dump_generic_node (buffer, DECL_INITIAL (t), spc, flags, false);
1648 pp_character (buffer, ';');
1652 /* Prints a structure: name, fields, and methods.
1653 FIXME: Still incomplete. */
1655 static void
1656 print_struct_decl (pretty_printer *buffer, tree node, int spc, int flags)
1658 /* Print the name of the structure. */
1659 if (TYPE_NAME (node))
1661 INDENT (spc);
1662 if (TREE_CODE (node) == RECORD_TYPE)
1663 pp_string (buffer, "struct ");
1664 else if ((TREE_CODE (node) == UNION_TYPE
1665 || TREE_CODE (node) == QUAL_UNION_TYPE))
1666 pp_string (buffer, "union ");
1668 dump_generic_node (buffer, TYPE_NAME (node), spc, 0, false);
1671 /* Print the contents of the structure. */
1672 pp_newline (buffer);
1673 INDENT (spc);
1674 pp_character (buffer, '{');
1675 pp_newline (buffer);
1677 /* Print the fields of the structure. */
1679 tree tmp;
1680 tmp = TYPE_FIELDS (node);
1681 while (tmp)
1683 /* Avoid to print recursively the structure. */
1684 /* FIXME : Not implemented correctly...,
1685 what about the case when we have a cycle in the contain graph? ...
1686 Maybe this could be solved by looking at the scope in which the
1687 structure was declared. */
1688 if (TREE_TYPE (tmp) != node
1689 || (TREE_CODE (TREE_TYPE (tmp)) == POINTER_TYPE
1690 && TREE_TYPE (TREE_TYPE (tmp)) != node))
1692 print_declaration (buffer, tmp, spc+2, flags);
1693 pp_newline (buffer);
1695 tmp = TREE_CHAIN (tmp);
1698 INDENT (spc);
1699 pp_character (buffer, '}');
1702 /* Return the priority of the operator OP.
1704 From lowest to highest precedence with either left-to-right (L-R)
1705 or right-to-left (R-L) associativity]:
1707 1 [L-R] ,
1708 2 [R-L] = += -= *= /= %= &= ^= |= <<= >>=
1709 3 [R-L] ?:
1710 4 [L-R] ||
1711 5 [L-R] &&
1712 6 [L-R] |
1713 7 [L-R] ^
1714 8 [L-R] &
1715 9 [L-R] == !=
1716 10 [L-R] < <= > >=
1717 11 [L-R] << >>
1718 12 [L-R] + -
1719 13 [L-R] * / %
1720 14 [R-L] ! ~ ++ -- + - * & (type) sizeof
1721 15 [L-R] fn() [] -> .
1723 unary +, - and * have higher precedence than the corresponding binary
1724 operators. */
1726 static int
1727 op_prio (tree op)
1729 if (op == NULL)
1730 return 9999;
1732 switch (TREE_CODE (op))
1734 case TREE_LIST:
1735 case COMPOUND_EXPR:
1736 case BIND_EXPR:
1737 return 1;
1739 case MODIFY_EXPR:
1740 case INIT_EXPR:
1741 return 2;
1743 case COND_EXPR:
1744 return 3;
1746 case TRUTH_OR_EXPR:
1747 case TRUTH_ORIF_EXPR:
1748 return 4;
1750 case TRUTH_AND_EXPR:
1751 case TRUTH_ANDIF_EXPR:
1752 return 5;
1754 case BIT_IOR_EXPR:
1755 return 6;
1757 case BIT_XOR_EXPR:
1758 case TRUTH_XOR_EXPR:
1759 return 7;
1761 case BIT_AND_EXPR:
1762 return 8;
1764 case EQ_EXPR:
1765 case NE_EXPR:
1766 return 9;
1768 case UNLT_EXPR:
1769 case UNLE_EXPR:
1770 case UNGT_EXPR:
1771 case UNGE_EXPR:
1772 case UNEQ_EXPR:
1773 case LTGT_EXPR:
1774 case ORDERED_EXPR:
1775 case UNORDERED_EXPR:
1776 case LT_EXPR:
1777 case LE_EXPR:
1778 case GT_EXPR:
1779 case GE_EXPR:
1780 return 10;
1782 case LSHIFT_EXPR:
1783 case RSHIFT_EXPR:
1784 case LROTATE_EXPR:
1785 case RROTATE_EXPR:
1786 return 11;
1788 case PLUS_EXPR:
1789 case MINUS_EXPR:
1790 return 12;
1792 case MULT_EXPR:
1793 case TRUNC_DIV_EXPR:
1794 case CEIL_DIV_EXPR:
1795 case FLOOR_DIV_EXPR:
1796 case ROUND_DIV_EXPR:
1797 case RDIV_EXPR:
1798 case EXACT_DIV_EXPR:
1799 case TRUNC_MOD_EXPR:
1800 case CEIL_MOD_EXPR:
1801 case FLOOR_MOD_EXPR:
1802 case ROUND_MOD_EXPR:
1803 return 13;
1805 case TRUTH_NOT_EXPR:
1806 case BIT_NOT_EXPR:
1807 case POSTINCREMENT_EXPR:
1808 case POSTDECREMENT_EXPR:
1809 case PREINCREMENT_EXPR:
1810 case PREDECREMENT_EXPR:
1811 case NEGATE_EXPR:
1812 case ALIGN_INDIRECT_REF:
1813 case MISALIGNED_INDIRECT_REF:
1814 case INDIRECT_REF:
1815 case ADDR_EXPR:
1816 case FLOAT_EXPR:
1817 case NOP_EXPR:
1818 case CONVERT_EXPR:
1819 case FIX_TRUNC_EXPR:
1820 case FIX_CEIL_EXPR:
1821 case FIX_FLOOR_EXPR:
1822 case FIX_ROUND_EXPR:
1823 case TARGET_EXPR:
1824 return 14;
1826 case CALL_EXPR:
1827 case ARRAY_REF:
1828 case ARRAY_RANGE_REF:
1829 case COMPONENT_REF:
1830 return 15;
1832 /* Special expressions. */
1833 case MIN_EXPR:
1834 case MAX_EXPR:
1835 case ABS_EXPR:
1836 case REALPART_EXPR:
1837 case IMAGPART_EXPR:
1838 case REDUC_MAX_EXPR:
1839 case REDUC_MIN_EXPR:
1840 case REDUC_PLUS_EXPR:
1841 case VEC_LSHIFT_EXPR:
1842 case VEC_RSHIFT_EXPR:
1843 return 16;
1845 case SAVE_EXPR:
1846 case NON_LVALUE_EXPR:
1847 return op_prio (TREE_OPERAND (op, 0));
1849 default:
1850 /* Return an arbitrarily high precedence to avoid surrounding single
1851 VAR_DECLs in ()s. */
1852 return 9999;
1857 /* Return the symbol associated with operator OP. */
1859 static const char *
1860 op_symbol (tree op)
1862 gcc_assert (op);
1864 switch (TREE_CODE (op))
1866 case MODIFY_EXPR:
1867 return "=";
1869 case TRUTH_OR_EXPR:
1870 case TRUTH_ORIF_EXPR:
1871 return "||";
1873 case TRUTH_AND_EXPR:
1874 case TRUTH_ANDIF_EXPR:
1875 return "&&";
1877 case BIT_IOR_EXPR:
1878 return "|";
1880 case TRUTH_XOR_EXPR:
1881 case BIT_XOR_EXPR:
1882 return "^";
1884 case ADDR_EXPR:
1885 case BIT_AND_EXPR:
1886 return "&";
1888 case ORDERED_EXPR:
1889 return "ord";
1890 case UNORDERED_EXPR:
1891 return "unord";
1893 case EQ_EXPR:
1894 return "==";
1895 case UNEQ_EXPR:
1896 return "u==";
1898 case NE_EXPR:
1899 return "!=";
1901 case LT_EXPR:
1902 return "<";
1903 case UNLT_EXPR:
1904 return "u<";
1906 case LE_EXPR:
1907 return "<=";
1908 case UNLE_EXPR:
1909 return "u<=";
1911 case GT_EXPR:
1912 return ">";
1913 case UNGT_EXPR:
1914 return "u>";
1916 case GE_EXPR:
1917 return ">=";
1918 case UNGE_EXPR:
1919 return "u>=";
1921 case LTGT_EXPR:
1922 return "<>";
1924 case LSHIFT_EXPR:
1925 return "<<";
1927 case RSHIFT_EXPR:
1928 return ">>";
1930 case VEC_LSHIFT_EXPR:
1931 return "v<<";
1933 case VEC_RSHIFT_EXPR:
1934 return "v>>";
1936 case PLUS_EXPR:
1937 return "+";
1939 case REDUC_PLUS_EXPR:
1940 return "r+";
1942 case NEGATE_EXPR:
1943 case MINUS_EXPR:
1944 return "-";
1946 case BIT_NOT_EXPR:
1947 return "~";
1949 case TRUTH_NOT_EXPR:
1950 return "!";
1952 case MULT_EXPR:
1953 case INDIRECT_REF:
1954 return "*";
1956 case ALIGN_INDIRECT_REF:
1957 return "A*";
1959 case MISALIGNED_INDIRECT_REF:
1960 return "M*";
1962 case TRUNC_DIV_EXPR:
1963 case RDIV_EXPR:
1964 return "/";
1966 case CEIL_DIV_EXPR:
1967 return "/[cl]";
1969 case FLOOR_DIV_EXPR:
1970 return "/[fl]";
1972 case ROUND_DIV_EXPR:
1973 return "/[rd]";
1975 case EXACT_DIV_EXPR:
1976 return "/[ex]";
1978 case TRUNC_MOD_EXPR:
1979 return "%";
1981 case CEIL_MOD_EXPR:
1982 return "%[cl]";
1984 case FLOOR_MOD_EXPR:
1985 return "%[fl]";
1987 case ROUND_MOD_EXPR:
1988 return "%[rd]";
1990 case PREDECREMENT_EXPR:
1991 return " --";
1993 case PREINCREMENT_EXPR:
1994 return " ++";
1996 case POSTDECREMENT_EXPR:
1997 return "-- ";
1999 case POSTINCREMENT_EXPR:
2000 return "++ ";
2002 default:
2003 return "<<< ??? >>>";
2007 /* Prints the name of a CALL_EXPR. */
2009 static void
2010 print_call_name (pretty_printer *buffer, tree node)
2012 tree op0;
2014 gcc_assert (TREE_CODE (node) == CALL_EXPR);
2016 op0 = TREE_OPERAND (node, 0);
2018 if (TREE_CODE (op0) == NON_LVALUE_EXPR)
2019 op0 = TREE_OPERAND (op0, 0);
2021 switch (TREE_CODE (op0))
2023 case VAR_DECL:
2024 case PARM_DECL:
2025 dump_function_name (buffer, op0);
2026 break;
2028 case ADDR_EXPR:
2029 case INDIRECT_REF:
2030 case NOP_EXPR:
2031 dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
2032 break;
2034 case COND_EXPR:
2035 pp_string (buffer, "(");
2036 dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
2037 pp_string (buffer, ") ? ");
2038 dump_generic_node (buffer, TREE_OPERAND (op0, 1), 0, 0, false);
2039 pp_string (buffer, " : ");
2040 dump_generic_node (buffer, TREE_OPERAND (op0, 2), 0, 0, false);
2041 break;
2043 case COMPONENT_REF:
2044 /* The function is a pointer contained in a structure. */
2045 if (TREE_CODE (TREE_OPERAND (op0, 0)) == INDIRECT_REF ||
2046 TREE_CODE (TREE_OPERAND (op0, 0)) == VAR_DECL)
2047 dump_function_name (buffer, TREE_OPERAND (op0, 1));
2048 else
2049 dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
2050 /* else
2051 We can have several levels of structures and a function
2052 pointer inside. This is not implemented yet... */
2053 /* NIY;*/
2054 break;
2056 case ARRAY_REF:
2057 if (TREE_CODE (TREE_OPERAND (op0, 0)) == VAR_DECL)
2058 dump_function_name (buffer, TREE_OPERAND (op0, 0));
2059 else
2060 dump_generic_node (buffer, op0, 0, 0, false);
2061 break;
2063 case SSA_NAME:
2064 case OBJ_TYPE_REF:
2065 dump_generic_node (buffer, op0, 0, 0, false);
2066 break;
2068 default:
2069 NIY;
2073 /* Parses the string STR and replaces new-lines by '\n', tabs by '\t', ... */
2075 static void
2076 pretty_print_string (pretty_printer *buffer, const char *str)
2078 if (str == NULL)
2079 return;
2081 while (*str)
2083 switch (str[0])
2085 case '\b':
2086 pp_string (buffer, "\\b");
2087 break;
2089 case '\f':
2090 pp_string (buffer, "\\f");
2091 break;
2093 case '\n':
2094 pp_string (buffer, "\\n");
2095 break;
2097 case '\r':
2098 pp_string (buffer, "\\r");
2099 break;
2101 case '\t':
2102 pp_string (buffer, "\\t");
2103 break;
2105 case '\v':
2106 pp_string (buffer, "\\v");
2107 break;
2109 case '\\':
2110 pp_string (buffer, "\\\\");
2111 break;
2113 case '\"':
2114 pp_string (buffer, "\\\"");
2115 break;
2117 case '\'':
2118 pp_string (buffer, "\\'");
2119 break;
2121 case '\0':
2122 pp_string (buffer, "\\0");
2123 break;
2125 case '\1':
2126 pp_string (buffer, "\\1");
2127 break;
2129 case '\2':
2130 pp_string (buffer, "\\2");
2131 break;
2133 case '\3':
2134 pp_string (buffer, "\\3");
2135 break;
2137 case '\4':
2138 pp_string (buffer, "\\4");
2139 break;
2141 case '\5':
2142 pp_string (buffer, "\\5");
2143 break;
2145 case '\6':
2146 pp_string (buffer, "\\6");
2147 break;
2149 case '\7':
2150 pp_string (buffer, "\\7");
2151 break;
2153 default:
2154 pp_character (buffer, str[0]);
2155 break;
2157 str++;
2161 static void
2162 maybe_init_pretty_print (FILE *file)
2164 if (!initialized)
2166 pp_construct (&buffer, /* prefix */NULL, /* line-width */0);
2167 pp_needs_newline (&buffer) = true;
2168 initialized = 1;
2171 buffer.buffer->stream = file;
2174 static void
2175 newline_and_indent (pretty_printer *buffer, int spc)
2177 pp_newline (buffer);
2178 INDENT (spc);
2181 static void
2182 dump_vops (pretty_printer *buffer, tree stmt, int spc, int flags)
2184 tree use;
2185 use_operand_p use_p;
2186 def_operand_p def_p;
2187 use_operand_p kill_p;
2188 ssa_op_iter iter;
2190 if (!ssa_operands_active ())
2191 return;
2193 FOR_EACH_SSA_MAYDEF_OPERAND (def_p, use_p, stmt, iter)
2195 pp_string (buffer, "# ");
2196 dump_generic_node (buffer, DEF_FROM_PTR (def_p),
2197 spc + 2, flags, false);
2198 pp_string (buffer, " = V_MAY_DEF <");
2199 dump_generic_node (buffer, USE_FROM_PTR (use_p),
2200 spc + 2, flags, false);
2201 pp_string (buffer, ">;");
2202 newline_and_indent (buffer, spc);
2205 FOR_EACH_SSA_MUSTDEF_OPERAND (def_p, kill_p, stmt, iter)
2207 pp_string (buffer, "# ");
2208 dump_generic_node (buffer, DEF_FROM_PTR (def_p),
2209 spc + 2, flags, false);
2210 pp_string (buffer, " = V_MUST_DEF <");
2211 dump_generic_node (buffer, USE_FROM_PTR (kill_p),
2212 spc + 2, flags, false);
2213 pp_string (buffer, ">;");
2214 newline_and_indent (buffer, spc);
2217 FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_VUSE)
2219 pp_string (buffer, "# VUSE <");
2220 dump_generic_node (buffer, use, spc + 2, flags, false);
2221 pp_string (buffer, ">;");
2222 newline_and_indent (buffer, spc);
2226 /* Dumps basic block BB to FILE with details described by FLAGS and
2227 indented by INDENT spaces. */
2229 void
2230 dump_generic_bb (FILE *file, basic_block bb, int indent, int flags)
2232 maybe_init_pretty_print (file);
2233 dumping_stmts = true;
2234 dump_generic_bb_buff (&buffer, bb, indent, flags);
2235 pp_flush (&buffer);
2238 /* Dumps header of basic block BB to buffer BUFFER indented by INDENT
2239 spaces and details described by flags. */
2241 static void
2242 dump_bb_header (pretty_printer *buffer, basic_block bb, int indent, int flags)
2244 edge e;
2245 tree stmt;
2246 edge_iterator ei;
2248 if (flags & TDF_BLOCKS)
2250 INDENT (indent);
2251 pp_string (buffer, "# BLOCK ");
2252 pp_decimal_int (buffer, bb->index);
2253 if (bb->frequency)
2255 pp_string (buffer, " freq:");
2256 pp_decimal_int (buffer, bb->frequency);
2258 if (bb->count)
2260 pp_string (buffer, " count:");
2261 pp_widest_integer (buffer, bb->count);
2264 if (flags & TDF_LINENO)
2266 block_stmt_iterator bsi;
2268 for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
2269 if (get_lineno (bsi_stmt (bsi)) != -1)
2271 pp_string (buffer, ", starting at line ");
2272 pp_decimal_int (buffer, get_lineno (bsi_stmt (bsi)));
2273 break;
2276 newline_and_indent (buffer, indent);
2278 pp_string (buffer, "# PRED:");
2279 pp_write_text_to_stream (buffer);
2280 FOR_EACH_EDGE (e, ei, bb->preds)
2281 if (flags & TDF_SLIM)
2283 pp_string (buffer, " ");
2284 if (e->src == ENTRY_BLOCK_PTR)
2285 pp_string (buffer, "ENTRY");
2286 else
2287 pp_decimal_int (buffer, e->src->index);
2289 else
2290 dump_edge_info (buffer->buffer->stream, e, 0);
2291 pp_newline (buffer);
2293 else
2295 stmt = first_stmt (bb);
2296 if (!stmt || TREE_CODE (stmt) != LABEL_EXPR)
2298 INDENT (indent - 2);
2299 pp_string (buffer, "<bb ");
2300 pp_decimal_int (buffer, bb->index);
2301 pp_string (buffer, ">:");
2302 pp_newline (buffer);
2305 pp_write_text_to_stream (buffer);
2306 check_bb_profile (bb, buffer->buffer->stream);
2309 /* Dumps end of basic block BB to buffer BUFFER indented by INDENT
2310 spaces. */
2312 static void
2313 dump_bb_end (pretty_printer *buffer, basic_block bb, int indent, int flags)
2315 edge e;
2316 edge_iterator ei;
2318 INDENT (indent);
2319 pp_string (buffer, "# SUCC:");
2320 pp_write_text_to_stream (buffer);
2321 FOR_EACH_EDGE (e, ei, bb->succs)
2322 if (flags & TDF_SLIM)
2324 pp_string (buffer, " ");
2325 if (e->dest == EXIT_BLOCK_PTR)
2326 pp_string (buffer, "EXIT");
2327 else
2328 pp_decimal_int (buffer, e->dest->index);
2330 else
2331 dump_edge_info (buffer->buffer->stream, e, 1);
2332 pp_newline (buffer);
2335 /* Dumps phi nodes of basic block BB to buffer BUFFER with details described by
2336 FLAGS indented by INDENT spaces. */
2338 static void
2339 dump_phi_nodes (pretty_printer *buffer, basic_block bb, int indent, int flags)
2341 tree phi = phi_nodes (bb);
2342 if (!phi)
2343 return;
2345 for (; phi; phi = PHI_CHAIN (phi))
2347 if (is_gimple_reg (PHI_RESULT (phi)) || (flags & TDF_VOPS))
2349 INDENT (indent);
2350 pp_string (buffer, "# ");
2351 dump_generic_node (buffer, phi, indent, flags, false);
2352 pp_newline (buffer);
2357 /* Dump jump to basic block BB that is represented implicitly in the cfg
2358 to BUFFER. */
2360 static void
2361 pp_cfg_jump (pretty_printer *buffer, basic_block bb)
2363 tree stmt;
2365 stmt = first_stmt (bb);
2367 pp_string (buffer, "goto <bb ");
2368 pp_decimal_int (buffer, bb->index);
2369 pp_string (buffer, ">");
2370 if (stmt && TREE_CODE (stmt) == LABEL_EXPR)
2372 pp_string (buffer, " (");
2373 dump_generic_node (buffer, LABEL_EXPR_LABEL (stmt), 0, 0, false);
2374 pp_string (buffer, ")");
2376 pp_semicolon (buffer);
2379 /* Dump edges represented implicitly in basic block BB to BUFFER, indented
2380 by INDENT spaces, with details given by FLAGS. */
2382 static void
2383 dump_implicit_edges (pretty_printer *buffer, basic_block bb, int indent,
2384 int flags)
2386 edge e;
2387 edge_iterator ei;
2389 /* If there is a fallthru edge, we may need to add an artificial goto to the
2390 dump. */
2391 FOR_EACH_EDGE (e, ei, bb->succs)
2392 if (e->flags & EDGE_FALLTHRU)
2393 break;
2394 if (e && e->dest != bb->next_bb)
2396 INDENT (indent);
2398 if ((flags & TDF_LINENO)
2399 #ifdef USE_MAPPED_LOCATION
2400 && e->goto_locus != UNKNOWN_LOCATION
2401 #else
2402 && e->goto_locus
2403 #endif
2406 expanded_location goto_xloc;
2407 #ifdef USE_MAPPED_LOCATION
2408 goto_xloc = expand_location (e->goto_locus);
2409 #else
2410 goto_xloc = *e->goto_locus;
2411 #endif
2412 pp_character (buffer, '[');
2413 if (goto_xloc.file)
2415 pp_string (buffer, goto_xloc.file);
2416 pp_string (buffer, " : ");
2418 pp_decimal_int (buffer, goto_xloc.line);
2419 pp_string (buffer, "] ");
2422 pp_cfg_jump (buffer, e->dest);
2423 pp_newline (buffer);
2427 /* Dumps basic block BB to buffer BUFFER with details described by FLAGS and
2428 indented by INDENT spaces. */
2430 static void
2431 dump_generic_bb_buff (pretty_printer *buffer, basic_block bb,
2432 int indent, int flags)
2434 block_stmt_iterator bsi;
2435 tree stmt;
2436 int label_indent = indent - 2;
2438 if (label_indent < 0)
2439 label_indent = 0;
2441 dump_bb_header (buffer, bb, indent, flags);
2443 dump_phi_nodes (buffer, bb, indent, flags);
2445 for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
2447 int curr_indent;
2449 stmt = bsi_stmt (bsi);
2451 curr_indent = TREE_CODE (stmt) == LABEL_EXPR ? label_indent : indent;
2453 INDENT (curr_indent);
2454 dump_generic_node (buffer, stmt, curr_indent, flags, true);
2455 pp_newline (buffer);
2458 dump_implicit_edges (buffer, bb, indent, flags);
2460 if (flags & TDF_BLOCKS)
2461 dump_bb_end (buffer, bb, indent, flags);