OSDN Git Service

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