* arm.c (arm_print_operand): Use output_operand_lossage where possible
[official-gcc.git] / gcc / tree-pretty-print.c
bloba4731392f8902710a3a183718b59cdd2723e5fd1
1 /* Pretty formatting of GENERIC trees in C syntax.
2 Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
3 Adapted from c-pretty-print.c by Diego Novillo <dnovillo@redhat.com>
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
10 version.
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING. If not, write to the Free
19 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
20 02111-1307, USA. */
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tm.h"
26 #include "errors.h"
27 #include "tree.h"
28 #include "diagnostic.h"
29 #include "real.h"
30 #include "hashtab.h"
31 #include "tree-flow.h"
32 #include "langhooks.h"
33 #include "tree-iterator.h"
34 #include "tree-chrec.h"
36 /* Local functions, macros and variables. */
37 static int op_prio (tree);
38 static const char *op_symbol (tree);
39 static void pretty_print_string (pretty_printer *, const char*);
40 static void print_call_name (pretty_printer *, tree);
41 static void newline_and_indent (pretty_printer *, int);
42 static void maybe_init_pretty_print (FILE *);
43 static void print_declaration (pretty_printer *, tree, int, int);
44 static void print_struct_decl (pretty_printer *, tree, int, int);
45 static void do_niy (pretty_printer *, tree);
46 static void dump_vops (pretty_printer *, tree, int, int);
47 static void dump_generic_bb_buff (pretty_printer *, basic_block, int, int);
49 #define INDENT(SPACE) do { \
50 int i; for (i = 0; i<SPACE; i++) pp_space (buffer); } while (0)
52 #define NIY do_niy(buffer,node)
54 #define PRINT_FUNCTION_NAME(NODE) pp_printf \
55 (buffer, "%s", TREE_CODE (NODE) == NOP_EXPR ? \
56 lang_hooks.decl_printable_name (TREE_OPERAND (NODE, 0), 1) : \
57 lang_hooks.decl_printable_name (NODE, 1))
59 static pretty_printer buffer;
60 static int initialized = 0;
61 static bool dumping_stmts;
63 /* Try to print something for an unknown tree code. */
65 static void
66 do_niy (pretty_printer *buffer, tree node)
68 int i, len;
70 pp_string (buffer, "<<< Unknown tree: ");
71 pp_string (buffer, tree_code_name[(int) TREE_CODE (node)]);
73 if (EXPR_P (node))
75 len = first_rtl_op (TREE_CODE (node));
76 for (i = 0; i < len; ++i)
78 newline_and_indent (buffer, 2);
79 dump_generic_node (buffer, TREE_OPERAND (node, i), 2, 0, false);
83 pp_string (buffer, " >>>\n");
86 void
87 debug_generic_expr (tree t)
89 print_generic_expr (stderr, t, TDF_VOPS|TDF_UID);
90 fprintf (stderr, "\n");
93 void
94 debug_generic_stmt (tree t)
96 print_generic_stmt (stderr, t, TDF_VOPS|TDF_UID);
97 fprintf (stderr, "\n");
100 /* Prints declaration DECL to the FILE with details specified by FLAGS. */
101 void
102 print_generic_decl (FILE *file, tree decl, int flags)
104 maybe_init_pretty_print (file);
105 dumping_stmts = true;
106 print_declaration (&buffer, decl, 2, flags);
107 pp_write_text_to_stream (&buffer);
110 /* Print tree T, and its successors, on file FILE. FLAGS specifies details
111 to show in the dump. See TDF_* in tree.h. */
113 void
114 print_generic_stmt (FILE *file, tree t, int flags)
116 maybe_init_pretty_print (file);
117 dumping_stmts = true;
118 dump_generic_node (&buffer, t, 0, flags, true);
119 pp_flush (&buffer);
122 /* Print tree T, and its successors, on file FILE. FLAGS specifies details
123 to show in the dump. See TDF_* in tree.h. The output is indented by
124 INDENT spaces. */
126 void
127 print_generic_stmt_indented (FILE *file, tree t, int flags, int indent)
129 int i;
131 maybe_init_pretty_print (file);
132 dumping_stmts = true;
134 for (i = 0; i < indent; i++)
135 pp_space (&buffer);
136 dump_generic_node (&buffer, t, indent, flags, true);
137 pp_flush (&buffer);
140 /* Print a single expression T on file FILE. FLAGS specifies details to show
141 in the dump. See TDF_* in tree.h. */
143 void
144 print_generic_expr (FILE *file, tree t, int flags)
146 maybe_init_pretty_print (file);
147 dumping_stmts = false;
148 dump_generic_node (&buffer, t, 0, flags, false);
151 /* Dump the name of a _DECL node and its DECL_UID if TDF_UID is set
152 in FLAGS. */
154 static void
155 dump_decl_name (pretty_printer *buffer, tree node, int flags)
157 if (DECL_NAME (node))
158 pp_tree_identifier (buffer, DECL_NAME (node));
160 if ((flags & TDF_UID)
161 || DECL_NAME (node) == NULL_TREE)
163 if (TREE_CODE (node) == LABEL_DECL
164 && LABEL_DECL_UID (node) != -1)
165 pp_printf (buffer, "L." HOST_WIDE_INT_PRINT_DEC,
166 LABEL_DECL_UID (node));
167 else
169 char c = TREE_CODE (node) == CONST_DECL ? 'C' : 'D';
170 pp_printf (buffer, "%c.%u", c, DECL_UID (node));
175 /* Like the above, but used for pretty printing function calls. */
177 static void
178 dump_function_name (pretty_printer *buffer, tree node)
180 if (DECL_NAME (node))
181 PRINT_FUNCTION_NAME (node);
182 else
183 dump_decl_name (buffer, node, 0);
186 /* Dump a function declaration. NODE is the FUNCTION_TYPE. BUFFER, SPC and
187 FLAGS are as in dump_generic_node. */
189 static void
190 dump_function_declaration (pretty_printer *buffer, tree node,
191 int spc, int flags)
193 bool wrote_arg = false;
194 tree arg;
196 pp_space (buffer);
197 pp_character (buffer, '(');
199 /* Print the argument types. The last element in the list is a VOID_TYPE.
200 The following avoids printing the last element. */
201 arg = TYPE_ARG_TYPES (node);
202 while (arg && TREE_CHAIN (arg) && arg != error_mark_node)
204 wrote_arg = true;
205 dump_generic_node (buffer, TREE_VALUE (arg), spc, flags, false);
206 arg = TREE_CHAIN (arg);
207 if (TREE_CHAIN (arg) && TREE_CODE (TREE_CHAIN (arg)) == TREE_LIST)
209 pp_character (buffer, ',');
210 pp_space (buffer);
214 if (!wrote_arg)
215 pp_string (buffer, "void");
217 pp_character (buffer, ')');
220 /* Dump the node NODE on the pretty_printer BUFFER, SPC spaces of indent.
221 FLAGS specifies details to show in the dump (see TDF_* in tree.h). If
222 IS_STMT is true, the object printed is considered to be a statement
223 and it is terminated by ';' if appropriate. */
226 dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
227 bool is_stmt)
229 tree type;
230 tree op0, op1;
231 const char *str;
232 bool is_expr;
234 if (node == NULL_TREE)
235 return spc;
237 is_expr = EXPR_P (node);
239 if (TREE_CODE (node) != ERROR_MARK
240 && is_gimple_stmt (node)
241 && (flags & TDF_VOPS)
242 && stmt_ann (node))
243 dump_vops (buffer, node, spc, flags);
245 if (dumping_stmts
246 && (flags & TDF_LINENO)
247 && EXPR_HAS_LOCATION (node))
249 expanded_location xloc = expand_location (EXPR_LOCATION (node));
250 pp_character (buffer, '[');
251 if (xloc.file)
253 pp_string (buffer, xloc.file);
254 pp_string (buffer, " : ");
256 pp_decimal_int (buffer, xloc.line);
257 pp_string (buffer, "] ");
260 switch (TREE_CODE (node))
262 case ERROR_MARK:
263 pp_string (buffer, "<<< error >>>");
264 break;
266 case IDENTIFIER_NODE:
267 pp_tree_identifier (buffer, node);
268 break;
270 case TREE_LIST:
271 while (node && node != error_mark_node)
273 if (TREE_PURPOSE (node))
275 dump_generic_node (buffer, TREE_PURPOSE (node), spc, flags, false);
276 pp_space (buffer);
278 dump_generic_node (buffer, TREE_VALUE (node), spc, flags, false);
279 node = TREE_CHAIN (node);
280 if (node && TREE_CODE (node) == TREE_LIST)
282 pp_character (buffer, ',');
283 pp_space (buffer);
286 break;
288 case TREE_BINFO:
289 dump_generic_node (buffer, BINFO_TYPE (node), spc, flags, false);
291 case TREE_VEC:
293 size_t i;
294 if (TREE_VEC_LENGTH (node) > 0)
296 size_t len = TREE_VEC_LENGTH (node);
297 for (i = 0; i < len - 1; i++)
299 dump_generic_node (buffer, TREE_VEC_ELT (node, i), spc, flags,
300 false);
301 pp_character (buffer, ',');
302 pp_space (buffer);
304 dump_generic_node (buffer, TREE_VEC_ELT (node, len - 1), spc,
305 flags, false);
308 break;
310 case BLOCK:
311 NIY;
312 break;
314 case VOID_TYPE:
315 case INTEGER_TYPE:
316 case REAL_TYPE:
317 case COMPLEX_TYPE:
318 case VECTOR_TYPE:
319 case ENUMERAL_TYPE:
320 case BOOLEAN_TYPE:
321 case CHAR_TYPE:
323 unsigned int quals = TYPE_QUALS (node);
324 enum tree_code_class class;
326 if (quals & TYPE_QUAL_CONST)
327 pp_string (buffer, "const ");
328 else if (quals & TYPE_QUAL_VOLATILE)
329 pp_string (buffer, "volatile ");
330 else if (quals & TYPE_QUAL_RESTRICT)
331 pp_string (buffer, "restrict ");
333 class = TREE_CODE_CLASS (TREE_CODE (node));
335 if (class == tcc_declaration)
337 if (DECL_NAME (node))
338 dump_decl_name (buffer, node, flags);
339 else
340 pp_string (buffer, "<unnamed type decl>");
342 else if (class == tcc_type)
344 if (TYPE_NAME (node))
346 if (TREE_CODE (TYPE_NAME (node)) == IDENTIFIER_NODE)
347 pp_tree_identifier (buffer, TYPE_NAME (node));
348 else if (TREE_CODE (TYPE_NAME (node)) == TYPE_DECL
349 && DECL_NAME (TYPE_NAME (node)))
350 dump_decl_name (buffer, TYPE_NAME (node), flags);
351 else
352 pp_string (buffer, "<unnamed type>");
354 else if (TREE_CODE (node) == VECTOR_TYPE)
356 pp_string (buffer, "vector ");
357 dump_generic_node (buffer, TREE_TYPE (node),
358 spc, flags, false);
360 else
361 pp_string (buffer, "<unnamed type>");
363 break;
366 case POINTER_TYPE:
367 case REFERENCE_TYPE:
368 str = (TREE_CODE (node) == POINTER_TYPE ? "*" : "&");
370 if (TREE_CODE (TREE_TYPE (node)) == FUNCTION_TYPE)
372 tree fnode = TREE_TYPE (node);
374 dump_generic_node (buffer, TREE_TYPE (fnode), spc, flags, false);
375 pp_space (buffer);
376 pp_character (buffer, '(');
377 pp_string (buffer, str);
378 if (TYPE_NAME (node) && DECL_NAME (TYPE_NAME (node)))
379 dump_decl_name (buffer, TYPE_NAME (node), flags);
380 else
381 pp_printf (buffer, "<T%x>", TYPE_UID (node));
383 pp_character (buffer, ')');
384 dump_function_declaration (buffer, fnode, spc, flags);
386 else
388 unsigned int quals = TYPE_QUALS (node);
390 dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
391 pp_space (buffer);
392 pp_string (buffer, str);
394 if (quals & TYPE_QUAL_CONST)
395 pp_string (buffer, " const");
396 else if (quals & TYPE_QUAL_VOLATILE)
397 pp_string (buffer, "volatile");
398 else if (quals & TYPE_QUAL_RESTRICT)
399 pp_string (buffer, " restrict");
401 break;
403 case OFFSET_TYPE:
404 NIY;
405 break;
407 case METHOD_TYPE:
408 dump_decl_name (buffer, TYPE_NAME (TYPE_METHOD_BASETYPE (node)), flags);
409 pp_string (buffer, "::");
410 break;
412 case FILE_TYPE:
413 NIY;
414 break;
416 case ARRAY_TYPE:
418 tree tmp;
420 /* Print the innermost component type. */
421 for (tmp = TREE_TYPE (node); TREE_CODE (tmp) == ARRAY_TYPE;
422 tmp = TREE_TYPE (tmp))
424 dump_generic_node (buffer, tmp, spc, flags, false);
426 /* Print the dimensions. */
427 for (tmp = node; TREE_CODE (tmp) == ARRAY_TYPE;
428 tmp = TREE_TYPE (tmp))
430 tree domain = TYPE_DOMAIN (tmp);
432 pp_character (buffer, '[');
433 if (domain)
435 if (TYPE_MIN_VALUE (domain)
436 && !integer_zerop (TYPE_MIN_VALUE (domain)))
438 dump_generic_node (buffer, TYPE_MIN_VALUE (domain),
439 spc, flags, false);
440 pp_string (buffer, " .. ");
443 if (TYPE_MAX_VALUE (domain))
444 dump_generic_node (buffer, TYPE_MAX_VALUE (domain),
445 spc, flags, false);
447 else
448 pp_string (buffer, "<unknown>");
450 pp_character (buffer, ']');
452 break;
455 case SET_TYPE:
456 NIY;
457 break;
459 case RECORD_TYPE:
460 case UNION_TYPE:
461 case QUAL_UNION_TYPE:
462 /* Print the name of the structure. */
463 if (TREE_CODE (node) == RECORD_TYPE)
464 pp_string (buffer, "struct ");
465 else if (TREE_CODE (node) == UNION_TYPE)
466 pp_string (buffer, "union ");
468 if (TYPE_NAME (node))
469 dump_generic_node (buffer, TYPE_NAME (node), spc, flags, false);
470 else
471 print_struct_decl (buffer, node, spc, flags);
472 break;
474 case LANG_TYPE:
475 NIY;
476 break;
478 case INTEGER_CST:
479 if (TREE_CODE (TREE_TYPE (node)) == POINTER_TYPE)
481 /* In the case of a pointer, one may want to divide by the
482 size of the pointed-to type. Unfortunately, this not
483 straightforward. The C front-end maps expressions
485 (int *) 5
486 int *p; (p + 5)
488 in such a way that the two INTEGER_CST nodes for "5" have
489 different values but identical types. In the latter
490 case, the 5 is multiplied by sizeof (int) in c-common.c
491 (pointer_int_sum) to convert it to a byte address, and
492 yet the type of the node is left unchanged. Argh. What
493 is consistent though is that the number value corresponds
494 to bytes (UNITS) offset.
496 NB: Neither of the following divisors can be trivially
497 used to recover the original literal:
499 TREE_INT_CST_LOW (TYPE_SIZE_UNIT (TREE_TYPE (node)))
500 TYPE_PRECISION (TREE_TYPE (TREE_TYPE (node))) */
501 pp_wide_integer (buffer, TREE_INT_CST_LOW (node));
502 pp_string (buffer, "B"); /* pseudo-unit */
504 else if (! host_integerp (node, 0))
506 tree val = node;
508 if (tree_int_cst_sgn (val) < 0)
510 pp_character (buffer, '-');
511 val = build_int_cst_wide (NULL_TREE,
512 -TREE_INT_CST_LOW (val),
513 ~TREE_INT_CST_HIGH (val)
514 + !TREE_INT_CST_LOW (val));
516 /* Would "%x%0*x" or "%x%*0x" get zero-padding on all
517 systems? */
519 static char format[10]; /* "%x%09999x\0" */
520 if (!format[0])
521 sprintf (format, "%%x%%0%dx", HOST_BITS_PER_INT / 4);
522 sprintf (pp_buffer (buffer)->digit_buffer, format,
523 TREE_INT_CST_HIGH (val),
524 TREE_INT_CST_LOW (val));
525 pp_string (buffer, pp_buffer (buffer)->digit_buffer);
528 else
529 pp_wide_integer (buffer, TREE_INT_CST_LOW (node));
530 break;
532 case REAL_CST:
533 /* Code copied from print_node. */
535 REAL_VALUE_TYPE d;
536 if (TREE_OVERFLOW (node))
537 pp_string (buffer, " overflow");
539 #if !defined(REAL_IS_NOT_DOUBLE) || defined(REAL_ARITHMETIC)
540 d = TREE_REAL_CST (node);
541 if (REAL_VALUE_ISINF (d))
542 pp_string (buffer, " Inf");
543 else if (REAL_VALUE_ISNAN (d))
544 pp_string (buffer, " Nan");
545 else
547 char string[100];
548 real_to_decimal (string, &d, sizeof (string), 0, 1);
549 pp_string (buffer, string);
551 #else
553 HOST_WIDE_INT i;
554 unsigned char *p = (unsigned char *) &TREE_REAL_CST (node);
555 pp_string (buffer, "0x");
556 for (i = 0; i < sizeof TREE_REAL_CST (node); i++)
557 output_formatted_integer (buffer, "%02x", *p++);
559 #endif
560 break;
563 case COMPLEX_CST:
564 pp_string (buffer, "__complex__ (");
565 dump_generic_node (buffer, TREE_REALPART (node), spc, flags, false);
566 pp_string (buffer, ", ");
567 dump_generic_node (buffer, TREE_IMAGPART (node), spc, flags, false);
568 pp_string (buffer, ")");
569 break;
571 case STRING_CST:
572 pp_string (buffer, "\"");
573 pretty_print_string (buffer, TREE_STRING_POINTER (node));
574 pp_string (buffer, "\"");
575 break;
577 case VECTOR_CST:
579 tree elt;
580 pp_string (buffer, "{ ");
581 for (elt = TREE_VECTOR_CST_ELTS (node); elt; elt = TREE_CHAIN (elt))
583 dump_generic_node (buffer, TREE_VALUE (elt), spc, flags, false);
584 if (TREE_CHAIN (elt))
585 pp_string (buffer, ", ");
587 pp_string (buffer, " }");
589 break;
591 case FUNCTION_TYPE:
592 break;
594 case FUNCTION_DECL:
595 case CONST_DECL:
596 dump_decl_name (buffer, node, flags);
597 break;
599 case LABEL_DECL:
600 if (DECL_NAME (node))
601 dump_decl_name (buffer, node, flags);
602 else if (LABEL_DECL_UID (node) != -1)
603 pp_printf (buffer, "<L" HOST_WIDE_INT_PRINT_DEC ">",
604 LABEL_DECL_UID (node));
605 else
606 pp_printf (buffer, "<D%u>", DECL_UID (node));
607 break;
609 case TYPE_DECL:
610 if (DECL_IS_BUILTIN (node))
612 /* Don't print the declaration of built-in types. */
613 break;
615 if (DECL_NAME (node))
616 dump_decl_name (buffer, node, flags);
617 else
619 if ((TREE_CODE (TREE_TYPE (node)) == RECORD_TYPE
620 || TREE_CODE (TREE_TYPE (node)) == UNION_TYPE)
621 && TYPE_METHODS (TREE_TYPE (node)))
623 /* The type is a c++ class: all structures have at least
624 4 methods. */
625 pp_string (buffer, "class ");
626 dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
628 else
630 pp_string (buffer,
631 (TREE_CODE (TREE_TYPE (node)) == UNION_TYPE
632 ? "union" : "struct "));
633 dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
636 break;
638 case VAR_DECL:
639 case PARM_DECL:
640 case FIELD_DECL:
641 case NAMESPACE_DECL:
642 dump_decl_name (buffer, node, flags);
643 break;
645 case RESULT_DECL:
646 pp_string (buffer, "<retval>");
647 break;
649 case COMPONENT_REF:
650 op0 = TREE_OPERAND (node, 0);
651 str = ".";
652 if (TREE_CODE (op0) == INDIRECT_REF)
654 op0 = TREE_OPERAND (op0, 0);
655 str = "->";
657 if (op_prio (op0) < op_prio (node))
658 pp_character (buffer, '(');
659 dump_generic_node (buffer, op0, spc, flags, false);
660 if (op_prio (op0) < op_prio (node))
661 pp_character (buffer, ')');
662 pp_string (buffer, str);
663 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
665 if (TREE_CODE (op0) != VALUE_HANDLE)
667 op0 = component_ref_field_offset (node);
668 if (op0 && TREE_CODE (op0) != INTEGER_CST)
670 pp_string (buffer, "{off: ");
671 dump_generic_node (buffer, op0, spc, flags, false);
672 pp_character (buffer, '}');
675 break;
677 case BIT_FIELD_REF:
678 pp_string (buffer, "BIT_FIELD_REF <");
679 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
680 pp_string (buffer, ", ");
681 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
682 pp_string (buffer, ", ");
683 dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
684 pp_string (buffer, ">");
685 break;
687 case ARRAY_REF:
688 case ARRAY_RANGE_REF:
689 op0 = TREE_OPERAND (node, 0);
690 if (op_prio (op0) < op_prio (node))
691 pp_character (buffer, '(');
692 dump_generic_node (buffer, op0, spc, flags, false);
693 if (op_prio (op0) < op_prio (node))
694 pp_character (buffer, ')');
695 pp_character (buffer, '[');
696 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
697 if (TREE_CODE (node) == ARRAY_RANGE_REF)
698 pp_string (buffer, " ...");
699 pp_character (buffer, ']');
701 op0 = array_ref_low_bound (node);
702 op1 = array_ref_element_size (node);
704 if (!integer_zerop (op0)
705 || (TYPE_SIZE_UNIT (TREE_TYPE (node))
706 && !operand_equal_p (op1, TYPE_SIZE_UNIT (TREE_TYPE (node)), 0)))
708 pp_string (buffer, "{lb: ");
709 dump_generic_node (buffer, op0, spc, flags, false);
710 pp_string (buffer, " sz: ");
711 dump_generic_node (buffer, op1, spc, flags, false);
712 pp_character (buffer, '}');
714 break;
716 case CONSTRUCTOR:
718 tree lnode;
719 bool is_struct_init = FALSE;
720 pp_character (buffer, '{');
721 lnode = CONSTRUCTOR_ELTS (node);
722 if (TREE_CODE (TREE_TYPE (node)) == RECORD_TYPE
723 || TREE_CODE (TREE_TYPE (node)) == UNION_TYPE)
724 is_struct_init = TRUE;
725 while (lnode && lnode != error_mark_node)
727 tree val;
728 if (TREE_PURPOSE (lnode) && is_struct_init)
730 pp_character (buffer, '.');
731 dump_generic_node (buffer, TREE_PURPOSE (lnode), spc, flags, false);
732 pp_string (buffer, "=");
734 val = TREE_VALUE (lnode);
735 if (val && TREE_CODE (val) == ADDR_EXPR)
736 if (TREE_CODE (TREE_OPERAND (val, 0)) == FUNCTION_DECL)
737 val = TREE_OPERAND (val, 0);
738 if (val && TREE_CODE (val) == FUNCTION_DECL)
740 dump_decl_name (buffer, val, flags);
742 else
744 dump_generic_node (buffer, TREE_VALUE (lnode), spc, flags, false);
746 lnode = TREE_CHAIN (lnode);
747 if (lnode && TREE_CODE (lnode) == TREE_LIST)
749 pp_character (buffer, ',');
750 pp_space (buffer);
753 pp_character (buffer, '}');
755 break;
757 case COMPOUND_EXPR:
759 tree *tp;
760 if (flags & TDF_SLIM)
762 pp_string (buffer, "<COMPOUND_EXPR>");
763 break;
766 dump_generic_node (buffer, TREE_OPERAND (node, 0),
767 spc, flags, dumping_stmts);
768 if (dumping_stmts)
769 newline_and_indent (buffer, spc);
770 else
772 pp_character (buffer, ',');
773 pp_space (buffer);
776 for (tp = &TREE_OPERAND (node, 1);
777 TREE_CODE (*tp) == COMPOUND_EXPR;
778 tp = &TREE_OPERAND (*tp, 1))
780 dump_generic_node (buffer, TREE_OPERAND (*tp, 0),
781 spc, flags, dumping_stmts);
782 if (dumping_stmts)
783 newline_and_indent (buffer, spc);
784 else
786 pp_character (buffer, ',');
787 pp_space (buffer);
791 dump_generic_node (buffer, *tp, spc, flags, dumping_stmts);
793 break;
795 case STATEMENT_LIST:
797 tree_stmt_iterator si;
798 bool first = true;
800 if ((flags & TDF_SLIM) || !dumping_stmts)
802 pp_string (buffer, "<STATEMENT_LIST>");
803 break;
806 for (si = tsi_start (node); !tsi_end_p (si); tsi_next (&si))
808 if (!first)
809 newline_and_indent (buffer, spc);
810 else
811 first = false;
812 dump_generic_node (buffer, tsi_stmt (si), spc, flags, true);
815 break;
817 case MODIFY_EXPR:
818 case INIT_EXPR:
819 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
820 pp_space (buffer);
821 pp_character (buffer, '=');
822 pp_space (buffer);
823 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
824 break;
826 case TARGET_EXPR:
827 pp_string (buffer, "TARGET_EXPR <");
828 dump_generic_node (buffer, TARGET_EXPR_SLOT (node), spc, flags, false);
829 pp_character (buffer, ',');
830 pp_space (buffer);
831 dump_generic_node (buffer, TARGET_EXPR_INITIAL (node), spc, flags, false);
832 pp_character (buffer, '>');
833 break;
835 case DECL_EXPR:
836 print_declaration (buffer, DECL_EXPR_DECL (node), spc, flags);
837 is_stmt = false;
838 break;
840 case COND_EXPR:
841 if (TREE_TYPE (node) == NULL || TREE_TYPE (node) == void_type_node)
843 pp_string (buffer, "if (");
844 dump_generic_node (buffer, COND_EXPR_COND (node), spc, flags, false);
845 pp_character (buffer, ')');
846 /* The lowered cond_exprs should always be printed in full. */
847 if (COND_EXPR_THEN (node)
848 && (IS_EMPTY_STMT (COND_EXPR_THEN (node))
849 || TREE_CODE (COND_EXPR_THEN (node)) == GOTO_EXPR)
850 && COND_EXPR_ELSE (node)
851 && (IS_EMPTY_STMT (COND_EXPR_ELSE (node))
852 || TREE_CODE (COND_EXPR_ELSE (node)) == GOTO_EXPR))
854 pp_space (buffer);
855 dump_generic_node (buffer, COND_EXPR_THEN (node), 0, flags, true);
856 pp_string (buffer, " else ");
857 dump_generic_node (buffer, COND_EXPR_ELSE (node), 0, flags, true);
859 else if (!(flags & TDF_SLIM))
861 /* Output COND_EXPR_THEN. */
862 if (COND_EXPR_THEN (node))
864 newline_and_indent (buffer, spc+2);
865 pp_character (buffer, '{');
866 newline_and_indent (buffer, spc+4);
867 dump_generic_node (buffer, COND_EXPR_THEN (node), spc+4,
868 flags, true);
869 newline_and_indent (buffer, spc+2);
870 pp_character (buffer, '}');
873 /* Output COND_EXPR_ELSE. */
874 if (COND_EXPR_ELSE (node))
876 newline_and_indent (buffer, spc);
877 pp_string (buffer, "else");
878 newline_and_indent (buffer, spc+2);
879 pp_character (buffer, '{');
880 newline_and_indent (buffer, spc+4);
881 dump_generic_node (buffer, COND_EXPR_ELSE (node), spc+4,
882 flags, true);
883 newline_and_indent (buffer, spc+2);
884 pp_character (buffer, '}');
887 is_expr = false;
889 else
891 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
892 pp_space (buffer);
893 pp_character (buffer, '?');
894 pp_space (buffer);
895 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
896 pp_space (buffer);
897 pp_character (buffer, ':');
898 pp_space (buffer);
899 dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
901 break;
903 case BIND_EXPR:
904 pp_character (buffer, '{');
905 if (!(flags & TDF_SLIM))
907 if (BIND_EXPR_VARS (node))
909 pp_newline (buffer);
911 for (op0 = BIND_EXPR_VARS (node); op0; op0 = TREE_CHAIN (op0))
913 print_declaration (buffer, op0, spc+2, flags);
914 pp_newline (buffer);
918 newline_and_indent (buffer, spc+2);
919 dump_generic_node (buffer, BIND_EXPR_BODY (node), spc+2, flags, true);
920 newline_and_indent (buffer, spc);
921 pp_character (buffer, '}');
923 is_expr = false;
924 break;
926 case CALL_EXPR:
927 print_call_name (buffer, node);
929 /* Print parameters. */
930 pp_space (buffer);
931 pp_character (buffer, '(');
932 op1 = TREE_OPERAND (node, 1);
933 if (op1)
934 dump_generic_node (buffer, op1, spc, flags, false);
935 pp_character (buffer, ')');
937 op1 = TREE_OPERAND (node, 2);
938 if (op1)
940 pp_string (buffer, " [static-chain: ");
941 dump_generic_node (buffer, op1, spc, flags, false);
942 pp_character (buffer, ']');
945 if (CALL_EXPR_HAS_RETURN_SLOT_ADDR (node))
946 pp_string (buffer, " [return slot addr]");
947 if (CALL_EXPR_TAILCALL (node))
948 pp_string (buffer, " [tail call]");
949 break;
951 case WITH_CLEANUP_EXPR:
952 NIY;
953 break;
955 case CLEANUP_POINT_EXPR:
956 pp_string (buffer, "<<cleanup_point ");
957 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
958 pp_string (buffer, ">>");
959 break;
961 case PLACEHOLDER_EXPR:
962 pp_string (buffer, "<PLACEHOLDER_EXPR ");
963 dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
964 pp_character (buffer, '>');
965 break;
967 /* Binary arithmetic and logic expressions. */
968 case MULT_EXPR:
969 case PLUS_EXPR:
970 case MINUS_EXPR:
971 case TRUNC_DIV_EXPR:
972 case CEIL_DIV_EXPR:
973 case FLOOR_DIV_EXPR:
974 case ROUND_DIV_EXPR:
975 case TRUNC_MOD_EXPR:
976 case CEIL_MOD_EXPR:
977 case FLOOR_MOD_EXPR:
978 case ROUND_MOD_EXPR:
979 case RDIV_EXPR:
980 case EXACT_DIV_EXPR:
981 case LSHIFT_EXPR:
982 case RSHIFT_EXPR:
983 case LROTATE_EXPR:
984 case RROTATE_EXPR:
985 case BIT_IOR_EXPR:
986 case BIT_XOR_EXPR:
987 case BIT_AND_EXPR:
988 case TRUTH_ANDIF_EXPR:
989 case TRUTH_ORIF_EXPR:
990 case TRUTH_AND_EXPR:
991 case TRUTH_OR_EXPR:
992 case TRUTH_XOR_EXPR:
993 case LT_EXPR:
994 case LE_EXPR:
995 case GT_EXPR:
996 case GE_EXPR:
997 case EQ_EXPR:
998 case NE_EXPR:
999 case UNLT_EXPR:
1000 case UNLE_EXPR:
1001 case UNGT_EXPR:
1002 case UNGE_EXPR:
1003 case UNEQ_EXPR:
1004 case LTGT_EXPR:
1005 case ORDERED_EXPR:
1006 case UNORDERED_EXPR:
1008 const char *op = op_symbol (node);
1009 op0 = TREE_OPERAND (node, 0);
1010 op1 = TREE_OPERAND (node, 1);
1012 /* When the operands are expressions with less priority,
1013 keep semantics of the tree representation. */
1014 if (op_prio (op0) < op_prio (node))
1016 pp_character (buffer, '(');
1017 dump_generic_node (buffer, op0, spc, flags, false);
1018 pp_character (buffer, ')');
1020 else
1021 dump_generic_node (buffer, op0, spc, flags, false);
1023 pp_space (buffer);
1024 pp_string (buffer, op);
1025 pp_space (buffer);
1027 /* When the operands are expressions with less priority,
1028 keep semantics of the tree representation. */
1029 if (op_prio (op1) < op_prio (node))
1031 pp_character (buffer, '(');
1032 dump_generic_node (buffer, op1, spc, flags, false);
1033 pp_character (buffer, ')');
1035 else
1036 dump_generic_node (buffer, op1, spc, flags, false);
1038 break;
1040 /* Unary arithmetic and logic expressions. */
1041 case NEGATE_EXPR:
1042 case BIT_NOT_EXPR:
1043 case TRUTH_NOT_EXPR:
1044 case ADDR_EXPR:
1045 case PREDECREMENT_EXPR:
1046 case PREINCREMENT_EXPR:
1047 case ALIGN_INDIRECT_REF:
1048 case MISALIGNED_INDIRECT_REF:
1049 case INDIRECT_REF:
1050 if (TREE_CODE (node) == ADDR_EXPR
1051 && (TREE_CODE (TREE_OPERAND (node, 0)) == STRING_CST
1052 || TREE_CODE (TREE_OPERAND (node, 0)) == FUNCTION_DECL))
1053 ; /* Do not output '&' for strings and function pointers. */
1054 else
1055 pp_string (buffer, op_symbol (node));
1057 if (op_prio (TREE_OPERAND (node, 0)) < op_prio (node))
1059 pp_character (buffer, '(');
1060 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1061 pp_character (buffer, ')');
1063 else
1064 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1066 if (TREE_CODE (node) == MISALIGNED_INDIRECT_REF)
1068 pp_string (buffer, "{misalignment: ");
1069 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1070 pp_character (buffer, '}');
1072 break;
1074 case POSTDECREMENT_EXPR:
1075 case POSTINCREMENT_EXPR:
1076 if (op_prio (TREE_OPERAND (node, 0)) < op_prio (node))
1078 pp_character (buffer, '(');
1079 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1080 pp_character (buffer, ')');
1082 else
1083 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1084 pp_string (buffer, op_symbol (node));
1085 break;
1087 case MIN_EXPR:
1088 pp_string (buffer, "MIN_EXPR <");
1089 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1090 pp_string (buffer, ", ");
1091 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1092 pp_character (buffer, '>');
1093 break;
1095 case MAX_EXPR:
1096 pp_string (buffer, "MAX_EXPR <");
1097 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1098 pp_string (buffer, ", ");
1099 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1100 pp_character (buffer, '>');
1101 break;
1103 case ABS_EXPR:
1104 pp_string (buffer, "ABS_EXPR <");
1105 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1106 pp_character (buffer, '>');
1107 break;
1109 case RANGE_EXPR:
1110 NIY;
1111 break;
1113 case FIX_TRUNC_EXPR:
1114 case FIX_CEIL_EXPR:
1115 case FIX_FLOOR_EXPR:
1116 case FIX_ROUND_EXPR:
1117 case FLOAT_EXPR:
1118 case CONVERT_EXPR:
1119 case NOP_EXPR:
1120 type = TREE_TYPE (node);
1121 op0 = TREE_OPERAND (node, 0);
1122 if (type != TREE_TYPE (op0))
1124 pp_character (buffer, '(');
1125 dump_generic_node (buffer, type, spc, flags, false);
1126 pp_string (buffer, ") ");
1128 if (op_prio (op0) < op_prio (node))
1129 pp_character (buffer, '(');
1130 dump_generic_node (buffer, op0, spc, flags, false);
1131 if (op_prio (op0) < op_prio (node))
1132 pp_character (buffer, ')');
1133 break;
1135 case VIEW_CONVERT_EXPR:
1136 pp_string (buffer, "VIEW_CONVERT_EXPR<");
1137 dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
1138 pp_string (buffer, ">(");
1139 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1140 pp_character (buffer, ')');
1141 break;
1143 case NON_LVALUE_EXPR:
1144 pp_string (buffer, "NON_LVALUE_EXPR <");
1145 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1146 pp_character (buffer, '>');
1147 break;
1149 case SAVE_EXPR:
1150 pp_string (buffer, "SAVE_EXPR <");
1151 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1152 pp_character (buffer, '>');
1153 break;
1155 case COMPLEX_EXPR:
1156 pp_string (buffer, "COMPLEX_EXPR <");
1157 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1158 pp_string (buffer, ", ");
1159 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1160 pp_string (buffer, ">");
1161 break;
1163 case CONJ_EXPR:
1164 pp_string (buffer, "CONJ_EXPR <");
1165 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1166 pp_string (buffer, ">");
1167 break;
1169 case REALPART_EXPR:
1170 pp_string (buffer, "REALPART_EXPR <");
1171 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1172 pp_string (buffer, ">");
1173 break;
1175 case IMAGPART_EXPR:
1176 pp_string (buffer, "IMAGPART_EXPR <");
1177 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1178 pp_string (buffer, ">");
1179 break;
1181 case VA_ARG_EXPR:
1182 pp_string (buffer, "VA_ARG_EXPR <");
1183 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1184 pp_string (buffer, ">");
1185 break;
1187 case TRY_FINALLY_EXPR:
1188 case TRY_CATCH_EXPR:
1189 pp_string (buffer, "try");
1190 newline_and_indent (buffer, spc+2);
1191 pp_string (buffer, "{");
1192 newline_and_indent (buffer, spc+4);
1193 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc+4, flags, true);
1194 newline_and_indent (buffer, spc+2);
1195 pp_string (buffer, "}");
1196 newline_and_indent (buffer, spc);
1197 pp_string (buffer,
1198 (TREE_CODE (node) == TRY_CATCH_EXPR) ? "catch" : "finally");
1199 newline_and_indent (buffer, spc+2);
1200 pp_string (buffer, "{");
1201 newline_and_indent (buffer, spc+4);
1202 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc+4, flags, true);
1203 newline_and_indent (buffer, spc+2);
1204 pp_string (buffer, "}");
1205 is_expr = false;
1206 break;
1208 case CATCH_EXPR:
1209 pp_string (buffer, "catch (");
1210 dump_generic_node (buffer, CATCH_TYPES (node), spc+2, flags, false);
1211 pp_string (buffer, ")");
1212 newline_and_indent (buffer, spc+2);
1213 pp_string (buffer, "{");
1214 newline_and_indent (buffer, spc+4);
1215 dump_generic_node (buffer, CATCH_BODY (node), spc+4, flags, true);
1216 newline_and_indent (buffer, spc+2);
1217 pp_string (buffer, "}");
1218 is_expr = false;
1219 break;
1221 case EH_FILTER_EXPR:
1222 pp_string (buffer, "<<<eh_filter (");
1223 dump_generic_node (buffer, EH_FILTER_TYPES (node), spc+2, flags, false);
1224 pp_string (buffer, ")>>>");
1225 newline_and_indent (buffer, spc+2);
1226 pp_string (buffer, "{");
1227 newline_and_indent (buffer, spc+4);
1228 dump_generic_node (buffer, EH_FILTER_FAILURE (node), spc+4, flags, true);
1229 newline_and_indent (buffer, spc+2);
1230 pp_string (buffer, "}");
1231 is_expr = false;
1232 break;
1234 case LABEL_EXPR:
1235 op0 = TREE_OPERAND (node, 0);
1236 /* If this is for break or continue, don't bother printing it. */
1237 if (DECL_NAME (op0))
1239 const char *name = IDENTIFIER_POINTER (DECL_NAME (op0));
1240 if (strcmp (name, "break") == 0
1241 || strcmp (name, "continue") == 0)
1242 break;
1244 dump_generic_node (buffer, op0, spc, flags, false);
1245 pp_character (buffer, ':');
1246 if (DECL_NONLOCAL (op0))
1247 pp_string (buffer, " [non-local]");
1248 break;
1250 case LABELED_BLOCK_EXPR:
1251 op0 = LABELED_BLOCK_LABEL (node);
1252 /* If this is for break or continue, don't bother printing it. */
1253 if (DECL_NAME (op0))
1255 const char *name = IDENTIFIER_POINTER (DECL_NAME (op0));
1256 if (strcmp (name, "break") == 0
1257 || strcmp (name, "continue") == 0)
1259 dump_generic_node (buffer, LABELED_BLOCK_BODY (node), spc, flags, false);
1260 break;
1263 dump_generic_node (buffer, LABELED_BLOCK_LABEL (node), spc, flags, false);
1264 pp_string (buffer, ": {");
1265 if (!(flags & TDF_SLIM))
1266 newline_and_indent (buffer, spc+2);
1267 dump_generic_node (buffer, LABELED_BLOCK_BODY (node), spc+2, flags, true);
1268 if (!flags)
1269 newline_and_indent (buffer, spc);
1270 pp_character (buffer, '}');
1271 is_expr = false;
1272 break;
1274 case EXIT_BLOCK_EXPR:
1275 op0 = LABELED_BLOCK_LABEL (EXIT_BLOCK_LABELED_BLOCK (node));
1276 /* If this is for a break or continue, print it accordingly. */
1277 if (DECL_NAME (op0))
1279 const char *name = IDENTIFIER_POINTER (DECL_NAME (op0));
1280 if (strcmp (name, "break") == 0
1281 || strcmp (name, "continue") == 0)
1283 pp_string (buffer, name);
1284 break;
1287 pp_string (buffer, "<<<exit block ");
1288 dump_generic_node (buffer, op0, spc, flags, false);
1289 pp_string (buffer, ">>>");
1290 break;
1292 case EXC_PTR_EXPR:
1293 pp_string (buffer, "<<<exception object>>>");
1294 break;
1296 case FILTER_EXPR:
1297 pp_string (buffer, "<<<filter object>>>");
1298 break;
1300 case LOOP_EXPR:
1301 pp_string (buffer, "while (1)");
1302 if (!(flags & TDF_SLIM))
1304 newline_and_indent (buffer, spc+2);
1305 pp_character (buffer, '{');
1306 newline_and_indent (buffer, spc+4);
1307 dump_generic_node (buffer, LOOP_EXPR_BODY (node), spc+4, flags, true);
1308 newline_and_indent (buffer, spc+2);
1309 pp_character (buffer, '}');
1311 is_expr = false;
1312 break;
1314 case RETURN_EXPR:
1315 pp_string (buffer, "return");
1316 op0 = TREE_OPERAND (node, 0);
1317 if (op0)
1319 pp_space (buffer);
1320 if (TREE_CODE (op0) == MODIFY_EXPR)
1321 dump_generic_node (buffer, TREE_OPERAND (op0, 1), spc, flags, false);
1322 else
1323 dump_generic_node (buffer, op0, spc, flags, false);
1325 break;
1327 case EXIT_EXPR:
1328 pp_string (buffer, "if (");
1329 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1330 pp_string (buffer, ") break");
1331 break;
1333 case SWITCH_EXPR:
1334 pp_string (buffer, "switch (");
1335 dump_generic_node (buffer, SWITCH_COND (node), spc, flags, false);
1336 pp_character (buffer, ')');
1337 if (!(flags & TDF_SLIM))
1339 newline_and_indent (buffer, spc+2);
1340 pp_character (buffer, '{');
1341 if (SWITCH_BODY (node))
1343 newline_and_indent (buffer, spc+4);
1344 dump_generic_node (buffer, SWITCH_BODY (node), spc+4, flags, true);
1346 else
1348 tree vec = SWITCH_LABELS (node);
1349 size_t i, n = TREE_VEC_LENGTH (vec);
1350 for (i = 0; i < n; ++i)
1352 tree elt = TREE_VEC_ELT (vec, i);
1353 newline_and_indent (buffer, spc+4);
1354 dump_generic_node (buffer, elt, spc+4, flags, false);
1355 pp_string (buffer, " goto ");
1356 dump_generic_node (buffer, CASE_LABEL (elt), spc+4, flags, true);
1357 pp_semicolon (buffer);
1360 newline_and_indent (buffer, spc+2);
1361 pp_character (buffer, '}');
1363 is_expr = false;
1364 break;
1366 case GOTO_EXPR:
1367 op0 = GOTO_DESTINATION (node);
1368 if (TREE_CODE (op0) != SSA_NAME && DECL_P (op0) && DECL_NAME (op0))
1370 const char *name = IDENTIFIER_POINTER (DECL_NAME (op0));
1371 if (strcmp (name, "break") == 0
1372 || strcmp (name, "continue") == 0)
1374 pp_string (buffer, name);
1375 break;
1378 pp_string (buffer, "goto ");
1379 dump_generic_node (buffer, op0, spc, flags, false);
1380 break;
1382 case RESX_EXPR:
1383 pp_string (buffer, "resx");
1384 /* ??? Any sensible way to present the eh region? */
1385 break;
1387 case ASM_EXPR:
1388 pp_string (buffer, "__asm__");
1389 if (ASM_VOLATILE_P (node))
1390 pp_string (buffer, " __volatile__");
1391 pp_character (buffer, '(');
1392 dump_generic_node (buffer, ASM_STRING (node), spc, flags, false);
1393 pp_character (buffer, ':');
1394 dump_generic_node (buffer, ASM_OUTPUTS (node), spc, flags, false);
1395 pp_character (buffer, ':');
1396 dump_generic_node (buffer, ASM_INPUTS (node), spc, flags, false);
1397 if (ASM_CLOBBERS (node))
1399 pp_character (buffer, ':');
1400 dump_generic_node (buffer, ASM_CLOBBERS (node), spc, flags, false);
1402 pp_string (buffer, ")");
1403 break;
1405 case CASE_LABEL_EXPR:
1406 if (CASE_LOW (node) && CASE_HIGH (node))
1408 pp_string (buffer, "case ");
1409 dump_generic_node (buffer, CASE_LOW (node), spc, flags, false);
1410 pp_string (buffer, " ... ");
1411 dump_generic_node (buffer, CASE_HIGH (node), spc, flags, false);
1413 else if (CASE_LOW (node))
1415 pp_string (buffer, "case ");
1416 dump_generic_node (buffer, CASE_LOW (node), spc, flags, false);
1418 else
1419 pp_string (buffer, "default ");
1420 pp_character (buffer, ':');
1421 break;
1423 case OBJ_TYPE_REF:
1424 pp_string (buffer, "OBJ_TYPE_REF(");
1425 dump_generic_node (buffer, OBJ_TYPE_REF_EXPR (node), spc, flags, false);
1426 pp_character (buffer, ';');
1427 dump_generic_node (buffer, OBJ_TYPE_REF_OBJECT (node), spc, flags, false);
1428 pp_character (buffer, '-');
1429 pp_character (buffer, '>');
1430 dump_generic_node (buffer, OBJ_TYPE_REF_TOKEN (node), spc, flags, false);
1431 pp_character (buffer, ')');
1432 break;
1434 case PHI_NODE:
1436 int i;
1438 dump_generic_node (buffer, PHI_RESULT (node), spc, flags, false);
1439 pp_string (buffer, " = PHI <");
1440 for (i = 0; i < PHI_NUM_ARGS (node); i++)
1442 dump_generic_node (buffer, PHI_ARG_DEF (node, i), spc, flags, false);
1443 pp_string (buffer, "(");
1444 pp_decimal_int (buffer, PHI_ARG_EDGE (node, i)->src->index);
1445 pp_string (buffer, ")");
1446 if (i < PHI_NUM_ARGS (node) - 1)
1447 pp_string (buffer, ", ");
1449 pp_string (buffer, ">;");
1451 break;
1453 case SSA_NAME:
1454 dump_generic_node (buffer, SSA_NAME_VAR (node), spc, flags, false);
1455 pp_string (buffer, "_");
1456 pp_decimal_int (buffer, SSA_NAME_VERSION (node));
1457 break;
1459 case WITH_SIZE_EXPR:
1460 pp_string (buffer, "WITH_SIZE_EXPR <");
1461 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1462 pp_string (buffer, ", ");
1463 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1464 pp_string (buffer, ">");
1465 break;
1467 case VALUE_HANDLE:
1468 pp_printf (buffer, "VH.%d", VALUE_HANDLE_ID (node));
1469 break;
1471 case SCEV_KNOWN:
1472 pp_string (buffer, "scev_known");
1473 break;
1475 case SCEV_NOT_KNOWN:
1476 pp_string (buffer, "scev_not_known");
1477 break;
1479 case POLYNOMIAL_CHREC:
1480 pp_string (buffer, "{");
1481 dump_generic_node (buffer, CHREC_LEFT (node), spc, flags, false);
1482 pp_string (buffer, ", +, ");
1483 dump_generic_node (buffer, CHREC_RIGHT (node), spc, flags, false);
1484 pp_string (buffer, "}_");
1485 dump_generic_node (buffer, CHREC_VAR (node), spc, flags, false);
1486 is_stmt = false;
1487 break;
1489 case REALIGN_LOAD_EXPR:
1490 pp_string (buffer, "REALIGN_LOAD <");
1491 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1492 pp_string (buffer, ", ");
1493 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1494 pp_string (buffer, ", ");
1495 dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
1496 pp_string (buffer, ">");
1497 break;
1499 case VEC_COND_EXPR:
1500 pp_string (buffer, " VEC_COND_EXPR < ");
1501 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1502 pp_string (buffer, " , ");
1503 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1504 pp_string (buffer, " , ");
1505 dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
1506 pp_string (buffer, " > ");
1507 break;
1509 default:
1510 NIY;
1513 if (is_stmt && is_expr)
1514 pp_semicolon (buffer);
1515 pp_write_text_to_stream (buffer);
1517 return spc;
1520 /* Print the declaration of a variable. */
1522 static void
1523 print_declaration (pretty_printer *buffer, tree t, int spc, int flags)
1525 INDENT (spc);
1527 if (TREE_CODE (t) == TYPE_DECL)
1528 pp_string (buffer, "typedef ");
1530 if (DECL_REGISTER (t))
1531 pp_string (buffer, "register ");
1533 if (TREE_PUBLIC (t) && DECL_EXTERNAL (t))
1534 pp_string (buffer, "extern ");
1535 else if (TREE_STATIC (t))
1536 pp_string (buffer, "static ");
1538 /* Print the type and name. */
1539 if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
1541 tree tmp;
1543 /* Print array's type. */
1544 tmp = TREE_TYPE (t);
1545 while (TREE_CODE (TREE_TYPE (tmp)) == ARRAY_TYPE)
1546 tmp = TREE_TYPE (tmp);
1547 dump_generic_node (buffer, TREE_TYPE (tmp), spc, flags, false);
1549 /* Print variable's name. */
1550 pp_space (buffer);
1551 dump_generic_node (buffer, t, spc, flags, false);
1553 /* Print the dimensions. */
1554 tmp = TREE_TYPE (t);
1555 while (TREE_CODE (tmp) == ARRAY_TYPE)
1557 pp_character (buffer, '[');
1558 if (TYPE_DOMAIN (tmp))
1560 if (TREE_CODE (TYPE_SIZE (tmp)) == INTEGER_CST)
1561 pp_wide_integer (buffer,
1562 TREE_INT_CST_LOW (TYPE_SIZE (tmp)) /
1563 TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (tmp))));
1564 else
1565 dump_generic_node (buffer, TYPE_SIZE_UNIT (tmp), spc, flags,
1566 false);
1568 pp_character (buffer, ']');
1569 tmp = TREE_TYPE (tmp);
1572 else if (TREE_CODE (t) == FUNCTION_DECL)
1574 dump_generic_node (buffer, TREE_TYPE (TREE_TYPE (t)), spc, flags, false);
1575 pp_space (buffer);
1576 dump_decl_name (buffer, t, flags);
1577 dump_function_declaration (buffer, TREE_TYPE (t), spc, flags);
1579 else
1581 /* Print type declaration. */
1582 dump_generic_node (buffer, TREE_TYPE (t), spc, flags, false);
1584 /* Print variable's name. */
1585 pp_space (buffer);
1586 dump_generic_node (buffer, t, spc, flags, false);
1589 if (TREE_CODE (t) == VAR_DECL && DECL_HARD_REGISTER (t))
1591 pp_string (buffer, " __asm__ ");
1592 pp_character (buffer, '(');
1593 dump_generic_node (buffer, DECL_ASSEMBLER_NAME (t), spc, flags, false);
1594 pp_character (buffer, ')');
1597 /* The initial value of a function serves to determine wether the function
1598 is declared or defined. So the following does not apply to function
1599 nodes. */
1600 if (TREE_CODE (t) != FUNCTION_DECL)
1602 /* Print the initial value. */
1603 if (DECL_INITIAL (t))
1605 pp_space (buffer);
1606 pp_character (buffer, '=');
1607 pp_space (buffer);
1608 dump_generic_node (buffer, DECL_INITIAL (t), spc, flags, false);
1612 pp_character (buffer, ';');
1616 /* Prints a structure: name, fields, and methods.
1617 FIXME: Still incomplete. */
1619 static void
1620 print_struct_decl (pretty_printer *buffer, tree node, int spc, int flags)
1622 /* Print the name of the structure. */
1623 if (TYPE_NAME (node))
1625 INDENT (spc);
1626 if (TREE_CODE (node) == RECORD_TYPE)
1627 pp_string (buffer, "struct ");
1628 else if ((TREE_CODE (node) == UNION_TYPE
1629 || TREE_CODE (node) == QUAL_UNION_TYPE))
1630 pp_string (buffer, "union ");
1632 dump_generic_node (buffer, TYPE_NAME (node), spc, 0, false);
1635 /* Print the contents of the structure. */
1636 pp_newline (buffer);
1637 INDENT (spc);
1638 pp_character (buffer, '{');
1639 pp_newline (buffer);
1641 /* Print the fields of the structure. */
1643 tree tmp;
1644 tmp = TYPE_FIELDS (node);
1645 while (tmp)
1647 /* Avoid to print recursively the structure. */
1648 /* FIXME : Not implemented correctly...,
1649 what about the case when we have a cycle in the contain graph? ...
1650 Maybe this could be solved by looking at the scope in which the
1651 structure was declared. */
1652 if (TREE_TYPE (tmp) != node
1653 || (TREE_CODE (TREE_TYPE (tmp)) == POINTER_TYPE
1654 && TREE_TYPE (TREE_TYPE (tmp)) != node))
1656 print_declaration (buffer, tmp, spc+2, flags);
1657 pp_newline (buffer);
1659 tmp = TREE_CHAIN (tmp);
1662 INDENT (spc);
1663 pp_character (buffer, '}');
1666 /* Return the priority of the operator OP.
1668 From lowest to highest precedence with either left-to-right (L-R)
1669 or right-to-left (R-L) associativity]:
1671 1 [L-R] ,
1672 2 [R-L] = += -= *= /= %= &= ^= |= <<= >>=
1673 3 [R-L] ?:
1674 4 [L-R] ||
1675 5 [L-R] &&
1676 6 [L-R] |
1677 7 [L-R] ^
1678 8 [L-R] &
1679 9 [L-R] == !=
1680 10 [L-R] < <= > >=
1681 11 [L-R] << >>
1682 12 [L-R] + -
1683 13 [L-R] * / %
1684 14 [R-L] ! ~ ++ -- + - * & (type) sizeof
1685 15 [L-R] fn() [] -> .
1687 unary +, - and * have higher precedence than the corresponding binary
1688 operators. */
1690 static int
1691 op_prio (tree op)
1693 if (op == NULL)
1694 return 9999;
1696 switch (TREE_CODE (op))
1698 case TREE_LIST:
1699 case COMPOUND_EXPR:
1700 case BIND_EXPR:
1701 return 1;
1703 case MODIFY_EXPR:
1704 case INIT_EXPR:
1705 return 2;
1707 case COND_EXPR:
1708 return 3;
1710 case TRUTH_OR_EXPR:
1711 case TRUTH_ORIF_EXPR:
1712 return 4;
1714 case TRUTH_AND_EXPR:
1715 case TRUTH_ANDIF_EXPR:
1716 return 5;
1718 case BIT_IOR_EXPR:
1719 return 6;
1721 case BIT_XOR_EXPR:
1722 case TRUTH_XOR_EXPR:
1723 return 7;
1725 case BIT_AND_EXPR:
1726 return 8;
1728 case EQ_EXPR:
1729 case NE_EXPR:
1730 return 9;
1732 case UNLT_EXPR:
1733 case UNLE_EXPR:
1734 case UNGT_EXPR:
1735 case UNGE_EXPR:
1736 case UNEQ_EXPR:
1737 case LTGT_EXPR:
1738 case ORDERED_EXPR:
1739 case UNORDERED_EXPR:
1740 case LT_EXPR:
1741 case LE_EXPR:
1742 case GT_EXPR:
1743 case GE_EXPR:
1744 return 10;
1746 case LSHIFT_EXPR:
1747 case RSHIFT_EXPR:
1748 case LROTATE_EXPR:
1749 case RROTATE_EXPR:
1750 return 11;
1752 case PLUS_EXPR:
1753 case MINUS_EXPR:
1754 return 12;
1756 case MULT_EXPR:
1757 case TRUNC_DIV_EXPR:
1758 case CEIL_DIV_EXPR:
1759 case FLOOR_DIV_EXPR:
1760 case ROUND_DIV_EXPR:
1761 case RDIV_EXPR:
1762 case EXACT_DIV_EXPR:
1763 case TRUNC_MOD_EXPR:
1764 case CEIL_MOD_EXPR:
1765 case FLOOR_MOD_EXPR:
1766 case ROUND_MOD_EXPR:
1767 return 13;
1769 case TRUTH_NOT_EXPR:
1770 case BIT_NOT_EXPR:
1771 case POSTINCREMENT_EXPR:
1772 case POSTDECREMENT_EXPR:
1773 case PREINCREMENT_EXPR:
1774 case PREDECREMENT_EXPR:
1775 case NEGATE_EXPR:
1776 case ALIGN_INDIRECT_REF:
1777 case MISALIGNED_INDIRECT_REF:
1778 case INDIRECT_REF:
1779 case ADDR_EXPR:
1780 case FLOAT_EXPR:
1781 case NOP_EXPR:
1782 case CONVERT_EXPR:
1783 case FIX_TRUNC_EXPR:
1784 case FIX_CEIL_EXPR:
1785 case FIX_FLOOR_EXPR:
1786 case FIX_ROUND_EXPR:
1787 case TARGET_EXPR:
1788 return 14;
1790 case CALL_EXPR:
1791 case ARRAY_REF:
1792 case ARRAY_RANGE_REF:
1793 case COMPONENT_REF:
1794 return 15;
1796 /* Special expressions. */
1797 case MIN_EXPR:
1798 case MAX_EXPR:
1799 case ABS_EXPR:
1800 case REALPART_EXPR:
1801 case IMAGPART_EXPR:
1802 return 16;
1804 case SAVE_EXPR:
1805 case NON_LVALUE_EXPR:
1806 return op_prio (TREE_OPERAND (op, 0));
1808 default:
1809 /* Return an arbitrarily high precedence to avoid surrounding single
1810 VAR_DECLs in ()s. */
1811 return 9999;
1816 /* Return the symbol associated with operator OP. */
1818 static const char *
1819 op_symbol (tree op)
1821 gcc_assert (op);
1823 switch (TREE_CODE (op))
1825 case MODIFY_EXPR:
1826 return "=";
1828 case TRUTH_OR_EXPR:
1829 case TRUTH_ORIF_EXPR:
1830 return "||";
1832 case TRUTH_AND_EXPR:
1833 case TRUTH_ANDIF_EXPR:
1834 return "&&";
1836 case BIT_IOR_EXPR:
1837 return "|";
1839 case TRUTH_XOR_EXPR:
1840 case BIT_XOR_EXPR:
1841 return "^";
1843 case ADDR_EXPR:
1844 case BIT_AND_EXPR:
1845 return "&";
1847 case ORDERED_EXPR:
1848 return "ord";
1849 case UNORDERED_EXPR:
1850 return "unord";
1852 case EQ_EXPR:
1853 return "==";
1854 case UNEQ_EXPR:
1855 return "u==";
1857 case NE_EXPR:
1858 return "!=";
1860 case LT_EXPR:
1861 return "<";
1862 case UNLT_EXPR:
1863 return "u<";
1865 case LE_EXPR:
1866 return "<=";
1867 case UNLE_EXPR:
1868 return "u<=";
1870 case GT_EXPR:
1871 return ">";
1872 case UNGT_EXPR:
1873 return "u>";
1875 case GE_EXPR:
1876 return ">=";
1877 case UNGE_EXPR:
1878 return "u>=";
1880 case LTGT_EXPR:
1881 return "<>";
1883 case LSHIFT_EXPR:
1884 return "<<";
1886 case RSHIFT_EXPR:
1887 return ">>";
1889 case PLUS_EXPR:
1890 return "+";
1892 case NEGATE_EXPR:
1893 case MINUS_EXPR:
1894 return "-";
1896 case BIT_NOT_EXPR:
1897 return "~";
1899 case TRUTH_NOT_EXPR:
1900 return "!";
1902 case MULT_EXPR:
1903 case INDIRECT_REF:
1904 return "*";
1906 case ALIGN_INDIRECT_REF:
1907 return "A*";
1909 case MISALIGNED_INDIRECT_REF:
1910 return "M*";
1912 case TRUNC_DIV_EXPR:
1913 case RDIV_EXPR:
1914 return "/";
1916 case CEIL_DIV_EXPR:
1917 return "/[cl]";
1919 case FLOOR_DIV_EXPR:
1920 return "/[fl]";
1922 case ROUND_DIV_EXPR:
1923 return "/[rd]";
1925 case EXACT_DIV_EXPR:
1926 return "/[ex]";
1928 case TRUNC_MOD_EXPR:
1929 return "%";
1931 case CEIL_MOD_EXPR:
1932 return "%[cl]";
1934 case FLOOR_MOD_EXPR:
1935 return "%[fl]";
1937 case ROUND_MOD_EXPR:
1938 return "%[rd]";
1940 case PREDECREMENT_EXPR:
1941 return " --";
1943 case PREINCREMENT_EXPR:
1944 return " ++";
1946 case POSTDECREMENT_EXPR:
1947 return "-- ";
1949 case POSTINCREMENT_EXPR:
1950 return "++ ";
1952 default:
1953 return "<<< ??? >>>";
1957 /* Prints the name of a CALL_EXPR. */
1959 static void
1960 print_call_name (pretty_printer *buffer, tree node)
1962 tree op0;
1964 gcc_assert (TREE_CODE (node) == CALL_EXPR);
1966 op0 = TREE_OPERAND (node, 0);
1968 if (TREE_CODE (op0) == NON_LVALUE_EXPR)
1969 op0 = TREE_OPERAND (op0, 0);
1971 switch (TREE_CODE (op0))
1973 case VAR_DECL:
1974 case PARM_DECL:
1975 dump_function_name (buffer, op0);
1976 break;
1978 case ADDR_EXPR:
1979 case INDIRECT_REF:
1980 case NOP_EXPR:
1981 dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
1982 break;
1984 case COND_EXPR:
1985 pp_string (buffer, "(");
1986 dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
1987 pp_string (buffer, ") ? ");
1988 dump_generic_node (buffer, TREE_OPERAND (op0, 1), 0, 0, false);
1989 pp_string (buffer, " : ");
1990 dump_generic_node (buffer, TREE_OPERAND (op0, 2), 0, 0, false);
1991 break;
1993 case COMPONENT_REF:
1994 /* The function is a pointer contained in a structure. */
1995 if (TREE_CODE (TREE_OPERAND (op0, 0)) == INDIRECT_REF ||
1996 TREE_CODE (TREE_OPERAND (op0, 0)) == VAR_DECL)
1997 dump_function_name (buffer, TREE_OPERAND (op0, 1));
1998 else
1999 dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
2000 /* else
2001 We can have several levels of structures and a function
2002 pointer inside. This is not implemented yet... */
2003 /* NIY;*/
2004 break;
2006 case ARRAY_REF:
2007 if (TREE_CODE (TREE_OPERAND (op0, 0)) == VAR_DECL)
2008 dump_function_name (buffer, TREE_OPERAND (op0, 0));
2009 else
2010 dump_generic_node (buffer, op0, 0, 0, false);
2011 break;
2013 case SSA_NAME:
2014 case OBJ_TYPE_REF:
2015 dump_generic_node (buffer, op0, 0, 0, false);
2016 break;
2018 default:
2019 NIY;
2023 /* Parses the string STR and replaces new-lines by '\n', tabs by '\t', ... */
2025 static void
2026 pretty_print_string (pretty_printer *buffer, const char *str)
2028 if (str == NULL)
2029 return;
2031 while (*str)
2033 switch (str[0])
2035 case '\b':
2036 pp_string (buffer, "\\b");
2037 break;
2039 case '\f':
2040 pp_string (buffer, "\\f");
2041 break;
2043 case '\n':
2044 pp_string (buffer, "\\n");
2045 break;
2047 case '\r':
2048 pp_string (buffer, "\\r");
2049 break;
2051 case '\t':
2052 pp_string (buffer, "\\t");
2053 break;
2055 case '\v':
2056 pp_string (buffer, "\\v");
2057 break;
2059 case '\\':
2060 pp_string (buffer, "\\\\");
2061 break;
2063 case '\"':
2064 pp_string (buffer, "\\\"");
2065 break;
2067 case '\'':
2068 pp_string (buffer, "\\'");
2069 break;
2071 case '\0':
2072 pp_string (buffer, "\\0");
2073 break;
2075 case '\1':
2076 pp_string (buffer, "\\1");
2077 break;
2079 case '\2':
2080 pp_string (buffer, "\\2");
2081 break;
2083 case '\3':
2084 pp_string (buffer, "\\3");
2085 break;
2087 case '\4':
2088 pp_string (buffer, "\\4");
2089 break;
2091 case '\5':
2092 pp_string (buffer, "\\5");
2093 break;
2095 case '\6':
2096 pp_string (buffer, "\\6");
2097 break;
2099 case '\7':
2100 pp_string (buffer, "\\7");
2101 break;
2103 default:
2104 pp_character (buffer, str[0]);
2105 break;
2107 str++;
2111 static void
2112 maybe_init_pretty_print (FILE *file)
2114 if (!initialized)
2116 pp_construct (&buffer, /* prefix */NULL, /* line-width */0);
2117 pp_needs_newline (&buffer) = true;
2118 initialized = 1;
2121 buffer.buffer->stream = file;
2124 static void
2125 newline_and_indent (pretty_printer *buffer, int spc)
2127 pp_newline (buffer);
2128 INDENT (spc);
2131 static void
2132 dump_vops (pretty_printer *buffer, tree stmt, int spc, int flags)
2134 tree use, def;
2135 use_operand_p use_p;
2136 def_operand_p def_p;
2137 ssa_op_iter iter;
2139 FOR_EACH_SSA_MAYDEF_OPERAND (def_p, use_p, stmt, iter)
2141 pp_string (buffer, "# ");
2142 dump_generic_node (buffer, DEF_FROM_PTR (def_p),
2143 spc + 2, flags, false);
2144 pp_string (buffer, " = V_MAY_DEF <");
2145 dump_generic_node (buffer, USE_FROM_PTR (use_p),
2146 spc + 2, flags, false);
2147 pp_string (buffer, ">;");
2148 newline_and_indent (buffer, spc);
2151 FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_VMUSTDEF)
2153 pp_string (buffer, "# V_MUST_DEF <");
2154 dump_generic_node (buffer, def, spc + 2, flags, false);
2155 pp_string (buffer, ">;");
2156 newline_and_indent (buffer, spc);
2159 FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_VUSE)
2161 pp_string (buffer, "# VUSE <");
2162 dump_generic_node (buffer, use, spc + 2, flags, false);
2163 pp_string (buffer, ">;");
2164 newline_and_indent (buffer, spc);
2168 /* Dumps basic block BB to FILE with details described by FLAGS and
2169 indented by INDENT spaces. */
2171 void
2172 dump_generic_bb (FILE *file, basic_block bb, int indent, int flags)
2174 maybe_init_pretty_print (file);
2175 dumping_stmts = true;
2176 dump_generic_bb_buff (&buffer, bb, indent, flags);
2177 pp_flush (&buffer);
2180 /* Dumps header of basic block BB to buffer BUFFER indented by INDENT
2181 spaces and details described by flags. */
2183 static void
2184 dump_bb_header (pretty_printer *buffer, basic_block bb, int indent, int flags)
2186 edge e;
2187 tree stmt;
2188 edge_iterator ei;
2190 if (flags & TDF_BLOCKS)
2192 INDENT (indent);
2193 pp_string (buffer, "# BLOCK ");
2194 pp_decimal_int (buffer, bb->index);
2196 if (flags & TDF_LINENO)
2198 block_stmt_iterator bsi;
2200 for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
2201 if (get_lineno (bsi_stmt (bsi)) != -1)
2203 pp_string (buffer, ", starting at line ");
2204 pp_decimal_int (buffer, get_lineno (bsi_stmt (bsi)));
2205 break;
2208 newline_and_indent (buffer, indent);
2210 pp_string (buffer, "# PRED:");
2211 pp_write_text_to_stream (buffer);
2212 FOR_EACH_EDGE (e, ei, bb->preds)
2213 if (flags & TDF_SLIM)
2215 pp_string (buffer, " ");
2216 if (e->src == ENTRY_BLOCK_PTR)
2217 pp_string (buffer, "ENTRY");
2218 else
2219 pp_decimal_int (buffer, e->src->index);
2221 else
2222 dump_edge_info (buffer->buffer->stream, e, 0);
2223 pp_newline (buffer);
2225 else
2227 stmt = first_stmt (bb);
2228 if (!stmt || TREE_CODE (stmt) != LABEL_EXPR)
2230 INDENT (indent - 2);
2231 pp_string (buffer, "<bb ");
2232 pp_decimal_int (buffer, bb->index);
2233 pp_string (buffer, ">:");
2234 pp_newline (buffer);
2237 pp_write_text_to_stream (buffer);
2238 check_bb_profile (bb, buffer->buffer->stream);
2241 /* Dumps end of basic block BB to buffer BUFFER indented by INDENT
2242 spaces. */
2244 static void
2245 dump_bb_end (pretty_printer *buffer, basic_block bb, int indent, int flags)
2247 edge e;
2248 edge_iterator ei;
2250 INDENT (indent);
2251 pp_string (buffer, "# SUCC:");
2252 pp_write_text_to_stream (buffer);
2253 FOR_EACH_EDGE (e, ei, bb->succs)
2254 if (flags & TDF_SLIM)
2256 pp_string (buffer, " ");
2257 if (e->dest == EXIT_BLOCK_PTR)
2258 pp_string (buffer, "EXIT");
2259 else
2260 pp_decimal_int (buffer, e->dest->index);
2262 else
2263 dump_edge_info (buffer->buffer->stream, e, 1);
2264 pp_newline (buffer);
2267 /* Dumps phi nodes of basic block BB to buffer BUFFER with details described by
2268 FLAGS indented by INDENT spaces. */
2270 static void
2271 dump_phi_nodes (pretty_printer *buffer, basic_block bb, int indent, int flags)
2273 tree phi = phi_nodes (bb);
2274 if (!phi)
2275 return;
2277 for (; phi; phi = PHI_CHAIN (phi))
2279 if (is_gimple_reg (PHI_RESULT (phi)) || (flags & TDF_VOPS))
2281 INDENT (indent);
2282 pp_string (buffer, "# ");
2283 dump_generic_node (buffer, phi, indent, flags, false);
2284 pp_newline (buffer);
2289 /* Dump jump to basic block BB that is represented implicitly in the cfg
2290 to BUFFER. */
2292 static void
2293 pp_cfg_jump (pretty_printer *buffer, basic_block bb)
2295 tree stmt;
2297 stmt = first_stmt (bb);
2299 pp_string (buffer, "goto <bb ");
2300 pp_decimal_int (buffer, bb->index);
2301 pp_string (buffer, ">");
2302 if (stmt && TREE_CODE (stmt) == LABEL_EXPR)
2304 pp_string (buffer, " (");
2305 dump_generic_node (buffer, LABEL_EXPR_LABEL (stmt), 0, 0, false);
2306 pp_string (buffer, ")");
2308 pp_semicolon (buffer);
2311 /* Dump edges represented implicitly in basic block BB to BUFFER, indented
2312 by INDENT spaces, with details given by FLAGS. */
2314 static void
2315 dump_implicit_edges (pretty_printer *buffer, basic_block bb, int indent,
2316 int flags)
2318 edge e;
2319 edge_iterator ei;
2321 /* If there is a fallthru edge, we may need to add an artificial goto to the
2322 dump. */
2323 FOR_EACH_EDGE (e, ei, bb->succs)
2324 if (e->flags & EDGE_FALLTHRU)
2325 break;
2326 if (e && e->dest != bb->next_bb)
2328 INDENT (indent);
2330 if ((flags & TDF_LINENO)
2331 #ifdef USE_MAPPED_LOCATION
2332 && e->goto_locus != UNKNOWN_LOCATION
2333 #else
2334 && e->goto_locus
2335 #endif
2338 expanded_location goto_xloc;
2339 #ifdef USE_MAPPED_LOCATION
2340 goto_xloc = expand_location (e->goto_locus);
2341 #else
2342 goto_xloc = *e->goto_locus;
2343 #endif
2344 pp_character (buffer, '[');
2345 if (goto_xloc.file)
2347 pp_string (buffer, goto_xloc.file);
2348 pp_string (buffer, " : ");
2350 pp_decimal_int (buffer, goto_xloc.line);
2351 pp_string (buffer, "] ");
2354 pp_cfg_jump (buffer, e->dest);
2355 pp_newline (buffer);
2359 /* Dumps basic block BB to buffer BUFFER with details described by FLAGS and
2360 indented by INDENT spaces. */
2362 static void
2363 dump_generic_bb_buff (pretty_printer *buffer, basic_block bb,
2364 int indent, int flags)
2366 block_stmt_iterator bsi;
2367 tree stmt;
2368 int label_indent = indent - 2;
2370 if (label_indent < 0)
2371 label_indent = 0;
2373 dump_bb_header (buffer, bb, indent, flags);
2375 if (bb_ann (bb))
2376 dump_phi_nodes (buffer, bb, indent, flags);
2378 for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
2380 int curr_indent;
2382 stmt = bsi_stmt (bsi);
2384 curr_indent = TREE_CODE (stmt) == LABEL_EXPR ? label_indent : indent;
2386 INDENT (curr_indent);
2387 dump_generic_node (buffer, stmt, curr_indent, flags, true);
2388 pp_newline (buffer);
2391 dump_implicit_edges (buffer, bb, indent, flags);
2393 if (flags & TDF_BLOCKS)
2394 dump_bb_end (buffer, bb, indent, flags);