OSDN Git Service

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