OSDN Git Service

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