OSDN Git Service

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