OSDN Git Service

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