OSDN Git Service

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