OSDN Git Service

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