OSDN Git Service

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