OSDN Git Service

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