OSDN Git Service

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