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