OSDN Git Service

* config/i386/i386.c (TARGET_MANGLE_FUNDAMENTAL_TYPE): Define.
[pf3gnuchains/gcc-fork.git] / gcc / tree-pretty-print.c
1 /* Pretty formatting of GENERIC trees in C syntax.
2    Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
3    Adapted from c-pretty-print.c by Diego Novillo <dnovillo@redhat.com>
4
5 This file is part of GCC.
6
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
10 version.
11
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15 for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING.  If not, write to the Free
19 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
20 02111-1307, USA.  */
21
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tm.h"
26 #include "tree.h"
27 #include "diagnostic.h"
28 #include "real.h"
29 #include "hashtab.h"
30 #include "tree-flow.h"
31 #include "langhooks.h"
32 #include "tree-iterator.h"
33 #include "tree-chrec.h"
34
35 /* Local functions, macros and variables.  */
36 static int op_prio (tree);
37 static const char *op_symbol (tree);
38 static void pretty_print_string (pretty_printer *, const char*);
39 static void print_call_name (pretty_printer *, tree);
40 static void newline_and_indent (pretty_printer *, int);
41 static void maybe_init_pretty_print (FILE *);
42 static void print_declaration (pretty_printer *, tree, int, int);
43 static void print_struct_decl (pretty_printer *, tree, int, int);
44 static void do_niy (pretty_printer *, tree);
45 static void dump_vops (pretty_printer *, tree, int, int);
46 static void dump_generic_bb_buff (pretty_printer *, basic_block, int, int);
47
48 #define INDENT(SPACE) do { \
49   int i; for (i = 0; i<SPACE; i++) pp_space (buffer); } while (0)
50
51 #define NIY do_niy(buffer,node)
52
53 #define PRINT_FUNCTION_NAME(NODE)  pp_printf             \
54   (buffer, "%s", TREE_CODE (NODE) == NOP_EXPR ?              \
55    lang_hooks.decl_printable_name (TREE_OPERAND (NODE, 0), 1) : \
56    lang_hooks.decl_printable_name (NODE, 1))
57
58 static pretty_printer buffer;
59 static int initialized = 0;
60 static bool dumping_stmts;
61
62 /* Try to print something for an unknown tree code.  */
63
64 static void
65 do_niy (pretty_printer *buffer, tree node)
66 {
67   int i, len;
68
69   pp_string (buffer, "<<< Unknown tree: ");
70   pp_string (buffer, tree_code_name[(int) TREE_CODE (node)]);
71
72   if (EXPR_P (node))
73     {
74       len = TREE_CODE_LENGTH (TREE_CODE (node));
75       for (i = 0; i < len; ++i)
76         {
77           newline_and_indent (buffer, 2);
78           dump_generic_node (buffer, TREE_OPERAND (node, i), 2, 0, false);
79         }
80     }
81
82   pp_string (buffer, " >>>\n");
83 }
84
85 void
86 debug_generic_expr (tree t)
87 {
88   print_generic_expr (stderr, t, TDF_VOPS|TDF_UID);
89   fprintf (stderr, "\n");
90 }
91
92 void
93 debug_generic_stmt (tree t)
94 {
95   print_generic_stmt (stderr, t, TDF_VOPS|TDF_UID);
96   fprintf (stderr, "\n");
97 }
98
99 /* Prints declaration DECL to the FILE with details specified by FLAGS.  */
100 void
101 print_generic_decl (FILE *file, tree decl, int flags)
102 {
103   maybe_init_pretty_print (file);
104   dumping_stmts = true;
105   print_declaration (&buffer, decl, 2, flags);
106   pp_write_text_to_stream (&buffer);
107 }
108
109 /* Print tree T, and its successors, on file FILE.  FLAGS specifies details
110    to show in the dump.  See TDF_* in tree.h.  */
111
112 void
113 print_generic_stmt (FILE *file, tree t, int flags)
114 {
115   maybe_init_pretty_print (file);
116   dumping_stmts = true;
117   dump_generic_node (&buffer, t, 0, flags, true);
118   pp_flush (&buffer);
119 }
120
121 /* Print tree T, and its successors, on file FILE.  FLAGS specifies details
122    to show in the dump.  See TDF_* in tree.h.  The output is indented by
123    INDENT spaces.  */
124
125 void
126 print_generic_stmt_indented (FILE *file, tree t, int flags, int indent)
127 {
128   int i;
129
130   maybe_init_pretty_print (file);
131   dumping_stmts = true;
132
133   for (i = 0; i < indent; i++)
134     pp_space (&buffer);
135   dump_generic_node (&buffer, t, indent, flags, true);
136   pp_flush (&buffer);
137 }
138
139 /* Print a single expression T on file FILE.  FLAGS specifies details to show
140    in the dump.  See TDF_* in tree.h.  */
141
142 void
143 print_generic_expr (FILE *file, tree t, int flags)
144 {
145   maybe_init_pretty_print (file);
146   dumping_stmts = false;
147   dump_generic_node (&buffer, t, 0, flags, false);
148 }
149
150 /* Dump the name of a _DECL node and its DECL_UID if TDF_UID is set
151    in FLAGS.  */
152
153 static void
154 dump_decl_name (pretty_printer *buffer, tree node, int flags)
155 {
156   if (DECL_NAME (node))
157     pp_tree_identifier (buffer, DECL_NAME (node));
158
159   if ((flags & TDF_UID)
160       || DECL_NAME (node) == NULL_TREE)
161     {
162       if (TREE_CODE (node) == LABEL_DECL
163           && LABEL_DECL_UID (node) != -1)
164         pp_printf (buffer, "L." HOST_WIDE_INT_PRINT_DEC,
165                    LABEL_DECL_UID (node));
166       else
167         {
168           char c = TREE_CODE (node) == CONST_DECL ? 'C' : 'D';
169           pp_printf (buffer, "%c.%u", c, DECL_UID (node));
170         }
171     }
172 }
173
174 /* Like the above, but used for pretty printing function calls.  */
175
176 static void
177 dump_function_name (pretty_printer *buffer, tree node)
178 {
179   if (DECL_NAME (node))
180     PRINT_FUNCTION_NAME (node);
181   else
182     dump_decl_name (buffer, node, 0);
183 }
184
185 /* Dump a function declaration.  NODE is the FUNCTION_TYPE.  BUFFER, SPC and
186    FLAGS are as in dump_generic_node.  */
187
188 static void
189 dump_function_declaration (pretty_printer *buffer, tree node,
190                            int spc, int flags)
191 {
192   bool wrote_arg = false;
193   tree arg;
194
195   pp_space (buffer);
196   pp_character (buffer, '(');
197
198   /* Print the argument types.  The last element in the list is a VOID_TYPE.
199      The following avoids printing the last element.  */
200   arg = TYPE_ARG_TYPES (node);
201   while (arg && TREE_CHAIN (arg) && arg != error_mark_node)
202     {
203       wrote_arg = true;
204       dump_generic_node (buffer, TREE_VALUE (arg), spc, flags, false);
205       arg = TREE_CHAIN (arg);
206       if (TREE_CHAIN (arg) && TREE_CODE (TREE_CHAIN (arg)) == TREE_LIST)
207         {
208           pp_character (buffer, ',');
209           pp_space (buffer);
210         }
211     }
212
213   if (!wrote_arg)
214     pp_string (buffer, "void");
215
216   pp_character (buffer, ')');
217 }
218
219 /* Dump the domain associated with an array.  */
220
221 static void
222 dump_array_domain (pretty_printer *buffer, tree domain, int spc, int flags)
223 {
224   pp_character (buffer, '[');
225   if (domain)
226     {
227       tree min = TYPE_MIN_VALUE (domain);
228       tree max = TYPE_MAX_VALUE (domain);
229
230       if (min && max
231           && integer_zerop (min)
232           && host_integerp (max, 0))
233         pp_wide_integer (buffer, TREE_INT_CST_LOW (max) + 1);
234       else
235         {
236           if (min)
237             dump_generic_node (buffer, min, spc, flags, false);
238           pp_character (buffer, ':');
239           if (max)
240             dump_generic_node (buffer, max, spc, flags, false);
241         }
242     }
243   else
244     pp_string (buffer, "<unknown>");
245   pp_character (buffer, ']');
246 }
247
248 /* Dump the node NODE on the pretty_printer BUFFER, SPC spaces of indent.
249    FLAGS specifies details to show in the dump (see TDF_* in tree.h).  If
250    IS_STMT is true, the object printed is considered to be a statement
251    and it is terminated by ';' if appropriate.  */
252
253 int
254 dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
255                    bool is_stmt)
256 {
257   tree type;
258   tree op0, op1;
259   const char *str;
260   bool is_expr;
261
262   if (node == NULL_TREE)
263     return spc;
264
265   is_expr = EXPR_P (node);
266
267   if (TREE_CODE (node) != ERROR_MARK
268       && is_gimple_stmt (node)
269       && (flags & TDF_VOPS)
270       && stmt_ann (node))
271     dump_vops (buffer, node, spc, flags);
272
273   if (is_stmt && (flags & TDF_STMTADDR))
274     pp_printf (buffer, "<&%p> ", (void *)node);
275
276   if (dumping_stmts
277       && (flags & TDF_LINENO)
278       && EXPR_HAS_LOCATION (node))
279     {
280       expanded_location xloc = expand_location (EXPR_LOCATION (node));
281       pp_character (buffer, '[');
282       if (xloc.file)
283         {
284           pp_string (buffer, xloc.file);
285           pp_string (buffer, " : ");
286         }
287       pp_decimal_int (buffer, xloc.line);
288       pp_string (buffer, "] ");
289     }
290
291   switch (TREE_CODE (node))
292     {
293     case ERROR_MARK:
294       pp_string (buffer, "<<< error >>>");
295       break;
296
297     case IDENTIFIER_NODE:
298       pp_tree_identifier (buffer, node);
299       break;
300
301     case TREE_LIST:
302       while (node && node != error_mark_node)
303         {
304           if (TREE_PURPOSE (node))
305             {
306               dump_generic_node (buffer, TREE_PURPOSE (node), spc, flags, false);
307               pp_space (buffer);
308             }
309           dump_generic_node (buffer, TREE_VALUE (node), spc, flags, false);
310           node = TREE_CHAIN (node);
311           if (node && TREE_CODE (node) == TREE_LIST)
312             {
313               pp_character (buffer, ',');
314               pp_space (buffer);
315             }
316         }
317       break;
318
319     case TREE_BINFO:
320       dump_generic_node (buffer, BINFO_TYPE (node), spc, flags, false);
321
322     case TREE_VEC:
323       {
324         size_t i;
325         if (TREE_VEC_LENGTH (node) > 0)
326           {
327             size_t len = TREE_VEC_LENGTH (node);
328             for (i = 0; i < len - 1; i++)
329               {     
330                 dump_generic_node (buffer, TREE_VEC_ELT (node, i), spc, flags,
331                                    false);
332                 pp_character (buffer, ',');
333                 pp_space (buffer);
334               }
335             dump_generic_node (buffer, TREE_VEC_ELT (node, len - 1), spc, 
336                                flags, false);
337           }
338       }
339       break;
340
341     case BLOCK:
342       NIY;
343       break;
344
345     case VOID_TYPE:
346     case INTEGER_TYPE:
347     case REAL_TYPE:
348     case COMPLEX_TYPE:
349     case VECTOR_TYPE:
350     case ENUMERAL_TYPE:
351     case BOOLEAN_TYPE:
352     case CHAR_TYPE:
353       {
354         unsigned int quals = TYPE_QUALS (node);
355         enum tree_code_class class;
356
357         if (quals & TYPE_QUAL_CONST)
358           pp_string (buffer, "const ");
359         else if (quals & TYPE_QUAL_VOLATILE)
360           pp_string (buffer, "volatile ");
361         else if (quals & TYPE_QUAL_RESTRICT)
362           pp_string (buffer, "restrict ");
363
364         class = TREE_CODE_CLASS (TREE_CODE (node));
365
366         if (class == tcc_declaration)
367           {
368             if (DECL_NAME (node))
369               dump_decl_name (buffer, node, flags);
370             else
371               pp_string (buffer, "<unnamed type decl>");
372           }
373         else if (class == tcc_type)
374           {
375             if (TYPE_NAME (node))
376               {
377                 if (TREE_CODE (TYPE_NAME (node)) == IDENTIFIER_NODE)
378                   pp_tree_identifier (buffer, TYPE_NAME (node));
379                 else if (TREE_CODE (TYPE_NAME (node)) == TYPE_DECL
380                          && DECL_NAME (TYPE_NAME (node)))
381                   dump_decl_name (buffer, TYPE_NAME (node), flags);
382                 else
383                   pp_string (buffer, "<unnamed type>");
384               }
385             else if (TREE_CODE (node) == VECTOR_TYPE)
386               {
387                 pp_string (buffer, "vector ");
388                 dump_generic_node (buffer, TREE_TYPE (node), 
389                                    spc, flags, false);
390               }
391             else
392               pp_string (buffer, "<unnamed type>");
393           }
394         break;
395       }
396
397     case POINTER_TYPE:
398     case REFERENCE_TYPE:
399       str = (TREE_CODE (node) == POINTER_TYPE ? "*" : "&");
400
401       if (TREE_CODE (TREE_TYPE (node)) == FUNCTION_TYPE)
402         {
403           tree fnode = TREE_TYPE (node);
404
405           dump_generic_node (buffer, TREE_TYPE (fnode), spc, flags, false);
406           pp_space (buffer);
407           pp_character (buffer, '(');
408           pp_string (buffer, str);
409           if (TYPE_NAME (node) && DECL_NAME (TYPE_NAME (node)))
410             dump_decl_name (buffer, TYPE_NAME (node), flags);
411           else
412             pp_printf (buffer, "<T%x>", TYPE_UID (node));
413
414           pp_character (buffer, ')');
415           dump_function_declaration (buffer, fnode, spc, flags);
416         }
417       else
418         {
419           unsigned int quals = TYPE_QUALS (node);
420
421           dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
422           pp_space (buffer);
423           pp_string (buffer, str);
424
425           if (quals & TYPE_QUAL_CONST)
426             pp_string (buffer, " const");
427           else if (quals & TYPE_QUAL_VOLATILE)
428             pp_string (buffer,  "volatile");
429           else if (quals & TYPE_QUAL_RESTRICT)
430             pp_string (buffer, " restrict");
431
432           if (TYPE_REF_CAN_ALIAS_ALL (node))
433             pp_string (buffer, " {ref-all}");
434         }
435       break;
436
437     case OFFSET_TYPE:
438       NIY;
439       break;
440
441     case METHOD_TYPE:
442       dump_decl_name (buffer, TYPE_NAME (TYPE_METHOD_BASETYPE (node)), flags);
443       pp_string (buffer, "::");
444       break;
445
446     case TARGET_MEM_REF:
447       {
448         const char *sep = "";
449         tree tmp;
450
451         pp_string (buffer, "MEM[");
452
453         tmp = TMR_SYMBOL (node);
454         if (tmp)
455           {
456             pp_string (buffer, sep);
457             sep = ", ";
458             pp_string (buffer, "symbol: ");
459             dump_generic_node (buffer, tmp, spc, flags, false);
460           }
461         tmp = TMR_BASE (node);
462         if (tmp)
463           {
464             pp_string (buffer, sep);
465             sep = ", ";
466             pp_string (buffer, "base: ");
467             dump_generic_node (buffer, tmp, spc, flags, false);
468           }
469         tmp = TMR_INDEX (node);
470         if (tmp)
471           {
472             pp_string (buffer, sep);
473             sep = ", ";
474             pp_string (buffer, "index: ");
475             dump_generic_node (buffer, tmp, spc, flags, false);
476           }
477         tmp = TMR_STEP (node);
478         if (tmp)
479           {
480             pp_string (buffer, sep);
481             sep = ", ";
482             pp_string (buffer, "step: ");
483             dump_generic_node (buffer, tmp, spc, flags, false);
484           }
485         tmp = TMR_OFFSET (node);
486         if (tmp)
487           {
488             pp_string (buffer, sep);
489             sep = ", ";
490             pp_string (buffer, "offset: ");
491             dump_generic_node (buffer, tmp, spc, flags, false);
492           }
493         pp_string (buffer, "]");
494         if (flags & TDF_DETAILS)
495           {
496             pp_string (buffer, "{");
497             dump_generic_node (buffer, TMR_ORIGINAL (node), spc, flags,
498                                false);
499             pp_string (buffer, "}");
500           }
501       }
502       break;
503
504     case ARRAY_TYPE:
505       {
506         tree tmp;
507
508         /* Print the innermost component type.  */
509         for (tmp = TREE_TYPE (node); TREE_CODE (tmp) == ARRAY_TYPE;
510              tmp = TREE_TYPE (tmp))
511           ;
512         dump_generic_node (buffer, tmp, spc, flags, false);
513
514         /* Print the dimensions.  */
515         for (tmp = node; TREE_CODE (tmp) == ARRAY_TYPE; tmp = TREE_TYPE (tmp))
516           dump_array_domain (buffer, TYPE_DOMAIN (tmp), spc, flags);
517         break;
518       }
519
520     case RECORD_TYPE:
521     case UNION_TYPE:
522     case QUAL_UNION_TYPE:
523       /* Print the name of the structure.  */
524       if (TREE_CODE (node) == RECORD_TYPE)
525         pp_string (buffer, "struct ");
526       else if (TREE_CODE (node) == UNION_TYPE)
527         pp_string (buffer, "union ");
528
529       if (TYPE_NAME (node))
530         dump_generic_node (buffer, TYPE_NAME (node), spc, flags, false);
531       else
532         print_struct_decl (buffer, node, spc, flags);
533       break;
534
535     case LANG_TYPE:
536       NIY;
537       break;
538
539     case INTEGER_CST:
540       if (TREE_CODE (TREE_TYPE (node)) == POINTER_TYPE)
541         {
542           /* In the case of a pointer, one may want to divide by the
543              size of the pointed-to type.  Unfortunately, this not
544              straightforward.  The C front-end maps expressions
545
546              (int *) 5
547              int *p; (p + 5)
548
549              in such a way that the two INTEGER_CST nodes for "5" have
550              different values but identical types.  In the latter
551              case, the 5 is multiplied by sizeof (int) in c-common.c
552              (pointer_int_sum) to convert it to a byte address, and
553              yet the type of the node is left unchanged.  Argh.  What
554              is consistent though is that the number value corresponds
555              to bytes (UNITS) offset.
556
557              NB: Neither of the following divisors can be trivially
558              used to recover the original literal:
559
560              TREE_INT_CST_LOW (TYPE_SIZE_UNIT (TREE_TYPE (node)))
561              TYPE_PRECISION (TREE_TYPE (TREE_TYPE (node)))  */
562           pp_wide_integer (buffer, TREE_INT_CST_LOW (node));
563           pp_string (buffer, "B"); /* pseudo-unit */
564         }
565       else if (! host_integerp (node, 0))
566         {
567           tree val = node;
568
569           if (tree_int_cst_sgn (val) < 0)
570             {
571               pp_character (buffer, '-');
572               val = build_int_cst_wide (NULL_TREE,
573                                         -TREE_INT_CST_LOW (val),
574                                         ~TREE_INT_CST_HIGH (val)
575                                         + !TREE_INT_CST_LOW (val));
576             }
577           /* Would "%x%0*x" or "%x%*0x" get zero-padding on all
578              systems?  */
579           {
580             static char format[10]; /* "%x%09999x\0" */
581             if (!format[0])
582               sprintf (format, "%%x%%0%dx", HOST_BITS_PER_INT / 4);
583             sprintf (pp_buffer (buffer)->digit_buffer, format,
584                      TREE_INT_CST_HIGH (val),
585                      TREE_INT_CST_LOW (val));
586             pp_string (buffer, pp_buffer (buffer)->digit_buffer);
587           }
588         }
589       else
590         pp_wide_integer (buffer, TREE_INT_CST_LOW (node));
591       break;
592
593     case REAL_CST:
594       /* Code copied from print_node.  */
595       {
596         REAL_VALUE_TYPE d;
597         if (TREE_OVERFLOW (node))
598           pp_string (buffer, " overflow");
599
600 #if !defined(REAL_IS_NOT_DOUBLE) || defined(REAL_ARITHMETIC)
601         d = TREE_REAL_CST (node);
602         if (REAL_VALUE_ISINF (d))
603           pp_string (buffer, " Inf");
604         else if (REAL_VALUE_ISNAN (d))
605           pp_string (buffer, " Nan");
606         else
607           {
608             char string[100];
609             real_to_decimal (string, &d, sizeof (string), 0, 1);
610             pp_string (buffer, string);
611           }
612 #else
613         {
614           HOST_WIDE_INT i;
615           unsigned char *p = (unsigned char *) &TREE_REAL_CST (node);
616           pp_string (buffer, "0x");
617           for (i = 0; i < sizeof TREE_REAL_CST (node); i++)
618             output_formatted_integer (buffer, "%02x", *p++);
619         }
620 #endif
621         break;
622       }
623
624     case COMPLEX_CST:
625       pp_string (buffer, "__complex__ (");
626       dump_generic_node (buffer, TREE_REALPART (node), spc, flags, false);
627       pp_string (buffer, ", ");
628       dump_generic_node (buffer, TREE_IMAGPART (node), spc, flags, false);
629       pp_string (buffer, ")");
630       break;
631
632     case STRING_CST:
633       pp_string (buffer, "\"");
634       pretty_print_string (buffer, TREE_STRING_POINTER (node));
635       pp_string (buffer, "\"");
636       break;
637
638     case VECTOR_CST:
639       {
640         tree elt;
641         pp_string (buffer, "{ ");
642         for (elt = TREE_VECTOR_CST_ELTS (node); elt; elt = TREE_CHAIN (elt))
643           {
644             dump_generic_node (buffer, TREE_VALUE (elt), spc, flags, false);
645             if (TREE_CHAIN (elt))
646               pp_string (buffer, ", ");
647           }
648         pp_string (buffer, " }");
649       }
650       break;
651
652     case FUNCTION_TYPE:
653       break;
654
655     case FUNCTION_DECL:
656     case CONST_DECL:
657       dump_decl_name (buffer, node, flags);
658       break;
659
660     case LABEL_DECL:
661       if (DECL_NAME (node))
662         dump_decl_name (buffer, node, flags);
663       else if (LABEL_DECL_UID (node) != -1)
664         pp_printf (buffer, "<L" HOST_WIDE_INT_PRINT_DEC ">",
665                    LABEL_DECL_UID (node));
666       else
667         pp_printf (buffer, "<D%u>", DECL_UID (node));
668       break;
669
670     case TYPE_DECL:
671       if (DECL_IS_BUILTIN (node))
672         {
673           /* Don't print the declaration of built-in types.  */
674           break;
675         }
676       if (DECL_NAME (node))
677         dump_decl_name (buffer, node, flags);
678       else
679         {
680           if ((TREE_CODE (TREE_TYPE (node)) == RECORD_TYPE
681                || TREE_CODE (TREE_TYPE (node)) == UNION_TYPE)
682               && TYPE_METHODS (TREE_TYPE (node)))
683             {
684               /* The type is a c++ class: all structures have at least
685                  4 methods.  */
686               pp_string (buffer, "class ");
687               dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
688             }
689           else
690             {
691               pp_string (buffer,
692                          (TREE_CODE (TREE_TYPE (node)) == UNION_TYPE
693                           ? "union" : "struct "));
694               dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
695             }
696         }
697       break;
698
699     case VAR_DECL:
700     case PARM_DECL:
701     case FIELD_DECL:
702     case NAMESPACE_DECL:
703       dump_decl_name (buffer, node, flags);
704       break;
705
706     case RESULT_DECL:
707       pp_string (buffer, "<retval>");
708       break;
709
710     case COMPONENT_REF:
711       op0 = TREE_OPERAND (node, 0);
712       str = ".";
713       if (TREE_CODE (op0) == INDIRECT_REF)
714         {
715           op0 = TREE_OPERAND (op0, 0);
716           str = "->";
717         }
718       if (op_prio (op0) < op_prio (node))
719         pp_character (buffer, '(');
720       dump_generic_node (buffer, op0, spc, flags, false);
721       if (op_prio (op0) < op_prio (node))
722         pp_character (buffer, ')');
723       pp_string (buffer, str);
724       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
725
726       if (TREE_CODE (op0) != VALUE_HANDLE)
727         {
728           op0 = component_ref_field_offset (node);
729           if (op0 && TREE_CODE (op0) != INTEGER_CST)
730             {
731               pp_string (buffer, "{off: ");
732               dump_generic_node (buffer, op0, spc, flags, false);
733               pp_character (buffer, '}');
734             }
735         }
736       break;
737
738     case BIT_FIELD_REF:
739       pp_string (buffer, "BIT_FIELD_REF <");
740       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
741       pp_string (buffer, ", ");
742       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
743       pp_string (buffer, ", ");
744       dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
745       pp_string (buffer, ">");
746       break;
747
748     case ARRAY_REF:
749     case ARRAY_RANGE_REF:
750       op0 = TREE_OPERAND (node, 0);
751       if (op_prio (op0) < op_prio (node))
752         pp_character (buffer, '(');
753       dump_generic_node (buffer, op0, spc, flags, false);
754       if (op_prio (op0) < op_prio (node))
755         pp_character (buffer, ')');
756       pp_character (buffer, '[');
757       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
758       if (TREE_CODE (node) == ARRAY_RANGE_REF)
759         pp_string (buffer, " ...");
760       pp_character (buffer, ']');
761
762       op0 = array_ref_low_bound (node);
763       op1 = array_ref_element_size (node);
764
765       if (!integer_zerop (op0)
766           || (TYPE_SIZE_UNIT (TREE_TYPE (node))
767               && !operand_equal_p (op1, TYPE_SIZE_UNIT (TREE_TYPE (node)), 0)))
768         {
769           pp_string (buffer, "{lb: ");
770           dump_generic_node (buffer, op0, spc, flags, false);
771           pp_string (buffer, " sz: ");
772           dump_generic_node (buffer, op1, spc, flags, false);
773           pp_character (buffer, '}');
774         }
775       break;
776
777     case CONSTRUCTOR:
778       {
779         tree lnode;
780         bool is_struct_init = FALSE;
781         pp_character (buffer, '{');
782         lnode = CONSTRUCTOR_ELTS (node);
783         if (TREE_CODE (TREE_TYPE (node)) == RECORD_TYPE
784             || TREE_CODE (TREE_TYPE (node)) == UNION_TYPE)
785           is_struct_init = TRUE;
786         while (lnode && lnode != error_mark_node)
787           {
788             tree val;
789             if (TREE_PURPOSE (lnode) && is_struct_init)
790               {
791                 pp_character (buffer, '.');
792                 dump_generic_node (buffer, TREE_PURPOSE (lnode), spc, flags, false);
793                 pp_string (buffer, "=");
794               }
795             val = TREE_VALUE (lnode);
796             if (val && TREE_CODE (val) == ADDR_EXPR)
797               if (TREE_CODE (TREE_OPERAND (val, 0)) == FUNCTION_DECL)
798                 val = TREE_OPERAND (val, 0);
799             if (val && TREE_CODE (val) == FUNCTION_DECL)
800               {
801                 dump_decl_name (buffer, val, flags);
802               }
803             else
804               {
805                 dump_generic_node (buffer, TREE_VALUE (lnode), spc, flags, false);
806               }
807             lnode = TREE_CHAIN (lnode);
808             if (lnode && TREE_CODE (lnode) == TREE_LIST)
809               {
810                 pp_character (buffer, ',');
811                 pp_space (buffer);
812               }
813           }
814         pp_character (buffer, '}');
815       }
816       break;
817
818     case COMPOUND_EXPR:
819       {
820         tree *tp;
821         if (flags & TDF_SLIM)
822           {
823             pp_string (buffer, "<COMPOUND_EXPR>");
824             break;
825           }
826
827         dump_generic_node (buffer, TREE_OPERAND (node, 0),
828                            spc, flags, dumping_stmts);
829         if (dumping_stmts)
830           newline_and_indent (buffer, spc);
831         else
832           {
833             pp_character (buffer, ',');
834             pp_space (buffer);
835           }
836
837         for (tp = &TREE_OPERAND (node, 1);
838              TREE_CODE (*tp) == COMPOUND_EXPR;
839              tp = &TREE_OPERAND (*tp, 1))
840           {
841             dump_generic_node (buffer, TREE_OPERAND (*tp, 0),
842                                spc, flags, dumping_stmts);
843             if (dumping_stmts)
844               newline_and_indent (buffer, spc);
845             else
846               {
847                 pp_character (buffer, ',');
848                 pp_space (buffer);
849               }
850           }
851
852         dump_generic_node (buffer, *tp, spc, flags, dumping_stmts);
853       }
854       break;
855
856     case STATEMENT_LIST:
857       {
858         tree_stmt_iterator si;
859         bool first = true;
860
861         if ((flags & TDF_SLIM) || !dumping_stmts)
862           {
863             pp_string (buffer, "<STATEMENT_LIST>");
864             break;
865           }
866
867         for (si = tsi_start (node); !tsi_end_p (si); tsi_next (&si))
868           {
869             if (!first)
870               newline_and_indent (buffer, spc);
871             else
872               first = false;
873             dump_generic_node (buffer, tsi_stmt (si), spc, flags, true);
874           }
875       }
876       break;
877
878     case MODIFY_EXPR:
879     case INIT_EXPR:
880       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
881       pp_space (buffer);
882       pp_character (buffer, '=');
883       pp_space (buffer);
884       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
885       break;
886
887     case TARGET_EXPR:
888       pp_string (buffer, "TARGET_EXPR <");
889       dump_generic_node (buffer, TARGET_EXPR_SLOT (node), spc, flags, false);
890       pp_character (buffer, ',');
891       pp_space (buffer);
892       dump_generic_node (buffer, TARGET_EXPR_INITIAL (node), spc, flags, false);
893       pp_character (buffer, '>');
894       break;
895
896     case DECL_EXPR:
897       print_declaration (buffer, DECL_EXPR_DECL (node), spc, flags);
898       is_stmt = false;
899       break;
900
901     case COND_EXPR:
902       if (TREE_TYPE (node) == NULL || TREE_TYPE (node) == void_type_node)
903         {
904           pp_string (buffer, "if (");
905           dump_generic_node (buffer, COND_EXPR_COND (node), spc, flags, false);
906           pp_character (buffer, ')');
907           /* The lowered cond_exprs should always be printed in full.  */
908           if (COND_EXPR_THEN (node)
909               && (IS_EMPTY_STMT (COND_EXPR_THEN (node))
910                   || TREE_CODE (COND_EXPR_THEN (node)) == GOTO_EXPR)
911               && COND_EXPR_ELSE (node)
912               && (IS_EMPTY_STMT (COND_EXPR_ELSE (node))
913                   || TREE_CODE (COND_EXPR_ELSE (node)) == GOTO_EXPR))
914             {
915               pp_space (buffer);
916               dump_generic_node (buffer, COND_EXPR_THEN (node), 0, flags, true);
917               pp_string (buffer, " else ");
918               dump_generic_node (buffer, COND_EXPR_ELSE (node), 0, flags, true);
919             }
920           else if (!(flags & TDF_SLIM))
921             {
922               /* Output COND_EXPR_THEN.  */
923               if (COND_EXPR_THEN (node))
924                 {
925                   newline_and_indent (buffer, spc+2);
926                   pp_character (buffer, '{');
927                   newline_and_indent (buffer, spc+4);
928                   dump_generic_node (buffer, COND_EXPR_THEN (node), spc+4,
929                                      flags, true);
930                   newline_and_indent (buffer, spc+2);
931                   pp_character (buffer, '}');
932                 }
933
934               /* Output COND_EXPR_ELSE.  */
935               if (COND_EXPR_ELSE (node))
936                 {
937                   newline_and_indent (buffer, spc);
938                   pp_string (buffer, "else");
939                   newline_and_indent (buffer, spc+2);
940                   pp_character (buffer, '{');
941                   newline_and_indent (buffer, spc+4);
942                   dump_generic_node (buffer, COND_EXPR_ELSE (node), spc+4,
943                                      flags, true);
944                   newline_and_indent (buffer, spc+2);
945                   pp_character (buffer, '}');
946                 }
947             }
948           is_expr = false;
949         }
950       else
951         {
952           dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
953           pp_space (buffer);
954           pp_character (buffer, '?');
955           pp_space (buffer);
956           dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
957           pp_space (buffer);
958           pp_character (buffer, ':');
959           pp_space (buffer);
960           dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
961         }
962       break;
963
964     case BIND_EXPR:
965       pp_character (buffer, '{');
966       if (!(flags & TDF_SLIM))
967         {
968           if (BIND_EXPR_VARS (node))
969             {
970               pp_newline (buffer);
971
972               for (op0 = BIND_EXPR_VARS (node); op0; op0 = TREE_CHAIN (op0))
973                 {
974                   print_declaration (buffer, op0, spc+2, flags);
975                   pp_newline (buffer);
976                 }
977             }
978
979           newline_and_indent (buffer, spc+2);
980           dump_generic_node (buffer, BIND_EXPR_BODY (node), spc+2, flags, true);
981           newline_and_indent (buffer, spc);
982           pp_character (buffer, '}');
983         }
984       is_expr = false;
985       break;
986
987     case CALL_EXPR:
988       print_call_name (buffer, node);
989
990       /* Print parameters.  */
991       pp_space (buffer);
992       pp_character (buffer, '(');
993       op1 = TREE_OPERAND (node, 1);
994       if (op1)
995         dump_generic_node (buffer, op1, spc, flags, false);
996       pp_character (buffer, ')');
997
998       op1 = TREE_OPERAND (node, 2);
999       if (op1)
1000         {
1001           pp_string (buffer, " [static-chain: ");
1002           dump_generic_node (buffer, op1, spc, flags, false);
1003           pp_character (buffer, ']');
1004         }
1005
1006       if (CALL_EXPR_HAS_RETURN_SLOT_ADDR (node))
1007         pp_string (buffer, " [return slot addr]");
1008       if (CALL_EXPR_TAILCALL (node))
1009         pp_string (buffer, " [tail call]");
1010       break;
1011
1012     case WITH_CLEANUP_EXPR:
1013       NIY;
1014       break;
1015
1016     case CLEANUP_POINT_EXPR:
1017       pp_string (buffer, "<<cleanup_point ");
1018       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1019       pp_string (buffer, ">>");
1020       break;
1021
1022     case PLACEHOLDER_EXPR:
1023       pp_string (buffer, "<PLACEHOLDER_EXPR ");
1024       dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
1025       pp_character (buffer, '>');
1026       break;
1027
1028       /* Binary arithmetic and logic expressions.  */
1029     case MULT_EXPR:
1030     case PLUS_EXPR:
1031     case MINUS_EXPR:
1032     case TRUNC_DIV_EXPR:
1033     case CEIL_DIV_EXPR:
1034     case FLOOR_DIV_EXPR:
1035     case ROUND_DIV_EXPR:
1036     case TRUNC_MOD_EXPR:
1037     case CEIL_MOD_EXPR:
1038     case FLOOR_MOD_EXPR:
1039     case ROUND_MOD_EXPR:
1040     case RDIV_EXPR:
1041     case EXACT_DIV_EXPR:
1042     case LSHIFT_EXPR:
1043     case RSHIFT_EXPR:
1044     case LROTATE_EXPR:
1045     case RROTATE_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 (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       return 16;
1842
1843     case SAVE_EXPR:
1844     case NON_LVALUE_EXPR:
1845       return op_prio (TREE_OPERAND (op, 0));
1846
1847     default:
1848       /* Return an arbitrarily high precedence to avoid surrounding single
1849          VAR_DECLs in ()s.  */
1850       return 9999;
1851     }
1852 }
1853
1854
1855 /* Return the symbol associated with operator OP.  */
1856
1857 static const char *
1858 op_symbol (tree op)
1859 {
1860   gcc_assert (op);
1861
1862   switch (TREE_CODE (op))
1863     {
1864     case MODIFY_EXPR:
1865       return "=";
1866
1867     case TRUTH_OR_EXPR:
1868     case TRUTH_ORIF_EXPR:
1869       return "||";
1870
1871     case TRUTH_AND_EXPR:
1872     case TRUTH_ANDIF_EXPR:
1873       return "&&";
1874
1875     case BIT_IOR_EXPR:
1876       return "|";
1877
1878     case TRUTH_XOR_EXPR:
1879     case BIT_XOR_EXPR:
1880       return "^";
1881
1882     case ADDR_EXPR:
1883     case BIT_AND_EXPR:
1884       return "&";
1885
1886     case ORDERED_EXPR:
1887       return "ord";
1888     case UNORDERED_EXPR:
1889       return "unord";
1890
1891     case EQ_EXPR:
1892       return "==";
1893     case UNEQ_EXPR:
1894       return "u==";
1895
1896     case NE_EXPR:
1897       return "!=";
1898
1899     case LT_EXPR:
1900       return "<";
1901     case UNLT_EXPR:
1902       return "u<";
1903
1904     case LE_EXPR:
1905       return "<=";
1906     case UNLE_EXPR:
1907       return "u<=";
1908
1909     case GT_EXPR:
1910       return ">";
1911     case UNGT_EXPR:
1912       return "u>";
1913
1914     case GE_EXPR:
1915       return ">=";
1916     case UNGE_EXPR:
1917       return "u>=";
1918
1919     case LTGT_EXPR:
1920       return "<>";
1921
1922     case LSHIFT_EXPR:
1923       return "<<";
1924
1925     case RSHIFT_EXPR:
1926       return ">>";
1927
1928     case PLUS_EXPR:
1929       return "+";
1930
1931     case REDUC_PLUS_EXPR:
1932       return "r+";
1933
1934     case NEGATE_EXPR:
1935     case MINUS_EXPR:
1936       return "-";
1937
1938     case BIT_NOT_EXPR:
1939       return "~";
1940
1941     case TRUTH_NOT_EXPR:
1942       return "!";
1943
1944     case MULT_EXPR:
1945     case INDIRECT_REF:
1946       return "*";
1947
1948     case ALIGN_INDIRECT_REF:
1949       return "A*";
1950
1951     case MISALIGNED_INDIRECT_REF:
1952       return "M*";
1953
1954     case TRUNC_DIV_EXPR:
1955     case RDIV_EXPR:
1956       return "/";
1957
1958     case CEIL_DIV_EXPR:
1959       return "/[cl]";
1960
1961     case FLOOR_DIV_EXPR:
1962       return "/[fl]";
1963
1964     case ROUND_DIV_EXPR:
1965       return "/[rd]";
1966
1967     case EXACT_DIV_EXPR:
1968       return "/[ex]";
1969
1970     case TRUNC_MOD_EXPR:
1971       return "%";
1972
1973     case CEIL_MOD_EXPR:
1974       return "%[cl]";
1975
1976     case FLOOR_MOD_EXPR:
1977       return "%[fl]";
1978
1979     case ROUND_MOD_EXPR:
1980       return "%[rd]";
1981
1982     case PREDECREMENT_EXPR:
1983       return " --";
1984
1985     case PREINCREMENT_EXPR:
1986       return " ++";
1987
1988     case POSTDECREMENT_EXPR:
1989       return "-- ";
1990
1991     case POSTINCREMENT_EXPR:
1992       return "++ ";
1993
1994     default:
1995       return "<<< ??? >>>";
1996     }
1997 }
1998
1999 /* Prints the name of a CALL_EXPR.  */
2000
2001 static void
2002 print_call_name (pretty_printer *buffer, tree node)
2003 {
2004   tree op0;
2005
2006   gcc_assert (TREE_CODE (node) == CALL_EXPR);
2007
2008   op0 = TREE_OPERAND (node, 0);
2009
2010   if (TREE_CODE (op0) == NON_LVALUE_EXPR)
2011     op0 = TREE_OPERAND (op0, 0);
2012
2013   switch (TREE_CODE (op0))
2014     {
2015     case VAR_DECL:
2016     case PARM_DECL:
2017       dump_function_name (buffer, op0);
2018       break;
2019
2020     case ADDR_EXPR:
2021     case INDIRECT_REF:
2022     case NOP_EXPR:
2023       dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
2024       break;
2025
2026     case COND_EXPR:
2027       pp_string (buffer, "(");
2028       dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
2029       pp_string (buffer, ") ? ");
2030       dump_generic_node (buffer, TREE_OPERAND (op0, 1), 0, 0, false);
2031       pp_string (buffer, " : ");
2032       dump_generic_node (buffer, TREE_OPERAND (op0, 2), 0, 0, false);
2033       break;
2034
2035     case COMPONENT_REF:
2036       /* The function is a pointer contained in a structure.  */
2037       if (TREE_CODE (TREE_OPERAND (op0, 0)) == INDIRECT_REF ||
2038           TREE_CODE (TREE_OPERAND (op0, 0)) == VAR_DECL)
2039         dump_function_name (buffer, TREE_OPERAND (op0, 1));
2040       else
2041         dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
2042       /* else
2043          We can have several levels of structures and a function
2044          pointer inside.  This is not implemented yet...  */
2045       /*                  NIY;*/
2046       break;
2047
2048     case ARRAY_REF:
2049       if (TREE_CODE (TREE_OPERAND (op0, 0)) == VAR_DECL)
2050         dump_function_name (buffer, TREE_OPERAND (op0, 0));
2051       else
2052         dump_generic_node (buffer, op0, 0, 0, false);
2053       break;
2054
2055     case SSA_NAME:
2056     case OBJ_TYPE_REF:
2057       dump_generic_node (buffer, op0, 0, 0, false);
2058       break;
2059
2060     default:
2061       NIY;
2062     }
2063 }
2064
2065 /* Parses the string STR and replaces new-lines by '\n', tabs by '\t', ...  */
2066
2067 static void
2068 pretty_print_string (pretty_printer *buffer, const char *str)
2069 {
2070   if (str == NULL)
2071     return;
2072
2073   while (*str)
2074     {
2075       switch (str[0])
2076         {
2077         case '\b':
2078           pp_string (buffer, "\\b");
2079           break;
2080
2081         case '\f':
2082           pp_string (buffer, "\\f");
2083           break;
2084
2085         case '\n':
2086           pp_string (buffer, "\\n");
2087           break;
2088
2089         case '\r':
2090           pp_string (buffer, "\\r");
2091           break;
2092
2093         case '\t':
2094           pp_string (buffer, "\\t");
2095           break;
2096
2097         case '\v':
2098           pp_string (buffer, "\\v");
2099           break;
2100
2101         case '\\':
2102           pp_string (buffer, "\\\\");
2103           break;
2104
2105         case '\"':
2106           pp_string (buffer, "\\\"");
2107           break;
2108
2109         case '\'':
2110           pp_string (buffer, "\\'");
2111           break;
2112
2113         case '\0':
2114           pp_string (buffer, "\\0");
2115           break;
2116
2117         case '\1':
2118           pp_string (buffer, "\\1");
2119           break;
2120
2121         case '\2':
2122           pp_string (buffer, "\\2");
2123           break;
2124
2125         case '\3':
2126           pp_string (buffer, "\\3");
2127           break;
2128
2129         case '\4':
2130           pp_string (buffer, "\\4");
2131           break;
2132
2133         case '\5':
2134           pp_string (buffer, "\\5");
2135           break;
2136
2137         case '\6':
2138           pp_string (buffer, "\\6");
2139           break;
2140
2141         case '\7':
2142           pp_string (buffer, "\\7");
2143           break;
2144
2145         default:
2146           pp_character (buffer, str[0]);
2147           break;
2148         }
2149       str++;
2150     }
2151 }
2152
2153 static void
2154 maybe_init_pretty_print (FILE *file)
2155 {
2156   if (!initialized)
2157     {
2158       pp_construct (&buffer, /* prefix */NULL, /* line-width */0);
2159       pp_needs_newline (&buffer) = true;
2160       initialized = 1;
2161     }
2162
2163   buffer.buffer->stream = file;
2164 }
2165
2166 static void
2167 newline_and_indent (pretty_printer *buffer, int spc)
2168 {
2169   pp_newline (buffer);
2170   INDENT (spc);
2171 }
2172
2173 static void
2174 dump_vops (pretty_printer *buffer, tree stmt, int spc, int flags)
2175 {
2176   tree use;
2177   use_operand_p use_p;
2178   def_operand_p def_p;
2179   use_operand_p kill_p;
2180   ssa_op_iter iter;
2181
2182   if (!ssa_operands_active ())
2183     return;
2184
2185   FOR_EACH_SSA_MAYDEF_OPERAND (def_p, use_p, stmt, iter)
2186     {
2187       pp_string (buffer, "#   ");
2188       dump_generic_node (buffer, DEF_FROM_PTR (def_p),
2189                          spc + 2, flags, false);
2190       pp_string (buffer, " = V_MAY_DEF <");
2191       dump_generic_node (buffer, USE_FROM_PTR (use_p),
2192                          spc + 2, flags, false);
2193       pp_string (buffer, ">;");
2194       newline_and_indent (buffer, spc);
2195     }
2196
2197   FOR_EACH_SSA_MUSTDEF_OPERAND (def_p, kill_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_MUST_DEF <");
2203       dump_generic_node (buffer, USE_FROM_PTR (kill_p),
2204                          spc + 2, flags, false);
2205       pp_string (buffer, ">;");
2206       newline_and_indent (buffer, spc);
2207     }
2208
2209   FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_VUSE)
2210     {
2211       pp_string (buffer, "#   VUSE <");
2212       dump_generic_node (buffer, use, spc + 2, flags, false);
2213       pp_string (buffer, ">;");
2214       newline_and_indent (buffer, spc);
2215     }
2216 }
2217
2218 /* Dumps basic block BB to FILE with details described by FLAGS and
2219    indented by INDENT spaces.  */
2220
2221 void
2222 dump_generic_bb (FILE *file, basic_block bb, int indent, int flags)
2223 {
2224   maybe_init_pretty_print (file);
2225   dumping_stmts = true;
2226   dump_generic_bb_buff (&buffer, bb, indent, flags);
2227   pp_flush (&buffer);
2228 }
2229
2230 /* Dumps header of basic block BB to buffer BUFFER indented by INDENT
2231    spaces and details described by flags.  */
2232
2233 static void
2234 dump_bb_header (pretty_printer *buffer, basic_block bb, int indent, int flags)
2235 {
2236   edge e;
2237   tree stmt;
2238   edge_iterator ei;
2239
2240   if (flags & TDF_BLOCKS)
2241     {
2242       INDENT (indent);
2243       pp_string (buffer, "# BLOCK ");
2244       pp_decimal_int (buffer, bb->index);
2245
2246       if (flags & TDF_LINENO)
2247         {
2248           block_stmt_iterator bsi;
2249
2250           for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
2251             if (get_lineno (bsi_stmt (bsi)) != -1)
2252               {
2253                 pp_string (buffer, ", starting at line ");
2254                 pp_decimal_int (buffer, get_lineno (bsi_stmt (bsi)));
2255                 break;
2256               }
2257         }
2258       newline_and_indent (buffer, indent);
2259
2260       pp_string (buffer, "# PRED:");
2261       pp_write_text_to_stream (buffer);
2262       FOR_EACH_EDGE (e, ei, bb->preds)
2263         if (flags & TDF_SLIM)
2264           {
2265             pp_string (buffer, " ");
2266             if (e->src == ENTRY_BLOCK_PTR)
2267               pp_string (buffer, "ENTRY");
2268             else
2269               pp_decimal_int (buffer, e->src->index);
2270           }
2271         else
2272           dump_edge_info (buffer->buffer->stream, e, 0);
2273       pp_newline (buffer);
2274     }
2275   else
2276     {
2277       stmt = first_stmt (bb);
2278       if (!stmt || TREE_CODE (stmt) != LABEL_EXPR)
2279         {
2280           INDENT (indent - 2);
2281           pp_string (buffer, "<bb ");
2282           pp_decimal_int (buffer, bb->index);
2283           pp_string (buffer, ">:");
2284           pp_newline (buffer);
2285         }
2286     }
2287   pp_write_text_to_stream (buffer);
2288   check_bb_profile (bb, buffer->buffer->stream);
2289 }
2290
2291 /* Dumps end of basic block BB to buffer BUFFER indented by INDENT
2292    spaces.  */
2293
2294 static void
2295 dump_bb_end (pretty_printer *buffer, basic_block bb, int indent, int flags)
2296 {
2297   edge e;
2298   edge_iterator ei;
2299
2300   INDENT (indent);
2301   pp_string (buffer, "# SUCC:");
2302   pp_write_text_to_stream (buffer);
2303   FOR_EACH_EDGE (e, ei, bb->succs)
2304     if (flags & TDF_SLIM)
2305       {
2306         pp_string (buffer, " ");
2307         if (e->dest == EXIT_BLOCK_PTR)
2308           pp_string (buffer, "EXIT");
2309         else
2310           pp_decimal_int (buffer, e->dest->index);
2311       }
2312     else
2313       dump_edge_info (buffer->buffer->stream, e, 1);
2314   pp_newline (buffer);
2315 }
2316
2317 /* Dumps phi nodes of basic block BB to buffer BUFFER with details described by
2318    FLAGS indented by INDENT spaces.  */
2319
2320 static void
2321 dump_phi_nodes (pretty_printer *buffer, basic_block bb, int indent, int flags)
2322 {
2323   tree phi = phi_nodes (bb);
2324   if (!phi)
2325     return;
2326
2327   for (; phi; phi = PHI_CHAIN (phi))
2328     {
2329       if (is_gimple_reg (PHI_RESULT (phi)) || (flags & TDF_VOPS))
2330         {
2331           INDENT (indent);
2332           pp_string (buffer, "# ");
2333           dump_generic_node (buffer, phi, indent, flags, false);
2334           pp_newline (buffer);
2335         }
2336     }
2337 }
2338
2339 /* Dump jump to basic block BB that is represented implicitly in the cfg
2340    to BUFFER.  */
2341
2342 static void
2343 pp_cfg_jump (pretty_printer *buffer, basic_block bb)
2344 {
2345   tree stmt;
2346
2347   stmt = first_stmt (bb);
2348
2349   pp_string (buffer, "goto <bb ");
2350   pp_decimal_int (buffer, bb->index);
2351   pp_string (buffer, ">");
2352   if (stmt && TREE_CODE (stmt) == LABEL_EXPR)
2353     {
2354       pp_string (buffer, " (");
2355       dump_generic_node (buffer, LABEL_EXPR_LABEL (stmt), 0, 0, false);
2356       pp_string (buffer, ")");
2357     }
2358   pp_semicolon (buffer);
2359 }
2360
2361 /* Dump edges represented implicitly in basic block BB to BUFFER, indented
2362    by INDENT spaces, with details given by FLAGS.  */
2363
2364 static void
2365 dump_implicit_edges (pretty_printer *buffer, basic_block bb, int indent,
2366                      int flags)
2367 {
2368   edge e;
2369   edge_iterator ei;
2370
2371   /* If there is a fallthru edge, we may need to add an artificial goto to the
2372      dump.  */
2373   FOR_EACH_EDGE (e, ei, bb->succs)
2374     if (e->flags & EDGE_FALLTHRU)
2375       break;
2376   if (e && e->dest != bb->next_bb)
2377     {
2378       INDENT (indent);
2379
2380       if ((flags & TDF_LINENO)
2381 #ifdef USE_MAPPED_LOCATION
2382           && e->goto_locus != UNKNOWN_LOCATION
2383 #else
2384           && e->goto_locus
2385 #endif
2386           )
2387         {
2388           expanded_location goto_xloc;
2389 #ifdef USE_MAPPED_LOCATION
2390           goto_xloc = expand_location (e->goto_locus);
2391 #else
2392           goto_xloc = *e->goto_locus;
2393 #endif
2394           pp_character (buffer, '[');
2395           if (goto_xloc.file)
2396             {
2397               pp_string (buffer, goto_xloc.file);
2398               pp_string (buffer, " : ");
2399             }
2400           pp_decimal_int (buffer, goto_xloc.line);
2401           pp_string (buffer, "] ");
2402         }
2403
2404       pp_cfg_jump (buffer, e->dest);
2405       pp_newline (buffer);
2406     }
2407 }
2408
2409 /* Dumps basic block BB to buffer BUFFER with details described by FLAGS and
2410    indented by INDENT spaces.  */
2411
2412 static void
2413 dump_generic_bb_buff (pretty_printer *buffer, basic_block bb,
2414                       int indent, int flags)
2415 {
2416   block_stmt_iterator bsi;
2417   tree stmt;
2418   int label_indent = indent - 2;
2419
2420   if (label_indent < 0)
2421     label_indent = 0;
2422
2423   dump_bb_header (buffer, bb, indent, flags);
2424
2425   dump_phi_nodes (buffer, bb, indent, flags);
2426
2427   for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
2428     {
2429       int curr_indent;
2430
2431       stmt = bsi_stmt (bsi);
2432
2433       curr_indent = TREE_CODE (stmt) == LABEL_EXPR ? label_indent : indent;
2434
2435       INDENT (curr_indent);
2436       dump_generic_node (buffer, stmt, curr_indent, flags, true);
2437       pp_newline (buffer);
2438     }
2439
2440   dump_implicit_edges (buffer, bb, indent, flags);
2441
2442   if (flags & TDF_BLOCKS)
2443     dump_bb_end (buffer, bb, indent, flags);
2444 }