OSDN Git Service

* lib/compat.exp (compat-execute): Break up long lines.
[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       {
909         const char *op = op_symbol (node);
910         op0 = TREE_OPERAND (node, 0);
911         op1 = TREE_OPERAND (node, 1);
912
913         /* When the operands are expressions with less priority,
914            keep semantics of the tree representation.  */
915         if (op_prio (op0) < op_prio (node))
916           {
917             pp_character (buffer, '(');
918             dump_generic_node (buffer, op0, spc, flags, false);
919             pp_character (buffer, ')');
920           }
921         else
922           dump_generic_node (buffer, op0, spc, flags, false);
923
924         pp_space (buffer);
925         pp_string (buffer, op);
926         pp_space (buffer);
927
928         /* When the operands are expressions with less priority,
929            keep semantics of the tree representation.  */
930         if (op_prio (op1) < op_prio (node))
931           {
932             pp_character (buffer, '(');
933             dump_generic_node (buffer, op1, spc, flags, false);
934             pp_character (buffer, ')');
935           }
936         else
937           dump_generic_node (buffer, op1, spc, flags, false);
938       }
939       break;
940
941       /* Unary arithmetic and logic expressions.  */
942     case NEGATE_EXPR:
943     case BIT_NOT_EXPR:
944     case TRUTH_NOT_EXPR:
945     case ADDR_EXPR:
946     case REFERENCE_EXPR:
947     case PREDECREMENT_EXPR:
948     case PREINCREMENT_EXPR:
949     case INDIRECT_REF:
950       if (TREE_CODE (node) == ADDR_EXPR
951           && (TREE_CODE (TREE_OPERAND (node, 0)) == STRING_CST
952               || TREE_CODE (TREE_OPERAND (node, 0)) == FUNCTION_DECL))
953         ;       /* Do not output '&' for strings and function pointers.  */
954       else
955         pp_string (buffer, op_symbol (node));
956
957       if (op_prio (TREE_OPERAND (node, 0)) < op_prio (node))
958         {
959           pp_character (buffer, '(');
960           dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
961           pp_character (buffer, ')');
962         }
963       else
964         dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
965       break;
966
967     case POSTDECREMENT_EXPR:
968     case POSTINCREMENT_EXPR:
969       if (op_prio (TREE_OPERAND (node, 0)) < op_prio (node))
970         {
971           pp_character (buffer, '(');
972           dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
973           pp_character (buffer, ')');
974         }
975       else
976         dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
977       pp_string (buffer, op_symbol (node));
978       break;
979
980     case MIN_EXPR:
981       pp_string (buffer, "MIN_EXPR <");
982       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
983       pp_string (buffer, ", ");
984       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
985       pp_character (buffer, '>');
986       break;
987
988     case MAX_EXPR:
989       pp_string (buffer, "MAX_EXPR <");
990       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
991       pp_string (buffer, ", ");
992       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
993       pp_character (buffer, '>');
994       break;
995
996     case ABS_EXPR:
997       pp_string (buffer, "ABS_EXPR <");
998       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
999       pp_character (buffer, '>');
1000       break;
1001
1002     case UNORDERED_EXPR:
1003       NIY;
1004       break;
1005
1006     case ORDERED_EXPR:
1007       NIY;
1008       break;
1009
1010     case IN_EXPR:
1011       NIY;
1012       break;
1013
1014     case SET_LE_EXPR:
1015       NIY;
1016       break;
1017
1018     case CARD_EXPR:
1019       NIY;
1020       break;
1021
1022     case RANGE_EXPR:
1023       NIY;
1024       break;
1025
1026     case FIX_TRUNC_EXPR:
1027     case FIX_CEIL_EXPR:
1028     case FIX_FLOOR_EXPR:
1029     case FIX_ROUND_EXPR:
1030     case FLOAT_EXPR:
1031     case CONVERT_EXPR:
1032     case NOP_EXPR:
1033       type = TREE_TYPE (node);
1034       op0 = TREE_OPERAND (node, 0);
1035       if (type != TREE_TYPE (op0))
1036         {
1037           pp_character (buffer, '(');
1038           dump_generic_node (buffer, type, spc, flags, false);
1039           pp_string (buffer, ")");
1040         }
1041       if (op_prio (op0) < op_prio (node))
1042         pp_character (buffer, '(');
1043       dump_generic_node (buffer, op0, spc, flags, false);
1044       if (op_prio (op0) < op_prio (node))
1045         pp_character (buffer, ')');
1046       break;
1047
1048     case VIEW_CONVERT_EXPR:
1049       pp_string (buffer, "VIEW_CONVERT_EXPR<");
1050       dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
1051       pp_string (buffer, ">(");
1052       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1053       pp_character (buffer, ')');
1054       break;
1055
1056     case NON_LVALUE_EXPR:
1057       pp_string (buffer, "NON_LVALUE_EXPR <");
1058       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1059       pp_character (buffer, '>');
1060       break;
1061
1062     case SAVE_EXPR:
1063       pp_string (buffer, "SAVE_EXPR <");
1064       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1065       pp_character (buffer, '>');
1066       break;
1067
1068     case UNSAVE_EXPR:
1069       pp_string (buffer, "UNSAVE_EXPR <");
1070       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1071       pp_character (buffer, '>');
1072       break;
1073
1074     case RTL_EXPR:
1075       NIY;
1076       break;
1077
1078     case ENTRY_VALUE_EXPR:
1079       NIY;
1080       break;
1081
1082     case COMPLEX_EXPR:
1083       pp_string (buffer, "COMPLEX_EXPR <");
1084       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1085       pp_string (buffer, ", ");
1086       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1087       pp_string (buffer, ">");
1088       break;
1089
1090     case CONJ_EXPR:
1091       pp_string (buffer, "CONJ_EXPR <");
1092       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1093       pp_string (buffer, ">");
1094       break;
1095
1096     case REALPART_EXPR:
1097       pp_string (buffer, "REALPART_EXPR <");
1098       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1099       pp_string (buffer, ">");
1100       break;
1101
1102     case IMAGPART_EXPR:
1103       pp_string (buffer, "IMAGPART_EXPR <");
1104       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1105       pp_string (buffer, ">");
1106       break;
1107
1108     case VA_ARG_EXPR:
1109       pp_string (buffer, "VA_ARG_EXPR <");
1110       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1111       pp_string (buffer, ">");
1112       break;
1113
1114     case TRY_FINALLY_EXPR:
1115     case TRY_CATCH_EXPR:
1116       pp_string (buffer, "try");
1117       newline_and_indent (buffer, spc+2);
1118       pp_string (buffer, "{");
1119       newline_and_indent (buffer, spc+4);
1120       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc+4, flags, true);
1121       newline_and_indent (buffer, spc+2);
1122       pp_string (buffer, "}");
1123       newline_and_indent (buffer, spc);
1124       pp_string (buffer,
1125                          (TREE_CODE (node) == TRY_CATCH_EXPR) ? "catch" : "finally");
1126       newline_and_indent (buffer, spc+2);
1127       pp_string (buffer, "{");
1128       newline_and_indent (buffer, spc+4);
1129       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc+4, flags, true);
1130       newline_and_indent (buffer, spc+2);
1131       pp_string (buffer, "}");
1132       is_expr = false;
1133       break;
1134
1135     case CATCH_EXPR:
1136       pp_string (buffer, "catch (");
1137       dump_generic_node (buffer, CATCH_TYPES (node), spc+2, flags, false);
1138       pp_string (buffer, ")");
1139       newline_and_indent (buffer, spc+2);
1140       pp_string (buffer, "{");
1141       newline_and_indent (buffer, spc+4);
1142       dump_generic_node (buffer, CATCH_BODY (node), spc+4, flags, true);
1143       newline_and_indent (buffer, spc+2);
1144       pp_string (buffer, "}");
1145       is_expr = false;
1146       break;
1147
1148     case EH_FILTER_EXPR:
1149       pp_string (buffer, "<<<eh_filter (");
1150       dump_generic_node (buffer, EH_FILTER_TYPES (node), spc+2, flags, false);
1151       pp_string (buffer, ")>>>");
1152       newline_and_indent (buffer, spc+2);
1153       pp_string (buffer, "{");
1154       newline_and_indent (buffer, spc+4);
1155       dump_generic_node (buffer, EH_FILTER_FAILURE (node), spc+4, flags, true);
1156       newline_and_indent (buffer, spc+2);
1157       pp_string (buffer, "}");
1158       is_expr = false;
1159       break;
1160
1161     case GOTO_SUBROUTINE_EXPR:
1162       NIY;
1163       break;
1164
1165     case LABEL_EXPR:
1166       op0 = TREE_OPERAND (node, 0);
1167       /* If this is for break or continue, don't bother printing it.  */
1168       if (DECL_NAME (op0))
1169         {
1170           const char *name = IDENTIFIER_POINTER (DECL_NAME (op0));
1171           if (strcmp (name, "break") == 0
1172               || strcmp (name, "continue") == 0)
1173             break;
1174         }
1175       dump_generic_node (buffer, op0, spc, flags, false);
1176       pp_character (buffer, ':');
1177       if (DECL_NONLOCAL (op0))
1178         pp_string (buffer, " [non-local]");
1179       break;
1180
1181     case LABELED_BLOCK_EXPR:
1182       op0 = LABELED_BLOCK_LABEL (node);
1183       /* If this is for break or continue, don't bother printing it.  */
1184       if (DECL_NAME (op0))
1185         {
1186           const char *name = IDENTIFIER_POINTER (DECL_NAME (op0));
1187           if (strcmp (name, "break") == 0
1188               || strcmp (name, "continue") == 0)
1189             {
1190               dump_generic_node (buffer, LABELED_BLOCK_BODY (node), spc, flags, false);
1191               break;
1192             }
1193         }
1194       dump_generic_node (buffer, LABELED_BLOCK_LABEL (node), spc, flags, false);
1195       pp_string (buffer, ": {");
1196       if (!(flags & TDF_SLIM))
1197         newline_and_indent (buffer, spc+2);
1198       dump_generic_node (buffer, LABELED_BLOCK_BODY (node), spc+2, flags, true);
1199       if (!flags)
1200         newline_and_indent (buffer, spc);
1201       pp_character (buffer, '}');
1202       is_expr = false;
1203       break;
1204
1205     case EXIT_BLOCK_EXPR:
1206       op0 = LABELED_BLOCK_LABEL (EXIT_BLOCK_LABELED_BLOCK (node));
1207       /* If this is for a break or continue, print it accordingly.  */
1208       if (DECL_NAME (op0))
1209         {
1210           const char *name = IDENTIFIER_POINTER (DECL_NAME (op0));
1211           if (strcmp (name, "break") == 0
1212               || strcmp (name, "continue") == 0)
1213             {
1214               pp_string (buffer, name);
1215               break;
1216             }
1217         }
1218       pp_string (buffer, "<<<exit block ");
1219       dump_generic_node (buffer, op0, spc, flags, false);
1220       pp_string (buffer, ">>>");
1221       break;
1222
1223     case EXC_PTR_EXPR:
1224       pp_string (buffer, "<<<exception object>>>");
1225       break;
1226
1227     case FILTER_EXPR:
1228       pp_string (buffer, "<<<filter object>>>");
1229       break;
1230
1231     case LOOP_EXPR:
1232       pp_string (buffer, "while (1)");
1233       if (!(flags & TDF_SLIM))
1234         {
1235           newline_and_indent (buffer, spc+2);
1236           pp_character (buffer, '{');
1237           newline_and_indent (buffer, spc+4);
1238           dump_generic_node (buffer, LOOP_EXPR_BODY (node), spc+4, flags, true);
1239           newline_and_indent (buffer, spc+2);
1240           pp_character (buffer, '}');
1241         }
1242       is_expr = false;
1243       break;
1244
1245     case RETURN_EXPR:
1246       pp_string (buffer, "return");
1247       op0 = TREE_OPERAND (node, 0);
1248       if (op0)
1249         {
1250           pp_space (buffer);
1251           if (TREE_CODE (op0) == MODIFY_EXPR)
1252             dump_generic_node (buffer, TREE_OPERAND (op0, 1), spc, flags, false);
1253           else
1254             dump_generic_node (buffer, op0, spc, flags, false);
1255         }
1256       break;
1257
1258     case EXIT_EXPR:
1259       pp_string (buffer, "if (");
1260       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1261       pp_string (buffer, ") break");
1262       break;
1263
1264     case SWITCH_EXPR:
1265       pp_string (buffer, "switch (");
1266       dump_generic_node (buffer, SWITCH_COND (node), spc, flags, false);
1267       pp_character (buffer, ')');
1268       if (!(flags & TDF_SLIM))
1269         {
1270           newline_and_indent (buffer, spc+2);
1271           pp_character (buffer, '{');
1272           if (SWITCH_BODY (node))
1273             {
1274               newline_and_indent (buffer, spc+4);
1275               dump_generic_node (buffer, SWITCH_BODY (node), spc+4, flags, true);
1276             }
1277           else
1278             {
1279               tree vec = SWITCH_LABELS (node);
1280               size_t i, n = TREE_VEC_LENGTH (vec);
1281               for (i = 0; i < n; ++i)
1282                 {
1283                   tree elt = TREE_VEC_ELT (vec, i);
1284                   newline_and_indent (buffer, spc+4);
1285                   dump_generic_node (buffer, elt, spc+4, flags, false);
1286                   pp_string (buffer, " goto ");
1287                   dump_generic_node (buffer, CASE_LABEL (elt), spc+4, flags, true);
1288                   pp_semicolon (buffer);
1289                 }
1290             }
1291           newline_and_indent (buffer, spc+2);
1292           pp_character (buffer, '}');
1293         }
1294       is_expr = false;
1295       break;
1296
1297     case GOTO_EXPR:
1298       op0 = GOTO_DESTINATION (node);
1299       if (TREE_CODE (op0) != SSA_NAME
1300           && DECL_P (op0)
1301           && DECL_NAME (op0))
1302         {
1303           const char *name = IDENTIFIER_POINTER (DECL_NAME (op0));
1304           if (strcmp (name, "break") == 0
1305               || strcmp (name, "continue") == 0)
1306             {
1307               pp_string (buffer, name);
1308               break;
1309             }
1310         }
1311       pp_string (buffer, "goto ");
1312       dump_generic_node (buffer, op0, spc, flags, false);
1313       break;
1314
1315     case RESX_EXPR:
1316       pp_string (buffer, "resx");
1317       /* ??? Any sensible way to present the eh region?  */
1318       break;
1319
1320     case ASM_EXPR:
1321       pp_string (buffer, "__asm__");
1322       if (ASM_VOLATILE_P (node))
1323         pp_string (buffer, " __volatile__");
1324       pp_character (buffer, '(');
1325       dump_generic_node (buffer, ASM_STRING (node), spc, flags, false);
1326       pp_character (buffer, ':');
1327       dump_generic_node (buffer, ASM_OUTPUTS (node), spc, flags, false);
1328       pp_character (buffer, ':');
1329       dump_generic_node (buffer, ASM_INPUTS (node), spc, flags, false);
1330       if (ASM_CLOBBERS (node))
1331         {
1332           pp_character (buffer, ':');
1333           dump_generic_node (buffer, ASM_CLOBBERS (node), spc, flags, false);
1334         }
1335       pp_string (buffer, ")");
1336       break;
1337
1338     case CASE_LABEL_EXPR:
1339       if (CASE_LOW (node) && CASE_HIGH (node))
1340         {
1341           pp_string (buffer, "case ");
1342           dump_generic_node (buffer, CASE_LOW (node), spc, flags, false);
1343           pp_string (buffer, " ... ");
1344           dump_generic_node (buffer, CASE_HIGH (node), spc, flags, false);
1345         }
1346       else if (CASE_LOW (node))
1347         {
1348           pp_string (buffer, "case ");
1349           dump_generic_node (buffer, CASE_LOW (node), spc, flags, false);
1350         }
1351       else
1352         pp_string (buffer, "default ");
1353       pp_character (buffer, ':');
1354       break;
1355
1356     case VTABLE_REF:
1357       pp_string (buffer, "VTABLE_REF <(");
1358       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1359       pp_string (buffer, "),");
1360       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1361       pp_character (buffer, ',');
1362       dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
1363       pp_character (buffer, '>');
1364       break;
1365
1366     case EPHI_NODE:
1367       {
1368         int i;
1369
1370         pp_string (buffer, " EPHI (");
1371         dump_generic_node (buffer, EREF_NAME (node), spc, flags, false);
1372         pp_string (buffer, ") ");
1373         pp_character (buffer, '[');
1374         pp_string (buffer, " class:");
1375         pp_decimal_int (buffer, EREF_CLASS (node));
1376         if (EPHI_DOWNSAFE (node))
1377           pp_string (buffer, " downsafe");
1378         if (EPHI_CANT_BE_AVAIL (node))
1379           pp_string (buffer, " cant_be_avail");
1380         if (EPHI_STOPS (node))
1381           pp_string (buffer, " stops");
1382         pp_string (buffer, " bb:");
1383         pp_decimal_int (buffer, bb_for_stmt (node)->index);
1384         pp_character (buffer, ']');
1385         if (! (flags & TDF_SLIM))
1386           {
1387             pp_string (buffer, " <");
1388             for (i = 0; i < EPHI_NUM_ARGS (node); i++)
1389               {     
1390                 if (EPHI_ARG_DEF (node, i))
1391                   {
1392                     newline_and_indent (buffer, spc + 2);
1393                     pp_string (buffer, " edge ");
1394                     pp_decimal_int (buffer, EPHI_ARG_EDGE (node, i)->src->index);
1395                     pp_string (buffer, "->");
1396                     pp_decimal_int (buffer, EPHI_ARG_EDGE (node, i)->dest->index);
1397                     pp_string (buffer, " [ ");
1398                     if (EPHI_ARG_HAS_REAL_USE (node, i))
1399                       pp_string (buffer, " real use");
1400                     if (EPHI_ARG_INJURED (node, i))
1401                       pp_string (buffer, " injured");
1402                     if (EPHI_ARG_STOPS (node, i))
1403                       pp_string (buffer, " stops");
1404                     pp_string (buffer, " ] ");
1405                     pp_string (buffer, " defined by:");
1406                     dump_generic_node (buffer, EPHI_ARG_DEF (node, i),
1407                                        spc + 4, flags | TDF_SLIM, false);
1408                   }
1409               }
1410           }
1411         pp_string (buffer, " >");
1412       }
1413       break;
1414     case EEXIT_NODE:
1415     case EKILL_NODE:
1416       if (TREE_CODE (node) == EEXIT_NODE)
1417         pp_string (buffer, "EEXIT (");
1418       else if (TREE_CODE (node) == EKILL_NODE)
1419         pp_string (buffer, "EKILL (");
1420       dump_generic_node (buffer, EREF_NAME (node), spc, flags, false);
1421       pp_string (buffer, ") ");
1422       pp_character (buffer, '[');
1423       pp_string (buffer, "class:");
1424       pp_decimal_int (buffer, EREF_CLASS (node));
1425       pp_string (buffer, " bb:");
1426       pp_decimal_int (buffer, bb_for_stmt (node)->index);
1427       pp_character (buffer, ']');
1428       break;
1429     case EUSE_NODE:
1430       pp_string (buffer, " EUSE (");
1431       dump_generic_node (buffer, EREF_NAME (node), spc, flags, false);
1432
1433       pp_string (buffer, ") ");
1434       pp_character (buffer, '[');
1435       pp_string (buffer, "class:");
1436       pp_decimal_int (buffer, EREF_CLASS (node));
1437       pp_string (buffer, " phiop:");
1438       pp_decimal_int (buffer, EUSE_PHIOP (node));
1439       pp_string (buffer, " bb:");
1440       pp_decimal_int (buffer, bb_for_stmt (node)->index);
1441       if (EUSE_LVAL (node))
1442         pp_string (buffer, " left-occurrence");
1443       pp_string (buffer, " ]");
1444         
1445       break;
1446     case PHI_NODE:
1447       {
1448         int i;
1449
1450         dump_generic_node (buffer, PHI_RESULT (node), spc, flags, false);
1451         pp_string (buffer, " = PHI <");
1452         for (i = 0; i < PHI_NUM_ARGS (node); i++)
1453           {
1454             dump_generic_node (buffer, PHI_ARG_DEF (node, i), spc, flags, false);
1455             pp_string (buffer, "(");
1456             pp_decimal_int (buffer, PHI_ARG_EDGE (node, i)->src->index);
1457             pp_string (buffer, ")");
1458             if (i < PHI_NUM_ARGS (node) - 1)
1459               pp_string (buffer, ", ");
1460           }
1461         pp_string (buffer, ">;");
1462       }
1463       break;
1464
1465     case SSA_NAME:
1466       dump_generic_node (buffer, SSA_NAME_VAR (node), spc, flags, false);
1467       pp_string (buffer, "_");
1468       pp_decimal_int (buffer, SSA_NAME_VERSION (node));
1469       break;
1470
1471     default:
1472       NIY;
1473     }
1474
1475   if (is_stmt && is_expr)
1476     pp_semicolon (buffer);
1477   pp_write_text_to_stream (buffer);
1478
1479   return spc;
1480 }
1481
1482 /* Print the declaration of a variable.  */
1483
1484 static void
1485 print_declaration (pretty_printer *buffer, tree t, int spc, int flags)
1486 {
1487   /* Don't print type declarations.  */
1488   if (TREE_CODE (t) == TYPE_DECL)
1489     return;
1490
1491   INDENT (spc);
1492
1493   if (DECL_REGISTER (t))
1494     pp_string (buffer, "register ");
1495
1496   if (TREE_PUBLIC (t) && DECL_EXTERNAL (t))
1497     pp_string (buffer, "extern ");
1498   else if (TREE_STATIC (t))
1499     pp_string (buffer, "static ");
1500
1501   /* Print the type and name.  */
1502   if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
1503     {
1504       tree tmp;
1505
1506       /* Print array's type.  */
1507       tmp = TREE_TYPE (t);
1508       while (TREE_CODE (TREE_TYPE (tmp)) == ARRAY_TYPE)
1509         tmp = TREE_TYPE (tmp);
1510       dump_generic_node (buffer, TREE_TYPE (tmp), spc, flags, false);
1511
1512       /* Print variable's name.  */
1513       pp_space (buffer);
1514       dump_generic_node (buffer, t, spc, flags, false);
1515
1516       /* Print the dimensions.  */
1517       tmp = TREE_TYPE (t);
1518       while (TREE_CODE (tmp) == ARRAY_TYPE)
1519         {
1520           pp_character (buffer, '[');
1521           if (TYPE_DOMAIN (tmp))
1522             {
1523               if (TREE_CODE (TYPE_SIZE (tmp)) == INTEGER_CST)
1524                 pp_wide_integer (buffer,
1525                                 TREE_INT_CST_LOW (TYPE_SIZE (tmp)) /
1526                                 TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (tmp))));
1527               else
1528                 dump_generic_node (buffer, TYPE_SIZE_UNIT (tmp), spc, flags,
1529                                    false);
1530             }
1531           pp_character (buffer, ']');
1532           tmp = TREE_TYPE (tmp);
1533         }
1534     }
1535   else
1536     {
1537       /* Print type declaration.  */
1538       dump_generic_node (buffer, TREE_TYPE (t), spc, flags, false);
1539
1540       /* Print variable's name.  */
1541       pp_space (buffer);
1542       dump_generic_node (buffer, t, spc, flags, false);
1543     }
1544
1545   /* The initial value of a function serves to determine wether the function
1546      is declared or defined.  So the following does not apply to function
1547      nodes.  */
1548   if (TREE_CODE (t) != FUNCTION_DECL)
1549     {
1550       /* Print the initial value.  */
1551       if (DECL_INITIAL (t))
1552         {
1553           pp_space (buffer);
1554           pp_character (buffer, '=');
1555           pp_space (buffer);
1556           dump_generic_node (buffer, DECL_INITIAL (t), spc, flags, false);
1557         }
1558     }
1559
1560   pp_character (buffer, ';');
1561 }
1562
1563
1564 /* Prints a structure: name, fields, and methods.
1565    FIXME: Still incomplete.  */
1566
1567 static void
1568 print_struct_decl (pretty_printer *buffer, tree node, int spc, int flags)
1569 {
1570   /* Print the name of the structure.  */
1571   if (TYPE_NAME (node))
1572     {
1573       INDENT (spc);
1574       if (TREE_CODE (node) == RECORD_TYPE)
1575         pp_string (buffer, "struct ");
1576       else if (TREE_CODE (node) == UNION_TYPE)
1577         pp_string (buffer, "union ");
1578       else
1579         NIY;
1580       dump_generic_node (buffer, TYPE_NAME (node), spc, 0, false);
1581     }
1582
1583   /* Print the contents of the structure.  */
1584   pp_newline (buffer);
1585   INDENT (spc);
1586   pp_character (buffer, '{');
1587   pp_newline (buffer);
1588
1589   /* Print the fields of the structure.  */
1590   {
1591     tree tmp;
1592     tmp = TYPE_FIELDS (node);
1593     while (tmp)
1594       {
1595         /* Avoid to print recursively the structure.  */
1596         /* FIXME : Not implemented correctly...,
1597            what about the case when we have a cycle in the contain graph? ...
1598            Maybe this could be solved by looking at the scope in which the
1599            structure was declared.  */
1600         if (TREE_TYPE (tmp) != node
1601             || (TREE_CODE (TREE_TYPE (tmp)) == POINTER_TYPE &&
1602                 TREE_TYPE (TREE_TYPE (tmp)) != node))
1603           {
1604             print_declaration (buffer, tmp, spc+2, flags);
1605             pp_newline (buffer);
1606           }
1607         else
1608           {
1609
1610           }
1611         tmp = TREE_CHAIN (tmp);
1612       }
1613   }
1614   INDENT (spc);
1615   pp_character (buffer, '}');
1616 }
1617
1618 /* Return the priority of the operator OP.
1619
1620    From lowest to highest precedence with either left-to-right (L-R)
1621    or right-to-left (R-L) associativity]:
1622
1623      1  [L-R] ,
1624      2  [R-L] = += -= *= /= %= &= ^= |= <<= >>=
1625      3  [R-L] ?:
1626      4  [L-R] ||
1627      5  [L-R] &&
1628      6  [L-R] |
1629      7  [L-R] ^
1630      8  [L-R] &
1631      9  [L-R] == !=
1632     10  [L-R] < <= > >=
1633     11  [L-R] << >>
1634     12  [L-R] + -
1635     13  [L-R] * / %
1636     14  [R-L] ! ~ ++ -- + - * & (type) sizeof
1637     15  [L-R] fn() [] -> .
1638
1639    unary +, - and * have higher precedence than the corresponding binary
1640    operators.  */
1641
1642 static int
1643 op_prio (tree op)
1644 {
1645   if (op == NULL)
1646     return 9999;
1647
1648   switch (TREE_CODE (op))
1649     {
1650     case TREE_LIST:
1651     case COMPOUND_EXPR:
1652     case BIND_EXPR:
1653       return 1;
1654
1655     case MODIFY_EXPR:
1656     case INIT_EXPR:
1657       return 2;
1658
1659     case COND_EXPR:
1660       return 3;
1661
1662     case TRUTH_OR_EXPR:
1663     case TRUTH_ORIF_EXPR:
1664       return 4;
1665
1666     case TRUTH_AND_EXPR:
1667     case TRUTH_ANDIF_EXPR:
1668       return 5;
1669
1670     case BIT_IOR_EXPR:
1671       return 6;
1672
1673     case BIT_XOR_EXPR:
1674     case TRUTH_XOR_EXPR:
1675       return 7;
1676
1677     case BIT_AND_EXPR:
1678       return 8;
1679
1680     case EQ_EXPR:
1681     case NE_EXPR:
1682       return 9;
1683
1684     case LT_EXPR:
1685     case LE_EXPR:
1686     case GT_EXPR:
1687     case GE_EXPR:
1688       return 10;
1689
1690     case LSHIFT_EXPR:
1691     case RSHIFT_EXPR:
1692     case LROTATE_EXPR:
1693     case RROTATE_EXPR:
1694       return 11;
1695
1696     case PLUS_EXPR:
1697     case MINUS_EXPR:
1698       return 12;
1699
1700     case MULT_EXPR:
1701     case TRUNC_DIV_EXPR:
1702     case CEIL_DIV_EXPR:
1703     case FLOOR_DIV_EXPR:
1704     case ROUND_DIV_EXPR:
1705     case RDIV_EXPR:
1706     case EXACT_DIV_EXPR:
1707     case TRUNC_MOD_EXPR:
1708     case CEIL_MOD_EXPR:
1709     case FLOOR_MOD_EXPR:
1710     case ROUND_MOD_EXPR:
1711       return 13;
1712
1713     case TRUTH_NOT_EXPR:
1714     case BIT_NOT_EXPR:
1715     case POSTINCREMENT_EXPR:
1716     case POSTDECREMENT_EXPR:
1717     case PREINCREMENT_EXPR:
1718     case PREDECREMENT_EXPR:
1719     case NEGATE_EXPR:
1720     case INDIRECT_REF:
1721     case ADDR_EXPR:
1722     case FLOAT_EXPR:
1723     case NOP_EXPR:
1724     case CONVERT_EXPR:
1725     case FIX_TRUNC_EXPR:
1726     case FIX_CEIL_EXPR:
1727     case FIX_FLOOR_EXPR:
1728     case FIX_ROUND_EXPR:
1729     case TARGET_EXPR:
1730       return 14;
1731
1732     case CALL_EXPR:
1733     case ARRAY_REF:
1734     case COMPONENT_REF:
1735       return 15;
1736
1737       /* Special expressions.  */
1738     case MIN_EXPR:
1739     case MAX_EXPR:
1740     case ABS_EXPR:
1741     case REALPART_EXPR:
1742     case IMAGPART_EXPR:
1743       return 16;
1744
1745     case SAVE_EXPR:
1746     case NON_LVALUE_EXPR:
1747       return op_prio (TREE_OPERAND (op, 0));
1748
1749     default:
1750       /* Return an arbitrarily high precedence to avoid surrounding single
1751          VAR_DECLs in ()s.  */
1752       return 9999;
1753     }
1754 }
1755
1756
1757 /* Return the symbol associated with operator OP.  */
1758
1759 static const char *
1760 op_symbol (tree op)
1761 {
1762   if (op == NULL)
1763     abort ();
1764
1765   switch (TREE_CODE (op))
1766     {
1767     case MODIFY_EXPR:
1768       return "=";
1769
1770     case TRUTH_OR_EXPR:
1771     case TRUTH_ORIF_EXPR:
1772       return "||";
1773
1774     case TRUTH_AND_EXPR:
1775     case TRUTH_ANDIF_EXPR:
1776       return "&&";
1777
1778     case BIT_IOR_EXPR:
1779       return "|";
1780
1781     case TRUTH_XOR_EXPR:
1782     case BIT_XOR_EXPR:
1783       return "^";
1784
1785     case ADDR_EXPR:
1786     case BIT_AND_EXPR:
1787       return "&";
1788
1789     case EQ_EXPR:
1790     case UNEQ_EXPR:
1791       return "==";
1792
1793     case NE_EXPR:
1794       return "!=";
1795
1796     case LT_EXPR:
1797     case UNLT_EXPR:
1798       return "<";
1799
1800     case LE_EXPR:
1801     case UNLE_EXPR:
1802       return "<=";
1803
1804     case GT_EXPR:
1805     case UNGT_EXPR:
1806       return ">";
1807
1808     case GE_EXPR:
1809     case UNGE_EXPR:
1810       return ">=";
1811
1812     case LSHIFT_EXPR:
1813       return "<<";
1814
1815     case RSHIFT_EXPR:
1816       return ">>";
1817
1818     case PLUS_EXPR:
1819       return "+";
1820
1821     case NEGATE_EXPR:
1822     case MINUS_EXPR:
1823       return "-";
1824
1825     case BIT_NOT_EXPR:
1826       return "~";
1827
1828     case TRUTH_NOT_EXPR:
1829       return "!";
1830
1831     case MULT_EXPR:
1832     case INDIRECT_REF:
1833       return "*";
1834
1835     case TRUNC_DIV_EXPR:
1836     case CEIL_DIV_EXPR:
1837     case FLOOR_DIV_EXPR:
1838     case ROUND_DIV_EXPR:
1839     case RDIV_EXPR:
1840     case EXACT_DIV_EXPR:
1841       return "/";
1842
1843     case TRUNC_MOD_EXPR:
1844     case CEIL_MOD_EXPR:
1845     case FLOOR_MOD_EXPR:
1846     case ROUND_MOD_EXPR:
1847       return "%";
1848
1849     case PREDECREMENT_EXPR:
1850       return " --";
1851
1852     case PREINCREMENT_EXPR:
1853       return " ++";
1854
1855     case POSTDECREMENT_EXPR:
1856       return "-- ";
1857
1858     case POSTINCREMENT_EXPR:
1859       return "++ ";
1860
1861     case REFERENCE_EXPR:
1862       return "";
1863
1864     default:
1865       return "<<< ??? >>>";
1866     }
1867 }
1868
1869 /* Prints the name of a CALL_EXPR.  */
1870
1871 static void
1872 print_call_name (pretty_printer *buffer, tree node)
1873 {
1874   tree op0;
1875
1876   if (TREE_CODE (node) != CALL_EXPR)
1877     abort ();
1878
1879   op0 = TREE_OPERAND (node, 0);
1880
1881   if (TREE_CODE (op0) == NON_LVALUE_EXPR)
1882     op0 = TREE_OPERAND (op0, 0);
1883
1884   switch (TREE_CODE (op0))
1885     {
1886     case VAR_DECL:
1887     case PARM_DECL:
1888       PRINT_FUNCTION_NAME (op0);
1889       break;
1890
1891     case ADDR_EXPR:
1892     case INDIRECT_REF:
1893     case NOP_EXPR:
1894       dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
1895       break;
1896
1897     case COND_EXPR:
1898       pp_string (buffer, "(");
1899       dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
1900       pp_string (buffer, ") ? ");
1901       dump_generic_node (buffer, TREE_OPERAND (op0, 1), 0, 0, false);
1902       pp_string (buffer, " : ");
1903       dump_generic_node (buffer, TREE_OPERAND (op0, 2), 0, 0, false);
1904       break;
1905
1906     case COMPONENT_REF:
1907       /* The function is a pointer contained in a structure.  */
1908       if (TREE_CODE (TREE_OPERAND (op0, 0)) == INDIRECT_REF ||
1909           TREE_CODE (TREE_OPERAND (op0, 0)) == VAR_DECL)
1910         PRINT_FUNCTION_NAME (TREE_OPERAND (op0, 1));
1911       else
1912         dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
1913       /* else
1914          We can have several levels of structures and a function
1915          pointer inside.  This is not implemented yet...  */
1916       /*                  NIY;*/
1917       break;
1918
1919     case ARRAY_REF:
1920       if (TREE_CODE (TREE_OPERAND (op0, 0)) == VAR_DECL)
1921         PRINT_FUNCTION_NAME (TREE_OPERAND (op0, 0));
1922       else
1923         dump_generic_node (buffer, op0, 0, 0, false);
1924       break;
1925
1926     case SSA_NAME:
1927       dump_generic_node (buffer, op0, 0, 0, false);
1928       break;
1929
1930     default:
1931       NIY;
1932     }
1933 }
1934
1935 /* Parses the string STR and replaces new-lines by '\n', tabs by '\t', ...  */
1936
1937 static void
1938 pretty_print_string (pretty_printer *buffer, const char *str)
1939 {
1940   if (str == NULL)
1941     return;
1942
1943   while (*str)
1944     {
1945       switch (str[0])
1946         {
1947         case '\b':
1948           pp_string (buffer, "\\b");
1949           break;
1950
1951         case '\f':
1952           pp_string (buffer, "\\f");
1953           break;
1954
1955         case '\n':
1956           pp_string (buffer, "\\n");
1957           break;
1958
1959         case '\r':
1960           pp_string (buffer, "\\r");
1961           break;
1962
1963         case '\t':
1964           pp_string (buffer, "\\t");
1965           break;
1966
1967         case '\v':
1968           pp_string (buffer, "\\v");
1969           break;
1970
1971         case '\\':
1972           pp_string (buffer, "\\\\");
1973           break;
1974
1975         case '\"':
1976           pp_string (buffer, "\\\"");
1977           break;
1978
1979         case '\'':
1980           pp_string (buffer, "\\'");
1981           break;
1982
1983         case '\0':
1984           pp_string (buffer, "\\0");
1985           break;
1986
1987         case '\1':
1988           pp_string (buffer, "\\1");
1989           break;
1990
1991         case '\2':
1992           pp_string (buffer, "\\2");
1993           break;
1994
1995         case '\3':
1996           pp_string (buffer, "\\3");
1997           break;
1998
1999         case '\4':
2000           pp_string (buffer, "\\4");
2001           break;
2002
2003         case '\5':
2004           pp_string (buffer, "\\5");
2005           break;
2006
2007         case '\6':
2008           pp_string (buffer, "\\6");
2009           break;
2010
2011         case '\7':
2012           pp_string (buffer, "\\7");
2013           break;
2014
2015         default:
2016           pp_character (buffer, str[0]);
2017           break;
2018         }
2019       str++;
2020     }
2021 }
2022
2023 static void
2024 maybe_init_pretty_print (FILE *file)
2025 {
2026   if (!initialized)
2027     {
2028       pp_construct (&buffer, /* prefix */NULL, /* line-width */0);
2029       pp_needs_newline (&buffer) = true;
2030       initialized = 1;
2031     }
2032
2033   buffer.buffer->stream = file;
2034 }
2035
2036 static void
2037 newline_and_indent (pretty_printer *buffer, int spc)
2038 {
2039   pp_newline (buffer);
2040   INDENT (spc);
2041 }
2042
2043 static void
2044 dump_vops (pretty_printer *buffer, tree stmt, int spc, int flags)
2045 {
2046   size_t i;
2047   stmt_ann_t ann = stmt_ann (stmt);
2048   vdef_optype vdefs = VDEF_OPS (ann);
2049   vuse_optype vuses = VUSE_OPS (ann);
2050
2051   for (i = 0; i < NUM_VDEFS (vdefs); i++)
2052     {
2053       pp_string (buffer, "#   ");
2054       dump_generic_node (buffer, VDEF_RESULT (vdefs, i), spc + 2, flags, false);
2055       pp_string (buffer, " = VDEF <");
2056       dump_generic_node (buffer, VDEF_OP (vdefs, i), spc + 2, flags, false);
2057       pp_string (buffer, ">;");
2058       newline_and_indent (buffer, spc);
2059     }
2060
2061   for (i = 0; i < NUM_VUSES (vuses); i++)
2062     {
2063       tree vuse = VUSE_OP (vuses, i);
2064       pp_string (buffer, "#   VUSE <");
2065       dump_generic_node (buffer, vuse, spc + 2, flags, false);
2066       pp_string (buffer, ">;");
2067       newline_and_indent (buffer, spc);
2068     }
2069 }
2070
2071 /* Dumps basic block BB to FILE with details described by FLAGS and
2072    indented by INDENT spaces.  */
2073
2074 void
2075 dump_generic_bb (FILE *file, basic_block bb, int indent, int flags)
2076 {
2077   maybe_init_pretty_print (file);
2078   dumping_stmts = true;
2079   dump_generic_bb_buff (&buffer, bb, indent, flags);
2080   pp_flush (&buffer);
2081 }
2082
2083 /* Dumps header of basic block BB to buffer BUFFER indented by INDENT
2084    spaces and details described by flags.  */
2085
2086 static void
2087 dump_bb_header (pretty_printer *buffer, basic_block bb, int indent, int flags)
2088 {
2089   edge e;
2090   tree stmt;
2091
2092   if (flags & TDF_BLOCKS)
2093     {
2094       INDENT (indent);
2095       pp_string (buffer, "# BLOCK ");
2096       pp_decimal_int (buffer, bb->index);
2097
2098       if (flags & TDF_LINENO)
2099         {
2100           block_stmt_iterator bsi;
2101
2102           for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
2103             if (get_lineno (bsi_stmt (bsi)) != -1)
2104               {
2105                 pp_string (buffer, ", starting at line ");
2106                 pp_decimal_int (buffer, get_lineno (bsi_stmt (bsi)));
2107                 break;
2108               }
2109         }
2110       newline_and_indent (buffer, indent);
2111
2112       pp_string (buffer, "# PRED:");
2113       pp_write_text_to_stream (buffer);
2114       for (e = bb->pred; e; e = e->pred_next)
2115         if (flags & TDF_SLIM)
2116           {
2117             pp_string (buffer, " ");
2118             if (e->src == ENTRY_BLOCK_PTR)
2119               pp_string (buffer, "ENTRY");
2120             else
2121               pp_decimal_int (buffer, e->src->index);
2122           }
2123         else
2124           dump_edge_info (buffer->buffer->stream, e, 0);
2125       pp_newline (buffer);
2126     }
2127   else
2128     {
2129       stmt = first_stmt (bb);
2130       if (!stmt || TREE_CODE (stmt) != LABEL_EXPR)
2131         {
2132           INDENT (indent - 2);
2133           pp_string (buffer, "<bb ");
2134           pp_decimal_int (buffer, bb->index);
2135           pp_string (buffer, ">:");
2136           pp_newline (buffer);
2137         }
2138     }
2139 }
2140
2141 /* Dumps end of basic block BB to buffer BUFFER indented by INDENT
2142    spaces.  */
2143
2144 static void
2145 dump_bb_end (pretty_printer *buffer, basic_block bb, int indent, int flags)
2146 {
2147   edge e;
2148
2149   INDENT (indent);
2150   pp_string (buffer, "# SUCC:");
2151   pp_write_text_to_stream (buffer);
2152   for (e = bb->succ; e; e = e->succ_next)
2153     if (flags & TDF_SLIM)
2154       {
2155         pp_string (buffer, " ");
2156         if (e->dest == EXIT_BLOCK_PTR)
2157           pp_string (buffer, "EXIT");
2158         else
2159           pp_decimal_int (buffer, e->dest->index);
2160       }
2161     else
2162       dump_edge_info (buffer->buffer->stream, e, 1);
2163   pp_newline (buffer);
2164 }
2165
2166 /* Dumps phi nodes of basic block BB to buffer BUFFER with details described by
2167    FLAGS indented by INDENT spaces.  */
2168
2169 static void
2170 dump_phi_nodes (pretty_printer *buffer, basic_block bb, int indent, int flags)
2171 {
2172   tree phi = phi_nodes (bb);
2173   if (!phi)
2174     return;
2175
2176   for (; phi; phi = TREE_CHAIN (phi))
2177     {
2178       if (is_gimple_reg (PHI_RESULT (phi)) || (flags & TDF_VOPS))
2179         {
2180           INDENT (indent);
2181           pp_string (buffer, "# ");
2182           dump_generic_node (buffer, phi, indent, flags, false);
2183           pp_newline (buffer);
2184         }
2185     }
2186 }
2187
2188 /* Dump jump to basic block BB that is represented implicitly in the cfg
2189    to BUFFER.  */
2190
2191 static void
2192 pp_cfg_jump (pretty_printer *buffer, basic_block bb)
2193 {
2194   tree stmt;
2195
2196   stmt = first_stmt (bb);
2197
2198   pp_string (buffer, "goto <bb ");
2199   pp_decimal_int (buffer, bb->index);
2200   pp_string (buffer, ">");
2201   if (stmt && TREE_CODE (stmt) == LABEL_EXPR)
2202     {
2203       pp_string (buffer, " (");
2204       dump_generic_node (buffer, LABEL_EXPR_LABEL (stmt), 0, 0, false);
2205       pp_string (buffer, ")");
2206     }
2207   pp_semicolon (buffer);
2208 }
2209
2210 /* Dump edges represented implicitly in basic block BB to BUFFER, indented
2211    by INDENT spaces, with details given by FLAGS.  */
2212
2213 static void
2214 dump_implicit_edges (pretty_printer *buffer, basic_block bb, int indent)
2215 {
2216   edge e;
2217
2218   /* If there is a fallthru edge, we may need to add an artificial goto to the
2219      dump.  */
2220   for (e = bb->succ; e; e = e->succ_next)
2221     if (e->flags & EDGE_FALLTHRU)
2222       break;
2223   if (e && e->dest != bb->next_bb)
2224     {
2225       INDENT (indent);
2226       pp_cfg_jump (buffer, e->dest);
2227       pp_newline (buffer);
2228     }
2229 }
2230
2231 /* Dumps basic block BB to buffer BUFFER with details described by FLAGS and
2232    indented by INDENT spaces.  */
2233
2234 static void
2235 dump_generic_bb_buff (pretty_printer *buffer, basic_block bb,
2236                       int indent, int flags)
2237 {
2238   block_stmt_iterator bsi;
2239   tree stmt;
2240   int label_indent = indent - 2;
2241
2242   if (label_indent < 0)
2243     label_indent = 0;
2244
2245   dump_bb_header (buffer, bb, indent, flags);
2246
2247   if (bb_ann (bb))
2248     dump_phi_nodes (buffer, bb, indent, flags);
2249   
2250   for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
2251     {
2252       int curr_indent;
2253
2254       stmt = bsi_stmt (bsi);
2255
2256       curr_indent = TREE_CODE (stmt) == LABEL_EXPR ? label_indent : indent;
2257
2258       INDENT (curr_indent);
2259       dump_generic_node (buffer, stmt, curr_indent, flags, true);
2260       pp_newline (buffer);
2261     }
2262
2263   dump_implicit_edges (buffer, bb, indent);
2264
2265   if (flags & TDF_BLOCKS)
2266     dump_bb_end (buffer, bb, indent, flags);
2267 }