OSDN Git Service

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