OSDN Git Service

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