OSDN Git Service

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