OSDN Git Service

* c-cppbuiltin.c (c_cpp_builtins): Change _OPENMP value to
[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
956       if (TREE_CODE (op0) != VALUE_HANDLE)
957         {
958           op0 = component_ref_field_offset (node);
959           if (op0 && TREE_CODE (op0) != INTEGER_CST)
960             {
961               pp_string (buffer, "{off: ");
962               dump_generic_node (buffer, op0, spc, flags, false);
963               pp_character (buffer, '}');
964             }
965         }
966       break;
967
968     case BIT_FIELD_REF:
969       pp_string (buffer, "BIT_FIELD_REF <");
970       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
971       pp_string (buffer, ", ");
972       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
973       pp_string (buffer, ", ");
974       dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
975       pp_string (buffer, ">");
976       break;
977
978     case ARRAY_REF:
979     case ARRAY_RANGE_REF:
980       op0 = TREE_OPERAND (node, 0);
981       if (op_prio (op0) < op_prio (node))
982         pp_character (buffer, '(');
983       dump_generic_node (buffer, op0, spc, flags, false);
984       if (op_prio (op0) < op_prio (node))
985         pp_character (buffer, ')');
986       pp_character (buffer, '[');
987       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
988       if (TREE_CODE (node) == ARRAY_RANGE_REF)
989         pp_string (buffer, " ...");
990       pp_character (buffer, ']');
991
992       op0 = array_ref_low_bound (node);
993       op1 = array_ref_element_size (node);
994
995       if (!integer_zerop (op0)
996           || TREE_OPERAND (node, 2)
997           || TREE_OPERAND (node, 3))
998         {
999           pp_string (buffer, "{lb: ");
1000           dump_generic_node (buffer, op0, spc, flags, false);
1001           pp_string (buffer, " sz: ");
1002           dump_generic_node (buffer, op1, spc, flags, false);
1003           pp_character (buffer, '}');
1004         }
1005       break;
1006
1007     case CONSTRUCTOR:
1008       {
1009         unsigned HOST_WIDE_INT ix;
1010         tree field, val;
1011         bool is_struct_init = FALSE;
1012         pp_character (buffer, '{');
1013         if (TREE_CODE (TREE_TYPE (node)) == RECORD_TYPE
1014             || TREE_CODE (TREE_TYPE (node)) == UNION_TYPE)
1015           is_struct_init = TRUE;
1016         FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (node), ix, field, val)
1017           {
1018             if (field && is_struct_init)
1019               {
1020                 pp_character (buffer, '.');
1021                 dump_generic_node (buffer, field, spc, flags, false);
1022                 pp_string (buffer, "=");
1023               }
1024             if (val && TREE_CODE (val) == ADDR_EXPR)
1025               if (TREE_CODE (TREE_OPERAND (val, 0)) == FUNCTION_DECL)
1026                 val = TREE_OPERAND (val, 0);
1027             if (val && TREE_CODE (val) == FUNCTION_DECL)
1028                 dump_decl_name (buffer, val, flags);
1029             else
1030                 dump_generic_node (buffer, val, spc, flags, false);
1031             if (ix != VEC_length (constructor_elt, CONSTRUCTOR_ELTS (node)) - 1)
1032               {
1033                 pp_character (buffer, ',');
1034                 pp_space (buffer);
1035               }
1036           }
1037         pp_character (buffer, '}');
1038       }
1039       break;
1040
1041     case COMPOUND_EXPR:
1042       {
1043         tree *tp;
1044         if (flags & TDF_SLIM)
1045           {
1046             pp_string (buffer, "<COMPOUND_EXPR>");
1047             break;
1048           }
1049
1050         dump_generic_node (buffer, TREE_OPERAND (node, 0),
1051                            spc, flags, !(flags & TDF_SLIM));
1052         if (flags & TDF_SLIM)
1053           newline_and_indent (buffer, spc);
1054         else
1055           {
1056             pp_character (buffer, ',');
1057             pp_space (buffer);
1058           }
1059
1060         for (tp = &TREE_OPERAND (node, 1);
1061              TREE_CODE (*tp) == COMPOUND_EXPR;
1062              tp = &TREE_OPERAND (*tp, 1))
1063           {
1064             dump_generic_node (buffer, TREE_OPERAND (*tp, 0),
1065                                spc, flags, !(flags & TDF_SLIM));
1066             if (flags & TDF_SLIM)
1067               newline_and_indent (buffer, spc);
1068             else
1069               {
1070                 pp_character (buffer, ',');
1071                 pp_space (buffer);
1072               }
1073           }
1074
1075         dump_generic_node (buffer, *tp, spc, flags, !(flags & TDF_SLIM));
1076       }
1077       break;
1078
1079     case STATEMENT_LIST:
1080       {
1081         tree_stmt_iterator si;
1082         bool first = true;
1083
1084         if (flags & TDF_SLIM)
1085           {
1086             pp_string (buffer, "<STATEMENT_LIST>");
1087             break;
1088           }
1089
1090         for (si = tsi_start (node); !tsi_end_p (si); tsi_next (&si))
1091           {
1092             if (!first)
1093               newline_and_indent (buffer, spc);
1094             else
1095               first = false;
1096             dump_generic_node (buffer, tsi_stmt (si), spc, flags, true);
1097           }
1098       }
1099       break;
1100
1101     case MODIFY_EXPR:
1102     case GIMPLE_MODIFY_STMT:
1103     case INIT_EXPR:
1104       dump_generic_node (buffer, GENERIC_TREE_OPERAND (node, 0), spc, flags,
1105                          false);
1106       pp_space (buffer);
1107       pp_character (buffer, '=');
1108       if (TREE_CODE (node) == GIMPLE_MODIFY_STMT
1109           && MOVE_NONTEMPORAL (node))
1110         pp_string (buffer, "{nt}");
1111       if (TREE_CODE (node) == GIMPLE_MODIFY_STMT)
1112         {
1113         stmt_ann_t ann;
1114         if ((ann = stmt_ann (node))
1115             && ann->has_volatile_ops)
1116           pp_string (buffer, "{v}");
1117         }
1118       pp_space (buffer);
1119       dump_generic_node (buffer, GENERIC_TREE_OPERAND (node, 1), spc, flags,
1120                          false);
1121       break;
1122
1123     case TARGET_EXPR:
1124       pp_string (buffer, "TARGET_EXPR <");
1125       dump_generic_node (buffer, TARGET_EXPR_SLOT (node), spc, flags, false);
1126       pp_character (buffer, ',');
1127       pp_space (buffer);
1128       dump_generic_node (buffer, TARGET_EXPR_INITIAL (node), spc, flags, false);
1129       pp_character (buffer, '>');
1130       break;
1131
1132     case DECL_EXPR:
1133       print_declaration (buffer, DECL_EXPR_DECL (node), spc, flags);
1134       is_stmt = false;
1135       break;
1136
1137     case COND_EXPR:
1138       if (TREE_TYPE (node) == NULL || TREE_TYPE (node) == void_type_node)
1139         {
1140           pp_string (buffer, "if (");
1141           dump_generic_node (buffer, COND_EXPR_COND (node), spc, flags, false);
1142           pp_character (buffer, ')');
1143           /* The lowered cond_exprs should always be printed in full.  */
1144           if (COND_EXPR_THEN (node)
1145               && (IS_EMPTY_STMT (COND_EXPR_THEN (node))
1146                   || TREE_CODE (COND_EXPR_THEN (node)) == GOTO_EXPR)
1147               && COND_EXPR_ELSE (node)
1148               && (IS_EMPTY_STMT (COND_EXPR_ELSE (node))
1149                   || TREE_CODE (COND_EXPR_ELSE (node)) == GOTO_EXPR))
1150             {
1151               pp_space (buffer);
1152               dump_generic_node (buffer, COND_EXPR_THEN (node),
1153                                  0, flags, true);
1154               if (!IS_EMPTY_STMT (COND_EXPR_ELSE (node)))
1155                 {
1156                   pp_string (buffer, " else ");
1157                   dump_generic_node (buffer, COND_EXPR_ELSE (node),
1158                                      0, flags, true);
1159                 }
1160             }
1161           else if (!(flags & TDF_SLIM))
1162             {
1163               /* Output COND_EXPR_THEN.  */
1164               if (COND_EXPR_THEN (node))
1165                 {
1166                   newline_and_indent (buffer, spc+2);
1167                   pp_character (buffer, '{');
1168                   newline_and_indent (buffer, spc+4);
1169                   dump_generic_node (buffer, COND_EXPR_THEN (node), spc+4,
1170                                      flags, true);
1171                   newline_and_indent (buffer, spc+2);
1172                   pp_character (buffer, '}');
1173                 }
1174
1175               /* Output COND_EXPR_ELSE.  */
1176               if (COND_EXPR_ELSE (node)
1177                   && !IS_EMPTY_STMT (COND_EXPR_ELSE (node)))
1178                 {
1179                   newline_and_indent (buffer, spc);
1180                   pp_string (buffer, "else");
1181                   newline_and_indent (buffer, spc+2);
1182                   pp_character (buffer, '{');
1183                   newline_and_indent (buffer, spc+4);
1184                   dump_generic_node (buffer, COND_EXPR_ELSE (node), spc+4,
1185                                      flags, true);
1186                   newline_and_indent (buffer, spc+2);
1187                   pp_character (buffer, '}');
1188                 }
1189             }
1190           is_expr = false;
1191         }
1192       else
1193         {
1194           dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1195           pp_space (buffer);
1196           pp_character (buffer, '?');
1197           pp_space (buffer);
1198           dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1199           pp_space (buffer);
1200           pp_character (buffer, ':');
1201           pp_space (buffer);
1202           dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
1203         }
1204       break;
1205
1206     case BIND_EXPR:
1207       pp_character (buffer, '{');
1208       if (!(flags & TDF_SLIM))
1209         {
1210           if (BIND_EXPR_VARS (node))
1211             {
1212               pp_newline (buffer);
1213
1214               for (op0 = BIND_EXPR_VARS (node); op0; op0 = TREE_CHAIN (op0))
1215                 {
1216                   print_declaration (buffer, op0, spc+2, flags);
1217                   pp_newline (buffer);
1218                 }
1219             }
1220
1221           newline_and_indent (buffer, spc+2);
1222           dump_generic_node (buffer, BIND_EXPR_BODY (node), spc+2, flags, true);
1223           newline_and_indent (buffer, spc);
1224           pp_character (buffer, '}');
1225         }
1226       is_expr = false;
1227       break;
1228
1229     case CALL_EXPR:
1230       print_call_name (buffer, node);
1231
1232       /* Print parameters.  */
1233       pp_space (buffer);
1234       pp_character (buffer, '(');
1235       {
1236         tree arg;
1237         call_expr_arg_iterator iter;
1238         FOR_EACH_CALL_EXPR_ARG (arg, iter, node)
1239           {
1240             dump_generic_node (buffer, arg, spc, flags, false);
1241             if (more_call_expr_args_p (&iter))
1242               {
1243                 pp_character (buffer, ',');
1244                 pp_space (buffer);
1245               }
1246           }
1247       }
1248       if (CALL_EXPR_VA_ARG_PACK (node))
1249         {
1250           if (call_expr_nargs (node) > 0)
1251             {
1252               pp_character (buffer, ',');
1253               pp_space (buffer);
1254             }
1255           pp_string (buffer, "__builtin_va_arg_pack ()");
1256         }
1257       pp_character (buffer, ')');
1258
1259       op1 = CALL_EXPR_STATIC_CHAIN (node);
1260       if (op1)
1261         {
1262           pp_string (buffer, " [static-chain: ");
1263           dump_generic_node (buffer, op1, spc, flags, false);
1264           pp_character (buffer, ']');
1265         }
1266
1267       if (CALL_EXPR_RETURN_SLOT_OPT (node))
1268         pp_string (buffer, " [return slot optimization]");
1269       if (CALL_EXPR_TAILCALL (node))
1270         pp_string (buffer, " [tail call]");
1271       break;
1272
1273     case WITH_CLEANUP_EXPR:
1274       NIY;
1275       break;
1276
1277     case CLEANUP_POINT_EXPR:
1278       pp_string (buffer, "<<cleanup_point ");
1279       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1280       pp_string (buffer, ">>");
1281       break;
1282
1283     case PLACEHOLDER_EXPR:
1284       pp_string (buffer, "<PLACEHOLDER_EXPR ");
1285       dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
1286       pp_character (buffer, '>');
1287       break;
1288
1289       /* Binary arithmetic and logic expressions.  */
1290     case WIDEN_SUM_EXPR:
1291     case WIDEN_MULT_EXPR:
1292     case MULT_EXPR:
1293     case PLUS_EXPR:
1294     case POINTER_PLUS_EXPR:
1295     case MINUS_EXPR:
1296     case TRUNC_DIV_EXPR:
1297     case CEIL_DIV_EXPR:
1298     case FLOOR_DIV_EXPR:
1299     case ROUND_DIV_EXPR:
1300     case TRUNC_MOD_EXPR:
1301     case CEIL_MOD_EXPR:
1302     case FLOOR_MOD_EXPR:
1303     case ROUND_MOD_EXPR:
1304     case RDIV_EXPR:
1305     case EXACT_DIV_EXPR:
1306     case LSHIFT_EXPR:
1307     case RSHIFT_EXPR:
1308     case LROTATE_EXPR:
1309     case RROTATE_EXPR:
1310     case VEC_LSHIFT_EXPR:
1311     case VEC_RSHIFT_EXPR:
1312     case BIT_IOR_EXPR:
1313     case BIT_XOR_EXPR:
1314     case BIT_AND_EXPR:
1315     case TRUTH_ANDIF_EXPR:
1316     case TRUTH_ORIF_EXPR:
1317     case TRUTH_AND_EXPR:
1318     case TRUTH_OR_EXPR:
1319     case TRUTH_XOR_EXPR:
1320     case LT_EXPR:
1321     case LE_EXPR:
1322     case GT_EXPR:
1323     case GE_EXPR:
1324     case EQ_EXPR:
1325     case NE_EXPR:
1326     case UNLT_EXPR:
1327     case UNLE_EXPR:
1328     case UNGT_EXPR:
1329     case UNGE_EXPR:
1330     case UNEQ_EXPR:
1331     case LTGT_EXPR:
1332     case ORDERED_EXPR:
1333     case UNORDERED_EXPR:
1334       {
1335         const char *op = op_symbol (node);
1336         op0 = TREE_OPERAND (node, 0);
1337         op1 = TREE_OPERAND (node, 1);
1338
1339         /* When the operands are expressions with less priority,
1340            keep semantics of the tree representation.  */
1341         if (op_prio (op0) <= op_prio (node))
1342           {
1343             pp_character (buffer, '(');
1344             dump_generic_node (buffer, op0, spc, flags, false);
1345             pp_character (buffer, ')');
1346           }
1347         else
1348           dump_generic_node (buffer, op0, spc, flags, false);
1349
1350         pp_space (buffer);
1351         pp_string (buffer, op);
1352         pp_space (buffer);
1353
1354         /* When the operands are expressions with less priority,
1355            keep semantics of the tree representation.  */
1356         if (op_prio (op1) <= op_prio (node))
1357           {
1358             pp_character (buffer, '(');
1359             dump_generic_node (buffer, op1, spc, flags, false);
1360             pp_character (buffer, ')');
1361           }
1362         else
1363           dump_generic_node (buffer, op1, spc, flags, false);
1364       }
1365       break;
1366
1367       /* Unary arithmetic and logic expressions.  */
1368     case NEGATE_EXPR:
1369     case BIT_NOT_EXPR:
1370     case TRUTH_NOT_EXPR:
1371     case ADDR_EXPR:
1372     case PREDECREMENT_EXPR:
1373     case PREINCREMENT_EXPR:
1374     case ALIGN_INDIRECT_REF:
1375     case MISALIGNED_INDIRECT_REF:
1376     case INDIRECT_REF:
1377       if (TREE_CODE (node) == ADDR_EXPR
1378           && (TREE_CODE (TREE_OPERAND (node, 0)) == STRING_CST
1379               || TREE_CODE (TREE_OPERAND (node, 0)) == FUNCTION_DECL))
1380         ;       /* Do not output '&' for strings and function pointers.  */
1381       else
1382         pp_string (buffer, op_symbol (node));
1383
1384       if (op_prio (TREE_OPERAND (node, 0)) < op_prio (node))
1385         {
1386           pp_character (buffer, '(');
1387           dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1388           pp_character (buffer, ')');
1389         }
1390       else
1391         dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1392
1393       if (TREE_CODE (node) == MISALIGNED_INDIRECT_REF)
1394         {
1395           pp_string (buffer, "{misalignment: ");
1396           dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1397           pp_character (buffer, '}');
1398         }
1399       break;
1400
1401     case POSTDECREMENT_EXPR:
1402     case POSTINCREMENT_EXPR:
1403       if (op_prio (TREE_OPERAND (node, 0)) < op_prio (node))
1404         {
1405           pp_character (buffer, '(');
1406           dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1407           pp_character (buffer, ')');
1408         }
1409       else
1410         dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1411       pp_string (buffer, op_symbol (node));
1412       break;
1413
1414     case MIN_EXPR:
1415       pp_string (buffer, "MIN_EXPR <");
1416       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1417       pp_string (buffer, ", ");
1418       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1419       pp_character (buffer, '>');
1420       break;
1421
1422     case MAX_EXPR:
1423       pp_string (buffer, "MAX_EXPR <");
1424       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1425       pp_string (buffer, ", ");
1426       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1427       pp_character (buffer, '>');
1428       break;
1429
1430     case ABS_EXPR:
1431       pp_string (buffer, "ABS_EXPR <");
1432       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1433       pp_character (buffer, '>');
1434       break;
1435
1436     case RANGE_EXPR:
1437       NIY;
1438       break;
1439
1440     case FIXED_CONVERT_EXPR:
1441     case FIX_TRUNC_EXPR:
1442     case FLOAT_EXPR:
1443     CASE_CONVERT:
1444       type = TREE_TYPE (node);
1445       op0 = TREE_OPERAND (node, 0);
1446       if (type != TREE_TYPE (op0))
1447         {
1448           pp_character (buffer, '(');
1449           dump_generic_node (buffer, type, spc, flags, false);
1450           pp_string (buffer, ") ");
1451         }
1452       if (op_prio (op0) < op_prio (node))
1453         pp_character (buffer, '(');
1454       dump_generic_node (buffer, op0, spc, flags, false);
1455       if (op_prio (op0) < op_prio (node))
1456         pp_character (buffer, ')');
1457       break;
1458
1459     case VIEW_CONVERT_EXPR:
1460       pp_string (buffer, "VIEW_CONVERT_EXPR<");
1461       dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
1462       pp_string (buffer, ">(");
1463       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1464       pp_character (buffer, ')');
1465       break;
1466
1467     case PAREN_EXPR:
1468       pp_string (buffer, "((");
1469       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1470       pp_string (buffer, "))");
1471       break;
1472
1473     case NON_LVALUE_EXPR:
1474       pp_string (buffer, "NON_LVALUE_EXPR <");
1475       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1476       pp_character (buffer, '>');
1477       break;
1478
1479     case SAVE_EXPR:
1480       pp_string (buffer, "SAVE_EXPR <");
1481       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1482       pp_character (buffer, '>');
1483       break;
1484
1485     case COMPLEX_EXPR:
1486       pp_string (buffer, "COMPLEX_EXPR <");
1487       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1488       pp_string (buffer, ", ");
1489       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1490       pp_string (buffer, ">");
1491       break;
1492
1493     case CONJ_EXPR:
1494       pp_string (buffer, "CONJ_EXPR <");
1495       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1496       pp_string (buffer, ">");
1497       break;
1498
1499     case REALPART_EXPR:
1500       pp_string (buffer, "REALPART_EXPR <");
1501       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1502       pp_string (buffer, ">");
1503       break;
1504
1505     case IMAGPART_EXPR:
1506       pp_string (buffer, "IMAGPART_EXPR <");
1507       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1508       pp_string (buffer, ">");
1509       break;
1510
1511     case VA_ARG_EXPR:
1512       pp_string (buffer, "VA_ARG_EXPR <");
1513       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1514       pp_string (buffer, ">");
1515       break;
1516
1517     case TRY_FINALLY_EXPR:
1518     case TRY_CATCH_EXPR:
1519       pp_string (buffer, "try");
1520       newline_and_indent (buffer, spc+2);
1521       pp_string (buffer, "{");
1522       newline_and_indent (buffer, spc+4);
1523       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc+4, flags, true);
1524       newline_and_indent (buffer, spc+2);
1525       pp_string (buffer, "}");
1526       newline_and_indent (buffer, spc);
1527       pp_string (buffer,
1528                          (TREE_CODE (node) == TRY_CATCH_EXPR) ? "catch" : "finally");
1529       newline_and_indent (buffer, spc+2);
1530       pp_string (buffer, "{");
1531       newline_and_indent (buffer, spc+4);
1532       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc+4, flags, true);
1533       newline_and_indent (buffer, spc+2);
1534       pp_string (buffer, "}");
1535       is_expr = false;
1536       break;
1537
1538     case CATCH_EXPR:
1539       pp_string (buffer, "catch (");
1540       dump_generic_node (buffer, CATCH_TYPES (node), spc+2, flags, false);
1541       pp_string (buffer, ")");
1542       newline_and_indent (buffer, spc+2);
1543       pp_string (buffer, "{");
1544       newline_and_indent (buffer, spc+4);
1545       dump_generic_node (buffer, CATCH_BODY (node), spc+4, flags, true);
1546       newline_and_indent (buffer, spc+2);
1547       pp_string (buffer, "}");
1548       is_expr = false;
1549       break;
1550
1551     case EH_FILTER_EXPR:
1552       pp_string (buffer, "<<<eh_filter (");
1553       dump_generic_node (buffer, EH_FILTER_TYPES (node), spc+2, flags, false);
1554       pp_string (buffer, ")>>>");
1555       newline_and_indent (buffer, spc+2);
1556       pp_string (buffer, "{");
1557       newline_and_indent (buffer, spc+4);
1558       dump_generic_node (buffer, EH_FILTER_FAILURE (node), spc+4, flags, true);
1559       newline_and_indent (buffer, spc+2);
1560       pp_string (buffer, "}");
1561       is_expr = false;
1562       break;
1563
1564     case CHANGE_DYNAMIC_TYPE_EXPR:
1565       pp_string (buffer, "<<<change_dynamic_type (");
1566       dump_generic_node (buffer, CHANGE_DYNAMIC_TYPE_NEW_TYPE (node), spc + 2,
1567                          flags, false);
1568       pp_string (buffer, ") ");
1569       dump_generic_node (buffer, CHANGE_DYNAMIC_TYPE_LOCATION (node), spc + 2,
1570                          flags, false);
1571       pp_string (buffer, ")>>>");
1572       is_expr = false;
1573       break;
1574
1575     case LABEL_EXPR:
1576       op0 = TREE_OPERAND (node, 0);
1577       /* If this is for break or continue, don't bother printing it.  */
1578       if (DECL_NAME (op0))
1579         {
1580           const char *name = IDENTIFIER_POINTER (DECL_NAME (op0));
1581           if (strcmp (name, "break") == 0
1582               || strcmp (name, "continue") == 0)
1583             break;
1584         }
1585       dump_generic_node (buffer, op0, spc, flags, false);
1586       pp_character (buffer, ':');
1587       if (DECL_NONLOCAL (op0))
1588         pp_string (buffer, " [non-local]");
1589       break;
1590
1591     case EXC_PTR_EXPR:
1592       pp_string (buffer, "<<<exception object>>>");
1593       break;
1594
1595     case FILTER_EXPR:
1596       pp_string (buffer, "<<<filter object>>>");
1597       break;
1598
1599     case LOOP_EXPR:
1600       pp_string (buffer, "while (1)");
1601       if (!(flags & TDF_SLIM))
1602         {
1603           newline_and_indent (buffer, spc+2);
1604           pp_character (buffer, '{');
1605           newline_and_indent (buffer, spc+4);
1606           dump_generic_node (buffer, LOOP_EXPR_BODY (node), spc+4, flags, true);
1607           newline_and_indent (buffer, spc+2);
1608           pp_character (buffer, '}');
1609         }
1610       is_expr = false;
1611       break;
1612
1613     case PREDICT_EXPR:
1614       pp_string (buffer, "// predicted ");
1615       if (PREDICT_EXPR_OUTCOME (node))
1616         pp_string (buffer, "likely by ");
1617       else
1618         pp_string (buffer, "unlikely by ");
1619       pp_string (buffer, predictor_name (PREDICT_EXPR_PREDICTOR (node)));
1620       pp_string (buffer, " predictor.");
1621       break;
1622
1623     case RETURN_EXPR:
1624       pp_string (buffer, "return");
1625       op0 = TREE_OPERAND (node, 0);
1626       if (op0)
1627         {
1628           pp_space (buffer);
1629           if (TREE_CODE (op0) == MODIFY_EXPR
1630               || TREE_CODE (op0) == GIMPLE_MODIFY_STMT)
1631             dump_generic_node (buffer, GENERIC_TREE_OPERAND (op0, 1),
1632                                spc, flags, false);
1633           else
1634             dump_generic_node (buffer, op0, spc, flags, false);
1635         }
1636       break;
1637
1638     case EXIT_EXPR:
1639       pp_string (buffer, "if (");
1640       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1641       pp_string (buffer, ") break");
1642       break;
1643
1644     case SWITCH_EXPR:
1645       pp_string (buffer, "switch (");
1646       dump_generic_node (buffer, SWITCH_COND (node), spc, flags, false);
1647       pp_character (buffer, ')');
1648       if (!(flags & TDF_SLIM))
1649         {
1650           newline_and_indent (buffer, spc+2);
1651           pp_character (buffer, '{');
1652           if (SWITCH_BODY (node))
1653             {
1654               newline_and_indent (buffer, spc+4);
1655               dump_generic_node (buffer, SWITCH_BODY (node), spc+4, flags,
1656                                  true);
1657             }
1658           else
1659             {
1660               tree vec = SWITCH_LABELS (node);
1661               size_t i, n = TREE_VEC_LENGTH (vec);
1662               for (i = 0; i < n; ++i)
1663                 {
1664                   tree elt = TREE_VEC_ELT (vec, i);
1665                   newline_and_indent (buffer, spc+4);
1666                   if (elt)
1667                     {
1668                       dump_generic_node (buffer, elt, spc+4, flags, false);
1669                       pp_string (buffer, " goto ");
1670                       dump_generic_node (buffer, CASE_LABEL (elt), spc+4,
1671                                          flags, true);
1672                       pp_semicolon (buffer);
1673                     }
1674                   else
1675                     pp_string (buffer, "case ???: goto ???;");
1676                 }
1677             }
1678           newline_and_indent (buffer, spc+2);
1679           pp_character (buffer, '}');
1680         }
1681       is_expr = false;
1682       break;
1683
1684     case GOTO_EXPR:
1685       op0 = GOTO_DESTINATION (node);
1686       if (TREE_CODE (op0) != SSA_NAME && DECL_P (op0) && DECL_NAME (op0))
1687         {
1688           const char *name = IDENTIFIER_POINTER (DECL_NAME (op0));
1689           if (strcmp (name, "break") == 0
1690               || strcmp (name, "continue") == 0)
1691             {
1692               pp_string (buffer, name);
1693               break;
1694             }
1695         }
1696       pp_string (buffer, "goto ");
1697       dump_generic_node (buffer, op0, spc, flags, false);
1698       break;
1699
1700     case RESX_EXPR:
1701       pp_string (buffer, "resx ");
1702       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1703       break;
1704
1705     case ASM_EXPR:
1706       pp_string (buffer, "__asm__");
1707       if (ASM_VOLATILE_P (node))
1708         pp_string (buffer, " __volatile__");
1709       pp_character (buffer, '(');
1710       dump_generic_node (buffer, ASM_STRING (node), spc, flags, false);
1711       pp_character (buffer, ':');
1712       dump_generic_node (buffer, ASM_OUTPUTS (node), spc, flags, false);
1713       pp_character (buffer, ':');
1714       dump_generic_node (buffer, ASM_INPUTS (node), spc, flags, false);
1715       if (ASM_CLOBBERS (node))
1716         {
1717           pp_character (buffer, ':');
1718           dump_generic_node (buffer, ASM_CLOBBERS (node), spc, flags, false);
1719         }
1720       pp_string (buffer, ")");
1721       break;
1722
1723     case CASE_LABEL_EXPR:
1724       if (CASE_LOW (node) && CASE_HIGH (node))
1725         {
1726           pp_string (buffer, "case ");
1727           dump_generic_node (buffer, CASE_LOW (node), spc, flags, false);
1728           pp_string (buffer, " ... ");
1729           dump_generic_node (buffer, CASE_HIGH (node), spc, flags, false);
1730         }
1731       else if (CASE_LOW (node))
1732         {
1733           pp_string (buffer, "case ");
1734           dump_generic_node (buffer, CASE_LOW (node), spc, flags, false);
1735         }
1736       else
1737         pp_string (buffer, "default ");
1738       pp_character (buffer, ':');
1739       break;
1740
1741     case OBJ_TYPE_REF:
1742       pp_string (buffer, "OBJ_TYPE_REF(");
1743       dump_generic_node (buffer, OBJ_TYPE_REF_EXPR (node), spc, flags, false);
1744       pp_character (buffer, ';');
1745       dump_generic_node (buffer, OBJ_TYPE_REF_OBJECT (node), spc, flags, false);
1746       pp_character (buffer, '-');
1747       pp_character (buffer, '>');
1748       dump_generic_node (buffer, OBJ_TYPE_REF_TOKEN (node), spc, flags, false);
1749       pp_character (buffer, ')');
1750       break;
1751
1752     case PHI_NODE:
1753       {
1754         int i;
1755
1756         dump_generic_node (buffer, PHI_RESULT (node), spc, flags, false);
1757         pp_string (buffer, " = PHI <");
1758         for (i = 0; i < PHI_NUM_ARGS (node); i++)
1759           {
1760             dump_generic_node (buffer, PHI_ARG_DEF (node, i), spc, flags, false);
1761             pp_string (buffer, "(");
1762             pp_decimal_int (buffer, PHI_ARG_EDGE (node, i)->src->index);
1763             pp_string (buffer, ")");
1764             if (i < PHI_NUM_ARGS (node) - 1)
1765               pp_string (buffer, ", ");
1766           }
1767         pp_string (buffer, ">");
1768
1769         if (stmt_references_memory_p (node) && (flags & TDF_MEMSYMS))
1770           dump_symbols (buffer, STORED_SYMS (node), flags);
1771       }
1772       break;
1773
1774     case SSA_NAME:
1775       dump_generic_node (buffer, SSA_NAME_VAR (node), spc, flags, false);
1776       pp_string (buffer, "_");
1777       pp_decimal_int (buffer, SSA_NAME_VERSION (node));
1778       if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (node))
1779         pp_string (buffer, "(ab)");
1780       else if (SSA_NAME_IS_DEFAULT_DEF (node))
1781         pp_string (buffer, "(D)");
1782       break;
1783
1784     case WITH_SIZE_EXPR:
1785       pp_string (buffer, "WITH_SIZE_EXPR <");
1786       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1787       pp_string (buffer, ", ");
1788       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1789       pp_string (buffer, ">");
1790       break;
1791
1792     case VALUE_HANDLE:
1793       pp_printf (buffer, "VH.%d", VALUE_HANDLE_ID (node));
1794       break;
1795
1796     case ASSERT_EXPR:
1797       pp_string (buffer, "ASSERT_EXPR <");
1798       dump_generic_node (buffer, ASSERT_EXPR_VAR (node), spc, flags, false);
1799       pp_string (buffer, ", ");
1800       dump_generic_node (buffer, ASSERT_EXPR_COND (node), spc, flags, false);
1801       pp_string (buffer, ">");
1802       break;
1803
1804     case SCEV_KNOWN:
1805       pp_string (buffer, "scev_known");
1806       break;
1807
1808     case SCEV_NOT_KNOWN:
1809       pp_string (buffer, "scev_not_known");
1810       break;
1811
1812     case POLYNOMIAL_CHREC:
1813       pp_string (buffer, "{");
1814       dump_generic_node (buffer, CHREC_LEFT (node), spc, flags, false);
1815       pp_string (buffer, ", +, ");
1816       dump_generic_node (buffer, CHREC_RIGHT (node), spc, flags, false);
1817       pp_string (buffer, "}_");
1818       dump_generic_node (buffer, CHREC_VAR (node), spc, flags, false);
1819       is_stmt = false;
1820       break;
1821
1822     case REALIGN_LOAD_EXPR:
1823       pp_string (buffer, "REALIGN_LOAD <");
1824       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1825       pp_string (buffer, ", ");
1826       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1827       pp_string (buffer, ", ");
1828       dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
1829       pp_string (buffer, ">");
1830       break;
1831       
1832     case VEC_COND_EXPR:
1833       pp_string (buffer, " VEC_COND_EXPR < ");
1834       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1835       pp_string (buffer, " , ");
1836       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1837       pp_string (buffer, " , ");
1838       dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
1839       pp_string (buffer, " > ");
1840       break;
1841
1842     case DOT_PROD_EXPR:
1843       pp_string (buffer, " DOT_PROD_EXPR < ");
1844       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1845       pp_string (buffer, ", ");
1846       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1847       pp_string (buffer, ", ");
1848       dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
1849       pp_string (buffer, " > ");
1850       break;
1851
1852     case OMP_PARALLEL:
1853       pp_string (buffer, "#pragma omp parallel");
1854       dump_omp_clauses (buffer, OMP_PARALLEL_CLAUSES (node), spc, flags);
1855       if (OMP_PARALLEL_FN (node))
1856         {
1857           pp_string (buffer, " [child fn: ");
1858           dump_generic_node (buffer, OMP_PARALLEL_FN (node), spc, flags, false);
1859
1860           pp_string (buffer, " (");
1861
1862           if (OMP_PARALLEL_DATA_ARG (node))
1863             dump_generic_node (buffer, OMP_PARALLEL_DATA_ARG (node), spc, flags,
1864                                false);
1865           else
1866             pp_string (buffer, "???");
1867
1868           pp_string (buffer, ")]");
1869         }
1870
1871     dump_omp_body:
1872       if (!(flags & TDF_SLIM) && OMP_BODY (node))
1873         {
1874           newline_and_indent (buffer, spc + 2);
1875           pp_character (buffer, '{');
1876           newline_and_indent (buffer, spc + 4);
1877           dump_generic_node (buffer, OMP_BODY (node), spc + 4, flags, false);
1878           newline_and_indent (buffer, spc + 2);
1879           pp_character (buffer, '}');
1880         }
1881       is_expr = false;
1882       break;
1883
1884     case OMP_TASK:
1885       pp_string (buffer, "#pragma omp task");
1886       dump_omp_clauses (buffer, OMP_TASK_CLAUSES (node), spc, flags);
1887       if (OMP_TASK_FN (node))
1888         {
1889           pp_string (buffer, " [child fn: ");
1890           dump_generic_node (buffer, OMP_TASK_FN (node), spc, flags, false);
1891
1892           pp_string (buffer, " (");
1893
1894           if (OMP_TASK_DATA_ARG (node))
1895             dump_generic_node (buffer, OMP_TASK_DATA_ARG (node), spc, flags,
1896                                false);
1897           else
1898             pp_string (buffer, "???");
1899
1900           pp_character (buffer, ')');
1901           if (OMP_TASK_COPYFN (node))
1902             {
1903               pp_string (buffer, ", copy fn: ");
1904               dump_generic_node (buffer, OMP_TASK_COPYFN (node), spc,
1905                                  flags, false);
1906             }
1907           pp_character (buffer, ']');
1908         }
1909       goto dump_omp_body;
1910
1911     case OMP_FOR:
1912       pp_string (buffer, "#pragma omp for");
1913       dump_omp_clauses (buffer, OMP_FOR_CLAUSES (node), spc, flags);
1914
1915       if (!(flags & TDF_SLIM))
1916         {
1917           int i;
1918
1919           if (OMP_FOR_PRE_BODY (node))
1920             {
1921               newline_and_indent (buffer, spc + 2);
1922               pp_character (buffer, '{');
1923               spc += 4;
1924               newline_and_indent (buffer, spc);
1925               dump_generic_node (buffer, OMP_FOR_PRE_BODY (node),
1926                   spc, flags, false);
1927             }
1928           spc -= 2;
1929           for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (node)); i++)
1930             {
1931               spc += 2;
1932               newline_and_indent (buffer, spc);
1933               pp_string (buffer, "for (");
1934               dump_generic_node (buffer, TREE_VEC_ELT (OMP_FOR_INIT (node), i),
1935                                  spc, flags, false);
1936               pp_string (buffer, "; ");
1937               dump_generic_node (buffer, TREE_VEC_ELT (OMP_FOR_COND (node), i),
1938                                  spc, flags, false);
1939               pp_string (buffer, "; ");
1940               dump_generic_node (buffer, TREE_VEC_ELT (OMP_FOR_INCR (node), i),
1941                                  spc, flags, false);
1942               pp_string (buffer, ")");
1943             }
1944           if (OMP_FOR_BODY (node))
1945             {
1946               newline_and_indent (buffer, spc + 2);
1947               pp_character (buffer, '{');
1948               newline_and_indent (buffer, spc + 4);
1949               dump_generic_node (buffer, OMP_FOR_BODY (node), spc + 4, flags,
1950                   false);
1951               newline_and_indent (buffer, spc + 2);
1952               pp_character (buffer, '}');
1953             }
1954           spc -= 2 * TREE_VEC_LENGTH (OMP_FOR_INIT (node)) - 2;
1955           if (OMP_FOR_PRE_BODY (node))
1956             {
1957               spc -= 4;
1958               newline_and_indent (buffer, spc + 2);
1959               pp_character (buffer, '}');
1960             }
1961         }
1962       is_expr = false;
1963       break;
1964
1965     case OMP_SECTIONS:
1966       pp_string (buffer, "#pragma omp sections");
1967       if (OMP_SECTIONS_CONTROL (node))
1968         {
1969           pp_string (buffer, " <");
1970           dump_generic_node (buffer, OMP_SECTIONS_CONTROL (node), spc,
1971                              flags, false);
1972           pp_string (buffer, ">");
1973         }
1974       dump_omp_clauses (buffer, OMP_SECTIONS_CLAUSES (node), spc, flags);
1975       goto dump_omp_body;
1976
1977     case OMP_SECTIONS_SWITCH:
1978       pp_string (buffer, "OMP_SECTIONS_SWITCH");
1979       is_expr = false;
1980       break;
1981  
1982     case OMP_SECTION:
1983       pp_string (buffer, "#pragma omp section");
1984       goto dump_omp_body;
1985  
1986     case OMP_MASTER:
1987       pp_string (buffer, "#pragma omp master");
1988       goto dump_omp_body;
1989
1990     case OMP_ORDERED:
1991       pp_string (buffer, "#pragma omp ordered");
1992       goto dump_omp_body;
1993
1994     case OMP_CRITICAL:
1995       pp_string (buffer, "#pragma omp critical");
1996       if (OMP_CRITICAL_NAME (node))
1997         {
1998           pp_space (buffer);
1999           pp_character (buffer, '(');
2000           dump_generic_node (buffer, OMP_CRITICAL_NAME (node), spc,
2001                              flags, false);
2002           pp_character (buffer, ')');
2003         }
2004       goto dump_omp_body;
2005
2006     case OMP_ATOMIC:
2007       pp_string (buffer, "#pragma omp atomic");
2008       newline_and_indent (buffer, spc + 2);
2009       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
2010       pp_space (buffer);
2011       pp_character (buffer, '=');
2012       pp_space (buffer);
2013       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
2014       break;
2015
2016     case OMP_ATOMIC_LOAD:
2017       pp_string (buffer, "#pragma omp atomic_load");
2018       newline_and_indent (buffer, spc + 2);
2019       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
2020       pp_space (buffer);
2021       pp_character (buffer, '=');
2022       pp_space (buffer);
2023       pp_character (buffer, '*');
2024       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
2025       break;
2026
2027     case OMP_ATOMIC_STORE:
2028       pp_string (buffer, "#pragma omp atomic_store (");
2029       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
2030       pp_character (buffer, ')');
2031       break;
2032
2033     case OMP_SINGLE:
2034       pp_string (buffer, "#pragma omp single");
2035       dump_omp_clauses (buffer, OMP_SINGLE_CLAUSES (node), spc, flags);
2036       goto dump_omp_body;
2037
2038     case OMP_RETURN:
2039       pp_string (buffer, "OMP_RETURN");
2040       if (OMP_RETURN_NOWAIT (node))
2041         pp_string (buffer, " [nowait]");
2042       is_expr = false;
2043       break;
2044
2045     case OMP_CONTINUE:
2046       pp_string (buffer, "OMP_CONTINUE <");
2047       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
2048       pp_string (buffer, " <- ");
2049       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
2050       pp_string (buffer, ">");
2051       is_expr = false;
2052       break;
2053
2054     case OMP_CLAUSE:
2055       dump_omp_clause (buffer, node, spc, flags);
2056       is_expr = false;
2057       break;
2058
2059     case REDUC_MAX_EXPR:
2060       pp_string (buffer, " REDUC_MAX_EXPR < ");
2061       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
2062       pp_string (buffer, " > ");
2063       break;
2064
2065     case REDUC_MIN_EXPR:
2066       pp_string (buffer, " REDUC_MIN_EXPR < ");
2067       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
2068       pp_string (buffer, " > ");
2069       break;
2070
2071     case REDUC_PLUS_EXPR:
2072       pp_string (buffer, " REDUC_PLUS_EXPR < ");
2073       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
2074       pp_string (buffer, " > ");
2075       break;
2076
2077     case VEC_WIDEN_MULT_HI_EXPR:
2078       pp_string (buffer, " VEC_WIDEN_MULT_HI_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_WIDEN_MULT_LO_EXPR:
2086       pp_string (buffer, " VEC_WIDEN_MULT_LO_EXPR < ");
2087       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
2088       pp_string (buffer, ", ");
2089       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
2090       pp_string (buffer, " > ");
2091       break;
2092
2093     case VEC_UNPACK_HI_EXPR:
2094       pp_string (buffer, " VEC_UNPACK_HI_EXPR < ");
2095       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
2096       pp_string (buffer, " > ");
2097       break;
2098
2099     case VEC_UNPACK_LO_EXPR:
2100       pp_string (buffer, " VEC_UNPACK_LO_EXPR < ");
2101       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
2102       pp_string (buffer, " > ");
2103       break;
2104
2105     case VEC_UNPACK_FLOAT_HI_EXPR:
2106       pp_string (buffer, " VEC_UNPACK_FLOAT_HI_EXPR < ");
2107       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
2108       pp_string (buffer, " > ");
2109       break;
2110
2111     case VEC_UNPACK_FLOAT_LO_EXPR:
2112       pp_string (buffer, " VEC_UNPACK_FLOAT_LO_EXPR < ");
2113       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
2114       pp_string (buffer, " > ");
2115       break;
2116
2117     case VEC_PACK_TRUNC_EXPR:
2118       pp_string (buffer, " VEC_PACK_TRUNC_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_SAT_EXPR:
2126       pp_string (buffer, " VEC_PACK_SAT_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 VEC_PACK_FIX_TRUNC_EXPR:
2134       pp_string (buffer, " VEC_PACK_FIX_TRUNC_EXPR < ");
2135       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
2136       pp_string (buffer, ", ");
2137       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
2138       pp_string (buffer, " > ");
2139       break;
2140
2141     case BLOCK:
2142       {
2143         tree t;
2144         pp_string (buffer, "BLOCK");
2145
2146         if (BLOCK_ABSTRACT (node))
2147           pp_string (buffer, " [abstract]");
2148
2149         if (TREE_ASM_WRITTEN (node))
2150           pp_string (buffer, " [written]");
2151
2152         newline_and_indent (buffer, spc + 2);
2153
2154         if (BLOCK_SUPERCONTEXT (node))
2155           {
2156             pp_string (buffer, "SUPERCONTEXT: ");
2157             if (TREE_CODE (BLOCK_SUPERCONTEXT (node)) == BLOCK)
2158               pp_printf (buffer, "BLOCK %p",
2159                          (void *)BLOCK_SUPERCONTEXT (node));
2160             else
2161               dump_generic_node (buffer, BLOCK_SUPERCONTEXT (node), 0, flags,
2162                                  false);
2163             newline_and_indent (buffer, spc + 2);
2164           }
2165
2166         if (BLOCK_SUBBLOCKS (node))
2167           {
2168             pp_string (buffer, "SUBBLOCKS: ");
2169             for (t = BLOCK_SUBBLOCKS (node); t; t = BLOCK_CHAIN (t))
2170               pp_printf (buffer, "%p ", (void *)t);
2171             newline_and_indent (buffer, spc + 2);
2172           }
2173
2174         if (BLOCK_VARS (node))
2175           {
2176             pp_string (buffer, "VARS: ");
2177             for (t = BLOCK_VARS (node); t; t = TREE_CHAIN (t))
2178               {
2179                 dump_generic_node (buffer, t, 0, flags, false);
2180                 pp_string (buffer, " ");
2181               }
2182             newline_and_indent (buffer, spc + 2);
2183           }
2184
2185         if (BLOCK_ABSTRACT_ORIGIN (node))
2186           {
2187             pp_string (buffer, "ABSTRACT_ORIGIN: ");
2188             if (TREE_CODE (BLOCK_ABSTRACT_ORIGIN (node)) == BLOCK)
2189               pp_printf (buffer, "BLOCK %p",
2190                          (void *)BLOCK_ABSTRACT_ORIGIN (node));
2191             else
2192               dump_generic_node (buffer, BLOCK_ABSTRACT_ORIGIN (node), 0, flags,
2193                                  false);
2194             newline_and_indent (buffer, spc + 2);
2195           }
2196       }
2197     break;
2198
2199     case VEC_EXTRACT_EVEN_EXPR:
2200       pp_string (buffer, " VEC_EXTRACT_EVEN_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_EXTRACT_ODD_EXPR:
2208       pp_string (buffer, " VEC_EXTRACT_ODD_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_HIGH_EXPR:
2216       pp_string (buffer, " VEC_INTERLEAVE_HIGH_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     case VEC_INTERLEAVE_LOW_EXPR:
2224       pp_string (buffer, " VEC_INTERLEAVE_LOW_EXPR < ");
2225       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
2226       pp_string (buffer, ", ");
2227       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
2228       pp_string (buffer, " > ");
2229       break;
2230
2231     default:
2232       NIY;
2233     }
2234
2235   if (is_stmt && is_expr)
2236     pp_semicolon (buffer);
2237
2238   /* If we're building a diagnostic, the formatted text will be written
2239      into BUFFER's stream by the caller; otherwise, write it now.  */
2240   if (!(flags & TDF_DIAGNOSTIC))
2241     pp_write_text_to_stream (buffer);
2242
2243   return spc;
2244 }
2245
2246 /* Print the declaration of a variable.  */
2247
2248 static void
2249 print_declaration (pretty_printer *buffer, tree t, int spc, int flags)
2250 {
2251   INDENT (spc);
2252
2253   if (TREE_CODE (t) == TYPE_DECL)
2254     pp_string (buffer, "typedef ");
2255
2256   if (CODE_CONTAINS_STRUCT (TREE_CODE (t), TS_DECL_WRTL) && DECL_REGISTER (t))
2257     pp_string (buffer, "register ");
2258
2259   if (TREE_PUBLIC (t) && DECL_EXTERNAL (t))
2260     pp_string (buffer, "extern ");
2261   else if (TREE_STATIC (t))
2262     pp_string (buffer, "static ");
2263
2264   /* Print the type and name.  */
2265   if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
2266     {
2267       tree tmp;
2268
2269       /* Print array's type.  */
2270       tmp = TREE_TYPE (t);
2271       while (TREE_CODE (TREE_TYPE (tmp)) == ARRAY_TYPE)
2272         tmp = TREE_TYPE (tmp);
2273       dump_generic_node (buffer, TREE_TYPE (tmp), spc, flags, false);
2274
2275       /* Print variable's name.  */
2276       pp_space (buffer);
2277       dump_generic_node (buffer, t, spc, flags, false);
2278
2279       /* Print the dimensions.  */
2280       tmp = TREE_TYPE (t);
2281       while (TREE_CODE (tmp) == ARRAY_TYPE)
2282         {
2283           dump_array_domain (buffer, TYPE_DOMAIN (tmp), spc, flags);
2284           tmp = TREE_TYPE (tmp);
2285         }
2286     }
2287   else if (TREE_CODE (t) == FUNCTION_DECL)
2288     {
2289       dump_generic_node (buffer, TREE_TYPE (TREE_TYPE (t)), spc, flags, false);
2290       pp_space (buffer);
2291       dump_decl_name (buffer, t, flags);
2292       dump_function_declaration (buffer, TREE_TYPE (t), spc, flags);
2293     }
2294   else
2295     {
2296       /* Print type declaration.  */
2297       dump_generic_node (buffer, TREE_TYPE (t), spc, flags, false);
2298
2299       /* Print variable's name.  */
2300       pp_space (buffer);
2301       dump_generic_node (buffer, t, spc, flags, false);
2302     }
2303
2304   if (TREE_CODE (t) == VAR_DECL && DECL_HARD_REGISTER (t))
2305     {
2306       pp_string (buffer, " __asm__ ");
2307       pp_character (buffer, '(');
2308       dump_generic_node (buffer, DECL_ASSEMBLER_NAME (t), spc, flags, false);
2309       pp_character (buffer, ')');
2310     }
2311
2312   /* The initial value of a function serves to determine whether the function
2313      is declared or defined.  So the following does not apply to function
2314      nodes.  */
2315   if (TREE_CODE (t) != FUNCTION_DECL)
2316     {
2317       /* Print the initial value.  */
2318       if (DECL_INITIAL (t))
2319         {
2320           pp_space (buffer);
2321           pp_character (buffer, '=');
2322           pp_space (buffer);
2323           dump_generic_node (buffer, DECL_INITIAL (t), spc, flags, false);
2324         }
2325     }
2326
2327   if (TREE_CODE (t) == VAR_DECL && DECL_HAS_VALUE_EXPR_P (t))
2328     {
2329       pp_string (buffer, " [value-expr: ");
2330       dump_generic_node (buffer, DECL_VALUE_EXPR (t), spc, flags, false);
2331       pp_character (buffer, ']');
2332     }
2333
2334   pp_character (buffer, ';');
2335 }
2336
2337
2338 /* Prints a structure: name, fields, and methods.
2339    FIXME: Still incomplete.  */
2340
2341 static void
2342 print_struct_decl (pretty_printer *buffer, const_tree node, int spc, int flags)
2343 {
2344   /* Print the name of the structure.  */
2345   if (TYPE_NAME (node))
2346     {
2347       INDENT (spc);
2348       if (TREE_CODE (node) == RECORD_TYPE)
2349         pp_string (buffer, "struct ");
2350       else if ((TREE_CODE (node) == UNION_TYPE
2351                 || TREE_CODE (node) == QUAL_UNION_TYPE))
2352         pp_string (buffer, "union ");
2353
2354       dump_generic_node (buffer, TYPE_NAME (node), spc, 0, false);
2355     }
2356
2357   /* Print the contents of the structure.  */
2358   pp_newline (buffer);
2359   INDENT (spc);
2360   pp_character (buffer, '{');
2361   pp_newline (buffer);
2362
2363   /* Print the fields of the structure.  */
2364   {
2365     tree tmp;
2366     tmp = TYPE_FIELDS (node);
2367     while (tmp)
2368       {
2369         /* Avoid to print recursively the structure.  */
2370         /* FIXME : Not implemented correctly...,
2371            what about the case when we have a cycle in the contain graph? ...
2372            Maybe this could be solved by looking at the scope in which the
2373            structure was declared.  */
2374         if (TREE_TYPE (tmp) != node
2375             || (TREE_CODE (TREE_TYPE (tmp)) == POINTER_TYPE
2376                 && TREE_TYPE (TREE_TYPE (tmp)) != node))
2377           {
2378             print_declaration (buffer, tmp, spc+2, flags);
2379             pp_newline (buffer);
2380           }
2381         tmp = TREE_CHAIN (tmp);
2382       }
2383   }
2384   INDENT (spc);
2385   pp_character (buffer, '}');
2386 }
2387
2388 /* Return the priority of the operator OP.
2389
2390    From lowest to highest precedence with either left-to-right (L-R)
2391    or right-to-left (R-L) associativity]:
2392
2393      1  [L-R] ,
2394      2  [R-L] = += -= *= /= %= &= ^= |= <<= >>=
2395      3  [R-L] ?:
2396      4  [L-R] ||
2397      5  [L-R] &&
2398      6  [L-R] |
2399      7  [L-R] ^
2400      8  [L-R] &
2401      9  [L-R] == !=
2402     10  [L-R] < <= > >=
2403     11  [L-R] << >>
2404     12  [L-R] + -
2405     13  [L-R] * / %
2406     14  [R-L] ! ~ ++ -- + - * & (type) sizeof
2407     15  [L-R] fn() [] -> .
2408
2409    unary +, - and * have higher precedence than the corresponding binary
2410    operators.  */
2411
2412 static int
2413 op_prio (const_tree op)
2414 {
2415   if (op == NULL)
2416     return 9999;
2417
2418   switch (TREE_CODE (op))
2419     {
2420     case TREE_LIST:
2421     case COMPOUND_EXPR:
2422     case BIND_EXPR:
2423       return 1;
2424
2425     case MODIFY_EXPR:
2426     case GIMPLE_MODIFY_STMT:
2427     case INIT_EXPR:
2428       return 2;
2429
2430     case COND_EXPR:
2431       return 3;
2432
2433     case TRUTH_OR_EXPR:
2434     case TRUTH_ORIF_EXPR:
2435       return 4;
2436
2437     case TRUTH_AND_EXPR:
2438     case TRUTH_ANDIF_EXPR:
2439       return 5;
2440
2441     case BIT_IOR_EXPR:
2442       return 6;
2443
2444     case BIT_XOR_EXPR:
2445     case TRUTH_XOR_EXPR:
2446       return 7;
2447
2448     case BIT_AND_EXPR:
2449       return 8;
2450
2451     case EQ_EXPR:
2452     case NE_EXPR:
2453       return 9;
2454
2455     case UNLT_EXPR:
2456     case UNLE_EXPR:
2457     case UNGT_EXPR:
2458     case UNGE_EXPR:
2459     case UNEQ_EXPR:
2460     case LTGT_EXPR:
2461     case ORDERED_EXPR:
2462     case UNORDERED_EXPR:
2463     case LT_EXPR:
2464     case LE_EXPR:
2465     case GT_EXPR:
2466     case GE_EXPR:
2467       return 10;
2468
2469     case LSHIFT_EXPR:
2470     case RSHIFT_EXPR:
2471     case LROTATE_EXPR:
2472     case RROTATE_EXPR:
2473       return 11;
2474
2475     case WIDEN_SUM_EXPR:
2476     case PLUS_EXPR:
2477     case POINTER_PLUS_EXPR:
2478     case MINUS_EXPR:
2479       return 12;
2480
2481     case VEC_WIDEN_MULT_HI_EXPR:
2482     case VEC_WIDEN_MULT_LO_EXPR:
2483     case WIDEN_MULT_EXPR:
2484     case DOT_PROD_EXPR:
2485     case MULT_EXPR:
2486     case TRUNC_DIV_EXPR:
2487     case CEIL_DIV_EXPR:
2488     case FLOOR_DIV_EXPR:
2489     case ROUND_DIV_EXPR:
2490     case RDIV_EXPR:
2491     case EXACT_DIV_EXPR:
2492     case TRUNC_MOD_EXPR:
2493     case CEIL_MOD_EXPR:
2494     case FLOOR_MOD_EXPR:
2495     case ROUND_MOD_EXPR:
2496       return 13;
2497
2498     case TRUTH_NOT_EXPR:
2499     case BIT_NOT_EXPR:
2500     case POSTINCREMENT_EXPR:
2501     case POSTDECREMENT_EXPR:
2502     case PREINCREMENT_EXPR:
2503     case PREDECREMENT_EXPR:
2504     case NEGATE_EXPR:
2505     case ALIGN_INDIRECT_REF:
2506     case MISALIGNED_INDIRECT_REF:
2507     case INDIRECT_REF:
2508     case ADDR_EXPR:
2509     case FLOAT_EXPR:
2510     CASE_CONVERT:
2511     case FIX_TRUNC_EXPR:
2512     case TARGET_EXPR:
2513       return 14;
2514
2515     case CALL_EXPR:
2516     case ARRAY_REF:
2517     case ARRAY_RANGE_REF:
2518     case COMPONENT_REF:
2519       return 15;
2520
2521       /* Special expressions.  */
2522     case MIN_EXPR:
2523     case MAX_EXPR:
2524     case ABS_EXPR:
2525     case REALPART_EXPR:
2526     case IMAGPART_EXPR:
2527     case REDUC_MAX_EXPR:
2528     case REDUC_MIN_EXPR:
2529     case REDUC_PLUS_EXPR:
2530     case VEC_LSHIFT_EXPR:
2531     case VEC_RSHIFT_EXPR:
2532     case VEC_UNPACK_HI_EXPR:
2533     case VEC_UNPACK_LO_EXPR:
2534     case VEC_UNPACK_FLOAT_HI_EXPR:
2535     case VEC_UNPACK_FLOAT_LO_EXPR:
2536     case VEC_PACK_TRUNC_EXPR:
2537     case VEC_PACK_SAT_EXPR:
2538       return 16;
2539
2540     case SAVE_EXPR:
2541     case NON_LVALUE_EXPR:
2542       return op_prio (TREE_OPERAND (op, 0));
2543
2544     default:
2545       /* Return an arbitrarily high precedence to avoid surrounding single
2546          VAR_DECLs in ()s.  */
2547       return 9999;
2548     }
2549 }
2550
2551
2552 /* Return the symbol associated with operator CODE.  */
2553
2554 const char *
2555 op_symbol_code (enum tree_code code)
2556 {
2557   switch (code)
2558     {
2559     case MODIFY_EXPR:
2560     case GIMPLE_MODIFY_STMT:
2561       return "=";
2562
2563     case TRUTH_OR_EXPR:
2564     case TRUTH_ORIF_EXPR:
2565       return "||";
2566
2567     case TRUTH_AND_EXPR:
2568     case TRUTH_ANDIF_EXPR:
2569       return "&&";
2570
2571     case BIT_IOR_EXPR:
2572       return "|";
2573
2574     case TRUTH_XOR_EXPR:
2575     case BIT_XOR_EXPR:
2576       return "^";
2577
2578     case ADDR_EXPR:
2579     case BIT_AND_EXPR:
2580       return "&";
2581
2582     case ORDERED_EXPR:
2583       return "ord";
2584     case UNORDERED_EXPR:
2585       return "unord";
2586
2587     case EQ_EXPR:
2588       return "==";
2589     case UNEQ_EXPR:
2590       return "u==";
2591
2592     case NE_EXPR:
2593       return "!=";
2594
2595     case LT_EXPR:
2596       return "<";
2597     case UNLT_EXPR:
2598       return "u<";
2599
2600     case LE_EXPR:
2601       return "<=";
2602     case UNLE_EXPR:
2603       return "u<=";
2604
2605     case GT_EXPR:
2606       return ">";
2607     case UNGT_EXPR:
2608       return "u>";
2609
2610     case GE_EXPR:
2611       return ">=";
2612     case UNGE_EXPR:
2613       return "u>=";
2614
2615     case LTGT_EXPR:
2616       return "<>";
2617
2618     case LSHIFT_EXPR:
2619       return "<<";
2620
2621     case RSHIFT_EXPR:
2622       return ">>";
2623
2624     case LROTATE_EXPR:
2625       return "r<<";
2626
2627     case RROTATE_EXPR:
2628       return "r>>";
2629
2630     case VEC_LSHIFT_EXPR:
2631       return "v<<";
2632
2633     case VEC_RSHIFT_EXPR:
2634       return "v>>";
2635
2636     case POINTER_PLUS_EXPR:
2637       return "+";
2638  
2639     case PLUS_EXPR:
2640       return "+";
2641
2642     case REDUC_PLUS_EXPR:
2643       return "r+";
2644
2645     case WIDEN_SUM_EXPR:
2646       return "w+";
2647
2648     case WIDEN_MULT_EXPR:
2649       return "w*";
2650
2651     case NEGATE_EXPR:
2652     case MINUS_EXPR:
2653       return "-";
2654
2655     case BIT_NOT_EXPR:
2656       return "~";
2657
2658     case TRUTH_NOT_EXPR:
2659       return "!";
2660
2661     case MULT_EXPR:
2662     case INDIRECT_REF:
2663       return "*";
2664
2665     case ALIGN_INDIRECT_REF:
2666       return "A*";
2667
2668     case MISALIGNED_INDIRECT_REF:
2669       return "M*";
2670
2671     case TRUNC_DIV_EXPR:
2672     case RDIV_EXPR:
2673       return "/";
2674
2675     case CEIL_DIV_EXPR:
2676       return "/[cl]";
2677
2678     case FLOOR_DIV_EXPR:
2679       return "/[fl]";
2680
2681     case ROUND_DIV_EXPR:
2682       return "/[rd]";
2683
2684     case EXACT_DIV_EXPR:
2685       return "/[ex]";
2686
2687     case TRUNC_MOD_EXPR:
2688       return "%";
2689
2690     case CEIL_MOD_EXPR:
2691       return "%[cl]";
2692
2693     case FLOOR_MOD_EXPR:
2694       return "%[fl]";
2695
2696     case ROUND_MOD_EXPR:
2697       return "%[rd]";
2698
2699     case PREDECREMENT_EXPR:
2700       return " --";
2701
2702     case PREINCREMENT_EXPR:
2703       return " ++";
2704
2705     case POSTDECREMENT_EXPR:
2706       return "-- ";
2707
2708     case POSTINCREMENT_EXPR:
2709       return "++ ";
2710
2711     case MAX_EXPR:
2712       return "max";
2713
2714     case MIN_EXPR:
2715       return "min";
2716
2717     default:
2718       return "<<< ??? >>>";
2719     }
2720 }
2721
2722 /* Return the symbol associated with operator OP.  */
2723
2724 static const char *
2725 op_symbol (const_tree op)
2726 {
2727   return op_symbol_code (TREE_CODE (op));
2728 }
2729
2730 /* Prints the name of a CALL_EXPR.  */
2731
2732 static void
2733 print_call_name (pretty_printer *buffer, const_tree node)
2734 {
2735   tree op0;
2736
2737   gcc_assert (TREE_CODE (node) == CALL_EXPR);
2738
2739   op0 = CALL_EXPR_FN (node);
2740
2741   if (TREE_CODE (op0) == NON_LVALUE_EXPR)
2742     op0 = TREE_OPERAND (op0, 0);
2743
2744   switch (TREE_CODE (op0))
2745     {
2746     case VAR_DECL:
2747     case PARM_DECL:
2748       dump_function_name (buffer, op0);
2749       break;
2750
2751     case ADDR_EXPR:
2752     case INDIRECT_REF:
2753     case NOP_EXPR:
2754       dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
2755       break;
2756
2757     case COND_EXPR:
2758       pp_string (buffer, "(");
2759       dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
2760       pp_string (buffer, ") ? ");
2761       dump_generic_node (buffer, TREE_OPERAND (op0, 1), 0, 0, false);
2762       pp_string (buffer, " : ");
2763       dump_generic_node (buffer, TREE_OPERAND (op0, 2), 0, 0, false);
2764       break;
2765
2766     case COMPONENT_REF:
2767       /* The function is a pointer contained in a structure.  */
2768       if (TREE_CODE (TREE_OPERAND (op0, 0)) == INDIRECT_REF ||
2769           TREE_CODE (TREE_OPERAND (op0, 0)) == VAR_DECL)
2770         dump_function_name (buffer, TREE_OPERAND (op0, 1));
2771       else
2772         dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
2773       /* else
2774          We can have several levels of structures and a function
2775          pointer inside.  This is not implemented yet...  */
2776       /*                  NIY;*/
2777       break;
2778
2779     case ARRAY_REF:
2780       if (TREE_CODE (TREE_OPERAND (op0, 0)) == VAR_DECL)
2781         dump_function_name (buffer, TREE_OPERAND (op0, 0));
2782       else
2783         dump_generic_node (buffer, op0, 0, 0, false);
2784       break;
2785
2786     case SSA_NAME:
2787     case OBJ_TYPE_REF:
2788       dump_generic_node (buffer, op0, 0, 0, false);
2789       break;
2790
2791     default:
2792       NIY;
2793     }
2794 }
2795
2796 /* Parses the string STR and replaces new-lines by '\n', tabs by '\t', ...  */
2797
2798 static void
2799 pretty_print_string (pretty_printer *buffer, const char *str)
2800 {
2801   if (str == NULL)
2802     return;
2803
2804   while (*str)
2805     {
2806       switch (str[0])
2807         {
2808         case '\b':
2809           pp_string (buffer, "\\b");
2810           break;
2811
2812         case '\f':
2813           pp_string (buffer, "\\f");
2814           break;
2815
2816         case '\n':
2817           pp_string (buffer, "\\n");
2818           break;
2819
2820         case '\r':
2821           pp_string (buffer, "\\r");
2822           break;
2823
2824         case '\t':
2825           pp_string (buffer, "\\t");
2826           break;
2827
2828         case '\v':
2829           pp_string (buffer, "\\v");
2830           break;
2831
2832         case '\\':
2833           pp_string (buffer, "\\\\");
2834           break;
2835
2836         case '\"':
2837           pp_string (buffer, "\\\"");
2838           break;
2839
2840         case '\'':
2841           pp_string (buffer, "\\'");
2842           break;
2843
2844           /* No need to handle \0; the loop terminates on \0.  */
2845
2846         case '\1':
2847           pp_string (buffer, "\\1");
2848           break;
2849
2850         case '\2':
2851           pp_string (buffer, "\\2");
2852           break;
2853
2854         case '\3':
2855           pp_string (buffer, "\\3");
2856           break;
2857
2858         case '\4':
2859           pp_string (buffer, "\\4");
2860           break;
2861
2862         case '\5':
2863           pp_string (buffer, "\\5");
2864           break;
2865
2866         case '\6':
2867           pp_string (buffer, "\\6");
2868           break;
2869
2870         case '\7':
2871           pp_string (buffer, "\\7");
2872           break;
2873
2874         default:
2875           pp_character (buffer, str[0]);
2876           break;
2877         }
2878       str++;
2879     }
2880 }
2881
2882 static void
2883 maybe_init_pretty_print (FILE *file)
2884 {
2885   if (!initialized)
2886     {
2887       pp_construct (&buffer, /* prefix */NULL, /* line-width */0);
2888       pp_needs_newline (&buffer) = true;
2889       initialized = 1;
2890     }
2891
2892   buffer.buffer->stream = file;
2893 }
2894
2895 static void
2896 newline_and_indent (pretty_printer *buffer, int spc)
2897 {
2898   pp_newline (buffer);
2899   INDENT (spc);
2900 }
2901
2902
2903 static void
2904 dump_vops (pretty_printer *buffer, tree stmt, int spc, int flags)
2905 {
2906   struct voptype_d *vdefs;
2907   struct voptype_d *vuses;
2908   int i, n;
2909
2910   if (!ssa_operands_active () || !stmt_references_memory_p (stmt))
2911     return;
2912
2913   /* Even if the statement doesn't have virtual operators yet, it may
2914      contain symbol information (this happens before aliases have been
2915      computed).  */
2916   if ((flags & TDF_MEMSYMS)
2917       && VUSE_OPS (stmt) == NULL
2918       && VDEF_OPS (stmt) == NULL)
2919     {
2920       if (LOADED_SYMS (stmt))
2921         {
2922           pp_string (buffer, "# LOADS: ");
2923           dump_symbols (buffer, LOADED_SYMS (stmt), flags);
2924           newline_and_indent (buffer, spc);
2925         }
2926
2927       if (STORED_SYMS (stmt))
2928         {
2929           pp_string (buffer, "# STORES: ");
2930           dump_symbols (buffer, STORED_SYMS (stmt), flags);
2931           newline_and_indent (buffer, spc);
2932         }
2933
2934       return;
2935     }
2936
2937   vuses = VUSE_OPS (stmt);
2938   while (vuses)
2939     {
2940       pp_string (buffer, "# VUSE <");
2941
2942       n = VUSE_NUM (vuses);
2943       for (i = 0; i < n; i++)
2944         {
2945           dump_generic_node (buffer, VUSE_OP (vuses, i), spc + 2, flags, false);
2946           if (i < n - 1)
2947             pp_string (buffer, ", ");
2948         }
2949
2950       pp_string (buffer, ">");
2951
2952       if (flags & TDF_MEMSYMS)
2953         dump_symbols (buffer, LOADED_SYMS (stmt), flags);
2954
2955       newline_and_indent (buffer, spc);
2956       vuses = vuses->next;
2957     }
2958
2959   vdefs = VDEF_OPS (stmt);
2960   while (vdefs)
2961     {
2962       pp_string (buffer, "# ");
2963       dump_generic_node (buffer, VDEF_RESULT (vdefs), spc + 2, flags, false);
2964       pp_string (buffer, " = VDEF <");
2965
2966       n = VDEF_NUM (vdefs);
2967       for (i = 0; i < n; i++)
2968         {
2969           dump_generic_node (buffer, VDEF_OP (vdefs, i), spc + 2, flags, 0);
2970           if (i < n - 1)
2971             pp_string (buffer, ", ");
2972         }
2973
2974       pp_string (buffer, ">");
2975
2976       if ((flags & TDF_MEMSYMS) && vdefs->next == NULL)
2977         dump_symbols (buffer, STORED_SYMS (stmt), flags);
2978
2979       newline_and_indent (buffer, spc);
2980       vdefs = vdefs->next;
2981     }
2982 }
2983
2984
2985 /* Dumps basic block BB to FILE with details described by FLAGS and
2986    indented by INDENT spaces.  */
2987
2988 void
2989 dump_generic_bb (FILE *file, basic_block bb, int indent, int flags)
2990 {
2991   maybe_init_pretty_print (file);
2992   dump_generic_bb_buff (&buffer, bb, indent, flags);
2993   pp_flush (&buffer);
2994 }
2995
2996 /* Dumps header of basic block BB to buffer BUFFER indented by INDENT
2997    spaces and details described by flags.  */
2998
2999 static void
3000 dump_bb_header (pretty_printer *buffer, basic_block bb, int indent, int flags)
3001 {
3002   edge e;
3003   tree stmt;
3004   edge_iterator ei;
3005
3006   if (flags & TDF_BLOCKS)
3007     {
3008       INDENT (indent);
3009       pp_string (buffer, "# BLOCK ");
3010       pp_decimal_int (buffer, bb->index);
3011       if (bb->frequency)
3012         {
3013           pp_string (buffer, " freq:");
3014           pp_decimal_int (buffer, bb->frequency);
3015         }
3016       if (bb->count)
3017         {
3018           pp_string (buffer, " count:");
3019           pp_widest_integer (buffer, bb->count);
3020         }
3021
3022       if (flags & TDF_LINENO)
3023         {
3024           block_stmt_iterator bsi;
3025
3026           for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
3027             if (get_lineno (bsi_stmt (bsi)) != -1)
3028               {
3029                 pp_string (buffer, ", starting at line ");
3030                 pp_decimal_int (buffer, get_lineno (bsi_stmt (bsi)));
3031                 break;
3032               }
3033         }
3034       newline_and_indent (buffer, indent);
3035
3036       pp_string (buffer, "# PRED:");
3037       pp_write_text_to_stream (buffer);
3038       FOR_EACH_EDGE (e, ei, bb->preds)
3039         if (flags & TDF_SLIM)
3040           {
3041             pp_string (buffer, " ");
3042             if (e->src == ENTRY_BLOCK_PTR)
3043               pp_string (buffer, "ENTRY");
3044             else
3045               pp_decimal_int (buffer, e->src->index);
3046           }
3047         else
3048           dump_edge_info (buffer->buffer->stream, e, 0);
3049       pp_newline (buffer);
3050     }
3051   else
3052     {
3053       stmt = first_stmt (bb);
3054       if (!stmt || TREE_CODE (stmt) != LABEL_EXPR)
3055         {
3056           INDENT (indent - 2);
3057           pp_string (buffer, "<bb ");
3058           pp_decimal_int (buffer, bb->index);
3059           pp_string (buffer, ">:");
3060           pp_newline (buffer);
3061         }
3062     }
3063   pp_write_text_to_stream (buffer);
3064   check_bb_profile (bb, buffer->buffer->stream);
3065 }
3066
3067 /* Dumps end of basic block BB to buffer BUFFER indented by INDENT
3068    spaces.  */
3069
3070 static void
3071 dump_bb_end (pretty_printer *buffer, basic_block bb, int indent, int flags)
3072 {
3073   edge e;
3074   edge_iterator ei;
3075
3076   INDENT (indent);
3077   pp_string (buffer, "# SUCC:");
3078   pp_write_text_to_stream (buffer);
3079   FOR_EACH_EDGE (e, ei, bb->succs)
3080     if (flags & TDF_SLIM)
3081       {
3082         pp_string (buffer, " ");
3083         if (e->dest == EXIT_BLOCK_PTR)
3084           pp_string (buffer, "EXIT");
3085         else
3086           pp_decimal_int (buffer, e->dest->index);
3087       }
3088     else
3089       dump_edge_info (buffer->buffer->stream, e, 1);
3090   pp_newline (buffer);
3091 }
3092
3093 /* Dump PHI nodes of basic block BB to BUFFER with details described
3094    by FLAGS and indented by INDENT spaces.  */
3095
3096 static void
3097 dump_phi_nodes (pretty_printer *buffer, basic_block bb, int indent, int flags)
3098 {
3099   tree phi = phi_nodes (bb);
3100   if (!phi)
3101     return;
3102
3103   for (; phi; phi = PHI_CHAIN (phi))
3104     {
3105       if (is_gimple_reg (PHI_RESULT (phi)) || (flags & TDF_VOPS))
3106         {
3107           INDENT (indent);
3108           pp_string (buffer, "# ");
3109           dump_generic_node (buffer, phi, indent, flags, false);
3110           pp_newline (buffer);
3111           if (flags & TDF_VERBOSE)
3112             print_node (buffer->buffer->stream, "", phi, indent);
3113         }
3114     }
3115 }
3116
3117
3118 /* Dump jump to basic block BB that is represented implicitly in the cfg
3119    to BUFFER.  */
3120
3121 static void
3122 pp_cfg_jump (pretty_printer *buffer, basic_block bb)
3123 {
3124   tree stmt;
3125
3126   stmt = first_stmt (bb);
3127
3128   pp_string (buffer, "goto <bb ");
3129   pp_decimal_int (buffer, bb->index);
3130   pp_string (buffer, ">");
3131   if (stmt && TREE_CODE (stmt) == LABEL_EXPR)
3132     {
3133       pp_string (buffer, " (");
3134       dump_generic_node (buffer, LABEL_EXPR_LABEL (stmt), 0, 0, false);
3135       pp_string (buffer, ")");
3136     }
3137   pp_semicolon (buffer);
3138 }
3139
3140 /* Dump edges represented implicitly in basic block BB to BUFFER, indented
3141    by INDENT spaces, with details given by FLAGS.  */
3142
3143 static void
3144 dump_implicit_edges (pretty_printer *buffer, basic_block bb, int indent,
3145                      int flags)
3146 {
3147   edge e;
3148   edge_iterator ei;
3149   tree stmt;
3150
3151   stmt = last_stmt (bb);
3152   if (stmt && TREE_CODE (stmt) == COND_EXPR)
3153     {
3154       edge true_edge, false_edge;
3155
3156       /* When we are emitting the code or changing CFG, it is possible that
3157          the edges are not yet created.  When we are using debug_bb in such
3158          a situation, we do not want it to crash.  */
3159       if (EDGE_COUNT (bb->succs) != 2)
3160         return;
3161       extract_true_false_edges_from_block (bb, &true_edge, &false_edge);
3162
3163       INDENT (indent + 2);
3164       pp_cfg_jump (buffer, true_edge->dest);
3165       newline_and_indent (buffer, indent);
3166       pp_string (buffer, "else");
3167       newline_and_indent (buffer, indent + 2);
3168       pp_cfg_jump (buffer, false_edge->dest);
3169       pp_newline (buffer);
3170       return;
3171     }
3172
3173   /* If there is a fallthru edge, we may need to add an artificial goto to the
3174      dump.  */
3175   FOR_EACH_EDGE (e, ei, bb->succs)
3176     if (e->flags & EDGE_FALLTHRU)
3177       break;
3178   if (e && e->dest != bb->next_bb)
3179     {
3180       INDENT (indent);
3181
3182       if ((flags & TDF_LINENO) && e->goto_locus != UNKNOWN_LOCATION)
3183         {
3184           expanded_location goto_xloc;
3185           goto_xloc = expand_location (e->goto_locus);
3186           pp_character (buffer, '[');
3187           if (goto_xloc.file)
3188             {
3189               pp_string (buffer, goto_xloc.file);
3190               pp_string (buffer, " : ");
3191             }
3192           pp_decimal_int (buffer, goto_xloc.line);
3193           pp_string (buffer, "] ");
3194         }
3195
3196       pp_cfg_jump (buffer, e->dest);
3197       pp_newline (buffer);
3198     }
3199 }
3200
3201 /* Dumps basic block BB to buffer BUFFER with details described by FLAGS and
3202    indented by INDENT spaces.  */
3203
3204 static void
3205 dump_generic_bb_buff (pretty_printer *buffer, basic_block bb,
3206                       int indent, int flags)
3207 {
3208   block_stmt_iterator bsi;
3209   tree stmt;
3210   int label_indent = indent - 2;
3211
3212   if (label_indent < 0)
3213     label_indent = 0;
3214
3215   dump_bb_header (buffer, bb, indent, flags);
3216
3217   dump_phi_nodes (buffer, bb, indent, flags);
3218
3219   for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
3220     {
3221       int curr_indent;
3222
3223       stmt = bsi_stmt (bsi);
3224
3225       curr_indent = TREE_CODE (stmt) == LABEL_EXPR ? label_indent : indent;
3226
3227       INDENT (curr_indent);
3228       dump_generic_node (buffer, stmt, curr_indent, flags, true);
3229       pp_newline (buffer);
3230       dump_histograms_for_stmt (cfun, buffer->buffer->stream, stmt);
3231       if (flags & TDF_VERBOSE)
3232         print_node (buffer->buffer->stream, "", stmt, curr_indent);
3233     }
3234
3235   dump_implicit_edges (buffer, bb, indent, flags);
3236
3237   if (flags & TDF_BLOCKS)
3238     dump_bb_end (buffer, bb, indent, flags);
3239 }