OSDN Git Service

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