OSDN Git Service

2006-12-13 Jakub Jelinek <jakub@redhat.com>
[pf3gnuchains/gcc-fork.git] / gcc / tree-pretty-print.c
1 /* Pretty formatting of GENERIC trees in C syntax.
2    Copyright (C) 2001, 2002, 2003, 2004, 2005, 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), 0, flags, true);
1097               pp_string (buffer, " else ");
1098               dump_generic_node (buffer, COND_EXPR_ELSE (node), 0, flags, true);
1099             }
1100           else if (!(flags & TDF_SLIM))
1101             {
1102               /* Output COND_EXPR_THEN.  */
1103               if (COND_EXPR_THEN (node))
1104                 {
1105                   newline_and_indent (buffer, spc+2);
1106                   pp_character (buffer, '{');
1107                   newline_and_indent (buffer, spc+4);
1108                   dump_generic_node (buffer, COND_EXPR_THEN (node), spc+4,
1109                                      flags, true);
1110                   newline_and_indent (buffer, spc+2);
1111                   pp_character (buffer, '}');
1112                 }
1113
1114               /* Output COND_EXPR_ELSE.  */
1115               if (COND_EXPR_ELSE (node))
1116                 {
1117                   newline_and_indent (buffer, spc);
1118                   pp_string (buffer, "else");
1119                   newline_and_indent (buffer, spc+2);
1120                   pp_character (buffer, '{');
1121                   newline_and_indent (buffer, spc+4);
1122                   dump_generic_node (buffer, COND_EXPR_ELSE (node), spc+4,
1123                                      flags, true);
1124                   newline_and_indent (buffer, spc+2);
1125                   pp_character (buffer, '}');
1126                 }
1127             }
1128           is_expr = false;
1129         }
1130       else
1131         {
1132           dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1133           pp_space (buffer);
1134           pp_character (buffer, '?');
1135           pp_space (buffer);
1136           dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1137           pp_space (buffer);
1138           pp_character (buffer, ':');
1139           pp_space (buffer);
1140           dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
1141         }
1142       break;
1143
1144     case BIND_EXPR:
1145       pp_character (buffer, '{');
1146       if (!(flags & TDF_SLIM))
1147         {
1148           if (BIND_EXPR_VARS (node))
1149             {
1150               pp_newline (buffer);
1151
1152               for (op0 = BIND_EXPR_VARS (node); op0; op0 = TREE_CHAIN (op0))
1153                 {
1154                   print_declaration (buffer, op0, spc+2, flags);
1155                   pp_newline (buffer);
1156                 }
1157             }
1158
1159           newline_and_indent (buffer, spc+2);
1160           dump_generic_node (buffer, BIND_EXPR_BODY (node), spc+2, flags, true);
1161           newline_and_indent (buffer, spc);
1162           pp_character (buffer, '}');
1163         }
1164       is_expr = false;
1165       break;
1166
1167     case CALL_EXPR:
1168       print_call_name (buffer, node);
1169
1170       /* Print parameters.  */
1171       pp_space (buffer);
1172       pp_character (buffer, '(');
1173       op1 = TREE_OPERAND (node, 1);
1174       if (op1)
1175         dump_generic_node (buffer, op1, spc, flags, false);
1176       pp_character (buffer, ')');
1177
1178       op1 = TREE_OPERAND (node, 2);
1179       if (op1)
1180         {
1181           pp_string (buffer, " [static-chain: ");
1182           dump_generic_node (buffer, op1, spc, flags, false);
1183           pp_character (buffer, ']');
1184         }
1185
1186       if (CALL_EXPR_RETURN_SLOT_OPT (node))
1187         pp_string (buffer, " [return slot optimization]");
1188       if (CALL_EXPR_TAILCALL (node))
1189         pp_string (buffer, " [tail call]");
1190       break;
1191
1192     case WITH_CLEANUP_EXPR:
1193       NIY;
1194       break;
1195
1196     case CLEANUP_POINT_EXPR:
1197       pp_string (buffer, "<<cleanup_point ");
1198       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1199       pp_string (buffer, ">>");
1200       break;
1201
1202     case PLACEHOLDER_EXPR:
1203       pp_string (buffer, "<PLACEHOLDER_EXPR ");
1204       dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
1205       pp_character (buffer, '>');
1206       break;
1207
1208       /* Binary arithmetic and logic expressions.  */
1209     case WIDEN_SUM_EXPR:
1210     case WIDEN_MULT_EXPR:
1211     case MULT_EXPR:
1212     case PLUS_EXPR:
1213     case MINUS_EXPR:
1214     case TRUNC_DIV_EXPR:
1215     case CEIL_DIV_EXPR:
1216     case FLOOR_DIV_EXPR:
1217     case ROUND_DIV_EXPR:
1218     case TRUNC_MOD_EXPR:
1219     case CEIL_MOD_EXPR:
1220     case FLOOR_MOD_EXPR:
1221     case ROUND_MOD_EXPR:
1222     case RDIV_EXPR:
1223     case EXACT_DIV_EXPR:
1224     case LSHIFT_EXPR:
1225     case RSHIFT_EXPR:
1226     case LROTATE_EXPR:
1227     case RROTATE_EXPR:
1228     case VEC_LSHIFT_EXPR:
1229     case VEC_RSHIFT_EXPR:
1230     case BIT_IOR_EXPR:
1231     case BIT_XOR_EXPR:
1232     case BIT_AND_EXPR:
1233     case TRUTH_ANDIF_EXPR:
1234     case TRUTH_ORIF_EXPR:
1235     case TRUTH_AND_EXPR:
1236     case TRUTH_OR_EXPR:
1237     case TRUTH_XOR_EXPR:
1238     case LT_EXPR:
1239     case LE_EXPR:
1240     case GT_EXPR:
1241     case GE_EXPR:
1242     case EQ_EXPR:
1243     case NE_EXPR:
1244     case UNLT_EXPR:
1245     case UNLE_EXPR:
1246     case UNGT_EXPR:
1247     case UNGE_EXPR:
1248     case UNEQ_EXPR:
1249     case LTGT_EXPR:
1250     case ORDERED_EXPR:
1251     case UNORDERED_EXPR:
1252       {
1253         const char *op = op_symbol (node);
1254         op0 = TREE_OPERAND (node, 0);
1255         op1 = TREE_OPERAND (node, 1);
1256
1257         /* When the operands are expressions with less priority,
1258            keep semantics of the tree representation.  */
1259         if (op_prio (op0) < op_prio (node))
1260           {
1261             pp_character (buffer, '(');
1262             dump_generic_node (buffer, op0, spc, flags, false);
1263             pp_character (buffer, ')');
1264           }
1265         else
1266           dump_generic_node (buffer, op0, spc, flags, false);
1267
1268         pp_space (buffer);
1269         pp_string (buffer, op);
1270         pp_space (buffer);
1271
1272         /* When the operands are expressions with less priority,
1273            keep semantics of the tree representation.  */
1274         if (op_prio (op1) < op_prio (node))
1275           {
1276             pp_character (buffer, '(');
1277             dump_generic_node (buffer, op1, spc, flags, false);
1278             pp_character (buffer, ')');
1279           }
1280         else
1281           dump_generic_node (buffer, op1, spc, flags, false);
1282       }
1283       break;
1284
1285       /* Unary arithmetic and logic expressions.  */
1286     case NEGATE_EXPR:
1287     case BIT_NOT_EXPR:
1288     case TRUTH_NOT_EXPR:
1289     case ADDR_EXPR:
1290     case PREDECREMENT_EXPR:
1291     case PREINCREMENT_EXPR:
1292     case ALIGN_INDIRECT_REF:
1293     case MISALIGNED_INDIRECT_REF:
1294     case INDIRECT_REF:
1295       if (TREE_CODE (node) == ADDR_EXPR
1296           && (TREE_CODE (TREE_OPERAND (node, 0)) == STRING_CST
1297               || TREE_CODE (TREE_OPERAND (node, 0)) == FUNCTION_DECL))
1298         ;       /* Do not output '&' for strings and function pointers.  */
1299       else
1300         pp_string (buffer, op_symbol (node));
1301
1302       if (op_prio (TREE_OPERAND (node, 0)) < op_prio (node))
1303         {
1304           pp_character (buffer, '(');
1305           dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1306           pp_character (buffer, ')');
1307         }
1308       else
1309         dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1310
1311       if (TREE_CODE (node) == MISALIGNED_INDIRECT_REF)
1312         {
1313           pp_string (buffer, "{misalignment: ");
1314           dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1315           pp_character (buffer, '}');
1316         }
1317       break;
1318
1319     case POSTDECREMENT_EXPR:
1320     case POSTINCREMENT_EXPR:
1321       if (op_prio (TREE_OPERAND (node, 0)) < op_prio (node))
1322         {
1323           pp_character (buffer, '(');
1324           dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1325           pp_character (buffer, ')');
1326         }
1327       else
1328         dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1329       pp_string (buffer, op_symbol (node));
1330       break;
1331
1332     case MIN_EXPR:
1333       pp_string (buffer, "MIN_EXPR <");
1334       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1335       pp_string (buffer, ", ");
1336       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1337       pp_character (buffer, '>');
1338       break;
1339
1340     case MAX_EXPR:
1341       pp_string (buffer, "MAX_EXPR <");
1342       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1343       pp_string (buffer, ", ");
1344       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1345       pp_character (buffer, '>');
1346       break;
1347
1348     case ABS_EXPR:
1349       pp_string (buffer, "ABS_EXPR <");
1350       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1351       pp_character (buffer, '>');
1352       break;
1353
1354     case RANGE_EXPR:
1355       NIY;
1356       break;
1357
1358     case FIX_TRUNC_EXPR:
1359     case FLOAT_EXPR:
1360     case CONVERT_EXPR:
1361     case NOP_EXPR:
1362       type = TREE_TYPE (node);
1363       op0 = TREE_OPERAND (node, 0);
1364       if (type != TREE_TYPE (op0))
1365         {
1366           pp_character (buffer, '(');
1367           dump_generic_node (buffer, type, spc, flags, false);
1368           pp_string (buffer, ") ");
1369         }
1370       if (op_prio (op0) < op_prio (node))
1371         pp_character (buffer, '(');
1372       dump_generic_node (buffer, op0, spc, flags, false);
1373       if (op_prio (op0) < op_prio (node))
1374         pp_character (buffer, ')');
1375       break;
1376
1377     case VIEW_CONVERT_EXPR:
1378       pp_string (buffer, "VIEW_CONVERT_EXPR<");
1379       dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
1380       pp_string (buffer, ">(");
1381       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1382       pp_character (buffer, ')');
1383       break;
1384
1385     case NON_LVALUE_EXPR:
1386       pp_string (buffer, "NON_LVALUE_EXPR <");
1387       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1388       pp_character (buffer, '>');
1389       break;
1390
1391     case SAVE_EXPR:
1392       pp_string (buffer, "SAVE_EXPR <");
1393       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1394       pp_character (buffer, '>');
1395       break;
1396
1397     case COMPLEX_EXPR:
1398       pp_string (buffer, "COMPLEX_EXPR <");
1399       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1400       pp_string (buffer, ", ");
1401       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1402       pp_string (buffer, ">");
1403       break;
1404
1405     case CONJ_EXPR:
1406       pp_string (buffer, "CONJ_EXPR <");
1407       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1408       pp_string (buffer, ">");
1409       break;
1410
1411     case REALPART_EXPR:
1412       pp_string (buffer, "REALPART_EXPR <");
1413       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1414       pp_string (buffer, ">");
1415       break;
1416
1417     case IMAGPART_EXPR:
1418       pp_string (buffer, "IMAGPART_EXPR <");
1419       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1420       pp_string (buffer, ">");
1421       break;
1422
1423     case VA_ARG_EXPR:
1424       pp_string (buffer, "VA_ARG_EXPR <");
1425       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1426       pp_string (buffer, ">");
1427       break;
1428
1429     case TRY_FINALLY_EXPR:
1430     case TRY_CATCH_EXPR:
1431       pp_string (buffer, "try");
1432       newline_and_indent (buffer, spc+2);
1433       pp_string (buffer, "{");
1434       newline_and_indent (buffer, spc+4);
1435       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc+4, flags, true);
1436       newline_and_indent (buffer, spc+2);
1437       pp_string (buffer, "}");
1438       newline_and_indent (buffer, spc);
1439       pp_string (buffer,
1440                          (TREE_CODE (node) == TRY_CATCH_EXPR) ? "catch" : "finally");
1441       newline_and_indent (buffer, spc+2);
1442       pp_string (buffer, "{");
1443       newline_and_indent (buffer, spc+4);
1444       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc+4, flags, true);
1445       newline_and_indent (buffer, spc+2);
1446       pp_string (buffer, "}");
1447       is_expr = false;
1448       break;
1449
1450     case CATCH_EXPR:
1451       pp_string (buffer, "catch (");
1452       dump_generic_node (buffer, CATCH_TYPES (node), spc+2, flags, false);
1453       pp_string (buffer, ")");
1454       newline_and_indent (buffer, spc+2);
1455       pp_string (buffer, "{");
1456       newline_and_indent (buffer, spc+4);
1457       dump_generic_node (buffer, CATCH_BODY (node), spc+4, flags, true);
1458       newline_and_indent (buffer, spc+2);
1459       pp_string (buffer, "}");
1460       is_expr = false;
1461       break;
1462
1463     case EH_FILTER_EXPR:
1464       pp_string (buffer, "<<<eh_filter (");
1465       dump_generic_node (buffer, EH_FILTER_TYPES (node), spc+2, flags, false);
1466       pp_string (buffer, ")>>>");
1467       newline_and_indent (buffer, spc+2);
1468       pp_string (buffer, "{");
1469       newline_and_indent (buffer, spc+4);
1470       dump_generic_node (buffer, EH_FILTER_FAILURE (node), spc+4, flags, true);
1471       newline_and_indent (buffer, spc+2);
1472       pp_string (buffer, "}");
1473       is_expr = false;
1474       break;
1475
1476     case LABEL_EXPR:
1477       op0 = TREE_OPERAND (node, 0);
1478       /* If this is for break or continue, don't bother printing it.  */
1479       if (DECL_NAME (op0))
1480         {
1481           const char *name = IDENTIFIER_POINTER (DECL_NAME (op0));
1482           if (strcmp (name, "break") == 0
1483               || strcmp (name, "continue") == 0)
1484             break;
1485         }
1486       dump_generic_node (buffer, op0, spc, flags, false);
1487       pp_character (buffer, ':');
1488       if (DECL_NONLOCAL (op0))
1489         pp_string (buffer, " [non-local]");
1490       break;
1491
1492     case EXC_PTR_EXPR:
1493       pp_string (buffer, "<<<exception object>>>");
1494       break;
1495
1496     case FILTER_EXPR:
1497       pp_string (buffer, "<<<filter object>>>");
1498       break;
1499
1500     case LOOP_EXPR:
1501       pp_string (buffer, "while (1)");
1502       if (!(flags & TDF_SLIM))
1503         {
1504           newline_and_indent (buffer, spc+2);
1505           pp_character (buffer, '{');
1506           newline_and_indent (buffer, spc+4);
1507           dump_generic_node (buffer, LOOP_EXPR_BODY (node), spc+4, flags, true);
1508           newline_and_indent (buffer, spc+2);
1509           pp_character (buffer, '}');
1510         }
1511       is_expr = false;
1512       break;
1513
1514     case RETURN_EXPR:
1515       pp_string (buffer, "return");
1516       op0 = TREE_OPERAND (node, 0);
1517       if (op0)
1518         {
1519           pp_space (buffer);
1520           if (TREE_CODE (op0) == MODIFY_EXPR
1521               || TREE_CODE (op0) == GIMPLE_MODIFY_STMT)
1522             dump_generic_node (buffer, GENERIC_TREE_OPERAND (op0, 1),
1523                                spc, flags, false);
1524           else
1525             dump_generic_node (buffer, op0, spc, flags, false);
1526         }
1527       break;
1528
1529     case EXIT_EXPR:
1530       pp_string (buffer, "if (");
1531       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1532       pp_string (buffer, ") break");
1533       break;
1534
1535     case SWITCH_EXPR:
1536       pp_string (buffer, "switch (");
1537       dump_generic_node (buffer, SWITCH_COND (node), spc, flags, false);
1538       pp_character (buffer, ')');
1539       if (!(flags & TDF_SLIM))
1540         {
1541           newline_and_indent (buffer, spc+2);
1542           pp_character (buffer, '{');
1543           if (SWITCH_BODY (node))
1544             {
1545               newline_and_indent (buffer, spc+4);
1546               dump_generic_node (buffer, SWITCH_BODY (node), spc+4, flags,
1547                                  true);
1548             }
1549           else
1550             {
1551               tree vec = SWITCH_LABELS (node);
1552               size_t i, n = TREE_VEC_LENGTH (vec);
1553               for (i = 0; i < n; ++i)
1554                 {
1555                   tree elt = TREE_VEC_ELT (vec, i);
1556                   newline_and_indent (buffer, spc+4);
1557                   if (elt)
1558                     {
1559                       dump_generic_node (buffer, elt, spc+4, flags, false);
1560                       pp_string (buffer, " goto ");
1561                       dump_generic_node (buffer, CASE_LABEL (elt), spc+4,
1562                                          flags, true);
1563                       pp_semicolon (buffer);
1564                     }
1565                   else
1566                     pp_string (buffer, "case ???: goto ???;");
1567                 }
1568             }
1569           newline_and_indent (buffer, spc+2);
1570           pp_character (buffer, '}');
1571         }
1572       is_expr = false;
1573       break;
1574
1575     case GOTO_EXPR:
1576       op0 = GOTO_DESTINATION (node);
1577       if (TREE_CODE (op0) != SSA_NAME && DECL_P (op0) && DECL_NAME (op0))
1578         {
1579           const char *name = IDENTIFIER_POINTER (DECL_NAME (op0));
1580           if (strcmp (name, "break") == 0
1581               || strcmp (name, "continue") == 0)
1582             {
1583               pp_string (buffer, name);
1584               break;
1585             }
1586         }
1587       pp_string (buffer, "goto ");
1588       dump_generic_node (buffer, op0, spc, flags, false);
1589       break;
1590
1591     case RESX_EXPR:
1592       pp_string (buffer, "resx ");
1593       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1594       break;
1595
1596     case ASM_EXPR:
1597       pp_string (buffer, "__asm__");
1598       if (ASM_VOLATILE_P (node))
1599         pp_string (buffer, " __volatile__");
1600       pp_character (buffer, '(');
1601       dump_generic_node (buffer, ASM_STRING (node), spc, flags, false);
1602       pp_character (buffer, ':');
1603       dump_generic_node (buffer, ASM_OUTPUTS (node), spc, flags, false);
1604       pp_character (buffer, ':');
1605       dump_generic_node (buffer, ASM_INPUTS (node), spc, flags, false);
1606       if (ASM_CLOBBERS (node))
1607         {
1608           pp_character (buffer, ':');
1609           dump_generic_node (buffer, ASM_CLOBBERS (node), spc, flags, false);
1610         }
1611       pp_string (buffer, ")");
1612       break;
1613
1614     case CASE_LABEL_EXPR:
1615       if (CASE_LOW (node) && CASE_HIGH (node))
1616         {
1617           pp_string (buffer, "case ");
1618           dump_generic_node (buffer, CASE_LOW (node), spc, flags, false);
1619           pp_string (buffer, " ... ");
1620           dump_generic_node (buffer, CASE_HIGH (node), spc, flags, false);
1621         }
1622       else if (CASE_LOW (node))
1623         {
1624           pp_string (buffer, "case ");
1625           dump_generic_node (buffer, CASE_LOW (node), spc, flags, false);
1626         }
1627       else
1628         pp_string (buffer, "default ");
1629       pp_character (buffer, ':');
1630       break;
1631
1632     case OBJ_TYPE_REF:
1633       pp_string (buffer, "OBJ_TYPE_REF(");
1634       dump_generic_node (buffer, OBJ_TYPE_REF_EXPR (node), spc, flags, false);
1635       pp_character (buffer, ';');
1636       dump_generic_node (buffer, OBJ_TYPE_REF_OBJECT (node), spc, flags, false);
1637       pp_character (buffer, '-');
1638       pp_character (buffer, '>');
1639       dump_generic_node (buffer, OBJ_TYPE_REF_TOKEN (node), spc, flags, false);
1640       pp_character (buffer, ')');
1641       break;
1642
1643     case PHI_NODE:
1644       {
1645         int i;
1646
1647         dump_generic_node (buffer, PHI_RESULT (node), spc, flags, false);
1648         pp_string (buffer, " = PHI <");
1649         for (i = 0; i < PHI_NUM_ARGS (node); i++)
1650           {
1651             dump_generic_node (buffer, PHI_ARG_DEF (node, i), spc, flags, false);
1652             pp_string (buffer, "(");
1653             pp_decimal_int (buffer, PHI_ARG_EDGE (node, i)->src->index);
1654             pp_string (buffer, ")");
1655             if (i < PHI_NUM_ARGS (node) - 1)
1656               pp_string (buffer, ", ");
1657           }
1658         pp_string (buffer, ">");
1659
1660         if (stmt_references_memory_p (node) && (flags & TDF_MEMSYMS))
1661           dump_symbols (buffer, STORED_SYMS (node), flags);
1662       }
1663       break;
1664
1665     case SSA_NAME:
1666       dump_generic_node (buffer, SSA_NAME_VAR (node), spc, flags, false);
1667       pp_string (buffer, "_");
1668       pp_decimal_int (buffer, SSA_NAME_VERSION (node));
1669       if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (node))
1670         pp_string (buffer, "(ab)");
1671       else if (SSA_NAME_IS_DEFAULT_DEF (node))
1672         pp_string (buffer, "(D)");
1673       break;
1674
1675     case WITH_SIZE_EXPR:
1676       pp_string (buffer, "WITH_SIZE_EXPR <");
1677       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1678       pp_string (buffer, ", ");
1679       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1680       pp_string (buffer, ">");
1681       break;
1682
1683     case VALUE_HANDLE:
1684       pp_printf (buffer, "VH.%d", VALUE_HANDLE_ID (node));
1685       break;
1686
1687     case ASSERT_EXPR:
1688       pp_string (buffer, "ASSERT_EXPR <");
1689       dump_generic_node (buffer, ASSERT_EXPR_VAR (node), spc, flags, false);
1690       pp_string (buffer, ", ");
1691       dump_generic_node (buffer, ASSERT_EXPR_COND (node), spc, flags, false);
1692       pp_string (buffer, ">");
1693       break;
1694
1695     case SCEV_KNOWN:
1696       pp_string (buffer, "scev_known");
1697       break;
1698
1699     case SCEV_NOT_KNOWN:
1700       pp_string (buffer, "scev_not_known");
1701       break;
1702
1703     case POLYNOMIAL_CHREC:
1704       pp_string (buffer, "{");
1705       dump_generic_node (buffer, CHREC_LEFT (node), spc, flags, false);
1706       pp_string (buffer, ", +, ");
1707       dump_generic_node (buffer, CHREC_RIGHT (node), spc, flags, false);
1708       pp_string (buffer, "}_");
1709       dump_generic_node (buffer, CHREC_VAR (node), spc, flags, false);
1710       is_stmt = false;
1711       break;
1712
1713     case REALIGN_LOAD_EXPR:
1714       pp_string (buffer, "REALIGN_LOAD <");
1715       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1716       pp_string (buffer, ", ");
1717       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1718       pp_string (buffer, ", ");
1719       dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
1720       pp_string (buffer, ">");
1721       break;
1722       
1723     case VEC_COND_EXPR:
1724       pp_string (buffer, " VEC_COND_EXPR < ");
1725       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1726       pp_string (buffer, " , ");
1727       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1728       pp_string (buffer, " , ");
1729       dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
1730       pp_string (buffer, " > ");
1731       break;
1732
1733     case DOT_PROD_EXPR:
1734       pp_string (buffer, " DOT_PROD_EXPR < ");
1735       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1736       pp_string (buffer, ", ");
1737       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1738       pp_string (buffer, ", ");
1739       dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
1740       pp_string (buffer, " > ");
1741       break;
1742
1743     case OMP_PARALLEL:
1744       pp_string (buffer, "#pragma omp parallel");
1745       dump_omp_clauses (buffer, OMP_PARALLEL_CLAUSES (node), spc, flags);
1746       if (OMP_PARALLEL_FN (node))
1747         {
1748           pp_string (buffer, " [child fn: ");
1749           dump_generic_node (buffer, OMP_PARALLEL_FN (node), spc, flags, false);
1750
1751           pp_string (buffer, " (");
1752
1753           if (OMP_PARALLEL_DATA_ARG (node))
1754             dump_generic_node (buffer, OMP_PARALLEL_DATA_ARG (node), spc, flags,
1755                                false);
1756           else
1757             pp_string (buffer, "???");
1758
1759           pp_string (buffer, ")]");
1760         }
1761
1762     dump_omp_body:
1763       if (!(flags & TDF_SLIM) && OMP_BODY (node))
1764         {
1765           newline_and_indent (buffer, spc + 2);
1766           pp_character (buffer, '{');
1767           newline_and_indent (buffer, spc + 4);
1768           dump_generic_node (buffer, OMP_BODY (node), spc + 4, flags, false);
1769           newline_and_indent (buffer, spc + 2);
1770           pp_character (buffer, '}');
1771         }
1772       is_expr = false;
1773       break;
1774
1775     case OMP_FOR:
1776       pp_string (buffer, "#pragma omp for");
1777       dump_omp_clauses (buffer, OMP_FOR_CLAUSES (node), spc, flags);
1778
1779       if (!(flags & TDF_SLIM))
1780         {
1781           if (OMP_FOR_PRE_BODY (node))
1782             {
1783               newline_and_indent (buffer, spc + 2);
1784               pp_character (buffer, '{');
1785               spc += 4;
1786               newline_and_indent (buffer, spc);
1787               dump_generic_node (buffer, OMP_FOR_PRE_BODY (node),
1788                   spc, flags, false);
1789             }
1790           newline_and_indent (buffer, spc);
1791           pp_string (buffer, "for (");
1792           dump_generic_node (buffer, OMP_FOR_INIT (node), spc, flags, false);
1793           pp_string (buffer, "; ");
1794           dump_generic_node (buffer, OMP_FOR_COND (node), spc, flags, false);
1795           pp_string (buffer, "; ");
1796           dump_generic_node (buffer, OMP_FOR_INCR (node), spc, flags, false);
1797           pp_string (buffer, ")");
1798           if (OMP_FOR_BODY (node))
1799             {
1800               newline_and_indent (buffer, spc + 2);
1801               pp_character (buffer, '{');
1802               newline_and_indent (buffer, spc + 4);
1803               dump_generic_node (buffer, OMP_FOR_BODY (node), spc + 4, flags,
1804                   false);
1805               newline_and_indent (buffer, spc + 2);
1806               pp_character (buffer, '}');
1807             }
1808           if (OMP_FOR_PRE_BODY (node))
1809             {
1810               spc -= 4;
1811               newline_and_indent (buffer, spc + 2);
1812               pp_character (buffer, '}');
1813             }
1814         }
1815       is_expr = false;
1816       break;
1817
1818     case OMP_SECTIONS:
1819       pp_string (buffer, "#pragma omp sections");
1820       dump_omp_clauses (buffer, OMP_SECTIONS_CLAUSES (node), spc, flags);
1821       goto dump_omp_body;
1822
1823     case OMP_SECTION:
1824       pp_string (buffer, "#pragma omp section");
1825       goto dump_omp_body;
1826  
1827     case OMP_MASTER:
1828       pp_string (buffer, "#pragma omp master");
1829       goto dump_omp_body;
1830
1831     case OMP_ORDERED:
1832       pp_string (buffer, "#pragma omp ordered");
1833       goto dump_omp_body;
1834
1835     case OMP_CRITICAL:
1836       pp_string (buffer, "#pragma omp critical");
1837       if (OMP_CRITICAL_NAME (node))
1838         {
1839           pp_space (buffer);
1840           pp_character (buffer, '(');
1841           dump_generic_node (buffer, OMP_CRITICAL_NAME (node), spc,
1842                              flags, false);
1843           pp_character (buffer, ')');
1844         }
1845       goto dump_omp_body;
1846
1847     case OMP_ATOMIC:
1848       pp_string (buffer, "#pragma omp atomic");
1849       newline_and_indent (buffer, spc + 2);
1850       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1851       pp_space (buffer);
1852       pp_character (buffer, '=');
1853       pp_space (buffer);
1854       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1855       break;
1856
1857     case OMP_SINGLE:
1858       pp_string (buffer, "#pragma omp single");
1859       dump_omp_clauses (buffer, OMP_SINGLE_CLAUSES (node), spc, flags);
1860       goto dump_omp_body;
1861
1862     case OMP_RETURN:
1863       pp_string (buffer, "OMP_RETURN");
1864       if (OMP_RETURN_NOWAIT (node))
1865         pp_string (buffer, " [nowait]");
1866       is_expr = false;
1867       break;
1868
1869     case OMP_CONTINUE:
1870       pp_string (buffer, "OMP_CONTINUE");
1871       is_expr = false;
1872       break;
1873
1874     case OMP_CLAUSE:
1875       dump_omp_clause (buffer, node, spc, flags);
1876       is_expr = false;
1877       break;
1878
1879     case REDUC_MAX_EXPR:
1880       pp_string (buffer, " REDUC_MAX_EXPR < ");
1881       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1882       pp_string (buffer, " > ");
1883       break;
1884
1885     case REDUC_MIN_EXPR:
1886       pp_string (buffer, " REDUC_MIN_EXPR < ");
1887       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1888       pp_string (buffer, " > ");
1889       break;
1890
1891     case REDUC_PLUS_EXPR:
1892       pp_string (buffer, " REDUC_PLUS_EXPR < ");
1893       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1894       pp_string (buffer, " > ");
1895       break;
1896
1897     case VEC_WIDEN_MULT_HI_EXPR:
1898       pp_string (buffer, " VEC_WIDEN_MULT_HI_EXPR < ");
1899       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1900       pp_string (buffer, ", ");
1901       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1902       pp_string (buffer, " > ");
1903       break;
1904
1905     case VEC_WIDEN_MULT_LO_EXPR:
1906       pp_string (buffer, " VEC_WIDEN_MULT_LO_EXPR < ");
1907       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1908       pp_string (buffer, ", ");
1909       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1910       pp_string (buffer, " > ");
1911       break;
1912
1913     case VEC_UNPACK_HI_EXPR:
1914       pp_string (buffer, " VEC_UNPACK_HI_EXPR < ");
1915       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1916       pp_string (buffer, " > ");
1917       break;
1918
1919     case VEC_UNPACK_LO_EXPR:
1920       pp_string (buffer, " VEC_UNPACK_LO_EXPR < ");
1921       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1922       pp_string (buffer, " > ");
1923       break;
1924
1925     case VEC_PACK_MOD_EXPR:
1926       pp_string (buffer, " VEC_PACK_MOD_EXPR < ");
1927       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1928       pp_string (buffer, ", ");
1929       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1930       pp_string (buffer, " > ");
1931       break;
1932                                                                                 
1933     case VEC_PACK_SAT_EXPR:
1934       pp_string (buffer, " VEC_PACK_SAT_EXPR < ");
1935       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1936       pp_string (buffer, ", ");
1937       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1938       pp_string (buffer, " > ");
1939       break;
1940                                                                                 
1941     case BLOCK:
1942       {
1943         tree t;
1944         pp_string (buffer, "BLOCK");
1945
1946         if (BLOCK_ABSTRACT (node))
1947           pp_string (buffer, " [abstract]");
1948
1949         if (TREE_ASM_WRITTEN (node))
1950           pp_string (buffer, " [written]");
1951
1952         newline_and_indent (buffer, spc + 2);
1953
1954         if (BLOCK_SUPERCONTEXT (node))
1955           {
1956             pp_string (buffer, "SUPERCONTEXT: ");
1957             if (TREE_CODE (BLOCK_SUPERCONTEXT (node)) == BLOCK)
1958               pp_printf (buffer, "BLOCK %p",
1959                          (void *)BLOCK_SUPERCONTEXT (node));
1960             else
1961               dump_generic_node (buffer, BLOCK_SUPERCONTEXT (node), 0, flags,
1962                                  false);
1963             newline_and_indent (buffer, spc + 2);
1964           }
1965
1966         if (BLOCK_SUBBLOCKS (node))
1967           {
1968             pp_string (buffer, "SUBBLOCKS: ");
1969             for (t = BLOCK_SUBBLOCKS (node); t; t = BLOCK_CHAIN (t))
1970               pp_printf (buffer, "%p ", (void *)t);
1971             newline_and_indent (buffer, spc + 2);
1972           }
1973
1974         if (BLOCK_VARS (node))
1975           {
1976             pp_string (buffer, "VARS: ");
1977             for (t = BLOCK_VARS (node); t; t = TREE_CHAIN (t))
1978               {
1979                 dump_generic_node (buffer, t, 0, flags, false);
1980                 pp_string (buffer, " ");
1981               }
1982             newline_and_indent (buffer, spc + 2);
1983           }
1984
1985         if (BLOCK_ABSTRACT_ORIGIN (node))
1986           {
1987             pp_string (buffer, "ABSTRACT_ORIGIN: ");
1988             if (TREE_CODE (BLOCK_ABSTRACT_ORIGIN (node)) == BLOCK)
1989               pp_printf (buffer, "BLOCK %p",
1990                          (void *)BLOCK_ABSTRACT_ORIGIN (node));
1991             else
1992               dump_generic_node (buffer, BLOCK_ABSTRACT_ORIGIN (node), 0, flags,
1993                                  false);
1994             newline_and_indent (buffer, spc + 2);
1995           }
1996       }
1997     break;
1998
1999     case VEC_EXTRACT_EVEN_EXPR:
2000       pp_string (buffer, " VEC_EXTRACT_EVEN_EXPR < ");
2001       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
2002       pp_string (buffer, ", ");
2003       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
2004       pp_string (buffer, " > ");
2005       break;
2006   
2007     case VEC_EXTRACT_ODD_EXPR:
2008       pp_string (buffer, " VEC_EXTRACT_ODD_EXPR < ");
2009       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
2010       pp_string (buffer, ", ");
2011       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
2012       pp_string (buffer, " > ");
2013       break;
2014
2015     case VEC_INTERLEAVE_HIGH_EXPR:
2016       pp_string (buffer, " VEC_INTERLEAVE_HIGH_EXPR < ");
2017       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
2018       pp_string (buffer, ", ");
2019       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
2020       pp_string (buffer, " > ");
2021       break;
2022
2023     case VEC_INTERLEAVE_LOW_EXPR:
2024       pp_string (buffer, " VEC_INTERLEAVE_LOW_EXPR < ");
2025       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
2026       pp_string (buffer, ", ");
2027       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
2028       pp_string (buffer, " > ");
2029       break;
2030
2031     default:
2032       NIY;
2033     }
2034
2035   if (is_stmt && is_expr)
2036     pp_semicolon (buffer);
2037   pp_write_text_to_stream (buffer);
2038
2039   return spc;
2040 }
2041
2042 /* Print the declaration of a variable.  */
2043
2044 static void
2045 print_declaration (pretty_printer *buffer, tree t, int spc, int flags)
2046 {
2047   INDENT (spc);
2048
2049   if (TREE_CODE (t) == TYPE_DECL)
2050     pp_string (buffer, "typedef ");
2051
2052   if (CODE_CONTAINS_STRUCT (TREE_CODE (t), TS_DECL_WRTL) && DECL_REGISTER (t))
2053     pp_string (buffer, "register ");
2054
2055   if (TREE_PUBLIC (t) && DECL_EXTERNAL (t))
2056     pp_string (buffer, "extern ");
2057   else if (TREE_STATIC (t))
2058     pp_string (buffer, "static ");
2059
2060   /* Print the type and name.  */
2061   if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
2062     {
2063       tree tmp;
2064
2065       /* Print array's type.  */
2066       tmp = TREE_TYPE (t);
2067       while (TREE_CODE (TREE_TYPE (tmp)) == ARRAY_TYPE)
2068         tmp = TREE_TYPE (tmp);
2069       dump_generic_node (buffer, TREE_TYPE (tmp), spc, flags, false);
2070
2071       /* Print variable's name.  */
2072       pp_space (buffer);
2073       dump_generic_node (buffer, t, spc, flags, false);
2074
2075       /* Print the dimensions.  */
2076       tmp = TREE_TYPE (t);
2077       while (TREE_CODE (tmp) == ARRAY_TYPE)
2078         {
2079           dump_array_domain (buffer, TYPE_DOMAIN (tmp), spc, flags);
2080           tmp = TREE_TYPE (tmp);
2081         }
2082     }
2083   else if (TREE_CODE (t) == FUNCTION_DECL)
2084     {
2085       dump_generic_node (buffer, TREE_TYPE (TREE_TYPE (t)), spc, flags, false);
2086       pp_space (buffer);
2087       dump_decl_name (buffer, t, flags);
2088       dump_function_declaration (buffer, TREE_TYPE (t), spc, flags);
2089     }
2090   else
2091     {
2092       /* Print type declaration.  */
2093       dump_generic_node (buffer, TREE_TYPE (t), spc, flags, false);
2094
2095       /* Print variable's name.  */
2096       pp_space (buffer);
2097       dump_generic_node (buffer, t, spc, flags, false);
2098     }
2099
2100   if (TREE_CODE (t) == VAR_DECL && DECL_HARD_REGISTER (t))
2101     {
2102       pp_string (buffer, " __asm__ ");
2103       pp_character (buffer, '(');
2104       dump_generic_node (buffer, DECL_ASSEMBLER_NAME (t), spc, flags, false);
2105       pp_character (buffer, ')');
2106     }
2107
2108   /* The initial value of a function serves to determine wether the function
2109      is declared or defined.  So the following does not apply to function
2110      nodes.  */
2111   if (TREE_CODE (t) != FUNCTION_DECL)
2112     {
2113       /* Print the initial value.  */
2114       if (DECL_INITIAL (t))
2115         {
2116           pp_space (buffer);
2117           pp_character (buffer, '=');
2118           pp_space (buffer);
2119           dump_generic_node (buffer, DECL_INITIAL (t), spc, flags, false);
2120         }
2121     }
2122
2123   if (TREE_CODE (t) == VAR_DECL && DECL_HAS_VALUE_EXPR_P (t))
2124     {
2125       pp_string (buffer, " [value-expr: ");
2126       dump_generic_node (buffer, DECL_VALUE_EXPR (t), spc, flags, false);
2127       pp_character (buffer, ']');
2128     }
2129
2130   pp_character (buffer, ';');
2131 }
2132
2133
2134 /* Prints a structure: name, fields, and methods.
2135    FIXME: Still incomplete.  */
2136
2137 static void
2138 print_struct_decl (pretty_printer *buffer, tree node, int spc, int flags)
2139 {
2140   /* Print the name of the structure.  */
2141   if (TYPE_NAME (node))
2142     {
2143       INDENT (spc);
2144       if (TREE_CODE (node) == RECORD_TYPE)
2145         pp_string (buffer, "struct ");
2146       else if ((TREE_CODE (node) == UNION_TYPE
2147                 || TREE_CODE (node) == QUAL_UNION_TYPE))
2148         pp_string (buffer, "union ");
2149
2150       dump_generic_node (buffer, TYPE_NAME (node), spc, 0, false);
2151     }
2152
2153   /* Print the contents of the structure.  */
2154   pp_newline (buffer);
2155   INDENT (spc);
2156   pp_character (buffer, '{');
2157   pp_newline (buffer);
2158
2159   /* Print the fields of the structure.  */
2160   {
2161     tree tmp;
2162     tmp = TYPE_FIELDS (node);
2163     while (tmp)
2164       {
2165         /* Avoid to print recursively the structure.  */
2166         /* FIXME : Not implemented correctly...,
2167            what about the case when we have a cycle in the contain graph? ...
2168            Maybe this could be solved by looking at the scope in which the
2169            structure was declared.  */
2170         if (TREE_TYPE (tmp) != node
2171             || (TREE_CODE (TREE_TYPE (tmp)) == POINTER_TYPE
2172                 && TREE_TYPE (TREE_TYPE (tmp)) != node))
2173           {
2174             print_declaration (buffer, tmp, spc+2, flags);
2175             pp_newline (buffer);
2176           }
2177         tmp = TREE_CHAIN (tmp);
2178       }
2179   }
2180   INDENT (spc);
2181   pp_character (buffer, '}');
2182 }
2183
2184 /* Return the priority of the operator OP.
2185
2186    From lowest to highest precedence with either left-to-right (L-R)
2187    or right-to-left (R-L) associativity]:
2188
2189      1  [L-R] ,
2190      2  [R-L] = += -= *= /= %= &= ^= |= <<= >>=
2191      3  [R-L] ?:
2192      4  [L-R] ||
2193      5  [L-R] &&
2194      6  [L-R] |
2195      7  [L-R] ^
2196      8  [L-R] &
2197      9  [L-R] == !=
2198     10  [L-R] < <= > >=
2199     11  [L-R] << >>
2200     12  [L-R] + -
2201     13  [L-R] * / %
2202     14  [R-L] ! ~ ++ -- + - * & (type) sizeof
2203     15  [L-R] fn() [] -> .
2204
2205    unary +, - and * have higher precedence than the corresponding binary
2206    operators.  */
2207
2208 static int
2209 op_prio (tree op)
2210 {
2211   if (op == NULL)
2212     return 9999;
2213
2214   switch (TREE_CODE (op))
2215     {
2216     case TREE_LIST:
2217     case COMPOUND_EXPR:
2218     case BIND_EXPR:
2219       return 1;
2220
2221     case MODIFY_EXPR:
2222     case GIMPLE_MODIFY_STMT:
2223     case INIT_EXPR:
2224       return 2;
2225
2226     case COND_EXPR:
2227       return 3;
2228
2229     case TRUTH_OR_EXPR:
2230     case TRUTH_ORIF_EXPR:
2231       return 4;
2232
2233     case TRUTH_AND_EXPR:
2234     case TRUTH_ANDIF_EXPR:
2235       return 5;
2236
2237     case BIT_IOR_EXPR:
2238       return 6;
2239
2240     case BIT_XOR_EXPR:
2241     case TRUTH_XOR_EXPR:
2242       return 7;
2243
2244     case BIT_AND_EXPR:
2245       return 8;
2246
2247     case EQ_EXPR:
2248     case NE_EXPR:
2249       return 9;
2250
2251     case UNLT_EXPR:
2252     case UNLE_EXPR:
2253     case UNGT_EXPR:
2254     case UNGE_EXPR:
2255     case UNEQ_EXPR:
2256     case LTGT_EXPR:
2257     case ORDERED_EXPR:
2258     case UNORDERED_EXPR:
2259     case LT_EXPR:
2260     case LE_EXPR:
2261     case GT_EXPR:
2262     case GE_EXPR:
2263       return 10;
2264
2265     case LSHIFT_EXPR:
2266     case RSHIFT_EXPR:
2267     case LROTATE_EXPR:
2268     case RROTATE_EXPR:
2269       return 11;
2270
2271     case WIDEN_SUM_EXPR:
2272     case PLUS_EXPR:
2273     case MINUS_EXPR:
2274       return 12;
2275
2276     case VEC_WIDEN_MULT_HI_EXPR:
2277     case VEC_WIDEN_MULT_LO_EXPR:
2278     case WIDEN_MULT_EXPR:
2279     case DOT_PROD_EXPR:
2280     case MULT_EXPR:
2281     case TRUNC_DIV_EXPR:
2282     case CEIL_DIV_EXPR:
2283     case FLOOR_DIV_EXPR:
2284     case ROUND_DIV_EXPR:
2285     case RDIV_EXPR:
2286     case EXACT_DIV_EXPR:
2287     case TRUNC_MOD_EXPR:
2288     case CEIL_MOD_EXPR:
2289     case FLOOR_MOD_EXPR:
2290     case ROUND_MOD_EXPR:
2291       return 13;
2292
2293     case TRUTH_NOT_EXPR:
2294     case BIT_NOT_EXPR:
2295     case POSTINCREMENT_EXPR:
2296     case POSTDECREMENT_EXPR:
2297     case PREINCREMENT_EXPR:
2298     case PREDECREMENT_EXPR:
2299     case NEGATE_EXPR:
2300     case ALIGN_INDIRECT_REF:
2301     case MISALIGNED_INDIRECT_REF:
2302     case INDIRECT_REF:
2303     case ADDR_EXPR:
2304     case FLOAT_EXPR:
2305     case NOP_EXPR:
2306     case CONVERT_EXPR:
2307     case FIX_TRUNC_EXPR:
2308     case TARGET_EXPR:
2309       return 14;
2310
2311     case CALL_EXPR:
2312     case ARRAY_REF:
2313     case ARRAY_RANGE_REF:
2314     case COMPONENT_REF:
2315       return 15;
2316
2317       /* Special expressions.  */
2318     case MIN_EXPR:
2319     case MAX_EXPR:
2320     case ABS_EXPR:
2321     case REALPART_EXPR:
2322     case IMAGPART_EXPR:
2323     case REDUC_MAX_EXPR:
2324     case REDUC_MIN_EXPR:
2325     case REDUC_PLUS_EXPR:
2326     case VEC_LSHIFT_EXPR:
2327     case VEC_RSHIFT_EXPR:
2328     case VEC_UNPACK_HI_EXPR:
2329     case VEC_UNPACK_LO_EXPR:
2330     case VEC_PACK_MOD_EXPR:
2331     case VEC_PACK_SAT_EXPR:
2332       return 16;
2333
2334     case SAVE_EXPR:
2335     case NON_LVALUE_EXPR:
2336       return op_prio (TREE_OPERAND (op, 0));
2337
2338     default:
2339       /* Return an arbitrarily high precedence to avoid surrounding single
2340          VAR_DECLs in ()s.  */
2341       return 9999;
2342     }
2343 }
2344
2345
2346 /* Return the symbol associated with operator OP.  */
2347
2348 static const char *
2349 op_symbol_1 (enum tree_code code)
2350 {
2351   switch (code)
2352     {
2353     case MODIFY_EXPR:
2354     case GIMPLE_MODIFY_STMT:
2355       return "=";
2356
2357     case TRUTH_OR_EXPR:
2358     case TRUTH_ORIF_EXPR:
2359       return "||";
2360
2361     case TRUTH_AND_EXPR:
2362     case TRUTH_ANDIF_EXPR:
2363       return "&&";
2364
2365     case BIT_IOR_EXPR:
2366       return "|";
2367
2368     case TRUTH_XOR_EXPR:
2369     case BIT_XOR_EXPR:
2370       return "^";
2371
2372     case ADDR_EXPR:
2373     case BIT_AND_EXPR:
2374       return "&";
2375
2376     case ORDERED_EXPR:
2377       return "ord";
2378     case UNORDERED_EXPR:
2379       return "unord";
2380
2381     case EQ_EXPR:
2382       return "==";
2383     case UNEQ_EXPR:
2384       return "u==";
2385
2386     case NE_EXPR:
2387       return "!=";
2388
2389     case LT_EXPR:
2390       return "<";
2391     case UNLT_EXPR:
2392       return "u<";
2393
2394     case LE_EXPR:
2395       return "<=";
2396     case UNLE_EXPR:
2397       return "u<=";
2398
2399     case GT_EXPR:
2400       return ">";
2401     case UNGT_EXPR:
2402       return "u>";
2403
2404     case GE_EXPR:
2405       return ">=";
2406     case UNGE_EXPR:
2407       return "u>=";
2408
2409     case LTGT_EXPR:
2410       return "<>";
2411
2412     case LSHIFT_EXPR:
2413       return "<<";
2414
2415     case RSHIFT_EXPR:
2416       return ">>";
2417
2418     case LROTATE_EXPR:
2419       return "r<<";
2420
2421     case RROTATE_EXPR:
2422       return "r>>";
2423
2424     case VEC_LSHIFT_EXPR:
2425       return "v<<";
2426
2427     case VEC_RSHIFT_EXPR:
2428       return "v>>";
2429  
2430     case PLUS_EXPR:
2431       return "+";
2432
2433     case REDUC_PLUS_EXPR:
2434       return "r+";
2435
2436     case WIDEN_SUM_EXPR:
2437       return "w+";
2438
2439     case WIDEN_MULT_EXPR:
2440       return "w*";
2441
2442     case NEGATE_EXPR:
2443     case MINUS_EXPR:
2444       return "-";
2445
2446     case BIT_NOT_EXPR:
2447       return "~";
2448
2449     case TRUTH_NOT_EXPR:
2450       return "!";
2451
2452     case MULT_EXPR:
2453     case INDIRECT_REF:
2454       return "*";
2455
2456     case ALIGN_INDIRECT_REF:
2457       return "A*";
2458
2459     case MISALIGNED_INDIRECT_REF:
2460       return "M*";
2461
2462     case TRUNC_DIV_EXPR:
2463     case RDIV_EXPR:
2464       return "/";
2465
2466     case CEIL_DIV_EXPR:
2467       return "/[cl]";
2468
2469     case FLOOR_DIV_EXPR:
2470       return "/[fl]";
2471
2472     case ROUND_DIV_EXPR:
2473       return "/[rd]";
2474
2475     case EXACT_DIV_EXPR:
2476       return "/[ex]";
2477
2478     case TRUNC_MOD_EXPR:
2479       return "%";
2480
2481     case CEIL_MOD_EXPR:
2482       return "%[cl]";
2483
2484     case FLOOR_MOD_EXPR:
2485       return "%[fl]";
2486
2487     case ROUND_MOD_EXPR:
2488       return "%[rd]";
2489
2490     case PREDECREMENT_EXPR:
2491       return " --";
2492
2493     case PREINCREMENT_EXPR:
2494       return " ++";
2495
2496     case POSTDECREMENT_EXPR:
2497       return "-- ";
2498
2499     case POSTINCREMENT_EXPR:
2500       return "++ ";
2501
2502     case MAX_EXPR:
2503       return "max";
2504
2505     case MIN_EXPR:
2506       return "min";
2507
2508     default:
2509       return "<<< ??? >>>";
2510     }
2511 }
2512
2513 static const char *
2514 op_symbol (tree op)
2515 {
2516   return op_symbol_1 (TREE_CODE (op));
2517 }
2518
2519 /* Prints the name of a CALL_EXPR.  */
2520
2521 static void
2522 print_call_name (pretty_printer *buffer, tree node)
2523 {
2524   tree op0;
2525
2526   gcc_assert (TREE_CODE (node) == CALL_EXPR);
2527
2528   op0 = TREE_OPERAND (node, 0);
2529
2530   if (TREE_CODE (op0) == NON_LVALUE_EXPR)
2531     op0 = TREE_OPERAND (op0, 0);
2532
2533   switch (TREE_CODE (op0))
2534     {
2535     case VAR_DECL:
2536     case PARM_DECL:
2537       dump_function_name (buffer, op0);
2538       break;
2539
2540     case ADDR_EXPR:
2541     case INDIRECT_REF:
2542     case NOP_EXPR:
2543       dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
2544       break;
2545
2546     case COND_EXPR:
2547       pp_string (buffer, "(");
2548       dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
2549       pp_string (buffer, ") ? ");
2550       dump_generic_node (buffer, TREE_OPERAND (op0, 1), 0, 0, false);
2551       pp_string (buffer, " : ");
2552       dump_generic_node (buffer, TREE_OPERAND (op0, 2), 0, 0, false);
2553       break;
2554
2555     case COMPONENT_REF:
2556       /* The function is a pointer contained in a structure.  */
2557       if (TREE_CODE (TREE_OPERAND (op0, 0)) == INDIRECT_REF ||
2558           TREE_CODE (TREE_OPERAND (op0, 0)) == VAR_DECL)
2559         dump_function_name (buffer, TREE_OPERAND (op0, 1));
2560       else
2561         dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
2562       /* else
2563          We can have several levels of structures and a function
2564          pointer inside.  This is not implemented yet...  */
2565       /*                  NIY;*/
2566       break;
2567
2568     case ARRAY_REF:
2569       if (TREE_CODE (TREE_OPERAND (op0, 0)) == VAR_DECL)
2570         dump_function_name (buffer, TREE_OPERAND (op0, 0));
2571       else
2572         dump_generic_node (buffer, op0, 0, 0, false);
2573       break;
2574
2575     case SSA_NAME:
2576     case OBJ_TYPE_REF:
2577       dump_generic_node (buffer, op0, 0, 0, false);
2578       break;
2579
2580     default:
2581       NIY;
2582     }
2583 }
2584
2585 /* Parses the string STR and replaces new-lines by '\n', tabs by '\t', ...  */
2586
2587 static void
2588 pretty_print_string (pretty_printer *buffer, const char *str)
2589 {
2590   if (str == NULL)
2591     return;
2592
2593   while (*str)
2594     {
2595       switch (str[0])
2596         {
2597         case '\b':
2598           pp_string (buffer, "\\b");
2599           break;
2600
2601         case '\f':
2602           pp_string (buffer, "\\f");
2603           break;
2604
2605         case '\n':
2606           pp_string (buffer, "\\n");
2607           break;
2608
2609         case '\r':
2610           pp_string (buffer, "\\r");
2611           break;
2612
2613         case '\t':
2614           pp_string (buffer, "\\t");
2615           break;
2616
2617         case '\v':
2618           pp_string (buffer, "\\v");
2619           break;
2620
2621         case '\\':
2622           pp_string (buffer, "\\\\");
2623           break;
2624
2625         case '\"':
2626           pp_string (buffer, "\\\"");
2627           break;
2628
2629         case '\'':
2630           pp_string (buffer, "\\'");
2631           break;
2632
2633           /* No need to handle \0; the loop terminates on \0.  */
2634
2635         case '\1':
2636           pp_string (buffer, "\\1");
2637           break;
2638
2639         case '\2':
2640           pp_string (buffer, "\\2");
2641           break;
2642
2643         case '\3':
2644           pp_string (buffer, "\\3");
2645           break;
2646
2647         case '\4':
2648           pp_string (buffer, "\\4");
2649           break;
2650
2651         case '\5':
2652           pp_string (buffer, "\\5");
2653           break;
2654
2655         case '\6':
2656           pp_string (buffer, "\\6");
2657           break;
2658
2659         case '\7':
2660           pp_string (buffer, "\\7");
2661           break;
2662
2663         default:
2664           pp_character (buffer, str[0]);
2665           break;
2666         }
2667       str++;
2668     }
2669 }
2670
2671 static void
2672 maybe_init_pretty_print (FILE *file)
2673 {
2674   if (!initialized)
2675     {
2676       pp_construct (&buffer, /* prefix */NULL, /* line-width */0);
2677       pp_needs_newline (&buffer) = true;
2678       initialized = 1;
2679     }
2680
2681   buffer.buffer->stream = file;
2682 }
2683
2684 static void
2685 newline_and_indent (pretty_printer *buffer, int spc)
2686 {
2687   pp_newline (buffer);
2688   INDENT (spc);
2689 }
2690
2691
2692 static void
2693 dump_vops (pretty_printer *buffer, tree stmt, int spc, int flags)
2694 {
2695   struct vdef_optype_d *vdefs;
2696   struct vuse_optype_d *vuses;
2697   int i, n;
2698
2699   if (!ssa_operands_active () || !stmt_references_memory_p (stmt))
2700     return;
2701
2702   /* Even if the statement doesn't have virtual operators yet, it may
2703      contain symbol information (this happens before aliases have been
2704      computed).  */
2705   if ((flags & TDF_MEMSYMS)
2706       && VUSE_OPS (stmt) == NULL
2707       && VDEF_OPS (stmt) == NULL)
2708     {
2709       if (LOADED_SYMS (stmt))
2710         {
2711           pp_string (buffer, "# LOADS: ");
2712           dump_symbols (buffer, LOADED_SYMS (stmt), flags);
2713           newline_and_indent (buffer, spc);
2714         }
2715
2716       if (STORED_SYMS (stmt))
2717         {
2718           pp_string (buffer, "# STORES: ");
2719           dump_symbols (buffer, STORED_SYMS (stmt), flags);
2720           newline_and_indent (buffer, spc);
2721         }
2722
2723       return;
2724     }
2725
2726   vuses = VUSE_OPS (stmt);
2727   while (vuses)
2728     {
2729       pp_string (buffer, "# VUSE <");
2730
2731       n = VUSE_NUM (vuses);
2732       for (i = 0; i < n; i++)
2733         {
2734           dump_generic_node (buffer, VUSE_OP (vuses, i), spc + 2, flags, false);
2735           if (i < n - 1)
2736             pp_string (buffer, ", ");
2737         }
2738
2739       pp_string (buffer, ">");
2740
2741       if (flags & TDF_MEMSYMS)
2742         dump_symbols (buffer, LOADED_SYMS (stmt), flags);
2743
2744       newline_and_indent (buffer, spc);
2745       vuses = vuses->next;
2746     }
2747
2748   vdefs = VDEF_OPS (stmt);
2749   while (vdefs)
2750     {
2751       pp_string (buffer, "# ");
2752       dump_generic_node (buffer, VDEF_RESULT (vdefs), spc + 2, flags, false);
2753       pp_string (buffer, " = VDEF <");
2754
2755       n = VDEF_NUM (vdefs);
2756       for (i = 0; i < n; i++)
2757         {
2758           dump_generic_node (buffer, VDEF_OP (vdefs, i), spc + 2, flags, 0);
2759           if (i < n - 1)
2760             pp_string (buffer, ", ");
2761         }
2762
2763       pp_string (buffer, ">");
2764
2765       if ((flags & TDF_MEMSYMS) && vdefs->next == NULL)
2766         dump_symbols (buffer, STORED_SYMS (stmt), flags);
2767
2768       newline_and_indent (buffer, spc);
2769       vdefs = vdefs->next;
2770     }
2771 }
2772
2773
2774 /* Dumps basic block BB to FILE with details described by FLAGS and
2775    indented by INDENT spaces.  */
2776
2777 void
2778 dump_generic_bb (FILE *file, basic_block bb, int indent, int flags)
2779 {
2780   maybe_init_pretty_print (file);
2781   dump_generic_bb_buff (&buffer, bb, indent, flags);
2782   pp_flush (&buffer);
2783 }
2784
2785 /* Dumps header of basic block BB to buffer BUFFER indented by INDENT
2786    spaces and details described by flags.  */
2787
2788 static void
2789 dump_bb_header (pretty_printer *buffer, basic_block bb, int indent, int flags)
2790 {
2791   edge e;
2792   tree stmt;
2793   edge_iterator ei;
2794
2795   if (flags & TDF_BLOCKS)
2796     {
2797       INDENT (indent);
2798       pp_string (buffer, "# BLOCK ");
2799       pp_decimal_int (buffer, bb->index);
2800       if (bb->frequency)
2801         {
2802           pp_string (buffer, " freq:");
2803           pp_decimal_int (buffer, bb->frequency);
2804         }
2805       if (bb->count)
2806         {
2807           pp_string (buffer, " count:");
2808           pp_widest_integer (buffer, bb->count);
2809         }
2810
2811       if (flags & TDF_LINENO)
2812         {
2813           block_stmt_iterator bsi;
2814
2815           for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
2816             if (get_lineno (bsi_stmt (bsi)) != -1)
2817               {
2818                 pp_string (buffer, ", starting at line ");
2819                 pp_decimal_int (buffer, get_lineno (bsi_stmt (bsi)));
2820                 break;
2821               }
2822         }
2823       newline_and_indent (buffer, indent);
2824
2825       pp_string (buffer, "# PRED:");
2826       pp_write_text_to_stream (buffer);
2827       FOR_EACH_EDGE (e, ei, bb->preds)
2828         if (flags & TDF_SLIM)
2829           {
2830             pp_string (buffer, " ");
2831             if (e->src == ENTRY_BLOCK_PTR)
2832               pp_string (buffer, "ENTRY");
2833             else
2834               pp_decimal_int (buffer, e->src->index);
2835           }
2836         else
2837           dump_edge_info (buffer->buffer->stream, e, 0);
2838       pp_newline (buffer);
2839     }
2840   else
2841     {
2842       stmt = first_stmt (bb);
2843       if (!stmt || TREE_CODE (stmt) != LABEL_EXPR)
2844         {
2845           INDENT (indent - 2);
2846           pp_string (buffer, "<bb ");
2847           pp_decimal_int (buffer, bb->index);
2848           pp_string (buffer, ">:");
2849           pp_newline (buffer);
2850         }
2851     }
2852   pp_write_text_to_stream (buffer);
2853   check_bb_profile (bb, buffer->buffer->stream);
2854 }
2855
2856 /* Dumps end of basic block BB to buffer BUFFER indented by INDENT
2857    spaces.  */
2858
2859 static void
2860 dump_bb_end (pretty_printer *buffer, basic_block bb, int indent, int flags)
2861 {
2862   edge e;
2863   edge_iterator ei;
2864
2865   INDENT (indent);
2866   pp_string (buffer, "# SUCC:");
2867   pp_write_text_to_stream (buffer);
2868   FOR_EACH_EDGE (e, ei, bb->succs)
2869     if (flags & TDF_SLIM)
2870       {
2871         pp_string (buffer, " ");
2872         if (e->dest == EXIT_BLOCK_PTR)
2873           pp_string (buffer, "EXIT");
2874         else
2875           pp_decimal_int (buffer, e->dest->index);
2876       }
2877     else
2878       dump_edge_info (buffer->buffer->stream, e, 1);
2879   pp_newline (buffer);
2880 }
2881
2882 /* Dump PHI nodes of basic block BB to BUFFER with details described
2883    by FLAGS and indented by INDENT spaces.  */
2884
2885 static void
2886 dump_phi_nodes (pretty_printer *buffer, basic_block bb, int indent, int flags)
2887 {
2888   tree phi = phi_nodes (bb);
2889   if (!phi)
2890     return;
2891
2892   for (; phi; phi = PHI_CHAIN (phi))
2893     {
2894       if (is_gimple_reg (PHI_RESULT (phi)) || (flags & TDF_VOPS))
2895         {
2896           INDENT (indent);
2897           pp_string (buffer, "# ");
2898           dump_generic_node (buffer, phi, indent, flags, false);
2899           pp_newline (buffer);
2900         }
2901     }
2902 }
2903
2904
2905 /* Dump jump to basic block BB that is represented implicitly in the cfg
2906    to BUFFER.  */
2907
2908 static void
2909 pp_cfg_jump (pretty_printer *buffer, basic_block bb)
2910 {
2911   tree stmt;
2912
2913   stmt = first_stmt (bb);
2914
2915   pp_string (buffer, "goto <bb ");
2916   pp_decimal_int (buffer, bb->index);
2917   pp_string (buffer, ">");
2918   if (stmt && TREE_CODE (stmt) == LABEL_EXPR)
2919     {
2920       pp_string (buffer, " (");
2921       dump_generic_node (buffer, LABEL_EXPR_LABEL (stmt), 0, 0, false);
2922       pp_string (buffer, ")");
2923     }
2924   pp_semicolon (buffer);
2925 }
2926
2927 /* Dump edges represented implicitly in basic block BB to BUFFER, indented
2928    by INDENT spaces, with details given by FLAGS.  */
2929
2930 static void
2931 dump_implicit_edges (pretty_printer *buffer, basic_block bb, int indent,
2932                      int flags)
2933 {
2934   edge e;
2935   edge_iterator ei;
2936
2937   /* If there is a fallthru edge, we may need to add an artificial goto to the
2938      dump.  */
2939   FOR_EACH_EDGE (e, ei, bb->succs)
2940     if (e->flags & EDGE_FALLTHRU)
2941       break;
2942   if (e && e->dest != bb->next_bb)
2943     {
2944       INDENT (indent);
2945
2946       if ((flags & TDF_LINENO)
2947 #ifdef USE_MAPPED_LOCATION
2948           && e->goto_locus != UNKNOWN_LOCATION
2949 #else
2950           && e->goto_locus
2951 #endif
2952           )
2953         {
2954           expanded_location goto_xloc;
2955 #ifdef USE_MAPPED_LOCATION
2956           goto_xloc = expand_location (e->goto_locus);
2957 #else
2958           goto_xloc = *e->goto_locus;
2959 #endif
2960           pp_character (buffer, '[');
2961           if (goto_xloc.file)
2962             {
2963               pp_string (buffer, goto_xloc.file);
2964               pp_string (buffer, " : ");
2965             }
2966           pp_decimal_int (buffer, goto_xloc.line);
2967           pp_string (buffer, "] ");
2968         }
2969
2970       pp_cfg_jump (buffer, e->dest);
2971       pp_newline (buffer);
2972     }
2973 }
2974
2975 /* Dumps basic block BB to buffer BUFFER with details described by FLAGS and
2976    indented by INDENT spaces.  */
2977
2978 static void
2979 dump_generic_bb_buff (pretty_printer *buffer, basic_block bb,
2980                       int indent, int flags)
2981 {
2982   block_stmt_iterator bsi;
2983   tree stmt;
2984   int label_indent = indent - 2;
2985
2986   if (label_indent < 0)
2987     label_indent = 0;
2988
2989   dump_bb_header (buffer, bb, indent, flags);
2990
2991   dump_phi_nodes (buffer, bb, indent, flags);
2992
2993   for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
2994     {
2995       int curr_indent;
2996
2997       stmt = bsi_stmt (bsi);
2998
2999       curr_indent = TREE_CODE (stmt) == LABEL_EXPR ? label_indent : indent;
3000
3001       INDENT (curr_indent);
3002       dump_generic_node (buffer, stmt, curr_indent, flags, true);
3003       pp_newline (buffer);
3004       dump_histograms_for_stmt (cfun, buffer->buffer->stream, stmt);
3005     }
3006
3007   dump_implicit_edges (buffer, bb, indent, flags);
3008
3009   if (flags & TDF_BLOCKS)
3010     dump_bb_end (buffer, bb, indent, flags);
3011 }