OSDN Git Service

8f36235eb43d65da64e5f848c62eb986802498e0
[pf3gnuchains/gcc-fork.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 = 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     dump_vops (buffer, node, spc, flags);
273
274   if (dumping_stmts
275       && (flags & TDF_LINENO)
276       && EXPR_HAS_LOCATION (node))
277     {
278       expanded_location xloc = expand_location (EXPR_LOCATION (node));
279       pp_character (buffer, '[');
280       if (xloc.file)
281         {
282           pp_string (buffer, xloc.file);
283           pp_string (buffer, " : ");
284         }
285       pp_decimal_int (buffer, xloc.line);
286       pp_string (buffer, "] ");
287     }
288
289   switch (TREE_CODE (node))
290     {
291     case ERROR_MARK:
292       pp_string (buffer, "<<< error >>>");
293       break;
294
295     case IDENTIFIER_NODE:
296       pp_tree_identifier (buffer, node);
297       break;
298
299     case TREE_LIST:
300       while (node && node != error_mark_node)
301         {
302           if (TREE_PURPOSE (node))
303             {
304               dump_generic_node (buffer, TREE_PURPOSE (node), spc, flags, false);
305               pp_space (buffer);
306             }
307           dump_generic_node (buffer, TREE_VALUE (node), spc, flags, false);
308           node = TREE_CHAIN (node);
309           if (node && TREE_CODE (node) == TREE_LIST)
310             {
311               pp_character (buffer, ',');
312               pp_space (buffer);
313             }
314         }
315       break;
316
317     case TREE_BINFO:
318       dump_generic_node (buffer, BINFO_TYPE (node), spc, flags, false);
319
320     case TREE_VEC:
321       {
322         size_t i;
323         if (TREE_VEC_LENGTH (node) > 0)
324           {
325             size_t len = TREE_VEC_LENGTH (node);
326             for (i = 0; i < len - 1; i++)
327               {     
328                 dump_generic_node (buffer, TREE_VEC_ELT (node, i), spc, flags,
329                                    false);
330                 pp_character (buffer, ',');
331                 pp_space (buffer);
332               }
333             dump_generic_node (buffer, TREE_VEC_ELT (node, len - 1), spc, 
334                                flags, false);
335           }
336       }
337       break;
338
339     case BLOCK:
340       NIY;
341       break;
342
343     case VOID_TYPE:
344     case INTEGER_TYPE:
345     case REAL_TYPE:
346     case COMPLEX_TYPE:
347     case VECTOR_TYPE:
348     case ENUMERAL_TYPE:
349     case BOOLEAN_TYPE:
350     case CHAR_TYPE:
351       {
352         unsigned int quals = TYPE_QUALS (node);
353         enum tree_code_class class;
354
355         if (quals & TYPE_QUAL_CONST)
356           pp_string (buffer, "const ");
357         else if (quals & TYPE_QUAL_VOLATILE)
358           pp_string (buffer, "volatile ");
359         else if (quals & TYPE_QUAL_RESTRICT)
360           pp_string (buffer, "restrict ");
361
362         class = TREE_CODE_CLASS (TREE_CODE (node));
363
364         if (class == tcc_declaration)
365           {
366             if (DECL_NAME (node))
367               dump_decl_name (buffer, node, flags);
368             else
369               pp_string (buffer, "<unnamed type decl>");
370           }
371         else if (class == tcc_type)
372           {
373             if (TYPE_NAME (node))
374               {
375                 if (TREE_CODE (TYPE_NAME (node)) == IDENTIFIER_NODE)
376                   pp_tree_identifier (buffer, TYPE_NAME (node));
377                 else if (TREE_CODE (TYPE_NAME (node)) == TYPE_DECL
378                          && DECL_NAME (TYPE_NAME (node)))
379                   dump_decl_name (buffer, TYPE_NAME (node), flags);
380                 else
381                   pp_string (buffer, "<unnamed type>");
382               }
383             else if (TREE_CODE (node) == VECTOR_TYPE)
384               {
385                 pp_string (buffer, "vector ");
386                 dump_generic_node (buffer, TREE_TYPE (node), 
387                                    spc, flags, false);
388               }
389             else
390               pp_string (buffer, "<unnamed type>");
391           }
392         break;
393       }
394
395     case POINTER_TYPE:
396     case REFERENCE_TYPE:
397       str = (TREE_CODE (node) == POINTER_TYPE ? "*" : "&");
398
399       if (TREE_CODE (TREE_TYPE (node)) == FUNCTION_TYPE)
400         {
401           tree fnode = TREE_TYPE (node);
402
403           dump_generic_node (buffer, TREE_TYPE (fnode), spc, flags, false);
404           pp_space (buffer);
405           pp_character (buffer, '(');
406           pp_string (buffer, str);
407           if (TYPE_NAME (node) && DECL_NAME (TYPE_NAME (node)))
408             dump_decl_name (buffer, TYPE_NAME (node), flags);
409           else
410             pp_printf (buffer, "<T%x>", TYPE_UID (node));
411
412           pp_character (buffer, ')');
413           dump_function_declaration (buffer, fnode, spc, flags);
414         }
415       else
416         {
417           unsigned int quals = TYPE_QUALS (node);
418
419           dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
420           pp_space (buffer);
421           pp_string (buffer, str);
422
423           if (quals & TYPE_QUAL_CONST)
424             pp_string (buffer, " const");
425           else if (quals & TYPE_QUAL_VOLATILE)
426             pp_string (buffer,  "volatile");
427           else if (quals & TYPE_QUAL_RESTRICT)
428             pp_string (buffer, " restrict");
429
430           if (TYPE_REF_CAN_ALIAS_ALL (node))
431             pp_string (buffer, " {ref-all}");
432         }
433       break;
434
435     case OFFSET_TYPE:
436       NIY;
437       break;
438
439     case METHOD_TYPE:
440       dump_decl_name (buffer, TYPE_NAME (TYPE_METHOD_BASETYPE (node)), flags);
441       pp_string (buffer, "::");
442       break;
443
444     case FILE_TYPE:
445       NIY;
446       break;
447
448     case ARRAY_TYPE:
449       {
450         tree tmp;
451
452         /* Print the innermost component type.  */
453         for (tmp = TREE_TYPE (node); TREE_CODE (tmp) == ARRAY_TYPE;
454              tmp = TREE_TYPE (tmp))
455           ;
456         dump_generic_node (buffer, tmp, spc, flags, false);
457
458         /* Print the dimensions.  */
459         for (tmp = node; TREE_CODE (tmp) == ARRAY_TYPE; tmp = TREE_TYPE (tmp))
460           dump_array_domain (buffer, TYPE_DOMAIN (tmp), spc, flags);
461         break;
462       }
463
464     case SET_TYPE:
465       NIY;
466       break;
467
468     case RECORD_TYPE:
469     case UNION_TYPE:
470     case QUAL_UNION_TYPE:
471       /* Print the name of the structure.  */
472       if (TREE_CODE (node) == RECORD_TYPE)
473         pp_string (buffer, "struct ");
474       else if (TREE_CODE (node) == UNION_TYPE)
475         pp_string (buffer, "union ");
476
477       if (TYPE_NAME (node))
478         dump_generic_node (buffer, TYPE_NAME (node), spc, flags, false);
479       else
480         print_struct_decl (buffer, node, spc, flags);
481       break;
482
483     case LANG_TYPE:
484       NIY;
485       break;
486
487     case INTEGER_CST:
488       if (TREE_CODE (TREE_TYPE (node)) == POINTER_TYPE)
489         {
490           /* In the case of a pointer, one may want to divide by the
491              size of the pointed-to type.  Unfortunately, this not
492              straightforward.  The C front-end maps expressions
493
494              (int *) 5
495              int *p; (p + 5)
496
497              in such a way that the two INTEGER_CST nodes for "5" have
498              different values but identical types.  In the latter
499              case, the 5 is multiplied by sizeof (int) in c-common.c
500              (pointer_int_sum) to convert it to a byte address, and
501              yet the type of the node is left unchanged.  Argh.  What
502              is consistent though is that the number value corresponds
503              to bytes (UNITS) offset.
504
505              NB: Neither of the following divisors can be trivially
506              used to recover the original literal:
507
508              TREE_INT_CST_LOW (TYPE_SIZE_UNIT (TREE_TYPE (node)))
509              TYPE_PRECISION (TREE_TYPE (TREE_TYPE (node)))  */
510           pp_wide_integer (buffer, TREE_INT_CST_LOW (node));
511           pp_string (buffer, "B"); /* pseudo-unit */
512         }
513       else if (! host_integerp (node, 0))
514         {
515           tree val = node;
516
517           if (tree_int_cst_sgn (val) < 0)
518             {
519               pp_character (buffer, '-');
520               val = build_int_cst_wide (NULL_TREE,
521                                         -TREE_INT_CST_LOW (val),
522                                         ~TREE_INT_CST_HIGH (val)
523                                         + !TREE_INT_CST_LOW (val));
524             }
525           /* Would "%x%0*x" or "%x%*0x" get zero-padding on all
526              systems?  */
527           {
528             static char format[10]; /* "%x%09999x\0" */
529             if (!format[0])
530               sprintf (format, "%%x%%0%dx", HOST_BITS_PER_INT / 4);
531             sprintf (pp_buffer (buffer)->digit_buffer, format,
532                      TREE_INT_CST_HIGH (val),
533                      TREE_INT_CST_LOW (val));
534             pp_string (buffer, pp_buffer (buffer)->digit_buffer);
535           }
536         }
537       else
538         pp_wide_integer (buffer, TREE_INT_CST_LOW (node));
539       break;
540
541     case REAL_CST:
542       /* Code copied from print_node.  */
543       {
544         REAL_VALUE_TYPE d;
545         if (TREE_OVERFLOW (node))
546           pp_string (buffer, " overflow");
547
548 #if !defined(REAL_IS_NOT_DOUBLE) || defined(REAL_ARITHMETIC)
549         d = TREE_REAL_CST (node);
550         if (REAL_VALUE_ISINF (d))
551           pp_string (buffer, " Inf");
552         else if (REAL_VALUE_ISNAN (d))
553           pp_string (buffer, " Nan");
554         else
555           {
556             char string[100];
557             real_to_decimal (string, &d, sizeof (string), 0, 1);
558             pp_string (buffer, string);
559           }
560 #else
561         {
562           HOST_WIDE_INT i;
563           unsigned char *p = (unsigned char *) &TREE_REAL_CST (node);
564           pp_string (buffer, "0x");
565           for (i = 0; i < sizeof TREE_REAL_CST (node); i++)
566             output_formatted_integer (buffer, "%02x", *p++);
567         }
568 #endif
569         break;
570       }
571
572     case COMPLEX_CST:
573       pp_string (buffer, "__complex__ (");
574       dump_generic_node (buffer, TREE_REALPART (node), spc, flags, false);
575       pp_string (buffer, ", ");
576       dump_generic_node (buffer, TREE_IMAGPART (node), spc, flags, false);
577       pp_string (buffer, ")");
578       break;
579
580     case STRING_CST:
581       pp_string (buffer, "\"");
582       pretty_print_string (buffer, TREE_STRING_POINTER (node));
583       pp_string (buffer, "\"");
584       break;
585
586     case VECTOR_CST:
587       {
588         tree elt;
589         pp_string (buffer, "{ ");
590         for (elt = TREE_VECTOR_CST_ELTS (node); elt; elt = TREE_CHAIN (elt))
591           {
592             dump_generic_node (buffer, TREE_VALUE (elt), spc, flags, false);
593             if (TREE_CHAIN (elt))
594               pp_string (buffer, ", ");
595           }
596         pp_string (buffer, " }");
597       }
598       break;
599
600     case FUNCTION_TYPE:
601       break;
602
603     case FUNCTION_DECL:
604     case CONST_DECL:
605       dump_decl_name (buffer, node, flags);
606       break;
607
608     case LABEL_DECL:
609       if (DECL_NAME (node))
610         dump_decl_name (buffer, node, flags);
611       else if (LABEL_DECL_UID (node) != -1)
612         pp_printf (buffer, "<L" HOST_WIDE_INT_PRINT_DEC ">",
613                    LABEL_DECL_UID (node));
614       else
615         pp_printf (buffer, "<D%u>", DECL_UID (node));
616       break;
617
618     case TYPE_DECL:
619       if (DECL_IS_BUILTIN (node))
620         {
621           /* Don't print the declaration of built-in types.  */
622           break;
623         }
624       if (DECL_NAME (node))
625         dump_decl_name (buffer, node, flags);
626       else
627         {
628           if ((TREE_CODE (TREE_TYPE (node)) == RECORD_TYPE
629                || TREE_CODE (TREE_TYPE (node)) == UNION_TYPE)
630               && TYPE_METHODS (TREE_TYPE (node)))
631             {
632               /* The type is a c++ class: all structures have at least
633                  4 methods.  */
634               pp_string (buffer, "class ");
635               dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
636             }
637           else
638             {
639               pp_string (buffer,
640                          (TREE_CODE (TREE_TYPE (node)) == UNION_TYPE
641                           ? "union" : "struct "));
642               dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
643             }
644         }
645       break;
646
647     case VAR_DECL:
648     case PARM_DECL:
649     case FIELD_DECL:
650     case NAMESPACE_DECL:
651       dump_decl_name (buffer, node, flags);
652       break;
653
654     case RESULT_DECL:
655       pp_string (buffer, "<retval>");
656       break;
657
658     case COMPONENT_REF:
659       op0 = TREE_OPERAND (node, 0);
660       str = ".";
661       if (TREE_CODE (op0) == INDIRECT_REF)
662         {
663           op0 = TREE_OPERAND (op0, 0);
664           str = "->";
665         }
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_string (buffer, str);
672       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
673
674       if (TREE_CODE (op0) != VALUE_HANDLE)
675         {
676           op0 = component_ref_field_offset (node);
677           if (op0 && TREE_CODE (op0) != INTEGER_CST)
678             {
679               pp_string (buffer, "{off: ");
680               dump_generic_node (buffer, op0, spc, flags, false);
681               pp_character (buffer, '}');
682             }
683         }
684       break;
685
686     case BIT_FIELD_REF:
687       pp_string (buffer, "BIT_FIELD_REF <");
688       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
689       pp_string (buffer, ", ");
690       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
691       pp_string (buffer, ", ");
692       dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
693       pp_string (buffer, ">");
694       break;
695
696     case ARRAY_REF:
697     case ARRAY_RANGE_REF:
698       op0 = TREE_OPERAND (node, 0);
699       if (op_prio (op0) < op_prio (node))
700         pp_character (buffer, '(');
701       dump_generic_node (buffer, op0, spc, flags, false);
702       if (op_prio (op0) < op_prio (node))
703         pp_character (buffer, ')');
704       pp_character (buffer, '[');
705       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
706       if (TREE_CODE (node) == ARRAY_RANGE_REF)
707         pp_string (buffer, " ...");
708       pp_character (buffer, ']');
709
710       op0 = array_ref_low_bound (node);
711       op1 = array_ref_element_size (node);
712
713       if (!integer_zerop (op0)
714           || (TYPE_SIZE_UNIT (TREE_TYPE (node))
715               && !operand_equal_p (op1, TYPE_SIZE_UNIT (TREE_TYPE (node)), 0)))
716         {
717           pp_string (buffer, "{lb: ");
718           dump_generic_node (buffer, op0, spc, flags, false);
719           pp_string (buffer, " sz: ");
720           dump_generic_node (buffer, op1, spc, flags, false);
721           pp_character (buffer, '}');
722         }
723       break;
724
725     case CONSTRUCTOR:
726       {
727         tree lnode;
728         bool is_struct_init = FALSE;
729         pp_character (buffer, '{');
730         lnode = CONSTRUCTOR_ELTS (node);
731         if (TREE_CODE (TREE_TYPE (node)) == RECORD_TYPE
732             || TREE_CODE (TREE_TYPE (node)) == UNION_TYPE)
733           is_struct_init = TRUE;
734         while (lnode && lnode != error_mark_node)
735           {
736             tree val;
737             if (TREE_PURPOSE (lnode) && is_struct_init)
738               {
739                 pp_character (buffer, '.');
740                 dump_generic_node (buffer, TREE_PURPOSE (lnode), spc, flags, false);
741                 pp_string (buffer, "=");
742               }
743             val = TREE_VALUE (lnode);
744             if (val && TREE_CODE (val) == ADDR_EXPR)
745               if (TREE_CODE (TREE_OPERAND (val, 0)) == FUNCTION_DECL)
746                 val = TREE_OPERAND (val, 0);
747             if (val && TREE_CODE (val) == FUNCTION_DECL)
748               {
749                 dump_decl_name (buffer, val, flags);
750               }
751             else
752               {
753                 dump_generic_node (buffer, TREE_VALUE (lnode), spc, flags, false);
754               }
755             lnode = TREE_CHAIN (lnode);
756             if (lnode && TREE_CODE (lnode) == TREE_LIST)
757               {
758                 pp_character (buffer, ',');
759                 pp_space (buffer);
760               }
761           }
762         pp_character (buffer, '}');
763       }
764       break;
765
766     case COMPOUND_EXPR:
767       {
768         tree *tp;
769         if (flags & TDF_SLIM)
770           {
771             pp_string (buffer, "<COMPOUND_EXPR>");
772             break;
773           }
774
775         dump_generic_node (buffer, TREE_OPERAND (node, 0),
776                            spc, flags, dumping_stmts);
777         if (dumping_stmts)
778           newline_and_indent (buffer, spc);
779         else
780           {
781             pp_character (buffer, ',');
782             pp_space (buffer);
783           }
784
785         for (tp = &TREE_OPERAND (node, 1);
786              TREE_CODE (*tp) == COMPOUND_EXPR;
787              tp = &TREE_OPERAND (*tp, 1))
788           {
789             dump_generic_node (buffer, TREE_OPERAND (*tp, 0),
790                                spc, flags, dumping_stmts);
791             if (dumping_stmts)
792               newline_and_indent (buffer, spc);
793             else
794               {
795                 pp_character (buffer, ',');
796                 pp_space (buffer);
797               }
798           }
799
800         dump_generic_node (buffer, *tp, spc, flags, dumping_stmts);
801       }
802       break;
803
804     case STATEMENT_LIST:
805       {
806         tree_stmt_iterator si;
807         bool first = true;
808
809         if ((flags & TDF_SLIM) || !dumping_stmts)
810           {
811             pp_string (buffer, "<STATEMENT_LIST>");
812             break;
813           }
814
815         for (si = tsi_start (node); !tsi_end_p (si); tsi_next (&si))
816           {
817             if (!first)
818               newline_and_indent (buffer, spc);
819             else
820               first = false;
821             dump_generic_node (buffer, tsi_stmt (si), spc, flags, true);
822           }
823       }
824       break;
825
826     case MODIFY_EXPR:
827     case INIT_EXPR:
828       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
829       pp_space (buffer);
830       pp_character (buffer, '=');
831       pp_space (buffer);
832       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
833       break;
834
835     case TARGET_EXPR:
836       pp_string (buffer, "TARGET_EXPR <");
837       dump_generic_node (buffer, TARGET_EXPR_SLOT (node), spc, flags, false);
838       pp_character (buffer, ',');
839       pp_space (buffer);
840       dump_generic_node (buffer, TARGET_EXPR_INITIAL (node), spc, flags, false);
841       pp_character (buffer, '>');
842       break;
843
844     case DECL_EXPR:
845       print_declaration (buffer, DECL_EXPR_DECL (node), spc, flags);
846       is_stmt = false;
847       break;
848
849     case COND_EXPR:
850       if (TREE_TYPE (node) == NULL || TREE_TYPE (node) == void_type_node)
851         {
852           pp_string (buffer, "if (");
853           dump_generic_node (buffer, COND_EXPR_COND (node), spc, flags, false);
854           pp_character (buffer, ')');
855           /* The lowered cond_exprs should always be printed in full.  */
856           if (COND_EXPR_THEN (node)
857               && (IS_EMPTY_STMT (COND_EXPR_THEN (node))
858                   || TREE_CODE (COND_EXPR_THEN (node)) == GOTO_EXPR)
859               && COND_EXPR_ELSE (node)
860               && (IS_EMPTY_STMT (COND_EXPR_ELSE (node))
861                   || TREE_CODE (COND_EXPR_ELSE (node)) == GOTO_EXPR))
862             {
863               pp_space (buffer);
864               dump_generic_node (buffer, COND_EXPR_THEN (node), 0, flags, true);
865               pp_string (buffer, " else ");
866               dump_generic_node (buffer, COND_EXPR_ELSE (node), 0, flags, true);
867             }
868           else if (!(flags & TDF_SLIM))
869             {
870               /* Output COND_EXPR_THEN.  */
871               if (COND_EXPR_THEN (node))
872                 {
873                   newline_and_indent (buffer, spc+2);
874                   pp_character (buffer, '{');
875                   newline_and_indent (buffer, spc+4);
876                   dump_generic_node (buffer, COND_EXPR_THEN (node), spc+4,
877                                      flags, true);
878                   newline_and_indent (buffer, spc+2);
879                   pp_character (buffer, '}');
880                 }
881
882               /* Output COND_EXPR_ELSE.  */
883               if (COND_EXPR_ELSE (node))
884                 {
885                   newline_and_indent (buffer, spc);
886                   pp_string (buffer, "else");
887                   newline_and_indent (buffer, spc+2);
888                   pp_character (buffer, '{');
889                   newline_and_indent (buffer, spc+4);
890                   dump_generic_node (buffer, COND_EXPR_ELSE (node), spc+4,
891                                      flags, true);
892                   newline_and_indent (buffer, spc+2);
893                   pp_character (buffer, '}');
894                 }
895             }
896           is_expr = false;
897         }
898       else
899         {
900           dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
901           pp_space (buffer);
902           pp_character (buffer, '?');
903           pp_space (buffer);
904           dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
905           pp_space (buffer);
906           pp_character (buffer, ':');
907           pp_space (buffer);
908           dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
909         }
910       break;
911
912     case BIND_EXPR:
913       pp_character (buffer, '{');
914       if (!(flags & TDF_SLIM))
915         {
916           if (BIND_EXPR_VARS (node))
917             {
918               pp_newline (buffer);
919
920               for (op0 = BIND_EXPR_VARS (node); op0; op0 = TREE_CHAIN (op0))
921                 {
922                   print_declaration (buffer, op0, spc+2, flags);
923                   pp_newline (buffer);
924                 }
925             }
926
927           newline_and_indent (buffer, spc+2);
928           dump_generic_node (buffer, BIND_EXPR_BODY (node), spc+2, flags, true);
929           newline_and_indent (buffer, spc);
930           pp_character (buffer, '}');
931         }
932       is_expr = false;
933       break;
934
935     case CALL_EXPR:
936       print_call_name (buffer, node);
937
938       /* Print parameters.  */
939       pp_space (buffer);
940       pp_character (buffer, '(');
941       op1 = TREE_OPERAND (node, 1);
942       if (op1)
943         dump_generic_node (buffer, op1, spc, flags, false);
944       pp_character (buffer, ')');
945
946       op1 = TREE_OPERAND (node, 2);
947       if (op1)
948         {
949           pp_string (buffer, " [static-chain: ");
950           dump_generic_node (buffer, op1, spc, flags, false);
951           pp_character (buffer, ']');
952         }
953
954       if (CALL_EXPR_HAS_RETURN_SLOT_ADDR (node))
955         pp_string (buffer, " [return slot addr]");
956       if (CALL_EXPR_TAILCALL (node))
957         pp_string (buffer, " [tail call]");
958       break;
959
960     case WITH_CLEANUP_EXPR:
961       NIY;
962       break;
963
964     case CLEANUP_POINT_EXPR:
965       pp_string (buffer, "<<cleanup_point ");
966       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
967       pp_string (buffer, ">>");
968       break;
969
970     case PLACEHOLDER_EXPR:
971       pp_string (buffer, "<PLACEHOLDER_EXPR ");
972       dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
973       pp_character (buffer, '>');
974       break;
975
976       /* Binary arithmetic and logic expressions.  */
977     case MULT_EXPR:
978     case PLUS_EXPR:
979     case MINUS_EXPR:
980     case TRUNC_DIV_EXPR:
981     case CEIL_DIV_EXPR:
982     case FLOOR_DIV_EXPR:
983     case ROUND_DIV_EXPR:
984     case TRUNC_MOD_EXPR:
985     case CEIL_MOD_EXPR:
986     case FLOOR_MOD_EXPR:
987     case ROUND_MOD_EXPR:
988     case RDIV_EXPR:
989     case EXACT_DIV_EXPR:
990     case LSHIFT_EXPR:
991     case RSHIFT_EXPR:
992     case LROTATE_EXPR:
993     case RROTATE_EXPR:
994     case BIT_IOR_EXPR:
995     case BIT_XOR_EXPR:
996     case BIT_AND_EXPR:
997     case TRUTH_ANDIF_EXPR:
998     case TRUTH_ORIF_EXPR:
999     case TRUTH_AND_EXPR:
1000     case TRUTH_OR_EXPR:
1001     case TRUTH_XOR_EXPR:
1002     case LT_EXPR:
1003     case LE_EXPR:
1004     case GT_EXPR:
1005     case GE_EXPR:
1006     case EQ_EXPR:
1007     case NE_EXPR:
1008     case UNLT_EXPR:
1009     case UNLE_EXPR:
1010     case UNGT_EXPR:
1011     case UNGE_EXPR:
1012     case UNEQ_EXPR:
1013     case LTGT_EXPR:
1014     case ORDERED_EXPR:
1015     case UNORDERED_EXPR:
1016       {
1017         const char *op = op_symbol (node);
1018         op0 = TREE_OPERAND (node, 0);
1019         op1 = TREE_OPERAND (node, 1);
1020
1021         /* When the operands are expressions with less priority,
1022            keep semantics of the tree representation.  */
1023         if (op_prio (op0) < op_prio (node))
1024           {
1025             pp_character (buffer, '(');
1026             dump_generic_node (buffer, op0, spc, flags, false);
1027             pp_character (buffer, ')');
1028           }
1029         else
1030           dump_generic_node (buffer, op0, spc, flags, false);
1031
1032         pp_space (buffer);
1033         pp_string (buffer, op);
1034         pp_space (buffer);
1035
1036         /* When the operands are expressions with less priority,
1037            keep semantics of the tree representation.  */
1038         if (op_prio (op1) < op_prio (node))
1039           {
1040             pp_character (buffer, '(');
1041             dump_generic_node (buffer, op1, spc, flags, false);
1042             pp_character (buffer, ')');
1043           }
1044         else
1045           dump_generic_node (buffer, op1, spc, flags, false);
1046       }
1047       break;
1048
1049       /* Unary arithmetic and logic expressions.  */
1050     case NEGATE_EXPR:
1051     case BIT_NOT_EXPR:
1052     case TRUTH_NOT_EXPR:
1053     case ADDR_EXPR:
1054     case PREDECREMENT_EXPR:
1055     case PREINCREMENT_EXPR:
1056     case ALIGN_INDIRECT_REF:
1057     case MISALIGNED_INDIRECT_REF:
1058     case INDIRECT_REF:
1059       if (TREE_CODE (node) == ADDR_EXPR
1060           && (TREE_CODE (TREE_OPERAND (node, 0)) == STRING_CST
1061               || TREE_CODE (TREE_OPERAND (node, 0)) == FUNCTION_DECL))
1062         ;       /* Do not output '&' for strings and function pointers.  */
1063       else
1064         pp_string (buffer, op_symbol (node));
1065
1066       if (op_prio (TREE_OPERAND (node, 0)) < op_prio (node))
1067         {
1068           pp_character (buffer, '(');
1069           dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1070           pp_character (buffer, ')');
1071         }
1072       else
1073         dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1074
1075       if (TREE_CODE (node) == MISALIGNED_INDIRECT_REF)
1076         {
1077           pp_string (buffer, "{misalignment: ");
1078           dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1079           pp_character (buffer, '}');
1080         }
1081       break;
1082
1083     case POSTDECREMENT_EXPR:
1084     case POSTINCREMENT_EXPR:
1085       if (op_prio (TREE_OPERAND (node, 0)) < op_prio (node))
1086         {
1087           pp_character (buffer, '(');
1088           dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1089           pp_character (buffer, ')');
1090         }
1091       else
1092         dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1093       pp_string (buffer, op_symbol (node));
1094       break;
1095
1096     case MIN_EXPR:
1097       pp_string (buffer, "MIN_EXPR <");
1098       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1099       pp_string (buffer, ", ");
1100       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1101       pp_character (buffer, '>');
1102       break;
1103
1104     case MAX_EXPR:
1105       pp_string (buffer, "MAX_EXPR <");
1106       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1107       pp_string (buffer, ", ");
1108       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1109       pp_character (buffer, '>');
1110       break;
1111
1112     case ABS_EXPR:
1113       pp_string (buffer, "ABS_EXPR <");
1114       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1115       pp_character (buffer, '>');
1116       break;
1117
1118     case RANGE_EXPR:
1119       NIY;
1120       break;
1121
1122     case FIX_TRUNC_EXPR:
1123     case FIX_CEIL_EXPR:
1124     case FIX_FLOOR_EXPR:
1125     case FIX_ROUND_EXPR:
1126     case FLOAT_EXPR:
1127     case CONVERT_EXPR:
1128     case NOP_EXPR:
1129       type = TREE_TYPE (node);
1130       op0 = TREE_OPERAND (node, 0);
1131       if (type != TREE_TYPE (op0))
1132         {
1133           pp_character (buffer, '(');
1134           dump_generic_node (buffer, type, spc, flags, false);
1135           pp_string (buffer, ") ");
1136         }
1137       if (op_prio (op0) < op_prio (node))
1138         pp_character (buffer, '(');
1139       dump_generic_node (buffer, op0, spc, flags, false);
1140       if (op_prio (op0) < op_prio (node))
1141         pp_character (buffer, ')');
1142       break;
1143
1144     case VIEW_CONVERT_EXPR:
1145       pp_string (buffer, "VIEW_CONVERT_EXPR<");
1146       dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
1147       pp_string (buffer, ">(");
1148       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1149       pp_character (buffer, ')');
1150       break;
1151
1152     case NON_LVALUE_EXPR:
1153       pp_string (buffer, "NON_LVALUE_EXPR <");
1154       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1155       pp_character (buffer, '>');
1156       break;
1157
1158     case SAVE_EXPR:
1159       pp_string (buffer, "SAVE_EXPR <");
1160       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1161       pp_character (buffer, '>');
1162       break;
1163
1164     case COMPLEX_EXPR:
1165       pp_string (buffer, "COMPLEX_EXPR <");
1166       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1167       pp_string (buffer, ", ");
1168       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1169       pp_string (buffer, ">");
1170       break;
1171
1172     case CONJ_EXPR:
1173       pp_string (buffer, "CONJ_EXPR <");
1174       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1175       pp_string (buffer, ">");
1176       break;
1177
1178     case REALPART_EXPR:
1179       pp_string (buffer, "REALPART_EXPR <");
1180       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1181       pp_string (buffer, ">");
1182       break;
1183
1184     case IMAGPART_EXPR:
1185       pp_string (buffer, "IMAGPART_EXPR <");
1186       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1187       pp_string (buffer, ">");
1188       break;
1189
1190     case VA_ARG_EXPR:
1191       pp_string (buffer, "VA_ARG_EXPR <");
1192       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1193       pp_string (buffer, ">");
1194       break;
1195
1196     case TRY_FINALLY_EXPR:
1197     case TRY_CATCH_EXPR:
1198       pp_string (buffer, "try");
1199       newline_and_indent (buffer, spc+2);
1200       pp_string (buffer, "{");
1201       newline_and_indent (buffer, spc+4);
1202       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc+4, flags, true);
1203       newline_and_indent (buffer, spc+2);
1204       pp_string (buffer, "}");
1205       newline_and_indent (buffer, spc);
1206       pp_string (buffer,
1207                          (TREE_CODE (node) == TRY_CATCH_EXPR) ? "catch" : "finally");
1208       newline_and_indent (buffer, spc+2);
1209       pp_string (buffer, "{");
1210       newline_and_indent (buffer, spc+4);
1211       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc+4, flags, true);
1212       newline_and_indent (buffer, spc+2);
1213       pp_string (buffer, "}");
1214       is_expr = false;
1215       break;
1216
1217     case CATCH_EXPR:
1218       pp_string (buffer, "catch (");
1219       dump_generic_node (buffer, CATCH_TYPES (node), spc+2, flags, false);
1220       pp_string (buffer, ")");
1221       newline_and_indent (buffer, spc+2);
1222       pp_string (buffer, "{");
1223       newline_and_indent (buffer, spc+4);
1224       dump_generic_node (buffer, CATCH_BODY (node), spc+4, flags, true);
1225       newline_and_indent (buffer, spc+2);
1226       pp_string (buffer, "}");
1227       is_expr = false;
1228       break;
1229
1230     case EH_FILTER_EXPR:
1231       pp_string (buffer, "<<<eh_filter (");
1232       dump_generic_node (buffer, EH_FILTER_TYPES (node), spc+2, flags, false);
1233       pp_string (buffer, ")>>>");
1234       newline_and_indent (buffer, spc+2);
1235       pp_string (buffer, "{");
1236       newline_and_indent (buffer, spc+4);
1237       dump_generic_node (buffer, EH_FILTER_FAILURE (node), spc+4, flags, true);
1238       newline_and_indent (buffer, spc+2);
1239       pp_string (buffer, "}");
1240       is_expr = false;
1241       break;
1242
1243     case LABEL_EXPR:
1244       op0 = TREE_OPERAND (node, 0);
1245       /* If this is for break or continue, don't bother printing it.  */
1246       if (DECL_NAME (op0))
1247         {
1248           const char *name = IDENTIFIER_POINTER (DECL_NAME (op0));
1249           if (strcmp (name, "break") == 0
1250               || strcmp (name, "continue") == 0)
1251             break;
1252         }
1253       dump_generic_node (buffer, op0, spc, flags, false);
1254       pp_character (buffer, ':');
1255       if (DECL_NONLOCAL (op0))
1256         pp_string (buffer, " [non-local]");
1257       break;
1258
1259     case EXC_PTR_EXPR:
1260       pp_string (buffer, "<<<exception object>>>");
1261       break;
1262
1263     case FILTER_EXPR:
1264       pp_string (buffer, "<<<filter object>>>");
1265       break;
1266
1267     case LOOP_EXPR:
1268       pp_string (buffer, "while (1)");
1269       if (!(flags & TDF_SLIM))
1270         {
1271           newline_and_indent (buffer, spc+2);
1272           pp_character (buffer, '{');
1273           newline_and_indent (buffer, spc+4);
1274           dump_generic_node (buffer, LOOP_EXPR_BODY (node), spc+4, flags, true);
1275           newline_and_indent (buffer, spc+2);
1276           pp_character (buffer, '}');
1277         }
1278       is_expr = false;
1279       break;
1280
1281     case RETURN_EXPR:
1282       pp_string (buffer, "return");
1283       op0 = TREE_OPERAND (node, 0);
1284       if (op0)
1285         {
1286           pp_space (buffer);
1287           if (TREE_CODE (op0) == MODIFY_EXPR)
1288             dump_generic_node (buffer, TREE_OPERAND (op0, 1), spc, flags, false);
1289           else
1290             dump_generic_node (buffer, op0, spc, flags, false);
1291         }
1292       break;
1293
1294     case EXIT_EXPR:
1295       pp_string (buffer, "if (");
1296       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1297       pp_string (buffer, ") break");
1298       break;
1299
1300     case SWITCH_EXPR:
1301       pp_string (buffer, "switch (");
1302       dump_generic_node (buffer, SWITCH_COND (node), spc, flags, false);
1303       pp_character (buffer, ')');
1304       if (!(flags & TDF_SLIM))
1305         {
1306           newline_and_indent (buffer, spc+2);
1307           pp_character (buffer, '{');
1308           if (SWITCH_BODY (node))
1309             {
1310               newline_and_indent (buffer, spc+4);
1311               dump_generic_node (buffer, SWITCH_BODY (node), spc+4, flags, true);
1312             }
1313           else
1314             {
1315               tree vec = SWITCH_LABELS (node);
1316               size_t i, n = TREE_VEC_LENGTH (vec);
1317               for (i = 0; i < n; ++i)
1318                 {
1319                   tree elt = TREE_VEC_ELT (vec, i);
1320                   newline_and_indent (buffer, spc+4);
1321                   dump_generic_node (buffer, elt, spc+4, flags, false);
1322                   pp_string (buffer, " goto ");
1323                   dump_generic_node (buffer, CASE_LABEL (elt), spc+4, flags, true);
1324                   pp_semicolon (buffer);
1325                 }
1326             }
1327           newline_and_indent (buffer, spc+2);
1328           pp_character (buffer, '}');
1329         }
1330       is_expr = false;
1331       break;
1332
1333     case GOTO_EXPR:
1334       op0 = GOTO_DESTINATION (node);
1335       if (TREE_CODE (op0) != SSA_NAME && DECL_P (op0) && DECL_NAME (op0))
1336         {
1337           const char *name = IDENTIFIER_POINTER (DECL_NAME (op0));
1338           if (strcmp (name, "break") == 0
1339               || strcmp (name, "continue") == 0)
1340             {
1341               pp_string (buffer, name);
1342               break;
1343             }
1344         }
1345       pp_string (buffer, "goto ");
1346       dump_generic_node (buffer, op0, spc, flags, false);
1347       break;
1348
1349     case RESX_EXPR:
1350       pp_string (buffer, "resx");
1351       /* ??? Any sensible way to present the eh region?  */
1352       break;
1353
1354     case ASM_EXPR:
1355       pp_string (buffer, "__asm__");
1356       if (ASM_VOLATILE_P (node))
1357         pp_string (buffer, " __volatile__");
1358       pp_character (buffer, '(');
1359       dump_generic_node (buffer, ASM_STRING (node), spc, flags, false);
1360       pp_character (buffer, ':');
1361       dump_generic_node (buffer, ASM_OUTPUTS (node), spc, flags, false);
1362       pp_character (buffer, ':');
1363       dump_generic_node (buffer, ASM_INPUTS (node), spc, flags, false);
1364       if (ASM_CLOBBERS (node))
1365         {
1366           pp_character (buffer, ':');
1367           dump_generic_node (buffer, ASM_CLOBBERS (node), spc, flags, false);
1368         }
1369       pp_string (buffer, ")");
1370       break;
1371
1372     case CASE_LABEL_EXPR:
1373       if (CASE_LOW (node) && CASE_HIGH (node))
1374         {
1375           pp_string (buffer, "case ");
1376           dump_generic_node (buffer, CASE_LOW (node), spc, flags, false);
1377           pp_string (buffer, " ... ");
1378           dump_generic_node (buffer, CASE_HIGH (node), spc, flags, false);
1379         }
1380       else if (CASE_LOW (node))
1381         {
1382           pp_string (buffer, "case ");
1383           dump_generic_node (buffer, CASE_LOW (node), spc, flags, false);
1384         }
1385       else
1386         pp_string (buffer, "default ");
1387       pp_character (buffer, ':');
1388       break;
1389
1390     case OBJ_TYPE_REF:
1391       pp_string (buffer, "OBJ_TYPE_REF(");
1392       dump_generic_node (buffer, OBJ_TYPE_REF_EXPR (node), spc, flags, false);
1393       pp_character (buffer, ';');
1394       dump_generic_node (buffer, OBJ_TYPE_REF_OBJECT (node), spc, flags, false);
1395       pp_character (buffer, '-');
1396       pp_character (buffer, '>');
1397       dump_generic_node (buffer, OBJ_TYPE_REF_TOKEN (node), spc, flags, false);
1398       pp_character (buffer, ')');
1399       break;
1400
1401     case PHI_NODE:
1402       {
1403         int i;
1404
1405         dump_generic_node (buffer, PHI_RESULT (node), spc, flags, false);
1406         pp_string (buffer, " = PHI <");
1407         for (i = 0; i < PHI_NUM_ARGS (node); i++)
1408           {
1409             dump_generic_node (buffer, PHI_ARG_DEF (node, i), spc, flags, false);
1410             pp_string (buffer, "(");
1411             pp_decimal_int (buffer, PHI_ARG_EDGE (node, i)->src->index);
1412             pp_string (buffer, ")");
1413             if (i < PHI_NUM_ARGS (node) - 1)
1414               pp_string (buffer, ", ");
1415           }
1416         pp_string (buffer, ">;");
1417       }
1418       break;
1419
1420     case SSA_NAME:
1421       dump_generic_node (buffer, SSA_NAME_VAR (node), spc, flags, false);
1422       pp_string (buffer, "_");
1423       pp_decimal_int (buffer, SSA_NAME_VERSION (node));
1424       break;
1425
1426     case WITH_SIZE_EXPR:
1427       pp_string (buffer, "WITH_SIZE_EXPR <");
1428       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1429       pp_string (buffer, ", ");
1430       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1431       pp_string (buffer, ">");
1432       break;
1433
1434     case VALUE_HANDLE:
1435       pp_printf (buffer, "VH.%d", VALUE_HANDLE_ID (node));
1436       break;
1437
1438     case SCEV_KNOWN:
1439       pp_string (buffer, "scev_known");
1440       break;
1441
1442     case SCEV_NOT_KNOWN:
1443       pp_string (buffer, "scev_not_known");
1444       break;
1445
1446     case POLYNOMIAL_CHREC:
1447       pp_string (buffer, "{");
1448       dump_generic_node (buffer, CHREC_LEFT (node), spc, flags, false);
1449       pp_string (buffer, ", +, ");
1450       dump_generic_node (buffer, CHREC_RIGHT (node), spc, flags, false);
1451       pp_string (buffer, "}_");
1452       dump_generic_node (buffer, CHREC_VAR (node), spc, flags, false);
1453       is_stmt = false;
1454       break;
1455
1456     case REALIGN_LOAD_EXPR:
1457       pp_string (buffer, "REALIGN_LOAD <");
1458       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1459       pp_string (buffer, ", ");
1460       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1461       pp_string (buffer, ", ");
1462       dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
1463       pp_string (buffer, ">");
1464       break;
1465       
1466     case VEC_COND_EXPR:
1467       pp_string (buffer, " VEC_COND_EXPR < ");
1468       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1469       pp_string (buffer, " , ");
1470       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1471       pp_string (buffer, " , ");
1472       dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
1473       pp_string (buffer, " > ");
1474       break;
1475
1476     default:
1477       NIY;
1478     }
1479
1480   if (is_stmt && is_expr)
1481     pp_semicolon (buffer);
1482   pp_write_text_to_stream (buffer);
1483
1484   return spc;
1485 }
1486
1487 /* Print the declaration of a variable.  */
1488
1489 static void
1490 print_declaration (pretty_printer *buffer, tree t, int spc, int flags)
1491 {
1492   INDENT (spc);
1493
1494   if (TREE_CODE (t) == TYPE_DECL)
1495     pp_string (buffer, "typedef ");
1496
1497   if (DECL_REGISTER (t))
1498     pp_string (buffer, "register ");
1499
1500   if (TREE_PUBLIC (t) && DECL_EXTERNAL (t))
1501     pp_string (buffer, "extern ");
1502   else if (TREE_STATIC (t))
1503     pp_string (buffer, "static ");
1504
1505   /* Print the type and name.  */
1506   if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
1507     {
1508       tree tmp;
1509
1510       /* Print array's type.  */
1511       tmp = TREE_TYPE (t);
1512       while (TREE_CODE (TREE_TYPE (tmp)) == ARRAY_TYPE)
1513         tmp = TREE_TYPE (tmp);
1514       dump_generic_node (buffer, TREE_TYPE (tmp), spc, flags, false);
1515
1516       /* Print variable's name.  */
1517       pp_space (buffer);
1518       dump_generic_node (buffer, t, spc, flags, false);
1519
1520       /* Print the dimensions.  */
1521       tmp = TREE_TYPE (t);
1522       while (TREE_CODE (tmp) == ARRAY_TYPE)
1523         {
1524           dump_array_domain (buffer, TYPE_DOMAIN (tmp), spc, flags);
1525           tmp = TREE_TYPE (tmp);
1526         }
1527     }
1528   else if (TREE_CODE (t) == FUNCTION_DECL)
1529     {
1530       dump_generic_node (buffer, TREE_TYPE (TREE_TYPE (t)), spc, flags, false);
1531       pp_space (buffer);
1532       dump_decl_name (buffer, t, flags);
1533       dump_function_declaration (buffer, TREE_TYPE (t), spc, flags);
1534     }
1535   else
1536     {
1537       /* Print type declaration.  */
1538       dump_generic_node (buffer, TREE_TYPE (t), spc, flags, false);
1539
1540       /* Print variable's name.  */
1541       pp_space (buffer);
1542       dump_generic_node (buffer, t, spc, flags, false);
1543     }
1544
1545   if (TREE_CODE (t) == VAR_DECL && DECL_HARD_REGISTER (t))
1546     {
1547       pp_string (buffer, " __asm__ ");
1548       pp_character (buffer, '(');
1549       dump_generic_node (buffer, DECL_ASSEMBLER_NAME (t), spc, flags, false);
1550       pp_character (buffer, ')');
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;
2091   use_operand_p use_p;
2092   def_operand_p def_p;
2093   use_operand_p kill_p;
2094   ssa_op_iter iter;
2095
2096   FOR_EACH_SSA_MAYDEF_OPERAND (def_p, use_p, stmt, iter)
2097     {
2098       pp_string (buffer, "#   ");
2099       dump_generic_node (buffer, DEF_FROM_PTR (def_p),
2100                          spc + 2, flags, false);
2101       pp_string (buffer, " = V_MAY_DEF <");
2102       dump_generic_node (buffer, USE_FROM_PTR (use_p),
2103                          spc + 2, flags, false);
2104       pp_string (buffer, ">;");
2105       newline_and_indent (buffer, spc);
2106     }
2107
2108   FOR_EACH_SSA_MUSTDEF_OPERAND (def_p, kill_p, stmt, iter)
2109     {
2110       pp_string (buffer, "#   ");
2111       dump_generic_node (buffer, DEF_FROM_PTR (def_p),
2112                          spc + 2, flags, false);
2113       pp_string (buffer, " = V_MUST_DEF <");
2114       dump_generic_node (buffer, USE_FROM_PTR (kill_p),
2115                          spc + 2, flags, false);
2116       pp_string (buffer, ">;");
2117       newline_and_indent (buffer, spc);
2118     }
2119
2120   FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_VUSE)
2121     {
2122       pp_string (buffer, "#   VUSE <");
2123       dump_generic_node (buffer, use, spc + 2, flags, false);
2124       pp_string (buffer, ">;");
2125       newline_and_indent (buffer, spc);
2126     }
2127 }
2128
2129 /* Dumps basic block BB to FILE with details described by FLAGS and
2130    indented by INDENT spaces.  */
2131
2132 void
2133 dump_generic_bb (FILE *file, basic_block bb, int indent, int flags)
2134 {
2135   maybe_init_pretty_print (file);
2136   dumping_stmts = true;
2137   dump_generic_bb_buff (&buffer, bb, indent, flags);
2138   pp_flush (&buffer);
2139 }
2140
2141 /* Dumps header of basic block BB to buffer BUFFER indented by INDENT
2142    spaces and details described by flags.  */
2143
2144 static void
2145 dump_bb_header (pretty_printer *buffer, basic_block bb, int indent, int flags)
2146 {
2147   edge e;
2148   tree stmt;
2149   edge_iterator ei;
2150
2151   if (flags & TDF_BLOCKS)
2152     {
2153       INDENT (indent);
2154       pp_string (buffer, "# BLOCK ");
2155       pp_decimal_int (buffer, bb->index);
2156
2157       if (flags & TDF_LINENO)
2158         {
2159           block_stmt_iterator bsi;
2160
2161           for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
2162             if (get_lineno (bsi_stmt (bsi)) != -1)
2163               {
2164                 pp_string (buffer, ", starting at line ");
2165                 pp_decimal_int (buffer, get_lineno (bsi_stmt (bsi)));
2166                 break;
2167               }
2168         }
2169       newline_and_indent (buffer, indent);
2170
2171       pp_string (buffer, "# PRED:");
2172       pp_write_text_to_stream (buffer);
2173       FOR_EACH_EDGE (e, ei, bb->preds)
2174         if (flags & TDF_SLIM)
2175           {
2176             pp_string (buffer, " ");
2177             if (e->src == ENTRY_BLOCK_PTR)
2178               pp_string (buffer, "ENTRY");
2179             else
2180               pp_decimal_int (buffer, e->src->index);
2181           }
2182         else
2183           dump_edge_info (buffer->buffer->stream, e, 0);
2184       pp_newline (buffer);
2185     }
2186   else
2187     {
2188       stmt = first_stmt (bb);
2189       if (!stmt || TREE_CODE (stmt) != LABEL_EXPR)
2190         {
2191           INDENT (indent - 2);
2192           pp_string (buffer, "<bb ");
2193           pp_decimal_int (buffer, bb->index);
2194           pp_string (buffer, ">:");
2195           pp_newline (buffer);
2196         }
2197     }
2198   pp_write_text_to_stream (buffer);
2199   check_bb_profile (bb, buffer->buffer->stream);
2200 }
2201
2202 /* Dumps end of basic block BB to buffer BUFFER indented by INDENT
2203    spaces.  */
2204
2205 static void
2206 dump_bb_end (pretty_printer *buffer, basic_block bb, int indent, int flags)
2207 {
2208   edge e;
2209   edge_iterator ei;
2210
2211   INDENT (indent);
2212   pp_string (buffer, "# SUCC:");
2213   pp_write_text_to_stream (buffer);
2214   FOR_EACH_EDGE (e, ei, bb->succs)
2215     if (flags & TDF_SLIM)
2216       {
2217         pp_string (buffer, " ");
2218         if (e->dest == EXIT_BLOCK_PTR)
2219           pp_string (buffer, "EXIT");
2220         else
2221           pp_decimal_int (buffer, e->dest->index);
2222       }
2223     else
2224       dump_edge_info (buffer->buffer->stream, e, 1);
2225   pp_newline (buffer);
2226 }
2227
2228 /* Dumps phi nodes of basic block BB to buffer BUFFER with details described by
2229    FLAGS indented by INDENT spaces.  */
2230
2231 static void
2232 dump_phi_nodes (pretty_printer *buffer, basic_block bb, int indent, int flags)
2233 {
2234   tree phi = phi_nodes (bb);
2235   if (!phi)
2236     return;
2237
2238   for (; phi; phi = PHI_CHAIN (phi))
2239     {
2240       if (is_gimple_reg (PHI_RESULT (phi)) || (flags & TDF_VOPS))
2241         {
2242           INDENT (indent);
2243           pp_string (buffer, "# ");
2244           dump_generic_node (buffer, phi, indent, flags, false);
2245           pp_newline (buffer);
2246         }
2247     }
2248 }
2249
2250 /* Dump jump to basic block BB that is represented implicitly in the cfg
2251    to BUFFER.  */
2252
2253 static void
2254 pp_cfg_jump (pretty_printer *buffer, basic_block bb)
2255 {
2256   tree stmt;
2257
2258   stmt = first_stmt (bb);
2259
2260   pp_string (buffer, "goto <bb ");
2261   pp_decimal_int (buffer, bb->index);
2262   pp_string (buffer, ">");
2263   if (stmt && TREE_CODE (stmt) == LABEL_EXPR)
2264     {
2265       pp_string (buffer, " (");
2266       dump_generic_node (buffer, LABEL_EXPR_LABEL (stmt), 0, 0, false);
2267       pp_string (buffer, ")");
2268     }
2269   pp_semicolon (buffer);
2270 }
2271
2272 /* Dump edges represented implicitly in basic block BB to BUFFER, indented
2273    by INDENT spaces, with details given by FLAGS.  */
2274
2275 static void
2276 dump_implicit_edges (pretty_printer *buffer, basic_block bb, int indent,
2277                      int flags)
2278 {
2279   edge e;
2280   edge_iterator ei;
2281
2282   /* If there is a fallthru edge, we may need to add an artificial goto to the
2283      dump.  */
2284   FOR_EACH_EDGE (e, ei, bb->succs)
2285     if (e->flags & EDGE_FALLTHRU)
2286       break;
2287   if (e && e->dest != bb->next_bb)
2288     {
2289       INDENT (indent);
2290
2291       if ((flags & TDF_LINENO)
2292 #ifdef USE_MAPPED_LOCATION
2293           && e->goto_locus != UNKNOWN_LOCATION
2294 #else
2295           && e->goto_locus
2296 #endif
2297           )
2298         {
2299           expanded_location goto_xloc;
2300 #ifdef USE_MAPPED_LOCATION
2301           goto_xloc = expand_location (e->goto_locus);
2302 #else
2303           goto_xloc = *e->goto_locus;
2304 #endif
2305           pp_character (buffer, '[');
2306           if (goto_xloc.file)
2307             {
2308               pp_string (buffer, goto_xloc.file);
2309               pp_string (buffer, " : ");
2310             }
2311           pp_decimal_int (buffer, goto_xloc.line);
2312           pp_string (buffer, "] ");
2313         }
2314
2315       pp_cfg_jump (buffer, e->dest);
2316       pp_newline (buffer);
2317     }
2318 }
2319
2320 /* Dumps basic block BB to buffer BUFFER with details described by FLAGS and
2321    indented by INDENT spaces.  */
2322
2323 static void
2324 dump_generic_bb_buff (pretty_printer *buffer, basic_block bb,
2325                       int indent, int flags)
2326 {
2327   block_stmt_iterator bsi;
2328   tree stmt;
2329   int label_indent = indent - 2;
2330
2331   if (label_indent < 0)
2332     label_indent = 0;
2333
2334   dump_bb_header (buffer, bb, indent, flags);
2335
2336   if (bb_ann (bb))
2337     dump_phi_nodes (buffer, bb, indent, flags);
2338
2339   for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
2340     {
2341       int curr_indent;
2342
2343       stmt = bsi_stmt (bsi);
2344
2345       curr_indent = TREE_CODE (stmt) == LABEL_EXPR ? label_indent : indent;
2346
2347       INDENT (curr_indent);
2348       dump_generic_node (buffer, stmt, curr_indent, flags, true);
2349       pp_newline (buffer);
2350     }
2351
2352   dump_implicit_edges (buffer, bb, indent, flags);
2353
2354   if (flags & TDF_BLOCKS)
2355     dump_bb_end (buffer, bb, indent, flags);
2356 }