OSDN Git Service

5d230822a92ff279a588d9ea2a1e25d7425a62b7
[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       if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (node))
1420         pp_string (buffer, "(ab)");
1421       break;
1422
1423     case WITH_SIZE_EXPR:
1424       pp_string (buffer, "WITH_SIZE_EXPR <");
1425       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1426       pp_string (buffer, ", ");
1427       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1428       pp_string (buffer, ">");
1429       break;
1430
1431     case VALUE_HANDLE:
1432       pp_printf (buffer, "VH.%d", VALUE_HANDLE_ID (node));
1433       break;
1434
1435     case ASSERT_EXPR:
1436       pp_string (buffer, "ASSERT_EXPR <");
1437       dump_generic_node (buffer, ASSERT_EXPR_VAR (node), spc, flags, false);
1438       pp_string (buffer, ", ");
1439       dump_generic_node (buffer, ASSERT_EXPR_COND (node), spc, flags, false);
1440       pp_string (buffer, ">");
1441       break;
1442
1443     case SCEV_KNOWN:
1444       pp_string (buffer, "scev_known");
1445       break;
1446
1447     case SCEV_NOT_KNOWN:
1448       pp_string (buffer, "scev_not_known");
1449       break;
1450
1451     case POLYNOMIAL_CHREC:
1452       pp_string (buffer, "{");
1453       dump_generic_node (buffer, CHREC_LEFT (node), spc, flags, false);
1454       pp_string (buffer, ", +, ");
1455       dump_generic_node (buffer, CHREC_RIGHT (node), spc, flags, false);
1456       pp_string (buffer, "}_");
1457       dump_generic_node (buffer, CHREC_VAR (node), spc, flags, false);
1458       is_stmt = false;
1459       break;
1460
1461     case REALIGN_LOAD_EXPR:
1462       pp_string (buffer, "REALIGN_LOAD <");
1463       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1464       pp_string (buffer, ", ");
1465       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1466       pp_string (buffer, ", ");
1467       dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
1468       pp_string (buffer, ">");
1469       break;
1470       
1471     case VEC_COND_EXPR:
1472       pp_string (buffer, " VEC_COND_EXPR < ");
1473       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1474       pp_string (buffer, " , ");
1475       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1476       pp_string (buffer, " , ");
1477       dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
1478       pp_string (buffer, " > ");
1479       break;
1480
1481     default:
1482       NIY;
1483     }
1484
1485   if (is_stmt && is_expr)
1486     pp_semicolon (buffer);
1487   pp_write_text_to_stream (buffer);
1488
1489   return spc;
1490 }
1491
1492 /* Print the declaration of a variable.  */
1493
1494 static void
1495 print_declaration (pretty_printer *buffer, tree t, int spc, int flags)
1496 {
1497   INDENT (spc);
1498
1499   if (TREE_CODE (t) == TYPE_DECL)
1500     pp_string (buffer, "typedef ");
1501
1502   if (DECL_REGISTER (t))
1503     pp_string (buffer, "register ");
1504
1505   if (TREE_PUBLIC (t) && DECL_EXTERNAL (t))
1506     pp_string (buffer, "extern ");
1507   else if (TREE_STATIC (t))
1508     pp_string (buffer, "static ");
1509
1510   /* Print the type and name.  */
1511   if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
1512     {
1513       tree tmp;
1514
1515       /* Print array's type.  */
1516       tmp = TREE_TYPE (t);
1517       while (TREE_CODE (TREE_TYPE (tmp)) == ARRAY_TYPE)
1518         tmp = TREE_TYPE (tmp);
1519       dump_generic_node (buffer, TREE_TYPE (tmp), spc, flags, false);
1520
1521       /* Print variable's name.  */
1522       pp_space (buffer);
1523       dump_generic_node (buffer, t, spc, flags, false);
1524
1525       /* Print the dimensions.  */
1526       tmp = TREE_TYPE (t);
1527       while (TREE_CODE (tmp) == ARRAY_TYPE)
1528         {
1529           dump_array_domain (buffer, TYPE_DOMAIN (tmp), spc, flags);
1530           tmp = TREE_TYPE (tmp);
1531         }
1532     }
1533   else if (TREE_CODE (t) == FUNCTION_DECL)
1534     {
1535       dump_generic_node (buffer, TREE_TYPE (TREE_TYPE (t)), spc, flags, false);
1536       pp_space (buffer);
1537       dump_decl_name (buffer, t, flags);
1538       dump_function_declaration (buffer, TREE_TYPE (t), spc, flags);
1539     }
1540   else
1541     {
1542       /* Print type declaration.  */
1543       dump_generic_node (buffer, TREE_TYPE (t), spc, flags, false);
1544
1545       /* Print variable's name.  */
1546       pp_space (buffer);
1547       dump_generic_node (buffer, t, spc, flags, false);
1548     }
1549
1550   if (TREE_CODE (t) == VAR_DECL && DECL_HARD_REGISTER (t))
1551     {
1552       pp_string (buffer, " __asm__ ");
1553       pp_character (buffer, '(');
1554       dump_generic_node (buffer, DECL_ASSEMBLER_NAME (t), spc, flags, false);
1555       pp_character (buffer, ')');
1556     }
1557
1558   /* The initial value of a function serves to determine wether the function
1559      is declared or defined.  So the following does not apply to function
1560      nodes.  */
1561   if (TREE_CODE (t) != FUNCTION_DECL)
1562     {
1563       /* Print the initial value.  */
1564       if (DECL_INITIAL (t))
1565         {
1566           pp_space (buffer);
1567           pp_character (buffer, '=');
1568           pp_space (buffer);
1569           dump_generic_node (buffer, DECL_INITIAL (t), spc, flags, false);
1570         }
1571     }
1572
1573   pp_character (buffer, ';');
1574 }
1575
1576
1577 /* Prints a structure: name, fields, and methods.
1578    FIXME: Still incomplete.  */
1579
1580 static void
1581 print_struct_decl (pretty_printer *buffer, tree node, int spc, int flags)
1582 {
1583   /* Print the name of the structure.  */
1584   if (TYPE_NAME (node))
1585     {
1586       INDENT (spc);
1587       if (TREE_CODE (node) == RECORD_TYPE)
1588         pp_string (buffer, "struct ");
1589       else if ((TREE_CODE (node) == UNION_TYPE
1590                 || TREE_CODE (node) == QUAL_UNION_TYPE))
1591         pp_string (buffer, "union ");
1592
1593       dump_generic_node (buffer, TYPE_NAME (node), spc, 0, false);
1594     }
1595
1596   /* Print the contents of the structure.  */
1597   pp_newline (buffer);
1598   INDENT (spc);
1599   pp_character (buffer, '{');
1600   pp_newline (buffer);
1601
1602   /* Print the fields of the structure.  */
1603   {
1604     tree tmp;
1605     tmp = TYPE_FIELDS (node);
1606     while (tmp)
1607       {
1608         /* Avoid to print recursively the structure.  */
1609         /* FIXME : Not implemented correctly...,
1610            what about the case when we have a cycle in the contain graph? ...
1611            Maybe this could be solved by looking at the scope in which the
1612            structure was declared.  */
1613         if (TREE_TYPE (tmp) != node
1614             || (TREE_CODE (TREE_TYPE (tmp)) == POINTER_TYPE
1615                 && TREE_TYPE (TREE_TYPE (tmp)) != node))
1616           {
1617             print_declaration (buffer, tmp, spc+2, flags);
1618             pp_newline (buffer);
1619           }
1620         tmp = TREE_CHAIN (tmp);
1621       }
1622   }
1623   INDENT (spc);
1624   pp_character (buffer, '}');
1625 }
1626
1627 /* Return the priority of the operator OP.
1628
1629    From lowest to highest precedence with either left-to-right (L-R)
1630    or right-to-left (R-L) associativity]:
1631
1632      1  [L-R] ,
1633      2  [R-L] = += -= *= /= %= &= ^= |= <<= >>=
1634      3  [R-L] ?:
1635      4  [L-R] ||
1636      5  [L-R] &&
1637      6  [L-R] |
1638      7  [L-R] ^
1639      8  [L-R] &
1640      9  [L-R] == !=
1641     10  [L-R] < <= > >=
1642     11  [L-R] << >>
1643     12  [L-R] + -
1644     13  [L-R] * / %
1645     14  [R-L] ! ~ ++ -- + - * & (type) sizeof
1646     15  [L-R] fn() [] -> .
1647
1648    unary +, - and * have higher precedence than the corresponding binary
1649    operators.  */
1650
1651 static int
1652 op_prio (tree op)
1653 {
1654   if (op == NULL)
1655     return 9999;
1656
1657   switch (TREE_CODE (op))
1658     {
1659     case TREE_LIST:
1660     case COMPOUND_EXPR:
1661     case BIND_EXPR:
1662       return 1;
1663
1664     case MODIFY_EXPR:
1665     case INIT_EXPR:
1666       return 2;
1667
1668     case COND_EXPR:
1669       return 3;
1670
1671     case TRUTH_OR_EXPR:
1672     case TRUTH_ORIF_EXPR:
1673       return 4;
1674
1675     case TRUTH_AND_EXPR:
1676     case TRUTH_ANDIF_EXPR:
1677       return 5;
1678
1679     case BIT_IOR_EXPR:
1680       return 6;
1681
1682     case BIT_XOR_EXPR:
1683     case TRUTH_XOR_EXPR:
1684       return 7;
1685
1686     case BIT_AND_EXPR:
1687       return 8;
1688
1689     case EQ_EXPR:
1690     case NE_EXPR:
1691       return 9;
1692
1693     case UNLT_EXPR:
1694     case UNLE_EXPR:
1695     case UNGT_EXPR:
1696     case UNGE_EXPR:
1697     case UNEQ_EXPR:
1698     case LTGT_EXPR:
1699     case ORDERED_EXPR:
1700     case UNORDERED_EXPR:
1701     case LT_EXPR:
1702     case LE_EXPR:
1703     case GT_EXPR:
1704     case GE_EXPR:
1705       return 10;
1706
1707     case LSHIFT_EXPR:
1708     case RSHIFT_EXPR:
1709     case LROTATE_EXPR:
1710     case RROTATE_EXPR:
1711       return 11;
1712
1713     case PLUS_EXPR:
1714     case MINUS_EXPR:
1715       return 12;
1716
1717     case MULT_EXPR:
1718     case TRUNC_DIV_EXPR:
1719     case CEIL_DIV_EXPR:
1720     case FLOOR_DIV_EXPR:
1721     case ROUND_DIV_EXPR:
1722     case RDIV_EXPR:
1723     case EXACT_DIV_EXPR:
1724     case TRUNC_MOD_EXPR:
1725     case CEIL_MOD_EXPR:
1726     case FLOOR_MOD_EXPR:
1727     case ROUND_MOD_EXPR:
1728       return 13;
1729
1730     case TRUTH_NOT_EXPR:
1731     case BIT_NOT_EXPR:
1732     case POSTINCREMENT_EXPR:
1733     case POSTDECREMENT_EXPR:
1734     case PREINCREMENT_EXPR:
1735     case PREDECREMENT_EXPR:
1736     case NEGATE_EXPR:
1737     case ALIGN_INDIRECT_REF:
1738     case MISALIGNED_INDIRECT_REF:
1739     case INDIRECT_REF:
1740     case ADDR_EXPR:
1741     case FLOAT_EXPR:
1742     case NOP_EXPR:
1743     case CONVERT_EXPR:
1744     case FIX_TRUNC_EXPR:
1745     case FIX_CEIL_EXPR:
1746     case FIX_FLOOR_EXPR:
1747     case FIX_ROUND_EXPR:
1748     case TARGET_EXPR:
1749       return 14;
1750
1751     case CALL_EXPR:
1752     case ARRAY_REF:
1753     case ARRAY_RANGE_REF:
1754     case COMPONENT_REF:
1755       return 15;
1756
1757       /* Special expressions.  */
1758     case MIN_EXPR:
1759     case MAX_EXPR:
1760     case ABS_EXPR:
1761     case REALPART_EXPR:
1762     case IMAGPART_EXPR:
1763       return 16;
1764
1765     case SAVE_EXPR:
1766     case NON_LVALUE_EXPR:
1767       return op_prio (TREE_OPERAND (op, 0));
1768
1769     default:
1770       /* Return an arbitrarily high precedence to avoid surrounding single
1771          VAR_DECLs in ()s.  */
1772       return 9999;
1773     }
1774 }
1775
1776
1777 /* Return the symbol associated with operator OP.  */
1778
1779 static const char *
1780 op_symbol (tree op)
1781 {
1782   gcc_assert (op);
1783
1784   switch (TREE_CODE (op))
1785     {
1786     case MODIFY_EXPR:
1787       return "=";
1788
1789     case TRUTH_OR_EXPR:
1790     case TRUTH_ORIF_EXPR:
1791       return "||";
1792
1793     case TRUTH_AND_EXPR:
1794     case TRUTH_ANDIF_EXPR:
1795       return "&&";
1796
1797     case BIT_IOR_EXPR:
1798       return "|";
1799
1800     case TRUTH_XOR_EXPR:
1801     case BIT_XOR_EXPR:
1802       return "^";
1803
1804     case ADDR_EXPR:
1805     case BIT_AND_EXPR:
1806       return "&";
1807
1808     case ORDERED_EXPR:
1809       return "ord";
1810     case UNORDERED_EXPR:
1811       return "unord";
1812
1813     case EQ_EXPR:
1814       return "==";
1815     case UNEQ_EXPR:
1816       return "u==";
1817
1818     case NE_EXPR:
1819       return "!=";
1820
1821     case LT_EXPR:
1822       return "<";
1823     case UNLT_EXPR:
1824       return "u<";
1825
1826     case LE_EXPR:
1827       return "<=";
1828     case UNLE_EXPR:
1829       return "u<=";
1830
1831     case GT_EXPR:
1832       return ">";
1833     case UNGT_EXPR:
1834       return "u>";
1835
1836     case GE_EXPR:
1837       return ">=";
1838     case UNGE_EXPR:
1839       return "u>=";
1840
1841     case LTGT_EXPR:
1842       return "<>";
1843
1844     case LSHIFT_EXPR:
1845       return "<<";
1846
1847     case RSHIFT_EXPR:
1848       return ">>";
1849
1850     case PLUS_EXPR:
1851       return "+";
1852
1853     case NEGATE_EXPR:
1854     case MINUS_EXPR:
1855       return "-";
1856
1857     case BIT_NOT_EXPR:
1858       return "~";
1859
1860     case TRUTH_NOT_EXPR:
1861       return "!";
1862
1863     case MULT_EXPR:
1864     case INDIRECT_REF:
1865       return "*";
1866
1867     case ALIGN_INDIRECT_REF:
1868       return "A*";
1869
1870     case MISALIGNED_INDIRECT_REF:
1871       return "M*";
1872
1873     case TRUNC_DIV_EXPR:
1874     case RDIV_EXPR:
1875       return "/";
1876
1877     case CEIL_DIV_EXPR:
1878       return "/[cl]";
1879
1880     case FLOOR_DIV_EXPR:
1881       return "/[fl]";
1882
1883     case ROUND_DIV_EXPR:
1884       return "/[rd]";
1885
1886     case EXACT_DIV_EXPR:
1887       return "/[ex]";
1888
1889     case TRUNC_MOD_EXPR:
1890       return "%";
1891
1892     case CEIL_MOD_EXPR:
1893       return "%[cl]";
1894
1895     case FLOOR_MOD_EXPR:
1896       return "%[fl]";
1897
1898     case ROUND_MOD_EXPR:
1899       return "%[rd]";
1900
1901     case PREDECREMENT_EXPR:
1902       return " --";
1903
1904     case PREINCREMENT_EXPR:
1905       return " ++";
1906
1907     case POSTDECREMENT_EXPR:
1908       return "-- ";
1909
1910     case POSTINCREMENT_EXPR:
1911       return "++ ";
1912
1913     default:
1914       return "<<< ??? >>>";
1915     }
1916 }
1917
1918 /* Prints the name of a CALL_EXPR.  */
1919
1920 static void
1921 print_call_name (pretty_printer *buffer, tree node)
1922 {
1923   tree op0;
1924
1925   gcc_assert (TREE_CODE (node) == CALL_EXPR);
1926
1927   op0 = TREE_OPERAND (node, 0);
1928
1929   if (TREE_CODE (op0) == NON_LVALUE_EXPR)
1930     op0 = TREE_OPERAND (op0, 0);
1931
1932   switch (TREE_CODE (op0))
1933     {
1934     case VAR_DECL:
1935     case PARM_DECL:
1936       dump_function_name (buffer, op0);
1937       break;
1938
1939     case ADDR_EXPR:
1940     case INDIRECT_REF:
1941     case NOP_EXPR:
1942       dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
1943       break;
1944
1945     case COND_EXPR:
1946       pp_string (buffer, "(");
1947       dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
1948       pp_string (buffer, ") ? ");
1949       dump_generic_node (buffer, TREE_OPERAND (op0, 1), 0, 0, false);
1950       pp_string (buffer, " : ");
1951       dump_generic_node (buffer, TREE_OPERAND (op0, 2), 0, 0, false);
1952       break;
1953
1954     case COMPONENT_REF:
1955       /* The function is a pointer contained in a structure.  */
1956       if (TREE_CODE (TREE_OPERAND (op0, 0)) == INDIRECT_REF ||
1957           TREE_CODE (TREE_OPERAND (op0, 0)) == VAR_DECL)
1958         dump_function_name (buffer, TREE_OPERAND (op0, 1));
1959       else
1960         dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
1961       /* else
1962          We can have several levels of structures and a function
1963          pointer inside.  This is not implemented yet...  */
1964       /*                  NIY;*/
1965       break;
1966
1967     case ARRAY_REF:
1968       if (TREE_CODE (TREE_OPERAND (op0, 0)) == VAR_DECL)
1969         dump_function_name (buffer, TREE_OPERAND (op0, 0));
1970       else
1971         dump_generic_node (buffer, op0, 0, 0, false);
1972       break;
1973
1974     case SSA_NAME:
1975     case OBJ_TYPE_REF:
1976       dump_generic_node (buffer, op0, 0, 0, false);
1977       break;
1978
1979     default:
1980       NIY;
1981     }
1982 }
1983
1984 /* Parses the string STR and replaces new-lines by '\n', tabs by '\t', ...  */
1985
1986 static void
1987 pretty_print_string (pretty_printer *buffer, const char *str)
1988 {
1989   if (str == NULL)
1990     return;
1991
1992   while (*str)
1993     {
1994       switch (str[0])
1995         {
1996         case '\b':
1997           pp_string (buffer, "\\b");
1998           break;
1999
2000         case '\f':
2001           pp_string (buffer, "\\f");
2002           break;
2003
2004         case '\n':
2005           pp_string (buffer, "\\n");
2006           break;
2007
2008         case '\r':
2009           pp_string (buffer, "\\r");
2010           break;
2011
2012         case '\t':
2013           pp_string (buffer, "\\t");
2014           break;
2015
2016         case '\v':
2017           pp_string (buffer, "\\v");
2018           break;
2019
2020         case '\\':
2021           pp_string (buffer, "\\\\");
2022           break;
2023
2024         case '\"':
2025           pp_string (buffer, "\\\"");
2026           break;
2027
2028         case '\'':
2029           pp_string (buffer, "\\'");
2030           break;
2031
2032         case '\0':
2033           pp_string (buffer, "\\0");
2034           break;
2035
2036         case '\1':
2037           pp_string (buffer, "\\1");
2038           break;
2039
2040         case '\2':
2041           pp_string (buffer, "\\2");
2042           break;
2043
2044         case '\3':
2045           pp_string (buffer, "\\3");
2046           break;
2047
2048         case '\4':
2049           pp_string (buffer, "\\4");
2050           break;
2051
2052         case '\5':
2053           pp_string (buffer, "\\5");
2054           break;
2055
2056         case '\6':
2057           pp_string (buffer, "\\6");
2058           break;
2059
2060         case '\7':
2061           pp_string (buffer, "\\7");
2062           break;
2063
2064         default:
2065           pp_character (buffer, str[0]);
2066           break;
2067         }
2068       str++;
2069     }
2070 }
2071
2072 static void
2073 maybe_init_pretty_print (FILE *file)
2074 {
2075   if (!initialized)
2076     {
2077       pp_construct (&buffer, /* prefix */NULL, /* line-width */0);
2078       pp_needs_newline (&buffer) = true;
2079       initialized = 1;
2080     }
2081
2082   buffer.buffer->stream = file;
2083 }
2084
2085 static void
2086 newline_and_indent (pretty_printer *buffer, int spc)
2087 {
2088   pp_newline (buffer);
2089   INDENT (spc);
2090 }
2091
2092 static void
2093 dump_vops (pretty_printer *buffer, tree stmt, int spc, int flags)
2094 {
2095   tree use;
2096   use_operand_p use_p;
2097   def_operand_p def_p;
2098   use_operand_p kill_p;
2099   ssa_op_iter iter;
2100
2101   FOR_EACH_SSA_MAYDEF_OPERAND (def_p, use_p, stmt, iter)
2102     {
2103       pp_string (buffer, "#   ");
2104       dump_generic_node (buffer, DEF_FROM_PTR (def_p),
2105                          spc + 2, flags, false);
2106       pp_string (buffer, " = V_MAY_DEF <");
2107       dump_generic_node (buffer, USE_FROM_PTR (use_p),
2108                          spc + 2, flags, false);
2109       pp_string (buffer, ">;");
2110       newline_and_indent (buffer, spc);
2111     }
2112
2113   FOR_EACH_SSA_MUSTDEF_OPERAND (def_p, kill_p, stmt, iter)
2114     {
2115       pp_string (buffer, "#   ");
2116       dump_generic_node (buffer, DEF_FROM_PTR (def_p),
2117                          spc + 2, flags, false);
2118       pp_string (buffer, " = V_MUST_DEF <");
2119       dump_generic_node (buffer, USE_FROM_PTR (kill_p),
2120                          spc + 2, flags, false);
2121       pp_string (buffer, ">;");
2122       newline_and_indent (buffer, spc);
2123     }
2124
2125   FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_VUSE)
2126     {
2127       pp_string (buffer, "#   VUSE <");
2128       dump_generic_node (buffer, use, spc + 2, flags, false);
2129       pp_string (buffer, ">;");
2130       newline_and_indent (buffer, spc);
2131     }
2132 }
2133
2134 /* Dumps basic block BB to FILE with details described by FLAGS and
2135    indented by INDENT spaces.  */
2136
2137 void
2138 dump_generic_bb (FILE *file, basic_block bb, int indent, int flags)
2139 {
2140   maybe_init_pretty_print (file);
2141   dumping_stmts = true;
2142   dump_generic_bb_buff (&buffer, bb, indent, flags);
2143   pp_flush (&buffer);
2144 }
2145
2146 /* Dumps header of basic block BB to buffer BUFFER indented by INDENT
2147    spaces and details described by flags.  */
2148
2149 static void
2150 dump_bb_header (pretty_printer *buffer, basic_block bb, int indent, int flags)
2151 {
2152   edge e;
2153   tree stmt;
2154   edge_iterator ei;
2155
2156   if (flags & TDF_BLOCKS)
2157     {
2158       INDENT (indent);
2159       pp_string (buffer, "# BLOCK ");
2160       pp_decimal_int (buffer, bb->index);
2161
2162       if (flags & TDF_LINENO)
2163         {
2164           block_stmt_iterator bsi;
2165
2166           for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
2167             if (get_lineno (bsi_stmt (bsi)) != -1)
2168               {
2169                 pp_string (buffer, ", starting at line ");
2170                 pp_decimal_int (buffer, get_lineno (bsi_stmt (bsi)));
2171                 break;
2172               }
2173         }
2174       newline_and_indent (buffer, indent);
2175
2176       pp_string (buffer, "# PRED:");
2177       pp_write_text_to_stream (buffer);
2178       FOR_EACH_EDGE (e, ei, bb->preds)
2179         if (flags & TDF_SLIM)
2180           {
2181             pp_string (buffer, " ");
2182             if (e->src == ENTRY_BLOCK_PTR)
2183               pp_string (buffer, "ENTRY");
2184             else
2185               pp_decimal_int (buffer, e->src->index);
2186           }
2187         else
2188           dump_edge_info (buffer->buffer->stream, e, 0);
2189       pp_newline (buffer);
2190     }
2191   else
2192     {
2193       stmt = first_stmt (bb);
2194       if (!stmt || TREE_CODE (stmt) != LABEL_EXPR)
2195         {
2196           INDENT (indent - 2);
2197           pp_string (buffer, "<bb ");
2198           pp_decimal_int (buffer, bb->index);
2199           pp_string (buffer, ">:");
2200           pp_newline (buffer);
2201         }
2202     }
2203   pp_write_text_to_stream (buffer);
2204   check_bb_profile (bb, buffer->buffer->stream);
2205 }
2206
2207 /* Dumps end of basic block BB to buffer BUFFER indented by INDENT
2208    spaces.  */
2209
2210 static void
2211 dump_bb_end (pretty_printer *buffer, basic_block bb, int indent, int flags)
2212 {
2213   edge e;
2214   edge_iterator ei;
2215
2216   INDENT (indent);
2217   pp_string (buffer, "# SUCC:");
2218   pp_write_text_to_stream (buffer);
2219   FOR_EACH_EDGE (e, ei, bb->succs)
2220     if (flags & TDF_SLIM)
2221       {
2222         pp_string (buffer, " ");
2223         if (e->dest == EXIT_BLOCK_PTR)
2224           pp_string (buffer, "EXIT");
2225         else
2226           pp_decimal_int (buffer, e->dest->index);
2227       }
2228     else
2229       dump_edge_info (buffer->buffer->stream, e, 1);
2230   pp_newline (buffer);
2231 }
2232
2233 /* Dumps phi nodes of basic block BB to buffer BUFFER with details described by
2234    FLAGS indented by INDENT spaces.  */
2235
2236 static void
2237 dump_phi_nodes (pretty_printer *buffer, basic_block bb, int indent, int flags)
2238 {
2239   tree phi = phi_nodes (bb);
2240   if (!phi)
2241     return;
2242
2243   for (; phi; phi = PHI_CHAIN (phi))
2244     {
2245       if (is_gimple_reg (PHI_RESULT (phi)) || (flags & TDF_VOPS))
2246         {
2247           INDENT (indent);
2248           pp_string (buffer, "# ");
2249           dump_generic_node (buffer, phi, indent, flags, false);
2250           pp_newline (buffer);
2251         }
2252     }
2253 }
2254
2255 /* Dump jump to basic block BB that is represented implicitly in the cfg
2256    to BUFFER.  */
2257
2258 static void
2259 pp_cfg_jump (pretty_printer *buffer, basic_block bb)
2260 {
2261   tree stmt;
2262
2263   stmt = first_stmt (bb);
2264
2265   pp_string (buffer, "goto <bb ");
2266   pp_decimal_int (buffer, bb->index);
2267   pp_string (buffer, ">");
2268   if (stmt && TREE_CODE (stmt) == LABEL_EXPR)
2269     {
2270       pp_string (buffer, " (");
2271       dump_generic_node (buffer, LABEL_EXPR_LABEL (stmt), 0, 0, false);
2272       pp_string (buffer, ")");
2273     }
2274   pp_semicolon (buffer);
2275 }
2276
2277 /* Dump edges represented implicitly in basic block BB to BUFFER, indented
2278    by INDENT spaces, with details given by FLAGS.  */
2279
2280 static void
2281 dump_implicit_edges (pretty_printer *buffer, basic_block bb, int indent,
2282                      int flags)
2283 {
2284   edge e;
2285   edge_iterator ei;
2286
2287   /* If there is a fallthru edge, we may need to add an artificial goto to the
2288      dump.  */
2289   FOR_EACH_EDGE (e, ei, bb->succs)
2290     if (e->flags & EDGE_FALLTHRU)
2291       break;
2292   if (e && e->dest != bb->next_bb)
2293     {
2294       INDENT (indent);
2295
2296       if ((flags & TDF_LINENO)
2297 #ifdef USE_MAPPED_LOCATION
2298           && e->goto_locus != UNKNOWN_LOCATION
2299 #else
2300           && e->goto_locus
2301 #endif
2302           )
2303         {
2304           expanded_location goto_xloc;
2305 #ifdef USE_MAPPED_LOCATION
2306           goto_xloc = expand_location (e->goto_locus);
2307 #else
2308           goto_xloc = *e->goto_locus;
2309 #endif
2310           pp_character (buffer, '[');
2311           if (goto_xloc.file)
2312             {
2313               pp_string (buffer, goto_xloc.file);
2314               pp_string (buffer, " : ");
2315             }
2316           pp_decimal_int (buffer, goto_xloc.line);
2317           pp_string (buffer, "] ");
2318         }
2319
2320       pp_cfg_jump (buffer, e->dest);
2321       pp_newline (buffer);
2322     }
2323 }
2324
2325 /* Dumps basic block BB to buffer BUFFER with details described by FLAGS and
2326    indented by INDENT spaces.  */
2327
2328 static void
2329 dump_generic_bb_buff (pretty_printer *buffer, basic_block bb,
2330                       int indent, int flags)
2331 {
2332   block_stmt_iterator bsi;
2333   tree stmt;
2334   int label_indent = indent - 2;
2335
2336   if (label_indent < 0)
2337     label_indent = 0;
2338
2339   dump_bb_header (buffer, bb, indent, flags);
2340
2341   if (bb_ann (bb))
2342     dump_phi_nodes (buffer, bb, indent, flags);
2343
2344   for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
2345     {
2346       int curr_indent;
2347
2348       stmt = bsi_stmt (bsi);
2349
2350       curr_indent = TREE_CODE (stmt) == LABEL_EXPR ? label_indent : indent;
2351
2352       INDENT (curr_indent);
2353       dump_generic_node (buffer, stmt, curr_indent, flags, true);
2354       pp_newline (buffer);
2355     }
2356
2357   dump_implicit_edges (buffer, bb, indent, flags);
2358
2359   if (flags & TDF_BLOCKS)
2360     dump_bb_end (buffer, bb, indent, flags);
2361 }