OSDN Git Service

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