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