OSDN Git Service

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