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