]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/tree-pretty-print.c
* configure.in: Check for srcdir/winsup rather than build directory winsup.
[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:
2363ef00 744 pp_string (buffer, "TARGET_EXPR <");
745 dump_generic_node (buffer, TARGET_EXPR_SLOT (node), spc, flags, false);
746 pp_character (buffer, ',');
747 pp_space (buffer);
4ee9c684 748 dump_generic_node (buffer, TARGET_EXPR_INITIAL (node), spc, flags, false);
2363ef00 749 pp_character (buffer, '>');
4ee9c684 750 break;
751
752 case COND_EXPR:
753 if (TREE_TYPE (node) == void_type_node)
754 {
755 pp_string (buffer, "if (");
756 dump_generic_node (buffer, COND_EXPR_COND (node), spc, flags, false);
757 pp_character (buffer, ')');
758 /* The lowered cond_exprs should always be printed in full. */
759 if (COND_EXPR_THEN (node)
760 && TREE_CODE (COND_EXPR_THEN (node)) == GOTO_EXPR
761 && COND_EXPR_ELSE (node)
762 && TREE_CODE (COND_EXPR_ELSE (node)) == GOTO_EXPR)
763 {
764 pp_space (buffer);
765 dump_generic_node (buffer, COND_EXPR_THEN (node), 0, flags, true);
766 pp_string (buffer, " else ");
767 dump_generic_node (buffer, COND_EXPR_ELSE (node), 0, flags, true);
768 }
769 else if (!(flags & TDF_SLIM))
770 {
771 /* Output COND_EXPR_THEN. */
772 if (COND_EXPR_THEN (node))
773 {
774 newline_and_indent (buffer, spc+2);
775 pp_character (buffer, '{');
776 newline_and_indent (buffer, spc+4);
777 dump_generic_node (buffer, COND_EXPR_THEN (node), spc+4,
778 flags, true);
779 newline_and_indent (buffer, spc+2);
780 pp_character (buffer, '}');
781 }
782
783 /* Output COND_EXPR_ELSE. */
784 if (COND_EXPR_ELSE (node))
785 {
786 newline_and_indent (buffer, spc);
787 pp_string (buffer, "else");
788 newline_and_indent (buffer, spc+2);
789 pp_character (buffer, '{');
790 newline_and_indent (buffer, spc+4);
791 dump_generic_node (buffer, COND_EXPR_ELSE (node), spc+4,
792 flags, true);
793 newline_and_indent (buffer, spc+2);
794 pp_character (buffer, '}');
795 }
796 }
797 is_expr = false;
798 }
799 else
800 {
801 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
802 pp_space (buffer);
803 pp_character (buffer, '?');
804 pp_space (buffer);
805 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
806 pp_space (buffer);
807 pp_character (buffer, ':');
808 pp_space (buffer);
809 dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
810 }
811 break;
812
813 case BIND_EXPR:
814 pp_character (buffer, '{');
815 if (!(flags & TDF_SLIM))
816 {
817 if (BIND_EXPR_VARS (node))
818 {
819 pp_newline (buffer);
820
821 for (op0 = BIND_EXPR_VARS (node); op0; op0 = TREE_CHAIN (op0))
822 {
823 print_declaration (buffer, op0, spc+2, flags);
824 pp_newline (buffer);
825 }
826 }
827
828 newline_and_indent (buffer, spc+2);
829 dump_generic_node (buffer, BIND_EXPR_BODY (node), spc+2, flags, true);
830 newline_and_indent (buffer, spc);
831 pp_character (buffer, '}');
832 }
833 is_expr = false;
834 break;
835
836 case CALL_EXPR:
837 print_call_name (buffer, node);
838
839 /* Print parameters. */
840 pp_space (buffer);
841 pp_character (buffer, '(');
842 op1 = TREE_OPERAND (node, 1);
843 if (op1)
844 dump_generic_node (buffer, op1, spc, flags, false);
845 pp_character (buffer, ')');
846
847 op1 = TREE_OPERAND (node, 2);
848 if (op1)
849 {
850 pp_string (buffer, " [static-chain: ");
851 dump_generic_node (buffer, op1, spc, flags, false);
852 pp_character (buffer, ']');
853 }
854
855 if (CALL_EXPR_TAILCALL (node))
856 pp_string (buffer, " [tail call]");
857 break;
858
859 case WITH_CLEANUP_EXPR:
860 NIY;
861 break;
862
863 case CLEANUP_POINT_EXPR:
864 pp_string (buffer, "<<cleanup_point ");
865 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
866 pp_string (buffer, ">>");
867 break;
868
869 case PLACEHOLDER_EXPR:
870 NIY;
871 break;
872
873 /* Binary arithmetic and logic expressions. */
874 case MULT_EXPR:
875 case PLUS_EXPR:
876 case MINUS_EXPR:
877 case TRUNC_DIV_EXPR:
878 case CEIL_DIV_EXPR:
879 case FLOOR_DIV_EXPR:
880 case ROUND_DIV_EXPR:
881 case TRUNC_MOD_EXPR:
882 case CEIL_MOD_EXPR:
883 case FLOOR_MOD_EXPR:
884 case ROUND_MOD_EXPR:
885 case RDIV_EXPR:
886 case EXACT_DIV_EXPR:
887 case LSHIFT_EXPR:
888 case RSHIFT_EXPR:
889 case LROTATE_EXPR:
890 case RROTATE_EXPR:
891 case BIT_IOR_EXPR:
892 case BIT_XOR_EXPR:
893 case BIT_AND_EXPR:
894 case TRUTH_ANDIF_EXPR:
895 case TRUTH_ORIF_EXPR:
896 case TRUTH_AND_EXPR:
897 case TRUTH_OR_EXPR:
898 case TRUTH_XOR_EXPR:
899 case LT_EXPR:
900 case LE_EXPR:
901 case GT_EXPR:
902 case GE_EXPR:
903 case EQ_EXPR:
904 case NE_EXPR:
905 case UNLT_EXPR:
906 case UNLE_EXPR:
907 case UNGT_EXPR:
908 case UNGE_EXPR:
909 case UNEQ_EXPR:
318a728f 910 case LTGT_EXPR:
911 case ORDERED_EXPR:
912 case UNORDERED_EXPR:
4ee9c684 913 {
914 const char *op = op_symbol (node);
915 op0 = TREE_OPERAND (node, 0);
916 op1 = TREE_OPERAND (node, 1);
917
918 /* When the operands are expressions with less priority,
919 keep semantics of the tree representation. */
920 if (op_prio (op0) < op_prio (node))
921 {
922 pp_character (buffer, '(');
923 dump_generic_node (buffer, op0, spc, flags, false);
924 pp_character (buffer, ')');
925 }
926 else
927 dump_generic_node (buffer, op0, spc, flags, false);
928
929 pp_space (buffer);
930 pp_string (buffer, op);
931 pp_space (buffer);
932
933 /* When the operands are expressions with less priority,
934 keep semantics of the tree representation. */
935 if (op_prio (op1) < op_prio (node))
936 {
937 pp_character (buffer, '(');
938 dump_generic_node (buffer, op1, spc, flags, false);
939 pp_character (buffer, ')');
940 }
941 else
942 dump_generic_node (buffer, op1, spc, flags, false);
943 }
944 break;
945
946 /* Unary arithmetic and logic expressions. */
947 case NEGATE_EXPR:
948 case BIT_NOT_EXPR:
949 case TRUTH_NOT_EXPR:
950 case ADDR_EXPR:
951 case REFERENCE_EXPR:
952 case PREDECREMENT_EXPR:
953 case PREINCREMENT_EXPR:
954 case INDIRECT_REF:
955 if (TREE_CODE (node) == ADDR_EXPR
956 && (TREE_CODE (TREE_OPERAND (node, 0)) == STRING_CST
957 || TREE_CODE (TREE_OPERAND (node, 0)) == FUNCTION_DECL))
958 ; /* Do not output '&' for strings and function pointers. */
959 else
960 pp_string (buffer, op_symbol (node));
961
962 if (op_prio (TREE_OPERAND (node, 0)) < op_prio (node))
963 {
964 pp_character (buffer, '(');
965 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
966 pp_character (buffer, ')');
967 }
968 else
969 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
970 break;
971
972 case POSTDECREMENT_EXPR:
973 case POSTINCREMENT_EXPR:
974 if (op_prio (TREE_OPERAND (node, 0)) < op_prio (node))
975 {
976 pp_character (buffer, '(');
977 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
978 pp_character (buffer, ')');
979 }
980 else
981 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
982 pp_string (buffer, op_symbol (node));
983 break;
984
985 case MIN_EXPR:
986 pp_string (buffer, "MIN_EXPR <");
987 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
988 pp_string (buffer, ", ");
989 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
990 pp_character (buffer, '>');
991 break;
992
993 case MAX_EXPR:
994 pp_string (buffer, "MAX_EXPR <");
995 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
996 pp_string (buffer, ", ");
997 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
998 pp_character (buffer, '>');
999 break;
1000
1001 case ABS_EXPR:
1002 pp_string (buffer, "ABS_EXPR <");
1003 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1004 pp_character (buffer, '>');
1005 break;
1006
4ee9c684 1007 case IN_EXPR:
1008 NIY;
1009 break;
1010
1011 case SET_LE_EXPR:
1012 NIY;
1013 break;
1014
1015 case CARD_EXPR:
1016 NIY;
1017 break;
1018
1019 case RANGE_EXPR:
1020 NIY;
1021 break;
1022
1023 case FIX_TRUNC_EXPR:
1024 case FIX_CEIL_EXPR:
1025 case FIX_FLOOR_EXPR:
1026 case FIX_ROUND_EXPR:
1027 case FLOAT_EXPR:
1028 case CONVERT_EXPR:
1029 case NOP_EXPR:
1030 type = TREE_TYPE (node);
1031 op0 = TREE_OPERAND (node, 0);
1032 if (type != TREE_TYPE (op0))
1033 {
1034 pp_character (buffer, '(');
1035 dump_generic_node (buffer, type, spc, flags, false);
1036 pp_string (buffer, ")");
1037 }
1038 if (op_prio (op0) < op_prio (node))
1039 pp_character (buffer, '(');
1040 dump_generic_node (buffer, op0, spc, flags, false);
1041 if (op_prio (op0) < op_prio (node))
1042 pp_character (buffer, ')');
1043 break;
1044
1045 case VIEW_CONVERT_EXPR:
1046 pp_string (buffer, "VIEW_CONVERT_EXPR<");
1047 dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
1048 pp_string (buffer, ">(");
1049 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1050 pp_character (buffer, ')');
1051 break;
1052
1053 case NON_LVALUE_EXPR:
1054 pp_string (buffer, "NON_LVALUE_EXPR <");
1055 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1056 pp_character (buffer, '>');
1057 break;
1058
1059 case SAVE_EXPR:
1060 pp_string (buffer, "SAVE_EXPR <");
1061 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1062 pp_character (buffer, '>');
1063 break;
1064
1065 case UNSAVE_EXPR:
1066 pp_string (buffer, "UNSAVE_EXPR <");
1067 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1068 pp_character (buffer, '>');
1069 break;
1070
1071 case RTL_EXPR:
1072 NIY;
1073 break;
1074
1075 case ENTRY_VALUE_EXPR:
1076 NIY;
1077 break;
1078
1079 case COMPLEX_EXPR:
1080 pp_string (buffer, "COMPLEX_EXPR <");
1081 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1082 pp_string (buffer, ", ");
1083 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1084 pp_string (buffer, ">");
1085 break;
1086
1087 case CONJ_EXPR:
1088 pp_string (buffer, "CONJ_EXPR <");
1089 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1090 pp_string (buffer, ">");
1091 break;
1092
1093 case REALPART_EXPR:
1094 pp_string (buffer, "REALPART_EXPR <");
1095 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1096 pp_string (buffer, ">");
1097 break;
1098
1099 case IMAGPART_EXPR:
1100 pp_string (buffer, "IMAGPART_EXPR <");
1101 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1102 pp_string (buffer, ">");
1103 break;
1104
1105 case VA_ARG_EXPR:
1106 pp_string (buffer, "VA_ARG_EXPR <");
1107 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1108 pp_string (buffer, ">");
1109 break;
1110
1111 case TRY_FINALLY_EXPR:
1112 case TRY_CATCH_EXPR:
1113 pp_string (buffer, "try");
1114 newline_and_indent (buffer, spc+2);
1115 pp_string (buffer, "{");
1116 newline_and_indent (buffer, spc+4);
1117 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc+4, flags, true);
1118 newline_and_indent (buffer, spc+2);
1119 pp_string (buffer, "}");
1120 newline_and_indent (buffer, spc);
1121 pp_string (buffer,
1122 (TREE_CODE (node) == TRY_CATCH_EXPR) ? "catch" : "finally");
1123 newline_and_indent (buffer, spc+2);
1124 pp_string (buffer, "{");
1125 newline_and_indent (buffer, spc+4);
1126 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc+4, flags, true);
1127 newline_and_indent (buffer, spc+2);
1128 pp_string (buffer, "}");
1129 is_expr = false;
1130 break;
1131
1132 case CATCH_EXPR:
1133 pp_string (buffer, "catch (");
1134 dump_generic_node (buffer, CATCH_TYPES (node), spc+2, flags, false);
1135 pp_string (buffer, ")");
1136 newline_and_indent (buffer, spc+2);
1137 pp_string (buffer, "{");
1138 newline_and_indent (buffer, spc+4);
1139 dump_generic_node (buffer, CATCH_BODY (node), spc+4, flags, true);
1140 newline_and_indent (buffer, spc+2);
1141 pp_string (buffer, "}");
1142 is_expr = false;
1143 break;
1144
1145 case EH_FILTER_EXPR:
1146 pp_string (buffer, "<<<eh_filter (");
1147 dump_generic_node (buffer, EH_FILTER_TYPES (node), spc+2, flags, false);
1148 pp_string (buffer, ")>>>");
1149 newline_and_indent (buffer, spc+2);
1150 pp_string (buffer, "{");
1151 newline_and_indent (buffer, spc+4);
1152 dump_generic_node (buffer, EH_FILTER_FAILURE (node), spc+4, flags, true);
1153 newline_and_indent (buffer, spc+2);
1154 pp_string (buffer, "}");
1155 is_expr = false;
1156 break;
1157
1158 case GOTO_SUBROUTINE_EXPR:
1159 NIY;
1160 break;
1161
1162 case LABEL_EXPR:
1163 op0 = TREE_OPERAND (node, 0);
1164 /* If this is for break or continue, don't bother printing it. */
1165 if (DECL_NAME (op0))
1166 {
1167 const char *name = IDENTIFIER_POINTER (DECL_NAME (op0));
1168 if (strcmp (name, "break") == 0
1169 || strcmp (name, "continue") == 0)
1170 break;
1171 }
1172 dump_generic_node (buffer, op0, spc, flags, false);
1173 pp_character (buffer, ':');
1174 if (DECL_NONLOCAL (op0))
1175 pp_string (buffer, " [non-local]");
1176 break;
1177
1178 case LABELED_BLOCK_EXPR:
1179 op0 = LABELED_BLOCK_LABEL (node);
1180 /* If this is for break or continue, don't bother printing it. */
1181 if (DECL_NAME (op0))
1182 {
1183 const char *name = IDENTIFIER_POINTER (DECL_NAME (op0));
1184 if (strcmp (name, "break") == 0
1185 || strcmp (name, "continue") == 0)
1186 {
1187 dump_generic_node (buffer, LABELED_BLOCK_BODY (node), spc, flags, false);
1188 break;
1189 }
1190 }
1191 dump_generic_node (buffer, LABELED_BLOCK_LABEL (node), spc, flags, false);
1192 pp_string (buffer, ": {");
1193 if (!(flags & TDF_SLIM))
1194 newline_and_indent (buffer, spc+2);
1195 dump_generic_node (buffer, LABELED_BLOCK_BODY (node), spc+2, flags, true);
1196 if (!flags)
1197 newline_and_indent (buffer, spc);
1198 pp_character (buffer, '}');
1199 is_expr = false;
1200 break;
1201
1202 case EXIT_BLOCK_EXPR:
1203 op0 = LABELED_BLOCK_LABEL (EXIT_BLOCK_LABELED_BLOCK (node));
1204 /* If this is for a break or continue, print it accordingly. */
1205 if (DECL_NAME (op0))
1206 {
1207 const char *name = IDENTIFIER_POINTER (DECL_NAME (op0));
1208 if (strcmp (name, "break") == 0
1209 || strcmp (name, "continue") == 0)
1210 {
1211 pp_string (buffer, name);
1212 break;
1213 }
1214 }
1215 pp_string (buffer, "<<<exit block ");
1216 dump_generic_node (buffer, op0, spc, flags, false);
1217 pp_string (buffer, ">>>");
1218 break;
1219
1220 case EXC_PTR_EXPR:
1221 pp_string (buffer, "<<<exception object>>>");
1222 break;
1223
1224 case FILTER_EXPR:
1225 pp_string (buffer, "<<<filter object>>>");
1226 break;
1227
1228 case LOOP_EXPR:
1229 pp_string (buffer, "while (1)");
1230 if (!(flags & TDF_SLIM))
1231 {
1232 newline_and_indent (buffer, spc+2);
1233 pp_character (buffer, '{');
1234 newline_and_indent (buffer, spc+4);
1235 dump_generic_node (buffer, LOOP_EXPR_BODY (node), spc+4, flags, true);
1236 newline_and_indent (buffer, spc+2);
1237 pp_character (buffer, '}');
1238 }
1239 is_expr = false;
1240 break;
1241
1242 case RETURN_EXPR:
1243 pp_string (buffer, "return");
1244 op0 = TREE_OPERAND (node, 0);
1245 if (op0)
1246 {
1247 pp_space (buffer);
1248 if (TREE_CODE (op0) == MODIFY_EXPR)
1249 dump_generic_node (buffer, TREE_OPERAND (op0, 1), spc, flags, false);
1250 else
1251 dump_generic_node (buffer, op0, spc, flags, false);
1252 }
1253 break;
1254
1255 case EXIT_EXPR:
1256 pp_string (buffer, "if (");
1257 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1258 pp_string (buffer, ") break");
1259 break;
1260
1261 case SWITCH_EXPR:
1262 pp_string (buffer, "switch (");
1263 dump_generic_node (buffer, SWITCH_COND (node), spc, flags, false);
1264 pp_character (buffer, ')');
1265 if (!(flags & TDF_SLIM))
1266 {
1267 newline_and_indent (buffer, spc+2);
1268 pp_character (buffer, '{');
1269 if (SWITCH_BODY (node))
1270 {
1271 newline_and_indent (buffer, spc+4);
1272 dump_generic_node (buffer, SWITCH_BODY (node), spc+4, flags, true);
1273 }
1274 else
1275 {
1276 tree vec = SWITCH_LABELS (node);
1277 size_t i, n = TREE_VEC_LENGTH (vec);
1278 for (i = 0; i < n; ++i)
1279 {
1280 tree elt = TREE_VEC_ELT (vec, i);
1281 newline_and_indent (buffer, spc+4);
1282 dump_generic_node (buffer, elt, spc+4, flags, false);
1283 pp_string (buffer, " goto ");
1284 dump_generic_node (buffer, CASE_LABEL (elt), spc+4, flags, true);
1285 pp_semicolon (buffer);
1286 }
1287 }
1288 newline_and_indent (buffer, spc+2);
1289 pp_character (buffer, '}');
1290 }
1291 is_expr = false;
1292 break;
1293
1294 case GOTO_EXPR:
1295 op0 = GOTO_DESTINATION (node);
1296 if (TREE_CODE (op0) != SSA_NAME
1297 && DECL_P (op0)
1298 && DECL_NAME (op0))
1299 {
1300 const char *name = IDENTIFIER_POINTER (DECL_NAME (op0));
1301 if (strcmp (name, "break") == 0
1302 || strcmp (name, "continue") == 0)
1303 {
1304 pp_string (buffer, name);
1305 break;
1306 }
1307 }
1308 pp_string (buffer, "goto ");
1309 dump_generic_node (buffer, op0, spc, flags, false);
1310 break;
1311
1312 case RESX_EXPR:
1313 pp_string (buffer, "resx");
1314 /* ??? Any sensible way to present the eh region? */
1315 break;
1316
1317 case ASM_EXPR:
1318 pp_string (buffer, "__asm__");
1319 if (ASM_VOLATILE_P (node))
1320 pp_string (buffer, " __volatile__");
1321 pp_character (buffer, '(');
1322 dump_generic_node (buffer, ASM_STRING (node), spc, flags, false);
1323 pp_character (buffer, ':');
1324 dump_generic_node (buffer, ASM_OUTPUTS (node), spc, flags, false);
1325 pp_character (buffer, ':');
1326 dump_generic_node (buffer, ASM_INPUTS (node), spc, flags, false);
1327 if (ASM_CLOBBERS (node))
1328 {
1329 pp_character (buffer, ':');
1330 dump_generic_node (buffer, ASM_CLOBBERS (node), spc, flags, false);
1331 }
1332 pp_string (buffer, ")");
1333 break;
1334
1335 case CASE_LABEL_EXPR:
1336 if (CASE_LOW (node) && CASE_HIGH (node))
1337 {
1338 pp_string (buffer, "case ");
1339 dump_generic_node (buffer, CASE_LOW (node), spc, flags, false);
1340 pp_string (buffer, " ... ");
1341 dump_generic_node (buffer, CASE_HIGH (node), spc, flags, false);
1342 }
1343 else if (CASE_LOW (node))
1344 {
1345 pp_string (buffer, "case ");
1346 dump_generic_node (buffer, CASE_LOW (node), spc, flags, false);
1347 }
1348 else
1349 pp_string (buffer, "default ");
1350 pp_character (buffer, ':');
1351 break;
1352
1353 case VTABLE_REF:
1354 pp_string (buffer, "VTABLE_REF <(");
1355 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1356 pp_string (buffer, "),");
1357 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1358 pp_character (buffer, ',');
1359 dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
1360 pp_character (buffer, '>');
1361 break;
1362
4ee9c684 1363 case PHI_NODE:
1364 {
1365 int i;
1366
1367 dump_generic_node (buffer, PHI_RESULT (node), spc, flags, false);
1368 pp_string (buffer, " = PHI <");
1369 for (i = 0; i < PHI_NUM_ARGS (node); i++)
1370 {
1371 dump_generic_node (buffer, PHI_ARG_DEF (node, i), spc, flags, false);
1372 pp_string (buffer, "(");
1373 pp_decimal_int (buffer, PHI_ARG_EDGE (node, i)->src->index);
1374 pp_string (buffer, ")");
1375 if (i < PHI_NUM_ARGS (node) - 1)
1376 pp_string (buffer, ", ");
1377 }
1378 pp_string (buffer, ">;");
1379 }
1380 break;
1381
1382 case SSA_NAME:
1383 dump_generic_node (buffer, SSA_NAME_VAR (node), spc, flags, false);
1384 pp_string (buffer, "_");
1385 pp_decimal_int (buffer, SSA_NAME_VERSION (node));
1386 break;
1387
1388 default:
1389 NIY;
1390 }
1391
1392 if (is_stmt && is_expr)
1393 pp_semicolon (buffer);
1394 pp_write_text_to_stream (buffer);
1395
1396 return spc;
1397}
1398
1399/* Print the declaration of a variable. */
1400
1401static void
1402print_declaration (pretty_printer *buffer, tree t, int spc, int flags)
1403{
1404 /* Don't print type declarations. */
1405 if (TREE_CODE (t) == TYPE_DECL)
1406 return;
1407
1408 INDENT (spc);
1409
1410 if (DECL_REGISTER (t))
1411 pp_string (buffer, "register ");
1412
1413 if (TREE_PUBLIC (t) && DECL_EXTERNAL (t))
1414 pp_string (buffer, "extern ");
1415 else if (TREE_STATIC (t))
1416 pp_string (buffer, "static ");
1417
1418 /* Print the type and name. */
1419 if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
1420 {
1421 tree tmp;
1422
1423 /* Print array's type. */
1424 tmp = TREE_TYPE (t);
1425 while (TREE_CODE (TREE_TYPE (tmp)) == ARRAY_TYPE)
1426 tmp = TREE_TYPE (tmp);
1427 dump_generic_node (buffer, TREE_TYPE (tmp), spc, flags, false);
1428
1429 /* Print variable's name. */
1430 pp_space (buffer);
1431 dump_generic_node (buffer, t, spc, flags, false);
1432
1433 /* Print the dimensions. */
1434 tmp = TREE_TYPE (t);
1435 while (TREE_CODE (tmp) == ARRAY_TYPE)
1436 {
1437 pp_character (buffer, '[');
1438 if (TYPE_DOMAIN (tmp))
1439 {
1440 if (TREE_CODE (TYPE_SIZE (tmp)) == INTEGER_CST)
1441 pp_wide_integer (buffer,
1442 TREE_INT_CST_LOW (TYPE_SIZE (tmp)) /
1443 TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (tmp))));
1444 else
1445 dump_generic_node (buffer, TYPE_SIZE_UNIT (tmp), spc, flags,
1446 false);
1447 }
1448 pp_character (buffer, ']');
1449 tmp = TREE_TYPE (tmp);
1450 }
1451 }
1452 else
1453 {
1454 /* Print type declaration. */
1455 dump_generic_node (buffer, TREE_TYPE (t), spc, flags, false);
1456
1457 /* Print variable's name. */
1458 pp_space (buffer);
1459 dump_generic_node (buffer, t, spc, flags, false);
1460 }
1461
1462 /* The initial value of a function serves to determine wether the function
1463 is declared or defined. So the following does not apply to function
1464 nodes. */
1465 if (TREE_CODE (t) != FUNCTION_DECL)
1466 {
1467 /* Print the initial value. */
1468 if (DECL_INITIAL (t))
1469 {
1470 pp_space (buffer);
1471 pp_character (buffer, '=');
1472 pp_space (buffer);
1473 dump_generic_node (buffer, DECL_INITIAL (t), spc, flags, false);
1474 }
1475 }
1476
1477 pp_character (buffer, ';');
1478}
1479
1480
1481/* Prints a structure: name, fields, and methods.
1482 FIXME: Still incomplete. */
1483
1484static void
1485print_struct_decl (pretty_printer *buffer, tree node, int spc, int flags)
1486{
1487 /* Print the name of the structure. */
1488 if (TYPE_NAME (node))
1489 {
1490 INDENT (spc);
1491 if (TREE_CODE (node) == RECORD_TYPE)
1492 pp_string (buffer, "struct ");
1493 else if (TREE_CODE (node) == UNION_TYPE)
1494 pp_string (buffer, "union ");
1495 else
1496 NIY;
1497 dump_generic_node (buffer, TYPE_NAME (node), spc, 0, false);
1498 }
1499
1500 /* Print the contents of the structure. */
1501 pp_newline (buffer);
1502 INDENT (spc);
1503 pp_character (buffer, '{');
1504 pp_newline (buffer);
1505
1506 /* Print the fields of the structure. */
1507 {
1508 tree tmp;
1509 tmp = TYPE_FIELDS (node);
1510 while (tmp)
1511 {
1512 /* Avoid to print recursively the structure. */
1513 /* FIXME : Not implemented correctly...,
1514 what about the case when we have a cycle in the contain graph? ...
1515 Maybe this could be solved by looking at the scope in which the
1516 structure was declared. */
1517 if (TREE_TYPE (tmp) != node
1518 || (TREE_CODE (TREE_TYPE (tmp)) == POINTER_TYPE &&
1519 TREE_TYPE (TREE_TYPE (tmp)) != node))
1520 {
1521 print_declaration (buffer, tmp, spc+2, flags);
1522 pp_newline (buffer);
1523 }
1524 else
1525 {
1526
1527 }
1528 tmp = TREE_CHAIN (tmp);
1529 }
1530 }
1531 INDENT (spc);
1532 pp_character (buffer, '}');
1533}
1534
1535/* Return the priority of the operator OP.
1536
1537 From lowest to highest precedence with either left-to-right (L-R)
1538 or right-to-left (R-L) associativity]:
1539
1540 1 [L-R] ,
1541 2 [R-L] = += -= *= /= %= &= ^= |= <<= >>=
1542 3 [R-L] ?:
1543 4 [L-R] ||
1544 5 [L-R] &&
1545 6 [L-R] |
1546 7 [L-R] ^
1547 8 [L-R] &
1548 9 [L-R] == !=
1549 10 [L-R] < <= > >=
1550 11 [L-R] << >>
1551 12 [L-R] + -
1552 13 [L-R] * / %
1553 14 [R-L] ! ~ ++ -- + - * & (type) sizeof
1554 15 [L-R] fn() [] -> .
1555
1556 unary +, - and * have higher precedence than the corresponding binary
1557 operators. */
1558
1559static int
1560op_prio (tree op)
1561{
1562 if (op == NULL)
1563 return 9999;
1564
1565 switch (TREE_CODE (op))
1566 {
1567 case TREE_LIST:
1568 case COMPOUND_EXPR:
1569 case BIND_EXPR:
1570 return 1;
1571
1572 case MODIFY_EXPR:
1573 case INIT_EXPR:
1574 return 2;
1575
1576 case COND_EXPR:
1577 return 3;
1578
1579 case TRUTH_OR_EXPR:
1580 case TRUTH_ORIF_EXPR:
1581 return 4;
1582
1583 case TRUTH_AND_EXPR:
1584 case TRUTH_ANDIF_EXPR:
1585 return 5;
1586
1587 case BIT_IOR_EXPR:
1588 return 6;
1589
1590 case BIT_XOR_EXPR:
1591 case TRUTH_XOR_EXPR:
1592 return 7;
1593
1594 case BIT_AND_EXPR:
1595 return 8;
1596
1597 case EQ_EXPR:
1598 case NE_EXPR:
1599 return 9;
1600
318a728f 1601 case UNLT_EXPR:
1602 case UNLE_EXPR:
1603 case UNGT_EXPR:
1604 case UNGE_EXPR:
1605 case UNEQ_EXPR:
1606 case LTGT_EXPR:
1607 case ORDERED_EXPR:
1608 case UNORDERED_EXPR:
4ee9c684 1609 case LT_EXPR:
1610 case LE_EXPR:
1611 case GT_EXPR:
1612 case GE_EXPR:
1613 return 10;
1614
1615 case LSHIFT_EXPR:
1616 case RSHIFT_EXPR:
1617 case LROTATE_EXPR:
1618 case RROTATE_EXPR:
1619 return 11;
1620
1621 case PLUS_EXPR:
1622 case MINUS_EXPR:
1623 return 12;
1624
1625 case MULT_EXPR:
1626 case TRUNC_DIV_EXPR:
1627 case CEIL_DIV_EXPR:
1628 case FLOOR_DIV_EXPR:
1629 case ROUND_DIV_EXPR:
1630 case RDIV_EXPR:
1631 case EXACT_DIV_EXPR:
1632 case TRUNC_MOD_EXPR:
1633 case CEIL_MOD_EXPR:
1634 case FLOOR_MOD_EXPR:
1635 case ROUND_MOD_EXPR:
1636 return 13;
1637
1638 case TRUTH_NOT_EXPR:
1639 case BIT_NOT_EXPR:
1640 case POSTINCREMENT_EXPR:
1641 case POSTDECREMENT_EXPR:
1642 case PREINCREMENT_EXPR:
1643 case PREDECREMENT_EXPR:
1644 case NEGATE_EXPR:
1645 case INDIRECT_REF:
1646 case ADDR_EXPR:
1647 case FLOAT_EXPR:
1648 case NOP_EXPR:
1649 case CONVERT_EXPR:
1650 case FIX_TRUNC_EXPR:
1651 case FIX_CEIL_EXPR:
1652 case FIX_FLOOR_EXPR:
1653 case FIX_ROUND_EXPR:
1654 case TARGET_EXPR:
1655 return 14;
1656
1657 case CALL_EXPR:
1658 case ARRAY_REF:
1659 case COMPONENT_REF:
1660 return 15;
1661
1662 /* Special expressions. */
1663 case MIN_EXPR:
1664 case MAX_EXPR:
1665 case ABS_EXPR:
1666 case REALPART_EXPR:
1667 case IMAGPART_EXPR:
1668 return 16;
1669
1670 case SAVE_EXPR:
1671 case NON_LVALUE_EXPR:
1672 return op_prio (TREE_OPERAND (op, 0));
1673
1674 default:
1675 /* Return an arbitrarily high precedence to avoid surrounding single
1676 VAR_DECLs in ()s. */
1677 return 9999;
1678 }
1679}
1680
1681
1682/* Return the symbol associated with operator OP. */
1683
1684static const char *
1685op_symbol (tree op)
1686{
1687 if (op == NULL)
1688 abort ();
1689
1690 switch (TREE_CODE (op))
1691 {
1692 case MODIFY_EXPR:
1693 return "=";
1694
1695 case TRUTH_OR_EXPR:
1696 case TRUTH_ORIF_EXPR:
1697 return "||";
1698
1699 case TRUTH_AND_EXPR:
1700 case TRUTH_ANDIF_EXPR:
1701 return "&&";
1702
1703 case BIT_IOR_EXPR:
1704 return "|";
1705
1706 case TRUTH_XOR_EXPR:
1707 case BIT_XOR_EXPR:
1708 return "^";
1709
1710 case ADDR_EXPR:
1711 case BIT_AND_EXPR:
1712 return "&";
1713
318a728f 1714 case ORDERED_EXPR:
1715 return "ord";
1716 case UNORDERED_EXPR:
1717 return "unord";
1718
4ee9c684 1719 case EQ_EXPR:
4ee9c684 1720 return "==";
318a728f 1721 case UNEQ_EXPR:
1722 return "u==";
4ee9c684 1723
1724 case NE_EXPR:
1725 return "!=";
1726
1727 case LT_EXPR:
4ee9c684 1728 return "<";
318a728f 1729 case UNLT_EXPR:
1730 return "u<";
4ee9c684 1731
1732 case LE_EXPR:
4ee9c684 1733 return "<=";
318a728f 1734 case UNLE_EXPR:
1735 return "u<=";
4ee9c684 1736
1737 case GT_EXPR:
4ee9c684 1738 return ">";
318a728f 1739 case UNGT_EXPR:
1740 return "u>";
4ee9c684 1741
1742 case GE_EXPR:
4ee9c684 1743 return ">=";
318a728f 1744 case UNGE_EXPR:
1745 return "u>=";
1746
1747 case LTGT_EXPR:
1748 return "<>";
4ee9c684 1749
1750 case LSHIFT_EXPR:
1751 return "<<";
1752
1753 case RSHIFT_EXPR:
1754 return ">>";
1755
1756 case PLUS_EXPR:
1757 return "+";
1758
1759 case NEGATE_EXPR:
1760 case MINUS_EXPR:
1761 return "-";
1762
1763 case BIT_NOT_EXPR:
1764 return "~";
1765
1766 case TRUTH_NOT_EXPR:
1767 return "!";
1768
1769 case MULT_EXPR:
1770 case INDIRECT_REF:
1771 return "*";
1772
1773 case TRUNC_DIV_EXPR:
1774 case CEIL_DIV_EXPR:
1775 case FLOOR_DIV_EXPR:
1776 case ROUND_DIV_EXPR:
1777 case RDIV_EXPR:
1778 case EXACT_DIV_EXPR:
1779 return "/";
1780
1781 case TRUNC_MOD_EXPR:
1782 case CEIL_MOD_EXPR:
1783 case FLOOR_MOD_EXPR:
1784 case ROUND_MOD_EXPR:
1785 return "%";
1786
1787 case PREDECREMENT_EXPR:
1788 return " --";
1789
1790 case PREINCREMENT_EXPR:
1791 return " ++";
1792
1793 case POSTDECREMENT_EXPR:
1794 return "-- ";
1795
1796 case POSTINCREMENT_EXPR:
1797 return "++ ";
1798
1799 case REFERENCE_EXPR:
1800 return "";
1801
1802 default:
1803 return "<<< ??? >>>";
1804 }
1805}
1806
1807/* Prints the name of a CALL_EXPR. */
1808
1809static void
1810print_call_name (pretty_printer *buffer, tree node)
1811{
1812 tree op0;
1813
1814 if (TREE_CODE (node) != CALL_EXPR)
1815 abort ();
1816
1817 op0 = TREE_OPERAND (node, 0);
1818
1819 if (TREE_CODE (op0) == NON_LVALUE_EXPR)
1820 op0 = TREE_OPERAND (op0, 0);
1821
1822 switch (TREE_CODE (op0))
1823 {
1824 case VAR_DECL:
1825 case PARM_DECL:
1826 PRINT_FUNCTION_NAME (op0);
1827 break;
1828
1829 case ADDR_EXPR:
1830 case INDIRECT_REF:
1831 case NOP_EXPR:
1832 dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
1833 break;
1834
1835 case COND_EXPR:
1836 pp_string (buffer, "(");
1837 dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
1838 pp_string (buffer, ") ? ");
1839 dump_generic_node (buffer, TREE_OPERAND (op0, 1), 0, 0, false);
1840 pp_string (buffer, " : ");
1841 dump_generic_node (buffer, TREE_OPERAND (op0, 2), 0, 0, false);
1842 break;
1843
1844 case COMPONENT_REF:
1845 /* The function is a pointer contained in a structure. */
1846 if (TREE_CODE (TREE_OPERAND (op0, 0)) == INDIRECT_REF ||
1847 TREE_CODE (TREE_OPERAND (op0, 0)) == VAR_DECL)
1848 PRINT_FUNCTION_NAME (TREE_OPERAND (op0, 1));
1849 else
1850 dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
1851 /* else
1852 We can have several levels of structures and a function
1853 pointer inside. This is not implemented yet... */
1854 /* NIY;*/
1855 break;
1856
1857 case ARRAY_REF:
1858 if (TREE_CODE (TREE_OPERAND (op0, 0)) == VAR_DECL)
1859 PRINT_FUNCTION_NAME (TREE_OPERAND (op0, 0));
1860 else
1861 dump_generic_node (buffer, op0, 0, 0, false);
1862 break;
1863
1864 case SSA_NAME:
1865 dump_generic_node (buffer, op0, 0, 0, false);
1866 break;
1867
1868 default:
1869 NIY;
1870 }
1871}
1872
1873/* Parses the string STR and replaces new-lines by '\n', tabs by '\t', ... */
1874
1875static void
1876pretty_print_string (pretty_printer *buffer, const char *str)
1877{
1878 if (str == NULL)
1879 return;
1880
1881 while (*str)
1882 {
1883 switch (str[0])
1884 {
1885 case '\b':
1886 pp_string (buffer, "\\b");
1887 break;
1888
1889 case '\f':
1890 pp_string (buffer, "\\f");
1891 break;
1892
1893 case '\n':
1894 pp_string (buffer, "\\n");
1895 break;
1896
1897 case '\r':
1898 pp_string (buffer, "\\r");
1899 break;
1900
1901 case '\t':
1902 pp_string (buffer, "\\t");
1903 break;
1904
1905 case '\v':
1906 pp_string (buffer, "\\v");
1907 break;
1908
1909 case '\\':
1910 pp_string (buffer, "\\\\");
1911 break;
1912
1913 case '\"':
1914 pp_string (buffer, "\\\"");
1915 break;
1916
1917 case '\'':
1918 pp_string (buffer, "\\'");
1919 break;
1920
1921 case '\0':
1922 pp_string (buffer, "\\0");
1923 break;
1924
1925 case '\1':
1926 pp_string (buffer, "\\1");
1927 break;
1928
1929 case '\2':
1930 pp_string (buffer, "\\2");
1931 break;
1932
1933 case '\3':
1934 pp_string (buffer, "\\3");
1935 break;
1936
1937 case '\4':
1938 pp_string (buffer, "\\4");
1939 break;
1940
1941 case '\5':
1942 pp_string (buffer, "\\5");
1943 break;
1944
1945 case '\6':
1946 pp_string (buffer, "\\6");
1947 break;
1948
1949 case '\7':
1950 pp_string (buffer, "\\7");
1951 break;
1952
1953 default:
1954 pp_character (buffer, str[0]);
1955 break;
1956 }
1957 str++;
1958 }
1959}
1960
1961static void
1962maybe_init_pretty_print (FILE *file)
1963{
1964 if (!initialized)
1965 {
1966 pp_construct (&buffer, /* prefix */NULL, /* line-width */0);
1967 pp_needs_newline (&buffer) = true;
1968 initialized = 1;
1969 }
1970
1971 buffer.buffer->stream = file;
1972}
1973
1974static void
1975newline_and_indent (pretty_printer *buffer, int spc)
1976{
1977 pp_newline (buffer);
1978 INDENT (spc);
1979}
1980
1981static void
1982dump_vops (pretty_printer *buffer, tree stmt, int spc, int flags)
1983{
1984 size_t i;
1985 stmt_ann_t ann = stmt_ann (stmt);
2cf24776 1986 v_may_def_optype v_may_defs = V_MAY_DEF_OPS (ann);
1987 v_must_def_optype v_must_defs = V_MUST_DEF_OPS (ann);
4ee9c684 1988 vuse_optype vuses = VUSE_OPS (ann);
1989
2cf24776 1990 for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++)
4ee9c684 1991 {
1992 pp_string (buffer, "# ");
2cf24776 1993 dump_generic_node (buffer, V_MAY_DEF_RESULT (v_may_defs, i),
1994 spc + 2, flags, false);
1995 pp_string (buffer, " = V_MAY_DEF <");
1996 dump_generic_node (buffer, V_MAY_DEF_OP (v_may_defs, i),
1997 spc + 2, flags, false);
1998 pp_string (buffer, ">;");
1999 newline_and_indent (buffer, spc);
2000 }
2001
2002 for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++)
2003 {
2004 tree v_must_def = V_MUST_DEF_OP (v_must_defs, i);
2005 pp_string (buffer, "# V_MUST_DEF <");
2006 dump_generic_node (buffer, v_must_def, spc + 2, flags, false);
4ee9c684 2007 pp_string (buffer, ">;");
2008 newline_and_indent (buffer, spc);
2009 }
2010
2011 for (i = 0; i < NUM_VUSES (vuses); i++)
2012 {
2013 tree vuse = VUSE_OP (vuses, i);
2014 pp_string (buffer, "# VUSE <");
2015 dump_generic_node (buffer, vuse, spc + 2, flags, false);
2016 pp_string (buffer, ">;");
2017 newline_and_indent (buffer, spc);
2018 }
2019}
2020
2021/* Dumps basic block BB to FILE with details described by FLAGS and
2022 indented by INDENT spaces. */
2023
2024void
2025dump_generic_bb (FILE *file, basic_block bb, int indent, int flags)
2026{
2027 maybe_init_pretty_print (file);
2028 dumping_stmts = true;
2029 dump_generic_bb_buff (&buffer, bb, indent, flags);
2030 pp_flush (&buffer);
2031}
2032
2033/* Dumps header of basic block BB to buffer BUFFER indented by INDENT
2034 spaces and details described by flags. */
2035
2036static void
2037dump_bb_header (pretty_printer *buffer, basic_block bb, int indent, int flags)
2038{
2039 edge e;
2040 tree stmt;
2041
2042 if (flags & TDF_BLOCKS)
2043 {
2044 INDENT (indent);
2045 pp_string (buffer, "# BLOCK ");
2046 pp_decimal_int (buffer, bb->index);
2047
2048 if (flags & TDF_LINENO)
2049 {
2050 block_stmt_iterator bsi;
2051
2052 for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
2053 if (get_lineno (bsi_stmt (bsi)) != -1)
2054 {
2055 pp_string (buffer, ", starting at line ");
2056 pp_decimal_int (buffer, get_lineno (bsi_stmt (bsi)));
2057 break;
2058 }
2059 }
2060 newline_and_indent (buffer, indent);
2061
2062 pp_string (buffer, "# PRED:");
2063 pp_write_text_to_stream (buffer);
2064 for (e = bb->pred; e; e = e->pred_next)
2065 if (flags & TDF_SLIM)
2066 {
2067 pp_string (buffer, " ");
2068 if (e->src == ENTRY_BLOCK_PTR)
2069 pp_string (buffer, "ENTRY");
2070 else
2071 pp_decimal_int (buffer, e->src->index);
2072 }
2073 else
2074 dump_edge_info (buffer->buffer->stream, e, 0);
2075 pp_newline (buffer);
2076 }
2077 else
2078 {
2079 stmt = first_stmt (bb);
2080 if (!stmt || TREE_CODE (stmt) != LABEL_EXPR)
2081 {
2082 INDENT (indent - 2);
2083 pp_string (buffer, "<bb ");
2084 pp_decimal_int (buffer, bb->index);
2085 pp_string (buffer, ">:");
2086 pp_newline (buffer);
2087 }
2088 }
2089}
2090
2091/* Dumps end of basic block BB to buffer BUFFER indented by INDENT
2092 spaces. */
2093
2094static void
2095dump_bb_end (pretty_printer *buffer, basic_block bb, int indent, int flags)
2096{
2097 edge e;
2098
2099 INDENT (indent);
2100 pp_string (buffer, "# SUCC:");
2101 pp_write_text_to_stream (buffer);
2102 for (e = bb->succ; e; e = e->succ_next)
2103 if (flags & TDF_SLIM)
2104 {
2105 pp_string (buffer, " ");
2106 if (e->dest == EXIT_BLOCK_PTR)
2107 pp_string (buffer, "EXIT");
2108 else
2109 pp_decimal_int (buffer, e->dest->index);
2110 }
2111 else
2112 dump_edge_info (buffer->buffer->stream, e, 1);
2113 pp_newline (buffer);
2114}
2115
2116/* Dumps phi nodes of basic block BB to buffer BUFFER with details described by
2117 FLAGS indented by INDENT spaces. */
2118
2119static void
2120dump_phi_nodes (pretty_printer *buffer, basic_block bb, int indent, int flags)
2121{
2122 tree phi = phi_nodes (bb);
2123 if (!phi)
2124 return;
2125
04f8eea3 2126 for (; phi; phi = PHI_CHAIN (phi))
4ee9c684 2127 {
2128 if (is_gimple_reg (PHI_RESULT (phi)) || (flags & TDF_VOPS))
2129 {
2130 INDENT (indent);
2131 pp_string (buffer, "# ");
2132 dump_generic_node (buffer, phi, indent, flags, false);
2133 pp_newline (buffer);
2134 }
2135 }
2136}
2137
2138/* Dump jump to basic block BB that is represented implicitly in the cfg
2139 to BUFFER. */
2140
2141static void
2142pp_cfg_jump (pretty_printer *buffer, basic_block bb)
2143{
2144 tree stmt;
2145
2146 stmt = first_stmt (bb);
2147
2148 pp_string (buffer, "goto <bb ");
2149 pp_decimal_int (buffer, bb->index);
2150 pp_string (buffer, ">");
2151 if (stmt && TREE_CODE (stmt) == LABEL_EXPR)
2152 {
2153 pp_string (buffer, " (");
2154 dump_generic_node (buffer, LABEL_EXPR_LABEL (stmt), 0, 0, false);
2155 pp_string (buffer, ")");
2156 }
2157 pp_semicolon (buffer);
2158}
2159
2160/* Dump edges represented implicitly in basic block BB to BUFFER, indented
2161 by INDENT spaces, with details given by FLAGS. */
2162
2163static void
815540dd 2164dump_implicit_edges (pretty_printer *buffer, basic_block bb, int indent,
2165 int flags)
4ee9c684 2166{
2167 edge e;
2168
2169 /* If there is a fallthru edge, we may need to add an artificial goto to the
2170 dump. */
2171 for (e = bb->succ; e; e = e->succ_next)
2172 if (e->flags & EDGE_FALLTHRU)
2173 break;
2174 if (e && e->dest != bb->next_bb)
2175 {
2176 INDENT (indent);
815540dd 2177
2178 if ((flags & TDF_LINENO) && e->goto_locus)
2179 {
2180 pp_character (buffer, '[');
2181 if (e->goto_locus->file)
2182 {
2183 pp_string (buffer, e->goto_locus->file);
2184 pp_string (buffer, " : ");
2185 }
2186 pp_decimal_int (buffer, e->goto_locus->line);
2187 pp_string (buffer, "] ");
2188 }
2189
4ee9c684 2190 pp_cfg_jump (buffer, e->dest);
2191 pp_newline (buffer);
2192 }
2193}
2194
2195/* Dumps basic block BB to buffer BUFFER with details described by FLAGS and
2196 indented by INDENT spaces. */
2197
2198static void
2199dump_generic_bb_buff (pretty_printer *buffer, basic_block bb,
2200 int indent, int flags)
2201{
2202 block_stmt_iterator bsi;
2203 tree stmt;
2204 int label_indent = indent - 2;
2205
2206 if (label_indent < 0)
2207 label_indent = 0;
2208
2209 dump_bb_header (buffer, bb, indent, flags);
2210
2211 if (bb_ann (bb))
2212 dump_phi_nodes (buffer, bb, indent, flags);
2213
2214 for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
2215 {
2216 int curr_indent;
2217
2218 stmt = bsi_stmt (bsi);
2219
2220 curr_indent = TREE_CODE (stmt) == LABEL_EXPR ? label_indent : indent;
2221
2222 INDENT (curr_indent);
2223 dump_generic_node (buffer, stmt, curr_indent, flags, true);
2224 pp_newline (buffer);
2225 }
2226
815540dd 2227 dump_implicit_edges (buffer, bb, indent, flags);
4ee9c684 2228
2229 if (flags & TDF_BLOCKS)
2230 dump_bb_end (buffer, bb, indent, flags);
2231}