OSDN Git Service

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