* alias.c (adjust_offset_for_component_ref): Use
[official-gcc.git] / gcc / tree-pretty-print.c
blob52aa18194171c920e6f62fd2dbd412bb03db639f
1 /* Pretty formatting of GENERIC trees in C syntax.
2 Copyright (C) 2001, 2002, 2003 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"
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 #define MASK_POINTER(P) ((unsigned)((unsigned long)(P) & 0xffff))
60 static pretty_printer buffer;
61 static int initialized = 0;
62 static bool dumping_stmts;
64 /* Try to print something for an unknown tree code. */
66 static void
67 do_niy (pretty_printer *buffer, tree node)
69 int i, len;
71 pp_string (buffer, "<<< Unknown tree: ");
72 pp_string (buffer, tree_code_name[(int) TREE_CODE (node)]);
74 if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (node))))
76 len = first_rtl_op (TREE_CODE (node));
77 for (i = 0; i < len; ++i)
79 newline_and_indent (buffer, 2);
80 dump_generic_node (buffer, TREE_OPERAND (node, i), 2, 0, false);
84 pp_string (buffer, " >>>\n");
87 void
88 debug_generic_expr (tree t)
90 print_generic_expr (stderr, t, TDF_VOPS|TDF_UID);
91 fprintf (stderr, "\n");
94 void
95 debug_generic_stmt (tree t)
97 print_generic_stmt (stderr, t, TDF_VOPS|TDF_UID);
98 fprintf (stderr, "\n");
101 /* Prints declaration DECL to the FILE with details specified by FLAGS. */
102 void
103 print_generic_decl (FILE *file, tree decl, int flags)
105 maybe_init_pretty_print (file);
106 dumping_stmts = true;
107 print_declaration (&buffer, decl, 2, flags);
108 pp_write_text_to_stream (&buffer);
111 /* Print tree T, and its successors, on file FILE. FLAGS specifies details
112 to show in the dump. See TDF_* in tree.h. */
114 void
115 print_generic_stmt (FILE *file, tree t, int flags)
117 maybe_init_pretty_print (file);
118 dumping_stmts = true;
119 dump_generic_node (&buffer, t, 0, flags, true);
120 pp_flush (&buffer);
123 /* Print tree T, and its successors, on file FILE. FLAGS specifies details
124 to show in the dump. See TDF_* in tree.h. The output is indented by
125 INDENT spaces. */
127 void
128 print_generic_stmt_indented (FILE *file, tree t, int flags, int indent)
130 int i;
132 maybe_init_pretty_print (file);
133 dumping_stmts = true;
135 for (i = 0; i < indent; i++)
136 pp_space (&buffer);
137 dump_generic_node (&buffer, t, indent, flags, true);
138 pp_flush (&buffer);
141 /* Print a single expression T on file FILE. FLAGS specifies details to show
142 in the dump. See TDF_* in tree.h. */
144 void
145 print_generic_expr (FILE *file, tree t, int flags)
147 maybe_init_pretty_print (file);
148 dumping_stmts = false;
149 dump_generic_node (&buffer, t, 0, flags, false);
152 /* Dump the name of a _DECL node and its DECL_UID if TDF_UID is set
153 in FLAGS. */
155 static void
156 dump_decl_name (pretty_printer *buffer, tree node, int flags)
158 if (DECL_NAME (node))
159 pp_tree_identifier (buffer, DECL_NAME (node));
161 if ((flags & TDF_UID)
162 || DECL_NAME (node) == NULL_TREE)
164 if (TREE_CODE (node) == LABEL_DECL
165 && LABEL_DECL_UID (node) != -1)
166 pp_printf (buffer, "<L" HOST_WIDE_INT_PRINT_DEC ">",
167 LABEL_DECL_UID (node));
168 else
169 pp_printf (buffer, "<D%u>", DECL_UID (node));
173 /* Dump the node NODE on the pretty_printer BUFFER, SPC spaces of indent.
174 FLAGS specifies details to show in the dump (see TDF_* in tree.h). If
175 IS_STMT is true, the object printed is considered to be a statement
176 and it is terminated by ';' if appropriate. */
179 dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
180 bool is_stmt)
182 tree type;
183 tree op0, op1;
184 const char* str;
185 bool is_expr;
187 if (node == NULL_TREE)
188 return spc;
190 is_expr = EXPR_P (node);
192 if (TREE_CODE (node) != ERROR_MARK
193 && is_gimple_stmt (node)
194 && (flags & TDF_VOPS)
195 && stmt_ann (node))
196 dump_vops (buffer, node, spc, flags);
198 if (dumping_stmts
199 && (flags & TDF_LINENO)
200 && EXPR_HAS_LOCATION (node))
202 pp_character (buffer, '[');
203 if (EXPR_FILENAME (node))
205 pp_string (buffer, EXPR_FILENAME (node));
206 pp_string (buffer, " : ");
208 pp_decimal_int (buffer, EXPR_LINENO (node));
209 pp_string (buffer, "] ");
212 switch (TREE_CODE (node))
214 case ERROR_MARK:
215 pp_string (buffer, "<<< error >>>");
216 break;
218 case IDENTIFIER_NODE:
219 pp_tree_identifier (buffer, node);
220 break;
222 case TREE_LIST:
223 while (node && node != error_mark_node)
225 if (TREE_PURPOSE (node))
227 dump_generic_node (buffer, TREE_PURPOSE (node), spc, flags, false);
228 pp_space (buffer);
230 dump_generic_node (buffer, TREE_VALUE (node), spc, flags, false);
231 node = TREE_CHAIN (node);
232 if (node && TREE_CODE (node) == TREE_LIST)
234 pp_character (buffer, ',');
235 pp_space (buffer);
238 break;
240 case TREE_VEC:
241 dump_generic_node (buffer, BINFO_TYPE (node), spc, flags, false);
242 break;
244 case BLOCK:
245 NIY;
246 break;
248 case VOID_TYPE:
249 case INTEGER_TYPE:
250 case REAL_TYPE:
251 case COMPLEX_TYPE:
252 case VECTOR_TYPE:
253 case ENUMERAL_TYPE:
254 case BOOLEAN_TYPE:
255 case CHAR_TYPE:
257 unsigned int quals = TYPE_QUALS (node);
258 char class;
260 if (quals & TYPE_QUAL_CONST)
261 pp_string (buffer, "const ");
262 else if (quals & TYPE_QUAL_VOLATILE)
263 pp_string (buffer, "volatile ");
264 else if (quals & TYPE_QUAL_RESTRICT)
265 pp_string (buffer, "restrict ");
267 class = TREE_CODE_CLASS (TREE_CODE (node));
269 if (class == 'd')
271 if (DECL_NAME (node))
272 dump_decl_name (buffer, node, flags);
273 else
274 pp_string (buffer, "<unnamed type decl>");
276 else if (class == 't')
278 if (TYPE_NAME (node))
280 if (TREE_CODE (TYPE_NAME (node)) == IDENTIFIER_NODE)
281 pp_tree_identifier (buffer, TYPE_NAME (node));
282 else if (TREE_CODE (TYPE_NAME (node)) == TYPE_DECL
283 && DECL_NAME (TYPE_NAME (node)))
284 dump_decl_name (buffer, TYPE_NAME (node), flags);
285 else
286 pp_string (buffer, "<unnamed type>");
288 else
289 pp_string (buffer, "<unnamed type>");
291 break;
294 case POINTER_TYPE:
295 case REFERENCE_TYPE:
296 str = (TREE_CODE (node) == POINTER_TYPE ? "*" : "&");
298 if (TREE_CODE (TREE_TYPE (node)) == FUNCTION_TYPE)
300 tree fnode = TREE_TYPE (node);
301 dump_generic_node (buffer, TREE_TYPE (fnode), spc, flags, false);
302 pp_space (buffer);
303 pp_character (buffer, '(');
304 pp_string (buffer, str);
305 if (TYPE_NAME (node) && DECL_NAME (TYPE_NAME (node)))
306 dump_decl_name (buffer, TYPE_NAME (node), flags);
307 else
308 pp_printf (buffer, "<T%x>", TYPE_UID (node));
310 pp_character (buffer, ')');
311 pp_space (buffer);
312 pp_character (buffer, '(');
313 /* Print the argument types. The last element in the list is a
314 VOID_TYPE. The following avoid to print the last element. */
316 tree tmp = TYPE_ARG_TYPES (fnode);
317 while (tmp && TREE_CHAIN (tmp) && tmp != error_mark_node)
319 dump_generic_node (buffer, TREE_VALUE (tmp), spc, flags, false);
320 tmp = TREE_CHAIN (tmp);
321 if (TREE_CHAIN (tmp) && TREE_CODE (TREE_CHAIN (tmp)) == TREE_LIST)
323 pp_character (buffer, ',');
324 pp_space (buffer);
328 pp_character (buffer, ')');
330 else
332 unsigned int quals = TYPE_QUALS (node);
334 dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
335 pp_space (buffer);
336 pp_string (buffer, str);
338 if (quals & TYPE_QUAL_CONST)
339 pp_string (buffer, " const");
340 else if (quals & TYPE_QUAL_VOLATILE)
341 pp_string (buffer, "volatile");
342 else if (quals & TYPE_QUAL_RESTRICT)
343 pp_string (buffer, " restrict");
345 break;
347 case OFFSET_TYPE:
348 NIY;
349 break;
351 case METHOD_TYPE:
352 dump_decl_name (buffer, TYPE_NAME (TYPE_METHOD_BASETYPE (node)), flags);
353 pp_string (buffer, "::");
354 break;
356 case FILE_TYPE:
357 NIY;
358 break;
360 case ARRAY_TYPE:
362 tree tmp;
364 /* Print the array type. */
365 dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
367 /* Print the dimensions. */
368 tmp = node;
369 while (tmp && TREE_CODE (tmp) == ARRAY_TYPE)
371 pp_character (buffer, '[');
372 if (TYPE_SIZE (tmp))
374 tree size = TYPE_SIZE (tmp);
375 if (TREE_CODE (size) == INTEGER_CST)
376 pp_wide_integer (buffer,
377 TREE_INT_CST_LOW (TYPE_SIZE (tmp)) /
378 TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (tmp))));
379 else if (TREE_CODE (size) == MULT_EXPR)
380 dump_generic_node (buffer, TREE_OPERAND (size, 0), spc, flags, false);
381 /* else punt. */
383 pp_character (buffer, ']');
384 tmp = TREE_TYPE (tmp);
386 break;
389 case SET_TYPE:
390 NIY;
391 break;
393 case RECORD_TYPE:
394 case UNION_TYPE:
395 case QUAL_UNION_TYPE:
396 /* Print the name of the structure. */
397 if (TREE_CODE (node) == RECORD_TYPE)
398 pp_string (buffer, "struct ");
399 else if (TREE_CODE (node) == UNION_TYPE)
400 pp_string (buffer, "union ");
402 if (TYPE_NAME (node))
403 dump_generic_node (buffer, TYPE_NAME (node), spc, flags, false);
404 else
405 print_struct_decl (buffer, node, spc, flags);
406 break;
408 case LANG_TYPE:
409 NIY;
410 break;
412 case INTEGER_CST:
413 if (TREE_CODE (TREE_TYPE (node)) == POINTER_TYPE)
415 /* In the case of a pointer, one may want to divide by the
416 size of the pointed-to type. Unfortunately, this not
417 straightforward. The C front-end maps expressions
419 (int *) 5
420 int *p; (p + 5)
422 in such a way that the two INTEGER_CST nodes for "5" have
423 different values but identical types. In the latter
424 case, the 5 is multiplied by sizeof (int) in c-common.c
425 (pointer_int_sum) to convert it to a byte address, and
426 yet the type of the node is left unchanged. Argh. What
427 is consistent though is that the number value corresponds
428 to bytes (UNITS) offset.
430 NB: Neither of the following divisors can be trivially
431 used to recover the original literal:
433 TREE_INT_CST_LOW (TYPE_SIZE_UNIT (TREE_TYPE (node)))
434 TYPE_PRECISION (TREE_TYPE (TREE_TYPE (node))) */
435 pp_wide_integer (buffer, TREE_INT_CST_LOW (node));
436 pp_string (buffer, "B"); /* pseudo-unit */
438 else if (! host_integerp (node, 0))
440 tree val = node;
442 if (tree_int_cst_sgn (val) < 0)
444 pp_character (buffer, '-');
445 val = build_int_2 (-TREE_INT_CST_LOW (val),
446 ~TREE_INT_CST_HIGH (val)
447 + !TREE_INT_CST_LOW (val));
449 /* Would "%x%0*x" or "%x%*0x" get zero-padding on all
450 systems? */
452 static char format[10]; /* "%x%09999x\0" */
453 if (!format[0])
454 sprintf (format, "%%x%%0%dx", HOST_BITS_PER_INT / 4);
455 sprintf (pp_buffer (buffer)->digit_buffer, format,
456 TREE_INT_CST_HIGH (val),
457 TREE_INT_CST_LOW (val));
458 pp_string (buffer, pp_buffer (buffer)->digit_buffer);
461 else
462 pp_wide_integer (buffer, TREE_INT_CST_LOW (node));
463 break;
465 case REAL_CST:
466 /* Code copied from print_node. */
468 REAL_VALUE_TYPE d;
469 if (TREE_OVERFLOW (node))
470 pp_string (buffer, " overflow");
472 #if !defined(REAL_IS_NOT_DOUBLE) || defined(REAL_ARITHMETIC)
473 d = TREE_REAL_CST (node);
474 if (REAL_VALUE_ISINF (d))
475 pp_string (buffer, " Inf");
476 else if (REAL_VALUE_ISNAN (d))
477 pp_string (buffer, " Nan");
478 else
480 char string[100];
481 real_to_decimal (string, &d, sizeof (string), 0, 1);
482 pp_string (buffer, string);
484 #else
486 HOST_WIDE_INT i;
487 unsigned char *p = (unsigned char *) &TREE_REAL_CST (node);
488 pp_string (buffer, "0x");
489 for (i = 0; i < sizeof TREE_REAL_CST (node); i++)
490 output_formatted_integer (buffer, "%02x", *p++);
492 #endif
493 break;
496 case COMPLEX_CST:
497 pp_string (buffer, "__complex__ (");
498 dump_generic_node (buffer, TREE_REALPART (node), spc, flags, false);
499 pp_string (buffer, ", ");
500 dump_generic_node (buffer, TREE_IMAGPART (node), spc, flags, false);
501 pp_string (buffer, ")");
502 break;
504 case STRING_CST:
505 pp_string (buffer, "\"");
506 pretty_print_string (buffer, TREE_STRING_POINTER (node));
507 pp_string (buffer, "\"");
508 break;
510 case VECTOR_CST:
512 tree elt;
513 pp_string (buffer, "{ ");
514 for (elt = TREE_VECTOR_CST_ELTS (node); elt; elt = TREE_CHAIN (elt))
516 dump_generic_node (buffer, TREE_VALUE (elt), spc, flags, false);
517 if (TREE_CHAIN (elt))
518 pp_string (buffer, ", ");
520 pp_string (buffer, " }");
522 break;
524 case FUNCTION_TYPE:
525 break;
527 case FUNCTION_DECL:
528 case CONST_DECL:
529 dump_decl_name (buffer, node, flags);
530 break;
532 case LABEL_DECL:
533 if (DECL_NAME (node))
534 dump_decl_name (buffer, node, flags);
535 else if (LABEL_DECL_UID (node) != -1)
536 pp_printf (buffer, "<L" HOST_WIDE_INT_PRINT_DEC ">",
537 LABEL_DECL_UID (node));
538 else
539 pp_printf (buffer, "<D%u>", DECL_UID (node));
540 break;
542 case TYPE_DECL:
543 if (strcmp (DECL_SOURCE_FILE (node), "<built-in>") == 0)
545 /* Don't print the declaration of built-in types. */
546 break;
548 if (DECL_NAME (node))
550 dump_decl_name (buffer, node, flags);
552 else
554 if (TYPE_METHODS (TREE_TYPE (node)))
556 /* The type is a c++ class: all structures have at least
557 4 methods. */
558 pp_string (buffer, "class ");
559 dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
561 else
563 pp_string (buffer, "struct ");
564 dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
565 pp_character (buffer, ';');
566 pp_newline (buffer);
569 break;
571 case VAR_DECL:
572 case PARM_DECL:
573 case FIELD_DECL:
574 case NAMESPACE_DECL:
575 dump_decl_name (buffer, node, flags);
576 break;
578 case RESULT_DECL:
579 pp_string (buffer, "<retval>");
580 break;
582 case COMPONENT_REF:
583 op0 = TREE_OPERAND (node, 0);
584 str = ".";
585 if (TREE_CODE (op0) == INDIRECT_REF)
587 op0 = TREE_OPERAND (op0, 0);
588 str = "->";
590 if (op_prio (op0) < op_prio (node))
591 pp_character (buffer, '(');
592 dump_generic_node (buffer, op0, spc, flags, false);
593 if (op_prio (op0) < op_prio (node))
594 pp_character (buffer, ')');
595 pp_string (buffer, str);
596 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
597 if (TREE_OPERAND (node, 2)
598 && TREE_CODE (TREE_OPERAND (node, 2)) != INTEGER_CST)
600 pp_string (buffer, "{off: ");
601 dump_generic_node (buffer, TREE_OPERAND (node, 2),
602 spc, flags, false);
603 pp_character (buffer, '}');
605 break;
607 case BIT_FIELD_REF:
608 pp_string (buffer, "BIT_FIELD_REF <");
609 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
610 pp_string (buffer, ", ");
611 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
612 pp_string (buffer, ", ");
613 dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
614 pp_string (buffer, ">");
615 break;
617 case BUFFER_REF:
618 NIY;
619 break;
621 case ARRAY_REF:
622 case ARRAY_RANGE_REF:
623 op0 = TREE_OPERAND (node, 0);
624 if (op_prio (op0) < op_prio (node))
625 pp_character (buffer, '(');
626 dump_generic_node (buffer, op0, spc, flags, false);
627 if (op_prio (op0) < op_prio (node))
628 pp_character (buffer, ')');
629 pp_character (buffer, '[');
630 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
631 if (TREE_CODE (node) == ARRAY_RANGE_REF)
632 pp_string (buffer, " ...");
633 pp_character (buffer, ']');
635 if ((TREE_OPERAND (node, 2)
636 && TREE_CODE (TREE_OPERAND (node, 2)) != INTEGER_CST)
637 || (TREE_OPERAND (node, 3)
638 && TREE_CODE (TREE_OPERAND (node, 3)) != INTEGER_CST))
640 pp_string (buffer, "{lb: ");
641 dump_generic_node (buffer, TREE_OPERAND (node, 2),
642 spc, flags, false);
643 pp_string (buffer, " sz: ");
644 dump_generic_node (buffer, TREE_OPERAND (node, 3),
645 spc, flags, false);
646 pp_character (buffer, '}');
648 break;
650 case CONSTRUCTOR:
652 tree lnode;
653 bool is_struct_init = FALSE;
654 pp_character (buffer, '{');
655 lnode = CONSTRUCTOR_ELTS (node);
656 if (TREE_CODE (TREE_TYPE (node)) == RECORD_TYPE
657 || TREE_CODE (TREE_TYPE (node)) == UNION_TYPE)
658 is_struct_init = TRUE;
659 while (lnode && lnode != error_mark_node)
661 tree val;
662 if (TREE_PURPOSE (lnode) && is_struct_init)
664 pp_character (buffer, '.');
665 dump_generic_node (buffer, TREE_PURPOSE (lnode), spc, flags, false);
666 pp_string (buffer, "=");
668 val = TREE_VALUE (lnode);
669 if (val && TREE_CODE (val) == ADDR_EXPR)
670 if (TREE_CODE (TREE_OPERAND (val, 0)) == FUNCTION_DECL)
671 val = TREE_OPERAND (val, 0);
672 if (val && TREE_CODE (val) == FUNCTION_DECL)
674 dump_decl_name (buffer, val, flags);
676 else
678 dump_generic_node (buffer, TREE_VALUE (lnode), spc, flags, false);
680 lnode = TREE_CHAIN (lnode);
681 if (lnode && TREE_CODE (lnode) == TREE_LIST)
683 pp_character (buffer, ',');
684 pp_space (buffer);
687 pp_character (buffer, '}');
689 break;
691 case COMPOUND_EXPR:
693 tree *tp;
694 if (flags & TDF_SLIM)
696 pp_string (buffer, "<COMPOUND_EXPR>");
697 break;
700 dump_generic_node (buffer, TREE_OPERAND (node, 0),
701 spc, flags, dumping_stmts);
702 if (dumping_stmts)
703 newline_and_indent (buffer, spc);
704 else
706 pp_character (buffer, ',');
707 pp_space (buffer);
710 for (tp = &TREE_OPERAND (node, 1);
711 TREE_CODE (*tp) == COMPOUND_EXPR;
712 tp = &TREE_OPERAND (*tp, 1))
714 dump_generic_node (buffer, TREE_OPERAND (*tp, 0),
715 spc, flags, dumping_stmts);
716 if (dumping_stmts)
717 newline_and_indent (buffer, spc);
718 else
720 pp_character (buffer, ',');
721 pp_space (buffer);
725 dump_generic_node (buffer, *tp, spc, flags, dumping_stmts);
727 break;
729 case STATEMENT_LIST:
731 tree_stmt_iterator si;
732 bool first = true;
734 if ((flags & TDF_SLIM) || !dumping_stmts)
736 pp_string (buffer, "<STATEMENT_LIST>");
737 break;
740 for (si = tsi_start (node); !tsi_end_p (si); tsi_next (&si))
742 if (!first)
743 newline_and_indent (buffer, spc);
744 else
745 first = false;
746 dump_generic_node (buffer, tsi_stmt (si), spc, flags, true);
749 break;
751 case MODIFY_EXPR:
752 case INIT_EXPR:
753 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
754 pp_space (buffer);
755 pp_character (buffer, '=');
756 pp_space (buffer);
757 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
758 break;
760 case TARGET_EXPR:
761 pp_string (buffer, "TARGET_EXPR <");
762 dump_generic_node (buffer, TARGET_EXPR_SLOT (node), spc, flags, false);
763 pp_character (buffer, ',');
764 pp_space (buffer);
765 dump_generic_node (buffer, TARGET_EXPR_INITIAL (node), spc, flags, false);
766 pp_character (buffer, '>');
767 break;
769 case COND_EXPR:
770 if (TREE_TYPE (node) == void_type_node)
772 pp_string (buffer, "if (");
773 dump_generic_node (buffer, COND_EXPR_COND (node), spc, flags, false);
774 pp_character (buffer, ')');
775 /* The lowered cond_exprs should always be printed in full. */
776 if (COND_EXPR_THEN (node)
777 && TREE_CODE (COND_EXPR_THEN (node)) == GOTO_EXPR
778 && COND_EXPR_ELSE (node)
779 && TREE_CODE (COND_EXPR_ELSE (node)) == GOTO_EXPR)
781 pp_space (buffer);
782 dump_generic_node (buffer, COND_EXPR_THEN (node), 0, flags, true);
783 pp_string (buffer, " else ");
784 dump_generic_node (buffer, COND_EXPR_ELSE (node), 0, flags, true);
786 else if (!(flags & TDF_SLIM))
788 /* Output COND_EXPR_THEN. */
789 if (COND_EXPR_THEN (node))
791 newline_and_indent (buffer, spc+2);
792 pp_character (buffer, '{');
793 newline_and_indent (buffer, spc+4);
794 dump_generic_node (buffer, COND_EXPR_THEN (node), spc+4,
795 flags, true);
796 newline_and_indent (buffer, spc+2);
797 pp_character (buffer, '}');
800 /* Output COND_EXPR_ELSE. */
801 if (COND_EXPR_ELSE (node))
803 newline_and_indent (buffer, spc);
804 pp_string (buffer, "else");
805 newline_and_indent (buffer, spc+2);
806 pp_character (buffer, '{');
807 newline_and_indent (buffer, spc+4);
808 dump_generic_node (buffer, COND_EXPR_ELSE (node), spc+4,
809 flags, true);
810 newline_and_indent (buffer, spc+2);
811 pp_character (buffer, '}');
814 is_expr = false;
816 else
818 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
819 pp_space (buffer);
820 pp_character (buffer, '?');
821 pp_space (buffer);
822 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
823 pp_space (buffer);
824 pp_character (buffer, ':');
825 pp_space (buffer);
826 dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
828 break;
830 case BIND_EXPR:
831 pp_character (buffer, '{');
832 if (!(flags & TDF_SLIM))
834 if (BIND_EXPR_VARS (node))
836 pp_newline (buffer);
838 for (op0 = BIND_EXPR_VARS (node); op0; op0 = TREE_CHAIN (op0))
840 print_declaration (buffer, op0, spc+2, flags);
841 pp_newline (buffer);
845 newline_and_indent (buffer, spc+2);
846 dump_generic_node (buffer, BIND_EXPR_BODY (node), spc+2, flags, true);
847 newline_and_indent (buffer, spc);
848 pp_character (buffer, '}');
850 is_expr = false;
851 break;
853 case CALL_EXPR:
854 print_call_name (buffer, node);
856 /* Print parameters. */
857 pp_space (buffer);
858 pp_character (buffer, '(');
859 op1 = TREE_OPERAND (node, 1);
860 if (op1)
861 dump_generic_node (buffer, op1, spc, flags, false);
862 pp_character (buffer, ')');
864 op1 = TREE_OPERAND (node, 2);
865 if (op1)
867 pp_string (buffer, " [static-chain: ");
868 dump_generic_node (buffer, op1, spc, flags, false);
869 pp_character (buffer, ']');
872 if (CALL_EXPR_TAILCALL (node))
873 pp_string (buffer, " [tail call]");
874 break;
876 case WITH_CLEANUP_EXPR:
877 NIY;
878 break;
880 case CLEANUP_POINT_EXPR:
881 pp_string (buffer, "<<cleanup_point ");
882 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
883 pp_string (buffer, ">>");
884 break;
886 case PLACEHOLDER_EXPR:
887 NIY;
888 break;
890 /* Binary arithmetic and logic expressions. */
891 case MULT_EXPR:
892 case PLUS_EXPR:
893 case MINUS_EXPR:
894 case TRUNC_DIV_EXPR:
895 case CEIL_DIV_EXPR:
896 case FLOOR_DIV_EXPR:
897 case ROUND_DIV_EXPR:
898 case TRUNC_MOD_EXPR:
899 case CEIL_MOD_EXPR:
900 case FLOOR_MOD_EXPR:
901 case ROUND_MOD_EXPR:
902 case RDIV_EXPR:
903 case EXACT_DIV_EXPR:
904 case LSHIFT_EXPR:
905 case RSHIFT_EXPR:
906 case LROTATE_EXPR:
907 case RROTATE_EXPR:
908 case BIT_IOR_EXPR:
909 case BIT_XOR_EXPR:
910 case BIT_AND_EXPR:
911 case TRUTH_ANDIF_EXPR:
912 case TRUTH_ORIF_EXPR:
913 case TRUTH_AND_EXPR:
914 case TRUTH_OR_EXPR:
915 case TRUTH_XOR_EXPR:
916 case LT_EXPR:
917 case LE_EXPR:
918 case GT_EXPR:
919 case GE_EXPR:
920 case EQ_EXPR:
921 case NE_EXPR:
922 case UNLT_EXPR:
923 case UNLE_EXPR:
924 case UNGT_EXPR:
925 case UNGE_EXPR:
926 case UNEQ_EXPR:
927 case LTGT_EXPR:
928 case ORDERED_EXPR:
929 case UNORDERED_EXPR:
931 const char *op = op_symbol (node);
932 op0 = TREE_OPERAND (node, 0);
933 op1 = TREE_OPERAND (node, 1);
935 /* When the operands are expressions with less priority,
936 keep semantics of the tree representation. */
937 if (op_prio (op0) < op_prio (node))
939 pp_character (buffer, '(');
940 dump_generic_node (buffer, op0, spc, flags, false);
941 pp_character (buffer, ')');
943 else
944 dump_generic_node (buffer, op0, spc, flags, false);
946 pp_space (buffer);
947 pp_string (buffer, op);
948 pp_space (buffer);
950 /* When the operands are expressions with less priority,
951 keep semantics of the tree representation. */
952 if (op_prio (op1) < op_prio (node))
954 pp_character (buffer, '(');
955 dump_generic_node (buffer, op1, spc, flags, false);
956 pp_character (buffer, ')');
958 else
959 dump_generic_node (buffer, op1, spc, flags, false);
961 break;
963 /* Unary arithmetic and logic expressions. */
964 case NEGATE_EXPR:
965 case BIT_NOT_EXPR:
966 case TRUTH_NOT_EXPR:
967 case ADDR_EXPR:
968 case REFERENCE_EXPR:
969 case PREDECREMENT_EXPR:
970 case PREINCREMENT_EXPR:
971 case INDIRECT_REF:
972 if (TREE_CODE (node) == ADDR_EXPR
973 && (TREE_CODE (TREE_OPERAND (node, 0)) == STRING_CST
974 || TREE_CODE (TREE_OPERAND (node, 0)) == FUNCTION_DECL))
975 ; /* Do not output '&' for strings and function pointers. */
976 else
977 pp_string (buffer, op_symbol (node));
979 if (op_prio (TREE_OPERAND (node, 0)) < op_prio (node))
981 pp_character (buffer, '(');
982 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
983 pp_character (buffer, ')');
985 else
986 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
987 break;
989 case POSTDECREMENT_EXPR:
990 case POSTINCREMENT_EXPR:
991 if (op_prio (TREE_OPERAND (node, 0)) < op_prio (node))
993 pp_character (buffer, '(');
994 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
995 pp_character (buffer, ')');
997 else
998 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
999 pp_string (buffer, op_symbol (node));
1000 break;
1002 case MIN_EXPR:
1003 pp_string (buffer, "MIN_EXPR <");
1004 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1005 pp_string (buffer, ", ");
1006 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1007 pp_character (buffer, '>');
1008 break;
1010 case MAX_EXPR:
1011 pp_string (buffer, "MAX_EXPR <");
1012 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1013 pp_string (buffer, ", ");
1014 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1015 pp_character (buffer, '>');
1016 break;
1018 case ABS_EXPR:
1019 pp_string (buffer, "ABS_EXPR <");
1020 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1021 pp_character (buffer, '>');
1022 break;
1024 case IN_EXPR:
1025 NIY;
1026 break;
1028 case SET_LE_EXPR:
1029 NIY;
1030 break;
1032 case CARD_EXPR:
1033 NIY;
1034 break;
1036 case RANGE_EXPR:
1037 NIY;
1038 break;
1040 case FIX_TRUNC_EXPR:
1041 case FIX_CEIL_EXPR:
1042 case FIX_FLOOR_EXPR:
1043 case FIX_ROUND_EXPR:
1044 case FLOAT_EXPR:
1045 case CONVERT_EXPR:
1046 case NOP_EXPR:
1047 type = TREE_TYPE (node);
1048 op0 = TREE_OPERAND (node, 0);
1049 if (type != TREE_TYPE (op0))
1051 pp_character (buffer, '(');
1052 dump_generic_node (buffer, type, spc, flags, false);
1053 pp_string (buffer, ")");
1055 if (op_prio (op0) < op_prio (node))
1056 pp_character (buffer, '(');
1057 dump_generic_node (buffer, op0, spc, flags, false);
1058 if (op_prio (op0) < op_prio (node))
1059 pp_character (buffer, ')');
1060 break;
1062 case VIEW_CONVERT_EXPR:
1063 pp_string (buffer, "VIEW_CONVERT_EXPR<");
1064 dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
1065 pp_string (buffer, ">(");
1066 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1067 pp_character (buffer, ')');
1068 break;
1070 case NON_LVALUE_EXPR:
1071 pp_string (buffer, "NON_LVALUE_EXPR <");
1072 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1073 pp_character (buffer, '>');
1074 break;
1076 case SAVE_EXPR:
1077 pp_string (buffer, "SAVE_EXPR <");
1078 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1079 pp_character (buffer, '>');
1080 break;
1082 case UNSAVE_EXPR:
1083 pp_string (buffer, "UNSAVE_EXPR <");
1084 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1085 pp_character (buffer, '>');
1086 break;
1088 case RTL_EXPR:
1089 NIY;
1090 break;
1092 case ENTRY_VALUE_EXPR:
1093 NIY;
1094 break;
1096 case COMPLEX_EXPR:
1097 pp_string (buffer, "COMPLEX_EXPR <");
1098 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1099 pp_string (buffer, ", ");
1100 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1101 pp_string (buffer, ">");
1102 break;
1104 case CONJ_EXPR:
1105 pp_string (buffer, "CONJ_EXPR <");
1106 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1107 pp_string (buffer, ">");
1108 break;
1110 case REALPART_EXPR:
1111 pp_string (buffer, "REALPART_EXPR <");
1112 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1113 pp_string (buffer, ">");
1114 break;
1116 case IMAGPART_EXPR:
1117 pp_string (buffer, "IMAGPART_EXPR <");
1118 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1119 pp_string (buffer, ">");
1120 break;
1122 case VA_ARG_EXPR:
1123 pp_string (buffer, "VA_ARG_EXPR <");
1124 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1125 pp_string (buffer, ">");
1126 break;
1128 case TRY_FINALLY_EXPR:
1129 case TRY_CATCH_EXPR:
1130 pp_string (buffer, "try");
1131 newline_and_indent (buffer, spc+2);
1132 pp_string (buffer, "{");
1133 newline_and_indent (buffer, spc+4);
1134 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc+4, flags, true);
1135 newline_and_indent (buffer, spc+2);
1136 pp_string (buffer, "}");
1137 newline_and_indent (buffer, spc);
1138 pp_string (buffer,
1139 (TREE_CODE (node) == TRY_CATCH_EXPR) ? "catch" : "finally");
1140 newline_and_indent (buffer, spc+2);
1141 pp_string (buffer, "{");
1142 newline_and_indent (buffer, spc+4);
1143 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc+4, flags, true);
1144 newline_and_indent (buffer, spc+2);
1145 pp_string (buffer, "}");
1146 is_expr = false;
1147 break;
1149 case CATCH_EXPR:
1150 pp_string (buffer, "catch (");
1151 dump_generic_node (buffer, CATCH_TYPES (node), spc+2, flags, false);
1152 pp_string (buffer, ")");
1153 newline_and_indent (buffer, spc+2);
1154 pp_string (buffer, "{");
1155 newline_and_indent (buffer, spc+4);
1156 dump_generic_node (buffer, CATCH_BODY (node), spc+4, flags, true);
1157 newline_and_indent (buffer, spc+2);
1158 pp_string (buffer, "}");
1159 is_expr = false;
1160 break;
1162 case EH_FILTER_EXPR:
1163 pp_string (buffer, "<<<eh_filter (");
1164 dump_generic_node (buffer, EH_FILTER_TYPES (node), spc+2, flags, false);
1165 pp_string (buffer, ")>>>");
1166 newline_and_indent (buffer, spc+2);
1167 pp_string (buffer, "{");
1168 newline_and_indent (buffer, spc+4);
1169 dump_generic_node (buffer, EH_FILTER_FAILURE (node), spc+4, flags, true);
1170 newline_and_indent (buffer, spc+2);
1171 pp_string (buffer, "}");
1172 is_expr = false;
1173 break;
1175 case GOTO_SUBROUTINE_EXPR:
1176 NIY;
1177 break;
1179 case LABEL_EXPR:
1180 op0 = TREE_OPERAND (node, 0);
1181 /* If this is for break or continue, don't bother printing it. */
1182 if (DECL_NAME (op0))
1184 const char *name = IDENTIFIER_POINTER (DECL_NAME (op0));
1185 if (strcmp (name, "break") == 0
1186 || strcmp (name, "continue") == 0)
1187 break;
1189 dump_generic_node (buffer, op0, spc, flags, false);
1190 pp_character (buffer, ':');
1191 if (DECL_NONLOCAL (op0))
1192 pp_string (buffer, " [non-local]");
1193 break;
1195 case LABELED_BLOCK_EXPR:
1196 op0 = LABELED_BLOCK_LABEL (node);
1197 /* If this is for break or continue, don't bother printing it. */
1198 if (DECL_NAME (op0))
1200 const char *name = IDENTIFIER_POINTER (DECL_NAME (op0));
1201 if (strcmp (name, "break") == 0
1202 || strcmp (name, "continue") == 0)
1204 dump_generic_node (buffer, LABELED_BLOCK_BODY (node), spc, flags, false);
1205 break;
1208 dump_generic_node (buffer, LABELED_BLOCK_LABEL (node), spc, flags, false);
1209 pp_string (buffer, ": {");
1210 if (!(flags & TDF_SLIM))
1211 newline_and_indent (buffer, spc+2);
1212 dump_generic_node (buffer, LABELED_BLOCK_BODY (node), spc+2, flags, true);
1213 if (!flags)
1214 newline_and_indent (buffer, spc);
1215 pp_character (buffer, '}');
1216 is_expr = false;
1217 break;
1219 case EXIT_BLOCK_EXPR:
1220 op0 = LABELED_BLOCK_LABEL (EXIT_BLOCK_LABELED_BLOCK (node));
1221 /* If this is for a break or continue, print it accordingly. */
1222 if (DECL_NAME (op0))
1224 const char *name = IDENTIFIER_POINTER (DECL_NAME (op0));
1225 if (strcmp (name, "break") == 0
1226 || strcmp (name, "continue") == 0)
1228 pp_string (buffer, name);
1229 break;
1232 pp_string (buffer, "<<<exit block ");
1233 dump_generic_node (buffer, op0, spc, flags, false);
1234 pp_string (buffer, ">>>");
1235 break;
1237 case EXC_PTR_EXPR:
1238 pp_string (buffer, "<<<exception object>>>");
1239 break;
1241 case FILTER_EXPR:
1242 pp_string (buffer, "<<<filter object>>>");
1243 break;
1245 case LOOP_EXPR:
1246 pp_string (buffer, "while (1)");
1247 if (!(flags & TDF_SLIM))
1249 newline_and_indent (buffer, spc+2);
1250 pp_character (buffer, '{');
1251 newline_and_indent (buffer, spc+4);
1252 dump_generic_node (buffer, LOOP_EXPR_BODY (node), spc+4, flags, true);
1253 newline_and_indent (buffer, spc+2);
1254 pp_character (buffer, '}');
1256 is_expr = false;
1257 break;
1259 case RETURN_EXPR:
1260 pp_string (buffer, "return");
1261 op0 = TREE_OPERAND (node, 0);
1262 if (op0)
1264 pp_space (buffer);
1265 if (TREE_CODE (op0) == MODIFY_EXPR)
1266 dump_generic_node (buffer, TREE_OPERAND (op0, 1), spc, flags, false);
1267 else
1268 dump_generic_node (buffer, op0, spc, flags, false);
1270 break;
1272 case EXIT_EXPR:
1273 pp_string (buffer, "if (");
1274 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1275 pp_string (buffer, ") break");
1276 break;
1278 case SWITCH_EXPR:
1279 pp_string (buffer, "switch (");
1280 dump_generic_node (buffer, SWITCH_COND (node), spc, flags, false);
1281 pp_character (buffer, ')');
1282 if (!(flags & TDF_SLIM))
1284 newline_and_indent (buffer, spc+2);
1285 pp_character (buffer, '{');
1286 if (SWITCH_BODY (node))
1288 newline_and_indent (buffer, spc+4);
1289 dump_generic_node (buffer, SWITCH_BODY (node), spc+4, flags, true);
1291 else
1293 tree vec = SWITCH_LABELS (node);
1294 size_t i, n = TREE_VEC_LENGTH (vec);
1295 for (i = 0; i < n; ++i)
1297 tree elt = TREE_VEC_ELT (vec, i);
1298 newline_and_indent (buffer, spc+4);
1299 dump_generic_node (buffer, elt, spc+4, flags, false);
1300 pp_string (buffer, " goto ");
1301 dump_generic_node (buffer, CASE_LABEL (elt), spc+4, flags, true);
1302 pp_semicolon (buffer);
1305 newline_and_indent (buffer, spc+2);
1306 pp_character (buffer, '}');
1308 is_expr = false;
1309 break;
1311 case GOTO_EXPR:
1312 op0 = GOTO_DESTINATION (node);
1313 if (TREE_CODE (op0) != SSA_NAME
1314 && DECL_P (op0)
1315 && DECL_NAME (op0))
1317 const char *name = IDENTIFIER_POINTER (DECL_NAME (op0));
1318 if (strcmp (name, "break") == 0
1319 || strcmp (name, "continue") == 0)
1321 pp_string (buffer, name);
1322 break;
1325 pp_string (buffer, "goto ");
1326 dump_generic_node (buffer, op0, spc, flags, false);
1327 break;
1329 case RESX_EXPR:
1330 pp_string (buffer, "resx");
1331 /* ??? Any sensible way to present the eh region? */
1332 break;
1334 case ASM_EXPR:
1335 pp_string (buffer, "__asm__");
1336 if (ASM_VOLATILE_P (node))
1337 pp_string (buffer, " __volatile__");
1338 pp_character (buffer, '(');
1339 dump_generic_node (buffer, ASM_STRING (node), spc, flags, false);
1340 pp_character (buffer, ':');
1341 dump_generic_node (buffer, ASM_OUTPUTS (node), spc, flags, false);
1342 pp_character (buffer, ':');
1343 dump_generic_node (buffer, ASM_INPUTS (node), spc, flags, false);
1344 if (ASM_CLOBBERS (node))
1346 pp_character (buffer, ':');
1347 dump_generic_node (buffer, ASM_CLOBBERS (node), spc, flags, false);
1349 pp_string (buffer, ")");
1350 break;
1352 case CASE_LABEL_EXPR:
1353 if (CASE_LOW (node) && CASE_HIGH (node))
1355 pp_string (buffer, "case ");
1356 dump_generic_node (buffer, CASE_LOW (node), spc, flags, false);
1357 pp_string (buffer, " ... ");
1358 dump_generic_node (buffer, CASE_HIGH (node), spc, flags, false);
1360 else if (CASE_LOW (node))
1362 pp_string (buffer, "case ");
1363 dump_generic_node (buffer, CASE_LOW (node), spc, flags, false);
1365 else
1366 pp_string (buffer, "default ");
1367 pp_character (buffer, ':');
1368 break;
1370 case VTABLE_REF:
1371 pp_string (buffer, "VTABLE_REF <(");
1372 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1373 pp_string (buffer, "),");
1374 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1375 pp_character (buffer, ',');
1376 dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
1377 pp_character (buffer, '>');
1378 break;
1380 case PHI_NODE:
1382 int i;
1384 dump_generic_node (buffer, PHI_RESULT (node), spc, flags, false);
1385 pp_string (buffer, " = PHI <");
1386 for (i = 0; i < PHI_NUM_ARGS (node); i++)
1388 dump_generic_node (buffer, PHI_ARG_DEF (node, i), spc, flags, false);
1389 pp_string (buffer, "(");
1390 pp_decimal_int (buffer, PHI_ARG_EDGE (node, i)->src->index);
1391 pp_string (buffer, ")");
1392 if (i < PHI_NUM_ARGS (node) - 1)
1393 pp_string (buffer, ", ");
1395 pp_string (buffer, ">;");
1397 break;
1399 case SSA_NAME:
1400 dump_generic_node (buffer, SSA_NAME_VAR (node), spc, flags, false);
1401 pp_string (buffer, "_");
1402 pp_decimal_int (buffer, SSA_NAME_VERSION (node));
1403 break;
1405 default:
1406 NIY;
1409 if (is_stmt && is_expr)
1410 pp_semicolon (buffer);
1411 pp_write_text_to_stream (buffer);
1413 return spc;
1416 /* Print the declaration of a variable. */
1418 static void
1419 print_declaration (pretty_printer *buffer, tree t, int spc, int flags)
1421 /* Don't print type declarations. */
1422 if (TREE_CODE (t) == TYPE_DECL)
1423 return;
1425 INDENT (spc);
1427 if (DECL_REGISTER (t))
1428 pp_string (buffer, "register ");
1430 if (TREE_PUBLIC (t) && DECL_EXTERNAL (t))
1431 pp_string (buffer, "extern ");
1432 else if (TREE_STATIC (t))
1433 pp_string (buffer, "static ");
1435 /* Print the type and name. */
1436 if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
1438 tree tmp;
1440 /* Print array's type. */
1441 tmp = TREE_TYPE (t);
1442 while (TREE_CODE (TREE_TYPE (tmp)) == ARRAY_TYPE)
1443 tmp = TREE_TYPE (tmp);
1444 dump_generic_node (buffer, TREE_TYPE (tmp), spc, flags, false);
1446 /* Print variable's name. */
1447 pp_space (buffer);
1448 dump_generic_node (buffer, t, spc, flags, false);
1450 /* Print the dimensions. */
1451 tmp = TREE_TYPE (t);
1452 while (TREE_CODE (tmp) == ARRAY_TYPE)
1454 pp_character (buffer, '[');
1455 if (TYPE_DOMAIN (tmp))
1457 if (TREE_CODE (TYPE_SIZE (tmp)) == INTEGER_CST)
1458 pp_wide_integer (buffer,
1459 TREE_INT_CST_LOW (TYPE_SIZE (tmp)) /
1460 TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (tmp))));
1461 else
1462 dump_generic_node (buffer, TYPE_SIZE_UNIT (tmp), spc, flags,
1463 false);
1465 pp_character (buffer, ']');
1466 tmp = TREE_TYPE (tmp);
1469 else
1471 /* Print type declaration. */
1472 dump_generic_node (buffer, TREE_TYPE (t), spc, flags, false);
1474 /* Print variable's name. */
1475 pp_space (buffer);
1476 dump_generic_node (buffer, t, spc, flags, false);
1479 /* The initial value of a function serves to determine wether the function
1480 is declared or defined. So the following does not apply to function
1481 nodes. */
1482 if (TREE_CODE (t) != FUNCTION_DECL)
1484 /* Print the initial value. */
1485 if (DECL_INITIAL (t))
1487 pp_space (buffer);
1488 pp_character (buffer, '=');
1489 pp_space (buffer);
1490 dump_generic_node (buffer, DECL_INITIAL (t), spc, flags, false);
1494 pp_character (buffer, ';');
1498 /* Prints a structure: name, fields, and methods.
1499 FIXME: Still incomplete. */
1501 static void
1502 print_struct_decl (pretty_printer *buffer, tree node, int spc, int flags)
1504 /* Print the name of the structure. */
1505 if (TYPE_NAME (node))
1507 INDENT (spc);
1508 if (TREE_CODE (node) == RECORD_TYPE)
1509 pp_string (buffer, "struct ");
1510 else if ((TREE_CODE (node) == UNION_TYPE
1511 || TREE_CODE (node) == QUAL_UNION_TYPE))
1512 pp_string (buffer, "union ");
1514 dump_generic_node (buffer, TYPE_NAME (node), spc, 0, false);
1517 /* Print the contents of the structure. */
1518 pp_newline (buffer);
1519 INDENT (spc);
1520 pp_character (buffer, '{');
1521 pp_newline (buffer);
1523 /* Print the fields of the structure. */
1525 tree tmp;
1526 tmp = TYPE_FIELDS (node);
1527 while (tmp)
1529 /* Avoid to print recursively the structure. */
1530 /* FIXME : Not implemented correctly...,
1531 what about the case when we have a cycle in the contain graph? ...
1532 Maybe this could be solved by looking at the scope in which the
1533 structure was declared. */
1534 if (TREE_TYPE (tmp) != node
1535 || (TREE_CODE (TREE_TYPE (tmp)) == POINTER_TYPE
1536 && TREE_TYPE (TREE_TYPE (tmp)) != node))
1538 print_declaration (buffer, tmp, spc+2, flags);
1539 pp_newline (buffer);
1541 else
1545 tmp = TREE_CHAIN (tmp);
1548 INDENT (spc);
1549 pp_character (buffer, '}');
1552 /* Return the priority of the operator OP.
1554 From lowest to highest precedence with either left-to-right (L-R)
1555 or right-to-left (R-L) associativity]:
1557 1 [L-R] ,
1558 2 [R-L] = += -= *= /= %= &= ^= |= <<= >>=
1559 3 [R-L] ?:
1560 4 [L-R] ||
1561 5 [L-R] &&
1562 6 [L-R] |
1563 7 [L-R] ^
1564 8 [L-R] &
1565 9 [L-R] == !=
1566 10 [L-R] < <= > >=
1567 11 [L-R] << >>
1568 12 [L-R] + -
1569 13 [L-R] * / %
1570 14 [R-L] ! ~ ++ -- + - * & (type) sizeof
1571 15 [L-R] fn() [] -> .
1573 unary +, - and * have higher precedence than the corresponding binary
1574 operators. */
1576 static int
1577 op_prio (tree op)
1579 if (op == NULL)
1580 return 9999;
1582 switch (TREE_CODE (op))
1584 case TREE_LIST:
1585 case COMPOUND_EXPR:
1586 case BIND_EXPR:
1587 return 1;
1589 case MODIFY_EXPR:
1590 case INIT_EXPR:
1591 return 2;
1593 case COND_EXPR:
1594 return 3;
1596 case TRUTH_OR_EXPR:
1597 case TRUTH_ORIF_EXPR:
1598 return 4;
1600 case TRUTH_AND_EXPR:
1601 case TRUTH_ANDIF_EXPR:
1602 return 5;
1604 case BIT_IOR_EXPR:
1605 return 6;
1607 case BIT_XOR_EXPR:
1608 case TRUTH_XOR_EXPR:
1609 return 7;
1611 case BIT_AND_EXPR:
1612 return 8;
1614 case EQ_EXPR:
1615 case NE_EXPR:
1616 return 9;
1618 case UNLT_EXPR:
1619 case UNLE_EXPR:
1620 case UNGT_EXPR:
1621 case UNGE_EXPR:
1622 case UNEQ_EXPR:
1623 case LTGT_EXPR:
1624 case ORDERED_EXPR:
1625 case UNORDERED_EXPR:
1626 case LT_EXPR:
1627 case LE_EXPR:
1628 case GT_EXPR:
1629 case GE_EXPR:
1630 return 10;
1632 case LSHIFT_EXPR:
1633 case RSHIFT_EXPR:
1634 case LROTATE_EXPR:
1635 case RROTATE_EXPR:
1636 return 11;
1638 case PLUS_EXPR:
1639 case MINUS_EXPR:
1640 return 12;
1642 case MULT_EXPR:
1643 case TRUNC_DIV_EXPR:
1644 case CEIL_DIV_EXPR:
1645 case FLOOR_DIV_EXPR:
1646 case ROUND_DIV_EXPR:
1647 case RDIV_EXPR:
1648 case EXACT_DIV_EXPR:
1649 case TRUNC_MOD_EXPR:
1650 case CEIL_MOD_EXPR:
1651 case FLOOR_MOD_EXPR:
1652 case ROUND_MOD_EXPR:
1653 return 13;
1655 case TRUTH_NOT_EXPR:
1656 case BIT_NOT_EXPR:
1657 case POSTINCREMENT_EXPR:
1658 case POSTDECREMENT_EXPR:
1659 case PREINCREMENT_EXPR:
1660 case PREDECREMENT_EXPR:
1661 case NEGATE_EXPR:
1662 case INDIRECT_REF:
1663 case ADDR_EXPR:
1664 case FLOAT_EXPR:
1665 case NOP_EXPR:
1666 case CONVERT_EXPR:
1667 case FIX_TRUNC_EXPR:
1668 case FIX_CEIL_EXPR:
1669 case FIX_FLOOR_EXPR:
1670 case FIX_ROUND_EXPR:
1671 case TARGET_EXPR:
1672 return 14;
1674 case CALL_EXPR:
1675 case ARRAY_REF:
1676 case ARRAY_RANGE_REF:
1677 case COMPONENT_REF:
1678 return 15;
1680 /* Special expressions. */
1681 case MIN_EXPR:
1682 case MAX_EXPR:
1683 case ABS_EXPR:
1684 case REALPART_EXPR:
1685 case IMAGPART_EXPR:
1686 return 16;
1688 case SAVE_EXPR:
1689 case NON_LVALUE_EXPR:
1690 return op_prio (TREE_OPERAND (op, 0));
1692 default:
1693 /* Return an arbitrarily high precedence to avoid surrounding single
1694 VAR_DECLs in ()s. */
1695 return 9999;
1700 /* Return the symbol associated with operator OP. */
1702 static const char *
1703 op_symbol (tree op)
1705 if (op == NULL)
1706 abort ();
1708 switch (TREE_CODE (op))
1710 case MODIFY_EXPR:
1711 return "=";
1713 case TRUTH_OR_EXPR:
1714 case TRUTH_ORIF_EXPR:
1715 return "||";
1717 case TRUTH_AND_EXPR:
1718 case TRUTH_ANDIF_EXPR:
1719 return "&&";
1721 case BIT_IOR_EXPR:
1722 return "|";
1724 case TRUTH_XOR_EXPR:
1725 case BIT_XOR_EXPR:
1726 return "^";
1728 case ADDR_EXPR:
1729 case BIT_AND_EXPR:
1730 return "&";
1732 case ORDERED_EXPR:
1733 return "ord";
1734 case UNORDERED_EXPR:
1735 return "unord";
1737 case EQ_EXPR:
1738 return "==";
1739 case UNEQ_EXPR:
1740 return "u==";
1742 case NE_EXPR:
1743 return "!=";
1745 case LT_EXPR:
1746 return "<";
1747 case UNLT_EXPR:
1748 return "u<";
1750 case LE_EXPR:
1751 return "<=";
1752 case UNLE_EXPR:
1753 return "u<=";
1755 case GT_EXPR:
1756 return ">";
1757 case UNGT_EXPR:
1758 return "u>";
1760 case GE_EXPR:
1761 return ">=";
1762 case UNGE_EXPR:
1763 return "u>=";
1765 case LTGT_EXPR:
1766 return "<>";
1768 case LSHIFT_EXPR:
1769 return "<<";
1771 case RSHIFT_EXPR:
1772 return ">>";
1774 case PLUS_EXPR:
1775 return "+";
1777 case NEGATE_EXPR:
1778 case MINUS_EXPR:
1779 return "-";
1781 case BIT_NOT_EXPR:
1782 return "~";
1784 case TRUTH_NOT_EXPR:
1785 return "!";
1787 case MULT_EXPR:
1788 case INDIRECT_REF:
1789 return "*";
1791 case TRUNC_DIV_EXPR:
1792 case CEIL_DIV_EXPR:
1793 case FLOOR_DIV_EXPR:
1794 case ROUND_DIV_EXPR:
1795 case RDIV_EXPR:
1796 case EXACT_DIV_EXPR:
1797 return "/";
1799 case TRUNC_MOD_EXPR:
1800 case CEIL_MOD_EXPR:
1801 case FLOOR_MOD_EXPR:
1802 case ROUND_MOD_EXPR:
1803 return "%";
1805 case PREDECREMENT_EXPR:
1806 return " --";
1808 case PREINCREMENT_EXPR:
1809 return " ++";
1811 case POSTDECREMENT_EXPR:
1812 return "-- ";
1814 case POSTINCREMENT_EXPR:
1815 return "++ ";
1817 case REFERENCE_EXPR:
1818 return "";
1820 default:
1821 return "<<< ??? >>>";
1825 /* Prints the name of a CALL_EXPR. */
1827 static void
1828 print_call_name (pretty_printer *buffer, tree node)
1830 tree op0;
1832 if (TREE_CODE (node) != CALL_EXPR)
1833 abort ();
1835 op0 = TREE_OPERAND (node, 0);
1837 if (TREE_CODE (op0) == NON_LVALUE_EXPR)
1838 op0 = TREE_OPERAND (op0, 0);
1840 switch (TREE_CODE (op0))
1842 case VAR_DECL:
1843 case PARM_DECL:
1844 PRINT_FUNCTION_NAME (op0);
1845 break;
1847 case ADDR_EXPR:
1848 case INDIRECT_REF:
1849 case NOP_EXPR:
1850 dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
1851 break;
1853 case COND_EXPR:
1854 pp_string (buffer, "(");
1855 dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
1856 pp_string (buffer, ") ? ");
1857 dump_generic_node (buffer, TREE_OPERAND (op0, 1), 0, 0, false);
1858 pp_string (buffer, " : ");
1859 dump_generic_node (buffer, TREE_OPERAND (op0, 2), 0, 0, false);
1860 break;
1862 case COMPONENT_REF:
1863 /* The function is a pointer contained in a structure. */
1864 if (TREE_CODE (TREE_OPERAND (op0, 0)) == INDIRECT_REF ||
1865 TREE_CODE (TREE_OPERAND (op0, 0)) == VAR_DECL)
1866 PRINT_FUNCTION_NAME (TREE_OPERAND (op0, 1));
1867 else
1868 dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
1869 /* else
1870 We can have several levels of structures and a function
1871 pointer inside. This is not implemented yet... */
1872 /* NIY;*/
1873 break;
1875 case ARRAY_REF:
1876 if (TREE_CODE (TREE_OPERAND (op0, 0)) == VAR_DECL)
1877 PRINT_FUNCTION_NAME (TREE_OPERAND (op0, 0));
1878 else
1879 dump_generic_node (buffer, op0, 0, 0, false);
1880 break;
1882 case SSA_NAME:
1883 dump_generic_node (buffer, op0, 0, 0, false);
1884 break;
1886 default:
1887 NIY;
1891 /* Parses the string STR and replaces new-lines by '\n', tabs by '\t', ... */
1893 static void
1894 pretty_print_string (pretty_printer *buffer, const char *str)
1896 if (str == NULL)
1897 return;
1899 while (*str)
1901 switch (str[0])
1903 case '\b':
1904 pp_string (buffer, "\\b");
1905 break;
1907 case '\f':
1908 pp_string (buffer, "\\f");
1909 break;
1911 case '\n':
1912 pp_string (buffer, "\\n");
1913 break;
1915 case '\r':
1916 pp_string (buffer, "\\r");
1917 break;
1919 case '\t':
1920 pp_string (buffer, "\\t");
1921 break;
1923 case '\v':
1924 pp_string (buffer, "\\v");
1925 break;
1927 case '\\':
1928 pp_string (buffer, "\\\\");
1929 break;
1931 case '\"':
1932 pp_string (buffer, "\\\"");
1933 break;
1935 case '\'':
1936 pp_string (buffer, "\\'");
1937 break;
1939 case '\0':
1940 pp_string (buffer, "\\0");
1941 break;
1943 case '\1':
1944 pp_string (buffer, "\\1");
1945 break;
1947 case '\2':
1948 pp_string (buffer, "\\2");
1949 break;
1951 case '\3':
1952 pp_string (buffer, "\\3");
1953 break;
1955 case '\4':
1956 pp_string (buffer, "\\4");
1957 break;
1959 case '\5':
1960 pp_string (buffer, "\\5");
1961 break;
1963 case '\6':
1964 pp_string (buffer, "\\6");
1965 break;
1967 case '\7':
1968 pp_string (buffer, "\\7");
1969 break;
1971 default:
1972 pp_character (buffer, str[0]);
1973 break;
1975 str++;
1979 static void
1980 maybe_init_pretty_print (FILE *file)
1982 if (!initialized)
1984 pp_construct (&buffer, /* prefix */NULL, /* line-width */0);
1985 pp_needs_newline (&buffer) = true;
1986 initialized = 1;
1989 buffer.buffer->stream = file;
1992 static void
1993 newline_and_indent (pretty_printer *buffer, int spc)
1995 pp_newline (buffer);
1996 INDENT (spc);
1999 static void
2000 dump_vops (pretty_printer *buffer, tree stmt, int spc, int flags)
2002 size_t i;
2003 stmt_ann_t ann = stmt_ann (stmt);
2004 v_may_def_optype v_may_defs = V_MAY_DEF_OPS (ann);
2005 v_must_def_optype v_must_defs = V_MUST_DEF_OPS (ann);
2006 vuse_optype vuses = VUSE_OPS (ann);
2008 for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++)
2010 pp_string (buffer, "# ");
2011 dump_generic_node (buffer, V_MAY_DEF_RESULT (v_may_defs, i),
2012 spc + 2, flags, false);
2013 pp_string (buffer, " = V_MAY_DEF <");
2014 dump_generic_node (buffer, V_MAY_DEF_OP (v_may_defs, i),
2015 spc + 2, flags, false);
2016 pp_string (buffer, ">;");
2017 newline_and_indent (buffer, spc);
2020 for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++)
2022 tree v_must_def = V_MUST_DEF_OP (v_must_defs, i);
2023 pp_string (buffer, "# V_MUST_DEF <");
2024 dump_generic_node (buffer, v_must_def, spc + 2, flags, false);
2025 pp_string (buffer, ">;");
2026 newline_and_indent (buffer, spc);
2029 for (i = 0; i < NUM_VUSES (vuses); i++)
2031 tree vuse = VUSE_OP (vuses, i);
2032 pp_string (buffer, "# VUSE <");
2033 dump_generic_node (buffer, vuse, spc + 2, flags, false);
2034 pp_string (buffer, ">;");
2035 newline_and_indent (buffer, spc);
2039 /* Dumps basic block BB to FILE with details described by FLAGS and
2040 indented by INDENT spaces. */
2042 void
2043 dump_generic_bb (FILE *file, basic_block bb, int indent, int flags)
2045 maybe_init_pretty_print (file);
2046 dumping_stmts = true;
2047 dump_generic_bb_buff (&buffer, bb, indent, flags);
2048 pp_flush (&buffer);
2051 /* Dumps header of basic block BB to buffer BUFFER indented by INDENT
2052 spaces and details described by flags. */
2054 static void
2055 dump_bb_header (pretty_printer *buffer, basic_block bb, int indent, int flags)
2057 edge e;
2058 tree stmt;
2060 if (flags & TDF_BLOCKS)
2062 INDENT (indent);
2063 pp_string (buffer, "# BLOCK ");
2064 pp_decimal_int (buffer, bb->index);
2066 if (flags & TDF_LINENO)
2068 block_stmt_iterator bsi;
2070 for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
2071 if (get_lineno (bsi_stmt (bsi)) != -1)
2073 pp_string (buffer, ", starting at line ");
2074 pp_decimal_int (buffer, get_lineno (bsi_stmt (bsi)));
2075 break;
2078 newline_and_indent (buffer, indent);
2080 pp_string (buffer, "# PRED:");
2081 pp_write_text_to_stream (buffer);
2082 for (e = bb->pred; e; e = e->pred_next)
2083 if (flags & TDF_SLIM)
2085 pp_string (buffer, " ");
2086 if (e->src == ENTRY_BLOCK_PTR)
2087 pp_string (buffer, "ENTRY");
2088 else
2089 pp_decimal_int (buffer, e->src->index);
2091 else
2092 dump_edge_info (buffer->buffer->stream, e, 0);
2093 pp_newline (buffer);
2095 else
2097 stmt = first_stmt (bb);
2098 if (!stmt || TREE_CODE (stmt) != LABEL_EXPR)
2100 INDENT (indent - 2);
2101 pp_string (buffer, "<bb ");
2102 pp_decimal_int (buffer, bb->index);
2103 pp_string (buffer, ">:");
2104 pp_newline (buffer);
2109 /* Dumps end of basic block BB to buffer BUFFER indented by INDENT
2110 spaces. */
2112 static void
2113 dump_bb_end (pretty_printer *buffer, basic_block bb, int indent, int flags)
2115 edge e;
2117 INDENT (indent);
2118 pp_string (buffer, "# SUCC:");
2119 pp_write_text_to_stream (buffer);
2120 for (e = bb->succ; e; e = e->succ_next)
2121 if (flags & TDF_SLIM)
2123 pp_string (buffer, " ");
2124 if (e->dest == EXIT_BLOCK_PTR)
2125 pp_string (buffer, "EXIT");
2126 else
2127 pp_decimal_int (buffer, e->dest->index);
2129 else
2130 dump_edge_info (buffer->buffer->stream, e, 1);
2131 pp_newline (buffer);
2134 /* Dumps phi nodes of basic block BB to buffer BUFFER with details described by
2135 FLAGS indented by INDENT spaces. */
2137 static void
2138 dump_phi_nodes (pretty_printer *buffer, basic_block bb, int indent, int flags)
2140 tree phi = phi_nodes (bb);
2141 if (!phi)
2142 return;
2144 for (; phi; phi = PHI_CHAIN (phi))
2146 if (is_gimple_reg (PHI_RESULT (phi)) || (flags & TDF_VOPS))
2148 INDENT (indent);
2149 pp_string (buffer, "# ");
2150 dump_generic_node (buffer, phi, indent, flags, false);
2151 pp_newline (buffer);
2156 /* Dump jump to basic block BB that is represented implicitly in the cfg
2157 to BUFFER. */
2159 static void
2160 pp_cfg_jump (pretty_printer *buffer, basic_block bb)
2162 tree stmt;
2164 stmt = first_stmt (bb);
2166 pp_string (buffer, "goto <bb ");
2167 pp_decimal_int (buffer, bb->index);
2168 pp_string (buffer, ">");
2169 if (stmt && TREE_CODE (stmt) == LABEL_EXPR)
2171 pp_string (buffer, " (");
2172 dump_generic_node (buffer, LABEL_EXPR_LABEL (stmt), 0, 0, false);
2173 pp_string (buffer, ")");
2175 pp_semicolon (buffer);
2178 /* Dump edges represented implicitly in basic block BB to BUFFER, indented
2179 by INDENT spaces, with details given by FLAGS. */
2181 static void
2182 dump_implicit_edges (pretty_printer *buffer, basic_block bb, int indent,
2183 int flags)
2185 edge e;
2187 /* If there is a fallthru edge, we may need to add an artificial goto to the
2188 dump. */
2189 for (e = bb->succ; e; e = e->succ_next)
2190 if (e->flags & EDGE_FALLTHRU)
2191 break;
2192 if (e && e->dest != bb->next_bb)
2194 INDENT (indent);
2196 if ((flags & TDF_LINENO) && e->goto_locus)
2198 pp_character (buffer, '[');
2199 if (e->goto_locus->file)
2201 pp_string (buffer, e->goto_locus->file);
2202 pp_string (buffer, " : ");
2204 pp_decimal_int (buffer, e->goto_locus->line);
2205 pp_string (buffer, "] ");
2208 pp_cfg_jump (buffer, e->dest);
2209 pp_newline (buffer);
2213 /* Dumps basic block BB to buffer BUFFER with details described by FLAGS and
2214 indented by INDENT spaces. */
2216 static void
2217 dump_generic_bb_buff (pretty_printer *buffer, basic_block bb,
2218 int indent, int flags)
2220 block_stmt_iterator bsi;
2221 tree stmt;
2222 int label_indent = indent - 2;
2224 if (label_indent < 0)
2225 label_indent = 0;
2227 dump_bb_header (buffer, bb, indent, flags);
2229 if (bb_ann (bb))
2230 dump_phi_nodes (buffer, bb, indent, flags);
2232 for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
2234 int curr_indent;
2236 stmt = bsi_stmt (bsi);
2238 curr_indent = TREE_CODE (stmt) == LABEL_EXPR ? label_indent : indent;
2240 INDENT (curr_indent);
2241 dump_generic_node (buffer, stmt, curr_indent, flags, true);
2242 pp_newline (buffer);
2245 dump_implicit_edges (buffer, bb, indent, flags);
2247 if (flags & TDF_BLOCKS)
2248 dump_bb_end (buffer, bb, indent, flags);