OSDN Git Service

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