2005-06-30 J. D. Johnston <jjohnst@us.ibm.com>
[official-gcc.git] / gcc / tree-pretty-print.c
blob4fa03269149eacf5eb298af00f6d25f2b19e0f06
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"
35 /* Local functions, macros and variables. */
36 static int op_prio (tree);
37 static const char *op_symbol (tree);
38 static void pretty_print_string (pretty_printer *, const char*);
39 static void print_call_name (pretty_printer *, tree);
40 static void newline_and_indent (pretty_printer *, int);
41 static void maybe_init_pretty_print (FILE *);
42 static void print_declaration (pretty_printer *, tree, int, int);
43 static void print_struct_decl (pretty_printer *, tree, int, int);
44 static void do_niy (pretty_printer *, tree);
45 static void dump_vops (pretty_printer *, tree, int, int);
46 static void dump_generic_bb_buff (pretty_printer *, basic_block, int, int);
48 #define INDENT(SPACE) do { \
49 int i; for (i = 0; i<SPACE; i++) pp_space (buffer); } while (0)
51 #define NIY do_niy(buffer,node)
53 #define PRINT_FUNCTION_NAME(NODE) pp_printf \
54 (buffer, "%s", TREE_CODE (NODE) == NOP_EXPR ? \
55 lang_hooks.decl_printable_name (TREE_OPERAND (NODE, 0), 1) : \
56 lang_hooks.decl_printable_name (NODE, 1))
58 static pretty_printer buffer;
59 static int initialized = 0;
60 static bool dumping_stmts;
62 /* Try to print something for an unknown tree code. */
64 static void
65 do_niy (pretty_printer *buffer, tree node)
67 int i, len;
69 pp_string (buffer, "<<< Unknown tree: ");
70 pp_string (buffer, tree_code_name[(int) TREE_CODE (node)]);
72 if (EXPR_P (node))
74 len = TREE_CODE_LENGTH (TREE_CODE (node));
75 for (i = 0; i < len; ++i)
77 newline_and_indent (buffer, 2);
78 dump_generic_node (buffer, TREE_OPERAND (node, i), 2, 0, false);
82 pp_string (buffer, " >>>\n");
85 void
86 debug_generic_expr (tree t)
88 print_generic_expr (stderr, t, TDF_VOPS|TDF_UID);
89 fprintf (stderr, "\n");
92 void
93 debug_generic_stmt (tree t)
95 print_generic_stmt (stderr, t, TDF_VOPS|TDF_UID);
96 fprintf (stderr, "\n");
99 /* Prints declaration DECL to the FILE with details specified by FLAGS. */
100 void
101 print_generic_decl (FILE *file, tree decl, int flags)
103 maybe_init_pretty_print (file);
104 dumping_stmts = true;
105 print_declaration (&buffer, decl, 2, flags);
106 pp_write_text_to_stream (&buffer);
109 /* Print tree T, and its successors, on file FILE. FLAGS specifies details
110 to show in the dump. See TDF_* in tree.h. */
112 void
113 print_generic_stmt (FILE *file, tree t, int flags)
115 maybe_init_pretty_print (file);
116 dumping_stmts = true;
117 dump_generic_node (&buffer, t, 0, flags, true);
118 pp_flush (&buffer);
121 /* Print tree T, and its successors, on file FILE. FLAGS specifies details
122 to show in the dump. See TDF_* in tree.h. The output is indented by
123 INDENT spaces. */
125 void
126 print_generic_stmt_indented (FILE *file, tree t, int flags, int indent)
128 int i;
130 maybe_init_pretty_print (file);
131 dumping_stmts = true;
133 for (i = 0; i < indent; i++)
134 pp_space (&buffer);
135 dump_generic_node (&buffer, t, indent, flags, true);
136 pp_flush (&buffer);
139 /* Print a single expression T on file FILE. FLAGS specifies details to show
140 in the dump. See TDF_* in tree.h. */
142 void
143 print_generic_expr (FILE *file, tree t, int flags)
145 maybe_init_pretty_print (file);
146 dumping_stmts = false;
147 dump_generic_node (&buffer, t, 0, flags, false);
150 /* Dump the name of a _DECL node and its DECL_UID if TDF_UID is set
151 in FLAGS. */
153 static void
154 dump_decl_name (pretty_printer *buffer, tree node, int flags)
156 if (DECL_NAME (node))
157 pp_tree_identifier (buffer, DECL_NAME (node));
159 if ((flags & TDF_UID)
160 || DECL_NAME (node) == NULL_TREE)
162 if (TREE_CODE (node) == LABEL_DECL
163 && LABEL_DECL_UID (node) != -1)
164 pp_printf (buffer, "L." HOST_WIDE_INT_PRINT_DEC,
165 LABEL_DECL_UID (node));
166 else
168 char c = TREE_CODE (node) == CONST_DECL ? 'C' : 'D';
169 pp_printf (buffer, "%c.%u", c, DECL_UID (node));
174 /* Like the above, but used for pretty printing function calls. */
176 static void
177 dump_function_name (pretty_printer *buffer, tree node)
179 if (DECL_NAME (node))
180 PRINT_FUNCTION_NAME (node);
181 else
182 dump_decl_name (buffer, node, 0);
185 /* Dump a function declaration. NODE is the FUNCTION_TYPE. BUFFER, SPC and
186 FLAGS are as in dump_generic_node. */
188 static void
189 dump_function_declaration (pretty_printer *buffer, tree node,
190 int spc, int flags)
192 bool wrote_arg = false;
193 tree arg;
195 pp_space (buffer);
196 pp_character (buffer, '(');
198 /* Print the argument types. The last element in the list is a VOID_TYPE.
199 The following avoids printing the last element. */
200 arg = TYPE_ARG_TYPES (node);
201 while (arg && TREE_CHAIN (arg) && arg != error_mark_node)
203 wrote_arg = true;
204 dump_generic_node (buffer, TREE_VALUE (arg), spc, flags, false);
205 arg = TREE_CHAIN (arg);
206 if (TREE_CHAIN (arg) && TREE_CODE (TREE_CHAIN (arg)) == TREE_LIST)
208 pp_character (buffer, ',');
209 pp_space (buffer);
213 if (!wrote_arg)
214 pp_string (buffer, "void");
216 pp_character (buffer, ')');
219 /* Dump the domain associated with an array. */
221 static void
222 dump_array_domain (pretty_printer *buffer, tree domain, int spc, int flags)
224 pp_character (buffer, '[');
225 if (domain)
227 tree min = TYPE_MIN_VALUE (domain);
228 tree max = TYPE_MAX_VALUE (domain);
230 if (min && max
231 && integer_zerop (min)
232 && host_integerp (max, 0))
233 pp_wide_integer (buffer, TREE_INT_CST_LOW (max) + 1);
234 else
236 if (min)
237 dump_generic_node (buffer, min, spc, flags, false);
238 pp_character (buffer, ':');
239 if (max)
240 dump_generic_node (buffer, max, spc, flags, false);
243 else
244 pp_string (buffer, "<unknown>");
245 pp_character (buffer, ']');
248 /* Dump the node NODE on the pretty_printer BUFFER, SPC spaces of indent.
249 FLAGS specifies details to show in the dump (see TDF_* in tree.h). If
250 IS_STMT is true, the object printed is considered to be a statement
251 and it is terminated by ';' if appropriate. */
254 dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
255 bool is_stmt)
257 tree type;
258 tree op0, op1;
259 const char *str;
260 bool is_expr;
262 if (node == NULL_TREE)
263 return spc;
265 is_expr = EXPR_P (node);
267 if (TREE_CODE (node) != ERROR_MARK
268 && is_gimple_stmt (node)
269 && (flags & TDF_VOPS)
270 && stmt_ann (node))
271 dump_vops (buffer, node, spc, flags);
273 if (is_stmt && (flags & TDF_STMTADDR))
274 pp_printf (buffer, "<&%p> ", (void *)node);
276 if (dumping_stmts
277 && (flags & TDF_LINENO)
278 && EXPR_HAS_LOCATION (node))
280 expanded_location xloc = expand_location (EXPR_LOCATION (node));
281 pp_character (buffer, '[');
282 if (xloc.file)
284 pp_string (buffer, xloc.file);
285 pp_string (buffer, " : ");
287 pp_decimal_int (buffer, xloc.line);
288 pp_string (buffer, "] ");
291 switch (TREE_CODE (node))
293 case ERROR_MARK:
294 pp_string (buffer, "<<< error >>>");
295 break;
297 case IDENTIFIER_NODE:
298 pp_tree_identifier (buffer, node);
299 break;
301 case TREE_LIST:
302 while (node && node != error_mark_node)
304 if (TREE_PURPOSE (node))
306 dump_generic_node (buffer, TREE_PURPOSE (node), spc, flags, false);
307 pp_space (buffer);
309 dump_generic_node (buffer, TREE_VALUE (node), spc, flags, false);
310 node = TREE_CHAIN (node);
311 if (node && TREE_CODE (node) == TREE_LIST)
313 pp_character (buffer, ',');
314 pp_space (buffer);
317 break;
319 case TREE_BINFO:
320 dump_generic_node (buffer, BINFO_TYPE (node), spc, flags, false);
322 case TREE_VEC:
324 size_t i;
325 if (TREE_VEC_LENGTH (node) > 0)
327 size_t len = TREE_VEC_LENGTH (node);
328 for (i = 0; i < len - 1; i++)
330 dump_generic_node (buffer, TREE_VEC_ELT (node, i), spc, flags,
331 false);
332 pp_character (buffer, ',');
333 pp_space (buffer);
335 dump_generic_node (buffer, TREE_VEC_ELT (node, len - 1), spc,
336 flags, false);
339 break;
341 case BLOCK:
342 NIY;
343 break;
345 case VOID_TYPE:
346 case INTEGER_TYPE:
347 case REAL_TYPE:
348 case COMPLEX_TYPE:
349 case VECTOR_TYPE:
350 case ENUMERAL_TYPE:
351 case BOOLEAN_TYPE:
352 case CHAR_TYPE:
354 unsigned int quals = TYPE_QUALS (node);
355 enum tree_code_class class;
357 if (quals & TYPE_QUAL_CONST)
358 pp_string (buffer, "const ");
359 else if (quals & TYPE_QUAL_VOLATILE)
360 pp_string (buffer, "volatile ");
361 else if (quals & TYPE_QUAL_RESTRICT)
362 pp_string (buffer, "restrict ");
364 class = TREE_CODE_CLASS (TREE_CODE (node));
366 if (class == tcc_declaration)
368 if (DECL_NAME (node))
369 dump_decl_name (buffer, node, flags);
370 else
371 pp_string (buffer, "<unnamed type decl>");
373 else if (class == tcc_type)
375 if (TYPE_NAME (node))
377 if (TREE_CODE (TYPE_NAME (node)) == IDENTIFIER_NODE)
378 pp_tree_identifier (buffer, TYPE_NAME (node));
379 else if (TREE_CODE (TYPE_NAME (node)) == TYPE_DECL
380 && DECL_NAME (TYPE_NAME (node)))
381 dump_decl_name (buffer, TYPE_NAME (node), flags);
382 else
383 pp_string (buffer, "<unnamed type>");
385 else if (TREE_CODE (node) == VECTOR_TYPE)
387 pp_string (buffer, "vector ");
388 dump_generic_node (buffer, TREE_TYPE (node),
389 spc, flags, false);
391 else
392 pp_string (buffer, "<unnamed type>");
394 break;
397 case POINTER_TYPE:
398 case REFERENCE_TYPE:
399 str = (TREE_CODE (node) == POINTER_TYPE ? "*" : "&");
401 if (TREE_CODE (TREE_TYPE (node)) == FUNCTION_TYPE)
403 tree fnode = TREE_TYPE (node);
405 dump_generic_node (buffer, TREE_TYPE (fnode), spc, flags, false);
406 pp_space (buffer);
407 pp_character (buffer, '(');
408 pp_string (buffer, str);
409 if (TYPE_NAME (node) && DECL_NAME (TYPE_NAME (node)))
410 dump_decl_name (buffer, TYPE_NAME (node), flags);
411 else
412 pp_printf (buffer, "<T%x>", TYPE_UID (node));
414 pp_character (buffer, ')');
415 dump_function_declaration (buffer, fnode, spc, flags);
417 else
419 unsigned int quals = TYPE_QUALS (node);
421 dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
422 pp_space (buffer);
423 pp_string (buffer, str);
425 if (quals & TYPE_QUAL_CONST)
426 pp_string (buffer, " const");
427 else if (quals & TYPE_QUAL_VOLATILE)
428 pp_string (buffer, "volatile");
429 else if (quals & TYPE_QUAL_RESTRICT)
430 pp_string (buffer, " restrict");
432 if (TYPE_REF_CAN_ALIAS_ALL (node))
433 pp_string (buffer, " {ref-all}");
435 break;
437 case OFFSET_TYPE:
438 NIY;
439 break;
441 case METHOD_TYPE:
442 dump_decl_name (buffer, TYPE_NAME (TYPE_METHOD_BASETYPE (node)), flags);
443 pp_string (buffer, "::");
444 break;
446 case TARGET_MEM_REF:
448 const char *sep = "";
449 tree tmp;
451 pp_string (buffer, "MEM[");
453 tmp = TMR_SYMBOL (node);
454 if (tmp)
456 pp_string (buffer, sep);
457 sep = ", ";
458 pp_string (buffer, "symbol: ");
459 dump_generic_node (buffer, tmp, spc, flags, false);
461 tmp = TMR_BASE (node);
462 if (tmp)
464 pp_string (buffer, sep);
465 sep = ", ";
466 pp_string (buffer, "base: ");
467 dump_generic_node (buffer, tmp, spc, flags, false);
469 tmp = TMR_INDEX (node);
470 if (tmp)
472 pp_string (buffer, sep);
473 sep = ", ";
474 pp_string (buffer, "index: ");
475 dump_generic_node (buffer, tmp, spc, flags, false);
477 tmp = TMR_STEP (node);
478 if (tmp)
480 pp_string (buffer, sep);
481 sep = ", ";
482 pp_string (buffer, "step: ");
483 dump_generic_node (buffer, tmp, spc, flags, false);
485 tmp = TMR_OFFSET (node);
486 if (tmp)
488 pp_string (buffer, sep);
489 sep = ", ";
490 pp_string (buffer, "offset: ");
491 dump_generic_node (buffer, tmp, spc, flags, false);
493 pp_string (buffer, "]");
494 if (flags & TDF_DETAILS)
496 pp_string (buffer, "{");
497 dump_generic_node (buffer, TMR_ORIGINAL (node), spc, flags,
498 false);
499 pp_string (buffer, "}");
502 break;
504 case ARRAY_TYPE:
506 tree tmp;
508 /* Print the innermost component type. */
509 for (tmp = TREE_TYPE (node); TREE_CODE (tmp) == ARRAY_TYPE;
510 tmp = TREE_TYPE (tmp))
512 dump_generic_node (buffer, tmp, spc, flags, false);
514 /* Print the dimensions. */
515 for (tmp = node; TREE_CODE (tmp) == ARRAY_TYPE; tmp = TREE_TYPE (tmp))
516 dump_array_domain (buffer, TYPE_DOMAIN (tmp), spc, flags);
517 break;
520 case RECORD_TYPE:
521 case UNION_TYPE:
522 case QUAL_UNION_TYPE:
523 /* Print the name of the structure. */
524 if (TREE_CODE (node) == RECORD_TYPE)
525 pp_string (buffer, "struct ");
526 else if (TREE_CODE (node) == UNION_TYPE)
527 pp_string (buffer, "union ");
529 if (TYPE_NAME (node))
530 dump_generic_node (buffer, TYPE_NAME (node), spc, flags, false);
531 else
532 print_struct_decl (buffer, node, spc, flags);
533 break;
535 case LANG_TYPE:
536 NIY;
537 break;
539 case INTEGER_CST:
540 if (TREE_CODE (TREE_TYPE (node)) == POINTER_TYPE)
542 /* In the case of a pointer, one may want to divide by the
543 size of the pointed-to type. Unfortunately, this not
544 straightforward. The C front-end maps expressions
546 (int *) 5
547 int *p; (p + 5)
549 in such a way that the two INTEGER_CST nodes for "5" have
550 different values but identical types. In the latter
551 case, the 5 is multiplied by sizeof (int) in c-common.c
552 (pointer_int_sum) to convert it to a byte address, and
553 yet the type of the node is left unchanged. Argh. What
554 is consistent though is that the number value corresponds
555 to bytes (UNITS) offset.
557 NB: Neither of the following divisors can be trivially
558 used to recover the original literal:
560 TREE_INT_CST_LOW (TYPE_SIZE_UNIT (TREE_TYPE (node)))
561 TYPE_PRECISION (TREE_TYPE (TREE_TYPE (node))) */
562 pp_wide_integer (buffer, TREE_INT_CST_LOW (node));
563 pp_string (buffer, "B"); /* pseudo-unit */
565 else if (! host_integerp (node, 0))
567 tree val = node;
569 if (tree_int_cst_sgn (val) < 0)
571 pp_character (buffer, '-');
572 val = build_int_cst_wide (NULL_TREE,
573 -TREE_INT_CST_LOW (val),
574 ~TREE_INT_CST_HIGH (val)
575 + !TREE_INT_CST_LOW (val));
577 /* Would "%x%0*x" or "%x%*0x" get zero-padding on all
578 systems? */
580 static char format[10]; /* "%x%09999x\0" */
581 if (!format[0])
582 sprintf (format, "%%x%%0%dx", HOST_BITS_PER_INT / 4);
583 sprintf (pp_buffer (buffer)->digit_buffer, format,
584 TREE_INT_CST_HIGH (val),
585 TREE_INT_CST_LOW (val));
586 pp_string (buffer, pp_buffer (buffer)->digit_buffer);
589 else
590 pp_wide_integer (buffer, TREE_INT_CST_LOW (node));
591 break;
593 case REAL_CST:
594 /* Code copied from print_node. */
596 REAL_VALUE_TYPE d;
597 if (TREE_OVERFLOW (node))
598 pp_string (buffer, " overflow");
600 #if !defined(REAL_IS_NOT_DOUBLE) || defined(REAL_ARITHMETIC)
601 d = TREE_REAL_CST (node);
602 if (REAL_VALUE_ISINF (d))
603 pp_string (buffer, " Inf");
604 else if (REAL_VALUE_ISNAN (d))
605 pp_string (buffer, " Nan");
606 else
608 char string[100];
609 real_to_decimal (string, &d, sizeof (string), 0, 1);
610 pp_string (buffer, string);
612 #else
614 HOST_WIDE_INT i;
615 unsigned char *p = (unsigned char *) &TREE_REAL_CST (node);
616 pp_string (buffer, "0x");
617 for (i = 0; i < sizeof TREE_REAL_CST (node); i++)
618 output_formatted_integer (buffer, "%02x", *p++);
620 #endif
621 break;
624 case COMPLEX_CST:
625 pp_string (buffer, "__complex__ (");
626 dump_generic_node (buffer, TREE_REALPART (node), spc, flags, false);
627 pp_string (buffer, ", ");
628 dump_generic_node (buffer, TREE_IMAGPART (node), spc, flags, false);
629 pp_string (buffer, ")");
630 break;
632 case STRING_CST:
633 pp_string (buffer, "\"");
634 pretty_print_string (buffer, TREE_STRING_POINTER (node));
635 pp_string (buffer, "\"");
636 break;
638 case VECTOR_CST:
640 tree elt;
641 pp_string (buffer, "{ ");
642 for (elt = TREE_VECTOR_CST_ELTS (node); elt; elt = TREE_CHAIN (elt))
644 dump_generic_node (buffer, TREE_VALUE (elt), spc, flags, false);
645 if (TREE_CHAIN (elt))
646 pp_string (buffer, ", ");
648 pp_string (buffer, " }");
650 break;
652 case FUNCTION_TYPE:
653 break;
655 case FUNCTION_DECL:
656 case CONST_DECL:
657 dump_decl_name (buffer, node, flags);
658 break;
660 case LABEL_DECL:
661 if (DECL_NAME (node))
662 dump_decl_name (buffer, node, flags);
663 else if (LABEL_DECL_UID (node) != -1)
664 pp_printf (buffer, "<L" HOST_WIDE_INT_PRINT_DEC ">",
665 LABEL_DECL_UID (node));
666 else
667 pp_printf (buffer, "<D%u>", DECL_UID (node));
668 break;
670 case TYPE_DECL:
671 if (DECL_IS_BUILTIN (node))
673 /* Don't print the declaration of built-in types. */
674 break;
676 if (DECL_NAME (node))
677 dump_decl_name (buffer, node, flags);
678 else
680 if ((TREE_CODE (TREE_TYPE (node)) == RECORD_TYPE
681 || TREE_CODE (TREE_TYPE (node)) == UNION_TYPE)
682 && TYPE_METHODS (TREE_TYPE (node)))
684 /* The type is a c++ class: all structures have at least
685 4 methods. */
686 pp_string (buffer, "class ");
687 dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
689 else
691 pp_string (buffer,
692 (TREE_CODE (TREE_TYPE (node)) == UNION_TYPE
693 ? "union" : "struct "));
694 dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
697 break;
699 case VAR_DECL:
700 case PARM_DECL:
701 case FIELD_DECL:
702 case NAMESPACE_DECL:
703 dump_decl_name (buffer, node, flags);
704 break;
706 case RESULT_DECL:
707 pp_string (buffer, "<retval>");
708 break;
710 case COMPONENT_REF:
711 op0 = TREE_OPERAND (node, 0);
712 str = ".";
713 if (TREE_CODE (op0) == INDIRECT_REF)
715 op0 = TREE_OPERAND (op0, 0);
716 str = "->";
718 if (op_prio (op0) < op_prio (node))
719 pp_character (buffer, '(');
720 dump_generic_node (buffer, op0, spc, flags, false);
721 if (op_prio (op0) < op_prio (node))
722 pp_character (buffer, ')');
723 pp_string (buffer, str);
724 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
726 if (TREE_CODE (op0) != VALUE_HANDLE)
728 op0 = component_ref_field_offset (node);
729 if (op0 && TREE_CODE (op0) != INTEGER_CST)
731 pp_string (buffer, "{off: ");
732 dump_generic_node (buffer, op0, spc, flags, false);
733 pp_character (buffer, '}');
736 break;
738 case BIT_FIELD_REF:
739 pp_string (buffer, "BIT_FIELD_REF <");
740 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
741 pp_string (buffer, ", ");
742 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
743 pp_string (buffer, ", ");
744 dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
745 pp_string (buffer, ">");
746 break;
748 case ARRAY_REF:
749 case ARRAY_RANGE_REF:
750 op0 = TREE_OPERAND (node, 0);
751 if (op_prio (op0) < op_prio (node))
752 pp_character (buffer, '(');
753 dump_generic_node (buffer, op0, spc, flags, false);
754 if (op_prio (op0) < op_prio (node))
755 pp_character (buffer, ')');
756 pp_character (buffer, '[');
757 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
758 if (TREE_CODE (node) == ARRAY_RANGE_REF)
759 pp_string (buffer, " ...");
760 pp_character (buffer, ']');
762 op0 = array_ref_low_bound (node);
763 op1 = array_ref_element_size (node);
765 if (!integer_zerop (op0)
766 || (TYPE_SIZE_UNIT (TREE_TYPE (node))
767 && !operand_equal_p (op1, TYPE_SIZE_UNIT (TREE_TYPE (node)), 0)))
769 pp_string (buffer, "{lb: ");
770 dump_generic_node (buffer, op0, spc, flags, false);
771 pp_string (buffer, " sz: ");
772 dump_generic_node (buffer, op1, spc, flags, false);
773 pp_character (buffer, '}');
775 break;
777 case CONSTRUCTOR:
779 tree lnode;
780 bool is_struct_init = FALSE;
781 pp_character (buffer, '{');
782 lnode = CONSTRUCTOR_ELTS (node);
783 if (TREE_CODE (TREE_TYPE (node)) == RECORD_TYPE
784 || TREE_CODE (TREE_TYPE (node)) == UNION_TYPE)
785 is_struct_init = TRUE;
786 while (lnode && lnode != error_mark_node)
788 tree val;
789 if (TREE_PURPOSE (lnode) && is_struct_init)
791 pp_character (buffer, '.');
792 dump_generic_node (buffer, TREE_PURPOSE (lnode), spc, flags, false);
793 pp_string (buffer, "=");
795 val = TREE_VALUE (lnode);
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)
801 dump_decl_name (buffer, val, flags);
803 else
805 dump_generic_node (buffer, TREE_VALUE (lnode), spc, flags, false);
807 lnode = TREE_CHAIN (lnode);
808 if (lnode && TREE_CODE (lnode) == TREE_LIST)
810 pp_character (buffer, ',');
811 pp_space (buffer);
814 pp_character (buffer, '}');
816 break;
818 case COMPOUND_EXPR:
820 tree *tp;
821 if (flags & TDF_SLIM)
823 pp_string (buffer, "<COMPOUND_EXPR>");
824 break;
827 dump_generic_node (buffer, TREE_OPERAND (node, 0),
828 spc, flags, dumping_stmts);
829 if (dumping_stmts)
830 newline_and_indent (buffer, spc);
831 else
833 pp_character (buffer, ',');
834 pp_space (buffer);
837 for (tp = &TREE_OPERAND (node, 1);
838 TREE_CODE (*tp) == COMPOUND_EXPR;
839 tp = &TREE_OPERAND (*tp, 1))
841 dump_generic_node (buffer, TREE_OPERAND (*tp, 0),
842 spc, flags, dumping_stmts);
843 if (dumping_stmts)
844 newline_and_indent (buffer, spc);
845 else
847 pp_character (buffer, ',');
848 pp_space (buffer);
852 dump_generic_node (buffer, *tp, spc, flags, dumping_stmts);
854 break;
856 case STATEMENT_LIST:
858 tree_stmt_iterator si;
859 bool first = true;
861 if ((flags & TDF_SLIM) || !dumping_stmts)
863 pp_string (buffer, "<STATEMENT_LIST>");
864 break;
867 for (si = tsi_start (node); !tsi_end_p (si); tsi_next (&si))
869 if (!first)
870 newline_and_indent (buffer, spc);
871 else
872 first = false;
873 dump_generic_node (buffer, tsi_stmt (si), spc, flags, true);
876 break;
878 case MODIFY_EXPR:
879 case INIT_EXPR:
880 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
881 pp_space (buffer);
882 pp_character (buffer, '=');
883 pp_space (buffer);
884 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
885 break;
887 case TARGET_EXPR:
888 pp_string (buffer, "TARGET_EXPR <");
889 dump_generic_node (buffer, TARGET_EXPR_SLOT (node), spc, flags, false);
890 pp_character (buffer, ',');
891 pp_space (buffer);
892 dump_generic_node (buffer, TARGET_EXPR_INITIAL (node), spc, flags, false);
893 pp_character (buffer, '>');
894 break;
896 case DECL_EXPR:
897 print_declaration (buffer, DECL_EXPR_DECL (node), spc, flags);
898 is_stmt = false;
899 break;
901 case COND_EXPR:
902 if (TREE_TYPE (node) == NULL || TREE_TYPE (node) == void_type_node)
904 pp_string (buffer, "if (");
905 dump_generic_node (buffer, COND_EXPR_COND (node), spc, flags, false);
906 pp_character (buffer, ')');
907 /* The lowered cond_exprs should always be printed in full. */
908 if (COND_EXPR_THEN (node)
909 && (IS_EMPTY_STMT (COND_EXPR_THEN (node))
910 || TREE_CODE (COND_EXPR_THEN (node)) == GOTO_EXPR)
911 && COND_EXPR_ELSE (node)
912 && (IS_EMPTY_STMT (COND_EXPR_ELSE (node))
913 || TREE_CODE (COND_EXPR_ELSE (node)) == GOTO_EXPR))
915 pp_space (buffer);
916 dump_generic_node (buffer, COND_EXPR_THEN (node), 0, flags, true);
917 pp_string (buffer, " else ");
918 dump_generic_node (buffer, COND_EXPR_ELSE (node), 0, flags, true);
920 else if (!(flags & TDF_SLIM))
922 /* Output COND_EXPR_THEN. */
923 if (COND_EXPR_THEN (node))
925 newline_and_indent (buffer, spc+2);
926 pp_character (buffer, '{');
927 newline_and_indent (buffer, spc+4);
928 dump_generic_node (buffer, COND_EXPR_THEN (node), spc+4,
929 flags, true);
930 newline_and_indent (buffer, spc+2);
931 pp_character (buffer, '}');
934 /* Output COND_EXPR_ELSE. */
935 if (COND_EXPR_ELSE (node))
937 newline_and_indent (buffer, spc);
938 pp_string (buffer, "else");
939 newline_and_indent (buffer, spc+2);
940 pp_character (buffer, '{');
941 newline_and_indent (buffer, spc+4);
942 dump_generic_node (buffer, COND_EXPR_ELSE (node), spc+4,
943 flags, true);
944 newline_and_indent (buffer, spc+2);
945 pp_character (buffer, '}');
948 is_expr = false;
950 else
952 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
953 pp_space (buffer);
954 pp_character (buffer, '?');
955 pp_space (buffer);
956 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
957 pp_space (buffer);
958 pp_character (buffer, ':');
959 pp_space (buffer);
960 dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
962 break;
964 case BIND_EXPR:
965 pp_character (buffer, '{');
966 if (!(flags & TDF_SLIM))
968 if (BIND_EXPR_VARS (node))
970 pp_newline (buffer);
972 for (op0 = BIND_EXPR_VARS (node); op0; op0 = TREE_CHAIN (op0))
974 print_declaration (buffer, op0, spc+2, flags);
975 pp_newline (buffer);
979 newline_and_indent (buffer, spc+2);
980 dump_generic_node (buffer, BIND_EXPR_BODY (node), spc+2, flags, true);
981 newline_and_indent (buffer, spc);
982 pp_character (buffer, '}');
984 is_expr = false;
985 break;
987 case CALL_EXPR:
988 print_call_name (buffer, node);
990 /* Print parameters. */
991 pp_space (buffer);
992 pp_character (buffer, '(');
993 op1 = TREE_OPERAND (node, 1);
994 if (op1)
995 dump_generic_node (buffer, op1, spc, flags, false);
996 pp_character (buffer, ')');
998 op1 = TREE_OPERAND (node, 2);
999 if (op1)
1001 pp_string (buffer, " [static-chain: ");
1002 dump_generic_node (buffer, op1, spc, flags, false);
1003 pp_character (buffer, ']');
1006 if (CALL_EXPR_RETURN_SLOT_OPT (node))
1007 pp_string (buffer, " [return slot optimization]");
1008 if (CALL_EXPR_TAILCALL (node))
1009 pp_string (buffer, " [tail call]");
1010 break;
1012 case WITH_CLEANUP_EXPR:
1013 NIY;
1014 break;
1016 case CLEANUP_POINT_EXPR:
1017 pp_string (buffer, "<<cleanup_point ");
1018 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1019 pp_string (buffer, ">>");
1020 break;
1022 case PLACEHOLDER_EXPR:
1023 pp_string (buffer, "<PLACEHOLDER_EXPR ");
1024 dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
1025 pp_character (buffer, '>');
1026 break;
1028 /* Binary arithmetic and logic expressions. */
1029 case MULT_EXPR:
1030 case PLUS_EXPR:
1031 case MINUS_EXPR:
1032 case TRUNC_DIV_EXPR:
1033 case CEIL_DIV_EXPR:
1034 case FLOOR_DIV_EXPR:
1035 case ROUND_DIV_EXPR:
1036 case TRUNC_MOD_EXPR:
1037 case CEIL_MOD_EXPR:
1038 case FLOOR_MOD_EXPR:
1039 case ROUND_MOD_EXPR:
1040 case RDIV_EXPR:
1041 case EXACT_DIV_EXPR:
1042 case LSHIFT_EXPR:
1043 case RSHIFT_EXPR:
1044 case LROTATE_EXPR:
1045 case RROTATE_EXPR:
1046 case VEC_LSHIFT_EXPR:
1047 case VEC_RSHIFT_EXPR:
1048 case BIT_IOR_EXPR:
1049 case BIT_XOR_EXPR:
1050 case BIT_AND_EXPR:
1051 case TRUTH_ANDIF_EXPR:
1052 case TRUTH_ORIF_EXPR:
1053 case TRUTH_AND_EXPR:
1054 case TRUTH_OR_EXPR:
1055 case TRUTH_XOR_EXPR:
1056 case LT_EXPR:
1057 case LE_EXPR:
1058 case GT_EXPR:
1059 case GE_EXPR:
1060 case EQ_EXPR:
1061 case NE_EXPR:
1062 case UNLT_EXPR:
1063 case UNLE_EXPR:
1064 case UNGT_EXPR:
1065 case UNGE_EXPR:
1066 case UNEQ_EXPR:
1067 case LTGT_EXPR:
1068 case ORDERED_EXPR:
1069 case UNORDERED_EXPR:
1071 const char *op = op_symbol (node);
1072 op0 = TREE_OPERAND (node, 0);
1073 op1 = TREE_OPERAND (node, 1);
1075 /* When the operands are expressions with less priority,
1076 keep semantics of the tree representation. */
1077 if (op_prio (op0) < op_prio (node))
1079 pp_character (buffer, '(');
1080 dump_generic_node (buffer, op0, spc, flags, false);
1081 pp_character (buffer, ')');
1083 else
1084 dump_generic_node (buffer, op0, spc, flags, false);
1086 pp_space (buffer);
1087 pp_string (buffer, op);
1088 pp_space (buffer);
1090 /* When the operands are expressions with less priority,
1091 keep semantics of the tree representation. */
1092 if (op_prio (op1) < op_prio (node))
1094 pp_character (buffer, '(');
1095 dump_generic_node (buffer, op1, spc, flags, false);
1096 pp_character (buffer, ')');
1098 else
1099 dump_generic_node (buffer, op1, spc, flags, false);
1101 break;
1103 /* Unary arithmetic and logic expressions. */
1104 case NEGATE_EXPR:
1105 case BIT_NOT_EXPR:
1106 case TRUTH_NOT_EXPR:
1107 case ADDR_EXPR:
1108 case PREDECREMENT_EXPR:
1109 case PREINCREMENT_EXPR:
1110 case ALIGN_INDIRECT_REF:
1111 case MISALIGNED_INDIRECT_REF:
1112 case INDIRECT_REF:
1113 if (TREE_CODE (node) == ADDR_EXPR
1114 && (TREE_CODE (TREE_OPERAND (node, 0)) == STRING_CST
1115 || TREE_CODE (TREE_OPERAND (node, 0)) == FUNCTION_DECL))
1116 ; /* Do not output '&' for strings and function pointers. */
1117 else
1118 pp_string (buffer, op_symbol (node));
1120 if (op_prio (TREE_OPERAND (node, 0)) < op_prio (node))
1122 pp_character (buffer, '(');
1123 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1124 pp_character (buffer, ')');
1126 else
1127 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1129 if (TREE_CODE (node) == MISALIGNED_INDIRECT_REF)
1131 pp_string (buffer, "{misalignment: ");
1132 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1133 pp_character (buffer, '}');
1135 break;
1137 case POSTDECREMENT_EXPR:
1138 case POSTINCREMENT_EXPR:
1139 if (op_prio (TREE_OPERAND (node, 0)) < op_prio (node))
1141 pp_character (buffer, '(');
1142 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1143 pp_character (buffer, ')');
1145 else
1146 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1147 pp_string (buffer, op_symbol (node));
1148 break;
1150 case MIN_EXPR:
1151 pp_string (buffer, "MIN_EXPR <");
1152 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1153 pp_string (buffer, ", ");
1154 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1155 pp_character (buffer, '>');
1156 break;
1158 case MAX_EXPR:
1159 pp_string (buffer, "MAX_EXPR <");
1160 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1161 pp_string (buffer, ", ");
1162 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1163 pp_character (buffer, '>');
1164 break;
1166 case ABS_EXPR:
1167 pp_string (buffer, "ABS_EXPR <");
1168 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1169 pp_character (buffer, '>');
1170 break;
1172 case RANGE_EXPR:
1173 NIY;
1174 break;
1176 case FIX_TRUNC_EXPR:
1177 case FIX_CEIL_EXPR:
1178 case FIX_FLOOR_EXPR:
1179 case FIX_ROUND_EXPR:
1180 case FLOAT_EXPR:
1181 case CONVERT_EXPR:
1182 case NOP_EXPR:
1183 type = TREE_TYPE (node);
1184 op0 = TREE_OPERAND (node, 0);
1185 if (type != TREE_TYPE (op0))
1187 pp_character (buffer, '(');
1188 dump_generic_node (buffer, type, spc, flags, false);
1189 pp_string (buffer, ") ");
1191 if (op_prio (op0) < op_prio (node))
1192 pp_character (buffer, '(');
1193 dump_generic_node (buffer, op0, spc, flags, false);
1194 if (op_prio (op0) < op_prio (node))
1195 pp_character (buffer, ')');
1196 break;
1198 case VIEW_CONVERT_EXPR:
1199 pp_string (buffer, "VIEW_CONVERT_EXPR<");
1200 dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
1201 pp_string (buffer, ">(");
1202 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1203 pp_character (buffer, ')');
1204 break;
1206 case NON_LVALUE_EXPR:
1207 pp_string (buffer, "NON_LVALUE_EXPR <");
1208 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1209 pp_character (buffer, '>');
1210 break;
1212 case SAVE_EXPR:
1213 pp_string (buffer, "SAVE_EXPR <");
1214 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1215 pp_character (buffer, '>');
1216 break;
1218 case COMPLEX_EXPR:
1219 pp_string (buffer, "COMPLEX_EXPR <");
1220 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1221 pp_string (buffer, ", ");
1222 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1223 pp_string (buffer, ">");
1224 break;
1226 case CONJ_EXPR:
1227 pp_string (buffer, "CONJ_EXPR <");
1228 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1229 pp_string (buffer, ">");
1230 break;
1232 case REALPART_EXPR:
1233 pp_string (buffer, "REALPART_EXPR <");
1234 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1235 pp_string (buffer, ">");
1236 break;
1238 case IMAGPART_EXPR:
1239 pp_string (buffer, "IMAGPART_EXPR <");
1240 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1241 pp_string (buffer, ">");
1242 break;
1244 case VA_ARG_EXPR:
1245 pp_string (buffer, "VA_ARG_EXPR <");
1246 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1247 pp_string (buffer, ">");
1248 break;
1250 case TRY_FINALLY_EXPR:
1251 case TRY_CATCH_EXPR:
1252 pp_string (buffer, "try");
1253 newline_and_indent (buffer, spc+2);
1254 pp_string (buffer, "{");
1255 newline_and_indent (buffer, spc+4);
1256 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc+4, flags, true);
1257 newline_and_indent (buffer, spc+2);
1258 pp_string (buffer, "}");
1259 newline_and_indent (buffer, spc);
1260 pp_string (buffer,
1261 (TREE_CODE (node) == TRY_CATCH_EXPR) ? "catch" : "finally");
1262 newline_and_indent (buffer, spc+2);
1263 pp_string (buffer, "{");
1264 newline_and_indent (buffer, spc+4);
1265 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc+4, flags, true);
1266 newline_and_indent (buffer, spc+2);
1267 pp_string (buffer, "}");
1268 is_expr = false;
1269 break;
1271 case CATCH_EXPR:
1272 pp_string (buffer, "catch (");
1273 dump_generic_node (buffer, CATCH_TYPES (node), spc+2, flags, false);
1274 pp_string (buffer, ")");
1275 newline_and_indent (buffer, spc+2);
1276 pp_string (buffer, "{");
1277 newline_and_indent (buffer, spc+4);
1278 dump_generic_node (buffer, CATCH_BODY (node), spc+4, flags, true);
1279 newline_and_indent (buffer, spc+2);
1280 pp_string (buffer, "}");
1281 is_expr = false;
1282 break;
1284 case EH_FILTER_EXPR:
1285 pp_string (buffer, "<<<eh_filter (");
1286 dump_generic_node (buffer, EH_FILTER_TYPES (node), spc+2, flags, false);
1287 pp_string (buffer, ")>>>");
1288 newline_and_indent (buffer, spc+2);
1289 pp_string (buffer, "{");
1290 newline_and_indent (buffer, spc+4);
1291 dump_generic_node (buffer, EH_FILTER_FAILURE (node), spc+4, flags, true);
1292 newline_and_indent (buffer, spc+2);
1293 pp_string (buffer, "}");
1294 is_expr = false;
1295 break;
1297 case LABEL_EXPR:
1298 op0 = TREE_OPERAND (node, 0);
1299 /* If this is for break or continue, don't bother printing it. */
1300 if (DECL_NAME (op0))
1302 const char *name = IDENTIFIER_POINTER (DECL_NAME (op0));
1303 if (strcmp (name, "break") == 0
1304 || strcmp (name, "continue") == 0)
1305 break;
1307 dump_generic_node (buffer, op0, spc, flags, false);
1308 pp_character (buffer, ':');
1309 if (DECL_NONLOCAL (op0))
1310 pp_string (buffer, " [non-local]");
1311 break;
1313 case EXC_PTR_EXPR:
1314 pp_string (buffer, "<<<exception object>>>");
1315 break;
1317 case FILTER_EXPR:
1318 pp_string (buffer, "<<<filter object>>>");
1319 break;
1321 case LOOP_EXPR:
1322 pp_string (buffer, "while (1)");
1323 if (!(flags & TDF_SLIM))
1325 newline_and_indent (buffer, spc+2);
1326 pp_character (buffer, '{');
1327 newline_and_indent (buffer, spc+4);
1328 dump_generic_node (buffer, LOOP_EXPR_BODY (node), spc+4, flags, true);
1329 newline_and_indent (buffer, spc+2);
1330 pp_character (buffer, '}');
1332 is_expr = false;
1333 break;
1335 case RETURN_EXPR:
1336 pp_string (buffer, "return");
1337 op0 = TREE_OPERAND (node, 0);
1338 if (op0)
1340 pp_space (buffer);
1341 if (TREE_CODE (op0) == MODIFY_EXPR)
1342 dump_generic_node (buffer, TREE_OPERAND (op0, 1), spc, flags, false);
1343 else
1344 dump_generic_node (buffer, op0, spc, flags, false);
1346 break;
1348 case EXIT_EXPR:
1349 pp_string (buffer, "if (");
1350 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1351 pp_string (buffer, ") break");
1352 break;
1354 case SWITCH_EXPR:
1355 pp_string (buffer, "switch (");
1356 dump_generic_node (buffer, SWITCH_COND (node), spc, flags, false);
1357 pp_character (buffer, ')');
1358 if (!(flags & TDF_SLIM))
1360 newline_and_indent (buffer, spc+2);
1361 pp_character (buffer, '{');
1362 if (SWITCH_BODY (node))
1364 newline_and_indent (buffer, spc+4);
1365 dump_generic_node (buffer, SWITCH_BODY (node), spc+4, flags, true);
1367 else
1369 tree vec = SWITCH_LABELS (node);
1370 size_t i, n = TREE_VEC_LENGTH (vec);
1371 for (i = 0; i < n; ++i)
1373 tree elt = TREE_VEC_ELT (vec, i);
1374 newline_and_indent (buffer, spc+4);
1375 dump_generic_node (buffer, elt, spc+4, flags, false);
1376 pp_string (buffer, " goto ");
1377 dump_generic_node (buffer, CASE_LABEL (elt), spc+4, flags, true);
1378 pp_semicolon (buffer);
1381 newline_and_indent (buffer, spc+2);
1382 pp_character (buffer, '}');
1384 is_expr = false;
1385 break;
1387 case GOTO_EXPR:
1388 op0 = GOTO_DESTINATION (node);
1389 if (TREE_CODE (op0) != SSA_NAME && DECL_P (op0) && DECL_NAME (op0))
1391 const char *name = IDENTIFIER_POINTER (DECL_NAME (op0));
1392 if (strcmp (name, "break") == 0
1393 || strcmp (name, "continue") == 0)
1395 pp_string (buffer, name);
1396 break;
1399 pp_string (buffer, "goto ");
1400 dump_generic_node (buffer, op0, spc, flags, false);
1401 break;
1403 case RESX_EXPR:
1404 pp_string (buffer, "resx");
1405 /* ??? Any sensible way to present the eh region? */
1406 break;
1408 case ASM_EXPR:
1409 pp_string (buffer, "__asm__");
1410 if (ASM_VOLATILE_P (node))
1411 pp_string (buffer, " __volatile__");
1412 pp_character (buffer, '(');
1413 dump_generic_node (buffer, ASM_STRING (node), spc, flags, false);
1414 pp_character (buffer, ':');
1415 dump_generic_node (buffer, ASM_OUTPUTS (node), spc, flags, false);
1416 pp_character (buffer, ':');
1417 dump_generic_node (buffer, ASM_INPUTS (node), spc, flags, false);
1418 if (ASM_CLOBBERS (node))
1420 pp_character (buffer, ':');
1421 dump_generic_node (buffer, ASM_CLOBBERS (node), spc, flags, false);
1423 pp_string (buffer, ")");
1424 break;
1426 case CASE_LABEL_EXPR:
1427 if (CASE_LOW (node) && CASE_HIGH (node))
1429 pp_string (buffer, "case ");
1430 dump_generic_node (buffer, CASE_LOW (node), spc, flags, false);
1431 pp_string (buffer, " ... ");
1432 dump_generic_node (buffer, CASE_HIGH (node), spc, flags, false);
1434 else if (CASE_LOW (node))
1436 pp_string (buffer, "case ");
1437 dump_generic_node (buffer, CASE_LOW (node), spc, flags, false);
1439 else
1440 pp_string (buffer, "default ");
1441 pp_character (buffer, ':');
1442 break;
1444 case OBJ_TYPE_REF:
1445 pp_string (buffer, "OBJ_TYPE_REF(");
1446 dump_generic_node (buffer, OBJ_TYPE_REF_EXPR (node), spc, flags, false);
1447 pp_character (buffer, ';');
1448 dump_generic_node (buffer, OBJ_TYPE_REF_OBJECT (node), spc, flags, false);
1449 pp_character (buffer, '-');
1450 pp_character (buffer, '>');
1451 dump_generic_node (buffer, OBJ_TYPE_REF_TOKEN (node), spc, flags, false);
1452 pp_character (buffer, ')');
1453 break;
1455 case PHI_NODE:
1457 int i;
1459 dump_generic_node (buffer, PHI_RESULT (node), spc, flags, false);
1460 pp_string (buffer, " = PHI <");
1461 for (i = 0; i < PHI_NUM_ARGS (node); i++)
1463 dump_generic_node (buffer, PHI_ARG_DEF (node, i), spc, flags, false);
1464 pp_string (buffer, "(");
1465 pp_decimal_int (buffer, PHI_ARG_EDGE (node, i)->src->index);
1466 pp_string (buffer, ")");
1467 if (i < PHI_NUM_ARGS (node) - 1)
1468 pp_string (buffer, ", ");
1470 pp_string (buffer, ">;");
1472 break;
1474 case SSA_NAME:
1475 dump_generic_node (buffer, SSA_NAME_VAR (node), spc, flags, false);
1476 pp_string (buffer, "_");
1477 pp_decimal_int (buffer, SSA_NAME_VERSION (node));
1478 if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (node))
1479 pp_string (buffer, "(ab)");
1480 break;
1482 case WITH_SIZE_EXPR:
1483 pp_string (buffer, "WITH_SIZE_EXPR <");
1484 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1485 pp_string (buffer, ", ");
1486 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1487 pp_string (buffer, ">");
1488 break;
1490 case VALUE_HANDLE:
1491 pp_printf (buffer, "VH.%d", VALUE_HANDLE_ID (node));
1492 break;
1494 case ASSERT_EXPR:
1495 pp_string (buffer, "ASSERT_EXPR <");
1496 dump_generic_node (buffer, ASSERT_EXPR_VAR (node), spc, flags, false);
1497 pp_string (buffer, ", ");
1498 dump_generic_node (buffer, ASSERT_EXPR_COND (node), spc, flags, false);
1499 pp_string (buffer, ">");
1500 break;
1502 case SCEV_KNOWN:
1503 pp_string (buffer, "scev_known");
1504 break;
1506 case SCEV_NOT_KNOWN:
1507 pp_string (buffer, "scev_not_known");
1508 break;
1510 case POLYNOMIAL_CHREC:
1511 pp_string (buffer, "{");
1512 dump_generic_node (buffer, CHREC_LEFT (node), spc, flags, false);
1513 pp_string (buffer, ", +, ");
1514 dump_generic_node (buffer, CHREC_RIGHT (node), spc, flags, false);
1515 pp_string (buffer, "}_");
1516 dump_generic_node (buffer, CHREC_VAR (node), spc, flags, false);
1517 is_stmt = false;
1518 break;
1520 case REALIGN_LOAD_EXPR:
1521 pp_string (buffer, "REALIGN_LOAD <");
1522 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1523 pp_string (buffer, ", ");
1524 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1525 pp_string (buffer, ", ");
1526 dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
1527 pp_string (buffer, ">");
1528 break;
1530 case VEC_COND_EXPR:
1531 pp_string (buffer, " VEC_COND_EXPR < ");
1532 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1533 pp_string (buffer, " , ");
1534 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1535 pp_string (buffer, " , ");
1536 dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
1537 pp_string (buffer, " > ");
1538 break;
1540 case REDUC_MAX_EXPR:
1541 pp_string (buffer, " REDUC_MAX_EXPR < ");
1542 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1543 pp_string (buffer, " > ");
1544 break;
1546 case REDUC_MIN_EXPR:
1547 pp_string (buffer, " REDUC_MIN_EXPR < ");
1548 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1549 pp_string (buffer, " > ");
1550 break;
1552 case REDUC_PLUS_EXPR:
1553 pp_string (buffer, " REDUC_PLUS_EXPR < ");
1554 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1555 pp_string (buffer, " > ");
1556 break;
1558 default:
1559 NIY;
1562 if (is_stmt && is_expr)
1563 pp_semicolon (buffer);
1564 pp_write_text_to_stream (buffer);
1566 return spc;
1569 /* Print the declaration of a variable. */
1571 static void
1572 print_declaration (pretty_printer *buffer, tree t, int spc, int flags)
1574 INDENT (spc);
1576 if (TREE_CODE (t) == TYPE_DECL)
1577 pp_string (buffer, "typedef ");
1579 if (DECL_REGISTER (t))
1580 pp_string (buffer, "register ");
1582 if (TREE_PUBLIC (t) && DECL_EXTERNAL (t))
1583 pp_string (buffer, "extern ");
1584 else if (TREE_STATIC (t))
1585 pp_string (buffer, "static ");
1587 /* Print the type and name. */
1588 if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
1590 tree tmp;
1592 /* Print array's type. */
1593 tmp = TREE_TYPE (t);
1594 while (TREE_CODE (TREE_TYPE (tmp)) == ARRAY_TYPE)
1595 tmp = TREE_TYPE (tmp);
1596 dump_generic_node (buffer, TREE_TYPE (tmp), spc, flags, false);
1598 /* Print variable's name. */
1599 pp_space (buffer);
1600 dump_generic_node (buffer, t, spc, flags, false);
1602 /* Print the dimensions. */
1603 tmp = TREE_TYPE (t);
1604 while (TREE_CODE (tmp) == ARRAY_TYPE)
1606 dump_array_domain (buffer, TYPE_DOMAIN (tmp), spc, flags);
1607 tmp = TREE_TYPE (tmp);
1610 else if (TREE_CODE (t) == FUNCTION_DECL)
1612 dump_generic_node (buffer, TREE_TYPE (TREE_TYPE (t)), spc, flags, false);
1613 pp_space (buffer);
1614 dump_decl_name (buffer, t, flags);
1615 dump_function_declaration (buffer, TREE_TYPE (t), spc, flags);
1617 else
1619 /* Print type declaration. */
1620 dump_generic_node (buffer, TREE_TYPE (t), spc, flags, false);
1622 /* Print variable's name. */
1623 pp_space (buffer);
1624 dump_generic_node (buffer, t, spc, flags, false);
1627 if (TREE_CODE (t) == VAR_DECL && DECL_HARD_REGISTER (t))
1629 pp_string (buffer, " __asm__ ");
1630 pp_character (buffer, '(');
1631 dump_generic_node (buffer, DECL_ASSEMBLER_NAME (t), spc, flags, false);
1632 pp_character (buffer, ')');
1635 /* The initial value of a function serves to determine wether the function
1636 is declared or defined. So the following does not apply to function
1637 nodes. */
1638 if (TREE_CODE (t) != FUNCTION_DECL)
1640 /* Print the initial value. */
1641 if (DECL_INITIAL (t))
1643 pp_space (buffer);
1644 pp_character (buffer, '=');
1645 pp_space (buffer);
1646 dump_generic_node (buffer, DECL_INITIAL (t), spc, flags, false);
1650 pp_character (buffer, ';');
1654 /* Prints a structure: name, fields, and methods.
1655 FIXME: Still incomplete. */
1657 static void
1658 print_struct_decl (pretty_printer *buffer, tree node, int spc, int flags)
1660 /* Print the name of the structure. */
1661 if (TYPE_NAME (node))
1663 INDENT (spc);
1664 if (TREE_CODE (node) == RECORD_TYPE)
1665 pp_string (buffer, "struct ");
1666 else if ((TREE_CODE (node) == UNION_TYPE
1667 || TREE_CODE (node) == QUAL_UNION_TYPE))
1668 pp_string (buffer, "union ");
1670 dump_generic_node (buffer, TYPE_NAME (node), spc, 0, false);
1673 /* Print the contents of the structure. */
1674 pp_newline (buffer);
1675 INDENT (spc);
1676 pp_character (buffer, '{');
1677 pp_newline (buffer);
1679 /* Print the fields of the structure. */
1681 tree tmp;
1682 tmp = TYPE_FIELDS (node);
1683 while (tmp)
1685 /* Avoid to print recursively the structure. */
1686 /* FIXME : Not implemented correctly...,
1687 what about the case when we have a cycle in the contain graph? ...
1688 Maybe this could be solved by looking at the scope in which the
1689 structure was declared. */
1690 if (TREE_TYPE (tmp) != node
1691 || (TREE_CODE (TREE_TYPE (tmp)) == POINTER_TYPE
1692 && TREE_TYPE (TREE_TYPE (tmp)) != node))
1694 print_declaration (buffer, tmp, spc+2, flags);
1695 pp_newline (buffer);
1697 tmp = TREE_CHAIN (tmp);
1700 INDENT (spc);
1701 pp_character (buffer, '}');
1704 /* Return the priority of the operator OP.
1706 From lowest to highest precedence with either left-to-right (L-R)
1707 or right-to-left (R-L) associativity]:
1709 1 [L-R] ,
1710 2 [R-L] = += -= *= /= %= &= ^= |= <<= >>=
1711 3 [R-L] ?:
1712 4 [L-R] ||
1713 5 [L-R] &&
1714 6 [L-R] |
1715 7 [L-R] ^
1716 8 [L-R] &
1717 9 [L-R] == !=
1718 10 [L-R] < <= > >=
1719 11 [L-R] << >>
1720 12 [L-R] + -
1721 13 [L-R] * / %
1722 14 [R-L] ! ~ ++ -- + - * & (type) sizeof
1723 15 [L-R] fn() [] -> .
1725 unary +, - and * have higher precedence than the corresponding binary
1726 operators. */
1728 static int
1729 op_prio (tree op)
1731 if (op == NULL)
1732 return 9999;
1734 switch (TREE_CODE (op))
1736 case TREE_LIST:
1737 case COMPOUND_EXPR:
1738 case BIND_EXPR:
1739 return 1;
1741 case MODIFY_EXPR:
1742 case INIT_EXPR:
1743 return 2;
1745 case COND_EXPR:
1746 return 3;
1748 case TRUTH_OR_EXPR:
1749 case TRUTH_ORIF_EXPR:
1750 return 4;
1752 case TRUTH_AND_EXPR:
1753 case TRUTH_ANDIF_EXPR:
1754 return 5;
1756 case BIT_IOR_EXPR:
1757 return 6;
1759 case BIT_XOR_EXPR:
1760 case TRUTH_XOR_EXPR:
1761 return 7;
1763 case BIT_AND_EXPR:
1764 return 8;
1766 case EQ_EXPR:
1767 case NE_EXPR:
1768 return 9;
1770 case UNLT_EXPR:
1771 case UNLE_EXPR:
1772 case UNGT_EXPR:
1773 case UNGE_EXPR:
1774 case UNEQ_EXPR:
1775 case LTGT_EXPR:
1776 case ORDERED_EXPR:
1777 case UNORDERED_EXPR:
1778 case LT_EXPR:
1779 case LE_EXPR:
1780 case GT_EXPR:
1781 case GE_EXPR:
1782 return 10;
1784 case LSHIFT_EXPR:
1785 case RSHIFT_EXPR:
1786 case LROTATE_EXPR:
1787 case RROTATE_EXPR:
1788 return 11;
1790 case PLUS_EXPR:
1791 case MINUS_EXPR:
1792 return 12;
1794 case MULT_EXPR:
1795 case TRUNC_DIV_EXPR:
1796 case CEIL_DIV_EXPR:
1797 case FLOOR_DIV_EXPR:
1798 case ROUND_DIV_EXPR:
1799 case RDIV_EXPR:
1800 case EXACT_DIV_EXPR:
1801 case TRUNC_MOD_EXPR:
1802 case CEIL_MOD_EXPR:
1803 case FLOOR_MOD_EXPR:
1804 case ROUND_MOD_EXPR:
1805 return 13;
1807 case TRUTH_NOT_EXPR:
1808 case BIT_NOT_EXPR:
1809 case POSTINCREMENT_EXPR:
1810 case POSTDECREMENT_EXPR:
1811 case PREINCREMENT_EXPR:
1812 case PREDECREMENT_EXPR:
1813 case NEGATE_EXPR:
1814 case ALIGN_INDIRECT_REF:
1815 case MISALIGNED_INDIRECT_REF:
1816 case INDIRECT_REF:
1817 case ADDR_EXPR:
1818 case FLOAT_EXPR:
1819 case NOP_EXPR:
1820 case CONVERT_EXPR:
1821 case FIX_TRUNC_EXPR:
1822 case FIX_CEIL_EXPR:
1823 case FIX_FLOOR_EXPR:
1824 case FIX_ROUND_EXPR:
1825 case TARGET_EXPR:
1826 return 14;
1828 case CALL_EXPR:
1829 case ARRAY_REF:
1830 case ARRAY_RANGE_REF:
1831 case COMPONENT_REF:
1832 return 15;
1834 /* Special expressions. */
1835 case MIN_EXPR:
1836 case MAX_EXPR:
1837 case ABS_EXPR:
1838 case REALPART_EXPR:
1839 case IMAGPART_EXPR:
1840 case REDUC_MAX_EXPR:
1841 case REDUC_MIN_EXPR:
1842 case REDUC_PLUS_EXPR:
1843 case VEC_LSHIFT_EXPR:
1844 case VEC_RSHIFT_EXPR:
1845 return 16;
1847 case SAVE_EXPR:
1848 case NON_LVALUE_EXPR:
1849 return op_prio (TREE_OPERAND (op, 0));
1851 default:
1852 /* Return an arbitrarily high precedence to avoid surrounding single
1853 VAR_DECLs in ()s. */
1854 return 9999;
1859 /* Return the symbol associated with operator OP. */
1861 static const char *
1862 op_symbol (tree op)
1864 gcc_assert (op);
1866 switch (TREE_CODE (op))
1868 case MODIFY_EXPR:
1869 return "=";
1871 case TRUTH_OR_EXPR:
1872 case TRUTH_ORIF_EXPR:
1873 return "||";
1875 case TRUTH_AND_EXPR:
1876 case TRUTH_ANDIF_EXPR:
1877 return "&&";
1879 case BIT_IOR_EXPR:
1880 return "|";
1882 case TRUTH_XOR_EXPR:
1883 case BIT_XOR_EXPR:
1884 return "^";
1886 case ADDR_EXPR:
1887 case BIT_AND_EXPR:
1888 return "&";
1890 case ORDERED_EXPR:
1891 return "ord";
1892 case UNORDERED_EXPR:
1893 return "unord";
1895 case EQ_EXPR:
1896 return "==";
1897 case UNEQ_EXPR:
1898 return "u==";
1900 case NE_EXPR:
1901 return "!=";
1903 case LT_EXPR:
1904 return "<";
1905 case UNLT_EXPR:
1906 return "u<";
1908 case LE_EXPR:
1909 return "<=";
1910 case UNLE_EXPR:
1911 return "u<=";
1913 case GT_EXPR:
1914 return ">";
1915 case UNGT_EXPR:
1916 return "u>";
1918 case GE_EXPR:
1919 return ">=";
1920 case UNGE_EXPR:
1921 return "u>=";
1923 case LTGT_EXPR:
1924 return "<>";
1926 case LSHIFT_EXPR:
1927 return "<<";
1929 case RSHIFT_EXPR:
1930 return ">>";
1932 case VEC_LSHIFT_EXPR:
1933 return "v<<";
1935 case VEC_RSHIFT_EXPR:
1936 return "v>>";
1938 case PLUS_EXPR:
1939 return "+";
1941 case REDUC_PLUS_EXPR:
1942 return "r+";
1944 case NEGATE_EXPR:
1945 case MINUS_EXPR:
1946 return "-";
1948 case BIT_NOT_EXPR:
1949 return "~";
1951 case TRUTH_NOT_EXPR:
1952 return "!";
1954 case MULT_EXPR:
1955 case INDIRECT_REF:
1956 return "*";
1958 case ALIGN_INDIRECT_REF:
1959 return "A*";
1961 case MISALIGNED_INDIRECT_REF:
1962 return "M*";
1964 case TRUNC_DIV_EXPR:
1965 case RDIV_EXPR:
1966 return "/";
1968 case CEIL_DIV_EXPR:
1969 return "/[cl]";
1971 case FLOOR_DIV_EXPR:
1972 return "/[fl]";
1974 case ROUND_DIV_EXPR:
1975 return "/[rd]";
1977 case EXACT_DIV_EXPR:
1978 return "/[ex]";
1980 case TRUNC_MOD_EXPR:
1981 return "%";
1983 case CEIL_MOD_EXPR:
1984 return "%[cl]";
1986 case FLOOR_MOD_EXPR:
1987 return "%[fl]";
1989 case ROUND_MOD_EXPR:
1990 return "%[rd]";
1992 case PREDECREMENT_EXPR:
1993 return " --";
1995 case PREINCREMENT_EXPR:
1996 return " ++";
1998 case POSTDECREMENT_EXPR:
1999 return "-- ";
2001 case POSTINCREMENT_EXPR:
2002 return "++ ";
2004 default:
2005 return "<<< ??? >>>";
2009 /* Prints the name of a CALL_EXPR. */
2011 static void
2012 print_call_name (pretty_printer *buffer, tree node)
2014 tree op0;
2016 gcc_assert (TREE_CODE (node) == CALL_EXPR);
2018 op0 = TREE_OPERAND (node, 0);
2020 if (TREE_CODE (op0) == NON_LVALUE_EXPR)
2021 op0 = TREE_OPERAND (op0, 0);
2023 switch (TREE_CODE (op0))
2025 case VAR_DECL:
2026 case PARM_DECL:
2027 dump_function_name (buffer, op0);
2028 break;
2030 case ADDR_EXPR:
2031 case INDIRECT_REF:
2032 case NOP_EXPR:
2033 dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
2034 break;
2036 case COND_EXPR:
2037 pp_string (buffer, "(");
2038 dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
2039 pp_string (buffer, ") ? ");
2040 dump_generic_node (buffer, TREE_OPERAND (op0, 1), 0, 0, false);
2041 pp_string (buffer, " : ");
2042 dump_generic_node (buffer, TREE_OPERAND (op0, 2), 0, 0, false);
2043 break;
2045 case COMPONENT_REF:
2046 /* The function is a pointer contained in a structure. */
2047 if (TREE_CODE (TREE_OPERAND (op0, 0)) == INDIRECT_REF ||
2048 TREE_CODE (TREE_OPERAND (op0, 0)) == VAR_DECL)
2049 dump_function_name (buffer, TREE_OPERAND (op0, 1));
2050 else
2051 dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
2052 /* else
2053 We can have several levels of structures and a function
2054 pointer inside. This is not implemented yet... */
2055 /* NIY;*/
2056 break;
2058 case ARRAY_REF:
2059 if (TREE_CODE (TREE_OPERAND (op0, 0)) == VAR_DECL)
2060 dump_function_name (buffer, TREE_OPERAND (op0, 0));
2061 else
2062 dump_generic_node (buffer, op0, 0, 0, false);
2063 break;
2065 case SSA_NAME:
2066 case OBJ_TYPE_REF:
2067 dump_generic_node (buffer, op0, 0, 0, false);
2068 break;
2070 default:
2071 NIY;
2075 /* Parses the string STR and replaces new-lines by '\n', tabs by '\t', ... */
2077 static void
2078 pretty_print_string (pretty_printer *buffer, const char *str)
2080 if (str == NULL)
2081 return;
2083 while (*str)
2085 switch (str[0])
2087 case '\b':
2088 pp_string (buffer, "\\b");
2089 break;
2091 case '\f':
2092 pp_string (buffer, "\\f");
2093 break;
2095 case '\n':
2096 pp_string (buffer, "\\n");
2097 break;
2099 case '\r':
2100 pp_string (buffer, "\\r");
2101 break;
2103 case '\t':
2104 pp_string (buffer, "\\t");
2105 break;
2107 case '\v':
2108 pp_string (buffer, "\\v");
2109 break;
2111 case '\\':
2112 pp_string (buffer, "\\\\");
2113 break;
2115 case '\"':
2116 pp_string (buffer, "\\\"");
2117 break;
2119 case '\'':
2120 pp_string (buffer, "\\'");
2121 break;
2123 case '\0':
2124 pp_string (buffer, "\\0");
2125 break;
2127 case '\1':
2128 pp_string (buffer, "\\1");
2129 break;
2131 case '\2':
2132 pp_string (buffer, "\\2");
2133 break;
2135 case '\3':
2136 pp_string (buffer, "\\3");
2137 break;
2139 case '\4':
2140 pp_string (buffer, "\\4");
2141 break;
2143 case '\5':
2144 pp_string (buffer, "\\5");
2145 break;
2147 case '\6':
2148 pp_string (buffer, "\\6");
2149 break;
2151 case '\7':
2152 pp_string (buffer, "\\7");
2153 break;
2155 default:
2156 pp_character (buffer, str[0]);
2157 break;
2159 str++;
2163 static void
2164 maybe_init_pretty_print (FILE *file)
2166 if (!initialized)
2168 pp_construct (&buffer, /* prefix */NULL, /* line-width */0);
2169 pp_needs_newline (&buffer) = true;
2170 initialized = 1;
2173 buffer.buffer->stream = file;
2176 static void
2177 newline_and_indent (pretty_printer *buffer, int spc)
2179 pp_newline (buffer);
2180 INDENT (spc);
2183 static void
2184 dump_vops (pretty_printer *buffer, tree stmt, int spc, int flags)
2186 tree use;
2187 use_operand_p use_p;
2188 def_operand_p def_p;
2189 use_operand_p kill_p;
2190 ssa_op_iter iter;
2192 if (!ssa_operands_active ())
2193 return;
2195 FOR_EACH_SSA_MAYDEF_OPERAND (def_p, use_p, stmt, iter)
2197 pp_string (buffer, "# ");
2198 dump_generic_node (buffer, DEF_FROM_PTR (def_p),
2199 spc + 2, flags, false);
2200 pp_string (buffer, " = V_MAY_DEF <");
2201 dump_generic_node (buffer, USE_FROM_PTR (use_p),
2202 spc + 2, flags, false);
2203 pp_string (buffer, ">;");
2204 newline_and_indent (buffer, spc);
2207 FOR_EACH_SSA_MUSTDEF_OPERAND (def_p, kill_p, stmt, iter)
2209 pp_string (buffer, "# ");
2210 dump_generic_node (buffer, DEF_FROM_PTR (def_p),
2211 spc + 2, flags, false);
2212 pp_string (buffer, " = V_MUST_DEF <");
2213 dump_generic_node (buffer, USE_FROM_PTR (kill_p),
2214 spc + 2, flags, false);
2215 pp_string (buffer, ">;");
2216 newline_and_indent (buffer, spc);
2219 FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_VUSE)
2221 pp_string (buffer, "# VUSE <");
2222 dump_generic_node (buffer, use, spc + 2, flags, false);
2223 pp_string (buffer, ">;");
2224 newline_and_indent (buffer, spc);
2228 /* Dumps basic block BB to FILE with details described by FLAGS and
2229 indented by INDENT spaces. */
2231 void
2232 dump_generic_bb (FILE *file, basic_block bb, int indent, int flags)
2234 maybe_init_pretty_print (file);
2235 dumping_stmts = true;
2236 dump_generic_bb_buff (&buffer, bb, indent, flags);
2237 pp_flush (&buffer);
2240 /* Dumps header of basic block BB to buffer BUFFER indented by INDENT
2241 spaces and details described by flags. */
2243 static void
2244 dump_bb_header (pretty_printer *buffer, basic_block bb, int indent, int flags)
2246 edge e;
2247 tree stmt;
2248 edge_iterator ei;
2250 if (flags & TDF_BLOCKS)
2252 INDENT (indent);
2253 pp_string (buffer, "# BLOCK ");
2254 pp_decimal_int (buffer, bb->index);
2256 if (flags & TDF_LINENO)
2258 block_stmt_iterator bsi;
2260 for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
2261 if (get_lineno (bsi_stmt (bsi)) != -1)
2263 pp_string (buffer, ", starting at line ");
2264 pp_decimal_int (buffer, get_lineno (bsi_stmt (bsi)));
2265 break;
2268 newline_and_indent (buffer, indent);
2270 pp_string (buffer, "# PRED:");
2271 pp_write_text_to_stream (buffer);
2272 FOR_EACH_EDGE (e, ei, bb->preds)
2273 if (flags & TDF_SLIM)
2275 pp_string (buffer, " ");
2276 if (e->src == ENTRY_BLOCK_PTR)
2277 pp_string (buffer, "ENTRY");
2278 else
2279 pp_decimal_int (buffer, e->src->index);
2281 else
2282 dump_edge_info (buffer->buffer->stream, e, 0);
2283 pp_newline (buffer);
2285 else
2287 stmt = first_stmt (bb);
2288 if (!stmt || TREE_CODE (stmt) != LABEL_EXPR)
2290 INDENT (indent - 2);
2291 pp_string (buffer, "<bb ");
2292 pp_decimal_int (buffer, bb->index);
2293 pp_string (buffer, ">:");
2294 pp_newline (buffer);
2297 pp_write_text_to_stream (buffer);
2298 check_bb_profile (bb, buffer->buffer->stream);
2301 /* Dumps end of basic block BB to buffer BUFFER indented by INDENT
2302 spaces. */
2304 static void
2305 dump_bb_end (pretty_printer *buffer, basic_block bb, int indent, int flags)
2307 edge e;
2308 edge_iterator ei;
2310 INDENT (indent);
2311 pp_string (buffer, "# SUCC:");
2312 pp_write_text_to_stream (buffer);
2313 FOR_EACH_EDGE (e, ei, bb->succs)
2314 if (flags & TDF_SLIM)
2316 pp_string (buffer, " ");
2317 if (e->dest == EXIT_BLOCK_PTR)
2318 pp_string (buffer, "EXIT");
2319 else
2320 pp_decimal_int (buffer, e->dest->index);
2322 else
2323 dump_edge_info (buffer->buffer->stream, e, 1);
2324 pp_newline (buffer);
2327 /* Dumps phi nodes of basic block BB to buffer BUFFER with details described by
2328 FLAGS indented by INDENT spaces. */
2330 static void
2331 dump_phi_nodes (pretty_printer *buffer, basic_block bb, int indent, int flags)
2333 tree phi = phi_nodes (bb);
2334 if (!phi)
2335 return;
2337 for (; phi; phi = PHI_CHAIN (phi))
2339 if (is_gimple_reg (PHI_RESULT (phi)) || (flags & TDF_VOPS))
2341 INDENT (indent);
2342 pp_string (buffer, "# ");
2343 dump_generic_node (buffer, phi, indent, flags, false);
2344 pp_newline (buffer);
2349 /* Dump jump to basic block BB that is represented implicitly in the cfg
2350 to BUFFER. */
2352 static void
2353 pp_cfg_jump (pretty_printer *buffer, basic_block bb)
2355 tree stmt;
2357 stmt = first_stmt (bb);
2359 pp_string (buffer, "goto <bb ");
2360 pp_decimal_int (buffer, bb->index);
2361 pp_string (buffer, ">");
2362 if (stmt && TREE_CODE (stmt) == LABEL_EXPR)
2364 pp_string (buffer, " (");
2365 dump_generic_node (buffer, LABEL_EXPR_LABEL (stmt), 0, 0, false);
2366 pp_string (buffer, ")");
2368 pp_semicolon (buffer);
2371 /* Dump edges represented implicitly in basic block BB to BUFFER, indented
2372 by INDENT spaces, with details given by FLAGS. */
2374 static void
2375 dump_implicit_edges (pretty_printer *buffer, basic_block bb, int indent,
2376 int flags)
2378 edge e;
2379 edge_iterator ei;
2381 /* If there is a fallthru edge, we may need to add an artificial goto to the
2382 dump. */
2383 FOR_EACH_EDGE (e, ei, bb->succs)
2384 if (e->flags & EDGE_FALLTHRU)
2385 break;
2386 if (e && e->dest != bb->next_bb)
2388 INDENT (indent);
2390 if ((flags & TDF_LINENO)
2391 #ifdef USE_MAPPED_LOCATION
2392 && e->goto_locus != UNKNOWN_LOCATION
2393 #else
2394 && e->goto_locus
2395 #endif
2398 expanded_location goto_xloc;
2399 #ifdef USE_MAPPED_LOCATION
2400 goto_xloc = expand_location (e->goto_locus);
2401 #else
2402 goto_xloc = *e->goto_locus;
2403 #endif
2404 pp_character (buffer, '[');
2405 if (goto_xloc.file)
2407 pp_string (buffer, goto_xloc.file);
2408 pp_string (buffer, " : ");
2410 pp_decimal_int (buffer, goto_xloc.line);
2411 pp_string (buffer, "] ");
2414 pp_cfg_jump (buffer, e->dest);
2415 pp_newline (buffer);
2419 /* Dumps basic block BB to buffer BUFFER with details described by FLAGS and
2420 indented by INDENT spaces. */
2422 static void
2423 dump_generic_bb_buff (pretty_printer *buffer, basic_block bb,
2424 int indent, int flags)
2426 block_stmt_iterator bsi;
2427 tree stmt;
2428 int label_indent = indent - 2;
2430 if (label_indent < 0)
2431 label_indent = 0;
2433 dump_bb_header (buffer, bb, indent, flags);
2435 dump_phi_nodes (buffer, bb, indent, flags);
2437 for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
2439 int curr_indent;
2441 stmt = bsi_stmt (bsi);
2443 curr_indent = TREE_CODE (stmt) == LABEL_EXPR ? label_indent : indent;
2445 INDENT (curr_indent);
2446 dump_generic_node (buffer, stmt, curr_indent, flags, true);
2447 pp_newline (buffer);
2450 dump_implicit_edges (buffer, bb, indent, flags);
2452 if (flags & TDF_BLOCKS)
2453 dump_bb_end (buffer, bb, indent, flags);