OSDN Git Service

PR testsuite/20772
[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 TYPE_MEMORY_TAG:
702     case NAME_MEMORY_TAG:
703     case STRUCT_FIELD_TAG:
704     case VAR_DECL:
705     case PARM_DECL:
706     case FIELD_DECL:
707     case NAMESPACE_DECL:
708       dump_decl_name (buffer, node, flags);
709       break;
710
711     case RESULT_DECL:
712       pp_string (buffer, "<retval>");
713       break;
714
715     case COMPONENT_REF:
716       op0 = TREE_OPERAND (node, 0);
717       str = ".";
718       if (TREE_CODE (op0) == INDIRECT_REF)
719         {
720           op0 = TREE_OPERAND (op0, 0);
721           str = "->";
722         }
723       if (op_prio (op0) < op_prio (node))
724         pp_character (buffer, '(');
725       dump_generic_node (buffer, op0, spc, flags, false);
726       if (op_prio (op0) < op_prio (node))
727         pp_character (buffer, ')');
728       pp_string (buffer, str);
729       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
730
731       if (TREE_CODE (op0) != VALUE_HANDLE)
732         {
733           op0 = component_ref_field_offset (node);
734           if (op0 && TREE_CODE (op0) != INTEGER_CST)
735             {
736               pp_string (buffer, "{off: ");
737               dump_generic_node (buffer, op0, spc, flags, false);
738               pp_character (buffer, '}');
739             }
740         }
741       break;
742
743     case BIT_FIELD_REF:
744       pp_string (buffer, "BIT_FIELD_REF <");
745       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
746       pp_string (buffer, ", ");
747       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
748       pp_string (buffer, ", ");
749       dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
750       pp_string (buffer, ">");
751       break;
752
753     case ARRAY_REF:
754     case ARRAY_RANGE_REF:
755       op0 = TREE_OPERAND (node, 0);
756       if (op_prio (op0) < op_prio (node))
757         pp_character (buffer, '(');
758       dump_generic_node (buffer, op0, spc, flags, false);
759       if (op_prio (op0) < op_prio (node))
760         pp_character (buffer, ')');
761       pp_character (buffer, '[');
762       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
763       if (TREE_CODE (node) == ARRAY_RANGE_REF)
764         pp_string (buffer, " ...");
765       pp_character (buffer, ']');
766
767       op0 = array_ref_low_bound (node);
768       op1 = array_ref_element_size (node);
769
770       if (!integer_zerop (op0)
771           || (TYPE_SIZE_UNIT (TREE_TYPE (node))
772               && !operand_equal_p (op1, TYPE_SIZE_UNIT (TREE_TYPE (node)), 0)))
773         {
774           pp_string (buffer, "{lb: ");
775           dump_generic_node (buffer, op0, spc, flags, false);
776           pp_string (buffer, " sz: ");
777           dump_generic_node (buffer, op1, spc, flags, false);
778           pp_character (buffer, '}');
779         }
780       break;
781
782     case CONSTRUCTOR:
783       {
784         unsigned HOST_WIDE_INT ix;
785         tree field, val;
786         bool is_struct_init = FALSE;
787         pp_character (buffer, '{');
788         if (TREE_CODE (TREE_TYPE (node)) == RECORD_TYPE
789             || TREE_CODE (TREE_TYPE (node)) == UNION_TYPE)
790           is_struct_init = TRUE;
791         FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (node), ix, field, val)
792           {
793             if (field && is_struct_init)
794               {
795                 pp_character (buffer, '.');
796                 dump_generic_node (buffer, field, spc, flags, false);
797                 pp_string (buffer, "=");
798               }
799             if (val && TREE_CODE (val) == ADDR_EXPR)
800               if (TREE_CODE (TREE_OPERAND (val, 0)) == FUNCTION_DECL)
801                 val = TREE_OPERAND (val, 0);
802             if (val && TREE_CODE (val) == FUNCTION_DECL)
803                 dump_decl_name (buffer, val, flags);
804             else
805                 dump_generic_node (buffer, val, spc, flags, false);
806             if (ix != VEC_length (constructor_elt, CONSTRUCTOR_ELTS (node)) - 1)
807               {
808                 pp_character (buffer, ',');
809                 pp_space (buffer);
810               }
811           }
812         pp_character (buffer, '}');
813       }
814       break;
815
816     case COMPOUND_EXPR:
817       {
818         tree *tp;
819         if (flags & TDF_SLIM)
820           {
821             pp_string (buffer, "<COMPOUND_EXPR>");
822             break;
823           }
824
825         dump_generic_node (buffer, TREE_OPERAND (node, 0),
826                            spc, flags, dumping_stmts);
827         if (dumping_stmts)
828           newline_and_indent (buffer, spc);
829         else
830           {
831             pp_character (buffer, ',');
832             pp_space (buffer);
833           }
834
835         for (tp = &TREE_OPERAND (node, 1);
836              TREE_CODE (*tp) == COMPOUND_EXPR;
837              tp = &TREE_OPERAND (*tp, 1))
838           {
839             dump_generic_node (buffer, TREE_OPERAND (*tp, 0),
840                                spc, flags, dumping_stmts);
841             if (dumping_stmts)
842               newline_and_indent (buffer, spc);
843             else
844               {
845                 pp_character (buffer, ',');
846                 pp_space (buffer);
847               }
848           }
849
850         dump_generic_node (buffer, *tp, spc, flags, dumping_stmts);
851       }
852       break;
853
854     case STATEMENT_LIST:
855       {
856         tree_stmt_iterator si;
857         bool first = true;
858
859         if ((flags & TDF_SLIM) || !dumping_stmts)
860           {
861             pp_string (buffer, "<STATEMENT_LIST>");
862             break;
863           }
864
865         for (si = tsi_start (node); !tsi_end_p (si); tsi_next (&si))
866           {
867             if (!first)
868               newline_and_indent (buffer, spc);
869             else
870               first = false;
871             dump_generic_node (buffer, tsi_stmt (si), spc, flags, true);
872           }
873       }
874       break;
875
876     case MODIFY_EXPR:
877     case INIT_EXPR:
878       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
879       pp_space (buffer);
880       pp_character (buffer, '=');
881       pp_space (buffer);
882       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
883       break;
884
885     case TARGET_EXPR:
886       pp_string (buffer, "TARGET_EXPR <");
887       dump_generic_node (buffer, TARGET_EXPR_SLOT (node), spc, flags, false);
888       pp_character (buffer, ',');
889       pp_space (buffer);
890       dump_generic_node (buffer, TARGET_EXPR_INITIAL (node), spc, flags, false);
891       pp_character (buffer, '>');
892       break;
893
894     case DECL_EXPR:
895       print_declaration (buffer, DECL_EXPR_DECL (node), spc, flags);
896       is_stmt = false;
897       break;
898
899     case COND_EXPR:
900       if (TREE_TYPE (node) == NULL || TREE_TYPE (node) == void_type_node)
901         {
902           pp_string (buffer, "if (");
903           dump_generic_node (buffer, COND_EXPR_COND (node), spc, flags, false);
904           pp_character (buffer, ')');
905           /* The lowered cond_exprs should always be printed in full.  */
906           if (COND_EXPR_THEN (node)
907               && (IS_EMPTY_STMT (COND_EXPR_THEN (node))
908                   || TREE_CODE (COND_EXPR_THEN (node)) == GOTO_EXPR)
909               && COND_EXPR_ELSE (node)
910               && (IS_EMPTY_STMT (COND_EXPR_ELSE (node))
911                   || TREE_CODE (COND_EXPR_ELSE (node)) == GOTO_EXPR))
912             {
913               pp_space (buffer);
914               dump_generic_node (buffer, COND_EXPR_THEN (node), 0, flags, true);
915               pp_string (buffer, " else ");
916               dump_generic_node (buffer, COND_EXPR_ELSE (node), 0, flags, true);
917             }
918           else if (!(flags & TDF_SLIM))
919             {
920               /* Output COND_EXPR_THEN.  */
921               if (COND_EXPR_THEN (node))
922                 {
923                   newline_and_indent (buffer, spc+2);
924                   pp_character (buffer, '{');
925                   newline_and_indent (buffer, spc+4);
926                   dump_generic_node (buffer, COND_EXPR_THEN (node), spc+4,
927                                      flags, true);
928                   newline_and_indent (buffer, spc+2);
929                   pp_character (buffer, '}');
930                 }
931
932               /* Output COND_EXPR_ELSE.  */
933               if (COND_EXPR_ELSE (node))
934                 {
935                   newline_and_indent (buffer, spc);
936                   pp_string (buffer, "else");
937                   newline_and_indent (buffer, spc+2);
938                   pp_character (buffer, '{');
939                   newline_and_indent (buffer, spc+4);
940                   dump_generic_node (buffer, COND_EXPR_ELSE (node), spc+4,
941                                      flags, true);
942                   newline_and_indent (buffer, spc+2);
943                   pp_character (buffer, '}');
944                 }
945             }
946           is_expr = false;
947         }
948       else
949         {
950           dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
951           pp_space (buffer);
952           pp_character (buffer, '?');
953           pp_space (buffer);
954           dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
955           pp_space (buffer);
956           pp_character (buffer, ':');
957           pp_space (buffer);
958           dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
959         }
960       break;
961
962     case BIND_EXPR:
963       pp_character (buffer, '{');
964       if (!(flags & TDF_SLIM))
965         {
966           if (BIND_EXPR_VARS (node))
967             {
968               pp_newline (buffer);
969
970               for (op0 = BIND_EXPR_VARS (node); op0; op0 = TREE_CHAIN (op0))
971                 {
972                   print_declaration (buffer, op0, spc+2, flags);
973                   pp_newline (buffer);
974                 }
975             }
976
977           newline_and_indent (buffer, spc+2);
978           dump_generic_node (buffer, BIND_EXPR_BODY (node), spc+2, flags, true);
979           newline_and_indent (buffer, spc);
980           pp_character (buffer, '}');
981         }
982       is_expr = false;
983       break;
984
985     case CALL_EXPR:
986       print_call_name (buffer, node);
987
988       /* Print parameters.  */
989       pp_space (buffer);
990       pp_character (buffer, '(');
991       op1 = TREE_OPERAND (node, 1);
992       if (op1)
993         dump_generic_node (buffer, op1, spc, flags, false);
994       pp_character (buffer, ')');
995
996       op1 = TREE_OPERAND (node, 2);
997       if (op1)
998         {
999           pp_string (buffer, " [static-chain: ");
1000           dump_generic_node (buffer, op1, spc, flags, false);
1001           pp_character (buffer, ']');
1002         }
1003
1004       if (CALL_EXPR_RETURN_SLOT_OPT (node))
1005         pp_string (buffer, " [return slot optimization]");
1006       if (CALL_EXPR_TAILCALL (node))
1007         pp_string (buffer, " [tail call]");
1008       break;
1009
1010     case WITH_CLEANUP_EXPR:
1011       NIY;
1012       break;
1013
1014     case CLEANUP_POINT_EXPR:
1015       pp_string (buffer, "<<cleanup_point ");
1016       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1017       pp_string (buffer, ">>");
1018       break;
1019
1020     case PLACEHOLDER_EXPR:
1021       pp_string (buffer, "<PLACEHOLDER_EXPR ");
1022       dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
1023       pp_character (buffer, '>');
1024       break;
1025
1026       /* Binary arithmetic and logic expressions.  */
1027     case MULT_EXPR:
1028     case PLUS_EXPR:
1029     case MINUS_EXPR:
1030     case TRUNC_DIV_EXPR:
1031     case CEIL_DIV_EXPR:
1032     case FLOOR_DIV_EXPR:
1033     case ROUND_DIV_EXPR:
1034     case TRUNC_MOD_EXPR:
1035     case CEIL_MOD_EXPR:
1036     case FLOOR_MOD_EXPR:
1037     case ROUND_MOD_EXPR:
1038     case RDIV_EXPR:
1039     case EXACT_DIV_EXPR:
1040     case LSHIFT_EXPR:
1041     case RSHIFT_EXPR:
1042     case LROTATE_EXPR:
1043     case RROTATE_EXPR:
1044     case VEC_LSHIFT_EXPR:
1045     case VEC_RSHIFT_EXPR:
1046     case BIT_IOR_EXPR:
1047     case BIT_XOR_EXPR:
1048     case BIT_AND_EXPR:
1049     case TRUTH_ANDIF_EXPR:
1050     case TRUTH_ORIF_EXPR:
1051     case TRUTH_AND_EXPR:
1052     case TRUTH_OR_EXPR:
1053     case TRUTH_XOR_EXPR:
1054     case LT_EXPR:
1055     case LE_EXPR:
1056     case GT_EXPR:
1057     case GE_EXPR:
1058     case EQ_EXPR:
1059     case NE_EXPR:
1060     case UNLT_EXPR:
1061     case UNLE_EXPR:
1062     case UNGT_EXPR:
1063     case UNGE_EXPR:
1064     case UNEQ_EXPR:
1065     case LTGT_EXPR:
1066     case ORDERED_EXPR:
1067     case UNORDERED_EXPR:
1068       {
1069         const char *op = op_symbol (node);
1070         op0 = TREE_OPERAND (node, 0);
1071         op1 = TREE_OPERAND (node, 1);
1072
1073         /* When the operands are expressions with less priority,
1074            keep semantics of the tree representation.  */
1075         if (op_prio (op0) < op_prio (node))
1076           {
1077             pp_character (buffer, '(');
1078             dump_generic_node (buffer, op0, spc, flags, false);
1079             pp_character (buffer, ')');
1080           }
1081         else
1082           dump_generic_node (buffer, op0, spc, flags, false);
1083
1084         pp_space (buffer);
1085         pp_string (buffer, op);
1086         pp_space (buffer);
1087
1088         /* When the operands are expressions with less priority,
1089            keep semantics of the tree representation.  */
1090         if (op_prio (op1) < op_prio (node))
1091           {
1092             pp_character (buffer, '(');
1093             dump_generic_node (buffer, op1, spc, flags, false);
1094             pp_character (buffer, ')');
1095           }
1096         else
1097           dump_generic_node (buffer, op1, spc, flags, false);
1098       }
1099       break;
1100
1101       /* Unary arithmetic and logic expressions.  */
1102     case NEGATE_EXPR:
1103     case BIT_NOT_EXPR:
1104     case TRUTH_NOT_EXPR:
1105     case ADDR_EXPR:
1106     case PREDECREMENT_EXPR:
1107     case PREINCREMENT_EXPR:
1108     case ALIGN_INDIRECT_REF:
1109     case MISALIGNED_INDIRECT_REF:
1110     case INDIRECT_REF:
1111       if (TREE_CODE (node) == ADDR_EXPR
1112           && (TREE_CODE (TREE_OPERAND (node, 0)) == STRING_CST
1113               || TREE_CODE (TREE_OPERAND (node, 0)) == FUNCTION_DECL))
1114         ;       /* Do not output '&' for strings and function pointers.  */
1115       else
1116         pp_string (buffer, op_symbol (node));
1117
1118       if (op_prio (TREE_OPERAND (node, 0)) < op_prio (node))
1119         {
1120           pp_character (buffer, '(');
1121           dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1122           pp_character (buffer, ')');
1123         }
1124       else
1125         dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1126
1127       if (TREE_CODE (node) == MISALIGNED_INDIRECT_REF)
1128         {
1129           pp_string (buffer, "{misalignment: ");
1130           dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1131           pp_character (buffer, '}');
1132         }
1133       break;
1134
1135     case POSTDECREMENT_EXPR:
1136     case POSTINCREMENT_EXPR:
1137       if (op_prio (TREE_OPERAND (node, 0)) < op_prio (node))
1138         {
1139           pp_character (buffer, '(');
1140           dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1141           pp_character (buffer, ')');
1142         }
1143       else
1144         dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1145       pp_string (buffer, op_symbol (node));
1146       break;
1147
1148     case MIN_EXPR:
1149       pp_string (buffer, "MIN_EXPR <");
1150       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1151       pp_string (buffer, ", ");
1152       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1153       pp_character (buffer, '>');
1154       break;
1155
1156     case MAX_EXPR:
1157       pp_string (buffer, "MAX_EXPR <");
1158       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1159       pp_string (buffer, ", ");
1160       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1161       pp_character (buffer, '>');
1162       break;
1163
1164     case ABS_EXPR:
1165       pp_string (buffer, "ABS_EXPR <");
1166       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1167       pp_character (buffer, '>');
1168       break;
1169
1170     case RANGE_EXPR:
1171       NIY;
1172       break;
1173
1174     case FIX_TRUNC_EXPR:
1175     case FIX_CEIL_EXPR:
1176     case FIX_FLOOR_EXPR:
1177     case FIX_ROUND_EXPR:
1178     case FLOAT_EXPR:
1179     case CONVERT_EXPR:
1180     case NOP_EXPR:
1181       type = TREE_TYPE (node);
1182       op0 = TREE_OPERAND (node, 0);
1183       if (type != TREE_TYPE (op0))
1184         {
1185           pp_character (buffer, '(');
1186           dump_generic_node (buffer, type, spc, flags, false);
1187           pp_string (buffer, ") ");
1188         }
1189       if (op_prio (op0) < op_prio (node))
1190         pp_character (buffer, '(');
1191       dump_generic_node (buffer, op0, spc, flags, false);
1192       if (op_prio (op0) < op_prio (node))
1193         pp_character (buffer, ')');
1194       break;
1195
1196     case VIEW_CONVERT_EXPR:
1197       pp_string (buffer, "VIEW_CONVERT_EXPR<");
1198       dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
1199       pp_string (buffer, ">(");
1200       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1201       pp_character (buffer, ')');
1202       break;
1203
1204     case NON_LVALUE_EXPR:
1205       pp_string (buffer, "NON_LVALUE_EXPR <");
1206       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1207       pp_character (buffer, '>');
1208       break;
1209
1210     case SAVE_EXPR:
1211       pp_string (buffer, "SAVE_EXPR <");
1212       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1213       pp_character (buffer, '>');
1214       break;
1215
1216     case COMPLEX_EXPR:
1217       pp_string (buffer, "COMPLEX_EXPR <");
1218       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1219       pp_string (buffer, ", ");
1220       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1221       pp_string (buffer, ">");
1222       break;
1223
1224     case CONJ_EXPR:
1225       pp_string (buffer, "CONJ_EXPR <");
1226       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1227       pp_string (buffer, ">");
1228       break;
1229
1230     case REALPART_EXPR:
1231       pp_string (buffer, "REALPART_EXPR <");
1232       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1233       pp_string (buffer, ">");
1234       break;
1235
1236     case IMAGPART_EXPR:
1237       pp_string (buffer, "IMAGPART_EXPR <");
1238       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1239       pp_string (buffer, ">");
1240       break;
1241
1242     case VA_ARG_EXPR:
1243       pp_string (buffer, "VA_ARG_EXPR <");
1244       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1245       pp_string (buffer, ">");
1246       break;
1247
1248     case TRY_FINALLY_EXPR:
1249     case TRY_CATCH_EXPR:
1250       pp_string (buffer, "try");
1251       newline_and_indent (buffer, spc+2);
1252       pp_string (buffer, "{");
1253       newline_and_indent (buffer, spc+4);
1254       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc+4, flags, true);
1255       newline_and_indent (buffer, spc+2);
1256       pp_string (buffer, "}");
1257       newline_and_indent (buffer, spc);
1258       pp_string (buffer,
1259                          (TREE_CODE (node) == TRY_CATCH_EXPR) ? "catch" : "finally");
1260       newline_and_indent (buffer, spc+2);
1261       pp_string (buffer, "{");
1262       newline_and_indent (buffer, spc+4);
1263       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc+4, flags, true);
1264       newline_and_indent (buffer, spc+2);
1265       pp_string (buffer, "}");
1266       is_expr = false;
1267       break;
1268
1269     case CATCH_EXPR:
1270       pp_string (buffer, "catch (");
1271       dump_generic_node (buffer, CATCH_TYPES (node), spc+2, flags, false);
1272       pp_string (buffer, ")");
1273       newline_and_indent (buffer, spc+2);
1274       pp_string (buffer, "{");
1275       newline_and_indent (buffer, spc+4);
1276       dump_generic_node (buffer, CATCH_BODY (node), spc+4, flags, true);
1277       newline_and_indent (buffer, spc+2);
1278       pp_string (buffer, "}");
1279       is_expr = false;
1280       break;
1281
1282     case EH_FILTER_EXPR:
1283       pp_string (buffer, "<<<eh_filter (");
1284       dump_generic_node (buffer, EH_FILTER_TYPES (node), spc+2, flags, false);
1285       pp_string (buffer, ")>>>");
1286       newline_and_indent (buffer, spc+2);
1287       pp_string (buffer, "{");
1288       newline_and_indent (buffer, spc+4);
1289       dump_generic_node (buffer, EH_FILTER_FAILURE (node), spc+4, flags, true);
1290       newline_and_indent (buffer, spc+2);
1291       pp_string (buffer, "}");
1292       is_expr = false;
1293       break;
1294
1295     case LABEL_EXPR:
1296       op0 = TREE_OPERAND (node, 0);
1297       /* If this is for break or continue, don't bother printing it.  */
1298       if (DECL_NAME (op0))
1299         {
1300           const char *name = IDENTIFIER_POINTER (DECL_NAME (op0));
1301           if (strcmp (name, "break") == 0
1302               || strcmp (name, "continue") == 0)
1303             break;
1304         }
1305       dump_generic_node (buffer, op0, spc, flags, false);
1306       pp_character (buffer, ':');
1307       if (DECL_NONLOCAL (op0))
1308         pp_string (buffer, " [non-local]");
1309       break;
1310
1311     case EXC_PTR_EXPR:
1312       pp_string (buffer, "<<<exception object>>>");
1313       break;
1314
1315     case FILTER_EXPR:
1316       pp_string (buffer, "<<<filter object>>>");
1317       break;
1318
1319     case LOOP_EXPR:
1320       pp_string (buffer, "while (1)");
1321       if (!(flags & TDF_SLIM))
1322         {
1323           newline_and_indent (buffer, spc+2);
1324           pp_character (buffer, '{');
1325           newline_and_indent (buffer, spc+4);
1326           dump_generic_node (buffer, LOOP_EXPR_BODY (node), spc+4, flags, true);
1327           newline_and_indent (buffer, spc+2);
1328           pp_character (buffer, '}');
1329         }
1330       is_expr = false;
1331       break;
1332
1333     case RETURN_EXPR:
1334       pp_string (buffer, "return");
1335       op0 = TREE_OPERAND (node, 0);
1336       if (op0)
1337         {
1338           pp_space (buffer);
1339           if (TREE_CODE (op0) == MODIFY_EXPR)
1340             dump_generic_node (buffer, TREE_OPERAND (op0, 1), spc, flags, false);
1341           else
1342             dump_generic_node (buffer, op0, spc, flags, false);
1343         }
1344       break;
1345
1346     case EXIT_EXPR:
1347       pp_string (buffer, "if (");
1348       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1349       pp_string (buffer, ") break");
1350       break;
1351
1352     case SWITCH_EXPR:
1353       pp_string (buffer, "switch (");
1354       dump_generic_node (buffer, SWITCH_COND (node), spc, flags, false);
1355       pp_character (buffer, ')');
1356       if (!(flags & TDF_SLIM))
1357         {
1358           newline_and_indent (buffer, spc+2);
1359           pp_character (buffer, '{');
1360           if (SWITCH_BODY (node))
1361             {
1362               newline_and_indent (buffer, spc+4);
1363               dump_generic_node (buffer, SWITCH_BODY (node), spc+4, flags, true);
1364             }
1365           else
1366             {
1367               tree vec = SWITCH_LABELS (node);
1368               size_t i, n = TREE_VEC_LENGTH (vec);
1369               for (i = 0; i < n; ++i)
1370                 {
1371                   tree elt = TREE_VEC_ELT (vec, i);
1372                   newline_and_indent (buffer, spc+4);
1373                   dump_generic_node (buffer, elt, spc+4, flags, false);
1374                   pp_string (buffer, " goto ");
1375                   dump_generic_node (buffer, CASE_LABEL (elt), spc+4, flags, true);
1376                   pp_semicolon (buffer);
1377                 }
1378             }
1379           newline_and_indent (buffer, spc+2);
1380           pp_character (buffer, '}');
1381         }
1382       is_expr = false;
1383       break;
1384
1385     case GOTO_EXPR:
1386       op0 = GOTO_DESTINATION (node);
1387       if (TREE_CODE (op0) != SSA_NAME && DECL_P (op0) && DECL_NAME (op0))
1388         {
1389           const char *name = IDENTIFIER_POINTER (DECL_NAME (op0));
1390           if (strcmp (name, "break") == 0
1391               || strcmp (name, "continue") == 0)
1392             {
1393               pp_string (buffer, name);
1394               break;
1395             }
1396         }
1397       pp_string (buffer, "goto ");
1398       dump_generic_node (buffer, op0, spc, flags, false);
1399       break;
1400
1401     case RESX_EXPR:
1402       pp_string (buffer, "resx");
1403       /* ??? Any sensible way to present the eh region?  */
1404       break;
1405
1406     case ASM_EXPR:
1407       pp_string (buffer, "__asm__");
1408       if (ASM_VOLATILE_P (node))
1409         pp_string (buffer, " __volatile__");
1410       pp_character (buffer, '(');
1411       dump_generic_node (buffer, ASM_STRING (node), spc, flags, false);
1412       pp_character (buffer, ':');
1413       dump_generic_node (buffer, ASM_OUTPUTS (node), spc, flags, false);
1414       pp_character (buffer, ':');
1415       dump_generic_node (buffer, ASM_INPUTS (node), spc, flags, false);
1416       if (ASM_CLOBBERS (node))
1417         {
1418           pp_character (buffer, ':');
1419           dump_generic_node (buffer, ASM_CLOBBERS (node), spc, flags, false);
1420         }
1421       pp_string (buffer, ")");
1422       break;
1423
1424     case CASE_LABEL_EXPR:
1425       if (CASE_LOW (node) && CASE_HIGH (node))
1426         {
1427           pp_string (buffer, "case ");
1428           dump_generic_node (buffer, CASE_LOW (node), spc, flags, false);
1429           pp_string (buffer, " ... ");
1430           dump_generic_node (buffer, CASE_HIGH (node), spc, flags, false);
1431         }
1432       else if (CASE_LOW (node))
1433         {
1434           pp_string (buffer, "case ");
1435           dump_generic_node (buffer, CASE_LOW (node), spc, flags, false);
1436         }
1437       else
1438         pp_string (buffer, "default ");
1439       pp_character (buffer, ':');
1440       break;
1441
1442     case OBJ_TYPE_REF:
1443       pp_string (buffer, "OBJ_TYPE_REF(");
1444       dump_generic_node (buffer, OBJ_TYPE_REF_EXPR (node), spc, flags, false);
1445       pp_character (buffer, ';');
1446       dump_generic_node (buffer, OBJ_TYPE_REF_OBJECT (node), spc, flags, false);
1447       pp_character (buffer, '-');
1448       pp_character (buffer, '>');
1449       dump_generic_node (buffer, OBJ_TYPE_REF_TOKEN (node), spc, flags, false);
1450       pp_character (buffer, ')');
1451       break;
1452
1453     case PHI_NODE:
1454       {
1455         int i;
1456
1457         dump_generic_node (buffer, PHI_RESULT (node), spc, flags, false);
1458         pp_string (buffer, " = PHI <");
1459         for (i = 0; i < PHI_NUM_ARGS (node); i++)
1460           {
1461             dump_generic_node (buffer, PHI_ARG_DEF (node, i), spc, flags, false);
1462             pp_string (buffer, "(");
1463             pp_decimal_int (buffer, PHI_ARG_EDGE (node, i)->src->index);
1464             pp_string (buffer, ")");
1465             if (i < PHI_NUM_ARGS (node) - 1)
1466               pp_string (buffer, ", ");
1467           }
1468         pp_string (buffer, ">;");
1469       }
1470       break;
1471
1472     case SSA_NAME:
1473       dump_generic_node (buffer, SSA_NAME_VAR (node), spc, flags, false);
1474       pp_string (buffer, "_");
1475       pp_decimal_int (buffer, SSA_NAME_VERSION (node));
1476       if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (node))
1477         pp_string (buffer, "(ab)");
1478       break;
1479
1480     case WITH_SIZE_EXPR:
1481       pp_string (buffer, "WITH_SIZE_EXPR <");
1482       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1483       pp_string (buffer, ", ");
1484       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1485       pp_string (buffer, ">");
1486       break;
1487
1488     case VALUE_HANDLE:
1489       pp_printf (buffer, "VH.%d", VALUE_HANDLE_ID (node));
1490       break;
1491
1492     case ASSERT_EXPR:
1493       pp_string (buffer, "ASSERT_EXPR <");
1494       dump_generic_node (buffer, ASSERT_EXPR_VAR (node), spc, flags, false);
1495       pp_string (buffer, ", ");
1496       dump_generic_node (buffer, ASSERT_EXPR_COND (node), spc, flags, false);
1497       pp_string (buffer, ">");
1498       break;
1499
1500     case SCEV_KNOWN:
1501       pp_string (buffer, "scev_known");
1502       break;
1503
1504     case SCEV_NOT_KNOWN:
1505       pp_string (buffer, "scev_not_known");
1506       break;
1507
1508     case POLYNOMIAL_CHREC:
1509       pp_string (buffer, "{");
1510       dump_generic_node (buffer, CHREC_LEFT (node), spc, flags, false);
1511       pp_string (buffer, ", +, ");
1512       dump_generic_node (buffer, CHREC_RIGHT (node), spc, flags, false);
1513       pp_string (buffer, "}_");
1514       dump_generic_node (buffer, CHREC_VAR (node), spc, flags, false);
1515       is_stmt = false;
1516       break;
1517
1518     case REALIGN_LOAD_EXPR:
1519       pp_string (buffer, "REALIGN_LOAD <");
1520       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1521       pp_string (buffer, ", ");
1522       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1523       pp_string (buffer, ", ");
1524       dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
1525       pp_string (buffer, ">");
1526       break;
1527       
1528     case VEC_COND_EXPR:
1529       pp_string (buffer, " VEC_COND_EXPR < ");
1530       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1531       pp_string (buffer, " , ");
1532       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1533       pp_string (buffer, " , ");
1534       dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
1535       pp_string (buffer, " > ");
1536       break;
1537
1538     case REDUC_MAX_EXPR:
1539       pp_string (buffer, " REDUC_MAX_EXPR < ");
1540       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1541       pp_string (buffer, " > ");
1542       break;
1543
1544     case REDUC_MIN_EXPR:
1545       pp_string (buffer, " REDUC_MIN_EXPR < ");
1546       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1547       pp_string (buffer, " > ");
1548       break;
1549
1550     case REDUC_PLUS_EXPR:
1551       pp_string (buffer, " REDUC_PLUS_EXPR < ");
1552       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1553       pp_string (buffer, " > ");
1554       break;
1555
1556     default:
1557       NIY;
1558     }
1559
1560   if (is_stmt && is_expr)
1561     pp_semicolon (buffer);
1562   pp_write_text_to_stream (buffer);
1563
1564   return spc;
1565 }
1566
1567 /* Print the declaration of a variable.  */
1568
1569 static void
1570 print_declaration (pretty_printer *buffer, tree t, int spc, int flags)
1571 {
1572   INDENT (spc);
1573
1574   if (TREE_CODE (t) == TYPE_DECL)
1575     pp_string (buffer, "typedef ");
1576
1577   if (CODE_CONTAINS_STRUCT (TREE_CODE (t), TS_DECL_WRTL) && DECL_REGISTER (t))
1578     pp_string (buffer, "register ");
1579
1580   if (TREE_PUBLIC (t) && DECL_EXTERNAL (t))
1581     pp_string (buffer, "extern ");
1582   else if (TREE_STATIC (t))
1583     pp_string (buffer, "static ");
1584
1585   /* Print the type and name.  */
1586   if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
1587     {
1588       tree tmp;
1589
1590       /* Print array's type.  */
1591       tmp = TREE_TYPE (t);
1592       while (TREE_CODE (TREE_TYPE (tmp)) == ARRAY_TYPE)
1593         tmp = TREE_TYPE (tmp);
1594       dump_generic_node (buffer, TREE_TYPE (tmp), spc, flags, false);
1595
1596       /* Print variable's name.  */
1597       pp_space (buffer);
1598       dump_generic_node (buffer, t, spc, flags, false);
1599
1600       /* Print the dimensions.  */
1601       tmp = TREE_TYPE (t);
1602       while (TREE_CODE (tmp) == ARRAY_TYPE)
1603         {
1604           dump_array_domain (buffer, TYPE_DOMAIN (tmp), spc, flags);
1605           tmp = TREE_TYPE (tmp);
1606         }
1607     }
1608   else if (TREE_CODE (t) == FUNCTION_DECL)
1609     {
1610       dump_generic_node (buffer, TREE_TYPE (TREE_TYPE (t)), spc, flags, false);
1611       pp_space (buffer);
1612       dump_decl_name (buffer, t, flags);
1613       dump_function_declaration (buffer, TREE_TYPE (t), spc, flags);
1614     }
1615   else
1616     {
1617       /* Print type declaration.  */
1618       dump_generic_node (buffer, TREE_TYPE (t), spc, flags, false);
1619
1620       /* Print variable's name.  */
1621       pp_space (buffer);
1622       dump_generic_node (buffer, t, spc, flags, false);
1623     }
1624
1625   if (TREE_CODE (t) == VAR_DECL && DECL_HARD_REGISTER (t))
1626     {
1627       pp_string (buffer, " __asm__ ");
1628       pp_character (buffer, '(');
1629       dump_generic_node (buffer, DECL_ASSEMBLER_NAME (t), spc, flags, false);
1630       pp_character (buffer, ')');
1631     }
1632
1633   /* The initial value of a function serves to determine wether the function
1634      is declared or defined.  So the following does not apply to function
1635      nodes.  */
1636   if (TREE_CODE (t) != FUNCTION_DECL)
1637     {
1638       /* Print the initial value.  */
1639       if (DECL_INITIAL (t))
1640         {
1641           pp_space (buffer);
1642           pp_character (buffer, '=');
1643           pp_space (buffer);
1644           dump_generic_node (buffer, DECL_INITIAL (t), spc, flags, false);
1645         }
1646     }
1647
1648   pp_character (buffer, ';');
1649 }
1650
1651
1652 /* Prints a structure: name, fields, and methods.
1653    FIXME: Still incomplete.  */
1654
1655 static void
1656 print_struct_decl (pretty_printer *buffer, tree node, int spc, int flags)
1657 {
1658   /* Print the name of the structure.  */
1659   if (TYPE_NAME (node))
1660     {
1661       INDENT (spc);
1662       if (TREE_CODE (node) == RECORD_TYPE)
1663         pp_string (buffer, "struct ");
1664       else if ((TREE_CODE (node) == UNION_TYPE
1665                 || TREE_CODE (node) == QUAL_UNION_TYPE))
1666         pp_string (buffer, "union ");
1667
1668       dump_generic_node (buffer, TYPE_NAME (node), spc, 0, false);
1669     }
1670
1671   /* Print the contents of the structure.  */
1672   pp_newline (buffer);
1673   INDENT (spc);
1674   pp_character (buffer, '{');
1675   pp_newline (buffer);
1676
1677   /* Print the fields of the structure.  */
1678   {
1679     tree tmp;
1680     tmp = TYPE_FIELDS (node);
1681     while (tmp)
1682       {
1683         /* Avoid to print recursively the structure.  */
1684         /* FIXME : Not implemented correctly...,
1685            what about the case when we have a cycle in the contain graph? ...
1686            Maybe this could be solved by looking at the scope in which the
1687            structure was declared.  */
1688         if (TREE_TYPE (tmp) != node
1689             || (TREE_CODE (TREE_TYPE (tmp)) == POINTER_TYPE
1690                 && TREE_TYPE (TREE_TYPE (tmp)) != node))
1691           {
1692             print_declaration (buffer, tmp, spc+2, flags);
1693             pp_newline (buffer);
1694           }
1695         tmp = TREE_CHAIN (tmp);
1696       }
1697   }
1698   INDENT (spc);
1699   pp_character (buffer, '}');
1700 }
1701
1702 /* Return the priority of the operator OP.
1703
1704    From lowest to highest precedence with either left-to-right (L-R)
1705    or right-to-left (R-L) associativity]:
1706
1707      1  [L-R] ,
1708      2  [R-L] = += -= *= /= %= &= ^= |= <<= >>=
1709      3  [R-L] ?:
1710      4  [L-R] ||
1711      5  [L-R] &&
1712      6  [L-R] |
1713      7  [L-R] ^
1714      8  [L-R] &
1715      9  [L-R] == !=
1716     10  [L-R] < <= > >=
1717     11  [L-R] << >>
1718     12  [L-R] + -
1719     13  [L-R] * / %
1720     14  [R-L] ! ~ ++ -- + - * & (type) sizeof
1721     15  [L-R] fn() [] -> .
1722
1723    unary +, - and * have higher precedence than the corresponding binary
1724    operators.  */
1725
1726 static int
1727 op_prio (tree op)
1728 {
1729   if (op == NULL)
1730     return 9999;
1731
1732   switch (TREE_CODE (op))
1733     {
1734     case TREE_LIST:
1735     case COMPOUND_EXPR:
1736     case BIND_EXPR:
1737       return 1;
1738
1739     case MODIFY_EXPR:
1740     case INIT_EXPR:
1741       return 2;
1742
1743     case COND_EXPR:
1744       return 3;
1745
1746     case TRUTH_OR_EXPR:
1747     case TRUTH_ORIF_EXPR:
1748       return 4;
1749
1750     case TRUTH_AND_EXPR:
1751     case TRUTH_ANDIF_EXPR:
1752       return 5;
1753
1754     case BIT_IOR_EXPR:
1755       return 6;
1756
1757     case BIT_XOR_EXPR:
1758     case TRUTH_XOR_EXPR:
1759       return 7;
1760
1761     case BIT_AND_EXPR:
1762       return 8;
1763
1764     case EQ_EXPR:
1765     case NE_EXPR:
1766       return 9;
1767
1768     case UNLT_EXPR:
1769     case UNLE_EXPR:
1770     case UNGT_EXPR:
1771     case UNGE_EXPR:
1772     case UNEQ_EXPR:
1773     case LTGT_EXPR:
1774     case ORDERED_EXPR:
1775     case UNORDERED_EXPR:
1776     case LT_EXPR:
1777     case LE_EXPR:
1778     case GT_EXPR:
1779     case GE_EXPR:
1780       return 10;
1781
1782     case LSHIFT_EXPR:
1783     case RSHIFT_EXPR:
1784     case LROTATE_EXPR:
1785     case RROTATE_EXPR:
1786       return 11;
1787
1788     case PLUS_EXPR:
1789     case MINUS_EXPR:
1790       return 12;
1791
1792     case MULT_EXPR:
1793     case TRUNC_DIV_EXPR:
1794     case CEIL_DIV_EXPR:
1795     case FLOOR_DIV_EXPR:
1796     case ROUND_DIV_EXPR:
1797     case RDIV_EXPR:
1798     case EXACT_DIV_EXPR:
1799     case TRUNC_MOD_EXPR:
1800     case CEIL_MOD_EXPR:
1801     case FLOOR_MOD_EXPR:
1802     case ROUND_MOD_EXPR:
1803       return 13;
1804
1805     case TRUTH_NOT_EXPR:
1806     case BIT_NOT_EXPR:
1807     case POSTINCREMENT_EXPR:
1808     case POSTDECREMENT_EXPR:
1809     case PREINCREMENT_EXPR:
1810     case PREDECREMENT_EXPR:
1811     case NEGATE_EXPR:
1812     case ALIGN_INDIRECT_REF:
1813     case MISALIGNED_INDIRECT_REF:
1814     case INDIRECT_REF:
1815     case ADDR_EXPR:
1816     case FLOAT_EXPR:
1817     case NOP_EXPR:
1818     case CONVERT_EXPR:
1819     case FIX_TRUNC_EXPR:
1820     case FIX_CEIL_EXPR:
1821     case FIX_FLOOR_EXPR:
1822     case FIX_ROUND_EXPR:
1823     case TARGET_EXPR:
1824       return 14;
1825
1826     case CALL_EXPR:
1827     case ARRAY_REF:
1828     case ARRAY_RANGE_REF:
1829     case COMPONENT_REF:
1830       return 15;
1831
1832       /* Special expressions.  */
1833     case MIN_EXPR:
1834     case MAX_EXPR:
1835     case ABS_EXPR:
1836     case REALPART_EXPR:
1837     case IMAGPART_EXPR:
1838     case REDUC_MAX_EXPR:
1839     case REDUC_MIN_EXPR:
1840     case REDUC_PLUS_EXPR:
1841     case VEC_LSHIFT_EXPR:
1842     case VEC_RSHIFT_EXPR:
1843       return 16;
1844
1845     case SAVE_EXPR:
1846     case NON_LVALUE_EXPR:
1847       return op_prio (TREE_OPERAND (op, 0));
1848
1849     default:
1850       /* Return an arbitrarily high precedence to avoid surrounding single
1851          VAR_DECLs in ()s.  */
1852       return 9999;
1853     }
1854 }
1855
1856
1857 /* Return the symbol associated with operator OP.  */
1858
1859 static const char *
1860 op_symbol (tree op)
1861 {
1862   gcc_assert (op);
1863
1864   switch (TREE_CODE (op))
1865     {
1866     case MODIFY_EXPR:
1867       return "=";
1868
1869     case TRUTH_OR_EXPR:
1870     case TRUTH_ORIF_EXPR:
1871       return "||";
1872
1873     case TRUTH_AND_EXPR:
1874     case TRUTH_ANDIF_EXPR:
1875       return "&&";
1876
1877     case BIT_IOR_EXPR:
1878       return "|";
1879
1880     case TRUTH_XOR_EXPR:
1881     case BIT_XOR_EXPR:
1882       return "^";
1883
1884     case ADDR_EXPR:
1885     case BIT_AND_EXPR:
1886       return "&";
1887
1888     case ORDERED_EXPR:
1889       return "ord";
1890     case UNORDERED_EXPR:
1891       return "unord";
1892
1893     case EQ_EXPR:
1894       return "==";
1895     case UNEQ_EXPR:
1896       return "u==";
1897
1898     case NE_EXPR:
1899       return "!=";
1900
1901     case LT_EXPR:
1902       return "<";
1903     case UNLT_EXPR:
1904       return "u<";
1905
1906     case LE_EXPR:
1907       return "<=";
1908     case UNLE_EXPR:
1909       return "u<=";
1910
1911     case GT_EXPR:
1912       return ">";
1913     case UNGT_EXPR:
1914       return "u>";
1915
1916     case GE_EXPR:
1917       return ">=";
1918     case UNGE_EXPR:
1919       return "u>=";
1920
1921     case LTGT_EXPR:
1922       return "<>";
1923
1924     case LSHIFT_EXPR:
1925       return "<<";
1926
1927     case RSHIFT_EXPR:
1928       return ">>";
1929
1930     case LROTATE_EXPR:
1931       return "r<<";
1932
1933     case RROTATE_EXPR:
1934       return "r>>";
1935
1936     case VEC_LSHIFT_EXPR:
1937       return "v<<";
1938
1939     case VEC_RSHIFT_EXPR:
1940       return "v>>";
1941  
1942     case PLUS_EXPR:
1943       return "+";
1944
1945     case REDUC_PLUS_EXPR:
1946       return "r+";
1947
1948     case NEGATE_EXPR:
1949     case MINUS_EXPR:
1950       return "-";
1951
1952     case BIT_NOT_EXPR:
1953       return "~";
1954
1955     case TRUTH_NOT_EXPR:
1956       return "!";
1957
1958     case MULT_EXPR:
1959     case INDIRECT_REF:
1960       return "*";
1961
1962     case ALIGN_INDIRECT_REF:
1963       return "A*";
1964
1965     case MISALIGNED_INDIRECT_REF:
1966       return "M*";
1967
1968     case TRUNC_DIV_EXPR:
1969     case RDIV_EXPR:
1970       return "/";
1971
1972     case CEIL_DIV_EXPR:
1973       return "/[cl]";
1974
1975     case FLOOR_DIV_EXPR:
1976       return "/[fl]";
1977
1978     case ROUND_DIV_EXPR:
1979       return "/[rd]";
1980
1981     case EXACT_DIV_EXPR:
1982       return "/[ex]";
1983
1984     case TRUNC_MOD_EXPR:
1985       return "%";
1986
1987     case CEIL_MOD_EXPR:
1988       return "%[cl]";
1989
1990     case FLOOR_MOD_EXPR:
1991       return "%[fl]";
1992
1993     case ROUND_MOD_EXPR:
1994       return "%[rd]";
1995
1996     case PREDECREMENT_EXPR:
1997       return " --";
1998
1999     case PREINCREMENT_EXPR:
2000       return " ++";
2001
2002     case POSTDECREMENT_EXPR:
2003       return "-- ";
2004
2005     case POSTINCREMENT_EXPR:
2006       return "++ ";
2007
2008     default:
2009       return "<<< ??? >>>";
2010     }
2011 }
2012
2013 /* Prints the name of a CALL_EXPR.  */
2014
2015 static void
2016 print_call_name (pretty_printer *buffer, tree node)
2017 {
2018   tree op0;
2019
2020   gcc_assert (TREE_CODE (node) == CALL_EXPR);
2021
2022   op0 = TREE_OPERAND (node, 0);
2023
2024   if (TREE_CODE (op0) == NON_LVALUE_EXPR)
2025     op0 = TREE_OPERAND (op0, 0);
2026
2027   switch (TREE_CODE (op0))
2028     {
2029     case VAR_DECL:
2030     case PARM_DECL:
2031       dump_function_name (buffer, op0);
2032       break;
2033
2034     case ADDR_EXPR:
2035     case INDIRECT_REF:
2036     case NOP_EXPR:
2037       dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
2038       break;
2039
2040     case COND_EXPR:
2041       pp_string (buffer, "(");
2042       dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
2043       pp_string (buffer, ") ? ");
2044       dump_generic_node (buffer, TREE_OPERAND (op0, 1), 0, 0, false);
2045       pp_string (buffer, " : ");
2046       dump_generic_node (buffer, TREE_OPERAND (op0, 2), 0, 0, false);
2047       break;
2048
2049     case COMPONENT_REF:
2050       /* The function is a pointer contained in a structure.  */
2051       if (TREE_CODE (TREE_OPERAND (op0, 0)) == INDIRECT_REF ||
2052           TREE_CODE (TREE_OPERAND (op0, 0)) == VAR_DECL)
2053         dump_function_name (buffer, TREE_OPERAND (op0, 1));
2054       else
2055         dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
2056       /* else
2057          We can have several levels of structures and a function
2058          pointer inside.  This is not implemented yet...  */
2059       /*                  NIY;*/
2060       break;
2061
2062     case ARRAY_REF:
2063       if (TREE_CODE (TREE_OPERAND (op0, 0)) == VAR_DECL)
2064         dump_function_name (buffer, TREE_OPERAND (op0, 0));
2065       else
2066         dump_generic_node (buffer, op0, 0, 0, false);
2067       break;
2068
2069     case SSA_NAME:
2070     case OBJ_TYPE_REF:
2071       dump_generic_node (buffer, op0, 0, 0, false);
2072       break;
2073
2074     default:
2075       NIY;
2076     }
2077 }
2078
2079 /* Parses the string STR and replaces new-lines by '\n', tabs by '\t', ...  */
2080
2081 static void
2082 pretty_print_string (pretty_printer *buffer, const char *str)
2083 {
2084   if (str == NULL)
2085     return;
2086
2087   while (*str)
2088     {
2089       switch (str[0])
2090         {
2091         case '\b':
2092           pp_string (buffer, "\\b");
2093           break;
2094
2095         case '\f':
2096           pp_string (buffer, "\\f");
2097           break;
2098
2099         case '\n':
2100           pp_string (buffer, "\\n");
2101           break;
2102
2103         case '\r':
2104           pp_string (buffer, "\\r");
2105           break;
2106
2107         case '\t':
2108           pp_string (buffer, "\\t");
2109           break;
2110
2111         case '\v':
2112           pp_string (buffer, "\\v");
2113           break;
2114
2115         case '\\':
2116           pp_string (buffer, "\\\\");
2117           break;
2118
2119         case '\"':
2120           pp_string (buffer, "\\\"");
2121           break;
2122
2123         case '\'':
2124           pp_string (buffer, "\\'");
2125           break;
2126
2127         case '\0':
2128           pp_string (buffer, "\\0");
2129           break;
2130
2131         case '\1':
2132           pp_string (buffer, "\\1");
2133           break;
2134
2135         case '\2':
2136           pp_string (buffer, "\\2");
2137           break;
2138
2139         case '\3':
2140           pp_string (buffer, "\\3");
2141           break;
2142
2143         case '\4':
2144           pp_string (buffer, "\\4");
2145           break;
2146
2147         case '\5':
2148           pp_string (buffer, "\\5");
2149           break;
2150
2151         case '\6':
2152           pp_string (buffer, "\\6");
2153           break;
2154
2155         case '\7':
2156           pp_string (buffer, "\\7");
2157           break;
2158
2159         default:
2160           pp_character (buffer, str[0]);
2161           break;
2162         }
2163       str++;
2164     }
2165 }
2166
2167 static void
2168 maybe_init_pretty_print (FILE *file)
2169 {
2170   if (!initialized)
2171     {
2172       pp_construct (&buffer, /* prefix */NULL, /* line-width */0);
2173       pp_needs_newline (&buffer) = true;
2174       initialized = 1;
2175     }
2176
2177   buffer.buffer->stream = file;
2178 }
2179
2180 static void
2181 newline_and_indent (pretty_printer *buffer, int spc)
2182 {
2183   pp_newline (buffer);
2184   INDENT (spc);
2185 }
2186
2187 static void
2188 dump_vops (pretty_printer *buffer, tree stmt, int spc, int flags)
2189 {
2190   tree use;
2191   use_operand_p use_p;
2192   def_operand_p def_p;
2193   use_operand_p kill_p;
2194   ssa_op_iter iter;
2195
2196   if (!ssa_operands_active ())
2197     return;
2198
2199   FOR_EACH_SSA_MAYDEF_OPERAND (def_p, use_p, stmt, iter)
2200     {
2201       pp_string (buffer, "#   ");
2202       dump_generic_node (buffer, DEF_FROM_PTR (def_p),
2203                          spc + 2, flags, false);
2204       pp_string (buffer, " = V_MAY_DEF <");
2205       dump_generic_node (buffer, USE_FROM_PTR (use_p),
2206                          spc + 2, flags, false);
2207       pp_string (buffer, ">;");
2208       newline_and_indent (buffer, spc);
2209     }
2210
2211   FOR_EACH_SSA_MUSTDEF_OPERAND (def_p, kill_p, stmt, iter)
2212     {
2213       pp_string (buffer, "#   ");
2214       dump_generic_node (buffer, DEF_FROM_PTR (def_p),
2215                          spc + 2, flags, false);
2216       pp_string (buffer, " = V_MUST_DEF <");
2217       dump_generic_node (buffer, USE_FROM_PTR (kill_p),
2218                          spc + 2, flags, false);
2219       pp_string (buffer, ">;");
2220       newline_and_indent (buffer, spc);
2221     }
2222
2223   FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_VUSE)
2224     {
2225       pp_string (buffer, "#   VUSE <");
2226       dump_generic_node (buffer, use, spc + 2, flags, false);
2227       pp_string (buffer, ">;");
2228       newline_and_indent (buffer, spc);
2229     }
2230 }
2231
2232 /* Dumps basic block BB to FILE with details described by FLAGS and
2233    indented by INDENT spaces.  */
2234
2235 void
2236 dump_generic_bb (FILE *file, basic_block bb, int indent, int flags)
2237 {
2238   maybe_init_pretty_print (file);
2239   dumping_stmts = true;
2240   dump_generic_bb_buff (&buffer, bb, indent, flags);
2241   pp_flush (&buffer);
2242 }
2243
2244 /* Dumps header of basic block BB to buffer BUFFER indented by INDENT
2245    spaces and details described by flags.  */
2246
2247 static void
2248 dump_bb_header (pretty_printer *buffer, basic_block bb, int indent, int flags)
2249 {
2250   edge e;
2251   tree stmt;
2252   edge_iterator ei;
2253
2254   if (flags & TDF_BLOCKS)
2255     {
2256       INDENT (indent);
2257       pp_string (buffer, "# BLOCK ");
2258       pp_decimal_int (buffer, bb->index);
2259       if (bb->frequency)
2260         {
2261           pp_string (buffer, " freq:");
2262           pp_decimal_int (buffer, bb->frequency);
2263         }
2264       if (bb->count)
2265         {
2266           pp_string (buffer, " count:");
2267           pp_widest_integer (buffer, bb->count);
2268         }
2269
2270       if (flags & TDF_LINENO)
2271         {
2272           block_stmt_iterator bsi;
2273
2274           for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
2275             if (get_lineno (bsi_stmt (bsi)) != -1)
2276               {
2277                 pp_string (buffer, ", starting at line ");
2278                 pp_decimal_int (buffer, get_lineno (bsi_stmt (bsi)));
2279                 break;
2280               }
2281         }
2282       newline_and_indent (buffer, indent);
2283
2284       pp_string (buffer, "# PRED:");
2285       pp_write_text_to_stream (buffer);
2286       FOR_EACH_EDGE (e, ei, bb->preds)
2287         if (flags & TDF_SLIM)
2288           {
2289             pp_string (buffer, " ");
2290             if (e->src == ENTRY_BLOCK_PTR)
2291               pp_string (buffer, "ENTRY");
2292             else
2293               pp_decimal_int (buffer, e->src->index);
2294           }
2295         else
2296           dump_edge_info (buffer->buffer->stream, e, 0);
2297       pp_newline (buffer);
2298     }
2299   else
2300     {
2301       stmt = first_stmt (bb);
2302       if (!stmt || TREE_CODE (stmt) != LABEL_EXPR)
2303         {
2304           INDENT (indent - 2);
2305           pp_string (buffer, "<bb ");
2306           pp_decimal_int (buffer, bb->index);
2307           pp_string (buffer, ">:");
2308           pp_newline (buffer);
2309         }
2310     }
2311   pp_write_text_to_stream (buffer);
2312   check_bb_profile (bb, buffer->buffer->stream);
2313 }
2314
2315 /* Dumps end of basic block BB to buffer BUFFER indented by INDENT
2316    spaces.  */
2317
2318 static void
2319 dump_bb_end (pretty_printer *buffer, basic_block bb, int indent, int flags)
2320 {
2321   edge e;
2322   edge_iterator ei;
2323
2324   INDENT (indent);
2325   pp_string (buffer, "# SUCC:");
2326   pp_write_text_to_stream (buffer);
2327   FOR_EACH_EDGE (e, ei, bb->succs)
2328     if (flags & TDF_SLIM)
2329       {
2330         pp_string (buffer, " ");
2331         if (e->dest == EXIT_BLOCK_PTR)
2332           pp_string (buffer, "EXIT");
2333         else
2334           pp_decimal_int (buffer, e->dest->index);
2335       }
2336     else
2337       dump_edge_info (buffer->buffer->stream, e, 1);
2338   pp_newline (buffer);
2339 }
2340
2341 /* Dumps phi nodes of basic block BB to buffer BUFFER with details described by
2342    FLAGS indented by INDENT spaces.  */
2343
2344 static void
2345 dump_phi_nodes (pretty_printer *buffer, basic_block bb, int indent, int flags)
2346 {
2347   tree phi = phi_nodes (bb);
2348   if (!phi)
2349     return;
2350
2351   for (; phi; phi = PHI_CHAIN (phi))
2352     {
2353       if (is_gimple_reg (PHI_RESULT (phi)) || (flags & TDF_VOPS))
2354         {
2355           INDENT (indent);
2356           pp_string (buffer, "# ");
2357           dump_generic_node (buffer, phi, indent, flags, false);
2358           pp_newline (buffer);
2359         }
2360     }
2361 }
2362
2363 /* Dump jump to basic block BB that is represented implicitly in the cfg
2364    to BUFFER.  */
2365
2366 static void
2367 pp_cfg_jump (pretty_printer *buffer, basic_block bb)
2368 {
2369   tree stmt;
2370
2371   stmt = first_stmt (bb);
2372
2373   pp_string (buffer, "goto <bb ");
2374   pp_decimal_int (buffer, bb->index);
2375   pp_string (buffer, ">");
2376   if (stmt && TREE_CODE (stmt) == LABEL_EXPR)
2377     {
2378       pp_string (buffer, " (");
2379       dump_generic_node (buffer, LABEL_EXPR_LABEL (stmt), 0, 0, false);
2380       pp_string (buffer, ")");
2381     }
2382   pp_semicolon (buffer);
2383 }
2384
2385 /* Dump edges represented implicitly in basic block BB to BUFFER, indented
2386    by INDENT spaces, with details given by FLAGS.  */
2387
2388 static void
2389 dump_implicit_edges (pretty_printer *buffer, basic_block bb, int indent,
2390                      int flags)
2391 {
2392   edge e;
2393   edge_iterator ei;
2394
2395   /* If there is a fallthru edge, we may need to add an artificial goto to the
2396      dump.  */
2397   FOR_EACH_EDGE (e, ei, bb->succs)
2398     if (e->flags & EDGE_FALLTHRU)
2399       break;
2400   if (e && e->dest != bb->next_bb)
2401     {
2402       INDENT (indent);
2403
2404       if ((flags & TDF_LINENO)
2405 #ifdef USE_MAPPED_LOCATION
2406           && e->goto_locus != UNKNOWN_LOCATION
2407 #else
2408           && e->goto_locus
2409 #endif
2410           )
2411         {
2412           expanded_location goto_xloc;
2413 #ifdef USE_MAPPED_LOCATION
2414           goto_xloc = expand_location (e->goto_locus);
2415 #else
2416           goto_xloc = *e->goto_locus;
2417 #endif
2418           pp_character (buffer, '[');
2419           if (goto_xloc.file)
2420             {
2421               pp_string (buffer, goto_xloc.file);
2422               pp_string (buffer, " : ");
2423             }
2424           pp_decimal_int (buffer, goto_xloc.line);
2425           pp_string (buffer, "] ");
2426         }
2427
2428       pp_cfg_jump (buffer, e->dest);
2429       pp_newline (buffer);
2430     }
2431 }
2432
2433 /* Dumps basic block BB to buffer BUFFER with details described by FLAGS and
2434    indented by INDENT spaces.  */
2435
2436 static void
2437 dump_generic_bb_buff (pretty_printer *buffer, basic_block bb,
2438                       int indent, int flags)
2439 {
2440   block_stmt_iterator bsi;
2441   tree stmt;
2442   int label_indent = indent - 2;
2443
2444   if (label_indent < 0)
2445     label_indent = 0;
2446
2447   dump_bb_header (buffer, bb, indent, flags);
2448
2449   dump_phi_nodes (buffer, bb, indent, flags);
2450
2451   for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
2452     {
2453       int curr_indent;
2454
2455       stmt = bsi_stmt (bsi);
2456
2457       curr_indent = TREE_CODE (stmt) == LABEL_EXPR ? label_indent : indent;
2458
2459       INDENT (curr_indent);
2460       dump_generic_node (buffer, stmt, curr_indent, flags, true);
2461       pp_newline (buffer);
2462     }
2463
2464   dump_implicit_edges (buffer, bb, indent, flags);
2465
2466   if (flags & TDF_BLOCKS)
2467     dump_bb_end (buffer, bb, indent, flags);
2468 }