OSDN Git Service

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