OSDN Git Service

* tree-pretty-print.c (dump_generic_node): Dump
[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_HAS_RETURN_SLOT_ADDR (node))
902         pp_string (buffer, " [return slot addr]");
903       if (CALL_EXPR_TAILCALL (node))
904         pp_string (buffer, " [tail call]");
905       break;
906
907     case WITH_CLEANUP_EXPR:
908       NIY;
909       break;
910
911     case CLEANUP_POINT_EXPR:
912       pp_string (buffer, "<<cleanup_point ");
913       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
914       pp_string (buffer, ">>");
915       break;
916
917     case PLACEHOLDER_EXPR:
918       pp_string (buffer, "<PLACEHOLDER_EXPR ");
919       dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
920       pp_character (buffer, '>');
921       break;
922
923       /* Binary arithmetic and logic expressions.  */
924     case MULT_EXPR:
925     case PLUS_EXPR:
926     case MINUS_EXPR:
927     case TRUNC_DIV_EXPR:
928     case CEIL_DIV_EXPR:
929     case FLOOR_DIV_EXPR:
930     case ROUND_DIV_EXPR:
931     case TRUNC_MOD_EXPR:
932     case CEIL_MOD_EXPR:
933     case FLOOR_MOD_EXPR:
934     case ROUND_MOD_EXPR:
935     case RDIV_EXPR:
936     case EXACT_DIV_EXPR:
937     case LSHIFT_EXPR:
938     case RSHIFT_EXPR:
939     case LROTATE_EXPR:
940     case RROTATE_EXPR:
941     case BIT_IOR_EXPR:
942     case BIT_XOR_EXPR:
943     case BIT_AND_EXPR:
944     case TRUTH_ANDIF_EXPR:
945     case TRUTH_ORIF_EXPR:
946     case TRUTH_AND_EXPR:
947     case TRUTH_OR_EXPR:
948     case TRUTH_XOR_EXPR:
949     case LT_EXPR:
950     case LE_EXPR:
951     case GT_EXPR:
952     case GE_EXPR:
953     case EQ_EXPR:
954     case NE_EXPR:
955     case UNLT_EXPR:
956     case UNLE_EXPR:
957     case UNGT_EXPR:
958     case UNGE_EXPR:
959     case UNEQ_EXPR:
960     case LTGT_EXPR:
961     case ORDERED_EXPR:
962     case UNORDERED_EXPR:
963       {
964         const char *op = op_symbol (node);
965         op0 = TREE_OPERAND (node, 0);
966         op1 = TREE_OPERAND (node, 1);
967
968         /* When the operands are expressions with less priority,
969            keep semantics of the tree representation.  */
970         if (op_prio (op0) < op_prio (node))
971           {
972             pp_character (buffer, '(');
973             dump_generic_node (buffer, op0, spc, flags, false);
974             pp_character (buffer, ')');
975           }
976         else
977           dump_generic_node (buffer, op0, spc, flags, false);
978
979         pp_space (buffer);
980         pp_string (buffer, op);
981         pp_space (buffer);
982
983         /* When the operands are expressions with less priority,
984            keep semantics of the tree representation.  */
985         if (op_prio (op1) < op_prio (node))
986           {
987             pp_character (buffer, '(');
988             dump_generic_node (buffer, op1, spc, flags, false);
989             pp_character (buffer, ')');
990           }
991         else
992           dump_generic_node (buffer, op1, spc, flags, false);
993       }
994       break;
995
996       /* Unary arithmetic and logic expressions.  */
997     case NEGATE_EXPR:
998     case BIT_NOT_EXPR:
999     case TRUTH_NOT_EXPR:
1000     case ADDR_EXPR:
1001     case PREDECREMENT_EXPR:
1002     case PREINCREMENT_EXPR:
1003     case INDIRECT_REF:
1004       if (TREE_CODE (node) == ADDR_EXPR
1005           && (TREE_CODE (TREE_OPERAND (node, 0)) == STRING_CST
1006               || TREE_CODE (TREE_OPERAND (node, 0)) == FUNCTION_DECL))
1007         ;       /* Do not output '&' for strings and function pointers.  */
1008       else
1009         pp_string (buffer, op_symbol (node));
1010
1011       if (op_prio (TREE_OPERAND (node, 0)) < op_prio (node))
1012         {
1013           pp_character (buffer, '(');
1014           dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1015           pp_character (buffer, ')');
1016         }
1017       else
1018         dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1019       break;
1020
1021     case POSTDECREMENT_EXPR:
1022     case POSTINCREMENT_EXPR:
1023       if (op_prio (TREE_OPERAND (node, 0)) < op_prio (node))
1024         {
1025           pp_character (buffer, '(');
1026           dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1027           pp_character (buffer, ')');
1028         }
1029       else
1030         dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1031       pp_string (buffer, op_symbol (node));
1032       break;
1033
1034     case MIN_EXPR:
1035       pp_string (buffer, "MIN_EXPR <");
1036       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1037       pp_string (buffer, ", ");
1038       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1039       pp_character (buffer, '>');
1040       break;
1041
1042     case MAX_EXPR:
1043       pp_string (buffer, "MAX_EXPR <");
1044       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1045       pp_string (buffer, ", ");
1046       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1047       pp_character (buffer, '>');
1048       break;
1049
1050     case ABS_EXPR:
1051       pp_string (buffer, "ABS_EXPR <");
1052       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1053       pp_character (buffer, '>');
1054       break;
1055
1056     case RANGE_EXPR:
1057       NIY;
1058       break;
1059
1060     case FIX_TRUNC_EXPR:
1061     case FIX_CEIL_EXPR:
1062     case FIX_FLOOR_EXPR:
1063     case FIX_ROUND_EXPR:
1064     case FLOAT_EXPR:
1065     case CONVERT_EXPR:
1066     case NOP_EXPR:
1067       type = TREE_TYPE (node);
1068       op0 = TREE_OPERAND (node, 0);
1069       if (type != TREE_TYPE (op0))
1070         {
1071           pp_character (buffer, '(');
1072           dump_generic_node (buffer, type, spc, flags, false);
1073           pp_string (buffer, ")");
1074         }
1075       if (op_prio (op0) < op_prio (node))
1076         pp_character (buffer, '(');
1077       dump_generic_node (buffer, op0, spc, flags, false);
1078       if (op_prio (op0) < op_prio (node))
1079         pp_character (buffer, ')');
1080       break;
1081
1082     case VIEW_CONVERT_EXPR:
1083       pp_string (buffer, "VIEW_CONVERT_EXPR<");
1084       dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
1085       pp_string (buffer, ">(");
1086       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1087       pp_character (buffer, ')');
1088       break;
1089
1090     case NON_LVALUE_EXPR:
1091       pp_string (buffer, "NON_LVALUE_EXPR <");
1092       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1093       pp_character (buffer, '>');
1094       break;
1095
1096     case SAVE_EXPR:
1097       pp_string (buffer, "SAVE_EXPR <");
1098       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1099       pp_character (buffer, '>');
1100       break;
1101
1102     case UNSAVE_EXPR:
1103       pp_string (buffer, "UNSAVE_EXPR <");
1104       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1105       pp_character (buffer, '>');
1106       break;
1107
1108     case ENTRY_VALUE_EXPR:
1109       NIY;
1110       break;
1111
1112     case COMPLEX_EXPR:
1113       pp_string (buffer, "COMPLEX_EXPR <");
1114       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1115       pp_string (buffer, ", ");
1116       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1117       pp_string (buffer, ">");
1118       break;
1119
1120     case CONJ_EXPR:
1121       pp_string (buffer, "CONJ_EXPR <");
1122       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1123       pp_string (buffer, ">");
1124       break;
1125
1126     case REALPART_EXPR:
1127       pp_string (buffer, "REALPART_EXPR <");
1128       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1129       pp_string (buffer, ">");
1130       break;
1131
1132     case IMAGPART_EXPR:
1133       pp_string (buffer, "IMAGPART_EXPR <");
1134       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1135       pp_string (buffer, ">");
1136       break;
1137
1138     case VA_ARG_EXPR:
1139       pp_string (buffer, "VA_ARG_EXPR <");
1140       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1141       pp_string (buffer, ">");
1142       break;
1143
1144     case TRY_FINALLY_EXPR:
1145     case TRY_CATCH_EXPR:
1146       pp_string (buffer, "try");
1147       newline_and_indent (buffer, spc+2);
1148       pp_string (buffer, "{");
1149       newline_and_indent (buffer, spc+4);
1150       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc+4, flags, true);
1151       newline_and_indent (buffer, spc+2);
1152       pp_string (buffer, "}");
1153       newline_and_indent (buffer, spc);
1154       pp_string (buffer,
1155                          (TREE_CODE (node) == TRY_CATCH_EXPR) ? "catch" : "finally");
1156       newline_and_indent (buffer, spc+2);
1157       pp_string (buffer, "{");
1158       newline_and_indent (buffer, spc+4);
1159       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc+4, flags, true);
1160       newline_and_indent (buffer, spc+2);
1161       pp_string (buffer, "}");
1162       is_expr = false;
1163       break;
1164
1165     case CATCH_EXPR:
1166       pp_string (buffer, "catch (");
1167       dump_generic_node (buffer, CATCH_TYPES (node), spc+2, flags, false);
1168       pp_string (buffer, ")");
1169       newline_and_indent (buffer, spc+2);
1170       pp_string (buffer, "{");
1171       newline_and_indent (buffer, spc+4);
1172       dump_generic_node (buffer, CATCH_BODY (node), spc+4, flags, true);
1173       newline_and_indent (buffer, spc+2);
1174       pp_string (buffer, "}");
1175       is_expr = false;
1176       break;
1177
1178     case EH_FILTER_EXPR:
1179       pp_string (buffer, "<<<eh_filter (");
1180       dump_generic_node (buffer, EH_FILTER_TYPES (node), spc+2, flags, false);
1181       pp_string (buffer, ")>>>");
1182       newline_and_indent (buffer, spc+2);
1183       pp_string (buffer, "{");
1184       newline_and_indent (buffer, spc+4);
1185       dump_generic_node (buffer, EH_FILTER_FAILURE (node), spc+4, flags, true);
1186       newline_and_indent (buffer, spc+2);
1187       pp_string (buffer, "}");
1188       is_expr = false;
1189       break;
1190
1191     case LABEL_EXPR:
1192       op0 = TREE_OPERAND (node, 0);
1193       /* If this is for break or continue, don't bother printing it.  */
1194       if (DECL_NAME (op0))
1195         {
1196           const char *name = IDENTIFIER_POINTER (DECL_NAME (op0));
1197           if (strcmp (name, "break") == 0
1198               || strcmp (name, "continue") == 0)
1199             break;
1200         }
1201       dump_generic_node (buffer, op0, spc, flags, false);
1202       pp_character (buffer, ':');
1203       if (DECL_NONLOCAL (op0))
1204         pp_string (buffer, " [non-local]");
1205       break;
1206
1207     case LABELED_BLOCK_EXPR:
1208       op0 = LABELED_BLOCK_LABEL (node);
1209       /* If this is for break or continue, don't bother printing it.  */
1210       if (DECL_NAME (op0))
1211         {
1212           const char *name = IDENTIFIER_POINTER (DECL_NAME (op0));
1213           if (strcmp (name, "break") == 0
1214               || strcmp (name, "continue") == 0)
1215             {
1216               dump_generic_node (buffer, LABELED_BLOCK_BODY (node), spc, flags, false);
1217               break;
1218             }
1219         }
1220       dump_generic_node (buffer, LABELED_BLOCK_LABEL (node), spc, flags, false);
1221       pp_string (buffer, ": {");
1222       if (!(flags & TDF_SLIM))
1223         newline_and_indent (buffer, spc+2);
1224       dump_generic_node (buffer, LABELED_BLOCK_BODY (node), spc+2, flags, true);
1225       if (!flags)
1226         newline_and_indent (buffer, spc);
1227       pp_character (buffer, '}');
1228       is_expr = false;
1229       break;
1230
1231     case EXIT_BLOCK_EXPR:
1232       op0 = LABELED_BLOCK_LABEL (EXIT_BLOCK_LABELED_BLOCK (node));
1233       /* If this is for a break or continue, print it accordingly.  */
1234       if (DECL_NAME (op0))
1235         {
1236           const char *name = IDENTIFIER_POINTER (DECL_NAME (op0));
1237           if (strcmp (name, "break") == 0
1238               || strcmp (name, "continue") == 0)
1239             {
1240               pp_string (buffer, name);
1241               break;
1242             }
1243         }
1244       pp_string (buffer, "<<<exit block ");
1245       dump_generic_node (buffer, op0, spc, flags, false);
1246       pp_string (buffer, ">>>");
1247       break;
1248
1249     case EXC_PTR_EXPR:
1250       pp_string (buffer, "<<<exception object>>>");
1251       break;
1252
1253     case FILTER_EXPR:
1254       pp_string (buffer, "<<<filter object>>>");
1255       break;
1256
1257     case LOOP_EXPR:
1258       pp_string (buffer, "while (1)");
1259       if (!(flags & TDF_SLIM))
1260         {
1261           newline_and_indent (buffer, spc+2);
1262           pp_character (buffer, '{');
1263           newline_and_indent (buffer, spc+4);
1264           dump_generic_node (buffer, LOOP_EXPR_BODY (node), spc+4, flags, true);
1265           newline_and_indent (buffer, spc+2);
1266           pp_character (buffer, '}');
1267         }
1268       is_expr = false;
1269       break;
1270
1271     case RETURN_EXPR:
1272       pp_string (buffer, "return");
1273       op0 = TREE_OPERAND (node, 0);
1274       if (op0)
1275         {
1276           pp_space (buffer);
1277           if (TREE_CODE (op0) == MODIFY_EXPR)
1278             dump_generic_node (buffer, TREE_OPERAND (op0, 1), spc, flags, false);
1279           else
1280             dump_generic_node (buffer, op0, spc, flags, false);
1281         }
1282       break;
1283
1284     case EXIT_EXPR:
1285       pp_string (buffer, "if (");
1286       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1287       pp_string (buffer, ") break");
1288       break;
1289
1290     case SWITCH_EXPR:
1291       pp_string (buffer, "switch (");
1292       dump_generic_node (buffer, SWITCH_COND (node), spc, flags, false);
1293       pp_character (buffer, ')');
1294       if (!(flags & TDF_SLIM))
1295         {
1296           newline_and_indent (buffer, spc+2);
1297           pp_character (buffer, '{');
1298           if (SWITCH_BODY (node))
1299             {
1300               newline_and_indent (buffer, spc+4);
1301               dump_generic_node (buffer, SWITCH_BODY (node), spc+4, flags, true);
1302             }
1303           else
1304             {
1305               tree vec = SWITCH_LABELS (node);
1306               size_t i, n = TREE_VEC_LENGTH (vec);
1307               for (i = 0; i < n; ++i)
1308                 {
1309                   tree elt = TREE_VEC_ELT (vec, i);
1310                   newline_and_indent (buffer, spc+4);
1311                   dump_generic_node (buffer, elt, spc+4, flags, false);
1312                   pp_string (buffer, " goto ");
1313                   dump_generic_node (buffer, CASE_LABEL (elt), spc+4, flags, true);
1314                   pp_semicolon (buffer);
1315                 }
1316             }
1317           newline_and_indent (buffer, spc+2);
1318           pp_character (buffer, '}');
1319         }
1320       is_expr = false;
1321       break;
1322
1323     case GOTO_EXPR:
1324       op0 = GOTO_DESTINATION (node);
1325       if (TREE_CODE (op0) != SSA_NAME
1326           && DECL_P (op0)
1327           && DECL_NAME (op0))
1328         {
1329           const char *name = IDENTIFIER_POINTER (DECL_NAME (op0));
1330           if (strcmp (name, "break") == 0
1331               || strcmp (name, "continue") == 0)
1332             {
1333               pp_string (buffer, name);
1334               break;
1335             }
1336         }
1337       pp_string (buffer, "goto ");
1338       dump_generic_node (buffer, op0, spc, flags, false);
1339       break;
1340
1341     case RESX_EXPR:
1342       pp_string (buffer, "resx");
1343       /* ??? Any sensible way to present the eh region?  */
1344       break;
1345
1346     case ASM_EXPR:
1347       pp_string (buffer, "__asm__");
1348       if (ASM_VOLATILE_P (node))
1349         pp_string (buffer, " __volatile__");
1350       pp_character (buffer, '(');
1351       dump_generic_node (buffer, ASM_STRING (node), spc, flags, false);
1352       pp_character (buffer, ':');
1353       dump_generic_node (buffer, ASM_OUTPUTS (node), spc, flags, false);
1354       pp_character (buffer, ':');
1355       dump_generic_node (buffer, ASM_INPUTS (node), spc, flags, false);
1356       if (ASM_CLOBBERS (node))
1357         {
1358           pp_character (buffer, ':');
1359           dump_generic_node (buffer, ASM_CLOBBERS (node), spc, flags, false);
1360         }
1361       pp_string (buffer, ")");
1362       break;
1363
1364     case CASE_LABEL_EXPR:
1365       if (CASE_LOW (node) && CASE_HIGH (node))
1366         {
1367           pp_string (buffer, "case ");
1368           dump_generic_node (buffer, CASE_LOW (node), spc, flags, false);
1369           pp_string (buffer, " ... ");
1370           dump_generic_node (buffer, CASE_HIGH (node), spc, flags, false);
1371         }
1372       else if (CASE_LOW (node))
1373         {
1374           pp_string (buffer, "case ");
1375           dump_generic_node (buffer, CASE_LOW (node), spc, flags, false);
1376         }
1377       else
1378         pp_string (buffer, "default ");
1379       pp_character (buffer, ':');
1380       break;
1381
1382     case OBJ_TYPE_REF:
1383       pp_string (buffer, "OBJ_TYPE_REF(");
1384       dump_generic_node (buffer, OBJ_TYPE_REF_EXPR (node), spc, flags, false);
1385       pp_character (buffer, ';');
1386       dump_generic_node (buffer, OBJ_TYPE_REF_OBJECT (node), spc, flags, false);
1387       pp_character (buffer, '-');
1388       pp_character (buffer, '>');
1389       dump_generic_node (buffer, OBJ_TYPE_REF_TOKEN (node), spc, flags, false);
1390       pp_character (buffer, ')');
1391       break;
1392
1393     case PHI_NODE:
1394       {
1395         int i;
1396
1397         dump_generic_node (buffer, PHI_RESULT (node), spc, flags, false);
1398         pp_string (buffer, " = PHI <");
1399         for (i = 0; i < PHI_NUM_ARGS (node); i++)
1400           {
1401             dump_generic_node (buffer, PHI_ARG_DEF (node, i), spc, flags, false);
1402             pp_string (buffer, "(");
1403             pp_decimal_int (buffer, PHI_ARG_EDGE (node, i)->src->index);
1404             pp_string (buffer, ")");
1405             if (i < PHI_NUM_ARGS (node) - 1)
1406               pp_string (buffer, ", ");
1407           }
1408         pp_string (buffer, ">;");
1409       }
1410       break;
1411
1412     case SSA_NAME:
1413       dump_generic_node (buffer, SSA_NAME_VAR (node), spc, flags, false);
1414       pp_string (buffer, "_");
1415       pp_decimal_int (buffer, SSA_NAME_VERSION (node));
1416       break;
1417
1418     case WITH_SIZE_EXPR:
1419       pp_string (buffer, "WITH_SIZE_EXPR <");
1420       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1421       pp_string (buffer, ", ");
1422       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1423       pp_string (buffer, ">");
1424       break;
1425
1426     case VALUE_HANDLE:
1427       pp_printf (buffer, "VH.%d", VALUE_HANDLE_ID (node));
1428       break;
1429
1430     case SCEV_KNOWN:
1431       pp_string (buffer, "scev_known");
1432       break;
1433
1434     case SCEV_NOT_KNOWN:
1435       pp_string (buffer, "scev_not_known");
1436       break;
1437
1438     case POLYNOMIAL_CHREC:
1439       pp_string (buffer, "{");
1440       dump_generic_node (buffer, CHREC_LEFT (node), spc, flags, false);
1441       pp_string (buffer, ", +, ");
1442       dump_generic_node (buffer, CHREC_RIGHT (node), spc, flags, false);
1443       pp_string (buffer, "}_");
1444       dump_generic_node (buffer, CHREC_VAR (node), spc, flags, false);
1445       is_stmt = false;
1446       break;
1447
1448     default:
1449       NIY;
1450     }
1451
1452   if (is_stmt && is_expr)
1453     pp_semicolon (buffer);
1454   pp_write_text_to_stream (buffer);
1455
1456   return spc;
1457 }
1458
1459 /* Print the declaration of a variable.  */
1460
1461 static void
1462 print_declaration (pretty_printer *buffer, tree t, int spc, int flags)
1463 {
1464   INDENT (spc);
1465
1466   if (TREE_CODE (t) == TYPE_DECL)
1467     pp_string (buffer, "typedef ");
1468
1469   if (DECL_REGISTER (t))
1470     pp_string (buffer, "register ");
1471
1472   if (TREE_PUBLIC (t) && DECL_EXTERNAL (t))
1473     pp_string (buffer, "extern ");
1474   else if (TREE_STATIC (t))
1475     pp_string (buffer, "static ");
1476
1477   /* Print the type and name.  */
1478   if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
1479     {
1480       tree tmp;
1481
1482       /* Print array's type.  */
1483       tmp = TREE_TYPE (t);
1484       while (TREE_CODE (TREE_TYPE (tmp)) == ARRAY_TYPE)
1485         tmp = TREE_TYPE (tmp);
1486       dump_generic_node (buffer, TREE_TYPE (tmp), spc, flags, false);
1487
1488       /* Print variable's name.  */
1489       pp_space (buffer);
1490       dump_generic_node (buffer, t, spc, flags, false);
1491
1492       /* Print the dimensions.  */
1493       tmp = TREE_TYPE (t);
1494       while (TREE_CODE (tmp) == ARRAY_TYPE)
1495         {
1496           pp_character (buffer, '[');
1497           if (TYPE_DOMAIN (tmp))
1498             {
1499               if (TREE_CODE (TYPE_SIZE (tmp)) == INTEGER_CST)
1500                 pp_wide_integer (buffer,
1501                                 TREE_INT_CST_LOW (TYPE_SIZE (tmp)) /
1502                                 TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (tmp))));
1503               else
1504                 dump_generic_node (buffer, TYPE_SIZE_UNIT (tmp), spc, flags,
1505                                    false);
1506             }
1507           pp_character (buffer, ']');
1508           tmp = TREE_TYPE (tmp);
1509         }
1510     }
1511   else if (TREE_CODE (t) == FUNCTION_DECL)
1512     {
1513       dump_generic_node (buffer, TREE_TYPE (TREE_TYPE (t)), spc, flags, false);
1514       pp_space (buffer);
1515       dump_decl_name (buffer, t, flags);
1516       dump_function_declaration (buffer, TREE_TYPE (t), spc, flags);
1517     }
1518   else
1519     {
1520       /* Print type declaration.  */
1521       dump_generic_node (buffer, TREE_TYPE (t), spc, flags, false);
1522
1523       /* Print variable's name.  */
1524       pp_space (buffer);
1525       dump_generic_node (buffer, t, spc, flags, false);
1526     }
1527
1528   /* The initial value of a function serves to determine wether the function
1529      is declared or defined.  So the following does not apply to function
1530      nodes.  */
1531   if (TREE_CODE (t) != FUNCTION_DECL)
1532     {
1533       /* Print the initial value.  */
1534       if (DECL_INITIAL (t))
1535         {
1536           pp_space (buffer);
1537           pp_character (buffer, '=');
1538           pp_space (buffer);
1539           dump_generic_node (buffer, DECL_INITIAL (t), spc, flags, false);
1540         }
1541     }
1542
1543   pp_character (buffer, ';');
1544 }
1545
1546
1547 /* Prints a structure: name, fields, and methods.
1548    FIXME: Still incomplete.  */
1549
1550 static void
1551 print_struct_decl (pretty_printer *buffer, tree node, int spc, int flags)
1552 {
1553   /* Print the name of the structure.  */
1554   if (TYPE_NAME (node))
1555     {
1556       INDENT (spc);
1557       if (TREE_CODE (node) == RECORD_TYPE)
1558         pp_string (buffer, "struct ");
1559       else if ((TREE_CODE (node) == UNION_TYPE
1560                 || TREE_CODE (node) == QUAL_UNION_TYPE))
1561         pp_string (buffer, "union ");
1562
1563       dump_generic_node (buffer, TYPE_NAME (node), spc, 0, false);
1564     }
1565
1566   /* Print the contents of the structure.  */
1567   pp_newline (buffer);
1568   INDENT (spc);
1569   pp_character (buffer, '{');
1570   pp_newline (buffer);
1571
1572   /* Print the fields of the structure.  */
1573   {
1574     tree tmp;
1575     tmp = TYPE_FIELDS (node);
1576     while (tmp)
1577       {
1578         /* Avoid to print recursively the structure.  */
1579         /* FIXME : Not implemented correctly...,
1580            what about the case when we have a cycle in the contain graph? ...
1581            Maybe this could be solved by looking at the scope in which the
1582            structure was declared.  */
1583         if (TREE_TYPE (tmp) != node
1584             || (TREE_CODE (TREE_TYPE (tmp)) == POINTER_TYPE
1585                 && TREE_TYPE (TREE_TYPE (tmp)) != node))
1586           {
1587             print_declaration (buffer, tmp, spc+2, flags);
1588             pp_newline (buffer);
1589           }
1590         tmp = TREE_CHAIN (tmp);
1591       }
1592   }
1593   INDENT (spc);
1594   pp_character (buffer, '}');
1595 }
1596
1597 /* Return the priority of the operator OP.
1598
1599    From lowest to highest precedence with either left-to-right (L-R)
1600    or right-to-left (R-L) associativity]:
1601
1602      1  [L-R] ,
1603      2  [R-L] = += -= *= /= %= &= ^= |= <<= >>=
1604      3  [R-L] ?:
1605      4  [L-R] ||
1606      5  [L-R] &&
1607      6  [L-R] |
1608      7  [L-R] ^
1609      8  [L-R] &
1610      9  [L-R] == !=
1611     10  [L-R] < <= > >=
1612     11  [L-R] << >>
1613     12  [L-R] + -
1614     13  [L-R] * / %
1615     14  [R-L] ! ~ ++ -- + - * & (type) sizeof
1616     15  [L-R] fn() [] -> .
1617
1618    unary +, - and * have higher precedence than the corresponding binary
1619    operators.  */
1620
1621 static int
1622 op_prio (tree op)
1623 {
1624   if (op == NULL)
1625     return 9999;
1626
1627   switch (TREE_CODE (op))
1628     {
1629     case TREE_LIST:
1630     case COMPOUND_EXPR:
1631     case BIND_EXPR:
1632       return 1;
1633
1634     case MODIFY_EXPR:
1635     case INIT_EXPR:
1636       return 2;
1637
1638     case COND_EXPR:
1639       return 3;
1640
1641     case TRUTH_OR_EXPR:
1642     case TRUTH_ORIF_EXPR:
1643       return 4;
1644
1645     case TRUTH_AND_EXPR:
1646     case TRUTH_ANDIF_EXPR:
1647       return 5;
1648
1649     case BIT_IOR_EXPR:
1650       return 6;
1651
1652     case BIT_XOR_EXPR:
1653     case TRUTH_XOR_EXPR:
1654       return 7;
1655
1656     case BIT_AND_EXPR:
1657       return 8;
1658
1659     case EQ_EXPR:
1660     case NE_EXPR:
1661       return 9;
1662
1663     case UNLT_EXPR:
1664     case UNLE_EXPR:
1665     case UNGT_EXPR:
1666     case UNGE_EXPR:
1667     case UNEQ_EXPR:
1668     case LTGT_EXPR:
1669     case ORDERED_EXPR:
1670     case UNORDERED_EXPR:
1671     case LT_EXPR:
1672     case LE_EXPR:
1673     case GT_EXPR:
1674     case GE_EXPR:
1675       return 10;
1676
1677     case LSHIFT_EXPR:
1678     case RSHIFT_EXPR:
1679     case LROTATE_EXPR:
1680     case RROTATE_EXPR:
1681       return 11;
1682
1683     case PLUS_EXPR:
1684     case MINUS_EXPR:
1685       return 12;
1686
1687     case MULT_EXPR:
1688     case TRUNC_DIV_EXPR:
1689     case CEIL_DIV_EXPR:
1690     case FLOOR_DIV_EXPR:
1691     case ROUND_DIV_EXPR:
1692     case RDIV_EXPR:
1693     case EXACT_DIV_EXPR:
1694     case TRUNC_MOD_EXPR:
1695     case CEIL_MOD_EXPR:
1696     case FLOOR_MOD_EXPR:
1697     case ROUND_MOD_EXPR:
1698       return 13;
1699
1700     case TRUTH_NOT_EXPR:
1701     case BIT_NOT_EXPR:
1702     case POSTINCREMENT_EXPR:
1703     case POSTDECREMENT_EXPR:
1704     case PREINCREMENT_EXPR:
1705     case PREDECREMENT_EXPR:
1706     case NEGATE_EXPR:
1707     case INDIRECT_REF:
1708     case ADDR_EXPR:
1709     case FLOAT_EXPR:
1710     case NOP_EXPR:
1711     case CONVERT_EXPR:
1712     case FIX_TRUNC_EXPR:
1713     case FIX_CEIL_EXPR:
1714     case FIX_FLOOR_EXPR:
1715     case FIX_ROUND_EXPR:
1716     case TARGET_EXPR:
1717       return 14;
1718
1719     case CALL_EXPR:
1720     case ARRAY_REF:
1721     case ARRAY_RANGE_REF:
1722     case COMPONENT_REF:
1723       return 15;
1724
1725       /* Special expressions.  */
1726     case MIN_EXPR:
1727     case MAX_EXPR:
1728     case ABS_EXPR:
1729     case REALPART_EXPR:
1730     case IMAGPART_EXPR:
1731       return 16;
1732
1733     case SAVE_EXPR:
1734     case NON_LVALUE_EXPR:
1735       return op_prio (TREE_OPERAND (op, 0));
1736
1737     default:
1738       /* Return an arbitrarily high precedence to avoid surrounding single
1739          VAR_DECLs in ()s.  */
1740       return 9999;
1741     }
1742 }
1743
1744
1745 /* Return the symbol associated with operator OP.  */
1746
1747 static const char *
1748 op_symbol (tree op)
1749 {
1750   if (op == NULL)
1751     abort ();
1752
1753   switch (TREE_CODE (op))
1754     {
1755     case MODIFY_EXPR:
1756       return "=";
1757
1758     case TRUTH_OR_EXPR:
1759     case TRUTH_ORIF_EXPR:
1760       return "||";
1761
1762     case TRUTH_AND_EXPR:
1763     case TRUTH_ANDIF_EXPR:
1764       return "&&";
1765
1766     case BIT_IOR_EXPR:
1767       return "|";
1768
1769     case TRUTH_XOR_EXPR:
1770     case BIT_XOR_EXPR:
1771       return "^";
1772
1773     case ADDR_EXPR:
1774     case BIT_AND_EXPR:
1775       return "&";
1776
1777     case ORDERED_EXPR:
1778       return "ord";
1779     case UNORDERED_EXPR:
1780       return "unord";
1781
1782     case EQ_EXPR:
1783       return "==";
1784     case UNEQ_EXPR:
1785       return "u==";
1786
1787     case NE_EXPR:
1788       return "!=";
1789
1790     case LT_EXPR:
1791       return "<";
1792     case UNLT_EXPR:
1793       return "u<";
1794
1795     case LE_EXPR:
1796       return "<=";
1797     case UNLE_EXPR:
1798       return "u<=";
1799
1800     case GT_EXPR:
1801       return ">";
1802     case UNGT_EXPR:
1803       return "u>";
1804
1805     case GE_EXPR:
1806       return ">=";
1807     case UNGE_EXPR:
1808       return "u>=";
1809
1810     case LTGT_EXPR:
1811       return "<>";
1812
1813     case LSHIFT_EXPR:
1814       return "<<";
1815
1816     case RSHIFT_EXPR:
1817       return ">>";
1818
1819     case PLUS_EXPR:
1820       return "+";
1821
1822     case NEGATE_EXPR:
1823     case MINUS_EXPR:
1824       return "-";
1825
1826     case BIT_NOT_EXPR:
1827       return "~";
1828
1829     case TRUTH_NOT_EXPR:
1830       return "!";
1831
1832     case MULT_EXPR:
1833     case INDIRECT_REF:
1834       return "*";
1835
1836     case TRUNC_DIV_EXPR:
1837     case CEIL_DIV_EXPR:
1838     case FLOOR_DIV_EXPR:
1839     case ROUND_DIV_EXPR:
1840     case RDIV_EXPR:
1841     case EXACT_DIV_EXPR:
1842       return "/";
1843
1844     case TRUNC_MOD_EXPR:
1845     case CEIL_MOD_EXPR:
1846     case FLOOR_MOD_EXPR:
1847     case ROUND_MOD_EXPR:
1848       return "%";
1849
1850     case PREDECREMENT_EXPR:
1851       return " --";
1852
1853     case PREINCREMENT_EXPR:
1854       return " ++";
1855
1856     case POSTDECREMENT_EXPR:
1857       return "-- ";
1858
1859     case POSTINCREMENT_EXPR:
1860       return "++ ";
1861
1862     default:
1863       return "<<< ??? >>>";
1864     }
1865 }
1866
1867 /* Prints the name of a CALL_EXPR.  */
1868
1869 static void
1870 print_call_name (pretty_printer *buffer, tree node)
1871 {
1872   tree op0;
1873
1874   if (TREE_CODE (node) != CALL_EXPR)
1875     abort ();
1876
1877   op0 = TREE_OPERAND (node, 0);
1878
1879   if (TREE_CODE (op0) == NON_LVALUE_EXPR)
1880     op0 = TREE_OPERAND (op0, 0);
1881
1882   switch (TREE_CODE (op0))
1883     {
1884     case VAR_DECL:
1885     case PARM_DECL:
1886       PRINT_FUNCTION_NAME (op0);
1887       break;
1888
1889     case ADDR_EXPR:
1890     case INDIRECT_REF:
1891     case NOP_EXPR:
1892       dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
1893       break;
1894
1895     case COND_EXPR:
1896       pp_string (buffer, "(");
1897       dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
1898       pp_string (buffer, ") ? ");
1899       dump_generic_node (buffer, TREE_OPERAND (op0, 1), 0, 0, false);
1900       pp_string (buffer, " : ");
1901       dump_generic_node (buffer, TREE_OPERAND (op0, 2), 0, 0, false);
1902       break;
1903
1904     case COMPONENT_REF:
1905       /* The function is a pointer contained in a structure.  */
1906       if (TREE_CODE (TREE_OPERAND (op0, 0)) == INDIRECT_REF ||
1907           TREE_CODE (TREE_OPERAND (op0, 0)) == VAR_DECL)
1908         PRINT_FUNCTION_NAME (TREE_OPERAND (op0, 1));
1909       else
1910         dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
1911       /* else
1912          We can have several levels of structures and a function
1913          pointer inside.  This is not implemented yet...  */
1914       /*                  NIY;*/
1915       break;
1916
1917     case ARRAY_REF:
1918       if (TREE_CODE (TREE_OPERAND (op0, 0)) == VAR_DECL)
1919         PRINT_FUNCTION_NAME (TREE_OPERAND (op0, 0));
1920       else
1921         dump_generic_node (buffer, op0, 0, 0, false);
1922       break;
1923
1924     case SSA_NAME:
1925     case OBJ_TYPE_REF:
1926       dump_generic_node (buffer, op0, 0, 0, false);
1927       break;
1928
1929     default:
1930       NIY;
1931     }
1932 }
1933
1934 /* Parses the string STR and replaces new-lines by '\n', tabs by '\t', ...  */
1935
1936 static void
1937 pretty_print_string (pretty_printer *buffer, const char *str)
1938 {
1939   if (str == NULL)
1940     return;
1941
1942   while (*str)
1943     {
1944       switch (str[0])
1945         {
1946         case '\b':
1947           pp_string (buffer, "\\b");
1948           break;
1949
1950         case '\f':
1951           pp_string (buffer, "\\f");
1952           break;
1953
1954         case '\n':
1955           pp_string (buffer, "\\n");
1956           break;
1957
1958         case '\r':
1959           pp_string (buffer, "\\r");
1960           break;
1961
1962         case '\t':
1963           pp_string (buffer, "\\t");
1964           break;
1965
1966         case '\v':
1967           pp_string (buffer, "\\v");
1968           break;
1969
1970         case '\\':
1971           pp_string (buffer, "\\\\");
1972           break;
1973
1974         case '\"':
1975           pp_string (buffer, "\\\"");
1976           break;
1977
1978         case '\'':
1979           pp_string (buffer, "\\'");
1980           break;
1981
1982         case '\0':
1983           pp_string (buffer, "\\0");
1984           break;
1985
1986         case '\1':
1987           pp_string (buffer, "\\1");
1988           break;
1989
1990         case '\2':
1991           pp_string (buffer, "\\2");
1992           break;
1993
1994         case '\3':
1995           pp_string (buffer, "\\3");
1996           break;
1997
1998         case '\4':
1999           pp_string (buffer, "\\4");
2000           break;
2001
2002         case '\5':
2003           pp_string (buffer, "\\5");
2004           break;
2005
2006         case '\6':
2007           pp_string (buffer, "\\6");
2008           break;
2009
2010         case '\7':
2011           pp_string (buffer, "\\7");
2012           break;
2013
2014         default:
2015           pp_character (buffer, str[0]);
2016           break;
2017         }
2018       str++;
2019     }
2020 }
2021
2022 static void
2023 maybe_init_pretty_print (FILE *file)
2024 {
2025   if (!initialized)
2026     {
2027       pp_construct (&buffer, /* prefix */NULL, /* line-width */0);
2028       pp_needs_newline (&buffer) = true;
2029       initialized = 1;
2030     }
2031
2032   buffer.buffer->stream = file;
2033 }
2034
2035 static void
2036 newline_and_indent (pretty_printer *buffer, int spc)
2037 {
2038   pp_newline (buffer);
2039   INDENT (spc);
2040 }
2041
2042 static void
2043 dump_vops (pretty_printer *buffer, tree stmt, int spc, int flags)
2044 {
2045   size_t i;
2046   stmt_ann_t ann = stmt_ann (stmt);
2047   v_may_def_optype v_may_defs = V_MAY_DEF_OPS (ann);
2048   v_must_def_optype v_must_defs = V_MUST_DEF_OPS (ann);
2049   vuse_optype vuses = VUSE_OPS (ann);
2050
2051   for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++)
2052     {
2053       pp_string (buffer, "#   ");
2054       dump_generic_node (buffer, V_MAY_DEF_RESULT (v_may_defs, i), 
2055                          spc + 2, flags, false);
2056       pp_string (buffer, " = V_MAY_DEF <");
2057       dump_generic_node (buffer, V_MAY_DEF_OP (v_may_defs, i), 
2058                          spc + 2, flags, false);
2059       pp_string (buffer, ">;");
2060       newline_and_indent (buffer, spc);
2061     }
2062
2063   for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++)
2064     {
2065       tree v_must_def = V_MUST_DEF_OP (v_must_defs, i);
2066       pp_string (buffer, "#   V_MUST_DEF <");
2067       dump_generic_node (buffer, v_must_def, spc + 2, flags, false);
2068       pp_string (buffer, ">;");
2069       newline_and_indent (buffer, spc);
2070     }
2071
2072   for (i = 0; i < NUM_VUSES (vuses); i++)
2073     {
2074       tree vuse = VUSE_OP (vuses, i);
2075       pp_string (buffer, "#   VUSE <");
2076       dump_generic_node (buffer, vuse, spc + 2, flags, false);
2077       pp_string (buffer, ">;");
2078       newline_and_indent (buffer, spc);
2079     }
2080 }
2081
2082 /* Dumps basic block BB to FILE with details described by FLAGS and
2083    indented by INDENT spaces.  */
2084
2085 void
2086 dump_generic_bb (FILE *file, basic_block bb, int indent, int flags)
2087 {
2088   maybe_init_pretty_print (file);
2089   dumping_stmts = true;
2090   dump_generic_bb_buff (&buffer, bb, indent, flags);
2091   pp_flush (&buffer);
2092 }
2093
2094 /* Dumps header of basic block BB to buffer BUFFER indented by INDENT
2095    spaces and details described by flags.  */
2096
2097 static void
2098 dump_bb_header (pretty_printer *buffer, basic_block bb, int indent, int flags)
2099 {
2100   edge e;
2101   tree stmt;
2102
2103   if (flags & TDF_BLOCKS)
2104     {
2105       INDENT (indent);
2106       pp_string (buffer, "# BLOCK ");
2107       pp_decimal_int (buffer, bb->index);
2108
2109       if (flags & TDF_LINENO)
2110         {
2111           block_stmt_iterator bsi;
2112
2113           for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
2114             if (get_lineno (bsi_stmt (bsi)) != -1)
2115               {
2116                 pp_string (buffer, ", starting at line ");
2117                 pp_decimal_int (buffer, get_lineno (bsi_stmt (bsi)));
2118                 break;
2119               }
2120         }
2121       newline_and_indent (buffer, indent);
2122
2123       pp_string (buffer, "# PRED:");
2124       pp_write_text_to_stream (buffer);
2125       for (e = bb->pred; e; e = e->pred_next)
2126         if (flags & TDF_SLIM)
2127           {
2128             pp_string (buffer, " ");
2129             if (e->src == ENTRY_BLOCK_PTR)
2130               pp_string (buffer, "ENTRY");
2131             else
2132               pp_decimal_int (buffer, e->src->index);
2133           }
2134         else
2135           dump_edge_info (buffer->buffer->stream, e, 0);
2136       pp_newline (buffer);
2137     }
2138   else
2139     {
2140       stmt = first_stmt (bb);
2141       if (!stmt || TREE_CODE (stmt) != LABEL_EXPR)
2142         {
2143           INDENT (indent - 2);
2144           pp_string (buffer, "<bb ");
2145           pp_decimal_int (buffer, bb->index);
2146           pp_string (buffer, ">:");
2147           pp_newline (buffer);
2148         }
2149     }
2150 }
2151
2152 /* Dumps end of basic block BB to buffer BUFFER indented by INDENT
2153    spaces.  */
2154
2155 static void
2156 dump_bb_end (pretty_printer *buffer, basic_block bb, int indent, int flags)
2157 {
2158   edge e;
2159
2160   INDENT (indent);
2161   pp_string (buffer, "# SUCC:");
2162   pp_write_text_to_stream (buffer);
2163   for (e = bb->succ; e; e = e->succ_next)
2164     if (flags & TDF_SLIM)
2165       {
2166         pp_string (buffer, " ");
2167         if (e->dest == EXIT_BLOCK_PTR)
2168           pp_string (buffer, "EXIT");
2169         else
2170           pp_decimal_int (buffer, e->dest->index);
2171       }
2172     else
2173       dump_edge_info (buffer->buffer->stream, e, 1);
2174   pp_newline (buffer);
2175 }
2176
2177 /* Dumps phi nodes of basic block BB to buffer BUFFER with details described by
2178    FLAGS indented by INDENT spaces.  */
2179
2180 static void
2181 dump_phi_nodes (pretty_printer *buffer, basic_block bb, int indent, int flags)
2182 {
2183   tree phi = phi_nodes (bb);
2184   if (!phi)
2185     return;
2186
2187   for (; phi; phi = PHI_CHAIN (phi))
2188     {
2189       if (is_gimple_reg (PHI_RESULT (phi)) || (flags & TDF_VOPS))
2190         {
2191           INDENT (indent);
2192           pp_string (buffer, "# ");
2193           dump_generic_node (buffer, phi, indent, flags, false);
2194           pp_newline (buffer);
2195         }
2196     }
2197 }
2198
2199 /* Dump jump to basic block BB that is represented implicitly in the cfg
2200    to BUFFER.  */
2201
2202 static void
2203 pp_cfg_jump (pretty_printer *buffer, basic_block bb)
2204 {
2205   tree stmt;
2206
2207   stmt = first_stmt (bb);
2208
2209   pp_string (buffer, "goto <bb ");
2210   pp_decimal_int (buffer, bb->index);
2211   pp_string (buffer, ">");
2212   if (stmt && TREE_CODE (stmt) == LABEL_EXPR)
2213     {
2214       pp_string (buffer, " (");
2215       dump_generic_node (buffer, LABEL_EXPR_LABEL (stmt), 0, 0, false);
2216       pp_string (buffer, ")");
2217     }
2218   pp_semicolon (buffer);
2219 }
2220
2221 /* Dump edges represented implicitly in basic block BB to BUFFER, indented
2222    by INDENT spaces, with details given by FLAGS.  */
2223
2224 static void
2225 dump_implicit_edges (pretty_printer *buffer, basic_block bb, int indent,
2226                      int flags)
2227 {
2228   edge e;
2229
2230   /* If there is a fallthru edge, we may need to add an artificial goto to the
2231      dump.  */
2232   for (e = bb->succ; e; e = e->succ_next)
2233     if (e->flags & EDGE_FALLTHRU)
2234       break;
2235   if (e && e->dest != bb->next_bb)
2236     {
2237       INDENT (indent);
2238
2239       if ((flags & TDF_LINENO)
2240 #ifdef USE_MAPPED_LOCATION
2241           && e->goto_locus != UNKNOWN_LOCATION
2242 #else
2243           && e->goto_locus
2244 #endif
2245           )
2246         {
2247           expanded_location goto_xloc;
2248 #ifdef USE_MAPPED_LOCATION
2249           goto_xloc = expand_location (e->goto_locus);
2250 #else
2251           goto_xloc = *e->goto_locus;
2252 #endif
2253           pp_character (buffer, '[');
2254           if (goto_xloc.file)
2255             {
2256               pp_string (buffer, goto_xloc.file);
2257               pp_string (buffer, " : ");
2258             }
2259           pp_decimal_int (buffer, goto_xloc.line);
2260           pp_string (buffer, "] ");
2261         }
2262
2263       pp_cfg_jump (buffer, e->dest);
2264       pp_newline (buffer);
2265     }
2266 }
2267
2268 /* Dumps basic block BB to buffer BUFFER with details described by FLAGS and
2269    indented by INDENT spaces.  */
2270
2271 static void
2272 dump_generic_bb_buff (pretty_printer *buffer, basic_block bb,
2273                       int indent, int flags)
2274 {
2275   block_stmt_iterator bsi;
2276   tree stmt;
2277   int label_indent = indent - 2;
2278
2279   if (label_indent < 0)
2280     label_indent = 0;
2281
2282   dump_bb_header (buffer, bb, indent, flags);
2283
2284   if (bb_ann (bb))
2285     dump_phi_nodes (buffer, bb, indent, flags);
2286   
2287   for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
2288     {
2289       int curr_indent;
2290
2291       stmt = bsi_stmt (bsi);
2292
2293       curr_indent = TREE_CODE (stmt) == LABEL_EXPR ? label_indent : indent;
2294
2295       INDENT (curr_indent);
2296       dump_generic_node (buffer, stmt, curr_indent, flags, true);
2297       pp_newline (buffer);
2298     }
2299
2300   dump_implicit_edges (buffer, bb, indent, flags);
2301
2302   if (flags & TDF_BLOCKS)
2303     dump_bb_end (buffer, bb, indent, flags);
2304 }