OSDN Git Service

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