OSDN Git Service

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