OSDN Git Service

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