OSDN Git Service

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