OSDN Git Service

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