OSDN Git Service

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