OSDN Git Service

PR target/33286
[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.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.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.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_SINGLE:
1945       pp_string (buffer, "#pragma omp single");
1946       dump_omp_clauses (buffer, OMP_SINGLE_CLAUSES (node), spc, flags);
1947       goto dump_omp_body;
1948
1949     case OMP_RETURN:
1950       pp_string (buffer, "OMP_RETURN");
1951       if (OMP_RETURN_NOWAIT (node))
1952         pp_string (buffer, " [nowait]");
1953       is_expr = false;
1954       break;
1955
1956     case OMP_CONTINUE:
1957       pp_string (buffer, "OMP_CONTINUE <");
1958       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1959       pp_string (buffer, " <- ");
1960       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1961       pp_string (buffer, ">");
1962       is_expr = false;
1963       break;
1964
1965     case OMP_CLAUSE:
1966       dump_omp_clause (buffer, node, spc, flags);
1967       is_expr = false;
1968       break;
1969
1970     case REDUC_MAX_EXPR:
1971       pp_string (buffer, " REDUC_MAX_EXPR < ");
1972       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1973       pp_string (buffer, " > ");
1974       break;
1975
1976     case REDUC_MIN_EXPR:
1977       pp_string (buffer, " REDUC_MIN_EXPR < ");
1978       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1979       pp_string (buffer, " > ");
1980       break;
1981
1982     case REDUC_PLUS_EXPR:
1983       pp_string (buffer, " REDUC_PLUS_EXPR < ");
1984       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1985       pp_string (buffer, " > ");
1986       break;
1987
1988     case VEC_WIDEN_MULT_HI_EXPR:
1989       pp_string (buffer, " VEC_WIDEN_MULT_HI_EXPR < ");
1990       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1991       pp_string (buffer, ", ");
1992       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1993       pp_string (buffer, " > ");
1994       break;
1995
1996     case VEC_WIDEN_MULT_LO_EXPR:
1997       pp_string (buffer, " VEC_WIDEN_MULT_LO_EXPR < ");
1998       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1999       pp_string (buffer, ", ");
2000       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
2001       pp_string (buffer, " > ");
2002       break;
2003
2004     case VEC_UNPACK_HI_EXPR:
2005       pp_string (buffer, " VEC_UNPACK_HI_EXPR < ");
2006       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
2007       pp_string (buffer, " > ");
2008       break;
2009
2010     case VEC_UNPACK_LO_EXPR:
2011       pp_string (buffer, " VEC_UNPACK_LO_EXPR < ");
2012       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
2013       pp_string (buffer, " > ");
2014       break;
2015
2016     case VEC_UNPACK_FLOAT_HI_EXPR:
2017       pp_string (buffer, " VEC_UNPACK_FLOAT_HI_EXPR < ");
2018       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
2019       pp_string (buffer, " > ");
2020       break;
2021
2022     case VEC_UNPACK_FLOAT_LO_EXPR:
2023       pp_string (buffer, " VEC_UNPACK_FLOAT_LO_EXPR < ");
2024       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
2025       pp_string (buffer, " > ");
2026       break;
2027
2028     case VEC_PACK_TRUNC_EXPR:
2029       pp_string (buffer, " VEC_PACK_TRUNC_EXPR < ");
2030       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
2031       pp_string (buffer, ", ");
2032       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
2033       pp_string (buffer, " > ");
2034       break;
2035
2036     case VEC_PACK_SAT_EXPR:
2037       pp_string (buffer, " VEC_PACK_SAT_EXPR < ");
2038       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
2039       pp_string (buffer, ", ");
2040       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
2041       pp_string (buffer, " > ");
2042       break;
2043
2044     case VEC_PACK_FIX_TRUNC_EXPR:
2045       pp_string (buffer, " VEC_PACK_FIX_TRUNC_EXPR < ");
2046       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
2047       pp_string (buffer, ", ");
2048       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
2049       pp_string (buffer, " > ");
2050       break;
2051
2052     case BLOCK:
2053       {
2054         tree t;
2055         pp_string (buffer, "BLOCK");
2056
2057         if (BLOCK_ABSTRACT (node))
2058           pp_string (buffer, " [abstract]");
2059
2060         if (TREE_ASM_WRITTEN (node))
2061           pp_string (buffer, " [written]");
2062
2063         newline_and_indent (buffer, spc + 2);
2064
2065         if (BLOCK_SUPERCONTEXT (node))
2066           {
2067             pp_string (buffer, "SUPERCONTEXT: ");
2068             if (TREE_CODE (BLOCK_SUPERCONTEXT (node)) == BLOCK)
2069               pp_printf (buffer, "BLOCK %p",
2070                          (void *)BLOCK_SUPERCONTEXT (node));
2071             else
2072               dump_generic_node (buffer, BLOCK_SUPERCONTEXT (node), 0, flags,
2073                                  false);
2074             newline_and_indent (buffer, spc + 2);
2075           }
2076
2077         if (BLOCK_SUBBLOCKS (node))
2078           {
2079             pp_string (buffer, "SUBBLOCKS: ");
2080             for (t = BLOCK_SUBBLOCKS (node); t; t = BLOCK_CHAIN (t))
2081               pp_printf (buffer, "%p ", (void *)t);
2082             newline_and_indent (buffer, spc + 2);
2083           }
2084
2085         if (BLOCK_VARS (node))
2086           {
2087             pp_string (buffer, "VARS: ");
2088             for (t = BLOCK_VARS (node); t; t = TREE_CHAIN (t))
2089               {
2090                 dump_generic_node (buffer, t, 0, flags, false);
2091                 pp_string (buffer, " ");
2092               }
2093             newline_and_indent (buffer, spc + 2);
2094           }
2095
2096         if (BLOCK_ABSTRACT_ORIGIN (node))
2097           {
2098             pp_string (buffer, "ABSTRACT_ORIGIN: ");
2099             if (TREE_CODE (BLOCK_ABSTRACT_ORIGIN (node)) == BLOCK)
2100               pp_printf (buffer, "BLOCK %p",
2101                          (void *)BLOCK_ABSTRACT_ORIGIN (node));
2102             else
2103               dump_generic_node (buffer, BLOCK_ABSTRACT_ORIGIN (node), 0, flags,
2104                                  false);
2105             newline_and_indent (buffer, spc + 2);
2106           }
2107       }
2108     break;
2109
2110     case VEC_EXTRACT_EVEN_EXPR:
2111       pp_string (buffer, " VEC_EXTRACT_EVEN_EXPR < ");
2112       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
2113       pp_string (buffer, ", ");
2114       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
2115       pp_string (buffer, " > ");
2116       break;
2117   
2118     case VEC_EXTRACT_ODD_EXPR:
2119       pp_string (buffer, " VEC_EXTRACT_ODD_EXPR < ");
2120       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
2121       pp_string (buffer, ", ");
2122       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
2123       pp_string (buffer, " > ");
2124       break;
2125
2126     case VEC_INTERLEAVE_HIGH_EXPR:
2127       pp_string (buffer, " VEC_INTERLEAVE_HIGH_EXPR < ");
2128       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
2129       pp_string (buffer, ", ");
2130       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
2131       pp_string (buffer, " > ");
2132       break;
2133
2134     case VEC_INTERLEAVE_LOW_EXPR:
2135       pp_string (buffer, " VEC_INTERLEAVE_LOW_EXPR < ");
2136       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
2137       pp_string (buffer, ", ");
2138       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
2139       pp_string (buffer, " > ");
2140       break;
2141
2142     default:
2143       NIY;
2144     }
2145
2146   if (is_stmt && is_expr)
2147     pp_semicolon (buffer);
2148
2149   /* If we're building a diagnostic, the formatted text will be written
2150      into BUFFER's stream by the caller; otherwise, write it now.  */
2151   if (!(flags & TDF_DIAGNOSTIC))
2152     pp_write_text_to_stream (buffer);
2153
2154   return spc;
2155 }
2156
2157 /* Print the declaration of a variable.  */
2158
2159 static void
2160 print_declaration (pretty_printer *buffer, tree t, int spc, int flags)
2161 {
2162   INDENT (spc);
2163
2164   if (TREE_CODE (t) == TYPE_DECL)
2165     pp_string (buffer, "typedef ");
2166
2167   if (CODE_CONTAINS_STRUCT (TREE_CODE (t), TS_DECL_WRTL) && DECL_REGISTER (t))
2168     pp_string (buffer, "register ");
2169
2170   if (TREE_PUBLIC (t) && DECL_EXTERNAL (t))
2171     pp_string (buffer, "extern ");
2172   else if (TREE_STATIC (t))
2173     pp_string (buffer, "static ");
2174
2175   /* Print the type and name.  */
2176   if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
2177     {
2178       tree tmp;
2179
2180       /* Print array's type.  */
2181       tmp = TREE_TYPE (t);
2182       while (TREE_CODE (TREE_TYPE (tmp)) == ARRAY_TYPE)
2183         tmp = TREE_TYPE (tmp);
2184       dump_generic_node (buffer, TREE_TYPE (tmp), spc, flags, false);
2185
2186       /* Print variable's name.  */
2187       pp_space (buffer);
2188       dump_generic_node (buffer, t, spc, flags, false);
2189
2190       /* Print the dimensions.  */
2191       tmp = TREE_TYPE (t);
2192       while (TREE_CODE (tmp) == ARRAY_TYPE)
2193         {
2194           dump_array_domain (buffer, TYPE_DOMAIN (tmp), spc, flags);
2195           tmp = TREE_TYPE (tmp);
2196         }
2197     }
2198   else if (TREE_CODE (t) == FUNCTION_DECL)
2199     {
2200       dump_generic_node (buffer, TREE_TYPE (TREE_TYPE (t)), spc, flags, false);
2201       pp_space (buffer);
2202       dump_decl_name (buffer, t, flags);
2203       dump_function_declaration (buffer, TREE_TYPE (t), spc, flags);
2204     }
2205   else
2206     {
2207       /* Print type declaration.  */
2208       dump_generic_node (buffer, TREE_TYPE (t), spc, flags, false);
2209
2210       /* Print variable's name.  */
2211       pp_space (buffer);
2212       dump_generic_node (buffer, t, spc, flags, false);
2213     }
2214
2215   if (TREE_CODE (t) == VAR_DECL && DECL_HARD_REGISTER (t))
2216     {
2217       pp_string (buffer, " __asm__ ");
2218       pp_character (buffer, '(');
2219       dump_generic_node (buffer, DECL_ASSEMBLER_NAME (t), spc, flags, false);
2220       pp_character (buffer, ')');
2221     }
2222
2223   /* The initial value of a function serves to determine wether the function
2224      is declared or defined.  So the following does not apply to function
2225      nodes.  */
2226   if (TREE_CODE (t) != FUNCTION_DECL)
2227     {
2228       /* Print the initial value.  */
2229       if (DECL_INITIAL (t))
2230         {
2231           pp_space (buffer);
2232           pp_character (buffer, '=');
2233           pp_space (buffer);
2234           dump_generic_node (buffer, DECL_INITIAL (t), spc, flags, false);
2235         }
2236     }
2237
2238   if (TREE_CODE (t) == VAR_DECL && DECL_HAS_VALUE_EXPR_P (t))
2239     {
2240       pp_string (buffer, " [value-expr: ");
2241       dump_generic_node (buffer, DECL_VALUE_EXPR (t), spc, flags, false);
2242       pp_character (buffer, ']');
2243     }
2244
2245   pp_character (buffer, ';');
2246 }
2247
2248
2249 /* Prints a structure: name, fields, and methods.
2250    FIXME: Still incomplete.  */
2251
2252 static void
2253 print_struct_decl (pretty_printer *buffer, const_tree node, int spc, int flags)
2254 {
2255   /* Print the name of the structure.  */
2256   if (TYPE_NAME (node))
2257     {
2258       INDENT (spc);
2259       if (TREE_CODE (node) == RECORD_TYPE)
2260         pp_string (buffer, "struct ");
2261       else if ((TREE_CODE (node) == UNION_TYPE
2262                 || TREE_CODE (node) == QUAL_UNION_TYPE))
2263         pp_string (buffer, "union ");
2264
2265       dump_generic_node (buffer, TYPE_NAME (node), spc, 0, false);
2266     }
2267
2268   /* Print the contents of the structure.  */
2269   pp_newline (buffer);
2270   INDENT (spc);
2271   pp_character (buffer, '{');
2272   pp_newline (buffer);
2273
2274   /* Print the fields of the structure.  */
2275   {
2276     tree tmp;
2277     tmp = TYPE_FIELDS (node);
2278     while (tmp)
2279       {
2280         /* Avoid to print recursively the structure.  */
2281         /* FIXME : Not implemented correctly...,
2282            what about the case when we have a cycle in the contain graph? ...
2283            Maybe this could be solved by looking at the scope in which the
2284            structure was declared.  */
2285         if (TREE_TYPE (tmp) != node
2286             || (TREE_CODE (TREE_TYPE (tmp)) == POINTER_TYPE
2287                 && TREE_TYPE (TREE_TYPE (tmp)) != node))
2288           {
2289             print_declaration (buffer, tmp, spc+2, flags);
2290             pp_newline (buffer);
2291           }
2292         tmp = TREE_CHAIN (tmp);
2293       }
2294   }
2295   INDENT (spc);
2296   pp_character (buffer, '}');
2297 }
2298
2299 /* Return the priority of the operator OP.
2300
2301    From lowest to highest precedence with either left-to-right (L-R)
2302    or right-to-left (R-L) associativity]:
2303
2304      1  [L-R] ,
2305      2  [R-L] = += -= *= /= %= &= ^= |= <<= >>=
2306      3  [R-L] ?:
2307      4  [L-R] ||
2308      5  [L-R] &&
2309      6  [L-R] |
2310      7  [L-R] ^
2311      8  [L-R] &
2312      9  [L-R] == !=
2313     10  [L-R] < <= > >=
2314     11  [L-R] << >>
2315     12  [L-R] + -
2316     13  [L-R] * / %
2317     14  [R-L] ! ~ ++ -- + - * & (type) sizeof
2318     15  [L-R] fn() [] -> .
2319
2320    unary +, - and * have higher precedence than the corresponding binary
2321    operators.  */
2322
2323 static int
2324 op_prio (const_tree op)
2325 {
2326   if (op == NULL)
2327     return 9999;
2328
2329   switch (TREE_CODE (op))
2330     {
2331     case TREE_LIST:
2332     case COMPOUND_EXPR:
2333     case BIND_EXPR:
2334       return 1;
2335
2336     case MODIFY_EXPR:
2337     case GIMPLE_MODIFY_STMT:
2338     case INIT_EXPR:
2339       return 2;
2340
2341     case COND_EXPR:
2342       return 3;
2343
2344     case TRUTH_OR_EXPR:
2345     case TRUTH_ORIF_EXPR:
2346       return 4;
2347
2348     case TRUTH_AND_EXPR:
2349     case TRUTH_ANDIF_EXPR:
2350       return 5;
2351
2352     case BIT_IOR_EXPR:
2353       return 6;
2354
2355     case BIT_XOR_EXPR:
2356     case TRUTH_XOR_EXPR:
2357       return 7;
2358
2359     case BIT_AND_EXPR:
2360       return 8;
2361
2362     case EQ_EXPR:
2363     case NE_EXPR:
2364       return 9;
2365
2366     case UNLT_EXPR:
2367     case UNLE_EXPR:
2368     case UNGT_EXPR:
2369     case UNGE_EXPR:
2370     case UNEQ_EXPR:
2371     case LTGT_EXPR:
2372     case ORDERED_EXPR:
2373     case UNORDERED_EXPR:
2374     case LT_EXPR:
2375     case LE_EXPR:
2376     case GT_EXPR:
2377     case GE_EXPR:
2378       return 10;
2379
2380     case LSHIFT_EXPR:
2381     case RSHIFT_EXPR:
2382     case LROTATE_EXPR:
2383     case RROTATE_EXPR:
2384       return 11;
2385
2386     case WIDEN_SUM_EXPR:
2387     case PLUS_EXPR:
2388     case POINTER_PLUS_EXPR:
2389     case MINUS_EXPR:
2390       return 12;
2391
2392     case VEC_WIDEN_MULT_HI_EXPR:
2393     case VEC_WIDEN_MULT_LO_EXPR:
2394     case WIDEN_MULT_EXPR:
2395     case DOT_PROD_EXPR:
2396     case MULT_EXPR:
2397     case TRUNC_DIV_EXPR:
2398     case CEIL_DIV_EXPR:
2399     case FLOOR_DIV_EXPR:
2400     case ROUND_DIV_EXPR:
2401     case RDIV_EXPR:
2402     case EXACT_DIV_EXPR:
2403     case TRUNC_MOD_EXPR:
2404     case CEIL_MOD_EXPR:
2405     case FLOOR_MOD_EXPR:
2406     case ROUND_MOD_EXPR:
2407       return 13;
2408
2409     case TRUTH_NOT_EXPR:
2410     case BIT_NOT_EXPR:
2411     case POSTINCREMENT_EXPR:
2412     case POSTDECREMENT_EXPR:
2413     case PREINCREMENT_EXPR:
2414     case PREDECREMENT_EXPR:
2415     case NEGATE_EXPR:
2416     case ALIGN_INDIRECT_REF:
2417     case MISALIGNED_INDIRECT_REF:
2418     case INDIRECT_REF:
2419     case ADDR_EXPR:
2420     case FLOAT_EXPR:
2421     case NOP_EXPR:
2422     case CONVERT_EXPR:
2423     case FIX_TRUNC_EXPR:
2424     case TARGET_EXPR:
2425       return 14;
2426
2427     case CALL_EXPR:
2428     case ARRAY_REF:
2429     case ARRAY_RANGE_REF:
2430     case COMPONENT_REF:
2431       return 15;
2432
2433       /* Special expressions.  */
2434     case MIN_EXPR:
2435     case MAX_EXPR:
2436     case ABS_EXPR:
2437     case REALPART_EXPR:
2438     case IMAGPART_EXPR:
2439     case REDUC_MAX_EXPR:
2440     case REDUC_MIN_EXPR:
2441     case REDUC_PLUS_EXPR:
2442     case VEC_LSHIFT_EXPR:
2443     case VEC_RSHIFT_EXPR:
2444     case VEC_UNPACK_HI_EXPR:
2445     case VEC_UNPACK_LO_EXPR:
2446     case VEC_UNPACK_FLOAT_HI_EXPR:
2447     case VEC_UNPACK_FLOAT_LO_EXPR:
2448     case VEC_PACK_TRUNC_EXPR:
2449     case VEC_PACK_SAT_EXPR:
2450       return 16;
2451
2452     case SAVE_EXPR:
2453     case NON_LVALUE_EXPR:
2454       return op_prio (TREE_OPERAND (op, 0));
2455
2456     default:
2457       /* Return an arbitrarily high precedence to avoid surrounding single
2458          VAR_DECLs in ()s.  */
2459       return 9999;
2460     }
2461 }
2462
2463
2464 /* Return the symbol associated with operator CODE.  */
2465
2466 const char *
2467 op_symbol_code (enum tree_code code)
2468 {
2469   switch (code)
2470     {
2471     case MODIFY_EXPR:
2472     case GIMPLE_MODIFY_STMT:
2473       return "=";
2474
2475     case TRUTH_OR_EXPR:
2476     case TRUTH_ORIF_EXPR:
2477       return "||";
2478
2479     case TRUTH_AND_EXPR:
2480     case TRUTH_ANDIF_EXPR:
2481       return "&&";
2482
2483     case BIT_IOR_EXPR:
2484       return "|";
2485
2486     case TRUTH_XOR_EXPR:
2487     case BIT_XOR_EXPR:
2488       return "^";
2489
2490     case ADDR_EXPR:
2491     case BIT_AND_EXPR:
2492       return "&";
2493
2494     case ORDERED_EXPR:
2495       return "ord";
2496     case UNORDERED_EXPR:
2497       return "unord";
2498
2499     case EQ_EXPR:
2500       return "==";
2501     case UNEQ_EXPR:
2502       return "u==";
2503
2504     case NE_EXPR:
2505       return "!=";
2506
2507     case LT_EXPR:
2508       return "<";
2509     case UNLT_EXPR:
2510       return "u<";
2511
2512     case LE_EXPR:
2513       return "<=";
2514     case UNLE_EXPR:
2515       return "u<=";
2516
2517     case GT_EXPR:
2518       return ">";
2519     case UNGT_EXPR:
2520       return "u>";
2521
2522     case GE_EXPR:
2523       return ">=";
2524     case UNGE_EXPR:
2525       return "u>=";
2526
2527     case LTGT_EXPR:
2528       return "<>";
2529
2530     case LSHIFT_EXPR:
2531       return "<<";
2532
2533     case RSHIFT_EXPR:
2534       return ">>";
2535
2536     case LROTATE_EXPR:
2537       return "r<<";
2538
2539     case RROTATE_EXPR:
2540       return "r>>";
2541
2542     case VEC_LSHIFT_EXPR:
2543       return "v<<";
2544
2545     case VEC_RSHIFT_EXPR:
2546       return "v>>";
2547
2548     case POINTER_PLUS_EXPR:
2549       return "+";
2550  
2551     case PLUS_EXPR:
2552       return "+";
2553
2554     case REDUC_PLUS_EXPR:
2555       return "r+";
2556
2557     case WIDEN_SUM_EXPR:
2558       return "w+";
2559
2560     case WIDEN_MULT_EXPR:
2561       return "w*";
2562
2563     case NEGATE_EXPR:
2564     case MINUS_EXPR:
2565       return "-";
2566
2567     case BIT_NOT_EXPR:
2568       return "~";
2569
2570     case TRUTH_NOT_EXPR:
2571       return "!";
2572
2573     case MULT_EXPR:
2574     case INDIRECT_REF:
2575       return "*";
2576
2577     case ALIGN_INDIRECT_REF:
2578       return "A*";
2579
2580     case MISALIGNED_INDIRECT_REF:
2581       return "M*";
2582
2583     case TRUNC_DIV_EXPR:
2584     case RDIV_EXPR:
2585       return "/";
2586
2587     case CEIL_DIV_EXPR:
2588       return "/[cl]";
2589
2590     case FLOOR_DIV_EXPR:
2591       return "/[fl]";
2592
2593     case ROUND_DIV_EXPR:
2594       return "/[rd]";
2595
2596     case EXACT_DIV_EXPR:
2597       return "/[ex]";
2598
2599     case TRUNC_MOD_EXPR:
2600       return "%";
2601
2602     case CEIL_MOD_EXPR:
2603       return "%[cl]";
2604
2605     case FLOOR_MOD_EXPR:
2606       return "%[fl]";
2607
2608     case ROUND_MOD_EXPR:
2609       return "%[rd]";
2610
2611     case PREDECREMENT_EXPR:
2612       return " --";
2613
2614     case PREINCREMENT_EXPR:
2615       return " ++";
2616
2617     case POSTDECREMENT_EXPR:
2618       return "-- ";
2619
2620     case POSTINCREMENT_EXPR:
2621       return "++ ";
2622
2623     case MAX_EXPR:
2624       return "max";
2625
2626     case MIN_EXPR:
2627       return "min";
2628
2629     default:
2630       return "<<< ??? >>>";
2631     }
2632 }
2633
2634 /* Return the symbol associated with operator OP.  */
2635
2636 static const char *
2637 op_symbol (const_tree op)
2638 {
2639   return op_symbol_code (TREE_CODE (op));
2640 }
2641
2642 /* Prints the name of a CALL_EXPR.  */
2643
2644 static void
2645 print_call_name (pretty_printer *buffer, const_tree node)
2646 {
2647   tree op0;
2648
2649   gcc_assert (TREE_CODE (node) == CALL_EXPR);
2650
2651   op0 = CALL_EXPR_FN (node);
2652
2653   if (TREE_CODE (op0) == NON_LVALUE_EXPR)
2654     op0 = TREE_OPERAND (op0, 0);
2655
2656   switch (TREE_CODE (op0))
2657     {
2658     case VAR_DECL:
2659     case PARM_DECL:
2660       dump_function_name (buffer, op0);
2661       break;
2662
2663     case ADDR_EXPR:
2664     case INDIRECT_REF:
2665     case NOP_EXPR:
2666       dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
2667       break;
2668
2669     case COND_EXPR:
2670       pp_string (buffer, "(");
2671       dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
2672       pp_string (buffer, ") ? ");
2673       dump_generic_node (buffer, TREE_OPERAND (op0, 1), 0, 0, false);
2674       pp_string (buffer, " : ");
2675       dump_generic_node (buffer, TREE_OPERAND (op0, 2), 0, 0, false);
2676       break;
2677
2678     case COMPONENT_REF:
2679       /* The function is a pointer contained in a structure.  */
2680       if (TREE_CODE (TREE_OPERAND (op0, 0)) == INDIRECT_REF ||
2681           TREE_CODE (TREE_OPERAND (op0, 0)) == VAR_DECL)
2682         dump_function_name (buffer, TREE_OPERAND (op0, 1));
2683       else
2684         dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
2685       /* else
2686          We can have several levels of structures and a function
2687          pointer inside.  This is not implemented yet...  */
2688       /*                  NIY;*/
2689       break;
2690
2691     case ARRAY_REF:
2692       if (TREE_CODE (TREE_OPERAND (op0, 0)) == VAR_DECL)
2693         dump_function_name (buffer, TREE_OPERAND (op0, 0));
2694       else
2695         dump_generic_node (buffer, op0, 0, 0, false);
2696       break;
2697
2698     case SSA_NAME:
2699     case OBJ_TYPE_REF:
2700       dump_generic_node (buffer, op0, 0, 0, false);
2701       break;
2702
2703     default:
2704       NIY;
2705     }
2706 }
2707
2708 /* Parses the string STR and replaces new-lines by '\n', tabs by '\t', ...  */
2709
2710 static void
2711 pretty_print_string (pretty_printer *buffer, const char *str)
2712 {
2713   if (str == NULL)
2714     return;
2715
2716   while (*str)
2717     {
2718       switch (str[0])
2719         {
2720         case '\b':
2721           pp_string (buffer, "\\b");
2722           break;
2723
2724         case '\f':
2725           pp_string (buffer, "\\f");
2726           break;
2727
2728         case '\n':
2729           pp_string (buffer, "\\n");
2730           break;
2731
2732         case '\r':
2733           pp_string (buffer, "\\r");
2734           break;
2735
2736         case '\t':
2737           pp_string (buffer, "\\t");
2738           break;
2739
2740         case '\v':
2741           pp_string (buffer, "\\v");
2742           break;
2743
2744         case '\\':
2745           pp_string (buffer, "\\\\");
2746           break;
2747
2748         case '\"':
2749           pp_string (buffer, "\\\"");
2750           break;
2751
2752         case '\'':
2753           pp_string (buffer, "\\'");
2754           break;
2755
2756           /* No need to handle \0; the loop terminates on \0.  */
2757
2758         case '\1':
2759           pp_string (buffer, "\\1");
2760           break;
2761
2762         case '\2':
2763           pp_string (buffer, "\\2");
2764           break;
2765
2766         case '\3':
2767           pp_string (buffer, "\\3");
2768           break;
2769
2770         case '\4':
2771           pp_string (buffer, "\\4");
2772           break;
2773
2774         case '\5':
2775           pp_string (buffer, "\\5");
2776           break;
2777
2778         case '\6':
2779           pp_string (buffer, "\\6");
2780           break;
2781
2782         case '\7':
2783           pp_string (buffer, "\\7");
2784           break;
2785
2786         default:
2787           pp_character (buffer, str[0]);
2788           break;
2789         }
2790       str++;
2791     }
2792 }
2793
2794 static void
2795 maybe_init_pretty_print (FILE *file)
2796 {
2797   if (!initialized)
2798     {
2799       pp_construct (&buffer, /* prefix */NULL, /* line-width */0);
2800       pp_needs_newline (&buffer) = true;
2801       initialized = 1;
2802     }
2803
2804   buffer.buffer->stream = file;
2805 }
2806
2807 static void
2808 newline_and_indent (pretty_printer *buffer, int spc)
2809 {
2810   pp_newline (buffer);
2811   INDENT (spc);
2812 }
2813
2814
2815 static void
2816 dump_vops (pretty_printer *buffer, tree stmt, int spc, int flags)
2817 {
2818   struct voptype_d *vdefs;
2819   struct voptype_d *vuses;
2820   int i, n;
2821
2822   if (!ssa_operands_active () || !stmt_references_memory_p (stmt))
2823     return;
2824
2825   /* Even if the statement doesn't have virtual operators yet, it may
2826      contain symbol information (this happens before aliases have been
2827      computed).  */
2828   if ((flags & TDF_MEMSYMS)
2829       && VUSE_OPS (stmt) == NULL
2830       && VDEF_OPS (stmt) == NULL)
2831     {
2832       if (LOADED_SYMS (stmt))
2833         {
2834           pp_string (buffer, "# LOADS: ");
2835           dump_symbols (buffer, LOADED_SYMS (stmt), flags);
2836           newline_and_indent (buffer, spc);
2837         }
2838
2839       if (STORED_SYMS (stmt))
2840         {
2841           pp_string (buffer, "# STORES: ");
2842           dump_symbols (buffer, STORED_SYMS (stmt), flags);
2843           newline_and_indent (buffer, spc);
2844         }
2845
2846       return;
2847     }
2848
2849   vuses = VUSE_OPS (stmt);
2850   while (vuses)
2851     {
2852       pp_string (buffer, "# VUSE <");
2853
2854       n = VUSE_NUM (vuses);
2855       for (i = 0; i < n; i++)
2856         {
2857           dump_generic_node (buffer, VUSE_OP (vuses, i), spc + 2, flags, false);
2858           if (i < n - 1)
2859             pp_string (buffer, ", ");
2860         }
2861
2862       pp_string (buffer, ">");
2863
2864       if (flags & TDF_MEMSYMS)
2865         dump_symbols (buffer, LOADED_SYMS (stmt), flags);
2866
2867       newline_and_indent (buffer, spc);
2868       vuses = vuses->next;
2869     }
2870
2871   vdefs = VDEF_OPS (stmt);
2872   while (vdefs)
2873     {
2874       pp_string (buffer, "# ");
2875       dump_generic_node (buffer, VDEF_RESULT (vdefs), spc + 2, flags, false);
2876       pp_string (buffer, " = VDEF <");
2877
2878       n = VDEF_NUM (vdefs);
2879       for (i = 0; i < n; i++)
2880         {
2881           dump_generic_node (buffer, VDEF_OP (vdefs, i), spc + 2, flags, 0);
2882           if (i < n - 1)
2883             pp_string (buffer, ", ");
2884         }
2885
2886       pp_string (buffer, ">");
2887
2888       if ((flags & TDF_MEMSYMS) && vdefs->next == NULL)
2889         dump_symbols (buffer, STORED_SYMS (stmt), flags);
2890
2891       newline_and_indent (buffer, spc);
2892       vdefs = vdefs->next;
2893     }
2894 }
2895
2896
2897 /* Dumps basic block BB to FILE with details described by FLAGS and
2898    indented by INDENT spaces.  */
2899
2900 void
2901 dump_generic_bb (FILE *file, basic_block bb, int indent, int flags)
2902 {
2903   maybe_init_pretty_print (file);
2904   dump_generic_bb_buff (&buffer, bb, indent, flags);
2905   pp_flush (&buffer);
2906 }
2907
2908 /* Dumps header of basic block BB to buffer BUFFER indented by INDENT
2909    spaces and details described by flags.  */
2910
2911 static void
2912 dump_bb_header (pretty_printer *buffer, basic_block bb, int indent, int flags)
2913 {
2914   edge e;
2915   tree stmt;
2916   edge_iterator ei;
2917
2918   if (flags & TDF_BLOCKS)
2919     {
2920       INDENT (indent);
2921       pp_string (buffer, "# BLOCK ");
2922       pp_decimal_int (buffer, bb->index);
2923       if (bb->frequency)
2924         {
2925           pp_string (buffer, " freq:");
2926           pp_decimal_int (buffer, bb->frequency);
2927         }
2928       if (bb->count)
2929         {
2930           pp_string (buffer, " count:");
2931           pp_widest_integer (buffer, bb->count);
2932         }
2933
2934       if (flags & TDF_LINENO)
2935         {
2936           block_stmt_iterator bsi;
2937
2938           for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
2939             if (get_lineno (bsi_stmt (bsi)) != -1)
2940               {
2941                 pp_string (buffer, ", starting at line ");
2942                 pp_decimal_int (buffer, get_lineno (bsi_stmt (bsi)));
2943                 break;
2944               }
2945         }
2946       newline_and_indent (buffer, indent);
2947
2948       pp_string (buffer, "# PRED:");
2949       pp_write_text_to_stream (buffer);
2950       FOR_EACH_EDGE (e, ei, bb->preds)
2951         if (flags & TDF_SLIM)
2952           {
2953             pp_string (buffer, " ");
2954             if (e->src == ENTRY_BLOCK_PTR)
2955               pp_string (buffer, "ENTRY");
2956             else
2957               pp_decimal_int (buffer, e->src->index);
2958           }
2959         else
2960           dump_edge_info (buffer->buffer->stream, e, 0);
2961       pp_newline (buffer);
2962     }
2963   else
2964     {
2965       stmt = first_stmt (bb);
2966       if (!stmt || TREE_CODE (stmt) != LABEL_EXPR)
2967         {
2968           INDENT (indent - 2);
2969           pp_string (buffer, "<bb ");
2970           pp_decimal_int (buffer, bb->index);
2971           pp_string (buffer, ">:");
2972           pp_newline (buffer);
2973         }
2974     }
2975   pp_write_text_to_stream (buffer);
2976   check_bb_profile (bb, buffer->buffer->stream);
2977 }
2978
2979 /* Dumps end of basic block BB to buffer BUFFER indented by INDENT
2980    spaces.  */
2981
2982 static void
2983 dump_bb_end (pretty_printer *buffer, basic_block bb, int indent, int flags)
2984 {
2985   edge e;
2986   edge_iterator ei;
2987
2988   INDENT (indent);
2989   pp_string (buffer, "# SUCC:");
2990   pp_write_text_to_stream (buffer);
2991   FOR_EACH_EDGE (e, ei, bb->succs)
2992     if (flags & TDF_SLIM)
2993       {
2994         pp_string (buffer, " ");
2995         if (e->dest == EXIT_BLOCK_PTR)
2996           pp_string (buffer, "EXIT");
2997         else
2998           pp_decimal_int (buffer, e->dest->index);
2999       }
3000     else
3001       dump_edge_info (buffer->buffer->stream, e, 1);
3002   pp_newline (buffer);
3003 }
3004
3005 /* Dump PHI nodes of basic block BB to BUFFER with details described
3006    by FLAGS and indented by INDENT spaces.  */
3007
3008 static void
3009 dump_phi_nodes (pretty_printer *buffer, basic_block bb, int indent, int flags)
3010 {
3011   tree phi = phi_nodes (bb);
3012   if (!phi)
3013     return;
3014
3015   for (; phi; phi = PHI_CHAIN (phi))
3016     {
3017       if (is_gimple_reg (PHI_RESULT (phi)) || (flags & TDF_VOPS))
3018         {
3019           INDENT (indent);
3020           pp_string (buffer, "# ");
3021           dump_generic_node (buffer, phi, indent, flags, false);
3022           pp_newline (buffer);
3023         }
3024     }
3025 }
3026
3027
3028 /* Dump jump to basic block BB that is represented implicitly in the cfg
3029    to BUFFER.  */
3030
3031 static void
3032 pp_cfg_jump (pretty_printer *buffer, basic_block bb)
3033 {
3034   tree stmt;
3035
3036   stmt = first_stmt (bb);
3037
3038   pp_string (buffer, "goto <bb ");
3039   pp_decimal_int (buffer, bb->index);
3040   pp_string (buffer, ">");
3041   if (stmt && TREE_CODE (stmt) == LABEL_EXPR)
3042     {
3043       pp_string (buffer, " (");
3044       dump_generic_node (buffer, LABEL_EXPR_LABEL (stmt), 0, 0, false);
3045       pp_string (buffer, ")");
3046     }
3047   pp_semicolon (buffer);
3048 }
3049
3050 /* Dump edges represented implicitly in basic block BB to BUFFER, indented
3051    by INDENT spaces, with details given by FLAGS.  */
3052
3053 static void
3054 dump_implicit_edges (pretty_printer *buffer, basic_block bb, int indent,
3055                      int flags)
3056 {
3057   edge e;
3058   edge_iterator ei;
3059   tree stmt;
3060
3061   stmt = last_stmt (bb);
3062   if (stmt && TREE_CODE (stmt) == COND_EXPR)
3063     {
3064       edge true_edge, false_edge;
3065
3066       /* When we are emitting the code or changing CFG, it is possible that
3067          the edges are not yet created.  When we are using debug_bb in such
3068          a situation, we do not want it to crash.  */
3069       if (EDGE_COUNT (bb->succs) != 2)
3070         return;
3071       extract_true_false_edges_from_block (bb, &true_edge, &false_edge);
3072
3073       INDENT (indent + 2);
3074       pp_cfg_jump (buffer, true_edge->dest);
3075       newline_and_indent (buffer, indent);
3076       pp_string (buffer, "else");
3077       newline_and_indent (buffer, indent + 2);
3078       pp_cfg_jump (buffer, false_edge->dest);
3079       pp_newline (buffer);
3080       return;
3081     }
3082
3083   /* If there is a fallthru edge, we may need to add an artificial goto to the
3084      dump.  */
3085   FOR_EACH_EDGE (e, ei, bb->succs)
3086     if (e->flags & EDGE_FALLTHRU)
3087       break;
3088   if (e && e->dest != bb->next_bb)
3089     {
3090       INDENT (indent);
3091
3092       if ((flags & TDF_LINENO)
3093 #ifdef USE_MAPPED_LOCATION
3094           && e->goto_locus != UNKNOWN_LOCATION
3095 #else
3096           && e->goto_locus
3097 #endif
3098           )
3099         {
3100           expanded_location goto_xloc;
3101 #ifdef USE_MAPPED_LOCATION
3102           goto_xloc = expand_location (e->goto_locus);
3103 #else
3104           goto_xloc = *e->goto_locus;
3105 #endif
3106           pp_character (buffer, '[');
3107           if (goto_xloc.file)
3108             {
3109               pp_string (buffer, goto_xloc.file);
3110               pp_string (buffer, " : ");
3111             }
3112           pp_decimal_int (buffer, goto_xloc.line);
3113           pp_string (buffer, "] ");
3114         }
3115
3116       pp_cfg_jump (buffer, e->dest);
3117       pp_newline (buffer);
3118     }
3119 }
3120
3121 /* Dumps basic block BB to buffer BUFFER with details described by FLAGS and
3122    indented by INDENT spaces.  */
3123
3124 static void
3125 dump_generic_bb_buff (pretty_printer *buffer, basic_block bb,
3126                       int indent, int flags)
3127 {
3128   block_stmt_iterator bsi;
3129   tree stmt;
3130   int label_indent = indent - 2;
3131
3132   if (label_indent < 0)
3133     label_indent = 0;
3134
3135   dump_bb_header (buffer, bb, indent, flags);
3136
3137   dump_phi_nodes (buffer, bb, indent, flags);
3138
3139   for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
3140     {
3141       int curr_indent;
3142
3143       stmt = bsi_stmt (bsi);
3144
3145       curr_indent = TREE_CODE (stmt) == LABEL_EXPR ? label_indent : indent;
3146
3147       INDENT (curr_indent);
3148       dump_generic_node (buffer, stmt, curr_indent, flags, true);
3149       pp_newline (buffer);
3150       dump_histograms_for_stmt (cfun, buffer->buffer->stream, stmt);
3151     }
3152
3153   dump_implicit_edges (buffer, bb, indent, flags);
3154
3155   if (flags & TDF_BLOCKS)
3156     dump_bb_end (buffer, bb, indent, flags);
3157 }