OSDN Git Service

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