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