OSDN Git Service

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