]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/tree-pretty-print.c
Daily bump.
[thirdparty/gcc.git] / gcc / tree-pretty-print.c
CommitLineData
4ee9c684 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>
4
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify it under
8the terms of the GNU General Public License as published by the Free
9Software Foundation; either version 2, or (at your option) any later
10version.
11
12GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13WARRANTY; without even the implied warranty of MERCHANTABILITY or
14FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15for more details.
16
17You should have received a copy of the GNU General Public License
18along with GCC; see the file COPYING. If not, write to the Free
19Software Foundation, 59 Temple Place - Suite 330, Boston, MA
2002111-1307, USA. */
21
22#include "config.h"
23#include "system.h"
24#include "coretypes.h"
25#include "tm.h"
26#include "errors.h"
27#include "tree.h"
28#include "diagnostic.h"
29#include "real.h"
30#include "hashtab.h"
31#include "tree-flow.h"
32#include "langhooks.h"
33#include "tree-iterator.h"
34
35/* Local functions, macros and variables. */
36static int op_prio (tree);
37static const char *op_symbol (tree);
38static void pretty_print_string (pretty_printer *, const char*);
39static void print_call_name (pretty_printer *, tree);
40static void newline_and_indent (pretty_printer *, int);
41static void maybe_init_pretty_print (FILE *);
42static void print_declaration (pretty_printer *, tree, int, int);
43static void print_struct_decl (pretty_printer *, tree, int, int);
44static void do_niy (pretty_printer *, tree);
45static void dump_vops (pretty_printer *, tree, int, int);
46static void dump_generic_bb_buff (pretty_printer *, basic_block, int, int);
47
48#define INDENT(SPACE) do { \
49 int i; for (i = 0; i<SPACE; i++) pp_space (buffer); } while (0)
50
51#define NIY do_niy(buffer,node)
52
53#define PRINT_FUNCTION_NAME(NODE) pp_printf \
54 (buffer, "%s", TREE_CODE (NODE) == NOP_EXPR ? \
5135beeb 55 lang_hooks.decl_printable_name (TREE_OPERAND (NODE, 0), 1) : \
56 lang_hooks.decl_printable_name (NODE, 1))
4ee9c684 57
58#define MASK_POINTER(P) ((unsigned)((unsigned long)(P) & 0xffff))
59
60static pretty_printer buffer;
61static int initialized = 0;
62static bool dumping_stmts;
63
64/* Try to print something for an unknown tree code. */
65
66static void
67do_niy (pretty_printer *buffer, tree node)
68{
69 int i, len;
70
71 pp_string (buffer, "<<< Unknown tree: ");
72 pp_string (buffer, tree_code_name[(int) TREE_CODE (node)]);
73
74 if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (node))))
75 {
76 len = first_rtl_op (TREE_CODE (node));
77 for (i = 0; i < len; ++i)
78 {
79 newline_and_indent (buffer, 2);
80 dump_generic_node (buffer, TREE_OPERAND (node, i), 2, 0, false);
81 }
82 }
83
84 pp_string (buffer, " >>>\n");
85}
86
87void
88debug_generic_expr (tree t)
89{
90 print_generic_expr (stderr, t, TDF_VOPS|TDF_UID);
91 fprintf (stderr, "\n");
92}
93
94void
95debug_generic_stmt (tree t)
96{
97 print_generic_stmt (stderr, t, TDF_VOPS|TDF_UID);
98 fprintf (stderr, "\n");
99}
100
101/* Prints declaration DECL to the FILE with details specified by FLAGS. */
102void
103print_generic_decl (FILE *file, tree decl, int flags)
104{
105 maybe_init_pretty_print (file);
106 dumping_stmts = true;
107 print_declaration (&buffer, decl, 2, flags);
108 pp_write_text_to_stream (&buffer);
109}
110
111/* Print tree T, and its successors, on file FILE. FLAGS specifies details
112 to show in the dump. See TDF_* in tree.h. */
113
114void
115print_generic_stmt (FILE *file, tree t, int flags)
116{
117 maybe_init_pretty_print (file);
118 dumping_stmts = true;
119 dump_generic_node (&buffer, t, 0, flags, true);
120 pp_flush (&buffer);
121}
122
123/* Print tree T, and its successors, on file FILE. FLAGS specifies details
124 to show in the dump. See TDF_* in tree.h. The output is indented by
125 INDENT spaces. */
126
127void
128print_generic_stmt_indented (FILE *file, tree t, int flags, int indent)
129{
130 int i;
131
132 maybe_init_pretty_print (file);
133 dumping_stmts = true;
134
135 for (i = 0; i < indent; i++)
136 pp_space (&buffer);
137 dump_generic_node (&buffer, t, indent, flags, true);
138 pp_flush (&buffer);
139}
140
141/* Print a single expression T on file FILE. FLAGS specifies details to show
142 in the dump. See TDF_* in tree.h. */
143
144void
145print_generic_expr (FILE *file, tree t, int flags)
146{
147 maybe_init_pretty_print (file);
148 dumping_stmts = false;
149 dump_generic_node (&buffer, t, 0, flags, false);
150}
151
152/* Dump the name of a _DECL node and its DECL_UID if TDF_UID is set
153 in FLAGS. */
154
155static void
156dump_decl_name (pretty_printer *buffer, tree node, int flags)
157{
158 if (DECL_NAME (node))
159 pp_tree_identifier (buffer, DECL_NAME (node));
160
161 if ((flags & TDF_UID)
162 || DECL_NAME (node) == NULL_TREE)
163 {
164 if (TREE_CODE (node) == LABEL_DECL
165 && LABEL_DECL_UID (node) != -1)
166 pp_printf (buffer, "<L" HOST_WIDE_INT_PRINT_DEC ">",
167 LABEL_DECL_UID (node));
168 else
169 pp_printf (buffer, "<D%u>", DECL_UID (node));
170 }
171}
172
173/* Dump the node NODE on the pretty_printer BUFFER, SPC spaces of indent.
174 FLAGS specifies details to show in the dump (see TDF_* in tree.h). If
175 IS_STMT is true, the object printed is considered to be a statement
176 and it is terminated by ';' if appropriate. */
177
178int
179dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
180 bool is_stmt)
181{
182 tree type;
183 tree op0, op1;
184 const char* str;
185 bool is_expr;
186
187 if (node == NULL_TREE)
188 return spc;
189
190 is_expr = EXPR_P (node);
191
192 if (TREE_CODE (node) != ERROR_MARK
193 && is_gimple_stmt (node)
194 && (flags & TDF_VOPS)
195 && stmt_ann (node))
196 dump_vops (buffer, node, spc, flags);
197
198 if (dumping_stmts
199 && (flags & TDF_LINENO)
200 && EXPR_HAS_LOCATION (node))
201 {
202 pp_character (buffer, '[');
203 if (EXPR_FILENAME (node))
204 {
205 pp_string (buffer, EXPR_FILENAME (node));
206 pp_string (buffer, " : ");
207 }
208 pp_decimal_int (buffer, EXPR_LINENO (node));
209 pp_string (buffer, "] ");
210 }
211
212 switch (TREE_CODE (node))
213 {
214 case ERROR_MARK:
215 pp_string (buffer, "<<< error >>>");
216 break;
217
218 case IDENTIFIER_NODE:
219 pp_tree_identifier (buffer, node);
220 break;
221
222 case TREE_LIST:
223 while (node && node != error_mark_node)
224 {
225 if (TREE_PURPOSE (node))
226 {
227 dump_generic_node (buffer, TREE_PURPOSE (node), spc, flags, false);
228 pp_space (buffer);
229 }
230 dump_generic_node (buffer, TREE_VALUE (node), spc, flags, false);
231 node = TREE_CHAIN (node);
232 if (node && TREE_CODE (node) == TREE_LIST)
233 {
234 pp_character (buffer, ',');
235 pp_space (buffer);
236 }
237 }
238 break;
239
240 case TREE_VEC:
241 dump_generic_node (buffer, BINFO_TYPE (node), spc, flags, false);
242 break;
243
244 case BLOCK:
245 NIY;
246 break;
247
248 case VOID_TYPE:
249 case INTEGER_TYPE:
250 case REAL_TYPE:
251 case COMPLEX_TYPE:
252 case VECTOR_TYPE:
253 case ENUMERAL_TYPE:
254 case BOOLEAN_TYPE:
255 case CHAR_TYPE:
256 {
257 unsigned int quals = TYPE_QUALS (node);
258 char class;
259
260 if (quals & TYPE_QUAL_CONST)
261 pp_string (buffer, "const ");
262 else if (quals & TYPE_QUAL_VOLATILE)
263 pp_string (buffer, "volatile ");
264 else if (quals & TYPE_QUAL_RESTRICT)
265 pp_string (buffer, "restrict ");
266
267 class = TREE_CODE_CLASS (TREE_CODE (node));
268
269 if (class == 'd')
270 {
271 if (DECL_NAME (node))
272 dump_decl_name (buffer, node, flags);
273 else
274 pp_string (buffer, "<unnamed type decl>");
275 }
276 else if (class == 't')
277 {
278 if (TYPE_NAME (node))
279 {
280 if (TREE_CODE (TYPE_NAME (node)) == IDENTIFIER_NODE)
281 pp_tree_identifier (buffer, TYPE_NAME (node));
282 else if (TREE_CODE (TYPE_NAME (node)) == TYPE_DECL
283 && DECL_NAME (TYPE_NAME (node)))
284 dump_decl_name (buffer, TYPE_NAME (node), flags);
285 else
286 pp_string (buffer, "<unnamed type>");
287 }
288 else
289 pp_string (buffer, "<unnamed type>");
290 }
291 break;
292 }
293
294 case POINTER_TYPE:
295 case REFERENCE_TYPE:
296 str = (TREE_CODE (node) == POINTER_TYPE ? "*" : "&");
297
298 if (TREE_CODE (TREE_TYPE (node)) == FUNCTION_TYPE)
299 {
300 tree fnode = TREE_TYPE (node);
301 dump_generic_node (buffer, TREE_TYPE (fnode), spc, flags, false);
302 pp_space (buffer);
303 pp_character (buffer, '(');
304 pp_string (buffer, str);
305 if (TYPE_NAME (node) && DECL_NAME (TYPE_NAME (node)))
306 dump_decl_name (buffer, TYPE_NAME (node), flags);
307 else
308 pp_printf (buffer, "<T%x>", TYPE_UID (node));
309
310 pp_character (buffer, ')');
311 pp_space (buffer);
312 pp_character (buffer, '(');
313 /* Print the argument types. The last element in the list is a
314 VOID_TYPE. The following avoid to print the last element. */
315 {
316 tree tmp = TYPE_ARG_TYPES (fnode);
317 while (tmp && TREE_CHAIN (tmp) && tmp != error_mark_node)
318 {
319 dump_generic_node (buffer, TREE_VALUE (tmp), spc, flags, false);
320 tmp = TREE_CHAIN (tmp);
321 if (TREE_CHAIN (tmp) && TREE_CODE (TREE_CHAIN (tmp)) == TREE_LIST)
322 {
323 pp_character (buffer, ',');
324 pp_space (buffer);
325 }
326 }
327 }
328 pp_character (buffer, ')');
329 }
330 else
331 {
332 unsigned int quals = TYPE_QUALS (node);
333
334 dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
335 pp_space (buffer);
336 pp_string (buffer, str);
337
338 if (quals & TYPE_QUAL_CONST)
339 pp_string (buffer, " const");
340 else if (quals & TYPE_QUAL_VOLATILE)
341 pp_string (buffer, "volatile");
342 else if (quals & TYPE_QUAL_RESTRICT)
343 pp_string (buffer, " restrict");
344 }
345 break;
346
347 case OFFSET_TYPE:
348 NIY;
349 break;
350
351 case METHOD_TYPE:
352 dump_decl_name (buffer, TYPE_NAME (TYPE_METHOD_BASETYPE (node)), flags);
353 pp_string (buffer, "::");
354 break;
355
356 case FILE_TYPE:
357 NIY;
358 break;
359
360 case ARRAY_TYPE:
361 {
362 tree tmp;
363
364 /* Print the array type. */
365 dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
366
367 /* Print the dimensions. */
368 tmp = node;
369 while (tmp && TREE_CODE (tmp) == ARRAY_TYPE)
370 {
371 pp_character (buffer, '[');
372 if (TYPE_SIZE (tmp))
373 {
374 tree size = TYPE_SIZE (tmp);
375 if (TREE_CODE (size) == INTEGER_CST)
376 pp_wide_integer (buffer,
377 TREE_INT_CST_LOW (TYPE_SIZE (tmp)) /
378 TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (tmp))));
379 else if (TREE_CODE (size) == MULT_EXPR)
380 dump_generic_node (buffer, TREE_OPERAND (size, 0), spc, flags, false);
381 /* else punt. */
382 }
383 pp_character (buffer, ']');
384 tmp = TREE_TYPE (tmp);
385 }
386 break;
387 }
388
389 case SET_TYPE:
390 NIY;
391 break;
392
393 case RECORD_TYPE:
394 case UNION_TYPE:
395 /* Print the name of the structure. */
396 if (TREE_CODE (node) == RECORD_TYPE)
397 pp_string (buffer, "struct ");
398 else if (TREE_CODE (node) == UNION_TYPE)
399 pp_string (buffer, "union ");
400
401 if (TYPE_NAME (node))
402 dump_generic_node (buffer, TYPE_NAME (node), spc, flags, false);
403 else
404 print_struct_decl (buffer, node, spc, flags);
405 break;
406
407 case QUAL_UNION_TYPE:
408 NIY;
409 break;
410
411
412 case LANG_TYPE:
413 NIY;
414 break;
415
416 case INTEGER_CST:
417 if (TREE_CODE (TREE_TYPE (node)) == POINTER_TYPE)
418 {
419 /* In the case of a pointer, one may want to divide by the
420 size of the pointed-to type. Unfortunately, this not
421 straightforward. The C front-end maps expressions
422
423 (int *) 5
424 int *p; (p + 5)
425
426 in such a way that the two INTEGER_CST nodes for "5" have
427 different values but identical types. In the latter
428 case, the 5 is multiplied by sizeof (int) in c-common.c
429 (pointer_int_sum) to convert it to a byte address, and
430 yet the type of the node is left unchanged. Argh. What
431 is consistent though is that the number value corresponds
432 to bytes (UNITS) offset.
433
434 NB: Neither of the following divisors can be trivially
435 used to recover the original literal:
436
437 TREE_INT_CST_LOW (TYPE_SIZE_UNIT (TREE_TYPE (node)))
438 TYPE_PRECISION (TREE_TYPE (TREE_TYPE (node))) */
439 pp_wide_integer (buffer, TREE_INT_CST_LOW (node));
440 pp_string (buffer, "B"); /* pseudo-unit */
441 }
442 else if (! host_integerp (node, 0))
443 {
444 tree val = node;
445
446 if (tree_int_cst_sgn (val) < 0)
447 {
448 pp_character (buffer, '-');
449 val = build_int_2 (-TREE_INT_CST_LOW (val),
450 ~TREE_INT_CST_HIGH (val)
451 + !TREE_INT_CST_LOW (val));
452 }
453 /* Would "%x%0*x" or "%x%*0x" get zero-padding on all
454 systems? */
455 {
456 static char format[10]; /* "%x%09999x\0" */
457 if (!format[0])
458 sprintf (format, "%%x%%0%dx", HOST_BITS_PER_INT / 4);
459 sprintf (pp_buffer (buffer)->digit_buffer, format,
460 TREE_INT_CST_HIGH (val),
461 TREE_INT_CST_LOW (val));
462 pp_string (buffer, pp_buffer (buffer)->digit_buffer);
463 }
464 }
465 else
466 pp_wide_integer (buffer, TREE_INT_CST_LOW (node));
467 break;
468
469 case REAL_CST:
470 /* Code copied from print_node. */
471 {
472 REAL_VALUE_TYPE d;
473 if (TREE_OVERFLOW (node))
474 pp_string (buffer, " overflow");
475
476#if !defined(REAL_IS_NOT_DOUBLE) || defined(REAL_ARITHMETIC)
477 d = TREE_REAL_CST (node);
478 if (REAL_VALUE_ISINF (d))
479 pp_string (buffer, " Inf");
480 else if (REAL_VALUE_ISNAN (d))
481 pp_string (buffer, " Nan");
482 else
483 {
484 char string[100];
485 real_to_decimal (string, &d, sizeof (string), 0, 1);
486 pp_string (buffer, string);
487 }
488#else
489 {
490 HOST_WIDE_INT i;
491 unsigned char *p = (unsigned char *) &TREE_REAL_CST (node);
492 pp_string (buffer, "0x");
493 for (i = 0; i < sizeof TREE_REAL_CST (node); i++)
494 output_formatted_integer (buffer, "%02x", *p++);
495 }
496#endif
497 break;
498 }
499
500 case COMPLEX_CST:
501 pp_string (buffer, "__complex__ (");
502 dump_generic_node (buffer, TREE_REALPART (node), spc, flags, false);
503 pp_string (buffer, ", ");
504 dump_generic_node (buffer, TREE_IMAGPART (node), spc, flags, false);
505 pp_string (buffer, ")");
506 break;
507
508 case STRING_CST:
509 pp_string (buffer, "\"");
510 pretty_print_string (buffer, TREE_STRING_POINTER (node));
511 pp_string (buffer, "\"");
512 break;
513
514 case VECTOR_CST:
515 {
516 tree elt;
517 pp_string (buffer, "{ ");
518 for (elt = TREE_VECTOR_CST_ELTS (node); elt; elt = TREE_CHAIN (elt))
519 {
520 dump_generic_node (buffer, TREE_VALUE (elt), spc, flags, false);
521 if (TREE_CHAIN (elt))
522 pp_string (buffer, ", ");
523 }
524 pp_string (buffer, " }");
525 }
526 break;
527
528 case FUNCTION_TYPE:
529 break;
530
531 case FUNCTION_DECL:
532 case CONST_DECL:
533 dump_decl_name (buffer, node, flags);
534 break;
535
536 case LABEL_DECL:
537 if (DECL_NAME (node))
538 dump_decl_name (buffer, node, flags);
539 else if (LABEL_DECL_UID (node) != -1)
540 pp_printf (buffer, "<L" HOST_WIDE_INT_PRINT_DEC ">",
541 LABEL_DECL_UID (node));
542 else
543 pp_printf (buffer, "<D%u>", DECL_UID (node));
544 break;
545
546 case TYPE_DECL:
547 if (strcmp (DECL_SOURCE_FILE (node), "<built-in>") == 0)
548 {
549 /* Don't print the declaration of built-in types. */
550 break;
551 }
552 if (DECL_NAME (node))
553 {
554 dump_decl_name (buffer, node, flags);
555 }
556 else
557 {
558 if (TYPE_METHODS (TREE_TYPE (node)))
559 {
560 /* The type is a c++ class: all structures have at least
0bed3869 561 4 methods. */
4ee9c684 562 pp_string (buffer, "class ");
563 dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
564 }
565 else
566 {
567 pp_string (buffer, "struct ");
568 dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
569 pp_character (buffer, ';');
570 pp_newline (buffer);
571 }
572 }
573 break;
574
575 case VAR_DECL:
576 case PARM_DECL:
577 case FIELD_DECL:
578 case NAMESPACE_DECL:
579 dump_decl_name (buffer, node, flags);
580 break;
581
582 case RESULT_DECL:
583 pp_string (buffer, "<retval>");
584 break;
585
586 case COMPONENT_REF:
587 op0 = TREE_OPERAND (node, 0);
588 str = ".";
589 if (TREE_CODE (op0) == INDIRECT_REF)
590 {
591 op0 = TREE_OPERAND (op0, 0);
592 str = "->";
593 }
594 if (op_prio (op0) < op_prio (node))
595 pp_character (buffer, '(');
596 dump_generic_node (buffer, op0, spc, flags, false);
597 if (op_prio (op0) < op_prio (node))
598 pp_character (buffer, ')');
599 pp_string (buffer, str);
600 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
601 break;
602
603 case BIT_FIELD_REF:
604 pp_string (buffer, "BIT_FIELD_REF <");
605 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
606 pp_string (buffer, ", ");
607 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
608 pp_string (buffer, ", ");
609 dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
610 pp_string (buffer, ">");
611 break;
612
613 case BUFFER_REF:
614 NIY;
615 break;
616
617 case ARRAY_REF:
618 op0 = TREE_OPERAND (node, 0);
619 if (op_prio (op0) < op_prio (node))
620 pp_character (buffer, '(');
621 dump_generic_node (buffer, op0, spc, flags, false);
622 if (op_prio (op0) < op_prio (node))
623 pp_character (buffer, ')');
624 pp_character (buffer, '[');
625 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
626 pp_character (buffer, ']');
627 break;
628
629 case ARRAY_RANGE_REF:
630 NIY;
631 break;
632
633 case CONSTRUCTOR:
634 {
635 tree lnode;
636 bool is_struct_init = FALSE;
637 pp_character (buffer, '{');
638 lnode = CONSTRUCTOR_ELTS (node);
639 if (TREE_CODE (TREE_TYPE (node)) == RECORD_TYPE
640 || TREE_CODE (TREE_TYPE (node)) == UNION_TYPE)
641 is_struct_init = TRUE;
642 while (lnode && lnode != error_mark_node)
643 {
644 tree val;
645 if (TREE_PURPOSE (lnode) && is_struct_init)
646 {
647 pp_character (buffer, '.');
648 dump_generic_node (buffer, TREE_PURPOSE (lnode), spc, flags, false);
649 pp_string (buffer, "=");
650 }
651 val = TREE_VALUE (lnode);
652 if (val && TREE_CODE (val) == ADDR_EXPR)
653 if (TREE_CODE (TREE_OPERAND (val, 0)) == FUNCTION_DECL)
654 val = TREE_OPERAND (val, 0);
655 if (val && TREE_CODE (val) == FUNCTION_DECL)
656 {
657 dump_decl_name (buffer, val, flags);
658 }
659 else
660 {
661 dump_generic_node (buffer, TREE_VALUE (lnode), spc, flags, false);
662 }
663 lnode = TREE_CHAIN (lnode);
664 if (lnode && TREE_CODE (lnode) == TREE_LIST)
665 {
666 pp_character (buffer, ',');
667 pp_space (buffer);
668 }
669 }
670 pp_character (buffer, '}');
671 }
672 break;
673
674 case COMPOUND_EXPR:
675 {
676 tree *tp;
677 if (flags & TDF_SLIM)
678 {
679 pp_string (buffer, "<COMPOUND_EXPR>");
680 break;
681 }
682
683 dump_generic_node (buffer, TREE_OPERAND (node, 0),
684 spc, flags, dumping_stmts);
685 if (dumping_stmts)
686 newline_and_indent (buffer, spc);
687 else
688 {
689 pp_character (buffer, ',');
690 pp_space (buffer);
691 }
692
693 for (tp = &TREE_OPERAND (node, 1);
694 TREE_CODE (*tp) == COMPOUND_EXPR;
695 tp = &TREE_OPERAND (*tp, 1))
696 {
697 dump_generic_node (buffer, TREE_OPERAND (*tp, 0),
698 spc, flags, dumping_stmts);
699 if (dumping_stmts)
700 newline_and_indent (buffer, spc);
701 else
702 {
703 pp_character (buffer, ',');
704 pp_space (buffer);
705 }
706 }
707
708 dump_generic_node (buffer, *tp, spc, flags, dumping_stmts);
709 }
710 break;
711
712 case STATEMENT_LIST:
713 {
714 tree_stmt_iterator si;
715 bool first = true;
716
717 if ((flags & TDF_SLIM) || !dumping_stmts)
718 {
719 pp_string (buffer, "<STATEMENT_LIST>");
720 break;
721 }
722
723 for (si = tsi_start (node); !tsi_end_p (si); tsi_next (&si))
724 {
725 if (!first)
726 newline_and_indent (buffer, spc);
727 else
728 first = false;
729 dump_generic_node (buffer, tsi_stmt (si), spc, flags, true);
730 }
731 }
732 break;
733
734 case MODIFY_EXPR:
735 case INIT_EXPR:
736 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
737 pp_space (buffer);
738 pp_character (buffer, '=');
739 pp_space (buffer);
740 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
741 break;
742
743 case TARGET_EXPR:
744 dump_generic_node (buffer, TYPE_NAME (TREE_TYPE (node)), spc, flags, false);
745 pp_character (buffer, '(');
746 dump_generic_node (buffer, TARGET_EXPR_INITIAL (node), spc, flags, false);
747 pp_character (buffer, ')');
748 break;
749
750 case COND_EXPR:
751 if (TREE_TYPE (node) == void_type_node)
752 {
753 pp_string (buffer, "if (");
754 dump_generic_node (buffer, COND_EXPR_COND (node), spc, flags, false);
755 pp_character (buffer, ')');
756 /* The lowered cond_exprs should always be printed in full. */
757 if (COND_EXPR_THEN (node)
758 && TREE_CODE (COND_EXPR_THEN (node)) == GOTO_EXPR
759 && COND_EXPR_ELSE (node)
760 && TREE_CODE (COND_EXPR_ELSE (node)) == GOTO_EXPR)
761 {
762 pp_space (buffer);
763 dump_generic_node (buffer, COND_EXPR_THEN (node), 0, flags, true);
764 pp_string (buffer, " else ");
765 dump_generic_node (buffer, COND_EXPR_ELSE (node), 0, flags, true);
766 }
767 else if (!(flags & TDF_SLIM))
768 {
769 /* Output COND_EXPR_THEN. */
770 if (COND_EXPR_THEN (node))
771 {
772 newline_and_indent (buffer, spc+2);
773 pp_character (buffer, '{');
774 newline_and_indent (buffer, spc+4);
775 dump_generic_node (buffer, COND_EXPR_THEN (node), spc+4,
776 flags, true);
777 newline_and_indent (buffer, spc+2);
778 pp_character (buffer, '}');
779 }
780
781 /* Output COND_EXPR_ELSE. */
782 if (COND_EXPR_ELSE (node))
783 {
784 newline_and_indent (buffer, spc);
785 pp_string (buffer, "else");
786 newline_and_indent (buffer, spc+2);
787 pp_character (buffer, '{');
788 newline_and_indent (buffer, spc+4);
789 dump_generic_node (buffer, COND_EXPR_ELSE (node), spc+4,
790 flags, true);
791 newline_and_indent (buffer, spc+2);
792 pp_character (buffer, '}');
793 }
794 }
795 is_expr = false;
796 }
797 else
798 {
799 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
800 pp_space (buffer);
801 pp_character (buffer, '?');
802 pp_space (buffer);
803 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
804 pp_space (buffer);
805 pp_character (buffer, ':');
806 pp_space (buffer);
807 dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
808 }
809 break;
810
811 case BIND_EXPR:
812 pp_character (buffer, '{');
813 if (!(flags & TDF_SLIM))
814 {
815 if (BIND_EXPR_VARS (node))
816 {
817 pp_newline (buffer);
818
819 for (op0 = BIND_EXPR_VARS (node); op0; op0 = TREE_CHAIN (op0))
820 {
821 print_declaration (buffer, op0, spc+2, flags);
822 pp_newline (buffer);
823 }
824 }
825
826 newline_and_indent (buffer, spc+2);
827 dump_generic_node (buffer, BIND_EXPR_BODY (node), spc+2, flags, true);
828 newline_and_indent (buffer, spc);
829 pp_character (buffer, '}');
830 }
831 is_expr = false;
832 break;
833
834 case CALL_EXPR:
835 print_call_name (buffer, node);
836
837 /* Print parameters. */
838 pp_space (buffer);
839 pp_character (buffer, '(');
840 op1 = TREE_OPERAND (node, 1);
841 if (op1)
842 dump_generic_node (buffer, op1, spc, flags, false);
843 pp_character (buffer, ')');
844
845 op1 = TREE_OPERAND (node, 2);
846 if (op1)
847 {
848 pp_string (buffer, " [static-chain: ");
849 dump_generic_node (buffer, op1, spc, flags, false);
850 pp_character (buffer, ']');
851 }
852
853 if (CALL_EXPR_TAILCALL (node))
854 pp_string (buffer, " [tail call]");
855 break;
856
857 case WITH_CLEANUP_EXPR:
858 NIY;
859 break;
860
861 case CLEANUP_POINT_EXPR:
862 pp_string (buffer, "<<cleanup_point ");
863 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
864 pp_string (buffer, ">>");
865 break;
866
867 case PLACEHOLDER_EXPR:
868 NIY;
869 break;
870
871 /* Binary arithmetic and logic expressions. */
872 case MULT_EXPR:
873 case PLUS_EXPR:
874 case MINUS_EXPR:
875 case TRUNC_DIV_EXPR:
876 case CEIL_DIV_EXPR:
877 case FLOOR_DIV_EXPR:
878 case ROUND_DIV_EXPR:
879 case TRUNC_MOD_EXPR:
880 case CEIL_MOD_EXPR:
881 case FLOOR_MOD_EXPR:
882 case ROUND_MOD_EXPR:
883 case RDIV_EXPR:
884 case EXACT_DIV_EXPR:
885 case LSHIFT_EXPR:
886 case RSHIFT_EXPR:
887 case LROTATE_EXPR:
888 case RROTATE_EXPR:
889 case BIT_IOR_EXPR:
890 case BIT_XOR_EXPR:
891 case BIT_AND_EXPR:
892 case TRUTH_ANDIF_EXPR:
893 case TRUTH_ORIF_EXPR:
894 case TRUTH_AND_EXPR:
895 case TRUTH_OR_EXPR:
896 case TRUTH_XOR_EXPR:
897 case LT_EXPR:
898 case LE_EXPR:
899 case GT_EXPR:
900 case GE_EXPR:
901 case EQ_EXPR:
902 case NE_EXPR:
903 case UNLT_EXPR:
904 case UNLE_EXPR:
905 case UNGT_EXPR:
906 case UNGE_EXPR:
907 case UNEQ_EXPR:
318a728f 908 case LTGT_EXPR:
909 case ORDERED_EXPR:
910 case UNORDERED_EXPR:
4ee9c684 911 {
912 const char *op = op_symbol (node);
913 op0 = TREE_OPERAND (node, 0);
914 op1 = TREE_OPERAND (node, 1);
915
916 /* When the operands are expressions with less priority,
917 keep semantics of the tree representation. */
918 if (op_prio (op0) < op_prio (node))
919 {
920 pp_character (buffer, '(');
921 dump_generic_node (buffer, op0, spc, flags, false);
922 pp_character (buffer, ')');
923 }
924 else
925 dump_generic_node (buffer, op0, spc, flags, false);
926
927 pp_space (buffer);
928 pp_string (buffer, op);
929 pp_space (buffer);
930
931 /* When the operands are expressions with less priority,
932 keep semantics of the tree representation. */
933 if (op_prio (op1) < op_prio (node))
934 {
935 pp_character (buffer, '(');
936 dump_generic_node (buffer, op1, spc, flags, false);
937 pp_character (buffer, ')');
938 }
939 else
940 dump_generic_node (buffer, op1, spc, flags, false);
941 }
942 break;
943
944 /* Unary arithmetic and logic expressions. */
945 case NEGATE_EXPR:
946 case BIT_NOT_EXPR:
947 case TRUTH_NOT_EXPR:
948 case ADDR_EXPR:
949 case REFERENCE_EXPR:
950 case PREDECREMENT_EXPR:
951 case PREINCREMENT_EXPR:
952 case INDIRECT_REF:
953 if (TREE_CODE (node) == ADDR_EXPR
954 && (TREE_CODE (TREE_OPERAND (node, 0)) == STRING_CST
955 || TREE_CODE (TREE_OPERAND (node, 0)) == FUNCTION_DECL))
956 ; /* Do not output '&' for strings and function pointers. */
957 else
958 pp_string (buffer, op_symbol (node));
959
960 if (op_prio (TREE_OPERAND (node, 0)) < op_prio (node))
961 {
962 pp_character (buffer, '(');
963 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
964 pp_character (buffer, ')');
965 }
966 else
967 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
968 break;
969
970 case POSTDECREMENT_EXPR:
971 case POSTINCREMENT_EXPR:
972 if (op_prio (TREE_OPERAND (node, 0)) < op_prio (node))
973 {
974 pp_character (buffer, '(');
975 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
976 pp_character (buffer, ')');
977 }
978 else
979 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
980 pp_string (buffer, op_symbol (node));
981 break;
982
983 case MIN_EXPR:
984 pp_string (buffer, "MIN_EXPR <");
985 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
986 pp_string (buffer, ", ");
987 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
988 pp_character (buffer, '>');
989 break;
990
991 case MAX_EXPR:
992 pp_string (buffer, "MAX_EXPR <");
993 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
994 pp_string (buffer, ", ");
995 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
996 pp_character (buffer, '>');
997 break;
998
999 case ABS_EXPR:
1000 pp_string (buffer, "ABS_EXPR <");
1001 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1002 pp_character (buffer, '>');
1003 break;
1004
4ee9c684 1005 case IN_EXPR:
1006 NIY;
1007 break;
1008
1009 case SET_LE_EXPR:
1010 NIY;
1011 break;
1012
1013 case CARD_EXPR:
1014 NIY;
1015 break;
1016
1017 case RANGE_EXPR:
1018 NIY;
1019 break;
1020
1021 case FIX_TRUNC_EXPR:
1022 case FIX_CEIL_EXPR:
1023 case FIX_FLOOR_EXPR:
1024 case FIX_ROUND_EXPR:
1025 case FLOAT_EXPR:
1026 case CONVERT_EXPR:
1027 case NOP_EXPR:
1028 type = TREE_TYPE (node);
1029 op0 = TREE_OPERAND (node, 0);
1030 if (type != TREE_TYPE (op0))
1031 {
1032 pp_character (buffer, '(');
1033 dump_generic_node (buffer, type, spc, flags, false);
1034 pp_string (buffer, ")");
1035 }
1036 if (op_prio (op0) < op_prio (node))
1037 pp_character (buffer, '(');
1038 dump_generic_node (buffer, op0, spc, flags, false);
1039 if (op_prio (op0) < op_prio (node))
1040 pp_character (buffer, ')');
1041 break;
1042
1043 case VIEW_CONVERT_EXPR:
1044 pp_string (buffer, "VIEW_CONVERT_EXPR<");
1045 dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
1046 pp_string (buffer, ">(");
1047 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1048 pp_character (buffer, ')');
1049 break;
1050
1051 case NON_LVALUE_EXPR:
1052 pp_string (buffer, "NON_LVALUE_EXPR <");
1053 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1054 pp_character (buffer, '>');
1055 break;
1056
1057 case SAVE_EXPR:
1058 pp_string (buffer, "SAVE_EXPR <");
1059 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1060 pp_character (buffer, '>');
1061 break;
1062
1063 case UNSAVE_EXPR:
1064 pp_string (buffer, "UNSAVE_EXPR <");
1065 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1066 pp_character (buffer, '>');
1067 break;
1068
1069 case RTL_EXPR:
1070 NIY;
1071 break;
1072
1073 case ENTRY_VALUE_EXPR:
1074 NIY;
1075 break;
1076
1077 case COMPLEX_EXPR:
1078 pp_string (buffer, "COMPLEX_EXPR <");
1079 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1080 pp_string (buffer, ", ");
1081 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1082 pp_string (buffer, ">");
1083 break;
1084
1085 case CONJ_EXPR:
1086 pp_string (buffer, "CONJ_EXPR <");
1087 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1088 pp_string (buffer, ">");
1089 break;
1090
1091 case REALPART_EXPR:
1092 pp_string (buffer, "REALPART_EXPR <");
1093 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1094 pp_string (buffer, ">");
1095 break;
1096
1097 case IMAGPART_EXPR:
1098 pp_string (buffer, "IMAGPART_EXPR <");
1099 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1100 pp_string (buffer, ">");
1101 break;
1102
1103 case VA_ARG_EXPR:
1104 pp_string (buffer, "VA_ARG_EXPR <");
1105 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1106 pp_string (buffer, ">");
1107 break;
1108
1109 case TRY_FINALLY_EXPR:
1110 case TRY_CATCH_EXPR:
1111 pp_string (buffer, "try");
1112 newline_and_indent (buffer, spc+2);
1113 pp_string (buffer, "{");
1114 newline_and_indent (buffer, spc+4);
1115 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc+4, flags, true);
1116 newline_and_indent (buffer, spc+2);
1117 pp_string (buffer, "}");
1118 newline_and_indent (buffer, spc);
1119 pp_string (buffer,
1120 (TREE_CODE (node) == TRY_CATCH_EXPR) ? "catch" : "finally");
1121 newline_and_indent (buffer, spc+2);
1122 pp_string (buffer, "{");
1123 newline_and_indent (buffer, spc+4);
1124 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc+4, flags, true);
1125 newline_and_indent (buffer, spc+2);
1126 pp_string (buffer, "}");
1127 is_expr = false;
1128 break;
1129
1130 case CATCH_EXPR:
1131 pp_string (buffer, "catch (");
1132 dump_generic_node (buffer, CATCH_TYPES (node), spc+2, flags, false);
1133 pp_string (buffer, ")");
1134 newline_and_indent (buffer, spc+2);
1135 pp_string (buffer, "{");
1136 newline_and_indent (buffer, spc+4);
1137 dump_generic_node (buffer, CATCH_BODY (node), spc+4, flags, true);
1138 newline_and_indent (buffer, spc+2);
1139 pp_string (buffer, "}");
1140 is_expr = false;
1141 break;
1142
1143 case EH_FILTER_EXPR:
1144 pp_string (buffer, "<<<eh_filter (");
1145 dump_generic_node (buffer, EH_FILTER_TYPES (node), spc+2, flags, false);
1146 pp_string (buffer, ")>>>");
1147 newline_and_indent (buffer, spc+2);
1148 pp_string (buffer, "{");
1149 newline_and_indent (buffer, spc+4);
1150 dump_generic_node (buffer, EH_FILTER_FAILURE (node), spc+4, flags, true);
1151 newline_and_indent (buffer, spc+2);
1152 pp_string (buffer, "}");
1153 is_expr = false;
1154 break;
1155
1156 case GOTO_SUBROUTINE_EXPR:
1157 NIY;
1158 break;
1159
1160 case LABEL_EXPR:
1161 op0 = TREE_OPERAND (node, 0);
1162 /* If this is for break or continue, don't bother printing it. */
1163 if (DECL_NAME (op0))
1164 {
1165 const char *name = IDENTIFIER_POINTER (DECL_NAME (op0));
1166 if (strcmp (name, "break") == 0
1167 || strcmp (name, "continue") == 0)
1168 break;
1169 }
1170 dump_generic_node (buffer, op0, spc, flags, false);
1171 pp_character (buffer, ':');
1172 if (DECL_NONLOCAL (op0))
1173 pp_string (buffer, " [non-local]");
1174 break;
1175
1176 case LABELED_BLOCK_EXPR:
1177 op0 = LABELED_BLOCK_LABEL (node);
1178 /* If this is for break or continue, don't bother printing it. */
1179 if (DECL_NAME (op0))
1180 {
1181 const char *name = IDENTIFIER_POINTER (DECL_NAME (op0));
1182 if (strcmp (name, "break") == 0
1183 || strcmp (name, "continue") == 0)
1184 {
1185 dump_generic_node (buffer, LABELED_BLOCK_BODY (node), spc, flags, false);
1186 break;
1187 }
1188 }
1189 dump_generic_node (buffer, LABELED_BLOCK_LABEL (node), spc, flags, false);
1190 pp_string (buffer, ": {");
1191 if (!(flags & TDF_SLIM))
1192 newline_and_indent (buffer, spc+2);
1193 dump_generic_node (buffer, LABELED_BLOCK_BODY (node), spc+2, flags, true);
1194 if (!flags)
1195 newline_and_indent (buffer, spc);
1196 pp_character (buffer, '}');
1197 is_expr = false;
1198 break;
1199
1200 case EXIT_BLOCK_EXPR:
1201 op0 = LABELED_BLOCK_LABEL (EXIT_BLOCK_LABELED_BLOCK (node));
1202 /* If this is for a break or continue, print it accordingly. */
1203 if (DECL_NAME (op0))
1204 {
1205 const char *name = IDENTIFIER_POINTER (DECL_NAME (op0));
1206 if (strcmp (name, "break") == 0
1207 || strcmp (name, "continue") == 0)
1208 {
1209 pp_string (buffer, name);
1210 break;
1211 }
1212 }
1213 pp_string (buffer, "<<<exit block ");
1214 dump_generic_node (buffer, op0, spc, flags, false);
1215 pp_string (buffer, ">>>");
1216 break;
1217
1218 case EXC_PTR_EXPR:
1219 pp_string (buffer, "<<<exception object>>>");
1220 break;
1221
1222 case FILTER_EXPR:
1223 pp_string (buffer, "<<<filter object>>>");
1224 break;
1225
1226 case LOOP_EXPR:
1227 pp_string (buffer, "while (1)");
1228 if (!(flags & TDF_SLIM))
1229 {
1230 newline_and_indent (buffer, spc+2);
1231 pp_character (buffer, '{');
1232 newline_and_indent (buffer, spc+4);
1233 dump_generic_node (buffer, LOOP_EXPR_BODY (node), spc+4, flags, true);
1234 newline_and_indent (buffer, spc+2);
1235 pp_character (buffer, '}');
1236 }
1237 is_expr = false;
1238 break;
1239
1240 case RETURN_EXPR:
1241 pp_string (buffer, "return");
1242 op0 = TREE_OPERAND (node, 0);
1243 if (op0)
1244 {
1245 pp_space (buffer);
1246 if (TREE_CODE (op0) == MODIFY_EXPR)
1247 dump_generic_node (buffer, TREE_OPERAND (op0, 1), spc, flags, false);
1248 else
1249 dump_generic_node (buffer, op0, spc, flags, false);
1250 }
1251 break;
1252
1253 case EXIT_EXPR:
1254 pp_string (buffer, "if (");
1255 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1256 pp_string (buffer, ") break");
1257 break;
1258
1259 case SWITCH_EXPR:
1260 pp_string (buffer, "switch (");
1261 dump_generic_node (buffer, SWITCH_COND (node), spc, flags, false);
1262 pp_character (buffer, ')');
1263 if (!(flags & TDF_SLIM))
1264 {
1265 newline_and_indent (buffer, spc+2);
1266 pp_character (buffer, '{');
1267 if (SWITCH_BODY (node))
1268 {
1269 newline_and_indent (buffer, spc+4);
1270 dump_generic_node (buffer, SWITCH_BODY (node), spc+4, flags, true);
1271 }
1272 else
1273 {
1274 tree vec = SWITCH_LABELS (node);
1275 size_t i, n = TREE_VEC_LENGTH (vec);
1276 for (i = 0; i < n; ++i)
1277 {
1278 tree elt = TREE_VEC_ELT (vec, i);
1279 newline_and_indent (buffer, spc+4);
1280 dump_generic_node (buffer, elt, spc+4, flags, false);
1281 pp_string (buffer, " goto ");
1282 dump_generic_node (buffer, CASE_LABEL (elt), spc+4, flags, true);
1283 pp_semicolon (buffer);
1284 }
1285 }
1286 newline_and_indent (buffer, spc+2);
1287 pp_character (buffer, '}');
1288 }
1289 is_expr = false;
1290 break;
1291
1292 case GOTO_EXPR:
1293 op0 = GOTO_DESTINATION (node);
1294 if (TREE_CODE (op0) != SSA_NAME
1295 && DECL_P (op0)
1296 && DECL_NAME (op0))
1297 {
1298 const char *name = IDENTIFIER_POINTER (DECL_NAME (op0));
1299 if (strcmp (name, "break") == 0
1300 || strcmp (name, "continue") == 0)
1301 {
1302 pp_string (buffer, name);
1303 break;
1304 }
1305 }
1306 pp_string (buffer, "goto ");
1307 dump_generic_node (buffer, op0, spc, flags, false);
1308 break;
1309
1310 case RESX_EXPR:
1311 pp_string (buffer, "resx");
1312 /* ??? Any sensible way to present the eh region? */
1313 break;
1314
1315 case ASM_EXPR:
1316 pp_string (buffer, "__asm__");
1317 if (ASM_VOLATILE_P (node))
1318 pp_string (buffer, " __volatile__");
1319 pp_character (buffer, '(');
1320 dump_generic_node (buffer, ASM_STRING (node), spc, flags, false);
1321 pp_character (buffer, ':');
1322 dump_generic_node (buffer, ASM_OUTPUTS (node), spc, flags, false);
1323 pp_character (buffer, ':');
1324 dump_generic_node (buffer, ASM_INPUTS (node), spc, flags, false);
1325 if (ASM_CLOBBERS (node))
1326 {
1327 pp_character (buffer, ':');
1328 dump_generic_node (buffer, ASM_CLOBBERS (node), spc, flags, false);
1329 }
1330 pp_string (buffer, ")");
1331 break;
1332
1333 case CASE_LABEL_EXPR:
1334 if (CASE_LOW (node) && CASE_HIGH (node))
1335 {
1336 pp_string (buffer, "case ");
1337 dump_generic_node (buffer, CASE_LOW (node), spc, flags, false);
1338 pp_string (buffer, " ... ");
1339 dump_generic_node (buffer, CASE_HIGH (node), spc, flags, false);
1340 }
1341 else if (CASE_LOW (node))
1342 {
1343 pp_string (buffer, "case ");
1344 dump_generic_node (buffer, CASE_LOW (node), spc, flags, false);
1345 }
1346 else
1347 pp_string (buffer, "default ");
1348 pp_character (buffer, ':');
1349 break;
1350
1351 case VTABLE_REF:
1352 pp_string (buffer, "VTABLE_REF <(");
1353 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1354 pp_string (buffer, "),");
1355 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1356 pp_character (buffer, ',');
1357 dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
1358 pp_character (buffer, '>');
1359 break;
1360
4ee9c684 1361 case PHI_NODE:
1362 {
1363 int i;
1364
1365 dump_generic_node (buffer, PHI_RESULT (node), spc, flags, false);
1366 pp_string (buffer, " = PHI <");
1367 for (i = 0; i < PHI_NUM_ARGS (node); i++)
1368 {
1369 dump_generic_node (buffer, PHI_ARG_DEF (node, i), spc, flags, false);
1370 pp_string (buffer, "(");
1371 pp_decimal_int (buffer, PHI_ARG_EDGE (node, i)->src->index);
1372 pp_string (buffer, ")");
1373 if (i < PHI_NUM_ARGS (node) - 1)
1374 pp_string (buffer, ", ");
1375 }
1376 pp_string (buffer, ">;");
1377 }
1378 break;
1379
1380 case SSA_NAME:
1381 dump_generic_node (buffer, SSA_NAME_VAR (node), spc, flags, false);
1382 pp_string (buffer, "_");
1383 pp_decimal_int (buffer, SSA_NAME_VERSION (node));
1384 break;
1385
1386 default:
1387 NIY;
1388 }
1389
1390 if (is_stmt && is_expr)
1391 pp_semicolon (buffer);
1392 pp_write_text_to_stream (buffer);
1393
1394 return spc;
1395}
1396
1397/* Print the declaration of a variable. */
1398
1399static void
1400print_declaration (pretty_printer *buffer, tree t, int spc, int flags)
1401{
1402 /* Don't print type declarations. */
1403 if (TREE_CODE (t) == TYPE_DECL)
1404 return;
1405
1406 INDENT (spc);
1407
1408 if (DECL_REGISTER (t))
1409 pp_string (buffer, "register ");
1410
1411 if (TREE_PUBLIC (t) && DECL_EXTERNAL (t))
1412 pp_string (buffer, "extern ");
1413 else if (TREE_STATIC (t))
1414 pp_string (buffer, "static ");
1415
1416 /* Print the type and name. */
1417 if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
1418 {
1419 tree tmp;
1420
1421 /* Print array's type. */
1422 tmp = TREE_TYPE (t);
1423 while (TREE_CODE (TREE_TYPE (tmp)) == ARRAY_TYPE)
1424 tmp = TREE_TYPE (tmp);
1425 dump_generic_node (buffer, TREE_TYPE (tmp), spc, flags, false);
1426
1427 /* Print variable's name. */
1428 pp_space (buffer);
1429 dump_generic_node (buffer, t, spc, flags, false);
1430
1431 /* Print the dimensions. */
1432 tmp = TREE_TYPE (t);
1433 while (TREE_CODE (tmp) == ARRAY_TYPE)
1434 {
1435 pp_character (buffer, '[');
1436 if (TYPE_DOMAIN (tmp))
1437 {
1438 if (TREE_CODE (TYPE_SIZE (tmp)) == INTEGER_CST)
1439 pp_wide_integer (buffer,
1440 TREE_INT_CST_LOW (TYPE_SIZE (tmp)) /
1441 TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (tmp))));
1442 else
1443 dump_generic_node (buffer, TYPE_SIZE_UNIT (tmp), spc, flags,
1444 false);
1445 }
1446 pp_character (buffer, ']');
1447 tmp = TREE_TYPE (tmp);
1448 }
1449 }
1450 else
1451 {
1452 /* Print type declaration. */
1453 dump_generic_node (buffer, TREE_TYPE (t), spc, flags, false);
1454
1455 /* Print variable's name. */
1456 pp_space (buffer);
1457 dump_generic_node (buffer, t, spc, flags, false);
1458 }
1459
1460 /* The initial value of a function serves to determine wether the function
1461 is declared or defined. So the following does not apply to function
1462 nodes. */
1463 if (TREE_CODE (t) != FUNCTION_DECL)
1464 {
1465 /* Print the initial value. */
1466 if (DECL_INITIAL (t))
1467 {
1468 pp_space (buffer);
1469 pp_character (buffer, '=');
1470 pp_space (buffer);
1471 dump_generic_node (buffer, DECL_INITIAL (t), spc, flags, false);
1472 }
1473 }
1474
1475 pp_character (buffer, ';');
1476}
1477
1478
1479/* Prints a structure: name, fields, and methods.
1480 FIXME: Still incomplete. */
1481
1482static void
1483print_struct_decl (pretty_printer *buffer, tree node, int spc, int flags)
1484{
1485 /* Print the name of the structure. */
1486 if (TYPE_NAME (node))
1487 {
1488 INDENT (spc);
1489 if (TREE_CODE (node) == RECORD_TYPE)
1490 pp_string (buffer, "struct ");
1491 else if (TREE_CODE (node) == UNION_TYPE)
1492 pp_string (buffer, "union ");
1493 else
1494 NIY;
1495 dump_generic_node (buffer, TYPE_NAME (node), spc, 0, false);
1496 }
1497
1498 /* Print the contents of the structure. */
1499 pp_newline (buffer);
1500 INDENT (spc);
1501 pp_character (buffer, '{');
1502 pp_newline (buffer);
1503
1504 /* Print the fields of the structure. */
1505 {
1506 tree tmp;
1507 tmp = TYPE_FIELDS (node);
1508 while (tmp)
1509 {
1510 /* Avoid to print recursively the structure. */
1511 /* FIXME : Not implemented correctly...,
1512 what about the case when we have a cycle in the contain graph? ...
1513 Maybe this could be solved by looking at the scope in which the
1514 structure was declared. */
1515 if (TREE_TYPE (tmp) != node
1516 || (TREE_CODE (TREE_TYPE (tmp)) == POINTER_TYPE &&
1517 TREE_TYPE (TREE_TYPE (tmp)) != node))
1518 {
1519 print_declaration (buffer, tmp, spc+2, flags);
1520 pp_newline (buffer);
1521 }
1522 else
1523 {
1524
1525 }
1526 tmp = TREE_CHAIN (tmp);
1527 }
1528 }
1529 INDENT (spc);
1530 pp_character (buffer, '}');
1531}
1532
1533/* Return the priority of the operator OP.
1534
1535 From lowest to highest precedence with either left-to-right (L-R)
1536 or right-to-left (R-L) associativity]:
1537
1538 1 [L-R] ,
1539 2 [R-L] = += -= *= /= %= &= ^= |= <<= >>=
1540 3 [R-L] ?:
1541 4 [L-R] ||
1542 5 [L-R] &&
1543 6 [L-R] |
1544 7 [L-R] ^
1545 8 [L-R] &
1546 9 [L-R] == !=
1547 10 [L-R] < <= > >=
1548 11 [L-R] << >>
1549 12 [L-R] + -
1550 13 [L-R] * / %
1551 14 [R-L] ! ~ ++ -- + - * & (type) sizeof
1552 15 [L-R] fn() [] -> .
1553
1554 unary +, - and * have higher precedence than the corresponding binary
1555 operators. */
1556
1557static int
1558op_prio (tree op)
1559{
1560 if (op == NULL)
1561 return 9999;
1562
1563 switch (TREE_CODE (op))
1564 {
1565 case TREE_LIST:
1566 case COMPOUND_EXPR:
1567 case BIND_EXPR:
1568 return 1;
1569
1570 case MODIFY_EXPR:
1571 case INIT_EXPR:
1572 return 2;
1573
1574 case COND_EXPR:
1575 return 3;
1576
1577 case TRUTH_OR_EXPR:
1578 case TRUTH_ORIF_EXPR:
1579 return 4;
1580
1581 case TRUTH_AND_EXPR:
1582 case TRUTH_ANDIF_EXPR:
1583 return 5;
1584
1585 case BIT_IOR_EXPR:
1586 return 6;
1587
1588 case BIT_XOR_EXPR:
1589 case TRUTH_XOR_EXPR:
1590 return 7;
1591
1592 case BIT_AND_EXPR:
1593 return 8;
1594
1595 case EQ_EXPR:
1596 case NE_EXPR:
1597 return 9;
1598
318a728f 1599 case UNLT_EXPR:
1600 case UNLE_EXPR:
1601 case UNGT_EXPR:
1602 case UNGE_EXPR:
1603 case UNEQ_EXPR:
1604 case LTGT_EXPR:
1605 case ORDERED_EXPR:
1606 case UNORDERED_EXPR:
4ee9c684 1607 case LT_EXPR:
1608 case LE_EXPR:
1609 case GT_EXPR:
1610 case GE_EXPR:
1611 return 10;
1612
1613 case LSHIFT_EXPR:
1614 case RSHIFT_EXPR:
1615 case LROTATE_EXPR:
1616 case RROTATE_EXPR:
1617 return 11;
1618
1619 case PLUS_EXPR:
1620 case MINUS_EXPR:
1621 return 12;
1622
1623 case MULT_EXPR:
1624 case TRUNC_DIV_EXPR:
1625 case CEIL_DIV_EXPR:
1626 case FLOOR_DIV_EXPR:
1627 case ROUND_DIV_EXPR:
1628 case RDIV_EXPR:
1629 case EXACT_DIV_EXPR:
1630 case TRUNC_MOD_EXPR:
1631 case CEIL_MOD_EXPR:
1632 case FLOOR_MOD_EXPR:
1633 case ROUND_MOD_EXPR:
1634 return 13;
1635
1636 case TRUTH_NOT_EXPR:
1637 case BIT_NOT_EXPR:
1638 case POSTINCREMENT_EXPR:
1639 case POSTDECREMENT_EXPR:
1640 case PREINCREMENT_EXPR:
1641 case PREDECREMENT_EXPR:
1642 case NEGATE_EXPR:
1643 case INDIRECT_REF:
1644 case ADDR_EXPR:
1645 case FLOAT_EXPR:
1646 case NOP_EXPR:
1647 case CONVERT_EXPR:
1648 case FIX_TRUNC_EXPR:
1649 case FIX_CEIL_EXPR:
1650 case FIX_FLOOR_EXPR:
1651 case FIX_ROUND_EXPR:
1652 case TARGET_EXPR:
1653 return 14;
1654
1655 case CALL_EXPR:
1656 case ARRAY_REF:
1657 case COMPONENT_REF:
1658 return 15;
1659
1660 /* Special expressions. */
1661 case MIN_EXPR:
1662 case MAX_EXPR:
1663 case ABS_EXPR:
1664 case REALPART_EXPR:
1665 case IMAGPART_EXPR:
1666 return 16;
1667
1668 case SAVE_EXPR:
1669 case NON_LVALUE_EXPR:
1670 return op_prio (TREE_OPERAND (op, 0));
1671
1672 default:
1673 /* Return an arbitrarily high precedence to avoid surrounding single
1674 VAR_DECLs in ()s. */
1675 return 9999;
1676 }
1677}
1678
1679
1680/* Return the symbol associated with operator OP. */
1681
1682static const char *
1683op_symbol (tree op)
1684{
1685 if (op == NULL)
1686 abort ();
1687
1688 switch (TREE_CODE (op))
1689 {
1690 case MODIFY_EXPR:
1691 return "=";
1692
1693 case TRUTH_OR_EXPR:
1694 case TRUTH_ORIF_EXPR:
1695 return "||";
1696
1697 case TRUTH_AND_EXPR:
1698 case TRUTH_ANDIF_EXPR:
1699 return "&&";
1700
1701 case BIT_IOR_EXPR:
1702 return "|";
1703
1704 case TRUTH_XOR_EXPR:
1705 case BIT_XOR_EXPR:
1706 return "^";
1707
1708 case ADDR_EXPR:
1709 case BIT_AND_EXPR:
1710 return "&";
1711
318a728f 1712 case ORDERED_EXPR:
1713 return "ord";
1714 case UNORDERED_EXPR:
1715 return "unord";
1716
4ee9c684 1717 case EQ_EXPR:
4ee9c684 1718 return "==";
318a728f 1719 case UNEQ_EXPR:
1720 return "u==";
4ee9c684 1721
1722 case NE_EXPR:
1723 return "!=";
1724
1725 case LT_EXPR:
4ee9c684 1726 return "<";
318a728f 1727 case UNLT_EXPR:
1728 return "u<";
4ee9c684 1729
1730 case LE_EXPR:
4ee9c684 1731 return "<=";
318a728f 1732 case UNLE_EXPR:
1733 return "u<=";
4ee9c684 1734
1735 case GT_EXPR:
4ee9c684 1736 return ">";
318a728f 1737 case UNGT_EXPR:
1738 return "u>";
4ee9c684 1739
1740 case GE_EXPR:
4ee9c684 1741 return ">=";
318a728f 1742 case UNGE_EXPR:
1743 return "u>=";
1744
1745 case LTGT_EXPR:
1746 return "<>";
4ee9c684 1747
1748 case LSHIFT_EXPR:
1749 return "<<";
1750
1751 case RSHIFT_EXPR:
1752 return ">>";
1753
1754 case PLUS_EXPR:
1755 return "+";
1756
1757 case NEGATE_EXPR:
1758 case MINUS_EXPR:
1759 return "-";
1760
1761 case BIT_NOT_EXPR:
1762 return "~";
1763
1764 case TRUTH_NOT_EXPR:
1765 return "!";
1766
1767 case MULT_EXPR:
1768 case INDIRECT_REF:
1769 return "*";
1770
1771 case TRUNC_DIV_EXPR:
1772 case CEIL_DIV_EXPR:
1773 case FLOOR_DIV_EXPR:
1774 case ROUND_DIV_EXPR:
1775 case RDIV_EXPR:
1776 case EXACT_DIV_EXPR:
1777 return "/";
1778
1779 case TRUNC_MOD_EXPR:
1780 case CEIL_MOD_EXPR:
1781 case FLOOR_MOD_EXPR:
1782 case ROUND_MOD_EXPR:
1783 return "%";
1784
1785 case PREDECREMENT_EXPR:
1786 return " --";
1787
1788 case PREINCREMENT_EXPR:
1789 return " ++";
1790
1791 case POSTDECREMENT_EXPR:
1792 return "-- ";
1793
1794 case POSTINCREMENT_EXPR:
1795 return "++ ";
1796
1797 case REFERENCE_EXPR:
1798 return "";
1799
1800 default:
1801 return "<<< ??? >>>";
1802 }
1803}
1804
1805/* Prints the name of a CALL_EXPR. */
1806
1807static void
1808print_call_name (pretty_printer *buffer, tree node)
1809{
1810 tree op0;
1811
1812 if (TREE_CODE (node) != CALL_EXPR)
1813 abort ();
1814
1815 op0 = TREE_OPERAND (node, 0);
1816
1817 if (TREE_CODE (op0) == NON_LVALUE_EXPR)
1818 op0 = TREE_OPERAND (op0, 0);
1819
1820 switch (TREE_CODE (op0))
1821 {
1822 case VAR_DECL:
1823 case PARM_DECL:
1824 PRINT_FUNCTION_NAME (op0);
1825 break;
1826
1827 case ADDR_EXPR:
1828 case INDIRECT_REF:
1829 case NOP_EXPR:
1830 dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
1831 break;
1832
1833 case COND_EXPR:
1834 pp_string (buffer, "(");
1835 dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
1836 pp_string (buffer, ") ? ");
1837 dump_generic_node (buffer, TREE_OPERAND (op0, 1), 0, 0, false);
1838 pp_string (buffer, " : ");
1839 dump_generic_node (buffer, TREE_OPERAND (op0, 2), 0, 0, false);
1840 break;
1841
1842 case COMPONENT_REF:
1843 /* The function is a pointer contained in a structure. */
1844 if (TREE_CODE (TREE_OPERAND (op0, 0)) == INDIRECT_REF ||
1845 TREE_CODE (TREE_OPERAND (op0, 0)) == VAR_DECL)
1846 PRINT_FUNCTION_NAME (TREE_OPERAND (op0, 1));
1847 else
1848 dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
1849 /* else
1850 We can have several levels of structures and a function
1851 pointer inside. This is not implemented yet... */
1852 /* NIY;*/
1853 break;
1854
1855 case ARRAY_REF:
1856 if (TREE_CODE (TREE_OPERAND (op0, 0)) == VAR_DECL)
1857 PRINT_FUNCTION_NAME (TREE_OPERAND (op0, 0));
1858 else
1859 dump_generic_node (buffer, op0, 0, 0, false);
1860 break;
1861
1862 case SSA_NAME:
1863 dump_generic_node (buffer, op0, 0, 0, false);
1864 break;
1865
1866 default:
1867 NIY;
1868 }
1869}
1870
1871/* Parses the string STR and replaces new-lines by '\n', tabs by '\t', ... */
1872
1873static void
1874pretty_print_string (pretty_printer *buffer, const char *str)
1875{
1876 if (str == NULL)
1877 return;
1878
1879 while (*str)
1880 {
1881 switch (str[0])
1882 {
1883 case '\b':
1884 pp_string (buffer, "\\b");
1885 break;
1886
1887 case '\f':
1888 pp_string (buffer, "\\f");
1889 break;
1890
1891 case '\n':
1892 pp_string (buffer, "\\n");
1893 break;
1894
1895 case '\r':
1896 pp_string (buffer, "\\r");
1897 break;
1898
1899 case '\t':
1900 pp_string (buffer, "\\t");
1901 break;
1902
1903 case '\v':
1904 pp_string (buffer, "\\v");
1905 break;
1906
1907 case '\\':
1908 pp_string (buffer, "\\\\");
1909 break;
1910
1911 case '\"':
1912 pp_string (buffer, "\\\"");
1913 break;
1914
1915 case '\'':
1916 pp_string (buffer, "\\'");
1917 break;
1918
1919 case '\0':
1920 pp_string (buffer, "\\0");
1921 break;
1922
1923 case '\1':
1924 pp_string (buffer, "\\1");
1925 break;
1926
1927 case '\2':
1928 pp_string (buffer, "\\2");
1929 break;
1930
1931 case '\3':
1932 pp_string (buffer, "\\3");
1933 break;
1934
1935 case '\4':
1936 pp_string (buffer, "\\4");
1937 break;
1938
1939 case '\5':
1940 pp_string (buffer, "\\5");
1941 break;
1942
1943 case '\6':
1944 pp_string (buffer, "\\6");
1945 break;
1946
1947 case '\7':
1948 pp_string (buffer, "\\7");
1949 break;
1950
1951 default:
1952 pp_character (buffer, str[0]);
1953 break;
1954 }
1955 str++;
1956 }
1957}
1958
1959static void
1960maybe_init_pretty_print (FILE *file)
1961{
1962 if (!initialized)
1963 {
1964 pp_construct (&buffer, /* prefix */NULL, /* line-width */0);
1965 pp_needs_newline (&buffer) = true;
1966 initialized = 1;
1967 }
1968
1969 buffer.buffer->stream = file;
1970}
1971
1972static void
1973newline_and_indent (pretty_printer *buffer, int spc)
1974{
1975 pp_newline (buffer);
1976 INDENT (spc);
1977}
1978
1979static void
1980dump_vops (pretty_printer *buffer, tree stmt, int spc, int flags)
1981{
1982 size_t i;
1983 stmt_ann_t ann = stmt_ann (stmt);
2cf24776 1984 v_may_def_optype v_may_defs = V_MAY_DEF_OPS (ann);
1985 v_must_def_optype v_must_defs = V_MUST_DEF_OPS (ann);
4ee9c684 1986 vuse_optype vuses = VUSE_OPS (ann);
1987
2cf24776 1988 for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++)
4ee9c684 1989 {
1990 pp_string (buffer, "# ");
2cf24776 1991 dump_generic_node (buffer, V_MAY_DEF_RESULT (v_may_defs, i),
1992 spc + 2, flags, false);
1993 pp_string (buffer, " = V_MAY_DEF <");
1994 dump_generic_node (buffer, V_MAY_DEF_OP (v_may_defs, i),
1995 spc + 2, flags, false);
1996 pp_string (buffer, ">;");
1997 newline_and_indent (buffer, spc);
1998 }
1999
2000 for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++)
2001 {
2002 tree v_must_def = V_MUST_DEF_OP (v_must_defs, i);
2003 pp_string (buffer, "# V_MUST_DEF <");
2004 dump_generic_node (buffer, v_must_def, spc + 2, flags, false);
4ee9c684 2005 pp_string (buffer, ">;");
2006 newline_and_indent (buffer, spc);
2007 }
2008
2009 for (i = 0; i < NUM_VUSES (vuses); i++)
2010 {
2011 tree vuse = VUSE_OP (vuses, i);
2012 pp_string (buffer, "# VUSE <");
2013 dump_generic_node (buffer, vuse, spc + 2, flags, false);
2014 pp_string (buffer, ">;");
2015 newline_and_indent (buffer, spc);
2016 }
2017}
2018
2019/* Dumps basic block BB to FILE with details described by FLAGS and
2020 indented by INDENT spaces. */
2021
2022void
2023dump_generic_bb (FILE *file, basic_block bb, int indent, int flags)
2024{
2025 maybe_init_pretty_print (file);
2026 dumping_stmts = true;
2027 dump_generic_bb_buff (&buffer, bb, indent, flags);
2028 pp_flush (&buffer);
2029}
2030
2031/* Dumps header of basic block BB to buffer BUFFER indented by INDENT
2032 spaces and details described by flags. */
2033
2034static void
2035dump_bb_header (pretty_printer *buffer, basic_block bb, int indent, int flags)
2036{
2037 edge e;
2038 tree stmt;
2039
2040 if (flags & TDF_BLOCKS)
2041 {
2042 INDENT (indent);
2043 pp_string (buffer, "# BLOCK ");
2044 pp_decimal_int (buffer, bb->index);
2045
2046 if (flags & TDF_LINENO)
2047 {
2048 block_stmt_iterator bsi;
2049
2050 for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
2051 if (get_lineno (bsi_stmt (bsi)) != -1)
2052 {
2053 pp_string (buffer, ", starting at line ");
2054 pp_decimal_int (buffer, get_lineno (bsi_stmt (bsi)));
2055 break;
2056 }
2057 }
2058 newline_and_indent (buffer, indent);
2059
2060 pp_string (buffer, "# PRED:");
2061 pp_write_text_to_stream (buffer);
2062 for (e = bb->pred; e; e = e->pred_next)
2063 if (flags & TDF_SLIM)
2064 {
2065 pp_string (buffer, " ");
2066 if (e->src == ENTRY_BLOCK_PTR)
2067 pp_string (buffer, "ENTRY");
2068 else
2069 pp_decimal_int (buffer, e->src->index);
2070 }
2071 else
2072 dump_edge_info (buffer->buffer->stream, e, 0);
2073 pp_newline (buffer);
2074 }
2075 else
2076 {
2077 stmt = first_stmt (bb);
2078 if (!stmt || TREE_CODE (stmt) != LABEL_EXPR)
2079 {
2080 INDENT (indent - 2);
2081 pp_string (buffer, "<bb ");
2082 pp_decimal_int (buffer, bb->index);
2083 pp_string (buffer, ">:");
2084 pp_newline (buffer);
2085 }
2086 }
2087}
2088
2089/* Dumps end of basic block BB to buffer BUFFER indented by INDENT
2090 spaces. */
2091
2092static void
2093dump_bb_end (pretty_printer *buffer, basic_block bb, int indent, int flags)
2094{
2095 edge e;
2096
2097 INDENT (indent);
2098 pp_string (buffer, "# SUCC:");
2099 pp_write_text_to_stream (buffer);
2100 for (e = bb->succ; e; e = e->succ_next)
2101 if (flags & TDF_SLIM)
2102 {
2103 pp_string (buffer, " ");
2104 if (e->dest == EXIT_BLOCK_PTR)
2105 pp_string (buffer, "EXIT");
2106 else
2107 pp_decimal_int (buffer, e->dest->index);
2108 }
2109 else
2110 dump_edge_info (buffer->buffer->stream, e, 1);
2111 pp_newline (buffer);
2112}
2113
2114/* Dumps phi nodes of basic block BB to buffer BUFFER with details described by
2115 FLAGS indented by INDENT spaces. */
2116
2117static void
2118dump_phi_nodes (pretty_printer *buffer, basic_block bb, int indent, int flags)
2119{
2120 tree phi = phi_nodes (bb);
2121 if (!phi)
2122 return;
2123
2124 for (; phi; phi = TREE_CHAIN (phi))
2125 {
2126 if (is_gimple_reg (PHI_RESULT (phi)) || (flags & TDF_VOPS))
2127 {
2128 INDENT (indent);
2129 pp_string (buffer, "# ");
2130 dump_generic_node (buffer, phi, indent, flags, false);
2131 pp_newline (buffer);
2132 }
2133 }
2134}
2135
2136/* Dump jump to basic block BB that is represented implicitly in the cfg
2137 to BUFFER. */
2138
2139static void
2140pp_cfg_jump (pretty_printer *buffer, basic_block bb)
2141{
2142 tree stmt;
2143
2144 stmt = first_stmt (bb);
2145
2146 pp_string (buffer, "goto <bb ");
2147 pp_decimal_int (buffer, bb->index);
2148 pp_string (buffer, ">");
2149 if (stmt && TREE_CODE (stmt) == LABEL_EXPR)
2150 {
2151 pp_string (buffer, " (");
2152 dump_generic_node (buffer, LABEL_EXPR_LABEL (stmt), 0, 0, false);
2153 pp_string (buffer, ")");
2154 }
2155 pp_semicolon (buffer);
2156}
2157
2158/* Dump edges represented implicitly in basic block BB to BUFFER, indented
2159 by INDENT spaces, with details given by FLAGS. */
2160
2161static void
815540dd 2162dump_implicit_edges (pretty_printer *buffer, basic_block bb, int indent,
2163 int flags)
4ee9c684 2164{
2165 edge e;
2166
2167 /* If there is a fallthru edge, we may need to add an artificial goto to the
2168 dump. */
2169 for (e = bb->succ; e; e = e->succ_next)
2170 if (e->flags & EDGE_FALLTHRU)
2171 break;
2172 if (e && e->dest != bb->next_bb)
2173 {
2174 INDENT (indent);
815540dd 2175
2176 if ((flags & TDF_LINENO) && e->goto_locus)
2177 {
2178 pp_character (buffer, '[');
2179 if (e->goto_locus->file)
2180 {
2181 pp_string (buffer, e->goto_locus->file);
2182 pp_string (buffer, " : ");
2183 }
2184 pp_decimal_int (buffer, e->goto_locus->line);
2185 pp_string (buffer, "] ");
2186 }
2187
4ee9c684 2188 pp_cfg_jump (buffer, e->dest);
2189 pp_newline (buffer);
2190 }
2191}
2192
2193/* Dumps basic block BB to buffer BUFFER with details described by FLAGS and
2194 indented by INDENT spaces. */
2195
2196static void
2197dump_generic_bb_buff (pretty_printer *buffer, basic_block bb,
2198 int indent, int flags)
2199{
2200 block_stmt_iterator bsi;
2201 tree stmt;
2202 int label_indent = indent - 2;
2203
2204 if (label_indent < 0)
2205 label_indent = 0;
2206
2207 dump_bb_header (buffer, bb, indent, flags);
2208
2209 if (bb_ann (bb))
2210 dump_phi_nodes (buffer, bb, indent, flags);
2211
2212 for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
2213 {
2214 int curr_indent;
2215
2216 stmt = bsi_stmt (bsi);
2217
2218 curr_indent = TREE_CODE (stmt) == LABEL_EXPR ? label_indent : indent;
2219
2220 INDENT (curr_indent);
2221 dump_generic_node (buffer, stmt, curr_indent, flags, true);
2222 pp_newline (buffer);
2223 }
2224
815540dd 2225 dump_implicit_edges (buffer, bb, indent, flags);
4ee9c684 2226
2227 if (flags & TDF_BLOCKS)
2228 dump_bb_end (buffer, bb, indent, flags);
2229}