OSDN Git Service

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