OSDN Git Service

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