Minor whitespace changes
[official-gcc.git] / gcc / tree-pretty-print.c
blobfe115bc3ca8e644680cf2e507118c5d9057ae217
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 static pretty_printer buffer;
59 static int initialized = 0;
60 static bool dumping_stmts;
62 /* Try to print something for an unknown tree code. */
64 static void
65 do_niy (pretty_printer *buffer, tree node)
67 int i, len;
69 pp_string (buffer, "<<< Unknown tree: ");
70 pp_string (buffer, tree_code_name[(int) TREE_CODE (node)]);
72 if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (node))))
74 len = first_rtl_op (TREE_CODE (node));
75 for (i = 0; i < len; ++i)
77 newline_and_indent (buffer, 2);
78 dump_generic_node (buffer, TREE_OPERAND (node, i), 2, 0, false);
82 pp_string (buffer, " >>>\n");
85 void
86 debug_generic_expr (tree t)
88 print_generic_expr (stderr, t, TDF_VOPS|TDF_UID);
89 fprintf (stderr, "\n");
92 void
93 debug_generic_stmt (tree t)
95 print_generic_stmt (stderr, t, TDF_VOPS|TDF_UID);
96 fprintf (stderr, "\n");
99 /* Prints declaration DECL to the FILE with details specified by FLAGS. */
100 void
101 print_generic_decl (FILE *file, tree decl, int flags)
103 maybe_init_pretty_print (file);
104 dumping_stmts = true;
105 print_declaration (&buffer, decl, 2, flags);
106 pp_write_text_to_stream (&buffer);
109 /* Print tree T, and its successors, on file FILE. FLAGS specifies details
110 to show in the dump. See TDF_* in tree.h. */
112 void
113 print_generic_stmt (FILE *file, tree t, int flags)
115 maybe_init_pretty_print (file);
116 dumping_stmts = true;
117 dump_generic_node (&buffer, t, 0, flags, true);
118 pp_flush (&buffer);
121 /* Print tree T, and its successors, on file FILE. FLAGS specifies details
122 to show in the dump. See TDF_* in tree.h. The output is indented by
123 INDENT spaces. */
125 void
126 print_generic_stmt_indented (FILE *file, tree t, int flags, int indent)
128 int i;
130 maybe_init_pretty_print (file);
131 dumping_stmts = true;
133 for (i = 0; i < indent; i++)
134 pp_space (&buffer);
135 dump_generic_node (&buffer, t, indent, flags, true);
136 pp_flush (&buffer);
139 /* Print a single expression T on file FILE. FLAGS specifies details to show
140 in the dump. See TDF_* in tree.h. */
142 void
143 print_generic_expr (FILE *file, tree t, int flags)
145 maybe_init_pretty_print (file);
146 dumping_stmts = false;
147 dump_generic_node (&buffer, t, 0, flags, false);
150 /* Dump the name of a _DECL node and its DECL_UID if TDF_UID is set
151 in FLAGS. */
153 static void
154 dump_decl_name (pretty_printer *buffer, tree node, int flags)
156 if (DECL_NAME (node))
157 pp_tree_identifier (buffer, DECL_NAME (node));
159 if ((flags & TDF_UID)
160 || DECL_NAME (node) == NULL_TREE)
162 if (TREE_CODE (node) == LABEL_DECL
163 && LABEL_DECL_UID (node) != -1)
164 pp_printf (buffer, "<L" HOST_WIDE_INT_PRINT_DEC ">",
165 LABEL_DECL_UID (node));
166 else
167 pp_printf (buffer, "<D%u>", DECL_UID (node));
171 /* Dump the node NODE on the pretty_printer BUFFER, SPC spaces of indent.
172 FLAGS specifies details to show in the dump (see TDF_* in tree.h). If
173 IS_STMT is true, the object printed is considered to be a statement
174 and it is terminated by ';' if appropriate. */
177 dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
178 bool is_stmt)
180 tree type;
181 tree op0, op1;
182 const char* str;
183 bool is_expr;
185 if (node == NULL_TREE)
186 return spc;
188 is_expr = EXPR_P (node);
190 if (TREE_CODE (node) != ERROR_MARK
191 && is_gimple_stmt (node)
192 && (flags & TDF_VOPS)
193 && stmt_ann (node))
194 dump_vops (buffer, node, spc, flags);
196 if (dumping_stmts
197 && (flags & TDF_LINENO)
198 && EXPR_HAS_LOCATION (node))
200 pp_character (buffer, '[');
201 if (EXPR_FILENAME (node))
203 pp_string (buffer, EXPR_FILENAME (node));
204 pp_string (buffer, " : ");
206 pp_decimal_int (buffer, EXPR_LINENO (node));
207 pp_string (buffer, "] ");
210 switch (TREE_CODE (node))
212 case ERROR_MARK:
213 pp_string (buffer, "<<< error >>>");
214 break;
216 case IDENTIFIER_NODE:
217 pp_tree_identifier (buffer, node);
218 break;
220 case TREE_LIST:
221 while (node && node != error_mark_node)
223 if (TREE_PURPOSE (node))
225 dump_generic_node (buffer, TREE_PURPOSE (node), spc, flags, false);
226 pp_space (buffer);
228 dump_generic_node (buffer, TREE_VALUE (node), spc, flags, false);
229 node = TREE_CHAIN (node);
230 if (node && TREE_CODE (node) == TREE_LIST)
232 pp_character (buffer, ',');
233 pp_space (buffer);
236 break;
238 case TREE_VEC:
239 dump_generic_node (buffer, BINFO_TYPE (node), spc, flags, false);
240 break;
242 case BLOCK:
243 NIY;
244 break;
246 case VOID_TYPE:
247 case INTEGER_TYPE:
248 case REAL_TYPE:
249 case COMPLEX_TYPE:
250 case VECTOR_TYPE:
251 case ENUMERAL_TYPE:
252 case BOOLEAN_TYPE:
253 case CHAR_TYPE:
255 unsigned int quals = TYPE_QUALS (node);
256 char class;
258 if (quals & TYPE_QUAL_CONST)
259 pp_string (buffer, "const ");
260 else if (quals & TYPE_QUAL_VOLATILE)
261 pp_string (buffer, "volatile ");
262 else if (quals & TYPE_QUAL_RESTRICT)
263 pp_string (buffer, "restrict ");
265 class = TREE_CODE_CLASS (TREE_CODE (node));
267 if (class == 'd')
269 if (DECL_NAME (node))
270 dump_decl_name (buffer, node, flags);
271 else
272 pp_string (buffer, "<unnamed type decl>");
274 else if (class == 't')
276 if (TYPE_NAME (node))
278 if (TREE_CODE (TYPE_NAME (node)) == IDENTIFIER_NODE)
279 pp_tree_identifier (buffer, TYPE_NAME (node));
280 else if (TREE_CODE (TYPE_NAME (node)) == TYPE_DECL
281 && DECL_NAME (TYPE_NAME (node)))
282 dump_decl_name (buffer, TYPE_NAME (node), flags);
283 else
284 pp_string (buffer, "<unnamed type>");
286 else
287 pp_string (buffer, "<unnamed type>");
289 break;
292 case POINTER_TYPE:
293 case REFERENCE_TYPE:
294 str = (TREE_CODE (node) == POINTER_TYPE ? "*" : "&");
296 if (TREE_CODE (TREE_TYPE (node)) == FUNCTION_TYPE)
298 tree fnode = TREE_TYPE (node);
299 dump_generic_node (buffer, TREE_TYPE (fnode), spc, flags, false);
300 pp_space (buffer);
301 pp_character (buffer, '(');
302 pp_string (buffer, str);
303 if (TYPE_NAME (node) && DECL_NAME (TYPE_NAME (node)))
304 dump_decl_name (buffer, TYPE_NAME (node), flags);
305 else
306 pp_printf (buffer, "<T%x>", TYPE_UID (node));
308 pp_character (buffer, ')');
309 pp_space (buffer);
310 pp_character (buffer, '(');
311 /* Print the argument types. The last element in the list is a
312 VOID_TYPE. The following avoid to print the last element. */
314 tree tmp = TYPE_ARG_TYPES (fnode);
315 while (tmp && TREE_CHAIN (tmp) && tmp != error_mark_node)
317 dump_generic_node (buffer, TREE_VALUE (tmp), spc, flags, false);
318 tmp = TREE_CHAIN (tmp);
319 if (TREE_CHAIN (tmp) && TREE_CODE (TREE_CHAIN (tmp)) == TREE_LIST)
321 pp_character (buffer, ',');
322 pp_space (buffer);
326 pp_character (buffer, ')');
328 else
330 unsigned int quals = TYPE_QUALS (node);
332 dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
333 pp_space (buffer);
334 pp_string (buffer, str);
336 if (quals & TYPE_QUAL_CONST)
337 pp_string (buffer, " const");
338 else if (quals & TYPE_QUAL_VOLATILE)
339 pp_string (buffer, "volatile");
340 else if (quals & TYPE_QUAL_RESTRICT)
341 pp_string (buffer, " restrict");
343 break;
345 case OFFSET_TYPE:
346 NIY;
347 break;
349 case METHOD_TYPE:
350 dump_decl_name (buffer, TYPE_NAME (TYPE_METHOD_BASETYPE (node)), flags);
351 pp_string (buffer, "::");
352 break;
354 case FILE_TYPE:
355 NIY;
356 break;
358 case ARRAY_TYPE:
360 tree tmp;
362 /* Print the array type. */
363 dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
365 /* Print the dimensions. */
366 tmp = node;
367 while (tmp && TREE_CODE (tmp) == ARRAY_TYPE)
369 pp_character (buffer, '[');
370 if (TYPE_SIZE (tmp))
372 tree size = TYPE_SIZE (tmp);
373 if (TREE_CODE (size) == INTEGER_CST)
374 pp_wide_integer (buffer,
375 TREE_INT_CST_LOW (TYPE_SIZE (tmp)) /
376 TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (tmp))));
377 else if (TREE_CODE (size) == MULT_EXPR)
378 dump_generic_node (buffer, TREE_OPERAND (size, 0), spc, flags, false);
379 /* else punt. */
381 pp_character (buffer, ']');
382 tmp = TREE_TYPE (tmp);
384 break;
387 case SET_TYPE:
388 NIY;
389 break;
391 case RECORD_TYPE:
392 case UNION_TYPE:
393 case QUAL_UNION_TYPE:
394 /* Print the name of the structure. */
395 if (TREE_CODE (node) == RECORD_TYPE)
396 pp_string (buffer, "struct ");
397 else if (TREE_CODE (node) == UNION_TYPE)
398 pp_string (buffer, "union ");
400 if (TYPE_NAME (node))
401 dump_generic_node (buffer, TYPE_NAME (node), spc, flags, false);
402 else
403 print_struct_decl (buffer, node, spc, flags);
404 break;
406 case LANG_TYPE:
407 NIY;
408 break;
410 case INTEGER_CST:
411 if (TREE_CODE (TREE_TYPE (node)) == POINTER_TYPE)
413 /* In the case of a pointer, one may want to divide by the
414 size of the pointed-to type. Unfortunately, this not
415 straightforward. The C front-end maps expressions
417 (int *) 5
418 int *p; (p + 5)
420 in such a way that the two INTEGER_CST nodes for "5" have
421 different values but identical types. In the latter
422 case, the 5 is multiplied by sizeof (int) in c-common.c
423 (pointer_int_sum) to convert it to a byte address, and
424 yet the type of the node is left unchanged. Argh. What
425 is consistent though is that the number value corresponds
426 to bytes (UNITS) offset.
428 NB: Neither of the following divisors can be trivially
429 used to recover the original literal:
431 TREE_INT_CST_LOW (TYPE_SIZE_UNIT (TREE_TYPE (node)))
432 TYPE_PRECISION (TREE_TYPE (TREE_TYPE (node))) */
433 pp_wide_integer (buffer, TREE_INT_CST_LOW (node));
434 pp_string (buffer, "B"); /* pseudo-unit */
436 else if (! host_integerp (node, 0))
438 tree val = node;
440 if (tree_int_cst_sgn (val) < 0)
442 pp_character (buffer, '-');
443 val = build_int_2 (-TREE_INT_CST_LOW (val),
444 ~TREE_INT_CST_HIGH (val)
445 + !TREE_INT_CST_LOW (val));
447 /* Would "%x%0*x" or "%x%*0x" get zero-padding on all
448 systems? */
450 static char format[10]; /* "%x%09999x\0" */
451 if (!format[0])
452 sprintf (format, "%%x%%0%dx", HOST_BITS_PER_INT / 4);
453 sprintf (pp_buffer (buffer)->digit_buffer, format,
454 TREE_INT_CST_HIGH (val),
455 TREE_INT_CST_LOW (val));
456 pp_string (buffer, pp_buffer (buffer)->digit_buffer);
459 else
460 pp_wide_integer (buffer, TREE_INT_CST_LOW (node));
461 break;
463 case REAL_CST:
464 /* Code copied from print_node. */
466 REAL_VALUE_TYPE d;
467 if (TREE_OVERFLOW (node))
468 pp_string (buffer, " overflow");
470 #if !defined(REAL_IS_NOT_DOUBLE) || defined(REAL_ARITHMETIC)
471 d = TREE_REAL_CST (node);
472 if (REAL_VALUE_ISINF (d))
473 pp_string (buffer, " Inf");
474 else if (REAL_VALUE_ISNAN (d))
475 pp_string (buffer, " Nan");
476 else
478 char string[100];
479 real_to_decimal (string, &d, sizeof (string), 0, 1);
480 pp_string (buffer, string);
482 #else
484 HOST_WIDE_INT i;
485 unsigned char *p = (unsigned char *) &TREE_REAL_CST (node);
486 pp_string (buffer, "0x");
487 for (i = 0; i < sizeof TREE_REAL_CST (node); i++)
488 output_formatted_integer (buffer, "%02x", *p++);
490 #endif
491 break;
494 case COMPLEX_CST:
495 pp_string (buffer, "__complex__ (");
496 dump_generic_node (buffer, TREE_REALPART (node), spc, flags, false);
497 pp_string (buffer, ", ");
498 dump_generic_node (buffer, TREE_IMAGPART (node), spc, flags, false);
499 pp_string (buffer, ")");
500 break;
502 case STRING_CST:
503 pp_string (buffer, "\"");
504 pretty_print_string (buffer, TREE_STRING_POINTER (node));
505 pp_string (buffer, "\"");
506 break;
508 case VECTOR_CST:
510 tree elt;
511 pp_string (buffer, "{ ");
512 for (elt = TREE_VECTOR_CST_ELTS (node); elt; elt = TREE_CHAIN (elt))
514 dump_generic_node (buffer, TREE_VALUE (elt), spc, flags, false);
515 if (TREE_CHAIN (elt))
516 pp_string (buffer, ", ");
518 pp_string (buffer, " }");
520 break;
522 case FUNCTION_TYPE:
523 break;
525 case FUNCTION_DECL:
526 case CONST_DECL:
527 dump_decl_name (buffer, node, flags);
528 break;
530 case LABEL_DECL:
531 if (DECL_NAME (node))
532 dump_decl_name (buffer, node, flags);
533 else if (LABEL_DECL_UID (node) != -1)
534 pp_printf (buffer, "<L" HOST_WIDE_INT_PRINT_DEC ">",
535 LABEL_DECL_UID (node));
536 else
537 pp_printf (buffer, "<D%u>", DECL_UID (node));
538 break;
540 case TYPE_DECL:
541 if (strcmp (DECL_SOURCE_FILE (node), "<built-in>") == 0)
543 /* Don't print the declaration of built-in types. */
544 break;
546 if (DECL_NAME (node))
548 dump_decl_name (buffer, node, flags);
550 else
552 if (TYPE_METHODS (TREE_TYPE (node)))
554 /* The type is a c++ class: all structures have at least
555 4 methods. */
556 pp_string (buffer, "class ");
557 dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
559 else
561 pp_string (buffer, "struct ");
562 dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
563 pp_character (buffer, ';');
564 pp_newline (buffer);
567 break;
569 case VAR_DECL:
570 case PARM_DECL:
571 case FIELD_DECL:
572 case NAMESPACE_DECL:
573 dump_decl_name (buffer, node, flags);
574 break;
576 case RESULT_DECL:
577 pp_string (buffer, "<retval>");
578 break;
580 case COMPONENT_REF:
581 op0 = TREE_OPERAND (node, 0);
582 str = ".";
583 if (TREE_CODE (op0) == INDIRECT_REF)
585 op0 = TREE_OPERAND (op0, 0);
586 str = "->";
588 if (op_prio (op0) < op_prio (node))
589 pp_character (buffer, '(');
590 dump_generic_node (buffer, op0, spc, flags, false);
591 if (op_prio (op0) < op_prio (node))
592 pp_character (buffer, ')');
593 pp_string (buffer, str);
594 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
595 if (TREE_OPERAND (node, 2)
596 && TREE_CODE (TREE_OPERAND (node, 2)) != INTEGER_CST)
598 pp_string (buffer, "{off: ");
599 dump_generic_node (buffer, TREE_OPERAND (node, 2),
600 spc, flags, false);
601 pp_character (buffer, '}');
603 break;
605 case BIT_FIELD_REF:
606 pp_string (buffer, "BIT_FIELD_REF <");
607 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
608 pp_string (buffer, ", ");
609 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
610 pp_string (buffer, ", ");
611 dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
612 pp_string (buffer, ">");
613 break;
615 case BUFFER_REF:
616 NIY;
617 break;
619 case ARRAY_REF:
620 case ARRAY_RANGE_REF:
621 op0 = TREE_OPERAND (node, 0);
622 if (op_prio (op0) < op_prio (node))
623 pp_character (buffer, '(');
624 dump_generic_node (buffer, op0, spc, flags, false);
625 if (op_prio (op0) < op_prio (node))
626 pp_character (buffer, ')');
627 pp_character (buffer, '[');
628 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
629 if (TREE_CODE (node) == ARRAY_RANGE_REF)
630 pp_string (buffer, " ...");
631 pp_character (buffer, ']');
633 if ((TREE_OPERAND (node, 2)
634 && TREE_CODE (TREE_OPERAND (node, 2)) != INTEGER_CST)
635 || (TREE_OPERAND (node, 3)
636 && TREE_CODE (TREE_OPERAND (node, 3)) != INTEGER_CST))
638 pp_string (buffer, "{lb: ");
639 dump_generic_node (buffer, TREE_OPERAND (node, 2),
640 spc, flags, false);
641 pp_string (buffer, " sz: ");
642 dump_generic_node (buffer, TREE_OPERAND (node, 3),
643 spc, flags, false);
644 pp_character (buffer, '}');
646 break;
648 case CONSTRUCTOR:
650 tree lnode;
651 bool is_struct_init = FALSE;
652 pp_character (buffer, '{');
653 lnode = CONSTRUCTOR_ELTS (node);
654 if (TREE_CODE (TREE_TYPE (node)) == RECORD_TYPE
655 || TREE_CODE (TREE_TYPE (node)) == UNION_TYPE)
656 is_struct_init = TRUE;
657 while (lnode && lnode != error_mark_node)
659 tree val;
660 if (TREE_PURPOSE (lnode) && is_struct_init)
662 pp_character (buffer, '.');
663 dump_generic_node (buffer, TREE_PURPOSE (lnode), spc, flags, false);
664 pp_string (buffer, "=");
666 val = TREE_VALUE (lnode);
667 if (val && TREE_CODE (val) == ADDR_EXPR)
668 if (TREE_CODE (TREE_OPERAND (val, 0)) == FUNCTION_DECL)
669 val = TREE_OPERAND (val, 0);
670 if (val && TREE_CODE (val) == FUNCTION_DECL)
672 dump_decl_name (buffer, val, flags);
674 else
676 dump_generic_node (buffer, TREE_VALUE (lnode), spc, flags, false);
678 lnode = TREE_CHAIN (lnode);
679 if (lnode && TREE_CODE (lnode) == TREE_LIST)
681 pp_character (buffer, ',');
682 pp_space (buffer);
685 pp_character (buffer, '}');
687 break;
689 case COMPOUND_EXPR:
691 tree *tp;
692 if (flags & TDF_SLIM)
694 pp_string (buffer, "<COMPOUND_EXPR>");
695 break;
698 dump_generic_node (buffer, TREE_OPERAND (node, 0),
699 spc, flags, dumping_stmts);
700 if (dumping_stmts)
701 newline_and_indent (buffer, spc);
702 else
704 pp_character (buffer, ',');
705 pp_space (buffer);
708 for (tp = &TREE_OPERAND (node, 1);
709 TREE_CODE (*tp) == COMPOUND_EXPR;
710 tp = &TREE_OPERAND (*tp, 1))
712 dump_generic_node (buffer, TREE_OPERAND (*tp, 0),
713 spc, flags, dumping_stmts);
714 if (dumping_stmts)
715 newline_and_indent (buffer, spc);
716 else
718 pp_character (buffer, ',');
719 pp_space (buffer);
723 dump_generic_node (buffer, *tp, spc, flags, dumping_stmts);
725 break;
727 case STATEMENT_LIST:
729 tree_stmt_iterator si;
730 bool first = true;
732 if ((flags & TDF_SLIM) || !dumping_stmts)
734 pp_string (buffer, "<STATEMENT_LIST>");
735 break;
738 for (si = tsi_start (node); !tsi_end_p (si); tsi_next (&si))
740 if (!first)
741 newline_and_indent (buffer, spc);
742 else
743 first = false;
744 dump_generic_node (buffer, tsi_stmt (si), spc, flags, true);
747 break;
749 case MODIFY_EXPR:
750 case INIT_EXPR:
751 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
752 pp_space (buffer);
753 pp_character (buffer, '=');
754 pp_space (buffer);
755 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
756 break;
758 case TARGET_EXPR:
759 pp_string (buffer, "TARGET_EXPR <");
760 dump_generic_node (buffer, TARGET_EXPR_SLOT (node), spc, flags, false);
761 pp_character (buffer, ',');
762 pp_space (buffer);
763 dump_generic_node (buffer, TARGET_EXPR_INITIAL (node), spc, flags, false);
764 pp_character (buffer, '>');
765 break;
767 case COND_EXPR:
768 if (TREE_TYPE (node) == void_type_node)
770 pp_string (buffer, "if (");
771 dump_generic_node (buffer, COND_EXPR_COND (node), spc, flags, false);
772 pp_character (buffer, ')');
773 /* The lowered cond_exprs should always be printed in full. */
774 if (COND_EXPR_THEN (node)
775 && TREE_CODE (COND_EXPR_THEN (node)) == GOTO_EXPR
776 && COND_EXPR_ELSE (node)
777 && TREE_CODE (COND_EXPR_ELSE (node)) == GOTO_EXPR)
779 pp_space (buffer);
780 dump_generic_node (buffer, COND_EXPR_THEN (node), 0, flags, true);
781 pp_string (buffer, " else ");
782 dump_generic_node (buffer, COND_EXPR_ELSE (node), 0, flags, true);
784 else if (!(flags & TDF_SLIM))
786 /* Output COND_EXPR_THEN. */
787 if (COND_EXPR_THEN (node))
789 newline_and_indent (buffer, spc+2);
790 pp_character (buffer, '{');
791 newline_and_indent (buffer, spc+4);
792 dump_generic_node (buffer, COND_EXPR_THEN (node), spc+4,
793 flags, true);
794 newline_and_indent (buffer, spc+2);
795 pp_character (buffer, '}');
798 /* Output COND_EXPR_ELSE. */
799 if (COND_EXPR_ELSE (node))
801 newline_and_indent (buffer, spc);
802 pp_string (buffer, "else");
803 newline_and_indent (buffer, spc+2);
804 pp_character (buffer, '{');
805 newline_and_indent (buffer, spc+4);
806 dump_generic_node (buffer, COND_EXPR_ELSE (node), spc+4,
807 flags, true);
808 newline_and_indent (buffer, spc+2);
809 pp_character (buffer, '}');
812 is_expr = false;
814 else
816 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
817 pp_space (buffer);
818 pp_character (buffer, '?');
819 pp_space (buffer);
820 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
821 pp_space (buffer);
822 pp_character (buffer, ':');
823 pp_space (buffer);
824 dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
826 break;
828 case BIND_EXPR:
829 pp_character (buffer, '{');
830 if (!(flags & TDF_SLIM))
832 if (BIND_EXPR_VARS (node))
834 pp_newline (buffer);
836 for (op0 = BIND_EXPR_VARS (node); op0; op0 = TREE_CHAIN (op0))
838 print_declaration (buffer, op0, spc+2, flags);
839 pp_newline (buffer);
843 newline_and_indent (buffer, spc+2);
844 dump_generic_node (buffer, BIND_EXPR_BODY (node), spc+2, flags, true);
845 newline_and_indent (buffer, spc);
846 pp_character (buffer, '}');
848 is_expr = false;
849 break;
851 case CALL_EXPR:
852 print_call_name (buffer, node);
854 /* Print parameters. */
855 pp_space (buffer);
856 pp_character (buffer, '(');
857 op1 = TREE_OPERAND (node, 1);
858 if (op1)
859 dump_generic_node (buffer, op1, spc, flags, false);
860 pp_character (buffer, ')');
862 op1 = TREE_OPERAND (node, 2);
863 if (op1)
865 pp_string (buffer, " [static-chain: ");
866 dump_generic_node (buffer, op1, spc, flags, false);
867 pp_character (buffer, ']');
870 if (CALL_EXPR_TAILCALL (node))
871 pp_string (buffer, " [tail call]");
872 break;
874 case WITH_CLEANUP_EXPR:
875 NIY;
876 break;
878 case CLEANUP_POINT_EXPR:
879 pp_string (buffer, "<<cleanup_point ");
880 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
881 pp_string (buffer, ">>");
882 break;
884 case PLACEHOLDER_EXPR:
885 NIY;
886 break;
888 /* Binary arithmetic and logic expressions. */
889 case MULT_EXPR:
890 case PLUS_EXPR:
891 case MINUS_EXPR:
892 case TRUNC_DIV_EXPR:
893 case CEIL_DIV_EXPR:
894 case FLOOR_DIV_EXPR:
895 case ROUND_DIV_EXPR:
896 case TRUNC_MOD_EXPR:
897 case CEIL_MOD_EXPR:
898 case FLOOR_MOD_EXPR:
899 case ROUND_MOD_EXPR:
900 case RDIV_EXPR:
901 case EXACT_DIV_EXPR:
902 case LSHIFT_EXPR:
903 case RSHIFT_EXPR:
904 case LROTATE_EXPR:
905 case RROTATE_EXPR:
906 case BIT_IOR_EXPR:
907 case BIT_XOR_EXPR:
908 case BIT_AND_EXPR:
909 case TRUTH_ANDIF_EXPR:
910 case TRUTH_ORIF_EXPR:
911 case TRUTH_AND_EXPR:
912 case TRUTH_OR_EXPR:
913 case TRUTH_XOR_EXPR:
914 case LT_EXPR:
915 case LE_EXPR:
916 case GT_EXPR:
917 case GE_EXPR:
918 case EQ_EXPR:
919 case NE_EXPR:
920 case UNLT_EXPR:
921 case UNLE_EXPR:
922 case UNGT_EXPR:
923 case UNGE_EXPR:
924 case UNEQ_EXPR:
925 case LTGT_EXPR:
926 case ORDERED_EXPR:
927 case UNORDERED_EXPR:
929 const char *op = op_symbol (node);
930 op0 = TREE_OPERAND (node, 0);
931 op1 = TREE_OPERAND (node, 1);
933 /* When the operands are expressions with less priority,
934 keep semantics of the tree representation. */
935 if (op_prio (op0) < op_prio (node))
937 pp_character (buffer, '(');
938 dump_generic_node (buffer, op0, spc, flags, false);
939 pp_character (buffer, ')');
941 else
942 dump_generic_node (buffer, op0, spc, flags, false);
944 pp_space (buffer);
945 pp_string (buffer, op);
946 pp_space (buffer);
948 /* When the operands are expressions with less priority,
949 keep semantics of the tree representation. */
950 if (op_prio (op1) < op_prio (node))
952 pp_character (buffer, '(');
953 dump_generic_node (buffer, op1, spc, flags, false);
954 pp_character (buffer, ')');
956 else
957 dump_generic_node (buffer, op1, spc, flags, false);
959 break;
961 /* Unary arithmetic and logic expressions. */
962 case NEGATE_EXPR:
963 case BIT_NOT_EXPR:
964 case TRUTH_NOT_EXPR:
965 case ADDR_EXPR:
966 case REFERENCE_EXPR:
967 case PREDECREMENT_EXPR:
968 case PREINCREMENT_EXPR:
969 case INDIRECT_REF:
970 if (TREE_CODE (node) == ADDR_EXPR
971 && (TREE_CODE (TREE_OPERAND (node, 0)) == STRING_CST
972 || TREE_CODE (TREE_OPERAND (node, 0)) == FUNCTION_DECL))
973 ; /* Do not output '&' for strings and function pointers. */
974 else
975 pp_string (buffer, op_symbol (node));
977 if (op_prio (TREE_OPERAND (node, 0)) < op_prio (node))
979 pp_character (buffer, '(');
980 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
981 pp_character (buffer, ')');
983 else
984 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
985 break;
987 case POSTDECREMENT_EXPR:
988 case POSTINCREMENT_EXPR:
989 if (op_prio (TREE_OPERAND (node, 0)) < op_prio (node))
991 pp_character (buffer, '(');
992 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
993 pp_character (buffer, ')');
995 else
996 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
997 pp_string (buffer, op_symbol (node));
998 break;
1000 case MIN_EXPR:
1001 pp_string (buffer, "MIN_EXPR <");
1002 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1003 pp_string (buffer, ", ");
1004 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1005 pp_character (buffer, '>');
1006 break;
1008 case MAX_EXPR:
1009 pp_string (buffer, "MAX_EXPR <");
1010 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1011 pp_string (buffer, ", ");
1012 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1013 pp_character (buffer, '>');
1014 break;
1016 case ABS_EXPR:
1017 pp_string (buffer, "ABS_EXPR <");
1018 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1019 pp_character (buffer, '>');
1020 break;
1022 case IN_EXPR:
1023 NIY;
1024 break;
1026 case SET_LE_EXPR:
1027 NIY;
1028 break;
1030 case CARD_EXPR:
1031 NIY;
1032 break;
1034 case RANGE_EXPR:
1035 NIY;
1036 break;
1038 case FIX_TRUNC_EXPR:
1039 case FIX_CEIL_EXPR:
1040 case FIX_FLOOR_EXPR:
1041 case FIX_ROUND_EXPR:
1042 case FLOAT_EXPR:
1043 case CONVERT_EXPR:
1044 case NOP_EXPR:
1045 type = TREE_TYPE (node);
1046 op0 = TREE_OPERAND (node, 0);
1047 if (type != TREE_TYPE (op0))
1049 pp_character (buffer, '(');
1050 dump_generic_node (buffer, type, spc, flags, false);
1051 pp_string (buffer, ")");
1053 if (op_prio (op0) < op_prio (node))
1054 pp_character (buffer, '(');
1055 dump_generic_node (buffer, op0, spc, flags, false);
1056 if (op_prio (op0) < op_prio (node))
1057 pp_character (buffer, ')');
1058 break;
1060 case VIEW_CONVERT_EXPR:
1061 pp_string (buffer, "VIEW_CONVERT_EXPR<");
1062 dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
1063 pp_string (buffer, ">(");
1064 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1065 pp_character (buffer, ')');
1066 break;
1068 case NON_LVALUE_EXPR:
1069 pp_string (buffer, "NON_LVALUE_EXPR <");
1070 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1071 pp_character (buffer, '>');
1072 break;
1074 case SAVE_EXPR:
1075 pp_string (buffer, "SAVE_EXPR <");
1076 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1077 pp_character (buffer, '>');
1078 break;
1080 case UNSAVE_EXPR:
1081 pp_string (buffer, "UNSAVE_EXPR <");
1082 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1083 pp_character (buffer, '>');
1084 break;
1086 case RTL_EXPR:
1087 NIY;
1088 break;
1090 case ENTRY_VALUE_EXPR:
1091 NIY;
1092 break;
1094 case COMPLEX_EXPR:
1095 pp_string (buffer, "COMPLEX_EXPR <");
1096 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1097 pp_string (buffer, ", ");
1098 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1099 pp_string (buffer, ">");
1100 break;
1102 case CONJ_EXPR:
1103 pp_string (buffer, "CONJ_EXPR <");
1104 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1105 pp_string (buffer, ">");
1106 break;
1108 case REALPART_EXPR:
1109 pp_string (buffer, "REALPART_EXPR <");
1110 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1111 pp_string (buffer, ">");
1112 break;
1114 case IMAGPART_EXPR:
1115 pp_string (buffer, "IMAGPART_EXPR <");
1116 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1117 pp_string (buffer, ">");
1118 break;
1120 case VA_ARG_EXPR:
1121 pp_string (buffer, "VA_ARG_EXPR <");
1122 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1123 pp_string (buffer, ">");
1124 break;
1126 case TRY_FINALLY_EXPR:
1127 case TRY_CATCH_EXPR:
1128 pp_string (buffer, "try");
1129 newline_and_indent (buffer, spc+2);
1130 pp_string (buffer, "{");
1131 newline_and_indent (buffer, spc+4);
1132 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc+4, flags, true);
1133 newline_and_indent (buffer, spc+2);
1134 pp_string (buffer, "}");
1135 newline_and_indent (buffer, spc);
1136 pp_string (buffer,
1137 (TREE_CODE (node) == TRY_CATCH_EXPR) ? "catch" : "finally");
1138 newline_and_indent (buffer, spc+2);
1139 pp_string (buffer, "{");
1140 newline_and_indent (buffer, spc+4);
1141 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc+4, flags, true);
1142 newline_and_indent (buffer, spc+2);
1143 pp_string (buffer, "}");
1144 is_expr = false;
1145 break;
1147 case CATCH_EXPR:
1148 pp_string (buffer, "catch (");
1149 dump_generic_node (buffer, CATCH_TYPES (node), spc+2, flags, false);
1150 pp_string (buffer, ")");
1151 newline_and_indent (buffer, spc+2);
1152 pp_string (buffer, "{");
1153 newline_and_indent (buffer, spc+4);
1154 dump_generic_node (buffer, CATCH_BODY (node), spc+4, flags, true);
1155 newline_and_indent (buffer, spc+2);
1156 pp_string (buffer, "}");
1157 is_expr = false;
1158 break;
1160 case EH_FILTER_EXPR:
1161 pp_string (buffer, "<<<eh_filter (");
1162 dump_generic_node (buffer, EH_FILTER_TYPES (node), spc+2, flags, false);
1163 pp_string (buffer, ")>>>");
1164 newline_and_indent (buffer, spc+2);
1165 pp_string (buffer, "{");
1166 newline_and_indent (buffer, spc+4);
1167 dump_generic_node (buffer, EH_FILTER_FAILURE (node), spc+4, flags, true);
1168 newline_and_indent (buffer, spc+2);
1169 pp_string (buffer, "}");
1170 is_expr = false;
1171 break;
1173 case GOTO_SUBROUTINE_EXPR:
1174 NIY;
1175 break;
1177 case LABEL_EXPR:
1178 op0 = TREE_OPERAND (node, 0);
1179 /* If this is for break or continue, don't bother printing it. */
1180 if (DECL_NAME (op0))
1182 const char *name = IDENTIFIER_POINTER (DECL_NAME (op0));
1183 if (strcmp (name, "break") == 0
1184 || strcmp (name, "continue") == 0)
1185 break;
1187 dump_generic_node (buffer, op0, spc, flags, false);
1188 pp_character (buffer, ':');
1189 if (DECL_NONLOCAL (op0))
1190 pp_string (buffer, " [non-local]");
1191 break;
1193 case LABELED_BLOCK_EXPR:
1194 op0 = LABELED_BLOCK_LABEL (node);
1195 /* If this is for break or continue, don't bother printing it. */
1196 if (DECL_NAME (op0))
1198 const char *name = IDENTIFIER_POINTER (DECL_NAME (op0));
1199 if (strcmp (name, "break") == 0
1200 || strcmp (name, "continue") == 0)
1202 dump_generic_node (buffer, LABELED_BLOCK_BODY (node), spc, flags, false);
1203 break;
1206 dump_generic_node (buffer, LABELED_BLOCK_LABEL (node), spc, flags, false);
1207 pp_string (buffer, ": {");
1208 if (!(flags & TDF_SLIM))
1209 newline_and_indent (buffer, spc+2);
1210 dump_generic_node (buffer, LABELED_BLOCK_BODY (node), spc+2, flags, true);
1211 if (!flags)
1212 newline_and_indent (buffer, spc);
1213 pp_character (buffer, '}');
1214 is_expr = false;
1215 break;
1217 case EXIT_BLOCK_EXPR:
1218 op0 = LABELED_BLOCK_LABEL (EXIT_BLOCK_LABELED_BLOCK (node));
1219 /* If this is for a break or continue, print it accordingly. */
1220 if (DECL_NAME (op0))
1222 const char *name = IDENTIFIER_POINTER (DECL_NAME (op0));
1223 if (strcmp (name, "break") == 0
1224 || strcmp (name, "continue") == 0)
1226 pp_string (buffer, name);
1227 break;
1230 pp_string (buffer, "<<<exit block ");
1231 dump_generic_node (buffer, op0, spc, flags, false);
1232 pp_string (buffer, ">>>");
1233 break;
1235 case EXC_PTR_EXPR:
1236 pp_string (buffer, "<<<exception object>>>");
1237 break;
1239 case FILTER_EXPR:
1240 pp_string (buffer, "<<<filter object>>>");
1241 break;
1243 case LOOP_EXPR:
1244 pp_string (buffer, "while (1)");
1245 if (!(flags & TDF_SLIM))
1247 newline_and_indent (buffer, spc+2);
1248 pp_character (buffer, '{');
1249 newline_and_indent (buffer, spc+4);
1250 dump_generic_node (buffer, LOOP_EXPR_BODY (node), spc+4, flags, true);
1251 newline_and_indent (buffer, spc+2);
1252 pp_character (buffer, '}');
1254 is_expr = false;
1255 break;
1257 case RETURN_EXPR:
1258 pp_string (buffer, "return");
1259 op0 = TREE_OPERAND (node, 0);
1260 if (op0)
1262 pp_space (buffer);
1263 if (TREE_CODE (op0) == MODIFY_EXPR)
1264 dump_generic_node (buffer, TREE_OPERAND (op0, 1), spc, flags, false);
1265 else
1266 dump_generic_node (buffer, op0, spc, flags, false);
1268 break;
1270 case EXIT_EXPR:
1271 pp_string (buffer, "if (");
1272 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1273 pp_string (buffer, ") break");
1274 break;
1276 case SWITCH_EXPR:
1277 pp_string (buffer, "switch (");
1278 dump_generic_node (buffer, SWITCH_COND (node), spc, flags, false);
1279 pp_character (buffer, ')');
1280 if (!(flags & TDF_SLIM))
1282 newline_and_indent (buffer, spc+2);
1283 pp_character (buffer, '{');
1284 if (SWITCH_BODY (node))
1286 newline_and_indent (buffer, spc+4);
1287 dump_generic_node (buffer, SWITCH_BODY (node), spc+4, flags, true);
1289 else
1291 tree vec = SWITCH_LABELS (node);
1292 size_t i, n = TREE_VEC_LENGTH (vec);
1293 for (i = 0; i < n; ++i)
1295 tree elt = TREE_VEC_ELT (vec, i);
1296 newline_and_indent (buffer, spc+4);
1297 dump_generic_node (buffer, elt, spc+4, flags, false);
1298 pp_string (buffer, " goto ");
1299 dump_generic_node (buffer, CASE_LABEL (elt), spc+4, flags, true);
1300 pp_semicolon (buffer);
1303 newline_and_indent (buffer, spc+2);
1304 pp_character (buffer, '}');
1306 is_expr = false;
1307 break;
1309 case GOTO_EXPR:
1310 op0 = GOTO_DESTINATION (node);
1311 if (TREE_CODE (op0) != SSA_NAME
1312 && DECL_P (op0)
1313 && DECL_NAME (op0))
1315 const char *name = IDENTIFIER_POINTER (DECL_NAME (op0));
1316 if (strcmp (name, "break") == 0
1317 || strcmp (name, "continue") == 0)
1319 pp_string (buffer, name);
1320 break;
1323 pp_string (buffer, "goto ");
1324 dump_generic_node (buffer, op0, spc, flags, false);
1325 break;
1327 case RESX_EXPR:
1328 pp_string (buffer, "resx");
1329 /* ??? Any sensible way to present the eh region? */
1330 break;
1332 case ASM_EXPR:
1333 pp_string (buffer, "__asm__");
1334 if (ASM_VOLATILE_P (node))
1335 pp_string (buffer, " __volatile__");
1336 pp_character (buffer, '(');
1337 dump_generic_node (buffer, ASM_STRING (node), spc, flags, false);
1338 pp_character (buffer, ':');
1339 dump_generic_node (buffer, ASM_OUTPUTS (node), spc, flags, false);
1340 pp_character (buffer, ':');
1341 dump_generic_node (buffer, ASM_INPUTS (node), spc, flags, false);
1342 if (ASM_CLOBBERS (node))
1344 pp_character (buffer, ':');
1345 dump_generic_node (buffer, ASM_CLOBBERS (node), spc, flags, false);
1347 pp_string (buffer, ")");
1348 break;
1350 case CASE_LABEL_EXPR:
1351 if (CASE_LOW (node) && CASE_HIGH (node))
1353 pp_string (buffer, "case ");
1354 dump_generic_node (buffer, CASE_LOW (node), spc, flags, false);
1355 pp_string (buffer, " ... ");
1356 dump_generic_node (buffer, CASE_HIGH (node), spc, flags, false);
1358 else if (CASE_LOW (node))
1360 pp_string (buffer, "case ");
1361 dump_generic_node (buffer, CASE_LOW (node), spc, flags, false);
1363 else
1364 pp_string (buffer, "default ");
1365 pp_character (buffer, ':');
1366 break;
1368 case OBJ_TYPE_REF:
1369 pp_string (buffer, "OBJ_TYPE_REF(");
1370 dump_generic_node (buffer, OBJ_TYPE_REF_EXPR (node), spc, flags, false);
1371 pp_character (buffer, ';');
1372 dump_generic_node (buffer, OBJ_TYPE_REF_OBJECT (node), spc, flags, false);
1373 pp_character (buffer, '-');
1374 pp_character (buffer, '>');
1375 dump_generic_node (buffer, OBJ_TYPE_REF_TOKEN (node), spc, flags, false);
1376 pp_character (buffer, ')');
1377 break;
1379 case PHI_NODE:
1381 int i;
1383 dump_generic_node (buffer, PHI_RESULT (node), spc, flags, false);
1384 pp_string (buffer, " = PHI <");
1385 for (i = 0; i < PHI_NUM_ARGS (node); i++)
1387 dump_generic_node (buffer, PHI_ARG_DEF (node, i), spc, flags, false);
1388 pp_string (buffer, "(");
1389 pp_decimal_int (buffer, PHI_ARG_EDGE (node, i)->src->index);
1390 pp_string (buffer, ")");
1391 if (i < PHI_NUM_ARGS (node) - 1)
1392 pp_string (buffer, ", ");
1394 pp_string (buffer, ">;");
1396 break;
1398 case SSA_NAME:
1399 dump_generic_node (buffer, SSA_NAME_VAR (node), spc, flags, false);
1400 pp_string (buffer, "_");
1401 pp_decimal_int (buffer, SSA_NAME_VERSION (node));
1402 break;
1404 case VALUE_HANDLE:
1405 pp_printf (buffer, "VH.%d", VALUE_HANDLE_ID (node));
1406 break;
1408 default:
1409 NIY;
1412 if (is_stmt && is_expr)
1413 pp_semicolon (buffer);
1414 pp_write_text_to_stream (buffer);
1416 return spc;
1419 /* Print the declaration of a variable. */
1421 static void
1422 print_declaration (pretty_printer *buffer, tree t, int spc, int flags)
1424 /* Don't print type declarations. */
1425 if (TREE_CODE (t) == TYPE_DECL)
1426 return;
1428 INDENT (spc);
1430 if (DECL_REGISTER (t))
1431 pp_string (buffer, "register ");
1433 if (TREE_PUBLIC (t) && DECL_EXTERNAL (t))
1434 pp_string (buffer, "extern ");
1435 else if (TREE_STATIC (t))
1436 pp_string (buffer, "static ");
1438 /* Print the type and name. */
1439 if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
1441 tree tmp;
1443 /* Print array's type. */
1444 tmp = TREE_TYPE (t);
1445 while (TREE_CODE (TREE_TYPE (tmp)) == ARRAY_TYPE)
1446 tmp = TREE_TYPE (tmp);
1447 dump_generic_node (buffer, TREE_TYPE (tmp), spc, flags, false);
1449 /* Print variable's name. */
1450 pp_space (buffer);
1451 dump_generic_node (buffer, t, spc, flags, false);
1453 /* Print the dimensions. */
1454 tmp = TREE_TYPE (t);
1455 while (TREE_CODE (tmp) == ARRAY_TYPE)
1457 pp_character (buffer, '[');
1458 if (TYPE_DOMAIN (tmp))
1460 if (TREE_CODE (TYPE_SIZE (tmp)) == INTEGER_CST)
1461 pp_wide_integer (buffer,
1462 TREE_INT_CST_LOW (TYPE_SIZE (tmp)) /
1463 TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (tmp))));
1464 else
1465 dump_generic_node (buffer, TYPE_SIZE_UNIT (tmp), spc, flags,
1466 false);
1468 pp_character (buffer, ']');
1469 tmp = TREE_TYPE (tmp);
1472 else
1474 /* Print type declaration. */
1475 dump_generic_node (buffer, TREE_TYPE (t), spc, flags, false);
1477 /* Print variable's name. */
1478 pp_space (buffer);
1479 dump_generic_node (buffer, t, spc, flags, false);
1482 /* The initial value of a function serves to determine wether the function
1483 is declared or defined. So the following does not apply to function
1484 nodes. */
1485 if (TREE_CODE (t) != FUNCTION_DECL)
1487 /* Print the initial value. */
1488 if (DECL_INITIAL (t))
1490 pp_space (buffer);
1491 pp_character (buffer, '=');
1492 pp_space (buffer);
1493 dump_generic_node (buffer, DECL_INITIAL (t), spc, flags, false);
1497 pp_character (buffer, ';');
1501 /* Prints a structure: name, fields, and methods.
1502 FIXME: Still incomplete. */
1504 static void
1505 print_struct_decl (pretty_printer *buffer, tree node, int spc, int flags)
1507 /* Print the name of the structure. */
1508 if (TYPE_NAME (node))
1510 INDENT (spc);
1511 if (TREE_CODE (node) == RECORD_TYPE)
1512 pp_string (buffer, "struct ");
1513 else if ((TREE_CODE (node) == UNION_TYPE
1514 || TREE_CODE (node) == QUAL_UNION_TYPE))
1515 pp_string (buffer, "union ");
1517 dump_generic_node (buffer, TYPE_NAME (node), spc, 0, false);
1520 /* Print the contents of the structure. */
1521 pp_newline (buffer);
1522 INDENT (spc);
1523 pp_character (buffer, '{');
1524 pp_newline (buffer);
1526 /* Print the fields of the structure. */
1528 tree tmp;
1529 tmp = TYPE_FIELDS (node);
1530 while (tmp)
1532 /* Avoid to print recursively the structure. */
1533 /* FIXME : Not implemented correctly...,
1534 what about the case when we have a cycle in the contain graph? ...
1535 Maybe this could be solved by looking at the scope in which the
1536 structure was declared. */
1537 if (TREE_TYPE (tmp) != node
1538 || (TREE_CODE (TREE_TYPE (tmp)) == POINTER_TYPE
1539 && TREE_TYPE (TREE_TYPE (tmp)) != node))
1541 print_declaration (buffer, tmp, spc+2, flags);
1542 pp_newline (buffer);
1544 else
1548 tmp = TREE_CHAIN (tmp);
1551 INDENT (spc);
1552 pp_character (buffer, '}');
1555 /* Return the priority of the operator OP.
1557 From lowest to highest precedence with either left-to-right (L-R)
1558 or right-to-left (R-L) associativity]:
1560 1 [L-R] ,
1561 2 [R-L] = += -= *= /= %= &= ^= |= <<= >>=
1562 3 [R-L] ?:
1563 4 [L-R] ||
1564 5 [L-R] &&
1565 6 [L-R] |
1566 7 [L-R] ^
1567 8 [L-R] &
1568 9 [L-R] == !=
1569 10 [L-R] < <= > >=
1570 11 [L-R] << >>
1571 12 [L-R] + -
1572 13 [L-R] * / %
1573 14 [R-L] ! ~ ++ -- + - * & (type) sizeof
1574 15 [L-R] fn() [] -> .
1576 unary +, - and * have higher precedence than the corresponding binary
1577 operators. */
1579 static int
1580 op_prio (tree op)
1582 if (op == NULL)
1583 return 9999;
1585 switch (TREE_CODE (op))
1587 case TREE_LIST:
1588 case COMPOUND_EXPR:
1589 case BIND_EXPR:
1590 return 1;
1592 case MODIFY_EXPR:
1593 case INIT_EXPR:
1594 return 2;
1596 case COND_EXPR:
1597 return 3;
1599 case TRUTH_OR_EXPR:
1600 case TRUTH_ORIF_EXPR:
1601 return 4;
1603 case TRUTH_AND_EXPR:
1604 case TRUTH_ANDIF_EXPR:
1605 return 5;
1607 case BIT_IOR_EXPR:
1608 return 6;
1610 case BIT_XOR_EXPR:
1611 case TRUTH_XOR_EXPR:
1612 return 7;
1614 case BIT_AND_EXPR:
1615 return 8;
1617 case EQ_EXPR:
1618 case NE_EXPR:
1619 return 9;
1621 case UNLT_EXPR:
1622 case UNLE_EXPR:
1623 case UNGT_EXPR:
1624 case UNGE_EXPR:
1625 case UNEQ_EXPR:
1626 case LTGT_EXPR:
1627 case ORDERED_EXPR:
1628 case UNORDERED_EXPR:
1629 case LT_EXPR:
1630 case LE_EXPR:
1631 case GT_EXPR:
1632 case GE_EXPR:
1633 return 10;
1635 case LSHIFT_EXPR:
1636 case RSHIFT_EXPR:
1637 case LROTATE_EXPR:
1638 case RROTATE_EXPR:
1639 return 11;
1641 case PLUS_EXPR:
1642 case MINUS_EXPR:
1643 return 12;
1645 case MULT_EXPR:
1646 case TRUNC_DIV_EXPR:
1647 case CEIL_DIV_EXPR:
1648 case FLOOR_DIV_EXPR:
1649 case ROUND_DIV_EXPR:
1650 case RDIV_EXPR:
1651 case EXACT_DIV_EXPR:
1652 case TRUNC_MOD_EXPR:
1653 case CEIL_MOD_EXPR:
1654 case FLOOR_MOD_EXPR:
1655 case ROUND_MOD_EXPR:
1656 return 13;
1658 case TRUTH_NOT_EXPR:
1659 case BIT_NOT_EXPR:
1660 case POSTINCREMENT_EXPR:
1661 case POSTDECREMENT_EXPR:
1662 case PREINCREMENT_EXPR:
1663 case PREDECREMENT_EXPR:
1664 case NEGATE_EXPR:
1665 case INDIRECT_REF:
1666 case ADDR_EXPR:
1667 case FLOAT_EXPR:
1668 case NOP_EXPR:
1669 case CONVERT_EXPR:
1670 case FIX_TRUNC_EXPR:
1671 case FIX_CEIL_EXPR:
1672 case FIX_FLOOR_EXPR:
1673 case FIX_ROUND_EXPR:
1674 case TARGET_EXPR:
1675 return 14;
1677 case CALL_EXPR:
1678 case ARRAY_REF:
1679 case ARRAY_RANGE_REF:
1680 case COMPONENT_REF:
1681 return 15;
1683 /* Special expressions. */
1684 case MIN_EXPR:
1685 case MAX_EXPR:
1686 case ABS_EXPR:
1687 case REALPART_EXPR:
1688 case IMAGPART_EXPR:
1689 return 16;
1691 case SAVE_EXPR:
1692 case NON_LVALUE_EXPR:
1693 return op_prio (TREE_OPERAND (op, 0));
1695 default:
1696 /* Return an arbitrarily high precedence to avoid surrounding single
1697 VAR_DECLs in ()s. */
1698 return 9999;
1703 /* Return the symbol associated with operator OP. */
1705 static const char *
1706 op_symbol (tree op)
1708 if (op == NULL)
1709 abort ();
1711 switch (TREE_CODE (op))
1713 case MODIFY_EXPR:
1714 return "=";
1716 case TRUTH_OR_EXPR:
1717 case TRUTH_ORIF_EXPR:
1718 return "||";
1720 case TRUTH_AND_EXPR:
1721 case TRUTH_ANDIF_EXPR:
1722 return "&&";
1724 case BIT_IOR_EXPR:
1725 return "|";
1727 case TRUTH_XOR_EXPR:
1728 case BIT_XOR_EXPR:
1729 return "^";
1731 case ADDR_EXPR:
1732 case BIT_AND_EXPR:
1733 return "&";
1735 case ORDERED_EXPR:
1736 return "ord";
1737 case UNORDERED_EXPR:
1738 return "unord";
1740 case EQ_EXPR:
1741 return "==";
1742 case UNEQ_EXPR:
1743 return "u==";
1745 case NE_EXPR:
1746 return "!=";
1748 case LT_EXPR:
1749 return "<";
1750 case UNLT_EXPR:
1751 return "u<";
1753 case LE_EXPR:
1754 return "<=";
1755 case UNLE_EXPR:
1756 return "u<=";
1758 case GT_EXPR:
1759 return ">";
1760 case UNGT_EXPR:
1761 return "u>";
1763 case GE_EXPR:
1764 return ">=";
1765 case UNGE_EXPR:
1766 return "u>=";
1768 case LTGT_EXPR:
1769 return "<>";
1771 case LSHIFT_EXPR:
1772 return "<<";
1774 case RSHIFT_EXPR:
1775 return ">>";
1777 case PLUS_EXPR:
1778 return "+";
1780 case NEGATE_EXPR:
1781 case MINUS_EXPR:
1782 return "-";
1784 case BIT_NOT_EXPR:
1785 return "~";
1787 case TRUTH_NOT_EXPR:
1788 return "!";
1790 case MULT_EXPR:
1791 case INDIRECT_REF:
1792 return "*";
1794 case TRUNC_DIV_EXPR:
1795 case CEIL_DIV_EXPR:
1796 case FLOOR_DIV_EXPR:
1797 case ROUND_DIV_EXPR:
1798 case RDIV_EXPR:
1799 case EXACT_DIV_EXPR:
1800 return "/";
1802 case TRUNC_MOD_EXPR:
1803 case CEIL_MOD_EXPR:
1804 case FLOOR_MOD_EXPR:
1805 case ROUND_MOD_EXPR:
1806 return "%";
1808 case PREDECREMENT_EXPR:
1809 return " --";
1811 case PREINCREMENT_EXPR:
1812 return " ++";
1814 case POSTDECREMENT_EXPR:
1815 return "-- ";
1817 case POSTINCREMENT_EXPR:
1818 return "++ ";
1820 case REFERENCE_EXPR:
1821 return "";
1823 default:
1824 return "<<< ??? >>>";
1828 /* Prints the name of a CALL_EXPR. */
1830 static void
1831 print_call_name (pretty_printer *buffer, tree node)
1833 tree op0;
1835 if (TREE_CODE (node) != CALL_EXPR)
1836 abort ();
1838 op0 = TREE_OPERAND (node, 0);
1840 if (TREE_CODE (op0) == NON_LVALUE_EXPR)
1841 op0 = TREE_OPERAND (op0, 0);
1843 switch (TREE_CODE (op0))
1845 case VAR_DECL:
1846 case PARM_DECL:
1847 PRINT_FUNCTION_NAME (op0);
1848 break;
1850 case ADDR_EXPR:
1851 case INDIRECT_REF:
1852 case NOP_EXPR:
1853 dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
1854 break;
1856 case COND_EXPR:
1857 pp_string (buffer, "(");
1858 dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
1859 pp_string (buffer, ") ? ");
1860 dump_generic_node (buffer, TREE_OPERAND (op0, 1), 0, 0, false);
1861 pp_string (buffer, " : ");
1862 dump_generic_node (buffer, TREE_OPERAND (op0, 2), 0, 0, false);
1863 break;
1865 case COMPONENT_REF:
1866 /* The function is a pointer contained in a structure. */
1867 if (TREE_CODE (TREE_OPERAND (op0, 0)) == INDIRECT_REF ||
1868 TREE_CODE (TREE_OPERAND (op0, 0)) == VAR_DECL)
1869 PRINT_FUNCTION_NAME (TREE_OPERAND (op0, 1));
1870 else
1871 dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
1872 /* else
1873 We can have several levels of structures and a function
1874 pointer inside. This is not implemented yet... */
1875 /* NIY;*/
1876 break;
1878 case ARRAY_REF:
1879 if (TREE_CODE (TREE_OPERAND (op0, 0)) == VAR_DECL)
1880 PRINT_FUNCTION_NAME (TREE_OPERAND (op0, 0));
1881 else
1882 dump_generic_node (buffer, op0, 0, 0, false);
1883 break;
1885 case SSA_NAME:
1886 case OBJ_TYPE_REF:
1887 dump_generic_node (buffer, op0, 0, 0, false);
1888 break;
1890 default:
1891 NIY;
1895 /* Parses the string STR and replaces new-lines by '\n', tabs by '\t', ... */
1897 static void
1898 pretty_print_string (pretty_printer *buffer, const char *str)
1900 if (str == NULL)
1901 return;
1903 while (*str)
1905 switch (str[0])
1907 case '\b':
1908 pp_string (buffer, "\\b");
1909 break;
1911 case '\f':
1912 pp_string (buffer, "\\f");
1913 break;
1915 case '\n':
1916 pp_string (buffer, "\\n");
1917 break;
1919 case '\r':
1920 pp_string (buffer, "\\r");
1921 break;
1923 case '\t':
1924 pp_string (buffer, "\\t");
1925 break;
1927 case '\v':
1928 pp_string (buffer, "\\v");
1929 break;
1931 case '\\':
1932 pp_string (buffer, "\\\\");
1933 break;
1935 case '\"':
1936 pp_string (buffer, "\\\"");
1937 break;
1939 case '\'':
1940 pp_string (buffer, "\\'");
1941 break;
1943 case '\0':
1944 pp_string (buffer, "\\0");
1945 break;
1947 case '\1':
1948 pp_string (buffer, "\\1");
1949 break;
1951 case '\2':
1952 pp_string (buffer, "\\2");
1953 break;
1955 case '\3':
1956 pp_string (buffer, "\\3");
1957 break;
1959 case '\4':
1960 pp_string (buffer, "\\4");
1961 break;
1963 case '\5':
1964 pp_string (buffer, "\\5");
1965 break;
1967 case '\6':
1968 pp_string (buffer, "\\6");
1969 break;
1971 case '\7':
1972 pp_string (buffer, "\\7");
1973 break;
1975 default:
1976 pp_character (buffer, str[0]);
1977 break;
1979 str++;
1983 static void
1984 maybe_init_pretty_print (FILE *file)
1986 if (!initialized)
1988 pp_construct (&buffer, /* prefix */NULL, /* line-width */0);
1989 pp_needs_newline (&buffer) = true;
1990 initialized = 1;
1993 buffer.buffer->stream = file;
1996 static void
1997 newline_and_indent (pretty_printer *buffer, int spc)
1999 pp_newline (buffer);
2000 INDENT (spc);
2003 static void
2004 dump_vops (pretty_printer *buffer, tree stmt, int spc, int flags)
2006 size_t i;
2007 stmt_ann_t ann = stmt_ann (stmt);
2008 v_may_def_optype v_may_defs = V_MAY_DEF_OPS (ann);
2009 v_must_def_optype v_must_defs = V_MUST_DEF_OPS (ann);
2010 vuse_optype vuses = VUSE_OPS (ann);
2012 for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++)
2014 pp_string (buffer, "# ");
2015 dump_generic_node (buffer, V_MAY_DEF_RESULT (v_may_defs, i),
2016 spc + 2, flags, false);
2017 pp_string (buffer, " = V_MAY_DEF <");
2018 dump_generic_node (buffer, V_MAY_DEF_OP (v_may_defs, i),
2019 spc + 2, flags, false);
2020 pp_string (buffer, ">;");
2021 newline_and_indent (buffer, spc);
2024 for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++)
2026 tree v_must_def = V_MUST_DEF_OP (v_must_defs, i);
2027 pp_string (buffer, "# V_MUST_DEF <");
2028 dump_generic_node (buffer, v_must_def, spc + 2, flags, false);
2029 pp_string (buffer, ">;");
2030 newline_and_indent (buffer, spc);
2033 for (i = 0; i < NUM_VUSES (vuses); i++)
2035 tree vuse = VUSE_OP (vuses, i);
2036 pp_string (buffer, "# VUSE <");
2037 dump_generic_node (buffer, vuse, spc + 2, flags, false);
2038 pp_string (buffer, ">;");
2039 newline_and_indent (buffer, spc);
2043 /* Dumps basic block BB to FILE with details described by FLAGS and
2044 indented by INDENT spaces. */
2046 void
2047 dump_generic_bb (FILE *file, basic_block bb, int indent, int flags)
2049 maybe_init_pretty_print (file);
2050 dumping_stmts = true;
2051 dump_generic_bb_buff (&buffer, bb, indent, flags);
2052 pp_flush (&buffer);
2055 /* Dumps header of basic block BB to buffer BUFFER indented by INDENT
2056 spaces and details described by flags. */
2058 static void
2059 dump_bb_header (pretty_printer *buffer, basic_block bb, int indent, int flags)
2061 edge e;
2062 tree stmt;
2064 if (flags & TDF_BLOCKS)
2066 INDENT (indent);
2067 pp_string (buffer, "# BLOCK ");
2068 pp_decimal_int (buffer, bb->index);
2070 if (flags & TDF_LINENO)
2072 block_stmt_iterator bsi;
2074 for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
2075 if (get_lineno (bsi_stmt (bsi)) != -1)
2077 pp_string (buffer, ", starting at line ");
2078 pp_decimal_int (buffer, get_lineno (bsi_stmt (bsi)));
2079 break;
2082 newline_and_indent (buffer, indent);
2084 pp_string (buffer, "# PRED:");
2085 pp_write_text_to_stream (buffer);
2086 for (e = bb->pred; e; e = e->pred_next)
2087 if (flags & TDF_SLIM)
2089 pp_string (buffer, " ");
2090 if (e->src == ENTRY_BLOCK_PTR)
2091 pp_string (buffer, "ENTRY");
2092 else
2093 pp_decimal_int (buffer, e->src->index);
2095 else
2096 dump_edge_info (buffer->buffer->stream, e, 0);
2097 pp_newline (buffer);
2099 else
2101 stmt = first_stmt (bb);
2102 if (!stmt || TREE_CODE (stmt) != LABEL_EXPR)
2104 INDENT (indent - 2);
2105 pp_string (buffer, "<bb ");
2106 pp_decimal_int (buffer, bb->index);
2107 pp_string (buffer, ">:");
2108 pp_newline (buffer);
2113 /* Dumps end of basic block BB to buffer BUFFER indented by INDENT
2114 spaces. */
2116 static void
2117 dump_bb_end (pretty_printer *buffer, basic_block bb, int indent, int flags)
2119 edge e;
2121 INDENT (indent);
2122 pp_string (buffer, "# SUCC:");
2123 pp_write_text_to_stream (buffer);
2124 for (e = bb->succ; e; e = e->succ_next)
2125 if (flags & TDF_SLIM)
2127 pp_string (buffer, " ");
2128 if (e->dest == EXIT_BLOCK_PTR)
2129 pp_string (buffer, "EXIT");
2130 else
2131 pp_decimal_int (buffer, e->dest->index);
2133 else
2134 dump_edge_info (buffer->buffer->stream, e, 1);
2135 pp_newline (buffer);
2138 /* Dumps phi nodes of basic block BB to buffer BUFFER with details described by
2139 FLAGS indented by INDENT spaces. */
2141 static void
2142 dump_phi_nodes (pretty_printer *buffer, basic_block bb, int indent, int flags)
2144 tree phi = phi_nodes (bb);
2145 if (!phi)
2146 return;
2148 for (; phi; phi = PHI_CHAIN (phi))
2150 if (is_gimple_reg (PHI_RESULT (phi)) || (flags & TDF_VOPS))
2152 INDENT (indent);
2153 pp_string (buffer, "# ");
2154 dump_generic_node (buffer, phi, indent, flags, false);
2155 pp_newline (buffer);
2160 /* Dump jump to basic block BB that is represented implicitly in the cfg
2161 to BUFFER. */
2163 static void
2164 pp_cfg_jump (pretty_printer *buffer, basic_block bb)
2166 tree stmt;
2168 stmt = first_stmt (bb);
2170 pp_string (buffer, "goto <bb ");
2171 pp_decimal_int (buffer, bb->index);
2172 pp_string (buffer, ">");
2173 if (stmt && TREE_CODE (stmt) == LABEL_EXPR)
2175 pp_string (buffer, " (");
2176 dump_generic_node (buffer, LABEL_EXPR_LABEL (stmt), 0, 0, false);
2177 pp_string (buffer, ")");
2179 pp_semicolon (buffer);
2182 /* Dump edges represented implicitly in basic block BB to BUFFER, indented
2183 by INDENT spaces, with details given by FLAGS. */
2185 static void
2186 dump_implicit_edges (pretty_printer *buffer, basic_block bb, int indent,
2187 int flags)
2189 edge e;
2191 /* If there is a fallthru edge, we may need to add an artificial goto to the
2192 dump. */
2193 for (e = bb->succ; e; e = e->succ_next)
2194 if (e->flags & EDGE_FALLTHRU)
2195 break;
2196 if (e && e->dest != bb->next_bb)
2198 INDENT (indent);
2200 if ((flags & TDF_LINENO) && e->goto_locus)
2202 pp_character (buffer, '[');
2203 if (e->goto_locus->file)
2205 pp_string (buffer, e->goto_locus->file);
2206 pp_string (buffer, " : ");
2208 pp_decimal_int (buffer, e->goto_locus->line);
2209 pp_string (buffer, "] ");
2212 pp_cfg_jump (buffer, e->dest);
2213 pp_newline (buffer);
2217 /* Dumps basic block BB to buffer BUFFER with details described by FLAGS and
2218 indented by INDENT spaces. */
2220 static void
2221 dump_generic_bb_buff (pretty_printer *buffer, basic_block bb,
2222 int indent, int flags)
2224 block_stmt_iterator bsi;
2225 tree stmt;
2226 int label_indent = indent - 2;
2228 if (label_indent < 0)
2229 label_indent = 0;
2231 dump_bb_header (buffer, bb, indent, flags);
2233 if (bb_ann (bb))
2234 dump_phi_nodes (buffer, bb, indent, flags);
2236 for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
2238 int curr_indent;
2240 stmt = bsi_stmt (bsi);
2242 curr_indent = TREE_CODE (stmt) == LABEL_EXPR ? label_indent : indent;
2244 INDENT (curr_indent);
2245 dump_generic_node (buffer, stmt, curr_indent, flags, true);
2246 pp_newline (buffer);
2249 dump_implicit_edges (buffer, bb, indent, flags);
2251 if (flags & TDF_BLOCKS)
2252 dump_bb_end (buffer, bb, indent, flags);