OSDN Git Service

fac5d29cac5106cd2bc7ef9ffd00f64ce7a3ee45
[pf3gnuchains/gcc-fork.git] / gcc / tree-pretty-print.c
1 /* Pretty formatting of GENERIC trees in C syntax.
2    Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 
3    Free Software Foundation, Inc.
4    Adapted from c-pretty-print.c by Diego Novillo <dnovillo@redhat.com>
5
6 This file is part of GCC.
7
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 2, or (at your option) any later
11 version.
12
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16 for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING.  If not, write to the Free
20 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
21 02110-1301, USA.  */
22
23 #include "config.h"
24 #include "system.h"
25 #include "coretypes.h"
26 #include "tm.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 #include "tree-pass.h"
36
37 /* Local functions, macros and variables.  */
38 static int op_prio (tree);
39 static const char *op_symbol_1 (enum tree_code);
40 static const char *op_symbol (tree);
41 static void pretty_print_string (pretty_printer *, const char*);
42 static void print_call_name (pretty_printer *, tree);
43 static void newline_and_indent (pretty_printer *, int);
44 static void maybe_init_pretty_print (FILE *);
45 static void print_declaration (pretty_printer *, tree, int, int);
46 static void print_struct_decl (pretty_printer *, tree, int, int);
47 static void do_niy (pretty_printer *, tree);
48 static void dump_vops (pretty_printer *, tree, int, int);
49 static void dump_generic_bb_buff (pretty_printer *, basic_block, int, int);
50
51 #define INDENT(SPACE) do { \
52   int i; for (i = 0; i<SPACE; i++) pp_space (buffer); } while (0)
53
54 #define NIY do_niy(buffer,node)
55
56 #define PRINT_FUNCTION_NAME(NODE)  pp_printf             \
57   (buffer, "%s", TREE_CODE (NODE) == NOP_EXPR ?              \
58    lang_hooks.decl_printable_name (TREE_OPERAND (NODE, 0), 1) : \
59    lang_hooks.decl_printable_name (NODE, 1))
60
61 static pretty_printer buffer;
62 static int initialized = 0;
63
64 /* Try to print something for an unknown tree code.  */
65
66 static void
67 do_niy (pretty_printer *buffer, tree node)
68 {
69   int i, len;
70
71   pp_string (buffer, "<<< Unknown tree: ");
72   pp_string (buffer, tree_code_name[(int) TREE_CODE (node)]);
73
74   if (EXPR_P (node))
75     {
76       len = TREE_CODE_LENGTH (TREE_CODE (node));
77       for (i = 0; i < len; ++i)
78         {
79           newline_and_indent (buffer, 2);
80           dump_generic_node (buffer, TREE_OPERAND (node, i), 2, 0, false);
81         }
82     }
83
84   pp_string (buffer, " >>>\n");
85 }
86
87 void
88 debug_generic_expr (tree t)
89 {
90   print_generic_expr (stderr, t, TDF_VOPS|TDF_MEMSYMS);
91   fprintf (stderr, "\n");
92 }
93
94 void
95 debug_generic_stmt (tree t)
96 {
97   print_generic_stmt (stderr, t, TDF_VOPS|TDF_MEMSYMS);
98   fprintf (stderr, "\n");
99 }
100
101 void
102 debug_tree_chain (tree t)
103 {
104   while (t)
105   {
106     print_generic_expr (stderr, t, TDF_VOPS|TDF_MEMSYMS|TDF_UID);
107     fprintf(stderr, " ");
108     t = TREE_CHAIN (t);
109   }
110   fprintf (stderr, "\n");
111 }
112
113 /* Prints declaration DECL to the FILE with details specified by FLAGS.  */
114 void
115 print_generic_decl (FILE *file, tree decl, int flags)
116 {
117   maybe_init_pretty_print (file);
118   print_declaration (&buffer, decl, 2, flags);
119   pp_write_text_to_stream (&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.  */
124
125 void
126 print_generic_stmt (FILE *file, tree t, int flags)
127 {
128   maybe_init_pretty_print (file);
129   dump_generic_node (&buffer, t, 0, flags, true);
130   pp_flush (&buffer);
131 }
132
133 /* Print tree T, and its successors, on file FILE.  FLAGS specifies details
134    to show in the dump.  See TDF_* in tree.h.  The output is indented by
135    INDENT spaces.  */
136
137 void
138 print_generic_stmt_indented (FILE *file, tree t, int flags, int indent)
139 {
140   int i;
141
142   maybe_init_pretty_print (file);
143
144   for (i = 0; i < indent; i++)
145     pp_space (&buffer);
146   dump_generic_node (&buffer, t, indent, flags, true);
147   pp_flush (&buffer);
148 }
149
150 /* Print a single expression T on file FILE.  FLAGS specifies details to show
151    in the dump.  See TDF_* in tree.h.  */
152
153 void
154 print_generic_expr (FILE *file, tree t, int flags)
155 {
156   maybe_init_pretty_print (file);
157   dump_generic_node (&buffer, t, 0, flags, false);
158 }
159
160 /* Dump the name of a _DECL node and its DECL_UID if TDF_UID is set
161    in FLAGS.  */
162
163 static void
164 dump_decl_name (pretty_printer *buffer, tree node, int flags)
165 {
166   tree t = node;
167
168   if (DECL_NAME (t))
169     pp_tree_identifier (buffer, DECL_NAME (t));
170   if ((flags & TDF_UID)
171       || DECL_NAME (t) == NULL_TREE)
172     {
173       if (TREE_CODE (t) == LABEL_DECL
174           && LABEL_DECL_UID (t) != -1)
175         pp_printf (buffer, "L." HOST_WIDE_INT_PRINT_DEC,
176                    LABEL_DECL_UID (t));
177       else
178         {
179           char c = TREE_CODE (t) == CONST_DECL ? 'C' : 'D';
180           pp_printf (buffer, "%c.%u", c, DECL_UID (t));
181         }
182     }
183 }
184
185 /* Like the above, but used for pretty printing function calls.  */
186
187 static void
188 dump_function_name (pretty_printer *buffer, tree node)
189 {
190   if (DECL_NAME (node))
191     PRINT_FUNCTION_NAME (node);
192   else
193     dump_decl_name (buffer, node, 0);
194 }
195
196 /* Dump a function declaration.  NODE is the FUNCTION_TYPE.  BUFFER, SPC and
197    FLAGS are as in dump_generic_node.  */
198
199 static void
200 dump_function_declaration (pretty_printer *buffer, tree node,
201                            int spc, int flags)
202 {
203   bool wrote_arg = false;
204   tree arg;
205
206   pp_space (buffer);
207   pp_character (buffer, '(');
208
209   /* Print the argument types.  The last element in the list is a VOID_TYPE.
210      The following avoids printing the last element.  */
211   arg = TYPE_ARG_TYPES (node);
212   while (arg && TREE_CHAIN (arg) && arg != error_mark_node)
213     {
214       wrote_arg = true;
215       dump_generic_node (buffer, TREE_VALUE (arg), spc, flags, false);
216       arg = TREE_CHAIN (arg);
217       if (TREE_CHAIN (arg) && TREE_CODE (TREE_CHAIN (arg)) == TREE_LIST)
218         {
219           pp_character (buffer, ',');
220           pp_space (buffer);
221         }
222     }
223
224   if (!wrote_arg)
225     pp_string (buffer, "void");
226
227   pp_character (buffer, ')');
228 }
229
230 /* Dump the domain associated with an array.  */
231
232 static void
233 dump_array_domain (pretty_printer *buffer, tree domain, int spc, int flags)
234 {
235   pp_character (buffer, '[');
236   if (domain)
237     {
238       tree min = TYPE_MIN_VALUE (domain);
239       tree max = TYPE_MAX_VALUE (domain);
240
241       if (min && max
242           && integer_zerop (min)
243           && host_integerp (max, 0))
244         pp_wide_integer (buffer, TREE_INT_CST_LOW (max) + 1);
245       else
246         {
247           if (min)
248             dump_generic_node (buffer, min, spc, flags, false);
249           pp_character (buffer, ':');
250           if (max)
251             dump_generic_node (buffer, max, spc, flags, false);
252         }
253     }
254   else
255     pp_string (buffer, "<unknown>");
256   pp_character (buffer, ']');
257 }
258
259
260 /* Dump OpenMP clause CLAUSE.  BUFFER, CLAUSE, SPC and FLAGS are as in
261    dump_generic_node.  */
262
263 static void
264 dump_omp_clause (pretty_printer *buffer, tree clause, int spc, int flags)
265 {
266   const char *name;
267
268   switch (OMP_CLAUSE_CODE (clause))
269     {
270     case OMP_CLAUSE_PRIVATE:
271       name = "private";
272       goto print_remap;
273     case OMP_CLAUSE_SHARED:
274       name = "shared";
275       goto print_remap;
276     case OMP_CLAUSE_FIRSTPRIVATE:
277       name = "firstprivate";
278       goto print_remap;
279     case OMP_CLAUSE_LASTPRIVATE:
280       name = "lastprivate";
281       goto print_remap;
282     case OMP_CLAUSE_COPYIN:
283       name = "copyin";
284       goto print_remap;
285     case OMP_CLAUSE_COPYPRIVATE:
286       name = "copyprivate";
287       goto print_remap;
288   print_remap:
289       pp_string (buffer, name);
290       pp_character (buffer, '(');
291       dump_generic_node (buffer, OMP_CLAUSE_DECL (clause),
292           spc, flags, false);
293       pp_character (buffer, ')');
294       break;
295
296     case OMP_CLAUSE_REDUCTION:
297       pp_string (buffer, "reduction(");
298       pp_string (buffer, op_symbol_1 (OMP_CLAUSE_REDUCTION_CODE (clause)));
299       pp_character (buffer, ':');
300       dump_generic_node (buffer, OMP_CLAUSE_DECL (clause),
301           spc, flags, false);
302       pp_character (buffer, ')');
303       break;
304
305     case OMP_CLAUSE_IF:
306       pp_string (buffer, "if(");
307       dump_generic_node (buffer, OMP_CLAUSE_IF_EXPR (clause),
308           spc, flags, false);
309       pp_character (buffer, ')');
310       break;
311
312     case OMP_CLAUSE_NUM_THREADS:
313       pp_string (buffer, "num_threads(");
314       dump_generic_node (buffer, OMP_CLAUSE_NUM_THREADS_EXPR (clause),
315           spc, flags, false);
316       pp_character (buffer, ')');
317       break;
318
319     case OMP_CLAUSE_NOWAIT:
320       pp_string (buffer, "nowait");
321       break;
322     case OMP_CLAUSE_ORDERED:
323       pp_string (buffer, "ordered");
324       break;
325
326     case OMP_CLAUSE_DEFAULT:
327       pp_string (buffer, "default(");
328       switch (OMP_CLAUSE_DEFAULT_KIND (clause))
329         {
330       case OMP_CLAUSE_DEFAULT_UNSPECIFIED:
331         break;
332       case OMP_CLAUSE_DEFAULT_SHARED:
333         pp_string (buffer, "shared");
334         break;
335       case OMP_CLAUSE_DEFAULT_NONE:
336         pp_string (buffer, "none");
337         break;
338       case OMP_CLAUSE_DEFAULT_PRIVATE:
339         pp_string (buffer, "private");
340         break;
341       default:
342         gcc_unreachable ();
343         }
344       pp_character (buffer, ')');
345       break;
346
347     case OMP_CLAUSE_SCHEDULE:
348       pp_string (buffer, "schedule(");
349       switch (OMP_CLAUSE_SCHEDULE_KIND (clause))
350         {
351       case OMP_CLAUSE_SCHEDULE_STATIC:
352         pp_string (buffer, "static");
353         break;
354       case OMP_CLAUSE_SCHEDULE_DYNAMIC:
355         pp_string (buffer, "dynamic");
356         break;
357       case OMP_CLAUSE_SCHEDULE_GUIDED:
358         pp_string (buffer, "guided");
359         break;
360       case OMP_CLAUSE_SCHEDULE_RUNTIME:
361         pp_string (buffer, "runtime");
362         break;
363       default:
364         gcc_unreachable ();
365         }
366       if (OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (clause))
367         {
368           pp_character (buffer, ',');
369           dump_generic_node (buffer,
370               OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (clause),
371               spc, flags, false);
372         }
373       pp_character (buffer, ')');
374       break;
375
376     default:
377       /* Should never happen.  */
378       dump_generic_node (buffer, clause, spc, flags, false);
379       break;
380     }
381 }
382
383
384 /* Dump the list of OpenMP clauses.  BUFFER, SPC and FLAGS are as in
385    dump_generic_node.  */
386
387 static void
388 dump_omp_clauses (pretty_printer *buffer, tree clause, int spc, int flags)
389 {
390   if (clause == NULL)
391     return;
392
393   pp_space (buffer);
394   while (1)
395     {
396       dump_omp_clause (buffer, clause, spc, flags);
397       clause = OMP_CLAUSE_CHAIN (clause);
398       if (clause == NULL)
399         return;
400       pp_space (buffer);
401     }
402 }
403
404
405 /* Dump the set of decls SYMS.  BUFFER, SPC and FLAGS are as in
406    dump_generic_node.  */
407
408 static void
409 dump_symbols (pretty_printer *buffer, bitmap syms, int flags)
410 {
411   unsigned i;
412   bitmap_iterator bi;
413
414   if (syms == NULL)
415     pp_string (buffer, "NIL");
416   else
417     {
418       pp_string (buffer, " { ");
419
420       EXECUTE_IF_SET_IN_BITMAP (syms, 0, i, bi)
421         {
422           tree sym = referenced_var_lookup (i);
423           dump_generic_node (buffer, sym, 0, flags, false);
424           pp_string (buffer, " ");
425         }
426
427       pp_string (buffer, "}");
428     }
429 }
430
431
432 /* Dump the node NODE on the pretty_printer BUFFER, SPC spaces of indent.
433    FLAGS specifies details to show in the dump (see TDF_* in tree.h).  If
434    IS_STMT is true, the object printed is considered to be a statement
435    and it is terminated by ';' if appropriate.  */
436
437 int
438 dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
439                    bool is_stmt)
440 {
441   tree type;
442   tree op0, op1;
443   const char *str;
444   bool is_expr;
445
446   if (node == NULL_TREE)
447     return spc;
448
449   is_expr = EXPR_P (node) || GIMPLE_STMT_P (node);
450
451   /* We use has_stmt_ann because CALL_EXPR can be both an expression
452      and a statement, and we have no guarantee that it will have a
453      stmt_ann when it is used as an RHS expression.  stmt_ann will assert
454      if you call it on something with a non-stmt annotation attached.  */
455   if (TREE_CODE (node) != ERROR_MARK
456       && is_gimple_stmt (node)
457       && (flags & (TDF_VOPS|TDF_MEMSYMS))
458       && has_stmt_ann (node)
459       && TREE_CODE (node) != PHI_NODE)
460     dump_vops (buffer, node, spc, flags);
461
462   if (is_stmt && (flags & TDF_STMTADDR))
463     pp_printf (buffer, "<&%p> ", (void *)node);
464
465   if ((flags & TDF_LINENO) && EXPR_HAS_LOCATION (node))
466     {
467       expanded_location xloc = expand_location (EXPR_LOCATION (node));
468       pp_character (buffer, '[');
469       if (xloc.file)
470         {
471           pp_string (buffer, xloc.file);
472           pp_string (buffer, " : ");
473         }
474       pp_decimal_int (buffer, xloc.line);
475       pp_string (buffer, "] ");
476     }
477
478   switch (TREE_CODE (node))
479     {
480     case ERROR_MARK:
481       pp_string (buffer, "<<< error >>>");
482       break;
483
484     case IDENTIFIER_NODE:
485       pp_tree_identifier (buffer, node);
486       break;
487
488     case TREE_LIST:
489       while (node && node != error_mark_node)
490         {
491           if (TREE_PURPOSE (node))
492             {
493               dump_generic_node (buffer, TREE_PURPOSE (node), spc, flags, false);
494               pp_space (buffer);
495             }
496           dump_generic_node (buffer, TREE_VALUE (node), spc, flags, false);
497           node = TREE_CHAIN (node);
498           if (node && TREE_CODE (node) == TREE_LIST)
499             {
500               pp_character (buffer, ',');
501               pp_space (buffer);
502             }
503         }
504       break;
505
506     case TREE_BINFO:
507       dump_generic_node (buffer, BINFO_TYPE (node), spc, flags, false);
508
509     case TREE_VEC:
510       {
511         size_t i;
512         if (TREE_VEC_LENGTH (node) > 0)
513           {
514             size_t len = TREE_VEC_LENGTH (node);
515             for (i = 0; i < len - 1; i++)
516               {     
517                 dump_generic_node (buffer, TREE_VEC_ELT (node, i), spc, flags,
518                                    false);
519                 pp_character (buffer, ',');
520                 pp_space (buffer);
521               }
522             dump_generic_node (buffer, TREE_VEC_ELT (node, len - 1), spc, 
523                                flags, false);
524           }
525       }
526       break;
527
528     case VOID_TYPE:
529     case INTEGER_TYPE:
530     case REAL_TYPE:
531     case COMPLEX_TYPE:
532     case VECTOR_TYPE:
533     case ENUMERAL_TYPE:
534     case BOOLEAN_TYPE:
535       {
536         unsigned int quals = TYPE_QUALS (node);
537         enum tree_code_class class;
538
539         if (quals & TYPE_QUAL_CONST)
540           pp_string (buffer, "const ");
541         else if (quals & TYPE_QUAL_VOLATILE)
542           pp_string (buffer, "volatile ");
543         else if (quals & TYPE_QUAL_RESTRICT)
544           pp_string (buffer, "restrict ");
545
546         class = TREE_CODE_CLASS (TREE_CODE (node));
547
548         if (class == tcc_declaration)
549           {
550             if (DECL_NAME (node))
551               dump_decl_name (buffer, node, flags);
552             else
553               pp_string (buffer, "<unnamed type decl>");
554           }
555         else if (class == tcc_type)
556           {
557             if (TYPE_NAME (node))
558               {
559                 if (TREE_CODE (TYPE_NAME (node)) == IDENTIFIER_NODE)
560                   pp_tree_identifier (buffer, TYPE_NAME (node));
561                 else if (TREE_CODE (TYPE_NAME (node)) == TYPE_DECL
562                          && DECL_NAME (TYPE_NAME (node)))
563                   dump_decl_name (buffer, TYPE_NAME (node), flags);
564                 else
565                   pp_string (buffer, "<unnamed type>");
566               }
567             else if (TREE_CODE (node) == VECTOR_TYPE)
568               {
569                 pp_string (buffer, "vector ");
570                 dump_generic_node (buffer, TREE_TYPE (node), 
571                                    spc, flags, false);
572               }
573             else
574               pp_string (buffer, "<unnamed type>");
575           }
576         break;
577       }
578
579     case POINTER_TYPE:
580     case REFERENCE_TYPE:
581       str = (TREE_CODE (node) == POINTER_TYPE ? "*" : "&");
582
583       if (TREE_CODE (TREE_TYPE (node)) == FUNCTION_TYPE)
584         {
585           tree fnode = TREE_TYPE (node);
586
587           dump_generic_node (buffer, TREE_TYPE (fnode), spc, flags, false);
588           pp_space (buffer);
589           pp_character (buffer, '(');
590           pp_string (buffer, str);
591           if (TYPE_NAME (node) && DECL_NAME (TYPE_NAME (node)))
592             dump_decl_name (buffer, TYPE_NAME (node), flags);
593           else
594             pp_printf (buffer, "<T%x>", TYPE_UID (node));
595
596           pp_character (buffer, ')');
597           dump_function_declaration (buffer, fnode, spc, flags);
598         }
599       else
600         {
601           unsigned int quals = TYPE_QUALS (node);
602
603           dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
604           pp_space (buffer);
605           pp_string (buffer, str);
606
607           if (quals & TYPE_QUAL_CONST)
608             pp_string (buffer, " const");
609           else if (quals & TYPE_QUAL_VOLATILE)
610             pp_string (buffer,  "volatile");
611           else if (quals & TYPE_QUAL_RESTRICT)
612             pp_string (buffer, " restrict");
613
614           if (TYPE_REF_CAN_ALIAS_ALL (node))
615             pp_string (buffer, " {ref-all}");
616         }
617       break;
618
619     case OFFSET_TYPE:
620       NIY;
621       break;
622
623     case METHOD_TYPE:
624       dump_decl_name (buffer, TYPE_NAME (TYPE_METHOD_BASETYPE (node)), flags);
625       pp_string (buffer, "::");
626       break;
627
628     case TARGET_MEM_REF:
629       {
630         const char *sep = "";
631         tree tmp;
632
633         pp_string (buffer, "MEM[");
634
635         tmp = TMR_SYMBOL (node);
636         if (tmp)
637           {
638             pp_string (buffer, sep);
639             sep = ", ";
640             pp_string (buffer, "symbol: ");
641             dump_generic_node (buffer, tmp, spc, flags, false);
642           }
643         tmp = TMR_BASE (node);
644         if (tmp)
645           {
646             pp_string (buffer, sep);
647             sep = ", ";
648             pp_string (buffer, "base: ");
649             dump_generic_node (buffer, tmp, spc, flags, false);
650           }
651         tmp = TMR_INDEX (node);
652         if (tmp)
653           {
654             pp_string (buffer, sep);
655             sep = ", ";
656             pp_string (buffer, "index: ");
657             dump_generic_node (buffer, tmp, spc, flags, false);
658           }
659         tmp = TMR_STEP (node);
660         if (tmp)
661           {
662             pp_string (buffer, sep);
663             sep = ", ";
664             pp_string (buffer, "step: ");
665             dump_generic_node (buffer, tmp, spc, flags, false);
666           }
667         tmp = TMR_OFFSET (node);
668         if (tmp)
669           {
670             pp_string (buffer, sep);
671             sep = ", ";
672             pp_string (buffer, "offset: ");
673             dump_generic_node (buffer, tmp, spc, flags, false);
674           }
675         pp_string (buffer, "]");
676         if (flags & TDF_DETAILS)
677           {
678             pp_string (buffer, "{");
679             dump_generic_node (buffer, TMR_ORIGINAL (node), spc, flags,
680                                false);
681             pp_string (buffer, "}");
682           }
683       }
684       break;
685
686     case ARRAY_TYPE:
687       {
688         tree tmp;
689
690         /* Print the innermost component type.  */
691         for (tmp = TREE_TYPE (node); TREE_CODE (tmp) == ARRAY_TYPE;
692              tmp = TREE_TYPE (tmp))
693           ;
694         dump_generic_node (buffer, tmp, spc, flags, false);
695
696         /* Print the dimensions.  */
697         for (tmp = node; TREE_CODE (tmp) == ARRAY_TYPE; tmp = TREE_TYPE (tmp))
698           dump_array_domain (buffer, TYPE_DOMAIN (tmp), spc, flags);
699         break;
700       }
701
702     case RECORD_TYPE:
703     case UNION_TYPE:
704     case QUAL_UNION_TYPE:
705       /* Print the name of the structure.  */
706       if (TREE_CODE (node) == RECORD_TYPE)
707         pp_string (buffer, "struct ");
708       else if (TREE_CODE (node) == UNION_TYPE)
709         pp_string (buffer, "union ");
710
711       if (TYPE_NAME (node))
712         dump_generic_node (buffer, TYPE_NAME (node), spc, flags, false);
713       else
714         print_struct_decl (buffer, node, spc, flags);
715       break;
716
717     case LANG_TYPE:
718       NIY;
719       break;
720
721     case INTEGER_CST:
722       if (TREE_CODE (TREE_TYPE (node)) == POINTER_TYPE)
723         {
724           /* In the case of a pointer, one may want to divide by the
725              size of the pointed-to type.  Unfortunately, this not
726              straightforward.  The C front-end maps expressions
727
728              (int *) 5
729              int *p; (p + 5)
730
731              in such a way that the two INTEGER_CST nodes for "5" have
732              different values but identical types.  In the latter
733              case, the 5 is multiplied by sizeof (int) in c-common.c
734              (pointer_int_sum) to convert it to a byte address, and
735              yet the type of the node is left unchanged.  Argh.  What
736              is consistent though is that the number value corresponds
737              to bytes (UNITS) offset.
738
739              NB: Neither of the following divisors can be trivially
740              used to recover the original literal:
741
742              TREE_INT_CST_LOW (TYPE_SIZE_UNIT (TREE_TYPE (node)))
743              TYPE_PRECISION (TREE_TYPE (TREE_TYPE (node)))  */
744           pp_wide_integer (buffer, TREE_INT_CST_LOW (node));
745           pp_string (buffer, "B"); /* pseudo-unit */
746         }
747       else if (! host_integerp (node, 0))
748         {
749           tree val = node;
750
751           if (tree_int_cst_sgn (val) < 0)
752             {
753               pp_character (buffer, '-');
754               val = build_int_cst_wide (NULL_TREE,
755                                         -TREE_INT_CST_LOW (val),
756                                         ~TREE_INT_CST_HIGH (val)
757                                         + !TREE_INT_CST_LOW (val));
758             }
759           /* Would "%x%0*x" or "%x%*0x" get zero-padding on all
760              systems?  */
761           {
762             sprintf (pp_buffer (buffer)->digit_buffer, HOST_WIDE_INT_PRINT_DOUBLE_HEX,
763                      TREE_INT_CST_HIGH (val),
764                      TREE_INT_CST_LOW (val));
765             pp_string (buffer, pp_buffer (buffer)->digit_buffer);
766           }
767         }
768       else
769         pp_wide_integer (buffer, TREE_INT_CST_LOW (node));
770       break;
771
772     case REAL_CST:
773       /* Code copied from print_node.  */
774       {
775         REAL_VALUE_TYPE d;
776         if (TREE_OVERFLOW (node))
777           pp_string (buffer, " overflow");
778
779 #if !defined(REAL_IS_NOT_DOUBLE) || defined(REAL_ARITHMETIC)
780         d = TREE_REAL_CST (node);
781         if (REAL_VALUE_ISINF (d))
782           pp_string (buffer, REAL_VALUE_NEGATIVE (d) ? " -Inf" : " Inf");
783         else if (REAL_VALUE_ISNAN (d))
784           pp_string (buffer, " Nan");
785         else
786           {
787             char string[100];
788             real_to_decimal (string, &d, sizeof (string), 0, 1);
789             pp_string (buffer, string);
790           }
791 #else
792         {
793           HOST_WIDE_INT i;
794           unsigned char *p = (unsigned char *) &TREE_REAL_CST (node);
795           pp_string (buffer, "0x");
796           for (i = 0; i < sizeof TREE_REAL_CST (node); i++)
797             output_formatted_integer (buffer, "%02x", *p++);
798         }
799 #endif
800         break;
801       }
802
803     case COMPLEX_CST:
804       pp_string (buffer, "__complex__ (");
805       dump_generic_node (buffer, TREE_REALPART (node), spc, flags, false);
806       pp_string (buffer, ", ");
807       dump_generic_node (buffer, TREE_IMAGPART (node), spc, flags, false);
808       pp_string (buffer, ")");
809       break;
810
811     case STRING_CST:
812       pp_string (buffer, "\"");
813       pretty_print_string (buffer, TREE_STRING_POINTER (node));
814       pp_string (buffer, "\"");
815       break;
816
817     case VECTOR_CST:
818       {
819         tree elt;
820         pp_string (buffer, "{ ");
821         for (elt = TREE_VECTOR_CST_ELTS (node); elt; elt = TREE_CHAIN (elt))
822           {
823             dump_generic_node (buffer, TREE_VALUE (elt), spc, flags, false);
824             if (TREE_CHAIN (elt))
825               pp_string (buffer, ", ");
826           }
827         pp_string (buffer, " }");
828       }
829       break;
830
831     case FUNCTION_TYPE:
832       break;
833
834     case FUNCTION_DECL:
835     case CONST_DECL:
836       dump_decl_name (buffer, node, flags);
837       break;
838
839     case LABEL_DECL:
840       if (DECL_NAME (node))
841         dump_decl_name (buffer, node, flags);
842       else if (LABEL_DECL_UID (node) != -1)
843         pp_printf (buffer, "<L" HOST_WIDE_INT_PRINT_DEC ">",
844                    LABEL_DECL_UID (node));
845       else
846         pp_printf (buffer, "<D%u>", DECL_UID (node));
847       break;
848
849     case TYPE_DECL:
850       if (DECL_IS_BUILTIN (node))
851         {
852           /* Don't print the declaration of built-in types.  */
853           break;
854         }
855       if (DECL_NAME (node))
856         dump_decl_name (buffer, node, flags);
857       else
858         {
859           if ((TREE_CODE (TREE_TYPE (node)) == RECORD_TYPE
860                || TREE_CODE (TREE_TYPE (node)) == UNION_TYPE)
861               && TYPE_METHODS (TREE_TYPE (node)))
862             {
863               /* The type is a c++ class: all structures have at least
864                  4 methods.  */
865               pp_string (buffer, "class ");
866               dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
867             }
868           else
869             {
870               pp_string (buffer,
871                          (TREE_CODE (TREE_TYPE (node)) == UNION_TYPE
872                           ? "union" : "struct "));
873               dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
874             }
875         }
876       break;
877
878     case SYMBOL_MEMORY_TAG:
879     case NAME_MEMORY_TAG:
880     case STRUCT_FIELD_TAG:
881     case VAR_DECL:
882     case PARM_DECL:
883     case FIELD_DECL:
884     case NAMESPACE_DECL:
885     case MEMORY_PARTITION_TAG:
886       dump_decl_name (buffer, node, flags);
887       break;
888
889     case RESULT_DECL:
890       pp_string (buffer, "<retval>");
891       break;
892
893     case COMPONENT_REF:
894       op0 = TREE_OPERAND (node, 0);
895       str = ".";
896       if (TREE_CODE (op0) == INDIRECT_REF)
897         {
898           op0 = TREE_OPERAND (op0, 0);
899           str = "->";
900         }
901       if (op_prio (op0) < op_prio (node))
902         pp_character (buffer, '(');
903       dump_generic_node (buffer, op0, spc, flags, false);
904       if (op_prio (op0) < op_prio (node))
905         pp_character (buffer, ')');
906       pp_string (buffer, str);
907       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
908
909       if (TREE_CODE (op0) != VALUE_HANDLE)
910         {
911           op0 = component_ref_field_offset (node);
912           if (op0 && TREE_CODE (op0) != INTEGER_CST)
913             {
914               pp_string (buffer, "{off: ");
915               dump_generic_node (buffer, op0, spc, flags, false);
916               pp_character (buffer, '}');
917             }
918         }
919       break;
920
921     case BIT_FIELD_REF:
922       pp_string (buffer, "BIT_FIELD_REF <");
923       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
924       pp_string (buffer, ", ");
925       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
926       pp_string (buffer, ", ");
927       dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
928       pp_string (buffer, ">");
929       break;
930
931     case ARRAY_REF:
932     case ARRAY_RANGE_REF:
933       op0 = TREE_OPERAND (node, 0);
934       if (op_prio (op0) < op_prio (node))
935         pp_character (buffer, '(');
936       dump_generic_node (buffer, op0, spc, flags, false);
937       if (op_prio (op0) < op_prio (node))
938         pp_character (buffer, ')');
939       pp_character (buffer, '[');
940       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
941       if (TREE_CODE (node) == ARRAY_RANGE_REF)
942         pp_string (buffer, " ...");
943       pp_character (buffer, ']');
944
945       op0 = array_ref_low_bound (node);
946       op1 = array_ref_element_size (node);
947
948       if (!integer_zerop (op0)
949           || (TYPE_SIZE_UNIT (TREE_TYPE (node))
950               && !operand_equal_p (op1, TYPE_SIZE_UNIT (TREE_TYPE (node)), 0)))
951         {
952           pp_string (buffer, "{lb: ");
953           dump_generic_node (buffer, op0, spc, flags, false);
954           pp_string (buffer, " sz: ");
955           dump_generic_node (buffer, op1, spc, flags, false);
956           pp_character (buffer, '}');
957         }
958       break;
959
960     case CONSTRUCTOR:
961       {
962         unsigned HOST_WIDE_INT ix;
963         tree field, val;
964         bool is_struct_init = FALSE;
965         pp_character (buffer, '{');
966         if (TREE_CODE (TREE_TYPE (node)) == RECORD_TYPE
967             || TREE_CODE (TREE_TYPE (node)) == UNION_TYPE)
968           is_struct_init = TRUE;
969         FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (node), ix, field, val)
970           {
971             if (field && is_struct_init)
972               {
973                 pp_character (buffer, '.');
974                 dump_generic_node (buffer, field, spc, flags, false);
975                 pp_string (buffer, "=");
976               }
977             if (val && TREE_CODE (val) == ADDR_EXPR)
978               if (TREE_CODE (TREE_OPERAND (val, 0)) == FUNCTION_DECL)
979                 val = TREE_OPERAND (val, 0);
980             if (val && TREE_CODE (val) == FUNCTION_DECL)
981                 dump_decl_name (buffer, val, flags);
982             else
983                 dump_generic_node (buffer, val, spc, flags, false);
984             if (ix != VEC_length (constructor_elt, CONSTRUCTOR_ELTS (node)) - 1)
985               {
986                 pp_character (buffer, ',');
987                 pp_space (buffer);
988               }
989           }
990         pp_character (buffer, '}');
991       }
992       break;
993
994     case COMPOUND_EXPR:
995       {
996         tree *tp;
997         if (flags & TDF_SLIM)
998           {
999             pp_string (buffer, "<COMPOUND_EXPR>");
1000             break;
1001           }
1002
1003         dump_generic_node (buffer, TREE_OPERAND (node, 0),
1004                            spc, flags, !(flags & TDF_SLIM));
1005         if (flags & TDF_SLIM)
1006           newline_and_indent (buffer, spc);
1007         else
1008           {
1009             pp_character (buffer, ',');
1010             pp_space (buffer);
1011           }
1012
1013         for (tp = &TREE_OPERAND (node, 1);
1014              TREE_CODE (*tp) == COMPOUND_EXPR;
1015              tp = &TREE_OPERAND (*tp, 1))
1016           {
1017             dump_generic_node (buffer, TREE_OPERAND (*tp, 0),
1018                                spc, flags, !(flags & TDF_SLIM));
1019             if (flags & TDF_SLIM)
1020               newline_and_indent (buffer, spc);
1021             else
1022               {
1023                 pp_character (buffer, ',');
1024                 pp_space (buffer);
1025               }
1026           }
1027
1028         dump_generic_node (buffer, *tp, spc, flags, !(flags & TDF_SLIM));
1029       }
1030       break;
1031
1032     case STATEMENT_LIST:
1033       {
1034         tree_stmt_iterator si;
1035         bool first = true;
1036
1037         if (flags & TDF_SLIM)
1038           {
1039             pp_string (buffer, "<STATEMENT_LIST>");
1040             break;
1041           }
1042
1043         for (si = tsi_start (node); !tsi_end_p (si); tsi_next (&si))
1044           {
1045             if (!first)
1046               newline_and_indent (buffer, spc);
1047             else
1048               first = false;
1049             dump_generic_node (buffer, tsi_stmt (si), spc, flags, true);
1050           }
1051       }
1052       break;
1053
1054     case MODIFY_EXPR:
1055     case GIMPLE_MODIFY_STMT:
1056     case INIT_EXPR:
1057       dump_generic_node (buffer, GENERIC_TREE_OPERAND (node, 0), spc, flags,
1058                          false);
1059       pp_space (buffer);
1060       pp_character (buffer, '=');
1061       pp_space (buffer);
1062       dump_generic_node (buffer, GENERIC_TREE_OPERAND (node, 1), spc, flags,
1063                          false);
1064       break;
1065
1066     case TARGET_EXPR:
1067       pp_string (buffer, "TARGET_EXPR <");
1068       dump_generic_node (buffer, TARGET_EXPR_SLOT (node), spc, flags, false);
1069       pp_character (buffer, ',');
1070       pp_space (buffer);
1071       dump_generic_node (buffer, TARGET_EXPR_INITIAL (node), spc, flags, false);
1072       pp_character (buffer, '>');
1073       break;
1074
1075     case DECL_EXPR:
1076       print_declaration (buffer, DECL_EXPR_DECL (node), spc, flags);
1077       is_stmt = false;
1078       break;
1079
1080     case COND_EXPR:
1081       if (TREE_TYPE (node) == NULL || TREE_TYPE (node) == void_type_node)
1082         {
1083           pp_string (buffer, "if (");
1084           dump_generic_node (buffer, COND_EXPR_COND (node), spc, flags, false);
1085           pp_character (buffer, ')');
1086           /* The lowered cond_exprs should always be printed in full.  */
1087           if (COND_EXPR_THEN (node)
1088               && (IS_EMPTY_STMT (COND_EXPR_THEN (node))
1089                   || TREE_CODE (COND_EXPR_THEN (node)) == GOTO_EXPR)
1090               && COND_EXPR_ELSE (node)
1091               && (IS_EMPTY_STMT (COND_EXPR_ELSE (node))
1092                   || TREE_CODE (COND_EXPR_ELSE (node)) == GOTO_EXPR))
1093             {
1094               pp_space (buffer);
1095               dump_generic_node (buffer, COND_EXPR_THEN (node), 0, flags, true);
1096               pp_string (buffer, " else ");
1097               dump_generic_node (buffer, COND_EXPR_ELSE (node), 0, flags, true);
1098             }
1099           else if (!(flags & TDF_SLIM))
1100             {
1101               /* Output COND_EXPR_THEN.  */
1102               if (COND_EXPR_THEN (node))
1103                 {
1104                   newline_and_indent (buffer, spc+2);
1105                   pp_character (buffer, '{');
1106                   newline_and_indent (buffer, spc+4);
1107                   dump_generic_node (buffer, COND_EXPR_THEN (node), spc+4,
1108                                      flags, true);
1109                   newline_and_indent (buffer, spc+2);
1110                   pp_character (buffer, '}');
1111                 }
1112
1113               /* Output COND_EXPR_ELSE.  */
1114               if (COND_EXPR_ELSE (node))
1115                 {
1116                   newline_and_indent (buffer, spc);
1117                   pp_string (buffer, "else");
1118                   newline_and_indent (buffer, spc+2);
1119                   pp_character (buffer, '{');
1120                   newline_and_indent (buffer, spc+4);
1121                   dump_generic_node (buffer, COND_EXPR_ELSE (node), spc+4,
1122                                      flags, true);
1123                   newline_and_indent (buffer, spc+2);
1124                   pp_character (buffer, '}');
1125                 }
1126             }
1127           is_expr = false;
1128         }
1129       else
1130         {
1131           dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1132           pp_space (buffer);
1133           pp_character (buffer, '?');
1134           pp_space (buffer);
1135           dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1136           pp_space (buffer);
1137           pp_character (buffer, ':');
1138           pp_space (buffer);
1139           dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
1140         }
1141       break;
1142
1143     case BIND_EXPR:
1144       pp_character (buffer, '{');
1145       if (!(flags & TDF_SLIM))
1146         {
1147           if (BIND_EXPR_VARS (node))
1148             {
1149               pp_newline (buffer);
1150
1151               for (op0 = BIND_EXPR_VARS (node); op0; op0 = TREE_CHAIN (op0))
1152                 {
1153                   print_declaration (buffer, op0, spc+2, flags);
1154                   pp_newline (buffer);
1155                 }
1156             }
1157
1158           newline_and_indent (buffer, spc+2);
1159           dump_generic_node (buffer, BIND_EXPR_BODY (node), spc+2, flags, true);
1160           newline_and_indent (buffer, spc);
1161           pp_character (buffer, '}');
1162         }
1163       is_expr = false;
1164       break;
1165
1166     case CALL_EXPR:
1167       print_call_name (buffer, node);
1168
1169       /* Print parameters.  */
1170       pp_space (buffer);
1171       pp_character (buffer, '(');
1172       op1 = TREE_OPERAND (node, 1);
1173       if (op1)
1174         dump_generic_node (buffer, op1, spc, flags, false);
1175       pp_character (buffer, ')');
1176
1177       op1 = TREE_OPERAND (node, 2);
1178       if (op1)
1179         {
1180           pp_string (buffer, " [static-chain: ");
1181           dump_generic_node (buffer, op1, spc, flags, false);
1182           pp_character (buffer, ']');
1183         }
1184
1185       if (CALL_EXPR_RETURN_SLOT_OPT (node))
1186         pp_string (buffer, " [return slot optimization]");
1187       if (CALL_EXPR_TAILCALL (node))
1188         pp_string (buffer, " [tail call]");
1189       break;
1190
1191     case WITH_CLEANUP_EXPR:
1192       NIY;
1193       break;
1194
1195     case CLEANUP_POINT_EXPR:
1196       pp_string (buffer, "<<cleanup_point ");
1197       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1198       pp_string (buffer, ">>");
1199       break;
1200
1201     case PLACEHOLDER_EXPR:
1202       pp_string (buffer, "<PLACEHOLDER_EXPR ");
1203       dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
1204       pp_character (buffer, '>');
1205       break;
1206
1207       /* Binary arithmetic and logic expressions.  */
1208     case WIDEN_SUM_EXPR:
1209     case WIDEN_MULT_EXPR:
1210     case MULT_EXPR:
1211     case PLUS_EXPR:
1212     case MINUS_EXPR:
1213     case TRUNC_DIV_EXPR:
1214     case CEIL_DIV_EXPR:
1215     case FLOOR_DIV_EXPR:
1216     case ROUND_DIV_EXPR:
1217     case TRUNC_MOD_EXPR:
1218     case CEIL_MOD_EXPR:
1219     case FLOOR_MOD_EXPR:
1220     case ROUND_MOD_EXPR:
1221     case RDIV_EXPR:
1222     case EXACT_DIV_EXPR:
1223     case LSHIFT_EXPR:
1224     case RSHIFT_EXPR:
1225     case LROTATE_EXPR:
1226     case RROTATE_EXPR:
1227     case VEC_LSHIFT_EXPR:
1228     case VEC_RSHIFT_EXPR:
1229     case BIT_IOR_EXPR:
1230     case BIT_XOR_EXPR:
1231     case BIT_AND_EXPR:
1232     case TRUTH_ANDIF_EXPR:
1233     case TRUTH_ORIF_EXPR:
1234     case TRUTH_AND_EXPR:
1235     case TRUTH_OR_EXPR:
1236     case TRUTH_XOR_EXPR:
1237     case LT_EXPR:
1238     case LE_EXPR:
1239     case GT_EXPR:
1240     case GE_EXPR:
1241     case EQ_EXPR:
1242     case NE_EXPR:
1243     case UNLT_EXPR:
1244     case UNLE_EXPR:
1245     case UNGT_EXPR:
1246     case UNGE_EXPR:
1247     case UNEQ_EXPR:
1248     case LTGT_EXPR:
1249     case ORDERED_EXPR:
1250     case UNORDERED_EXPR:
1251       {
1252         const char *op = op_symbol (node);
1253         op0 = TREE_OPERAND (node, 0);
1254         op1 = TREE_OPERAND (node, 1);
1255
1256         /* When the operands are expressions with less priority,
1257            keep semantics of the tree representation.  */
1258         if (op_prio (op0) < op_prio (node))
1259           {
1260             pp_character (buffer, '(');
1261             dump_generic_node (buffer, op0, spc, flags, false);
1262             pp_character (buffer, ')');
1263           }
1264         else
1265           dump_generic_node (buffer, op0, spc, flags, false);
1266
1267         pp_space (buffer);
1268         pp_string (buffer, op);
1269         pp_space (buffer);
1270
1271         /* When the operands are expressions with less priority,
1272            keep semantics of the tree representation.  */
1273         if (op_prio (op1) < op_prio (node))
1274           {
1275             pp_character (buffer, '(');
1276             dump_generic_node (buffer, op1, spc, flags, false);
1277             pp_character (buffer, ')');
1278           }
1279         else
1280           dump_generic_node (buffer, op1, spc, flags, false);
1281       }
1282       break;
1283
1284       /* Unary arithmetic and logic expressions.  */
1285     case NEGATE_EXPR:
1286     case BIT_NOT_EXPR:
1287     case TRUTH_NOT_EXPR:
1288     case ADDR_EXPR:
1289     case PREDECREMENT_EXPR:
1290     case PREINCREMENT_EXPR:
1291     case ALIGN_INDIRECT_REF:
1292     case MISALIGNED_INDIRECT_REF:
1293     case INDIRECT_REF:
1294       if (TREE_CODE (node) == ADDR_EXPR
1295           && (TREE_CODE (TREE_OPERAND (node, 0)) == STRING_CST
1296               || TREE_CODE (TREE_OPERAND (node, 0)) == FUNCTION_DECL))
1297         ;       /* Do not output '&' for strings and function pointers.  */
1298       else
1299         pp_string (buffer, op_symbol (node));
1300
1301       if (op_prio (TREE_OPERAND (node, 0)) < op_prio (node))
1302         {
1303           pp_character (buffer, '(');
1304           dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1305           pp_character (buffer, ')');
1306         }
1307       else
1308         dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1309
1310       if (TREE_CODE (node) == MISALIGNED_INDIRECT_REF)
1311         {
1312           pp_string (buffer, "{misalignment: ");
1313           dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1314           pp_character (buffer, '}');
1315         }
1316       break;
1317
1318     case POSTDECREMENT_EXPR:
1319     case POSTINCREMENT_EXPR:
1320       if (op_prio (TREE_OPERAND (node, 0)) < op_prio (node))
1321         {
1322           pp_character (buffer, '(');
1323           dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1324           pp_character (buffer, ')');
1325         }
1326       else
1327         dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1328       pp_string (buffer, op_symbol (node));
1329       break;
1330
1331     case MIN_EXPR:
1332       pp_string (buffer, "MIN_EXPR <");
1333       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1334       pp_string (buffer, ", ");
1335       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1336       pp_character (buffer, '>');
1337       break;
1338
1339     case MAX_EXPR:
1340       pp_string (buffer, "MAX_EXPR <");
1341       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1342       pp_string (buffer, ", ");
1343       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1344       pp_character (buffer, '>');
1345       break;
1346
1347     case ABS_EXPR:
1348       pp_string (buffer, "ABS_EXPR <");
1349       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1350       pp_character (buffer, '>');
1351       break;
1352
1353     case RANGE_EXPR:
1354       NIY;
1355       break;
1356
1357     case FIX_TRUNC_EXPR:
1358     case FLOAT_EXPR:
1359     case CONVERT_EXPR:
1360     case NOP_EXPR:
1361       type = TREE_TYPE (node);
1362       op0 = TREE_OPERAND (node, 0);
1363       if (type != TREE_TYPE (op0))
1364         {
1365           pp_character (buffer, '(');
1366           dump_generic_node (buffer, type, spc, flags, false);
1367           pp_string (buffer, ") ");
1368         }
1369       if (op_prio (op0) < op_prio (node))
1370         pp_character (buffer, '(');
1371       dump_generic_node (buffer, op0, spc, flags, false);
1372       if (op_prio (op0) < op_prio (node))
1373         pp_character (buffer, ')');
1374       break;
1375
1376     case VIEW_CONVERT_EXPR:
1377       pp_string (buffer, "VIEW_CONVERT_EXPR<");
1378       dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
1379       pp_string (buffer, ">(");
1380       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1381       pp_character (buffer, ')');
1382       break;
1383
1384     case NON_LVALUE_EXPR:
1385       pp_string (buffer, "NON_LVALUE_EXPR <");
1386       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1387       pp_character (buffer, '>');
1388       break;
1389
1390     case SAVE_EXPR:
1391       pp_string (buffer, "SAVE_EXPR <");
1392       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1393       pp_character (buffer, '>');
1394       break;
1395
1396     case COMPLEX_EXPR:
1397       pp_string (buffer, "COMPLEX_EXPR <");
1398       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1399       pp_string (buffer, ", ");
1400       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1401       pp_string (buffer, ">");
1402       break;
1403
1404     case CONJ_EXPR:
1405       pp_string (buffer, "CONJ_EXPR <");
1406       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1407       pp_string (buffer, ">");
1408       break;
1409
1410     case REALPART_EXPR:
1411       pp_string (buffer, "REALPART_EXPR <");
1412       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1413       pp_string (buffer, ">");
1414       break;
1415
1416     case IMAGPART_EXPR:
1417       pp_string (buffer, "IMAGPART_EXPR <");
1418       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1419       pp_string (buffer, ">");
1420       break;
1421
1422     case VA_ARG_EXPR:
1423       pp_string (buffer, "VA_ARG_EXPR <");
1424       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1425       pp_string (buffer, ">");
1426       break;
1427
1428     case TRY_FINALLY_EXPR:
1429     case TRY_CATCH_EXPR:
1430       pp_string (buffer, "try");
1431       newline_and_indent (buffer, spc+2);
1432       pp_string (buffer, "{");
1433       newline_and_indent (buffer, spc+4);
1434       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc+4, flags, true);
1435       newline_and_indent (buffer, spc+2);
1436       pp_string (buffer, "}");
1437       newline_and_indent (buffer, spc);
1438       pp_string (buffer,
1439                          (TREE_CODE (node) == TRY_CATCH_EXPR) ? "catch" : "finally");
1440       newline_and_indent (buffer, spc+2);
1441       pp_string (buffer, "{");
1442       newline_and_indent (buffer, spc+4);
1443       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc+4, flags, true);
1444       newline_and_indent (buffer, spc+2);
1445       pp_string (buffer, "}");
1446       is_expr = false;
1447       break;
1448
1449     case CATCH_EXPR:
1450       pp_string (buffer, "catch (");
1451       dump_generic_node (buffer, CATCH_TYPES (node), spc+2, flags, false);
1452       pp_string (buffer, ")");
1453       newline_and_indent (buffer, spc+2);
1454       pp_string (buffer, "{");
1455       newline_and_indent (buffer, spc+4);
1456       dump_generic_node (buffer, CATCH_BODY (node), spc+4, flags, true);
1457       newline_and_indent (buffer, spc+2);
1458       pp_string (buffer, "}");
1459       is_expr = false;
1460       break;
1461
1462     case EH_FILTER_EXPR:
1463       pp_string (buffer, "<<<eh_filter (");
1464       dump_generic_node (buffer, EH_FILTER_TYPES (node), spc+2, flags, false);
1465       pp_string (buffer, ")>>>");
1466       newline_and_indent (buffer, spc+2);
1467       pp_string (buffer, "{");
1468       newline_and_indent (buffer, spc+4);
1469       dump_generic_node (buffer, EH_FILTER_FAILURE (node), spc+4, flags, true);
1470       newline_and_indent (buffer, spc+2);
1471       pp_string (buffer, "}");
1472       is_expr = false;
1473       break;
1474
1475     case LABEL_EXPR:
1476       op0 = TREE_OPERAND (node, 0);
1477       /* If this is for break or continue, don't bother printing it.  */
1478       if (DECL_NAME (op0))
1479         {
1480           const char *name = IDENTIFIER_POINTER (DECL_NAME (op0));
1481           if (strcmp (name, "break") == 0
1482               || strcmp (name, "continue") == 0)
1483             break;
1484         }
1485       dump_generic_node (buffer, op0, spc, flags, false);
1486       pp_character (buffer, ':');
1487       if (DECL_NONLOCAL (op0))
1488         pp_string (buffer, " [non-local]");
1489       break;
1490
1491     case EXC_PTR_EXPR:
1492       pp_string (buffer, "<<<exception object>>>");
1493       break;
1494
1495     case FILTER_EXPR:
1496       pp_string (buffer, "<<<filter object>>>");
1497       break;
1498
1499     case LOOP_EXPR:
1500       pp_string (buffer, "while (1)");
1501       if (!(flags & TDF_SLIM))
1502         {
1503           newline_and_indent (buffer, spc+2);
1504           pp_character (buffer, '{');
1505           newline_and_indent (buffer, spc+4);
1506           dump_generic_node (buffer, LOOP_EXPR_BODY (node), spc+4, flags, true);
1507           newline_and_indent (buffer, spc+2);
1508           pp_character (buffer, '}');
1509         }
1510       is_expr = false;
1511       break;
1512
1513     case RETURN_EXPR:
1514       pp_string (buffer, "return");
1515       op0 = TREE_OPERAND (node, 0);
1516       if (op0)
1517         {
1518           pp_space (buffer);
1519           if (TREE_CODE (op0) == MODIFY_EXPR
1520               || TREE_CODE (op0) == GIMPLE_MODIFY_STMT)
1521             dump_generic_node (buffer, GENERIC_TREE_OPERAND (op0, 1),
1522                                spc, flags, false);
1523           else
1524             dump_generic_node (buffer, op0, spc, flags, false);
1525         }
1526       break;
1527
1528     case EXIT_EXPR:
1529       pp_string (buffer, "if (");
1530       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1531       pp_string (buffer, ") break");
1532       break;
1533
1534     case SWITCH_EXPR:
1535       pp_string (buffer, "switch (");
1536       dump_generic_node (buffer, SWITCH_COND (node), spc, flags, false);
1537       pp_character (buffer, ')');
1538       if (!(flags & TDF_SLIM))
1539         {
1540           newline_and_indent (buffer, spc+2);
1541           pp_character (buffer, '{');
1542           if (SWITCH_BODY (node))
1543             {
1544               newline_and_indent (buffer, spc+4);
1545               dump_generic_node (buffer, SWITCH_BODY (node), spc+4, flags,
1546                                  true);
1547             }
1548           else
1549             {
1550               tree vec = SWITCH_LABELS (node);
1551               size_t i, n = TREE_VEC_LENGTH (vec);
1552               for (i = 0; i < n; ++i)
1553                 {
1554                   tree elt = TREE_VEC_ELT (vec, i);
1555                   newline_and_indent (buffer, spc+4);
1556                   if (elt)
1557                     {
1558                       dump_generic_node (buffer, elt, spc+4, flags, false);
1559                       pp_string (buffer, " goto ");
1560                       dump_generic_node (buffer, CASE_LABEL (elt), spc+4,
1561                                          flags, true);
1562                       pp_semicolon (buffer);
1563                     }
1564                   else
1565                     pp_string (buffer, "case ???: goto ???;");
1566                 }
1567             }
1568           newline_and_indent (buffer, spc+2);
1569           pp_character (buffer, '}');
1570         }
1571       is_expr = false;
1572       break;
1573
1574     case GOTO_EXPR:
1575       op0 = GOTO_DESTINATION (node);
1576       if (TREE_CODE (op0) != SSA_NAME && DECL_P (op0) && DECL_NAME (op0))
1577         {
1578           const char *name = IDENTIFIER_POINTER (DECL_NAME (op0));
1579           if (strcmp (name, "break") == 0
1580               || strcmp (name, "continue") == 0)
1581             {
1582               pp_string (buffer, name);
1583               break;
1584             }
1585         }
1586       pp_string (buffer, "goto ");
1587       dump_generic_node (buffer, op0, spc, flags, false);
1588       break;
1589
1590     case RESX_EXPR:
1591       pp_string (buffer, "resx ");
1592       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1593       break;
1594
1595     case ASM_EXPR:
1596       pp_string (buffer, "__asm__");
1597       if (ASM_VOLATILE_P (node))
1598         pp_string (buffer, " __volatile__");
1599       pp_character (buffer, '(');
1600       dump_generic_node (buffer, ASM_STRING (node), spc, flags, false);
1601       pp_character (buffer, ':');
1602       dump_generic_node (buffer, ASM_OUTPUTS (node), spc, flags, false);
1603       pp_character (buffer, ':');
1604       dump_generic_node (buffer, ASM_INPUTS (node), spc, flags, false);
1605       if (ASM_CLOBBERS (node))
1606         {
1607           pp_character (buffer, ':');
1608           dump_generic_node (buffer, ASM_CLOBBERS (node), spc, flags, false);
1609         }
1610       pp_string (buffer, ")");
1611       break;
1612
1613     case CASE_LABEL_EXPR:
1614       if (CASE_LOW (node) && CASE_HIGH (node))
1615         {
1616           pp_string (buffer, "case ");
1617           dump_generic_node (buffer, CASE_LOW (node), spc, flags, false);
1618           pp_string (buffer, " ... ");
1619           dump_generic_node (buffer, CASE_HIGH (node), spc, flags, false);
1620         }
1621       else if (CASE_LOW (node))
1622         {
1623           pp_string (buffer, "case ");
1624           dump_generic_node (buffer, CASE_LOW (node), spc, flags, false);
1625         }
1626       else
1627         pp_string (buffer, "default ");
1628       pp_character (buffer, ':');
1629       break;
1630
1631     case OBJ_TYPE_REF:
1632       pp_string (buffer, "OBJ_TYPE_REF(");
1633       dump_generic_node (buffer, OBJ_TYPE_REF_EXPR (node), spc, flags, false);
1634       pp_character (buffer, ';');
1635       dump_generic_node (buffer, OBJ_TYPE_REF_OBJECT (node), spc, flags, false);
1636       pp_character (buffer, '-');
1637       pp_character (buffer, '>');
1638       dump_generic_node (buffer, OBJ_TYPE_REF_TOKEN (node), spc, flags, false);
1639       pp_character (buffer, ')');
1640       break;
1641
1642     case PHI_NODE:
1643       {
1644         int i;
1645
1646         dump_generic_node (buffer, PHI_RESULT (node), spc, flags, false);
1647         pp_string (buffer, " = PHI <");
1648         for (i = 0; i < PHI_NUM_ARGS (node); i++)
1649           {
1650             dump_generic_node (buffer, PHI_ARG_DEF (node, i), spc, flags, false);
1651             pp_string (buffer, "(");
1652             pp_decimal_int (buffer, PHI_ARG_EDGE (node, i)->src->index);
1653             pp_string (buffer, ")");
1654             if (i < PHI_NUM_ARGS (node) - 1)
1655               pp_string (buffer, ", ");
1656           }
1657         pp_string (buffer, ">");
1658
1659         if (stmt_references_memory_p (node) && (flags & TDF_MEMSYMS))
1660           dump_symbols (buffer, STORED_SYMS (node), flags);
1661       }
1662       break;
1663
1664     case SSA_NAME:
1665       dump_generic_node (buffer, SSA_NAME_VAR (node), spc, flags, false);
1666       pp_string (buffer, "_");
1667       pp_decimal_int (buffer, SSA_NAME_VERSION (node));
1668       if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (node))
1669         pp_string (buffer, "(ab)");
1670       else if (SSA_NAME_IS_DEFAULT_DEF (node))
1671         pp_string (buffer, "(D)");
1672       break;
1673
1674     case WITH_SIZE_EXPR:
1675       pp_string (buffer, "WITH_SIZE_EXPR <");
1676       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1677       pp_string (buffer, ", ");
1678       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1679       pp_string (buffer, ">");
1680       break;
1681
1682     case VALUE_HANDLE:
1683       pp_printf (buffer, "VH.%d", VALUE_HANDLE_ID (node));
1684       break;
1685
1686     case ASSERT_EXPR:
1687       pp_string (buffer, "ASSERT_EXPR <");
1688       dump_generic_node (buffer, ASSERT_EXPR_VAR (node), spc, flags, false);
1689       pp_string (buffer, ", ");
1690       dump_generic_node (buffer, ASSERT_EXPR_COND (node), spc, flags, false);
1691       pp_string (buffer, ">");
1692       break;
1693
1694     case SCEV_KNOWN:
1695       pp_string (buffer, "scev_known");
1696       break;
1697
1698     case SCEV_NOT_KNOWN:
1699       pp_string (buffer, "scev_not_known");
1700       break;
1701
1702     case POLYNOMIAL_CHREC:
1703       pp_string (buffer, "{");
1704       dump_generic_node (buffer, CHREC_LEFT (node), spc, flags, false);
1705       pp_string (buffer, ", +, ");
1706       dump_generic_node (buffer, CHREC_RIGHT (node), spc, flags, false);
1707       pp_string (buffer, "}_");
1708       dump_generic_node (buffer, CHREC_VAR (node), spc, flags, false);
1709       is_stmt = false;
1710       break;
1711
1712     case REALIGN_LOAD_EXPR:
1713       pp_string (buffer, "REALIGN_LOAD <");
1714       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1715       pp_string (buffer, ", ");
1716       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1717       pp_string (buffer, ", ");
1718       dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
1719       pp_string (buffer, ">");
1720       break;
1721       
1722     case VEC_COND_EXPR:
1723       pp_string (buffer, " VEC_COND_EXPR < ");
1724       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1725       pp_string (buffer, " , ");
1726       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1727       pp_string (buffer, " , ");
1728       dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
1729       pp_string (buffer, " > ");
1730       break;
1731
1732     case DOT_PROD_EXPR:
1733       pp_string (buffer, " DOT_PROD_EXPR < ");
1734       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1735       pp_string (buffer, ", ");
1736       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1737       pp_string (buffer, ", ");
1738       dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
1739       pp_string (buffer, " > ");
1740       break;
1741
1742     case OMP_PARALLEL:
1743       pp_string (buffer, "#pragma omp parallel");
1744       dump_omp_clauses (buffer, OMP_PARALLEL_CLAUSES (node), spc, flags);
1745       if (OMP_PARALLEL_FN (node))
1746         {
1747           pp_string (buffer, " [child fn: ");
1748           dump_generic_node (buffer, OMP_PARALLEL_FN (node), spc, flags, false);
1749
1750           pp_string (buffer, " (");
1751
1752           if (OMP_PARALLEL_DATA_ARG (node))
1753             dump_generic_node (buffer, OMP_PARALLEL_DATA_ARG (node), spc, flags,
1754                                false);
1755           else
1756             pp_string (buffer, "???");
1757
1758           pp_string (buffer, ")]");
1759         }
1760
1761     dump_omp_body:
1762       if (!(flags & TDF_SLIM) && OMP_BODY (node))
1763         {
1764           newline_and_indent (buffer, spc + 2);
1765           pp_character (buffer, '{');
1766           newline_and_indent (buffer, spc + 4);
1767           dump_generic_node (buffer, OMP_BODY (node), spc + 4, flags, false);
1768           newline_and_indent (buffer, spc + 2);
1769           pp_character (buffer, '}');
1770         }
1771       is_expr = false;
1772       break;
1773
1774     case OMP_FOR:
1775       pp_string (buffer, "#pragma omp for");
1776       dump_omp_clauses (buffer, OMP_FOR_CLAUSES (node), spc, flags);
1777
1778       if (!(flags & TDF_SLIM))
1779         {
1780           if (OMP_FOR_PRE_BODY (node))
1781             {
1782               newline_and_indent (buffer, spc + 2);
1783               pp_character (buffer, '{');
1784               spc += 4;
1785               newline_and_indent (buffer, spc);
1786               dump_generic_node (buffer, OMP_FOR_PRE_BODY (node),
1787                   spc, flags, false);
1788             }
1789           newline_and_indent (buffer, spc);
1790           pp_string (buffer, "for (");
1791           dump_generic_node (buffer, OMP_FOR_INIT (node), spc, flags, false);
1792           pp_string (buffer, "; ");
1793           dump_generic_node (buffer, OMP_FOR_COND (node), spc, flags, false);
1794           pp_string (buffer, "; ");
1795           dump_generic_node (buffer, OMP_FOR_INCR (node), spc, flags, false);
1796           pp_string (buffer, ")");
1797           if (OMP_FOR_BODY (node))
1798             {
1799               newline_and_indent (buffer, spc + 2);
1800               pp_character (buffer, '{');
1801               newline_and_indent (buffer, spc + 4);
1802               dump_generic_node (buffer, OMP_FOR_BODY (node), spc + 4, flags,
1803                   false);
1804               newline_and_indent (buffer, spc + 2);
1805               pp_character (buffer, '}');
1806             }
1807           if (OMP_FOR_PRE_BODY (node))
1808             {
1809               spc -= 4;
1810               newline_and_indent (buffer, spc + 2);
1811               pp_character (buffer, '}');
1812             }
1813         }
1814       is_expr = false;
1815       break;
1816
1817     case OMP_SECTIONS:
1818       pp_string (buffer, "#pragma omp sections");
1819       dump_omp_clauses (buffer, OMP_SECTIONS_CLAUSES (node), spc, flags);
1820       goto dump_omp_body;
1821
1822     case OMP_SECTION:
1823       pp_string (buffer, "#pragma omp section");
1824       goto dump_omp_body;
1825  
1826     case OMP_MASTER:
1827       pp_string (buffer, "#pragma omp master");
1828       goto dump_omp_body;
1829
1830     case OMP_ORDERED:
1831       pp_string (buffer, "#pragma omp ordered");
1832       goto dump_omp_body;
1833
1834     case OMP_CRITICAL:
1835       pp_string (buffer, "#pragma omp critical");
1836       if (OMP_CRITICAL_NAME (node))
1837         {
1838           pp_space (buffer);
1839           pp_character (buffer, '(');
1840           dump_generic_node (buffer, OMP_CRITICAL_NAME (node), spc,
1841                              flags, false);
1842           pp_character (buffer, ')');
1843         }
1844       goto dump_omp_body;
1845
1846     case OMP_ATOMIC:
1847       pp_string (buffer, "#pragma omp atomic");
1848       newline_and_indent (buffer, spc + 2);
1849       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1850       pp_space (buffer);
1851       pp_character (buffer, '=');
1852       pp_space (buffer);
1853       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1854       break;
1855
1856     case OMP_SINGLE:
1857       pp_string (buffer, "#pragma omp single");
1858       dump_omp_clauses (buffer, OMP_SINGLE_CLAUSES (node), spc, flags);
1859       goto dump_omp_body;
1860
1861     case OMP_RETURN:
1862       pp_string (buffer, "OMP_RETURN");
1863       if (OMP_RETURN_NOWAIT (node))
1864         pp_string (buffer, " [nowait]");
1865       is_expr = false;
1866       break;
1867
1868     case OMP_CONTINUE:
1869       pp_string (buffer, "OMP_CONTINUE");
1870       is_expr = false;
1871       break;
1872
1873     case OMP_CLAUSE:
1874       dump_omp_clause (buffer, node, spc, flags);
1875       is_expr = false;
1876       break;
1877
1878     case REDUC_MAX_EXPR:
1879       pp_string (buffer, " REDUC_MAX_EXPR < ");
1880       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1881       pp_string (buffer, " > ");
1882       break;
1883
1884     case REDUC_MIN_EXPR:
1885       pp_string (buffer, " REDUC_MIN_EXPR < ");
1886       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1887       pp_string (buffer, " > ");
1888       break;
1889
1890     case REDUC_PLUS_EXPR:
1891       pp_string (buffer, " REDUC_PLUS_EXPR < ");
1892       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1893       pp_string (buffer, " > ");
1894       break;
1895
1896     case VEC_WIDEN_MULT_HI_EXPR:
1897       pp_string (buffer, " VEC_WIDEN_MULT_HI_EXPR < ");
1898       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1899       pp_string (buffer, ", ");
1900       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1901       pp_string (buffer, " > ");
1902       break;
1903
1904     case VEC_WIDEN_MULT_LO_EXPR:
1905       pp_string (buffer, " VEC_WIDEN_MULT_LO_EXPR < ");
1906       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1907       pp_string (buffer, ", ");
1908       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1909       pp_string (buffer, " > ");
1910       break;
1911
1912     case VEC_UNPACK_HI_EXPR:
1913       pp_string (buffer, " VEC_UNPACK_HI_EXPR < ");
1914       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1915       pp_string (buffer, " > ");
1916       break;
1917
1918     case VEC_UNPACK_LO_EXPR:
1919       pp_string (buffer, " VEC_UNPACK_LO_EXPR < ");
1920       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1921       pp_string (buffer, " > ");
1922       break;
1923
1924     case VEC_PACK_MOD_EXPR:
1925       pp_string (buffer, " VEC_PACK_MOD_EXPR < ");
1926       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1927       pp_string (buffer, ", ");
1928       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1929       pp_string (buffer, " > ");
1930       break;
1931                                                                                 
1932     case VEC_PACK_SAT_EXPR:
1933       pp_string (buffer, " VEC_PACK_SAT_EXPR < ");
1934       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1935       pp_string (buffer, ", ");
1936       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1937       pp_string (buffer, " > ");
1938       break;
1939                                                                                 
1940     case BLOCK:
1941       {
1942         tree t;
1943         pp_string (buffer, "BLOCK");
1944
1945         if (BLOCK_ABSTRACT (node))
1946           pp_string (buffer, " [abstract]");
1947
1948         if (TREE_ASM_WRITTEN (node))
1949           pp_string (buffer, " [written]");
1950
1951         newline_and_indent (buffer, spc + 2);
1952
1953         if (BLOCK_SUPERCONTEXT (node))
1954           {
1955             pp_string (buffer, "SUPERCONTEXT: ");
1956             if (TREE_CODE (BLOCK_SUPERCONTEXT (node)) == BLOCK)
1957               pp_printf (buffer, "BLOCK %p",
1958                          (void *)BLOCK_SUPERCONTEXT (node));
1959             else
1960               dump_generic_node (buffer, BLOCK_SUPERCONTEXT (node), 0, flags,
1961                                  false);
1962             newline_and_indent (buffer, spc + 2);
1963           }
1964
1965         if (BLOCK_SUBBLOCKS (node))
1966           {
1967             pp_string (buffer, "SUBBLOCKS: ");
1968             for (t = BLOCK_SUBBLOCKS (node); t; t = BLOCK_CHAIN (t))
1969               pp_printf (buffer, "%p ", (void *)t);
1970             newline_and_indent (buffer, spc + 2);
1971           }
1972
1973         if (BLOCK_VARS (node))
1974           {
1975             pp_string (buffer, "VARS: ");
1976             for (t = BLOCK_VARS (node); t; t = TREE_CHAIN (t))
1977               {
1978                 dump_generic_node (buffer, t, 0, flags, false);
1979                 pp_string (buffer, " ");
1980               }
1981             newline_and_indent (buffer, spc + 2);
1982           }
1983
1984         if (BLOCK_ABSTRACT_ORIGIN (node))
1985           {
1986             pp_string (buffer, "ABSTRACT_ORIGIN: ");
1987             if (TREE_CODE (BLOCK_ABSTRACT_ORIGIN (node)) == BLOCK)
1988               pp_printf (buffer, "BLOCK %p",
1989                          (void *)BLOCK_ABSTRACT_ORIGIN (node));
1990             else
1991               dump_generic_node (buffer, BLOCK_ABSTRACT_ORIGIN (node), 0, flags,
1992                                  false);
1993             newline_and_indent (buffer, spc + 2);
1994           }
1995       }
1996     break;
1997
1998     case VEC_EXTRACT_EVEN_EXPR:
1999       pp_string (buffer, " VEC_EXTRACT_EVEN_EXPR < ");
2000       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
2001       pp_string (buffer, ", ");
2002       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
2003       pp_string (buffer, " > ");
2004       break;
2005   
2006     case VEC_EXTRACT_ODD_EXPR:
2007       pp_string (buffer, " VEC_EXTRACT_ODD_EXPR < ");
2008       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
2009       pp_string (buffer, ", ");
2010       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
2011       pp_string (buffer, " > ");
2012       break;
2013
2014     case VEC_INTERLEAVE_HIGH_EXPR:
2015       pp_string (buffer, " VEC_INTERLEAVE_HIGH_EXPR < ");
2016       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
2017       pp_string (buffer, ", ");
2018       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
2019       pp_string (buffer, " > ");
2020       break;
2021
2022     case VEC_INTERLEAVE_LOW_EXPR:
2023       pp_string (buffer, " VEC_INTERLEAVE_LOW_EXPR < ");
2024       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
2025       pp_string (buffer, ", ");
2026       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
2027       pp_string (buffer, " > ");
2028       break;
2029
2030     default:
2031       NIY;
2032     }
2033
2034   if (is_stmt && is_expr)
2035     pp_semicolon (buffer);
2036   pp_write_text_to_stream (buffer);
2037
2038   return spc;
2039 }
2040
2041 /* Print the declaration of a variable.  */
2042
2043 static void
2044 print_declaration (pretty_printer *buffer, tree t, int spc, int flags)
2045 {
2046   INDENT (spc);
2047
2048   if (TREE_CODE (t) == TYPE_DECL)
2049     pp_string (buffer, "typedef ");
2050
2051   if (CODE_CONTAINS_STRUCT (TREE_CODE (t), TS_DECL_WRTL) && DECL_REGISTER (t))
2052     pp_string (buffer, "register ");
2053
2054   if (TREE_PUBLIC (t) && DECL_EXTERNAL (t))
2055     pp_string (buffer, "extern ");
2056   else if (TREE_STATIC (t))
2057     pp_string (buffer, "static ");
2058
2059   /* Print the type and name.  */
2060   if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
2061     {
2062       tree tmp;
2063
2064       /* Print array's type.  */
2065       tmp = TREE_TYPE (t);
2066       while (TREE_CODE (TREE_TYPE (tmp)) == ARRAY_TYPE)
2067         tmp = TREE_TYPE (tmp);
2068       dump_generic_node (buffer, TREE_TYPE (tmp), spc, flags, false);
2069
2070       /* Print variable's name.  */
2071       pp_space (buffer);
2072       dump_generic_node (buffer, t, spc, flags, false);
2073
2074       /* Print the dimensions.  */
2075       tmp = TREE_TYPE (t);
2076       while (TREE_CODE (tmp) == ARRAY_TYPE)
2077         {
2078           dump_array_domain (buffer, TYPE_DOMAIN (tmp), spc, flags);
2079           tmp = TREE_TYPE (tmp);
2080         }
2081     }
2082   else if (TREE_CODE (t) == FUNCTION_DECL)
2083     {
2084       dump_generic_node (buffer, TREE_TYPE (TREE_TYPE (t)), spc, flags, false);
2085       pp_space (buffer);
2086       dump_decl_name (buffer, t, flags);
2087       dump_function_declaration (buffer, TREE_TYPE (t), spc, flags);
2088     }
2089   else
2090     {
2091       /* Print type declaration.  */
2092       dump_generic_node (buffer, TREE_TYPE (t), spc, flags, false);
2093
2094       /* Print variable's name.  */
2095       pp_space (buffer);
2096       dump_generic_node (buffer, t, spc, flags, false);
2097     }
2098
2099   if (TREE_CODE (t) == VAR_DECL && DECL_HARD_REGISTER (t))
2100     {
2101       pp_string (buffer, " __asm__ ");
2102       pp_character (buffer, '(');
2103       dump_generic_node (buffer, DECL_ASSEMBLER_NAME (t), spc, flags, false);
2104       pp_character (buffer, ')');
2105     }
2106
2107   /* The initial value of a function serves to determine wether the function
2108      is declared or defined.  So the following does not apply to function
2109      nodes.  */
2110   if (TREE_CODE (t) != FUNCTION_DECL)
2111     {
2112       /* Print the initial value.  */
2113       if (DECL_INITIAL (t))
2114         {
2115           pp_space (buffer);
2116           pp_character (buffer, '=');
2117           pp_space (buffer);
2118           dump_generic_node (buffer, DECL_INITIAL (t), spc, flags, false);
2119         }
2120     }
2121
2122   if (TREE_CODE (t) == VAR_DECL && DECL_HAS_VALUE_EXPR_P (t))
2123     {
2124       pp_string (buffer, " [value-expr: ");
2125       dump_generic_node (buffer, DECL_VALUE_EXPR (t), spc, flags, false);
2126       pp_character (buffer, ']');
2127     }
2128
2129   pp_character (buffer, ';');
2130 }
2131
2132
2133 /* Prints a structure: name, fields, and methods.
2134    FIXME: Still incomplete.  */
2135
2136 static void
2137 print_struct_decl (pretty_printer *buffer, tree node, int spc, int flags)
2138 {
2139   /* Print the name of the structure.  */
2140   if (TYPE_NAME (node))
2141     {
2142       INDENT (spc);
2143       if (TREE_CODE (node) == RECORD_TYPE)
2144         pp_string (buffer, "struct ");
2145       else if ((TREE_CODE (node) == UNION_TYPE
2146                 || TREE_CODE (node) == QUAL_UNION_TYPE))
2147         pp_string (buffer, "union ");
2148
2149       dump_generic_node (buffer, TYPE_NAME (node), spc, 0, false);
2150     }
2151
2152   /* Print the contents of the structure.  */
2153   pp_newline (buffer);
2154   INDENT (spc);
2155   pp_character (buffer, '{');
2156   pp_newline (buffer);
2157
2158   /* Print the fields of the structure.  */
2159   {
2160     tree tmp;
2161     tmp = TYPE_FIELDS (node);
2162     while (tmp)
2163       {
2164         /* Avoid to print recursively the structure.  */
2165         /* FIXME : Not implemented correctly...,
2166            what about the case when we have a cycle in the contain graph? ...
2167            Maybe this could be solved by looking at the scope in which the
2168            structure was declared.  */
2169         if (TREE_TYPE (tmp) != node
2170             || (TREE_CODE (TREE_TYPE (tmp)) == POINTER_TYPE
2171                 && TREE_TYPE (TREE_TYPE (tmp)) != node))
2172           {
2173             print_declaration (buffer, tmp, spc+2, flags);
2174             pp_newline (buffer);
2175           }
2176         tmp = TREE_CHAIN (tmp);
2177       }
2178   }
2179   INDENT (spc);
2180   pp_character (buffer, '}');
2181 }
2182
2183 /* Return the priority of the operator OP.
2184
2185    From lowest to highest precedence with either left-to-right (L-R)
2186    or right-to-left (R-L) associativity]:
2187
2188      1  [L-R] ,
2189      2  [R-L] = += -= *= /= %= &= ^= |= <<= >>=
2190      3  [R-L] ?:
2191      4  [L-R] ||
2192      5  [L-R] &&
2193      6  [L-R] |
2194      7  [L-R] ^
2195      8  [L-R] &
2196      9  [L-R] == !=
2197     10  [L-R] < <= > >=
2198     11  [L-R] << >>
2199     12  [L-R] + -
2200     13  [L-R] * / %
2201     14  [R-L] ! ~ ++ -- + - * & (type) sizeof
2202     15  [L-R] fn() [] -> .
2203
2204    unary +, - and * have higher precedence than the corresponding binary
2205    operators.  */
2206
2207 static int
2208 op_prio (tree op)
2209 {
2210   if (op == NULL)
2211     return 9999;
2212
2213   switch (TREE_CODE (op))
2214     {
2215     case TREE_LIST:
2216     case COMPOUND_EXPR:
2217     case BIND_EXPR:
2218       return 1;
2219
2220     case MODIFY_EXPR:
2221     case GIMPLE_MODIFY_STMT:
2222     case INIT_EXPR:
2223       return 2;
2224
2225     case COND_EXPR:
2226       return 3;
2227
2228     case TRUTH_OR_EXPR:
2229     case TRUTH_ORIF_EXPR:
2230       return 4;
2231
2232     case TRUTH_AND_EXPR:
2233     case TRUTH_ANDIF_EXPR:
2234       return 5;
2235
2236     case BIT_IOR_EXPR:
2237       return 6;
2238
2239     case BIT_XOR_EXPR:
2240     case TRUTH_XOR_EXPR:
2241       return 7;
2242
2243     case BIT_AND_EXPR:
2244       return 8;
2245
2246     case EQ_EXPR:
2247     case NE_EXPR:
2248       return 9;
2249
2250     case UNLT_EXPR:
2251     case UNLE_EXPR:
2252     case UNGT_EXPR:
2253     case UNGE_EXPR:
2254     case UNEQ_EXPR:
2255     case LTGT_EXPR:
2256     case ORDERED_EXPR:
2257     case UNORDERED_EXPR:
2258     case LT_EXPR:
2259     case LE_EXPR:
2260     case GT_EXPR:
2261     case GE_EXPR:
2262       return 10;
2263
2264     case LSHIFT_EXPR:
2265     case RSHIFT_EXPR:
2266     case LROTATE_EXPR:
2267     case RROTATE_EXPR:
2268       return 11;
2269
2270     case WIDEN_SUM_EXPR:
2271     case PLUS_EXPR:
2272     case MINUS_EXPR:
2273       return 12;
2274
2275     case VEC_WIDEN_MULT_HI_EXPR:
2276     case VEC_WIDEN_MULT_LO_EXPR:
2277     case WIDEN_MULT_EXPR:
2278     case DOT_PROD_EXPR:
2279     case MULT_EXPR:
2280     case TRUNC_DIV_EXPR:
2281     case CEIL_DIV_EXPR:
2282     case FLOOR_DIV_EXPR:
2283     case ROUND_DIV_EXPR:
2284     case RDIV_EXPR:
2285     case EXACT_DIV_EXPR:
2286     case TRUNC_MOD_EXPR:
2287     case CEIL_MOD_EXPR:
2288     case FLOOR_MOD_EXPR:
2289     case ROUND_MOD_EXPR:
2290       return 13;
2291
2292     case TRUTH_NOT_EXPR:
2293     case BIT_NOT_EXPR:
2294     case POSTINCREMENT_EXPR:
2295     case POSTDECREMENT_EXPR:
2296     case PREINCREMENT_EXPR:
2297     case PREDECREMENT_EXPR:
2298     case NEGATE_EXPR:
2299     case ALIGN_INDIRECT_REF:
2300     case MISALIGNED_INDIRECT_REF:
2301     case INDIRECT_REF:
2302     case ADDR_EXPR:
2303     case FLOAT_EXPR:
2304     case NOP_EXPR:
2305     case CONVERT_EXPR:
2306     case FIX_TRUNC_EXPR:
2307     case TARGET_EXPR:
2308       return 14;
2309
2310     case CALL_EXPR:
2311     case ARRAY_REF:
2312     case ARRAY_RANGE_REF:
2313     case COMPONENT_REF:
2314       return 15;
2315
2316       /* Special expressions.  */
2317     case MIN_EXPR:
2318     case MAX_EXPR:
2319     case ABS_EXPR:
2320     case REALPART_EXPR:
2321     case IMAGPART_EXPR:
2322     case REDUC_MAX_EXPR:
2323     case REDUC_MIN_EXPR:
2324     case REDUC_PLUS_EXPR:
2325     case VEC_LSHIFT_EXPR:
2326     case VEC_RSHIFT_EXPR:
2327     case VEC_UNPACK_HI_EXPR:
2328     case VEC_UNPACK_LO_EXPR:
2329     case VEC_PACK_MOD_EXPR:
2330     case VEC_PACK_SAT_EXPR:
2331       return 16;
2332
2333     case SAVE_EXPR:
2334     case NON_LVALUE_EXPR:
2335       return op_prio (TREE_OPERAND (op, 0));
2336
2337     default:
2338       /* Return an arbitrarily high precedence to avoid surrounding single
2339          VAR_DECLs in ()s.  */
2340       return 9999;
2341     }
2342 }
2343
2344
2345 /* Return the symbol associated with operator OP.  */
2346
2347 static const char *
2348 op_symbol_1 (enum tree_code code)
2349 {
2350   switch (code)
2351     {
2352     case MODIFY_EXPR:
2353     case GIMPLE_MODIFY_STMT:
2354       return "=";
2355
2356     case TRUTH_OR_EXPR:
2357     case TRUTH_ORIF_EXPR:
2358       return "||";
2359
2360     case TRUTH_AND_EXPR:
2361     case TRUTH_ANDIF_EXPR:
2362       return "&&";
2363
2364     case BIT_IOR_EXPR:
2365       return "|";
2366
2367     case TRUTH_XOR_EXPR:
2368     case BIT_XOR_EXPR:
2369       return "^";
2370
2371     case ADDR_EXPR:
2372     case BIT_AND_EXPR:
2373       return "&";
2374
2375     case ORDERED_EXPR:
2376       return "ord";
2377     case UNORDERED_EXPR:
2378       return "unord";
2379
2380     case EQ_EXPR:
2381       return "==";
2382     case UNEQ_EXPR:
2383       return "u==";
2384
2385     case NE_EXPR:
2386       return "!=";
2387
2388     case LT_EXPR:
2389       return "<";
2390     case UNLT_EXPR:
2391       return "u<";
2392
2393     case LE_EXPR:
2394       return "<=";
2395     case UNLE_EXPR:
2396       return "u<=";
2397
2398     case GT_EXPR:
2399       return ">";
2400     case UNGT_EXPR:
2401       return "u>";
2402
2403     case GE_EXPR:
2404       return ">=";
2405     case UNGE_EXPR:
2406       return "u>=";
2407
2408     case LTGT_EXPR:
2409       return "<>";
2410
2411     case LSHIFT_EXPR:
2412       return "<<";
2413
2414     case RSHIFT_EXPR:
2415       return ">>";
2416
2417     case LROTATE_EXPR:
2418       return "r<<";
2419
2420     case RROTATE_EXPR:
2421       return "r>>";
2422
2423     case VEC_LSHIFT_EXPR:
2424       return "v<<";
2425
2426     case VEC_RSHIFT_EXPR:
2427       return "v>>";
2428  
2429     case PLUS_EXPR:
2430       return "+";
2431
2432     case REDUC_PLUS_EXPR:
2433       return "r+";
2434
2435     case WIDEN_SUM_EXPR:
2436       return "w+";
2437
2438     case WIDEN_MULT_EXPR:
2439       return "w*";
2440
2441     case NEGATE_EXPR:
2442     case MINUS_EXPR:
2443       return "-";
2444
2445     case BIT_NOT_EXPR:
2446       return "~";
2447
2448     case TRUTH_NOT_EXPR:
2449       return "!";
2450
2451     case MULT_EXPR:
2452     case INDIRECT_REF:
2453       return "*";
2454
2455     case ALIGN_INDIRECT_REF:
2456       return "A*";
2457
2458     case MISALIGNED_INDIRECT_REF:
2459       return "M*";
2460
2461     case TRUNC_DIV_EXPR:
2462     case RDIV_EXPR:
2463       return "/";
2464
2465     case CEIL_DIV_EXPR:
2466       return "/[cl]";
2467
2468     case FLOOR_DIV_EXPR:
2469       return "/[fl]";
2470
2471     case ROUND_DIV_EXPR:
2472       return "/[rd]";
2473
2474     case EXACT_DIV_EXPR:
2475       return "/[ex]";
2476
2477     case TRUNC_MOD_EXPR:
2478       return "%";
2479
2480     case CEIL_MOD_EXPR:
2481       return "%[cl]";
2482
2483     case FLOOR_MOD_EXPR:
2484       return "%[fl]";
2485
2486     case ROUND_MOD_EXPR:
2487       return "%[rd]";
2488
2489     case PREDECREMENT_EXPR:
2490       return " --";
2491
2492     case PREINCREMENT_EXPR:
2493       return " ++";
2494
2495     case POSTDECREMENT_EXPR:
2496       return "-- ";
2497
2498     case POSTINCREMENT_EXPR:
2499       return "++ ";
2500
2501     case MAX_EXPR:
2502       return "max";
2503
2504     case MIN_EXPR:
2505       return "min";
2506
2507     default:
2508       return "<<< ??? >>>";
2509     }
2510 }
2511
2512 static const char *
2513 op_symbol (tree op)
2514 {
2515   return op_symbol_1 (TREE_CODE (op));
2516 }
2517
2518 /* Prints the name of a CALL_EXPR.  */
2519
2520 static void
2521 print_call_name (pretty_printer *buffer, tree node)
2522 {
2523   tree op0;
2524
2525   gcc_assert (TREE_CODE (node) == CALL_EXPR);
2526
2527   op0 = TREE_OPERAND (node, 0);
2528
2529   if (TREE_CODE (op0) == NON_LVALUE_EXPR)
2530     op0 = TREE_OPERAND (op0, 0);
2531
2532   switch (TREE_CODE (op0))
2533     {
2534     case VAR_DECL:
2535     case PARM_DECL:
2536       dump_function_name (buffer, op0);
2537       break;
2538
2539     case ADDR_EXPR:
2540     case INDIRECT_REF:
2541     case NOP_EXPR:
2542       dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
2543       break;
2544
2545     case COND_EXPR:
2546       pp_string (buffer, "(");
2547       dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
2548       pp_string (buffer, ") ? ");
2549       dump_generic_node (buffer, TREE_OPERAND (op0, 1), 0, 0, false);
2550       pp_string (buffer, " : ");
2551       dump_generic_node (buffer, TREE_OPERAND (op0, 2), 0, 0, false);
2552       break;
2553
2554     case COMPONENT_REF:
2555       /* The function is a pointer contained in a structure.  */
2556       if (TREE_CODE (TREE_OPERAND (op0, 0)) == INDIRECT_REF ||
2557           TREE_CODE (TREE_OPERAND (op0, 0)) == VAR_DECL)
2558         dump_function_name (buffer, TREE_OPERAND (op0, 1));
2559       else
2560         dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
2561       /* else
2562          We can have several levels of structures and a function
2563          pointer inside.  This is not implemented yet...  */
2564       /*                  NIY;*/
2565       break;
2566
2567     case ARRAY_REF:
2568       if (TREE_CODE (TREE_OPERAND (op0, 0)) == VAR_DECL)
2569         dump_function_name (buffer, TREE_OPERAND (op0, 0));
2570       else
2571         dump_generic_node (buffer, op0, 0, 0, false);
2572       break;
2573
2574     case SSA_NAME:
2575     case OBJ_TYPE_REF:
2576       dump_generic_node (buffer, op0, 0, 0, false);
2577       break;
2578
2579     default:
2580       NIY;
2581     }
2582 }
2583
2584 /* Parses the string STR and replaces new-lines by '\n', tabs by '\t', ...  */
2585
2586 static void
2587 pretty_print_string (pretty_printer *buffer, const char *str)
2588 {
2589   if (str == NULL)
2590     return;
2591
2592   while (*str)
2593     {
2594       switch (str[0])
2595         {
2596         case '\b':
2597           pp_string (buffer, "\\b");
2598           break;
2599
2600         case '\f':
2601           pp_string (buffer, "\\f");
2602           break;
2603
2604         case '\n':
2605           pp_string (buffer, "\\n");
2606           break;
2607
2608         case '\r':
2609           pp_string (buffer, "\\r");
2610           break;
2611
2612         case '\t':
2613           pp_string (buffer, "\\t");
2614           break;
2615
2616         case '\v':
2617           pp_string (buffer, "\\v");
2618           break;
2619
2620         case '\\':
2621           pp_string (buffer, "\\\\");
2622           break;
2623
2624         case '\"':
2625           pp_string (buffer, "\\\"");
2626           break;
2627
2628         case '\'':
2629           pp_string (buffer, "\\'");
2630           break;
2631
2632           /* No need to handle \0; the loop terminates on \0.  */
2633
2634         case '\1':
2635           pp_string (buffer, "\\1");
2636           break;
2637
2638         case '\2':
2639           pp_string (buffer, "\\2");
2640           break;
2641
2642         case '\3':
2643           pp_string (buffer, "\\3");
2644           break;
2645
2646         case '\4':
2647           pp_string (buffer, "\\4");
2648           break;
2649
2650         case '\5':
2651           pp_string (buffer, "\\5");
2652           break;
2653
2654         case '\6':
2655           pp_string (buffer, "\\6");
2656           break;
2657
2658         case '\7':
2659           pp_string (buffer, "\\7");
2660           break;
2661
2662         default:
2663           pp_character (buffer, str[0]);
2664           break;
2665         }
2666       str++;
2667     }
2668 }
2669
2670 static void
2671 maybe_init_pretty_print (FILE *file)
2672 {
2673   if (!initialized)
2674     {
2675       pp_construct (&buffer, /* prefix */NULL, /* line-width */0);
2676       pp_needs_newline (&buffer) = true;
2677       initialized = 1;
2678     }
2679
2680   buffer.buffer->stream = file;
2681 }
2682
2683 static void
2684 newline_and_indent (pretty_printer *buffer, int spc)
2685 {
2686   pp_newline (buffer);
2687   INDENT (spc);
2688 }
2689
2690
2691 static void
2692 dump_vops (pretty_printer *buffer, tree stmt, int spc, int flags)
2693 {
2694   struct vdef_optype_d *vdefs;
2695   struct vuse_optype_d *vuses;
2696   int i, n;
2697
2698   if (!ssa_operands_active () || !stmt_references_memory_p (stmt))
2699     return;
2700
2701   /* Even if the statement doesn't have virtual operators yet, it may
2702      contain symbol information (this happens before aliases have been
2703      computed).  */
2704   if ((flags & TDF_MEMSYMS)
2705       && VUSE_OPS (stmt) == NULL
2706       && VDEF_OPS (stmt) == NULL)
2707     {
2708       if (LOADED_SYMS (stmt))
2709         {
2710           pp_string (buffer, "# LOADS: ");
2711           dump_symbols (buffer, LOADED_SYMS (stmt), flags);
2712           newline_and_indent (buffer, spc);
2713         }
2714
2715       if (STORED_SYMS (stmt))
2716         {
2717           pp_string (buffer, "# STORES: ");
2718           dump_symbols (buffer, STORED_SYMS (stmt), flags);
2719           newline_and_indent (buffer, spc);
2720         }
2721
2722       return;
2723     }
2724
2725   vuses = VUSE_OPS (stmt);
2726   while (vuses)
2727     {
2728       pp_string (buffer, "# VUSE <");
2729
2730       n = VUSE_NUM (vuses);
2731       for (i = 0; i < n; i++)
2732         {
2733           dump_generic_node (buffer, VUSE_OP (vuses, i), spc + 2, flags, false);
2734           if (i < n - 1)
2735             pp_string (buffer, ", ");
2736         }
2737
2738       pp_string (buffer, ">");
2739
2740       if (flags & TDF_MEMSYMS)
2741         dump_symbols (buffer, LOADED_SYMS (stmt), flags);
2742
2743       newline_and_indent (buffer, spc);
2744       vuses = vuses->next;
2745     }
2746
2747   vdefs = VDEF_OPS (stmt);
2748   while (vdefs)
2749     {
2750       pp_string (buffer, "# ");
2751       dump_generic_node (buffer, VDEF_RESULT (vdefs), spc + 2, flags, false);
2752       pp_string (buffer, " = VDEF <");
2753
2754       n = VDEF_NUM (vdefs);
2755       for (i = 0; i < n; i++)
2756         {
2757           dump_generic_node (buffer, VDEF_OP (vdefs, i), spc + 2, flags, 0);
2758           if (i < n - 1)
2759             pp_string (buffer, ", ");
2760         }
2761
2762       pp_string (buffer, ">");
2763
2764       if ((flags & TDF_MEMSYMS) && vdefs->next == NULL)
2765         dump_symbols (buffer, STORED_SYMS (stmt), flags);
2766
2767       newline_and_indent (buffer, spc);
2768       vdefs = vdefs->next;
2769     }
2770 }
2771
2772
2773 /* Dumps basic block BB to FILE with details described by FLAGS and
2774    indented by INDENT spaces.  */
2775
2776 void
2777 dump_generic_bb (FILE *file, basic_block bb, int indent, int flags)
2778 {
2779   maybe_init_pretty_print (file);
2780   dump_generic_bb_buff (&buffer, bb, indent, flags);
2781   pp_flush (&buffer);
2782 }
2783
2784 /* Dumps header of basic block BB to buffer BUFFER indented by INDENT
2785    spaces and details described by flags.  */
2786
2787 static void
2788 dump_bb_header (pretty_printer *buffer, basic_block bb, int indent, int flags)
2789 {
2790   edge e;
2791   tree stmt;
2792   edge_iterator ei;
2793
2794   if (flags & TDF_BLOCKS)
2795     {
2796       INDENT (indent);
2797       pp_string (buffer, "# BLOCK ");
2798       pp_decimal_int (buffer, bb->index);
2799       if (bb->frequency)
2800         {
2801           pp_string (buffer, " freq:");
2802           pp_decimal_int (buffer, bb->frequency);
2803         }
2804       if (bb->count)
2805         {
2806           pp_string (buffer, " count:");
2807           pp_widest_integer (buffer, bb->count);
2808         }
2809
2810       if (flags & TDF_LINENO)
2811         {
2812           block_stmt_iterator bsi;
2813
2814           for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
2815             if (get_lineno (bsi_stmt (bsi)) != -1)
2816               {
2817                 pp_string (buffer, ", starting at line ");
2818                 pp_decimal_int (buffer, get_lineno (bsi_stmt (bsi)));
2819                 break;
2820               }
2821         }
2822       newline_and_indent (buffer, indent);
2823
2824       pp_string (buffer, "# PRED:");
2825       pp_write_text_to_stream (buffer);
2826       FOR_EACH_EDGE (e, ei, bb->preds)
2827         if (flags & TDF_SLIM)
2828           {
2829             pp_string (buffer, " ");
2830             if (e->src == ENTRY_BLOCK_PTR)
2831               pp_string (buffer, "ENTRY");
2832             else
2833               pp_decimal_int (buffer, e->src->index);
2834           }
2835         else
2836           dump_edge_info (buffer->buffer->stream, e, 0);
2837       pp_newline (buffer);
2838     }
2839   else
2840     {
2841       stmt = first_stmt (bb);
2842       if (!stmt || TREE_CODE (stmt) != LABEL_EXPR)
2843         {
2844           INDENT (indent - 2);
2845           pp_string (buffer, "<bb ");
2846           pp_decimal_int (buffer, bb->index);
2847           pp_string (buffer, ">:");
2848           pp_newline (buffer);
2849         }
2850     }
2851   pp_write_text_to_stream (buffer);
2852   check_bb_profile (bb, buffer->buffer->stream);
2853 }
2854
2855 /* Dumps end of basic block BB to buffer BUFFER indented by INDENT
2856    spaces.  */
2857
2858 static void
2859 dump_bb_end (pretty_printer *buffer, basic_block bb, int indent, int flags)
2860 {
2861   edge e;
2862   edge_iterator ei;
2863
2864   INDENT (indent);
2865   pp_string (buffer, "# SUCC:");
2866   pp_write_text_to_stream (buffer);
2867   FOR_EACH_EDGE (e, ei, bb->succs)
2868     if (flags & TDF_SLIM)
2869       {
2870         pp_string (buffer, " ");
2871         if (e->dest == EXIT_BLOCK_PTR)
2872           pp_string (buffer, "EXIT");
2873         else
2874           pp_decimal_int (buffer, e->dest->index);
2875       }
2876     else
2877       dump_edge_info (buffer->buffer->stream, e, 1);
2878   pp_newline (buffer);
2879 }
2880
2881 /* Dump PHI nodes of basic block BB to BUFFER with details described
2882    by FLAGS and indented by INDENT spaces.  */
2883
2884 static void
2885 dump_phi_nodes (pretty_printer *buffer, basic_block bb, int indent, int flags)
2886 {
2887   tree phi = phi_nodes (bb);
2888   if (!phi)
2889     return;
2890
2891   for (; phi; phi = PHI_CHAIN (phi))
2892     {
2893       if (is_gimple_reg (PHI_RESULT (phi)) || (flags & TDF_VOPS))
2894         {
2895           INDENT (indent);
2896           pp_string (buffer, "# ");
2897           dump_generic_node (buffer, phi, indent, flags, false);
2898           pp_newline (buffer);
2899         }
2900     }
2901 }
2902
2903
2904 /* Dump jump to basic block BB that is represented implicitly in the cfg
2905    to BUFFER.  */
2906
2907 static void
2908 pp_cfg_jump (pretty_printer *buffer, basic_block bb)
2909 {
2910   tree stmt;
2911
2912   stmt = first_stmt (bb);
2913
2914   pp_string (buffer, "goto <bb ");
2915   pp_decimal_int (buffer, bb->index);
2916   pp_string (buffer, ">");
2917   if (stmt && TREE_CODE (stmt) == LABEL_EXPR)
2918     {
2919       pp_string (buffer, " (");
2920       dump_generic_node (buffer, LABEL_EXPR_LABEL (stmt), 0, 0, false);
2921       pp_string (buffer, ")");
2922     }
2923   pp_semicolon (buffer);
2924 }
2925
2926 /* Dump edges represented implicitly in basic block BB to BUFFER, indented
2927    by INDENT spaces, with details given by FLAGS.  */
2928
2929 static void
2930 dump_implicit_edges (pretty_printer *buffer, basic_block bb, int indent,
2931                      int flags)
2932 {
2933   edge e;
2934   edge_iterator ei;
2935
2936   /* If there is a fallthru edge, we may need to add an artificial goto to the
2937      dump.  */
2938   FOR_EACH_EDGE (e, ei, bb->succs)
2939     if (e->flags & EDGE_FALLTHRU)
2940       break;
2941   if (e && e->dest != bb->next_bb)
2942     {
2943       INDENT (indent);
2944
2945       if ((flags & TDF_LINENO)
2946 #ifdef USE_MAPPED_LOCATION
2947           && e->goto_locus != UNKNOWN_LOCATION
2948 #else
2949           && e->goto_locus
2950 #endif
2951           )
2952         {
2953           expanded_location goto_xloc;
2954 #ifdef USE_MAPPED_LOCATION
2955           goto_xloc = expand_location (e->goto_locus);
2956 #else
2957           goto_xloc = *e->goto_locus;
2958 #endif
2959           pp_character (buffer, '[');
2960           if (goto_xloc.file)
2961             {
2962               pp_string (buffer, goto_xloc.file);
2963               pp_string (buffer, " : ");
2964             }
2965           pp_decimal_int (buffer, goto_xloc.line);
2966           pp_string (buffer, "] ");
2967         }
2968
2969       pp_cfg_jump (buffer, e->dest);
2970       pp_newline (buffer);
2971     }
2972 }
2973
2974 /* Dumps basic block BB to buffer BUFFER with details described by FLAGS and
2975    indented by INDENT spaces.  */
2976
2977 static void
2978 dump_generic_bb_buff (pretty_printer *buffer, basic_block bb,
2979                       int indent, int flags)
2980 {
2981   block_stmt_iterator bsi;
2982   tree stmt;
2983   int label_indent = indent - 2;
2984
2985   if (label_indent < 0)
2986     label_indent = 0;
2987
2988   dump_bb_header (buffer, bb, indent, flags);
2989
2990   dump_phi_nodes (buffer, bb, indent, flags);
2991
2992   for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
2993     {
2994       int curr_indent;
2995
2996       stmt = bsi_stmt (bsi);
2997
2998       curr_indent = TREE_CODE (stmt) == LABEL_EXPR ? label_indent : indent;
2999
3000       INDENT (curr_indent);
3001       dump_generic_node (buffer, stmt, curr_indent, flags, true);
3002       pp_newline (buffer);
3003     }
3004
3005   dump_implicit_edges (buffer, bb, indent, flags);
3006
3007   if (flags & TDF_BLOCKS)
3008     dump_bb_end (buffer, bb, indent, flags);
3009 }