OSDN Git Service

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