OSDN Git Service

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