* config/m32c/m32c.c (m32c_valid_pointer_mode): Remove stray debug
[official-gcc.git] / gcc / tree-pretty-print.c
blob6fa0326d429c75e46804f42a2c13785b7947f8df
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 VAR_DECL:
702 case PARM_DECL:
703 case FIELD_DECL:
704 case NAMESPACE_DECL:
705 dump_decl_name (buffer, node, flags);
706 break;
708 case RESULT_DECL:
709 pp_string (buffer, "<retval>");
710 break;
712 case COMPONENT_REF:
713 op0 = TREE_OPERAND (node, 0);
714 str = ".";
715 if (TREE_CODE (op0) == INDIRECT_REF)
717 op0 = TREE_OPERAND (op0, 0);
718 str = "->";
720 if (op_prio (op0) < op_prio (node))
721 pp_character (buffer, '(');
722 dump_generic_node (buffer, op0, spc, flags, false);
723 if (op_prio (op0) < op_prio (node))
724 pp_character (buffer, ')');
725 pp_string (buffer, str);
726 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
728 if (TREE_CODE (op0) != VALUE_HANDLE)
730 op0 = component_ref_field_offset (node);
731 if (op0 && TREE_CODE (op0) != INTEGER_CST)
733 pp_string (buffer, "{off: ");
734 dump_generic_node (buffer, op0, spc, flags, false);
735 pp_character (buffer, '}');
738 break;
740 case BIT_FIELD_REF:
741 pp_string (buffer, "BIT_FIELD_REF <");
742 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
743 pp_string (buffer, ", ");
744 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
745 pp_string (buffer, ", ");
746 dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
747 pp_string (buffer, ">");
748 break;
750 case ARRAY_REF:
751 case ARRAY_RANGE_REF:
752 op0 = TREE_OPERAND (node, 0);
753 if (op_prio (op0) < op_prio (node))
754 pp_character (buffer, '(');
755 dump_generic_node (buffer, op0, spc, flags, false);
756 if (op_prio (op0) < op_prio (node))
757 pp_character (buffer, ')');
758 pp_character (buffer, '[');
759 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
760 if (TREE_CODE (node) == ARRAY_RANGE_REF)
761 pp_string (buffer, " ...");
762 pp_character (buffer, ']');
764 op0 = array_ref_low_bound (node);
765 op1 = array_ref_element_size (node);
767 if (!integer_zerop (op0)
768 || (TYPE_SIZE_UNIT (TREE_TYPE (node))
769 && !operand_equal_p (op1, TYPE_SIZE_UNIT (TREE_TYPE (node)), 0)))
771 pp_string (buffer, "{lb: ");
772 dump_generic_node (buffer, op0, spc, flags, false);
773 pp_string (buffer, " sz: ");
774 dump_generic_node (buffer, op1, spc, flags, false);
775 pp_character (buffer, '}');
777 break;
779 case CONSTRUCTOR:
781 unsigned HOST_WIDE_INT ix;
782 tree field, val;
783 bool is_struct_init = FALSE;
784 pp_character (buffer, '{');
785 if (TREE_CODE (TREE_TYPE (node)) == RECORD_TYPE
786 || TREE_CODE (TREE_TYPE (node)) == UNION_TYPE)
787 is_struct_init = TRUE;
788 FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (node), ix, field, val)
790 if (field && is_struct_init)
792 pp_character (buffer, '.');
793 dump_generic_node (buffer, field, spc, flags, false);
794 pp_string (buffer, "=");
796 if (val && TREE_CODE (val) == ADDR_EXPR)
797 if (TREE_CODE (TREE_OPERAND (val, 0)) == FUNCTION_DECL)
798 val = TREE_OPERAND (val, 0);
799 if (val && TREE_CODE (val) == FUNCTION_DECL)
800 dump_decl_name (buffer, val, flags);
801 else
802 dump_generic_node (buffer, val, spc, flags, false);
803 if (ix != VEC_length (constructor_elt, CONSTRUCTOR_ELTS (node)) - 1)
805 pp_character (buffer, ',');
806 pp_space (buffer);
809 pp_character (buffer, '}');
811 break;
813 case COMPOUND_EXPR:
815 tree *tp;
816 if (flags & TDF_SLIM)
818 pp_string (buffer, "<COMPOUND_EXPR>");
819 break;
822 dump_generic_node (buffer, TREE_OPERAND (node, 0),
823 spc, flags, dumping_stmts);
824 if (dumping_stmts)
825 newline_and_indent (buffer, spc);
826 else
828 pp_character (buffer, ',');
829 pp_space (buffer);
832 for (tp = &TREE_OPERAND (node, 1);
833 TREE_CODE (*tp) == COMPOUND_EXPR;
834 tp = &TREE_OPERAND (*tp, 1))
836 dump_generic_node (buffer, TREE_OPERAND (*tp, 0),
837 spc, flags, dumping_stmts);
838 if (dumping_stmts)
839 newline_and_indent (buffer, spc);
840 else
842 pp_character (buffer, ',');
843 pp_space (buffer);
847 dump_generic_node (buffer, *tp, spc, flags, dumping_stmts);
849 break;
851 case STATEMENT_LIST:
853 tree_stmt_iterator si;
854 bool first = true;
856 if ((flags & TDF_SLIM) || !dumping_stmts)
858 pp_string (buffer, "<STATEMENT_LIST>");
859 break;
862 for (si = tsi_start (node); !tsi_end_p (si); tsi_next (&si))
864 if (!first)
865 newline_and_indent (buffer, spc);
866 else
867 first = false;
868 dump_generic_node (buffer, tsi_stmt (si), spc, flags, true);
871 break;
873 case MODIFY_EXPR:
874 case INIT_EXPR:
875 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
876 pp_space (buffer);
877 pp_character (buffer, '=');
878 pp_space (buffer);
879 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
880 break;
882 case TARGET_EXPR:
883 pp_string (buffer, "TARGET_EXPR <");
884 dump_generic_node (buffer, TARGET_EXPR_SLOT (node), spc, flags, false);
885 pp_character (buffer, ',');
886 pp_space (buffer);
887 dump_generic_node (buffer, TARGET_EXPR_INITIAL (node), spc, flags, false);
888 pp_character (buffer, '>');
889 break;
891 case DECL_EXPR:
892 print_declaration (buffer, DECL_EXPR_DECL (node), spc, flags);
893 is_stmt = false;
894 break;
896 case COND_EXPR:
897 if (TREE_TYPE (node) == NULL || TREE_TYPE (node) == void_type_node)
899 pp_string (buffer, "if (");
900 dump_generic_node (buffer, COND_EXPR_COND (node), spc, flags, false);
901 pp_character (buffer, ')');
902 /* The lowered cond_exprs should always be printed in full. */
903 if (COND_EXPR_THEN (node)
904 && (IS_EMPTY_STMT (COND_EXPR_THEN (node))
905 || TREE_CODE (COND_EXPR_THEN (node)) == GOTO_EXPR)
906 && COND_EXPR_ELSE (node)
907 && (IS_EMPTY_STMT (COND_EXPR_ELSE (node))
908 || TREE_CODE (COND_EXPR_ELSE (node)) == GOTO_EXPR))
910 pp_space (buffer);
911 dump_generic_node (buffer, COND_EXPR_THEN (node), 0, flags, true);
912 pp_string (buffer, " else ");
913 dump_generic_node (buffer, COND_EXPR_ELSE (node), 0, flags, true);
915 else if (!(flags & TDF_SLIM))
917 /* Output COND_EXPR_THEN. */
918 if (COND_EXPR_THEN (node))
920 newline_and_indent (buffer, spc+2);
921 pp_character (buffer, '{');
922 newline_and_indent (buffer, spc+4);
923 dump_generic_node (buffer, COND_EXPR_THEN (node), spc+4,
924 flags, true);
925 newline_and_indent (buffer, spc+2);
926 pp_character (buffer, '}');
929 /* Output COND_EXPR_ELSE. */
930 if (COND_EXPR_ELSE (node))
932 newline_and_indent (buffer, spc);
933 pp_string (buffer, "else");
934 newline_and_indent (buffer, spc+2);
935 pp_character (buffer, '{');
936 newline_and_indent (buffer, spc+4);
937 dump_generic_node (buffer, COND_EXPR_ELSE (node), spc+4,
938 flags, true);
939 newline_and_indent (buffer, spc+2);
940 pp_character (buffer, '}');
943 is_expr = false;
945 else
947 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
948 pp_space (buffer);
949 pp_character (buffer, '?');
950 pp_space (buffer);
951 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
952 pp_space (buffer);
953 pp_character (buffer, ':');
954 pp_space (buffer);
955 dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
957 break;
959 case BIND_EXPR:
960 pp_character (buffer, '{');
961 if (!(flags & TDF_SLIM))
963 if (BIND_EXPR_VARS (node))
965 pp_newline (buffer);
967 for (op0 = BIND_EXPR_VARS (node); op0; op0 = TREE_CHAIN (op0))
969 print_declaration (buffer, op0, spc+2, flags);
970 pp_newline (buffer);
974 newline_and_indent (buffer, spc+2);
975 dump_generic_node (buffer, BIND_EXPR_BODY (node), spc+2, flags, true);
976 newline_and_indent (buffer, spc);
977 pp_character (buffer, '}');
979 is_expr = false;
980 break;
982 case CALL_EXPR:
983 print_call_name (buffer, node);
985 /* Print parameters. */
986 pp_space (buffer);
987 pp_character (buffer, '(');
988 op1 = TREE_OPERAND (node, 1);
989 if (op1)
990 dump_generic_node (buffer, op1, spc, flags, false);
991 pp_character (buffer, ')');
993 op1 = TREE_OPERAND (node, 2);
994 if (op1)
996 pp_string (buffer, " [static-chain: ");
997 dump_generic_node (buffer, op1, spc, flags, false);
998 pp_character (buffer, ']');
1001 if (CALL_EXPR_RETURN_SLOT_OPT (node))
1002 pp_string (buffer, " [return slot optimization]");
1003 if (CALL_EXPR_TAILCALL (node))
1004 pp_string (buffer, " [tail call]");
1005 break;
1007 case WITH_CLEANUP_EXPR:
1008 NIY;
1009 break;
1011 case CLEANUP_POINT_EXPR:
1012 pp_string (buffer, "<<cleanup_point ");
1013 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1014 pp_string (buffer, ">>");
1015 break;
1017 case PLACEHOLDER_EXPR:
1018 pp_string (buffer, "<PLACEHOLDER_EXPR ");
1019 dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
1020 pp_character (buffer, '>');
1021 break;
1023 /* Binary arithmetic and logic expressions. */
1024 case MULT_EXPR:
1025 case PLUS_EXPR:
1026 case MINUS_EXPR:
1027 case TRUNC_DIV_EXPR:
1028 case CEIL_DIV_EXPR:
1029 case FLOOR_DIV_EXPR:
1030 case ROUND_DIV_EXPR:
1031 case TRUNC_MOD_EXPR:
1032 case CEIL_MOD_EXPR:
1033 case FLOOR_MOD_EXPR:
1034 case ROUND_MOD_EXPR:
1035 case RDIV_EXPR:
1036 case EXACT_DIV_EXPR:
1037 case LSHIFT_EXPR:
1038 case RSHIFT_EXPR:
1039 case LROTATE_EXPR:
1040 case RROTATE_EXPR:
1041 case VEC_LSHIFT_EXPR:
1042 case VEC_RSHIFT_EXPR:
1043 case BIT_IOR_EXPR:
1044 case BIT_XOR_EXPR:
1045 case BIT_AND_EXPR:
1046 case TRUTH_ANDIF_EXPR:
1047 case TRUTH_ORIF_EXPR:
1048 case TRUTH_AND_EXPR:
1049 case TRUTH_OR_EXPR:
1050 case TRUTH_XOR_EXPR:
1051 case LT_EXPR:
1052 case LE_EXPR:
1053 case GT_EXPR:
1054 case GE_EXPR:
1055 case EQ_EXPR:
1056 case NE_EXPR:
1057 case UNLT_EXPR:
1058 case UNLE_EXPR:
1059 case UNGT_EXPR:
1060 case UNGE_EXPR:
1061 case UNEQ_EXPR:
1062 case LTGT_EXPR:
1063 case ORDERED_EXPR:
1064 case UNORDERED_EXPR:
1066 const char *op = op_symbol (node);
1067 op0 = TREE_OPERAND (node, 0);
1068 op1 = TREE_OPERAND (node, 1);
1070 /* When the operands are expressions with less priority,
1071 keep semantics of the tree representation. */
1072 if (op_prio (op0) < op_prio (node))
1074 pp_character (buffer, '(');
1075 dump_generic_node (buffer, op0, spc, flags, false);
1076 pp_character (buffer, ')');
1078 else
1079 dump_generic_node (buffer, op0, spc, flags, false);
1081 pp_space (buffer);
1082 pp_string (buffer, op);
1083 pp_space (buffer);
1085 /* When the operands are expressions with less priority,
1086 keep semantics of the tree representation. */
1087 if (op_prio (op1) < op_prio (node))
1089 pp_character (buffer, '(');
1090 dump_generic_node (buffer, op1, spc, flags, false);
1091 pp_character (buffer, ')');
1093 else
1094 dump_generic_node (buffer, op1, spc, flags, false);
1096 break;
1098 /* Unary arithmetic and logic expressions. */
1099 case NEGATE_EXPR:
1100 case BIT_NOT_EXPR:
1101 case TRUTH_NOT_EXPR:
1102 case ADDR_EXPR:
1103 case PREDECREMENT_EXPR:
1104 case PREINCREMENT_EXPR:
1105 case ALIGN_INDIRECT_REF:
1106 case MISALIGNED_INDIRECT_REF:
1107 case INDIRECT_REF:
1108 if (TREE_CODE (node) == ADDR_EXPR
1109 && (TREE_CODE (TREE_OPERAND (node, 0)) == STRING_CST
1110 || TREE_CODE (TREE_OPERAND (node, 0)) == FUNCTION_DECL))
1111 ; /* Do not output '&' for strings and function pointers. */
1112 else
1113 pp_string (buffer, op_symbol (node));
1115 if (op_prio (TREE_OPERAND (node, 0)) < op_prio (node))
1117 pp_character (buffer, '(');
1118 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1119 pp_character (buffer, ')');
1121 else
1122 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1124 if (TREE_CODE (node) == MISALIGNED_INDIRECT_REF)
1126 pp_string (buffer, "{misalignment: ");
1127 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1128 pp_character (buffer, '}');
1130 break;
1132 case POSTDECREMENT_EXPR:
1133 case POSTINCREMENT_EXPR:
1134 if (op_prio (TREE_OPERAND (node, 0)) < op_prio (node))
1136 pp_character (buffer, '(');
1137 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1138 pp_character (buffer, ')');
1140 else
1141 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1142 pp_string (buffer, op_symbol (node));
1143 break;
1145 case MIN_EXPR:
1146 pp_string (buffer, "MIN_EXPR <");
1147 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1148 pp_string (buffer, ", ");
1149 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1150 pp_character (buffer, '>');
1151 break;
1153 case MAX_EXPR:
1154 pp_string (buffer, "MAX_EXPR <");
1155 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1156 pp_string (buffer, ", ");
1157 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1158 pp_character (buffer, '>');
1159 break;
1161 case ABS_EXPR:
1162 pp_string (buffer, "ABS_EXPR <");
1163 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1164 pp_character (buffer, '>');
1165 break;
1167 case RANGE_EXPR:
1168 NIY;
1169 break;
1171 case FIX_TRUNC_EXPR:
1172 case FIX_CEIL_EXPR:
1173 case FIX_FLOOR_EXPR:
1174 case FIX_ROUND_EXPR:
1175 case FLOAT_EXPR:
1176 case CONVERT_EXPR:
1177 case NOP_EXPR:
1178 type = TREE_TYPE (node);
1179 op0 = TREE_OPERAND (node, 0);
1180 if (type != TREE_TYPE (op0))
1182 pp_character (buffer, '(');
1183 dump_generic_node (buffer, type, spc, flags, false);
1184 pp_string (buffer, ") ");
1186 if (op_prio (op0) < op_prio (node))
1187 pp_character (buffer, '(');
1188 dump_generic_node (buffer, op0, spc, flags, false);
1189 if (op_prio (op0) < op_prio (node))
1190 pp_character (buffer, ')');
1191 break;
1193 case VIEW_CONVERT_EXPR:
1194 pp_string (buffer, "VIEW_CONVERT_EXPR<");
1195 dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
1196 pp_string (buffer, ">(");
1197 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1198 pp_character (buffer, ')');
1199 break;
1201 case NON_LVALUE_EXPR:
1202 pp_string (buffer, "NON_LVALUE_EXPR <");
1203 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1204 pp_character (buffer, '>');
1205 break;
1207 case SAVE_EXPR:
1208 pp_string (buffer, "SAVE_EXPR <");
1209 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1210 pp_character (buffer, '>');
1211 break;
1213 case COMPLEX_EXPR:
1214 pp_string (buffer, "COMPLEX_EXPR <");
1215 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1216 pp_string (buffer, ", ");
1217 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1218 pp_string (buffer, ">");
1219 break;
1221 case CONJ_EXPR:
1222 pp_string (buffer, "CONJ_EXPR <");
1223 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1224 pp_string (buffer, ">");
1225 break;
1227 case REALPART_EXPR:
1228 pp_string (buffer, "REALPART_EXPR <");
1229 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1230 pp_string (buffer, ">");
1231 break;
1233 case IMAGPART_EXPR:
1234 pp_string (buffer, "IMAGPART_EXPR <");
1235 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1236 pp_string (buffer, ">");
1237 break;
1239 case VA_ARG_EXPR:
1240 pp_string (buffer, "VA_ARG_EXPR <");
1241 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1242 pp_string (buffer, ">");
1243 break;
1245 case TRY_FINALLY_EXPR:
1246 case TRY_CATCH_EXPR:
1247 pp_string (buffer, "try");
1248 newline_and_indent (buffer, spc+2);
1249 pp_string (buffer, "{");
1250 newline_and_indent (buffer, spc+4);
1251 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc+4, flags, true);
1252 newline_and_indent (buffer, spc+2);
1253 pp_string (buffer, "}");
1254 newline_and_indent (buffer, spc);
1255 pp_string (buffer,
1256 (TREE_CODE (node) == TRY_CATCH_EXPR) ? "catch" : "finally");
1257 newline_and_indent (buffer, spc+2);
1258 pp_string (buffer, "{");
1259 newline_and_indent (buffer, spc+4);
1260 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc+4, flags, true);
1261 newline_and_indent (buffer, spc+2);
1262 pp_string (buffer, "}");
1263 is_expr = false;
1264 break;
1266 case CATCH_EXPR:
1267 pp_string (buffer, "catch (");
1268 dump_generic_node (buffer, CATCH_TYPES (node), spc+2, flags, false);
1269 pp_string (buffer, ")");
1270 newline_and_indent (buffer, spc+2);
1271 pp_string (buffer, "{");
1272 newline_and_indent (buffer, spc+4);
1273 dump_generic_node (buffer, CATCH_BODY (node), spc+4, flags, true);
1274 newline_and_indent (buffer, spc+2);
1275 pp_string (buffer, "}");
1276 is_expr = false;
1277 break;
1279 case EH_FILTER_EXPR:
1280 pp_string (buffer, "<<<eh_filter (");
1281 dump_generic_node (buffer, EH_FILTER_TYPES (node), spc+2, flags, false);
1282 pp_string (buffer, ")>>>");
1283 newline_and_indent (buffer, spc+2);
1284 pp_string (buffer, "{");
1285 newline_and_indent (buffer, spc+4);
1286 dump_generic_node (buffer, EH_FILTER_FAILURE (node), spc+4, flags, true);
1287 newline_and_indent (buffer, spc+2);
1288 pp_string (buffer, "}");
1289 is_expr = false;
1290 break;
1292 case LABEL_EXPR:
1293 op0 = TREE_OPERAND (node, 0);
1294 /* If this is for break or continue, don't bother printing it. */
1295 if (DECL_NAME (op0))
1297 const char *name = IDENTIFIER_POINTER (DECL_NAME (op0));
1298 if (strcmp (name, "break") == 0
1299 || strcmp (name, "continue") == 0)
1300 break;
1302 dump_generic_node (buffer, op0, spc, flags, false);
1303 pp_character (buffer, ':');
1304 if (DECL_NONLOCAL (op0))
1305 pp_string (buffer, " [non-local]");
1306 break;
1308 case EXC_PTR_EXPR:
1309 pp_string (buffer, "<<<exception object>>>");
1310 break;
1312 case FILTER_EXPR:
1313 pp_string (buffer, "<<<filter object>>>");
1314 break;
1316 case LOOP_EXPR:
1317 pp_string (buffer, "while (1)");
1318 if (!(flags & TDF_SLIM))
1320 newline_and_indent (buffer, spc+2);
1321 pp_character (buffer, '{');
1322 newline_and_indent (buffer, spc+4);
1323 dump_generic_node (buffer, LOOP_EXPR_BODY (node), spc+4, flags, true);
1324 newline_and_indent (buffer, spc+2);
1325 pp_character (buffer, '}');
1327 is_expr = false;
1328 break;
1330 case RETURN_EXPR:
1331 pp_string (buffer, "return");
1332 op0 = TREE_OPERAND (node, 0);
1333 if (op0)
1335 pp_space (buffer);
1336 if (TREE_CODE (op0) == MODIFY_EXPR)
1337 dump_generic_node (buffer, TREE_OPERAND (op0, 1), spc, flags, false);
1338 else
1339 dump_generic_node (buffer, op0, spc, flags, false);
1341 break;
1343 case EXIT_EXPR:
1344 pp_string (buffer, "if (");
1345 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1346 pp_string (buffer, ") break");
1347 break;
1349 case SWITCH_EXPR:
1350 pp_string (buffer, "switch (");
1351 dump_generic_node (buffer, SWITCH_COND (node), spc, flags, false);
1352 pp_character (buffer, ')');
1353 if (!(flags & TDF_SLIM))
1355 newline_and_indent (buffer, spc+2);
1356 pp_character (buffer, '{');
1357 if (SWITCH_BODY (node))
1359 newline_and_indent (buffer, spc+4);
1360 dump_generic_node (buffer, SWITCH_BODY (node), spc+4, flags, true);
1362 else
1364 tree vec = SWITCH_LABELS (node);
1365 size_t i, n = TREE_VEC_LENGTH (vec);
1366 for (i = 0; i < n; ++i)
1368 tree elt = TREE_VEC_ELT (vec, i);
1369 newline_and_indent (buffer, spc+4);
1370 dump_generic_node (buffer, elt, spc+4, flags, false);
1371 pp_string (buffer, " goto ");
1372 dump_generic_node (buffer, CASE_LABEL (elt), spc+4, flags, true);
1373 pp_semicolon (buffer);
1376 newline_and_indent (buffer, spc+2);
1377 pp_character (buffer, '}');
1379 is_expr = false;
1380 break;
1382 case GOTO_EXPR:
1383 op0 = GOTO_DESTINATION (node);
1384 if (TREE_CODE (op0) != SSA_NAME && DECL_P (op0) && DECL_NAME (op0))
1386 const char *name = IDENTIFIER_POINTER (DECL_NAME (op0));
1387 if (strcmp (name, "break") == 0
1388 || strcmp (name, "continue") == 0)
1390 pp_string (buffer, name);
1391 break;
1394 pp_string (buffer, "goto ");
1395 dump_generic_node (buffer, op0, spc, flags, false);
1396 break;
1398 case RESX_EXPR:
1399 pp_string (buffer, "resx");
1400 /* ??? Any sensible way to present the eh region? */
1401 break;
1403 case ASM_EXPR:
1404 pp_string (buffer, "__asm__");
1405 if (ASM_VOLATILE_P (node))
1406 pp_string (buffer, " __volatile__");
1407 pp_character (buffer, '(');
1408 dump_generic_node (buffer, ASM_STRING (node), spc, flags, false);
1409 pp_character (buffer, ':');
1410 dump_generic_node (buffer, ASM_OUTPUTS (node), spc, flags, false);
1411 pp_character (buffer, ':');
1412 dump_generic_node (buffer, ASM_INPUTS (node), spc, flags, false);
1413 if (ASM_CLOBBERS (node))
1415 pp_character (buffer, ':');
1416 dump_generic_node (buffer, ASM_CLOBBERS (node), spc, flags, false);
1418 pp_string (buffer, ")");
1419 break;
1421 case CASE_LABEL_EXPR:
1422 if (CASE_LOW (node) && CASE_HIGH (node))
1424 pp_string (buffer, "case ");
1425 dump_generic_node (buffer, CASE_LOW (node), spc, flags, false);
1426 pp_string (buffer, " ... ");
1427 dump_generic_node (buffer, CASE_HIGH (node), spc, flags, false);
1429 else if (CASE_LOW (node))
1431 pp_string (buffer, "case ");
1432 dump_generic_node (buffer, CASE_LOW (node), spc, flags, false);
1434 else
1435 pp_string (buffer, "default ");
1436 pp_character (buffer, ':');
1437 break;
1439 case OBJ_TYPE_REF:
1440 pp_string (buffer, "OBJ_TYPE_REF(");
1441 dump_generic_node (buffer, OBJ_TYPE_REF_EXPR (node), spc, flags, false);
1442 pp_character (buffer, ';');
1443 dump_generic_node (buffer, OBJ_TYPE_REF_OBJECT (node), spc, flags, false);
1444 pp_character (buffer, '-');
1445 pp_character (buffer, '>');
1446 dump_generic_node (buffer, OBJ_TYPE_REF_TOKEN (node), spc, flags, false);
1447 pp_character (buffer, ')');
1448 break;
1450 case PHI_NODE:
1452 int i;
1454 dump_generic_node (buffer, PHI_RESULT (node), spc, flags, false);
1455 pp_string (buffer, " = PHI <");
1456 for (i = 0; i < PHI_NUM_ARGS (node); i++)
1458 dump_generic_node (buffer, PHI_ARG_DEF (node, i), spc, flags, false);
1459 pp_string (buffer, "(");
1460 pp_decimal_int (buffer, PHI_ARG_EDGE (node, i)->src->index);
1461 pp_string (buffer, ")");
1462 if (i < PHI_NUM_ARGS (node) - 1)
1463 pp_string (buffer, ", ");
1465 pp_string (buffer, ">;");
1467 break;
1469 case SSA_NAME:
1470 dump_generic_node (buffer, SSA_NAME_VAR (node), spc, flags, false);
1471 pp_string (buffer, "_");
1472 pp_decimal_int (buffer, SSA_NAME_VERSION (node));
1473 if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (node))
1474 pp_string (buffer, "(ab)");
1475 break;
1477 case WITH_SIZE_EXPR:
1478 pp_string (buffer, "WITH_SIZE_EXPR <");
1479 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1480 pp_string (buffer, ", ");
1481 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1482 pp_string (buffer, ">");
1483 break;
1485 case VALUE_HANDLE:
1486 pp_printf (buffer, "VH.%d", VALUE_HANDLE_ID (node));
1487 break;
1489 case ASSERT_EXPR:
1490 pp_string (buffer, "ASSERT_EXPR <");
1491 dump_generic_node (buffer, ASSERT_EXPR_VAR (node), spc, flags, false);
1492 pp_string (buffer, ", ");
1493 dump_generic_node (buffer, ASSERT_EXPR_COND (node), spc, flags, false);
1494 pp_string (buffer, ">");
1495 break;
1497 case SCEV_KNOWN:
1498 pp_string (buffer, "scev_known");
1499 break;
1501 case SCEV_NOT_KNOWN:
1502 pp_string (buffer, "scev_not_known");
1503 break;
1505 case POLYNOMIAL_CHREC:
1506 pp_string (buffer, "{");
1507 dump_generic_node (buffer, CHREC_LEFT (node), spc, flags, false);
1508 pp_string (buffer, ", +, ");
1509 dump_generic_node (buffer, CHREC_RIGHT (node), spc, flags, false);
1510 pp_string (buffer, "}_");
1511 dump_generic_node (buffer, CHREC_VAR (node), spc, flags, false);
1512 is_stmt = false;
1513 break;
1515 case REALIGN_LOAD_EXPR:
1516 pp_string (buffer, "REALIGN_LOAD <");
1517 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1518 pp_string (buffer, ", ");
1519 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1520 pp_string (buffer, ", ");
1521 dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
1522 pp_string (buffer, ">");
1523 break;
1525 case VEC_COND_EXPR:
1526 pp_string (buffer, " VEC_COND_EXPR < ");
1527 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1528 pp_string (buffer, " , ");
1529 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1530 pp_string (buffer, " , ");
1531 dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
1532 pp_string (buffer, " > ");
1533 break;
1535 case REDUC_MAX_EXPR:
1536 pp_string (buffer, " REDUC_MAX_EXPR < ");
1537 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1538 pp_string (buffer, " > ");
1539 break;
1541 case REDUC_MIN_EXPR:
1542 pp_string (buffer, " REDUC_MIN_EXPR < ");
1543 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1544 pp_string (buffer, " > ");
1545 break;
1547 case REDUC_PLUS_EXPR:
1548 pp_string (buffer, " REDUC_PLUS_EXPR < ");
1549 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1550 pp_string (buffer, " > ");
1551 break;
1553 default:
1554 NIY;
1557 if (is_stmt && is_expr)
1558 pp_semicolon (buffer);
1559 pp_write_text_to_stream (buffer);
1561 return spc;
1564 /* Print the declaration of a variable. */
1566 static void
1567 print_declaration (pretty_printer *buffer, tree t, int spc, int flags)
1569 INDENT (spc);
1571 if (TREE_CODE (t) == TYPE_DECL)
1572 pp_string (buffer, "typedef ");
1574 if (CODE_CONTAINS_STRUCT (TREE_CODE (t), TS_DECL_WRTL) && DECL_REGISTER (t))
1575 pp_string (buffer, "register ");
1577 if (TREE_PUBLIC (t) && DECL_EXTERNAL (t))
1578 pp_string (buffer, "extern ");
1579 else if (TREE_STATIC (t))
1580 pp_string (buffer, "static ");
1582 /* Print the type and name. */
1583 if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
1585 tree tmp;
1587 /* Print array's type. */
1588 tmp = TREE_TYPE (t);
1589 while (TREE_CODE (TREE_TYPE (tmp)) == ARRAY_TYPE)
1590 tmp = TREE_TYPE (tmp);
1591 dump_generic_node (buffer, TREE_TYPE (tmp), spc, flags, false);
1593 /* Print variable's name. */
1594 pp_space (buffer);
1595 dump_generic_node (buffer, t, spc, flags, false);
1597 /* Print the dimensions. */
1598 tmp = TREE_TYPE (t);
1599 while (TREE_CODE (tmp) == ARRAY_TYPE)
1601 dump_array_domain (buffer, TYPE_DOMAIN (tmp), spc, flags);
1602 tmp = TREE_TYPE (tmp);
1605 else if (TREE_CODE (t) == FUNCTION_DECL)
1607 dump_generic_node (buffer, TREE_TYPE (TREE_TYPE (t)), spc, flags, false);
1608 pp_space (buffer);
1609 dump_decl_name (buffer, t, flags);
1610 dump_function_declaration (buffer, TREE_TYPE (t), spc, flags);
1612 else
1614 /* Print type declaration. */
1615 dump_generic_node (buffer, TREE_TYPE (t), spc, flags, false);
1617 /* Print variable's name. */
1618 pp_space (buffer);
1619 dump_generic_node (buffer, t, spc, flags, false);
1622 if (TREE_CODE (t) == VAR_DECL && DECL_HARD_REGISTER (t))
1624 pp_string (buffer, " __asm__ ");
1625 pp_character (buffer, '(');
1626 dump_generic_node (buffer, DECL_ASSEMBLER_NAME (t), spc, flags, false);
1627 pp_character (buffer, ')');
1630 /* The initial value of a function serves to determine wether the function
1631 is declared or defined. So the following does not apply to function
1632 nodes. */
1633 if (TREE_CODE (t) != FUNCTION_DECL)
1635 /* Print the initial value. */
1636 if (DECL_INITIAL (t))
1638 pp_space (buffer);
1639 pp_character (buffer, '=');
1640 pp_space (buffer);
1641 dump_generic_node (buffer, DECL_INITIAL (t), spc, flags, false);
1645 pp_character (buffer, ';');
1649 /* Prints a structure: name, fields, and methods.
1650 FIXME: Still incomplete. */
1652 static void
1653 print_struct_decl (pretty_printer *buffer, tree node, int spc, int flags)
1655 /* Print the name of the structure. */
1656 if (TYPE_NAME (node))
1658 INDENT (spc);
1659 if (TREE_CODE (node) == RECORD_TYPE)
1660 pp_string (buffer, "struct ");
1661 else if ((TREE_CODE (node) == UNION_TYPE
1662 || TREE_CODE (node) == QUAL_UNION_TYPE))
1663 pp_string (buffer, "union ");
1665 dump_generic_node (buffer, TYPE_NAME (node), spc, 0, false);
1668 /* Print the contents of the structure. */
1669 pp_newline (buffer);
1670 INDENT (spc);
1671 pp_character (buffer, '{');
1672 pp_newline (buffer);
1674 /* Print the fields of the structure. */
1676 tree tmp;
1677 tmp = TYPE_FIELDS (node);
1678 while (tmp)
1680 /* Avoid to print recursively the structure. */
1681 /* FIXME : Not implemented correctly...,
1682 what about the case when we have a cycle in the contain graph? ...
1683 Maybe this could be solved by looking at the scope in which the
1684 structure was declared. */
1685 if (TREE_TYPE (tmp) != node
1686 || (TREE_CODE (TREE_TYPE (tmp)) == POINTER_TYPE
1687 && TREE_TYPE (TREE_TYPE (tmp)) != node))
1689 print_declaration (buffer, tmp, spc+2, flags);
1690 pp_newline (buffer);
1692 tmp = TREE_CHAIN (tmp);
1695 INDENT (spc);
1696 pp_character (buffer, '}');
1699 /* Return the priority of the operator OP.
1701 From lowest to highest precedence with either left-to-right (L-R)
1702 or right-to-left (R-L) associativity]:
1704 1 [L-R] ,
1705 2 [R-L] = += -= *= /= %= &= ^= |= <<= >>=
1706 3 [R-L] ?:
1707 4 [L-R] ||
1708 5 [L-R] &&
1709 6 [L-R] |
1710 7 [L-R] ^
1711 8 [L-R] &
1712 9 [L-R] == !=
1713 10 [L-R] < <= > >=
1714 11 [L-R] << >>
1715 12 [L-R] + -
1716 13 [L-R] * / %
1717 14 [R-L] ! ~ ++ -- + - * & (type) sizeof
1718 15 [L-R] fn() [] -> .
1720 unary +, - and * have higher precedence than the corresponding binary
1721 operators. */
1723 static int
1724 op_prio (tree op)
1726 if (op == NULL)
1727 return 9999;
1729 switch (TREE_CODE (op))
1731 case TREE_LIST:
1732 case COMPOUND_EXPR:
1733 case BIND_EXPR:
1734 return 1;
1736 case MODIFY_EXPR:
1737 case INIT_EXPR:
1738 return 2;
1740 case COND_EXPR:
1741 return 3;
1743 case TRUTH_OR_EXPR:
1744 case TRUTH_ORIF_EXPR:
1745 return 4;
1747 case TRUTH_AND_EXPR:
1748 case TRUTH_ANDIF_EXPR:
1749 return 5;
1751 case BIT_IOR_EXPR:
1752 return 6;
1754 case BIT_XOR_EXPR:
1755 case TRUTH_XOR_EXPR:
1756 return 7;
1758 case BIT_AND_EXPR:
1759 return 8;
1761 case EQ_EXPR:
1762 case NE_EXPR:
1763 return 9;
1765 case UNLT_EXPR:
1766 case UNLE_EXPR:
1767 case UNGT_EXPR:
1768 case UNGE_EXPR:
1769 case UNEQ_EXPR:
1770 case LTGT_EXPR:
1771 case ORDERED_EXPR:
1772 case UNORDERED_EXPR:
1773 case LT_EXPR:
1774 case LE_EXPR:
1775 case GT_EXPR:
1776 case GE_EXPR:
1777 return 10;
1779 case LSHIFT_EXPR:
1780 case RSHIFT_EXPR:
1781 case LROTATE_EXPR:
1782 case RROTATE_EXPR:
1783 return 11;
1785 case PLUS_EXPR:
1786 case MINUS_EXPR:
1787 return 12;
1789 case MULT_EXPR:
1790 case TRUNC_DIV_EXPR:
1791 case CEIL_DIV_EXPR:
1792 case FLOOR_DIV_EXPR:
1793 case ROUND_DIV_EXPR:
1794 case RDIV_EXPR:
1795 case EXACT_DIV_EXPR:
1796 case TRUNC_MOD_EXPR:
1797 case CEIL_MOD_EXPR:
1798 case FLOOR_MOD_EXPR:
1799 case ROUND_MOD_EXPR:
1800 return 13;
1802 case TRUTH_NOT_EXPR:
1803 case BIT_NOT_EXPR:
1804 case POSTINCREMENT_EXPR:
1805 case POSTDECREMENT_EXPR:
1806 case PREINCREMENT_EXPR:
1807 case PREDECREMENT_EXPR:
1808 case NEGATE_EXPR:
1809 case ALIGN_INDIRECT_REF:
1810 case MISALIGNED_INDIRECT_REF:
1811 case INDIRECT_REF:
1812 case ADDR_EXPR:
1813 case FLOAT_EXPR:
1814 case NOP_EXPR:
1815 case CONVERT_EXPR:
1816 case FIX_TRUNC_EXPR:
1817 case FIX_CEIL_EXPR:
1818 case FIX_FLOOR_EXPR:
1819 case FIX_ROUND_EXPR:
1820 case TARGET_EXPR:
1821 return 14;
1823 case CALL_EXPR:
1824 case ARRAY_REF:
1825 case ARRAY_RANGE_REF:
1826 case COMPONENT_REF:
1827 return 15;
1829 /* Special expressions. */
1830 case MIN_EXPR:
1831 case MAX_EXPR:
1832 case ABS_EXPR:
1833 case REALPART_EXPR:
1834 case IMAGPART_EXPR:
1835 case REDUC_MAX_EXPR:
1836 case REDUC_MIN_EXPR:
1837 case REDUC_PLUS_EXPR:
1838 case VEC_LSHIFT_EXPR:
1839 case VEC_RSHIFT_EXPR:
1840 return 16;
1842 case SAVE_EXPR:
1843 case NON_LVALUE_EXPR:
1844 return op_prio (TREE_OPERAND (op, 0));
1846 default:
1847 /* Return an arbitrarily high precedence to avoid surrounding single
1848 VAR_DECLs in ()s. */
1849 return 9999;
1854 /* Return the symbol associated with operator OP. */
1856 static const char *
1857 op_symbol (tree op)
1859 gcc_assert (op);
1861 switch (TREE_CODE (op))
1863 case MODIFY_EXPR:
1864 return "=";
1866 case TRUTH_OR_EXPR:
1867 case TRUTH_ORIF_EXPR:
1868 return "||";
1870 case TRUTH_AND_EXPR:
1871 case TRUTH_ANDIF_EXPR:
1872 return "&&";
1874 case BIT_IOR_EXPR:
1875 return "|";
1877 case TRUTH_XOR_EXPR:
1878 case BIT_XOR_EXPR:
1879 return "^";
1881 case ADDR_EXPR:
1882 case BIT_AND_EXPR:
1883 return "&";
1885 case ORDERED_EXPR:
1886 return "ord";
1887 case UNORDERED_EXPR:
1888 return "unord";
1890 case EQ_EXPR:
1891 return "==";
1892 case UNEQ_EXPR:
1893 return "u==";
1895 case NE_EXPR:
1896 return "!=";
1898 case LT_EXPR:
1899 return "<";
1900 case UNLT_EXPR:
1901 return "u<";
1903 case LE_EXPR:
1904 return "<=";
1905 case UNLE_EXPR:
1906 return "u<=";
1908 case GT_EXPR:
1909 return ">";
1910 case UNGT_EXPR:
1911 return "u>";
1913 case GE_EXPR:
1914 return ">=";
1915 case UNGE_EXPR:
1916 return "u>=";
1918 case LTGT_EXPR:
1919 return "<>";
1921 case LSHIFT_EXPR:
1922 return "<<";
1924 case RSHIFT_EXPR:
1925 return ">>";
1927 case VEC_LSHIFT_EXPR:
1928 return "v<<";
1930 case VEC_RSHIFT_EXPR:
1931 return "v>>";
1933 case PLUS_EXPR:
1934 return "+";
1936 case REDUC_PLUS_EXPR:
1937 return "r+";
1939 case NEGATE_EXPR:
1940 case MINUS_EXPR:
1941 return "-";
1943 case BIT_NOT_EXPR:
1944 return "~";
1946 case TRUTH_NOT_EXPR:
1947 return "!";
1949 case MULT_EXPR:
1950 case INDIRECT_REF:
1951 return "*";
1953 case ALIGN_INDIRECT_REF:
1954 return "A*";
1956 case MISALIGNED_INDIRECT_REF:
1957 return "M*";
1959 case TRUNC_DIV_EXPR:
1960 case RDIV_EXPR:
1961 return "/";
1963 case CEIL_DIV_EXPR:
1964 return "/[cl]";
1966 case FLOOR_DIV_EXPR:
1967 return "/[fl]";
1969 case ROUND_DIV_EXPR:
1970 return "/[rd]";
1972 case EXACT_DIV_EXPR:
1973 return "/[ex]";
1975 case TRUNC_MOD_EXPR:
1976 return "%";
1978 case CEIL_MOD_EXPR:
1979 return "%[cl]";
1981 case FLOOR_MOD_EXPR:
1982 return "%[fl]";
1984 case ROUND_MOD_EXPR:
1985 return "%[rd]";
1987 case PREDECREMENT_EXPR:
1988 return " --";
1990 case PREINCREMENT_EXPR:
1991 return " ++";
1993 case POSTDECREMENT_EXPR:
1994 return "-- ";
1996 case POSTINCREMENT_EXPR:
1997 return "++ ";
1999 default:
2000 return "<<< ??? >>>";
2004 /* Prints the name of a CALL_EXPR. */
2006 static void
2007 print_call_name (pretty_printer *buffer, tree node)
2009 tree op0;
2011 gcc_assert (TREE_CODE (node) == CALL_EXPR);
2013 op0 = TREE_OPERAND (node, 0);
2015 if (TREE_CODE (op0) == NON_LVALUE_EXPR)
2016 op0 = TREE_OPERAND (op0, 0);
2018 switch (TREE_CODE (op0))
2020 case VAR_DECL:
2021 case PARM_DECL:
2022 dump_function_name (buffer, op0);
2023 break;
2025 case ADDR_EXPR:
2026 case INDIRECT_REF:
2027 case NOP_EXPR:
2028 dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
2029 break;
2031 case COND_EXPR:
2032 pp_string (buffer, "(");
2033 dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
2034 pp_string (buffer, ") ? ");
2035 dump_generic_node (buffer, TREE_OPERAND (op0, 1), 0, 0, false);
2036 pp_string (buffer, " : ");
2037 dump_generic_node (buffer, TREE_OPERAND (op0, 2), 0, 0, false);
2038 break;
2040 case COMPONENT_REF:
2041 /* The function is a pointer contained in a structure. */
2042 if (TREE_CODE (TREE_OPERAND (op0, 0)) == INDIRECT_REF ||
2043 TREE_CODE (TREE_OPERAND (op0, 0)) == VAR_DECL)
2044 dump_function_name (buffer, TREE_OPERAND (op0, 1));
2045 else
2046 dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
2047 /* else
2048 We can have several levels of structures and a function
2049 pointer inside. This is not implemented yet... */
2050 /* NIY;*/
2051 break;
2053 case ARRAY_REF:
2054 if (TREE_CODE (TREE_OPERAND (op0, 0)) == VAR_DECL)
2055 dump_function_name (buffer, TREE_OPERAND (op0, 0));
2056 else
2057 dump_generic_node (buffer, op0, 0, 0, false);
2058 break;
2060 case SSA_NAME:
2061 case OBJ_TYPE_REF:
2062 dump_generic_node (buffer, op0, 0, 0, false);
2063 break;
2065 default:
2066 NIY;
2070 /* Parses the string STR and replaces new-lines by '\n', tabs by '\t', ... */
2072 static void
2073 pretty_print_string (pretty_printer *buffer, const char *str)
2075 if (str == NULL)
2076 return;
2078 while (*str)
2080 switch (str[0])
2082 case '\b':
2083 pp_string (buffer, "\\b");
2084 break;
2086 case '\f':
2087 pp_string (buffer, "\\f");
2088 break;
2090 case '\n':
2091 pp_string (buffer, "\\n");
2092 break;
2094 case '\r':
2095 pp_string (buffer, "\\r");
2096 break;
2098 case '\t':
2099 pp_string (buffer, "\\t");
2100 break;
2102 case '\v':
2103 pp_string (buffer, "\\v");
2104 break;
2106 case '\\':
2107 pp_string (buffer, "\\\\");
2108 break;
2110 case '\"':
2111 pp_string (buffer, "\\\"");
2112 break;
2114 case '\'':
2115 pp_string (buffer, "\\'");
2116 break;
2118 case '\0':
2119 pp_string (buffer, "\\0");
2120 break;
2122 case '\1':
2123 pp_string (buffer, "\\1");
2124 break;
2126 case '\2':
2127 pp_string (buffer, "\\2");
2128 break;
2130 case '\3':
2131 pp_string (buffer, "\\3");
2132 break;
2134 case '\4':
2135 pp_string (buffer, "\\4");
2136 break;
2138 case '\5':
2139 pp_string (buffer, "\\5");
2140 break;
2142 case '\6':
2143 pp_string (buffer, "\\6");
2144 break;
2146 case '\7':
2147 pp_string (buffer, "\\7");
2148 break;
2150 default:
2151 pp_character (buffer, str[0]);
2152 break;
2154 str++;
2158 static void
2159 maybe_init_pretty_print (FILE *file)
2161 if (!initialized)
2163 pp_construct (&buffer, /* prefix */NULL, /* line-width */0);
2164 pp_needs_newline (&buffer) = true;
2165 initialized = 1;
2168 buffer.buffer->stream = file;
2171 static void
2172 newline_and_indent (pretty_printer *buffer, int spc)
2174 pp_newline (buffer);
2175 INDENT (spc);
2178 static void
2179 dump_vops (pretty_printer *buffer, tree stmt, int spc, int flags)
2181 tree use;
2182 use_operand_p use_p;
2183 def_operand_p def_p;
2184 use_operand_p kill_p;
2185 ssa_op_iter iter;
2187 if (!ssa_operands_active ())
2188 return;
2190 FOR_EACH_SSA_MAYDEF_OPERAND (def_p, use_p, stmt, iter)
2192 pp_string (buffer, "# ");
2193 dump_generic_node (buffer, DEF_FROM_PTR (def_p),
2194 spc + 2, flags, false);
2195 pp_string (buffer, " = V_MAY_DEF <");
2196 dump_generic_node (buffer, USE_FROM_PTR (use_p),
2197 spc + 2, flags, false);
2198 pp_string (buffer, ">;");
2199 newline_and_indent (buffer, spc);
2202 FOR_EACH_SSA_MUSTDEF_OPERAND (def_p, kill_p, stmt, iter)
2204 pp_string (buffer, "# ");
2205 dump_generic_node (buffer, DEF_FROM_PTR (def_p),
2206 spc + 2, flags, false);
2207 pp_string (buffer, " = V_MUST_DEF <");
2208 dump_generic_node (buffer, USE_FROM_PTR (kill_p),
2209 spc + 2, flags, false);
2210 pp_string (buffer, ">;");
2211 newline_and_indent (buffer, spc);
2214 FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_VUSE)
2216 pp_string (buffer, "# VUSE <");
2217 dump_generic_node (buffer, use, spc + 2, flags, false);
2218 pp_string (buffer, ">;");
2219 newline_and_indent (buffer, spc);
2223 /* Dumps basic block BB to FILE with details described by FLAGS and
2224 indented by INDENT spaces. */
2226 void
2227 dump_generic_bb (FILE *file, basic_block bb, int indent, int flags)
2229 maybe_init_pretty_print (file);
2230 dumping_stmts = true;
2231 dump_generic_bb_buff (&buffer, bb, indent, flags);
2232 pp_flush (&buffer);
2235 /* Dumps header of basic block BB to buffer BUFFER indented by INDENT
2236 spaces and details described by flags. */
2238 static void
2239 dump_bb_header (pretty_printer *buffer, basic_block bb, int indent, int flags)
2241 edge e;
2242 tree stmt;
2243 edge_iterator ei;
2245 if (flags & TDF_BLOCKS)
2247 INDENT (indent);
2248 pp_string (buffer, "# BLOCK ");
2249 pp_decimal_int (buffer, bb->index);
2250 if (bb->frequency)
2252 pp_string (buffer, " freq:");
2253 pp_decimal_int (buffer, bb->frequency);
2255 if (bb->count)
2257 pp_string (buffer, " count:");
2258 pp_widest_integer (buffer, bb->count);
2261 if (flags & TDF_LINENO)
2263 block_stmt_iterator bsi;
2265 for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
2266 if (get_lineno (bsi_stmt (bsi)) != -1)
2268 pp_string (buffer, ", starting at line ");
2269 pp_decimal_int (buffer, get_lineno (bsi_stmt (bsi)));
2270 break;
2273 newline_and_indent (buffer, indent);
2275 pp_string (buffer, "# PRED:");
2276 pp_write_text_to_stream (buffer);
2277 FOR_EACH_EDGE (e, ei, bb->preds)
2278 if (flags & TDF_SLIM)
2280 pp_string (buffer, " ");
2281 if (e->src == ENTRY_BLOCK_PTR)
2282 pp_string (buffer, "ENTRY");
2283 else
2284 pp_decimal_int (buffer, e->src->index);
2286 else
2287 dump_edge_info (buffer->buffer->stream, e, 0);
2288 pp_newline (buffer);
2290 else
2292 stmt = first_stmt (bb);
2293 if (!stmt || TREE_CODE (stmt) != LABEL_EXPR)
2295 INDENT (indent - 2);
2296 pp_string (buffer, "<bb ");
2297 pp_decimal_int (buffer, bb->index);
2298 pp_string (buffer, ">:");
2299 pp_newline (buffer);
2302 pp_write_text_to_stream (buffer);
2303 check_bb_profile (bb, buffer->buffer->stream);
2306 /* Dumps end of basic block BB to buffer BUFFER indented by INDENT
2307 spaces. */
2309 static void
2310 dump_bb_end (pretty_printer *buffer, basic_block bb, int indent, int flags)
2312 edge e;
2313 edge_iterator ei;
2315 INDENT (indent);
2316 pp_string (buffer, "# SUCC:");
2317 pp_write_text_to_stream (buffer);
2318 FOR_EACH_EDGE (e, ei, bb->succs)
2319 if (flags & TDF_SLIM)
2321 pp_string (buffer, " ");
2322 if (e->dest == EXIT_BLOCK_PTR)
2323 pp_string (buffer, "EXIT");
2324 else
2325 pp_decimal_int (buffer, e->dest->index);
2327 else
2328 dump_edge_info (buffer->buffer->stream, e, 1);
2329 pp_newline (buffer);
2332 /* Dumps phi nodes of basic block BB to buffer BUFFER with details described by
2333 FLAGS indented by INDENT spaces. */
2335 static void
2336 dump_phi_nodes (pretty_printer *buffer, basic_block bb, int indent, int flags)
2338 tree phi = phi_nodes (bb);
2339 if (!phi)
2340 return;
2342 for (; phi; phi = PHI_CHAIN (phi))
2344 if (is_gimple_reg (PHI_RESULT (phi)) || (flags & TDF_VOPS))
2346 INDENT (indent);
2347 pp_string (buffer, "# ");
2348 dump_generic_node (buffer, phi, indent, flags, false);
2349 pp_newline (buffer);
2354 /* Dump jump to basic block BB that is represented implicitly in the cfg
2355 to BUFFER. */
2357 static void
2358 pp_cfg_jump (pretty_printer *buffer, basic_block bb)
2360 tree stmt;
2362 stmt = first_stmt (bb);
2364 pp_string (buffer, "goto <bb ");
2365 pp_decimal_int (buffer, bb->index);
2366 pp_string (buffer, ">");
2367 if (stmt && TREE_CODE (stmt) == LABEL_EXPR)
2369 pp_string (buffer, " (");
2370 dump_generic_node (buffer, LABEL_EXPR_LABEL (stmt), 0, 0, false);
2371 pp_string (buffer, ")");
2373 pp_semicolon (buffer);
2376 /* Dump edges represented implicitly in basic block BB to BUFFER, indented
2377 by INDENT spaces, with details given by FLAGS. */
2379 static void
2380 dump_implicit_edges (pretty_printer *buffer, basic_block bb, int indent,
2381 int flags)
2383 edge e;
2384 edge_iterator ei;
2386 /* If there is a fallthru edge, we may need to add an artificial goto to the
2387 dump. */
2388 FOR_EACH_EDGE (e, ei, bb->succs)
2389 if (e->flags & EDGE_FALLTHRU)
2390 break;
2391 if (e && e->dest != bb->next_bb)
2393 INDENT (indent);
2395 if ((flags & TDF_LINENO)
2396 #ifdef USE_MAPPED_LOCATION
2397 && e->goto_locus != UNKNOWN_LOCATION
2398 #else
2399 && e->goto_locus
2400 #endif
2403 expanded_location goto_xloc;
2404 #ifdef USE_MAPPED_LOCATION
2405 goto_xloc = expand_location (e->goto_locus);
2406 #else
2407 goto_xloc = *e->goto_locus;
2408 #endif
2409 pp_character (buffer, '[');
2410 if (goto_xloc.file)
2412 pp_string (buffer, goto_xloc.file);
2413 pp_string (buffer, " : ");
2415 pp_decimal_int (buffer, goto_xloc.line);
2416 pp_string (buffer, "] ");
2419 pp_cfg_jump (buffer, e->dest);
2420 pp_newline (buffer);
2424 /* Dumps basic block BB to buffer BUFFER with details described by FLAGS and
2425 indented by INDENT spaces. */
2427 static void
2428 dump_generic_bb_buff (pretty_printer *buffer, basic_block bb,
2429 int indent, int flags)
2431 block_stmt_iterator bsi;
2432 tree stmt;
2433 int label_indent = indent - 2;
2435 if (label_indent < 0)
2436 label_indent = 0;
2438 dump_bb_header (buffer, bb, indent, flags);
2440 dump_phi_nodes (buffer, bb, indent, flags);
2442 for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
2444 int curr_indent;
2446 stmt = bsi_stmt (bsi);
2448 curr_indent = TREE_CODE (stmt) == LABEL_EXPR ? label_indent : indent;
2450 INDENT (curr_indent);
2451 dump_generic_node (buffer, stmt, curr_indent, flags, true);
2452 pp_newline (buffer);
2455 dump_implicit_edges (buffer, bb, indent, flags);
2457 if (flags & TDF_BLOCKS)
2458 dump_bb_end (buffer, bb, indent, flags);