OSDN Git Service

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