OSDN Git Service

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