tree-pretty-print.c (dump_generic_node, [...]): Don't look at TYPE_METHODS unless...
[official-gcc.git] / gcc / tree-pretty-print.c
blob477c2830b32acc6867efdcff62adcf8fbc7c8321
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 ((TREE_CODE (TREE_TYPE (node)) == RECORD_TYPE
553 || TREE_CODE (TREE_TYPE (node)) == UNION_TYPE)
554 && 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 OBJ_TYPE_REF:
1371 pp_string (buffer, "OBJ_TYPE_REF(");
1372 dump_generic_node (buffer, OBJ_TYPE_REF_EXPR (node), spc, flags, false);
1373 pp_character (buffer, ';');
1374 dump_generic_node (buffer, OBJ_TYPE_REF_OBJECT (node), spc, flags, false);
1375 pp_character (buffer, '-');
1376 pp_character (buffer, '>');
1377 dump_generic_node (buffer, OBJ_TYPE_REF_TOKEN (node), spc, flags, false);
1378 pp_character (buffer, ')');
1379 break;
1381 case PHI_NODE:
1383 int i;
1385 dump_generic_node (buffer, PHI_RESULT (node), spc, flags, false);
1386 pp_string (buffer, " = PHI <");
1387 for (i = 0; i < PHI_NUM_ARGS (node); i++)
1389 dump_generic_node (buffer, PHI_ARG_DEF (node, i), spc, flags, false);
1390 pp_string (buffer, "(");
1391 pp_decimal_int (buffer, PHI_ARG_EDGE (node, i)->src->index);
1392 pp_string (buffer, ")");
1393 if (i < PHI_NUM_ARGS (node) - 1)
1394 pp_string (buffer, ", ");
1396 pp_string (buffer, ">;");
1398 break;
1400 case SSA_NAME:
1401 dump_generic_node (buffer, SSA_NAME_VAR (node), spc, flags, false);
1402 pp_string (buffer, "_");
1403 pp_decimal_int (buffer, SSA_NAME_VERSION (node));
1404 break;
1406 case VALUE_HANDLE:
1407 pp_printf (buffer, "VH.%d", VALUE_HANDLE_ID (node));
1408 break;
1410 default:
1411 NIY;
1414 if (is_stmt && is_expr)
1415 pp_semicolon (buffer);
1416 pp_write_text_to_stream (buffer);
1418 return spc;
1421 /* Print the declaration of a variable. */
1423 static void
1424 print_declaration (pretty_printer *buffer, tree t, int spc, int flags)
1426 /* Don't print type declarations. */
1427 if (TREE_CODE (t) == TYPE_DECL)
1428 return;
1430 INDENT (spc);
1432 if (DECL_REGISTER (t))
1433 pp_string (buffer, "register ");
1435 if (TREE_PUBLIC (t) && DECL_EXTERNAL (t))
1436 pp_string (buffer, "extern ");
1437 else if (TREE_STATIC (t))
1438 pp_string (buffer, "static ");
1440 /* Print the type and name. */
1441 if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
1443 tree tmp;
1445 /* Print array's type. */
1446 tmp = TREE_TYPE (t);
1447 while (TREE_CODE (TREE_TYPE (tmp)) == ARRAY_TYPE)
1448 tmp = TREE_TYPE (tmp);
1449 dump_generic_node (buffer, TREE_TYPE (tmp), spc, flags, false);
1451 /* Print variable's name. */
1452 pp_space (buffer);
1453 dump_generic_node (buffer, t, spc, flags, false);
1455 /* Print the dimensions. */
1456 tmp = TREE_TYPE (t);
1457 while (TREE_CODE (tmp) == ARRAY_TYPE)
1459 pp_character (buffer, '[');
1460 if (TYPE_DOMAIN (tmp))
1462 if (TREE_CODE (TYPE_SIZE (tmp)) == INTEGER_CST)
1463 pp_wide_integer (buffer,
1464 TREE_INT_CST_LOW (TYPE_SIZE (tmp)) /
1465 TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (tmp))));
1466 else
1467 dump_generic_node (buffer, TYPE_SIZE_UNIT (tmp), spc, flags,
1468 false);
1470 pp_character (buffer, ']');
1471 tmp = TREE_TYPE (tmp);
1474 else
1476 /* Print type declaration. */
1477 dump_generic_node (buffer, TREE_TYPE (t), spc, flags, false);
1479 /* Print variable's name. */
1480 pp_space (buffer);
1481 dump_generic_node (buffer, t, spc, flags, false);
1484 /* The initial value of a function serves to determine wether the function
1485 is declared or defined. So the following does not apply to function
1486 nodes. */
1487 if (TREE_CODE (t) != FUNCTION_DECL)
1489 /* Print the initial value. */
1490 if (DECL_INITIAL (t))
1492 pp_space (buffer);
1493 pp_character (buffer, '=');
1494 pp_space (buffer);
1495 dump_generic_node (buffer, DECL_INITIAL (t), spc, flags, false);
1499 pp_character (buffer, ';');
1503 /* Prints a structure: name, fields, and methods.
1504 FIXME: Still incomplete. */
1506 static void
1507 print_struct_decl (pretty_printer *buffer, tree node, int spc, int flags)
1509 /* Print the name of the structure. */
1510 if (TYPE_NAME (node))
1512 INDENT (spc);
1513 if (TREE_CODE (node) == RECORD_TYPE)
1514 pp_string (buffer, "struct ");
1515 else if ((TREE_CODE (node) == UNION_TYPE
1516 || TREE_CODE (node) == QUAL_UNION_TYPE))
1517 pp_string (buffer, "union ");
1519 dump_generic_node (buffer, TYPE_NAME (node), spc, 0, false);
1522 /* Print the contents of the structure. */
1523 pp_newline (buffer);
1524 INDENT (spc);
1525 pp_character (buffer, '{');
1526 pp_newline (buffer);
1528 /* Print the fields of the structure. */
1530 tree tmp;
1531 tmp = TYPE_FIELDS (node);
1532 while (tmp)
1534 /* Avoid to print recursively the structure. */
1535 /* FIXME : Not implemented correctly...,
1536 what about the case when we have a cycle in the contain graph? ...
1537 Maybe this could be solved by looking at the scope in which the
1538 structure was declared. */
1539 if (TREE_TYPE (tmp) != node
1540 || (TREE_CODE (TREE_TYPE (tmp)) == POINTER_TYPE
1541 && TREE_TYPE (TREE_TYPE (tmp)) != node))
1543 print_declaration (buffer, tmp, spc+2, flags);
1544 pp_newline (buffer);
1546 else
1550 tmp = TREE_CHAIN (tmp);
1553 INDENT (spc);
1554 pp_character (buffer, '}');
1557 /* Return the priority of the operator OP.
1559 From lowest to highest precedence with either left-to-right (L-R)
1560 or right-to-left (R-L) associativity]:
1562 1 [L-R] ,
1563 2 [R-L] = += -= *= /= %= &= ^= |= <<= >>=
1564 3 [R-L] ?:
1565 4 [L-R] ||
1566 5 [L-R] &&
1567 6 [L-R] |
1568 7 [L-R] ^
1569 8 [L-R] &
1570 9 [L-R] == !=
1571 10 [L-R] < <= > >=
1572 11 [L-R] << >>
1573 12 [L-R] + -
1574 13 [L-R] * / %
1575 14 [R-L] ! ~ ++ -- + - * & (type) sizeof
1576 15 [L-R] fn() [] -> .
1578 unary +, - and * have higher precedence than the corresponding binary
1579 operators. */
1581 static int
1582 op_prio (tree op)
1584 if (op == NULL)
1585 return 9999;
1587 switch (TREE_CODE (op))
1589 case TREE_LIST:
1590 case COMPOUND_EXPR:
1591 case BIND_EXPR:
1592 return 1;
1594 case MODIFY_EXPR:
1595 case INIT_EXPR:
1596 return 2;
1598 case COND_EXPR:
1599 return 3;
1601 case TRUTH_OR_EXPR:
1602 case TRUTH_ORIF_EXPR:
1603 return 4;
1605 case TRUTH_AND_EXPR:
1606 case TRUTH_ANDIF_EXPR:
1607 return 5;
1609 case BIT_IOR_EXPR:
1610 return 6;
1612 case BIT_XOR_EXPR:
1613 case TRUTH_XOR_EXPR:
1614 return 7;
1616 case BIT_AND_EXPR:
1617 return 8;
1619 case EQ_EXPR:
1620 case NE_EXPR:
1621 return 9;
1623 case UNLT_EXPR:
1624 case UNLE_EXPR:
1625 case UNGT_EXPR:
1626 case UNGE_EXPR:
1627 case UNEQ_EXPR:
1628 case LTGT_EXPR:
1629 case ORDERED_EXPR:
1630 case UNORDERED_EXPR:
1631 case LT_EXPR:
1632 case LE_EXPR:
1633 case GT_EXPR:
1634 case GE_EXPR:
1635 return 10;
1637 case LSHIFT_EXPR:
1638 case RSHIFT_EXPR:
1639 case LROTATE_EXPR:
1640 case RROTATE_EXPR:
1641 return 11;
1643 case PLUS_EXPR:
1644 case MINUS_EXPR:
1645 return 12;
1647 case MULT_EXPR:
1648 case TRUNC_DIV_EXPR:
1649 case CEIL_DIV_EXPR:
1650 case FLOOR_DIV_EXPR:
1651 case ROUND_DIV_EXPR:
1652 case RDIV_EXPR:
1653 case EXACT_DIV_EXPR:
1654 case TRUNC_MOD_EXPR:
1655 case CEIL_MOD_EXPR:
1656 case FLOOR_MOD_EXPR:
1657 case ROUND_MOD_EXPR:
1658 return 13;
1660 case TRUTH_NOT_EXPR:
1661 case BIT_NOT_EXPR:
1662 case POSTINCREMENT_EXPR:
1663 case POSTDECREMENT_EXPR:
1664 case PREINCREMENT_EXPR:
1665 case PREDECREMENT_EXPR:
1666 case NEGATE_EXPR:
1667 case INDIRECT_REF:
1668 case ADDR_EXPR:
1669 case FLOAT_EXPR:
1670 case NOP_EXPR:
1671 case CONVERT_EXPR:
1672 case FIX_TRUNC_EXPR:
1673 case FIX_CEIL_EXPR:
1674 case FIX_FLOOR_EXPR:
1675 case FIX_ROUND_EXPR:
1676 case TARGET_EXPR:
1677 return 14;
1679 case CALL_EXPR:
1680 case ARRAY_REF:
1681 case ARRAY_RANGE_REF:
1682 case COMPONENT_REF:
1683 return 15;
1685 /* Special expressions. */
1686 case MIN_EXPR:
1687 case MAX_EXPR:
1688 case ABS_EXPR:
1689 case REALPART_EXPR:
1690 case IMAGPART_EXPR:
1691 return 16;
1693 case SAVE_EXPR:
1694 case NON_LVALUE_EXPR:
1695 return op_prio (TREE_OPERAND (op, 0));
1697 default:
1698 /* Return an arbitrarily high precedence to avoid surrounding single
1699 VAR_DECLs in ()s. */
1700 return 9999;
1705 /* Return the symbol associated with operator OP. */
1707 static const char *
1708 op_symbol (tree op)
1710 if (op == NULL)
1711 abort ();
1713 switch (TREE_CODE (op))
1715 case MODIFY_EXPR:
1716 return "=";
1718 case TRUTH_OR_EXPR:
1719 case TRUTH_ORIF_EXPR:
1720 return "||";
1722 case TRUTH_AND_EXPR:
1723 case TRUTH_ANDIF_EXPR:
1724 return "&&";
1726 case BIT_IOR_EXPR:
1727 return "|";
1729 case TRUTH_XOR_EXPR:
1730 case BIT_XOR_EXPR:
1731 return "^";
1733 case ADDR_EXPR:
1734 case BIT_AND_EXPR:
1735 return "&";
1737 case ORDERED_EXPR:
1738 return "ord";
1739 case UNORDERED_EXPR:
1740 return "unord";
1742 case EQ_EXPR:
1743 return "==";
1744 case UNEQ_EXPR:
1745 return "u==";
1747 case NE_EXPR:
1748 return "!=";
1750 case LT_EXPR:
1751 return "<";
1752 case UNLT_EXPR:
1753 return "u<";
1755 case LE_EXPR:
1756 return "<=";
1757 case UNLE_EXPR:
1758 return "u<=";
1760 case GT_EXPR:
1761 return ">";
1762 case UNGT_EXPR:
1763 return "u>";
1765 case GE_EXPR:
1766 return ">=";
1767 case UNGE_EXPR:
1768 return "u>=";
1770 case LTGT_EXPR:
1771 return "<>";
1773 case LSHIFT_EXPR:
1774 return "<<";
1776 case RSHIFT_EXPR:
1777 return ">>";
1779 case PLUS_EXPR:
1780 return "+";
1782 case NEGATE_EXPR:
1783 case MINUS_EXPR:
1784 return "-";
1786 case BIT_NOT_EXPR:
1787 return "~";
1789 case TRUTH_NOT_EXPR:
1790 return "!";
1792 case MULT_EXPR:
1793 case INDIRECT_REF:
1794 return "*";
1796 case TRUNC_DIV_EXPR:
1797 case CEIL_DIV_EXPR:
1798 case FLOOR_DIV_EXPR:
1799 case ROUND_DIV_EXPR:
1800 case RDIV_EXPR:
1801 case EXACT_DIV_EXPR:
1802 return "/";
1804 case TRUNC_MOD_EXPR:
1805 case CEIL_MOD_EXPR:
1806 case FLOOR_MOD_EXPR:
1807 case ROUND_MOD_EXPR:
1808 return "%";
1810 case PREDECREMENT_EXPR:
1811 return " --";
1813 case PREINCREMENT_EXPR:
1814 return " ++";
1816 case POSTDECREMENT_EXPR:
1817 return "-- ";
1819 case POSTINCREMENT_EXPR:
1820 return "++ ";
1822 case REFERENCE_EXPR:
1823 return "";
1825 default:
1826 return "<<< ??? >>>";
1830 /* Prints the name of a CALL_EXPR. */
1832 static void
1833 print_call_name (pretty_printer *buffer, tree node)
1835 tree op0;
1837 if (TREE_CODE (node) != CALL_EXPR)
1838 abort ();
1840 op0 = TREE_OPERAND (node, 0);
1842 if (TREE_CODE (op0) == NON_LVALUE_EXPR)
1843 op0 = TREE_OPERAND (op0, 0);
1845 switch (TREE_CODE (op0))
1847 case VAR_DECL:
1848 case PARM_DECL:
1849 PRINT_FUNCTION_NAME (op0);
1850 break;
1852 case ADDR_EXPR:
1853 case INDIRECT_REF:
1854 case NOP_EXPR:
1855 dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
1856 break;
1858 case COND_EXPR:
1859 pp_string (buffer, "(");
1860 dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
1861 pp_string (buffer, ") ? ");
1862 dump_generic_node (buffer, TREE_OPERAND (op0, 1), 0, 0, false);
1863 pp_string (buffer, " : ");
1864 dump_generic_node (buffer, TREE_OPERAND (op0, 2), 0, 0, false);
1865 break;
1867 case COMPONENT_REF:
1868 /* The function is a pointer contained in a structure. */
1869 if (TREE_CODE (TREE_OPERAND (op0, 0)) == INDIRECT_REF ||
1870 TREE_CODE (TREE_OPERAND (op0, 0)) == VAR_DECL)
1871 PRINT_FUNCTION_NAME (TREE_OPERAND (op0, 1));
1872 else
1873 dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
1874 /* else
1875 We can have several levels of structures and a function
1876 pointer inside. This is not implemented yet... */
1877 /* NIY;*/
1878 break;
1880 case ARRAY_REF:
1881 if (TREE_CODE (TREE_OPERAND (op0, 0)) == VAR_DECL)
1882 PRINT_FUNCTION_NAME (TREE_OPERAND (op0, 0));
1883 else
1884 dump_generic_node (buffer, op0, 0, 0, false);
1885 break;
1887 case SSA_NAME:
1888 case OBJ_TYPE_REF:
1889 dump_generic_node (buffer, op0, 0, 0, false);
1890 break;
1892 default:
1893 NIY;
1897 /* Parses the string STR and replaces new-lines by '\n', tabs by '\t', ... */
1899 static void
1900 pretty_print_string (pretty_printer *buffer, const char *str)
1902 if (str == NULL)
1903 return;
1905 while (*str)
1907 switch (str[0])
1909 case '\b':
1910 pp_string (buffer, "\\b");
1911 break;
1913 case '\f':
1914 pp_string (buffer, "\\f");
1915 break;
1917 case '\n':
1918 pp_string (buffer, "\\n");
1919 break;
1921 case '\r':
1922 pp_string (buffer, "\\r");
1923 break;
1925 case '\t':
1926 pp_string (buffer, "\\t");
1927 break;
1929 case '\v':
1930 pp_string (buffer, "\\v");
1931 break;
1933 case '\\':
1934 pp_string (buffer, "\\\\");
1935 break;
1937 case '\"':
1938 pp_string (buffer, "\\\"");
1939 break;
1941 case '\'':
1942 pp_string (buffer, "\\'");
1943 break;
1945 case '\0':
1946 pp_string (buffer, "\\0");
1947 break;
1949 case '\1':
1950 pp_string (buffer, "\\1");
1951 break;
1953 case '\2':
1954 pp_string (buffer, "\\2");
1955 break;
1957 case '\3':
1958 pp_string (buffer, "\\3");
1959 break;
1961 case '\4':
1962 pp_string (buffer, "\\4");
1963 break;
1965 case '\5':
1966 pp_string (buffer, "\\5");
1967 break;
1969 case '\6':
1970 pp_string (buffer, "\\6");
1971 break;
1973 case '\7':
1974 pp_string (buffer, "\\7");
1975 break;
1977 default:
1978 pp_character (buffer, str[0]);
1979 break;
1981 str++;
1985 static void
1986 maybe_init_pretty_print (FILE *file)
1988 if (!initialized)
1990 pp_construct (&buffer, /* prefix */NULL, /* line-width */0);
1991 pp_needs_newline (&buffer) = true;
1992 initialized = 1;
1995 buffer.buffer->stream = file;
1998 static void
1999 newline_and_indent (pretty_printer *buffer, int spc)
2001 pp_newline (buffer);
2002 INDENT (spc);
2005 static void
2006 dump_vops (pretty_printer *buffer, tree stmt, int spc, int flags)
2008 size_t i;
2009 stmt_ann_t ann = stmt_ann (stmt);
2010 v_may_def_optype v_may_defs = V_MAY_DEF_OPS (ann);
2011 v_must_def_optype v_must_defs = V_MUST_DEF_OPS (ann);
2012 vuse_optype vuses = VUSE_OPS (ann);
2014 for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++)
2016 pp_string (buffer, "# ");
2017 dump_generic_node (buffer, V_MAY_DEF_RESULT (v_may_defs, i),
2018 spc + 2, flags, false);
2019 pp_string (buffer, " = V_MAY_DEF <");
2020 dump_generic_node (buffer, V_MAY_DEF_OP (v_may_defs, i),
2021 spc + 2, flags, false);
2022 pp_string (buffer, ">;");
2023 newline_and_indent (buffer, spc);
2026 for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++)
2028 tree v_must_def = V_MUST_DEF_OP (v_must_defs, i);
2029 pp_string (buffer, "# V_MUST_DEF <");
2030 dump_generic_node (buffer, v_must_def, spc + 2, flags, false);
2031 pp_string (buffer, ">;");
2032 newline_and_indent (buffer, spc);
2035 for (i = 0; i < NUM_VUSES (vuses); i++)
2037 tree vuse = VUSE_OP (vuses, i);
2038 pp_string (buffer, "# VUSE <");
2039 dump_generic_node (buffer, vuse, spc + 2, flags, false);
2040 pp_string (buffer, ">;");
2041 newline_and_indent (buffer, spc);
2045 /* Dumps basic block BB to FILE with details described by FLAGS and
2046 indented by INDENT spaces. */
2048 void
2049 dump_generic_bb (FILE *file, basic_block bb, int indent, int flags)
2051 maybe_init_pretty_print (file);
2052 dumping_stmts = true;
2053 dump_generic_bb_buff (&buffer, bb, indent, flags);
2054 pp_flush (&buffer);
2057 /* Dumps header of basic block BB to buffer BUFFER indented by INDENT
2058 spaces and details described by flags. */
2060 static void
2061 dump_bb_header (pretty_printer *buffer, basic_block bb, int indent, int flags)
2063 edge e;
2064 tree stmt;
2066 if (flags & TDF_BLOCKS)
2068 INDENT (indent);
2069 pp_string (buffer, "# BLOCK ");
2070 pp_decimal_int (buffer, bb->index);
2072 if (flags & TDF_LINENO)
2074 block_stmt_iterator bsi;
2076 for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
2077 if (get_lineno (bsi_stmt (bsi)) != -1)
2079 pp_string (buffer, ", starting at line ");
2080 pp_decimal_int (buffer, get_lineno (bsi_stmt (bsi)));
2081 break;
2084 newline_and_indent (buffer, indent);
2086 pp_string (buffer, "# PRED:");
2087 pp_write_text_to_stream (buffer);
2088 for (e = bb->pred; e; e = e->pred_next)
2089 if (flags & TDF_SLIM)
2091 pp_string (buffer, " ");
2092 if (e->src == ENTRY_BLOCK_PTR)
2093 pp_string (buffer, "ENTRY");
2094 else
2095 pp_decimal_int (buffer, e->src->index);
2097 else
2098 dump_edge_info (buffer->buffer->stream, e, 0);
2099 pp_newline (buffer);
2101 else
2103 stmt = first_stmt (bb);
2104 if (!stmt || TREE_CODE (stmt) != LABEL_EXPR)
2106 INDENT (indent - 2);
2107 pp_string (buffer, "<bb ");
2108 pp_decimal_int (buffer, bb->index);
2109 pp_string (buffer, ">:");
2110 pp_newline (buffer);
2115 /* Dumps end of basic block BB to buffer BUFFER indented by INDENT
2116 spaces. */
2118 static void
2119 dump_bb_end (pretty_printer *buffer, basic_block bb, int indent, int flags)
2121 edge e;
2123 INDENT (indent);
2124 pp_string (buffer, "# SUCC:");
2125 pp_write_text_to_stream (buffer);
2126 for (e = bb->succ; e; e = e->succ_next)
2127 if (flags & TDF_SLIM)
2129 pp_string (buffer, " ");
2130 if (e->dest == EXIT_BLOCK_PTR)
2131 pp_string (buffer, "EXIT");
2132 else
2133 pp_decimal_int (buffer, e->dest->index);
2135 else
2136 dump_edge_info (buffer->buffer->stream, e, 1);
2137 pp_newline (buffer);
2140 /* Dumps phi nodes of basic block BB to buffer BUFFER with details described by
2141 FLAGS indented by INDENT spaces. */
2143 static void
2144 dump_phi_nodes (pretty_printer *buffer, basic_block bb, int indent, int flags)
2146 tree phi = phi_nodes (bb);
2147 if (!phi)
2148 return;
2150 for (; phi; phi = PHI_CHAIN (phi))
2152 if (is_gimple_reg (PHI_RESULT (phi)) || (flags & TDF_VOPS))
2154 INDENT (indent);
2155 pp_string (buffer, "# ");
2156 dump_generic_node (buffer, phi, indent, flags, false);
2157 pp_newline (buffer);
2162 /* Dump jump to basic block BB that is represented implicitly in the cfg
2163 to BUFFER. */
2165 static void
2166 pp_cfg_jump (pretty_printer *buffer, basic_block bb)
2168 tree stmt;
2170 stmt = first_stmt (bb);
2172 pp_string (buffer, "goto <bb ");
2173 pp_decimal_int (buffer, bb->index);
2174 pp_string (buffer, ">");
2175 if (stmt && TREE_CODE (stmt) == LABEL_EXPR)
2177 pp_string (buffer, " (");
2178 dump_generic_node (buffer, LABEL_EXPR_LABEL (stmt), 0, 0, false);
2179 pp_string (buffer, ")");
2181 pp_semicolon (buffer);
2184 /* Dump edges represented implicitly in basic block BB to BUFFER, indented
2185 by INDENT spaces, with details given by FLAGS. */
2187 static void
2188 dump_implicit_edges (pretty_printer *buffer, basic_block bb, int indent,
2189 int flags)
2191 edge e;
2193 /* If there is a fallthru edge, we may need to add an artificial goto to the
2194 dump. */
2195 for (e = bb->succ; e; e = e->succ_next)
2196 if (e->flags & EDGE_FALLTHRU)
2197 break;
2198 if (e && e->dest != bb->next_bb)
2200 INDENT (indent);
2202 if ((flags & TDF_LINENO) && e->goto_locus)
2204 pp_character (buffer, '[');
2205 if (e->goto_locus->file)
2207 pp_string (buffer, e->goto_locus->file);
2208 pp_string (buffer, " : ");
2210 pp_decimal_int (buffer, e->goto_locus->line);
2211 pp_string (buffer, "] ");
2214 pp_cfg_jump (buffer, e->dest);
2215 pp_newline (buffer);
2219 /* Dumps basic block BB to buffer BUFFER with details described by FLAGS and
2220 indented by INDENT spaces. */
2222 static void
2223 dump_generic_bb_buff (pretty_printer *buffer, basic_block bb,
2224 int indent, int flags)
2226 block_stmt_iterator bsi;
2227 tree stmt;
2228 int label_indent = indent - 2;
2230 if (label_indent < 0)
2231 label_indent = 0;
2233 dump_bb_header (buffer, bb, indent, flags);
2235 if (bb_ann (bb))
2236 dump_phi_nodes (buffer, bb, indent, flags);
2238 for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
2240 int curr_indent;
2242 stmt = bsi_stmt (bsi);
2244 curr_indent = TREE_CODE (stmt) == LABEL_EXPR ? label_indent : indent;
2246 INDENT (curr_indent);
2247 dump_generic_node (buffer, stmt, curr_indent, flags, true);
2248 pp_newline (buffer);
2251 dump_implicit_edges (buffer, bb, indent, flags);
2253 if (flags & TDF_BLOCKS)
2254 dump_bb_end (buffer, bb, indent, flags);