OSDN Git Service

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