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