OSDN Git Service

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