PR middle-end/25568
[official-gcc.git] / gcc / tree-pretty-print.c
blob313e461dc8517e7816eed8303090d8c41181fe24
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 LROTATE_EXPR:
1931 return "r<<";
1933 case RROTATE_EXPR:
1934 return "r>>";
1936 case VEC_LSHIFT_EXPR:
1937 return "v<<";
1939 case VEC_RSHIFT_EXPR:
1940 return "v>>";
1942 case PLUS_EXPR:
1943 return "+";
1945 case REDUC_PLUS_EXPR:
1946 return "r+";
1948 case NEGATE_EXPR:
1949 case MINUS_EXPR:
1950 return "-";
1952 case BIT_NOT_EXPR:
1953 return "~";
1955 case TRUTH_NOT_EXPR:
1956 return "!";
1958 case MULT_EXPR:
1959 case INDIRECT_REF:
1960 return "*";
1962 case ALIGN_INDIRECT_REF:
1963 return "A*";
1965 case MISALIGNED_INDIRECT_REF:
1966 return "M*";
1968 case TRUNC_DIV_EXPR:
1969 case RDIV_EXPR:
1970 return "/";
1972 case CEIL_DIV_EXPR:
1973 return "/[cl]";
1975 case FLOOR_DIV_EXPR:
1976 return "/[fl]";
1978 case ROUND_DIV_EXPR:
1979 return "/[rd]";
1981 case EXACT_DIV_EXPR:
1982 return "/[ex]";
1984 case TRUNC_MOD_EXPR:
1985 return "%";
1987 case CEIL_MOD_EXPR:
1988 return "%[cl]";
1990 case FLOOR_MOD_EXPR:
1991 return "%[fl]";
1993 case ROUND_MOD_EXPR:
1994 return "%[rd]";
1996 case PREDECREMENT_EXPR:
1997 return " --";
1999 case PREINCREMENT_EXPR:
2000 return " ++";
2002 case POSTDECREMENT_EXPR:
2003 return "-- ";
2005 case POSTINCREMENT_EXPR:
2006 return "++ ";
2008 default:
2009 return "<<< ??? >>>";
2013 /* Prints the name of a CALL_EXPR. */
2015 static void
2016 print_call_name (pretty_printer *buffer, tree node)
2018 tree op0;
2020 gcc_assert (TREE_CODE (node) == CALL_EXPR);
2022 op0 = TREE_OPERAND (node, 0);
2024 if (TREE_CODE (op0) == NON_LVALUE_EXPR)
2025 op0 = TREE_OPERAND (op0, 0);
2027 switch (TREE_CODE (op0))
2029 case VAR_DECL:
2030 case PARM_DECL:
2031 dump_function_name (buffer, op0);
2032 break;
2034 case ADDR_EXPR:
2035 case INDIRECT_REF:
2036 case NOP_EXPR:
2037 dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
2038 break;
2040 case COND_EXPR:
2041 pp_string (buffer, "(");
2042 dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
2043 pp_string (buffer, ") ? ");
2044 dump_generic_node (buffer, TREE_OPERAND (op0, 1), 0, 0, false);
2045 pp_string (buffer, " : ");
2046 dump_generic_node (buffer, TREE_OPERAND (op0, 2), 0, 0, false);
2047 break;
2049 case COMPONENT_REF:
2050 /* The function is a pointer contained in a structure. */
2051 if (TREE_CODE (TREE_OPERAND (op0, 0)) == INDIRECT_REF ||
2052 TREE_CODE (TREE_OPERAND (op0, 0)) == VAR_DECL)
2053 dump_function_name (buffer, TREE_OPERAND (op0, 1));
2054 else
2055 dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
2056 /* else
2057 We can have several levels of structures and a function
2058 pointer inside. This is not implemented yet... */
2059 /* NIY;*/
2060 break;
2062 case ARRAY_REF:
2063 if (TREE_CODE (TREE_OPERAND (op0, 0)) == VAR_DECL)
2064 dump_function_name (buffer, TREE_OPERAND (op0, 0));
2065 else
2066 dump_generic_node (buffer, op0, 0, 0, false);
2067 break;
2069 case SSA_NAME:
2070 case OBJ_TYPE_REF:
2071 dump_generic_node (buffer, op0, 0, 0, false);
2072 break;
2074 default:
2075 NIY;
2079 /* Parses the string STR and replaces new-lines by '\n', tabs by '\t', ... */
2081 static void
2082 pretty_print_string (pretty_printer *buffer, const char *str)
2084 if (str == NULL)
2085 return;
2087 while (*str)
2089 switch (str[0])
2091 case '\b':
2092 pp_string (buffer, "\\b");
2093 break;
2095 case '\f':
2096 pp_string (buffer, "\\f");
2097 break;
2099 case '\n':
2100 pp_string (buffer, "\\n");
2101 break;
2103 case '\r':
2104 pp_string (buffer, "\\r");
2105 break;
2107 case '\t':
2108 pp_string (buffer, "\\t");
2109 break;
2111 case '\v':
2112 pp_string (buffer, "\\v");
2113 break;
2115 case '\\':
2116 pp_string (buffer, "\\\\");
2117 break;
2119 case '\"':
2120 pp_string (buffer, "\\\"");
2121 break;
2123 case '\'':
2124 pp_string (buffer, "\\'");
2125 break;
2127 case '\0':
2128 pp_string (buffer, "\\0");
2129 break;
2131 case '\1':
2132 pp_string (buffer, "\\1");
2133 break;
2135 case '\2':
2136 pp_string (buffer, "\\2");
2137 break;
2139 case '\3':
2140 pp_string (buffer, "\\3");
2141 break;
2143 case '\4':
2144 pp_string (buffer, "\\4");
2145 break;
2147 case '\5':
2148 pp_string (buffer, "\\5");
2149 break;
2151 case '\6':
2152 pp_string (buffer, "\\6");
2153 break;
2155 case '\7':
2156 pp_string (buffer, "\\7");
2157 break;
2159 default:
2160 pp_character (buffer, str[0]);
2161 break;
2163 str++;
2167 static void
2168 maybe_init_pretty_print (FILE *file)
2170 if (!initialized)
2172 pp_construct (&buffer, /* prefix */NULL, /* line-width */0);
2173 pp_needs_newline (&buffer) = true;
2174 initialized = 1;
2177 buffer.buffer->stream = file;
2180 static void
2181 newline_and_indent (pretty_printer *buffer, int spc)
2183 pp_newline (buffer);
2184 INDENT (spc);
2187 static void
2188 dump_vops (pretty_printer *buffer, tree stmt, int spc, int flags)
2190 tree use;
2191 use_operand_p use_p;
2192 def_operand_p def_p;
2193 use_operand_p kill_p;
2194 ssa_op_iter iter;
2196 if (!ssa_operands_active ())
2197 return;
2199 FOR_EACH_SSA_MAYDEF_OPERAND (def_p, use_p, stmt, iter)
2201 pp_string (buffer, "# ");
2202 dump_generic_node (buffer, DEF_FROM_PTR (def_p),
2203 spc + 2, flags, false);
2204 pp_string (buffer, " = V_MAY_DEF <");
2205 dump_generic_node (buffer, USE_FROM_PTR (use_p),
2206 spc + 2, flags, false);
2207 pp_string (buffer, ">;");
2208 newline_and_indent (buffer, spc);
2211 FOR_EACH_SSA_MUSTDEF_OPERAND (def_p, kill_p, stmt, iter)
2213 pp_string (buffer, "# ");
2214 dump_generic_node (buffer, DEF_FROM_PTR (def_p),
2215 spc + 2, flags, false);
2216 pp_string (buffer, " = V_MUST_DEF <");
2217 dump_generic_node (buffer, USE_FROM_PTR (kill_p),
2218 spc + 2, flags, false);
2219 pp_string (buffer, ">;");
2220 newline_and_indent (buffer, spc);
2223 FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_VUSE)
2225 pp_string (buffer, "# VUSE <");
2226 dump_generic_node (buffer, use, spc + 2, flags, false);
2227 pp_string (buffer, ">;");
2228 newline_and_indent (buffer, spc);
2232 /* Dumps basic block BB to FILE with details described by FLAGS and
2233 indented by INDENT spaces. */
2235 void
2236 dump_generic_bb (FILE *file, basic_block bb, int indent, int flags)
2238 maybe_init_pretty_print (file);
2239 dumping_stmts = true;
2240 dump_generic_bb_buff (&buffer, bb, indent, flags);
2241 pp_flush (&buffer);
2244 /* Dumps header of basic block BB to buffer BUFFER indented by INDENT
2245 spaces and details described by flags. */
2247 static void
2248 dump_bb_header (pretty_printer *buffer, basic_block bb, int indent, int flags)
2250 edge e;
2251 tree stmt;
2252 edge_iterator ei;
2254 if (flags & TDF_BLOCKS)
2256 INDENT (indent);
2257 pp_string (buffer, "# BLOCK ");
2258 pp_decimal_int (buffer, bb->index);
2259 if (bb->frequency)
2261 pp_string (buffer, " freq:");
2262 pp_decimal_int (buffer, bb->frequency);
2264 if (bb->count)
2266 pp_string (buffer, " count:");
2267 pp_widest_integer (buffer, bb->count);
2270 if (flags & TDF_LINENO)
2272 block_stmt_iterator bsi;
2274 for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
2275 if (get_lineno (bsi_stmt (bsi)) != -1)
2277 pp_string (buffer, ", starting at line ");
2278 pp_decimal_int (buffer, get_lineno (bsi_stmt (bsi)));
2279 break;
2282 newline_and_indent (buffer, indent);
2284 pp_string (buffer, "# PRED:");
2285 pp_write_text_to_stream (buffer);
2286 FOR_EACH_EDGE (e, ei, bb->preds)
2287 if (flags & TDF_SLIM)
2289 pp_string (buffer, " ");
2290 if (e->src == ENTRY_BLOCK_PTR)
2291 pp_string (buffer, "ENTRY");
2292 else
2293 pp_decimal_int (buffer, e->src->index);
2295 else
2296 dump_edge_info (buffer->buffer->stream, e, 0);
2297 pp_newline (buffer);
2299 else
2301 stmt = first_stmt (bb);
2302 if (!stmt || TREE_CODE (stmt) != LABEL_EXPR)
2304 INDENT (indent - 2);
2305 pp_string (buffer, "<bb ");
2306 pp_decimal_int (buffer, bb->index);
2307 pp_string (buffer, ">:");
2308 pp_newline (buffer);
2311 pp_write_text_to_stream (buffer);
2312 check_bb_profile (bb, buffer->buffer->stream);
2315 /* Dumps end of basic block BB to buffer BUFFER indented by INDENT
2316 spaces. */
2318 static void
2319 dump_bb_end (pretty_printer *buffer, basic_block bb, int indent, int flags)
2321 edge e;
2322 edge_iterator ei;
2324 INDENT (indent);
2325 pp_string (buffer, "# SUCC:");
2326 pp_write_text_to_stream (buffer);
2327 FOR_EACH_EDGE (e, ei, bb->succs)
2328 if (flags & TDF_SLIM)
2330 pp_string (buffer, " ");
2331 if (e->dest == EXIT_BLOCK_PTR)
2332 pp_string (buffer, "EXIT");
2333 else
2334 pp_decimal_int (buffer, e->dest->index);
2336 else
2337 dump_edge_info (buffer->buffer->stream, e, 1);
2338 pp_newline (buffer);
2341 /* Dumps phi nodes of basic block BB to buffer BUFFER with details described by
2342 FLAGS indented by INDENT spaces. */
2344 static void
2345 dump_phi_nodes (pretty_printer *buffer, basic_block bb, int indent, int flags)
2347 tree phi = phi_nodes (bb);
2348 if (!phi)
2349 return;
2351 for (; phi; phi = PHI_CHAIN (phi))
2353 if (is_gimple_reg (PHI_RESULT (phi)) || (flags & TDF_VOPS))
2355 INDENT (indent);
2356 pp_string (buffer, "# ");
2357 dump_generic_node (buffer, phi, indent, flags, false);
2358 pp_newline (buffer);
2363 /* Dump jump to basic block BB that is represented implicitly in the cfg
2364 to BUFFER. */
2366 static void
2367 pp_cfg_jump (pretty_printer *buffer, basic_block bb)
2369 tree stmt;
2371 stmt = first_stmt (bb);
2373 pp_string (buffer, "goto <bb ");
2374 pp_decimal_int (buffer, bb->index);
2375 pp_string (buffer, ">");
2376 if (stmt && TREE_CODE (stmt) == LABEL_EXPR)
2378 pp_string (buffer, " (");
2379 dump_generic_node (buffer, LABEL_EXPR_LABEL (stmt), 0, 0, false);
2380 pp_string (buffer, ")");
2382 pp_semicolon (buffer);
2385 /* Dump edges represented implicitly in basic block BB to BUFFER, indented
2386 by INDENT spaces, with details given by FLAGS. */
2388 static void
2389 dump_implicit_edges (pretty_printer *buffer, basic_block bb, int indent,
2390 int flags)
2392 edge e;
2393 edge_iterator ei;
2395 /* If there is a fallthru edge, we may need to add an artificial goto to the
2396 dump. */
2397 FOR_EACH_EDGE (e, ei, bb->succs)
2398 if (e->flags & EDGE_FALLTHRU)
2399 break;
2400 if (e && e->dest != bb->next_bb)
2402 INDENT (indent);
2404 if ((flags & TDF_LINENO)
2405 #ifdef USE_MAPPED_LOCATION
2406 && e->goto_locus != UNKNOWN_LOCATION
2407 #else
2408 && e->goto_locus
2409 #endif
2412 expanded_location goto_xloc;
2413 #ifdef USE_MAPPED_LOCATION
2414 goto_xloc = expand_location (e->goto_locus);
2415 #else
2416 goto_xloc = *e->goto_locus;
2417 #endif
2418 pp_character (buffer, '[');
2419 if (goto_xloc.file)
2421 pp_string (buffer, goto_xloc.file);
2422 pp_string (buffer, " : ");
2424 pp_decimal_int (buffer, goto_xloc.line);
2425 pp_string (buffer, "] ");
2428 pp_cfg_jump (buffer, e->dest);
2429 pp_newline (buffer);
2433 /* Dumps basic block BB to buffer BUFFER with details described by FLAGS and
2434 indented by INDENT spaces. */
2436 static void
2437 dump_generic_bb_buff (pretty_printer *buffer, basic_block bb,
2438 int indent, int flags)
2440 block_stmt_iterator bsi;
2441 tree stmt;
2442 int label_indent = indent - 2;
2444 if (label_indent < 0)
2445 label_indent = 0;
2447 dump_bb_header (buffer, bb, indent, flags);
2449 dump_phi_nodes (buffer, bb, indent, flags);
2451 for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
2453 int curr_indent;
2455 stmt = bsi_stmt (bsi);
2457 curr_indent = TREE_CODE (stmt) == LABEL_EXPR ? label_indent : indent;
2459 INDENT (curr_indent);
2460 dump_generic_node (buffer, stmt, curr_indent, flags, true);
2461 pp_newline (buffer);
2464 dump_implicit_edges (buffer, bb, indent, flags);
2466 if (flags & TDF_BLOCKS)
2467 dump_bb_end (buffer, bb, indent, flags);