OSDN Git Service

Fix ChangeLog entry.
[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_EXPR:
1826       pp_string (buffer, "OMP_RETURN");
1827       is_expr = false;
1828       break;
1829
1830     case OMP_CLAUSE:
1831       dump_omp_clause (buffer, node, spc, flags);
1832       is_expr = false;
1833       break;
1834
1835     case REDUC_MAX_EXPR:
1836       pp_string (buffer, " REDUC_MAX_EXPR < ");
1837       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1838       pp_string (buffer, " > ");
1839       break;
1840
1841     case REDUC_MIN_EXPR:
1842       pp_string (buffer, " REDUC_MIN_EXPR < ");
1843       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1844       pp_string (buffer, " > ");
1845       break;
1846
1847     case REDUC_PLUS_EXPR:
1848       pp_string (buffer, " REDUC_PLUS_EXPR < ");
1849       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1850       pp_string (buffer, " > ");
1851       break;
1852
1853     case BLOCK:
1854       {
1855         tree t;
1856         pp_string (buffer, "BLOCK");
1857
1858         if (BLOCK_ABSTRACT (node))
1859           pp_string (buffer, " [abstract]");
1860
1861         if (TREE_ASM_WRITTEN (node))
1862           pp_string (buffer, " [written]");
1863
1864         newline_and_indent (buffer, spc + 2);
1865
1866         if (BLOCK_SUPERCONTEXT (node))
1867           {
1868             pp_string (buffer, "SUPERCONTEXT: ");
1869             if (TREE_CODE (BLOCK_SUPERCONTEXT (node)) == BLOCK)
1870               pp_printf (buffer, "BLOCK %p",
1871                          (void *)BLOCK_SUPERCONTEXT (node));
1872             else
1873               dump_generic_node (buffer, BLOCK_SUPERCONTEXT (node), 0, flags,
1874                                  false);
1875             newline_and_indent (buffer, spc + 2);
1876           }
1877
1878         if (BLOCK_SUBBLOCKS (node))
1879           {
1880             pp_string (buffer, "SUBBLOCKS: ");
1881             for (t = BLOCK_SUBBLOCKS (node); t; t = BLOCK_CHAIN (t))
1882               pp_printf (buffer, "%p ", (void *)t);
1883             newline_and_indent (buffer, spc + 2);
1884           }
1885
1886         if (BLOCK_VARS (node))
1887           {
1888             pp_string (buffer, "VARS: ");
1889             for (t = BLOCK_VARS (node); t; t = TREE_CHAIN (t))
1890               {
1891                 dump_generic_node (buffer, t, 0, flags, false);
1892                 pp_string (buffer, " ");
1893               }
1894             newline_and_indent (buffer, spc + 2);
1895           }
1896
1897         if (BLOCK_ABSTRACT_ORIGIN (node))
1898           {
1899             pp_string (buffer, "ABSTRACT_ORIGIN: ");
1900             if (TREE_CODE (BLOCK_ABSTRACT_ORIGIN (node)) == BLOCK)
1901               pp_printf (buffer, "BLOCK %p",
1902                          (void *)BLOCK_ABSTRACT_ORIGIN (node));
1903             else
1904               dump_generic_node (buffer, BLOCK_ABSTRACT_ORIGIN (node), 0, flags,
1905                                  false);
1906             newline_and_indent (buffer, spc + 2);
1907           }
1908       }
1909     break;
1910
1911     default:
1912       NIY;
1913     }
1914
1915   if (is_stmt && is_expr)
1916     pp_semicolon (buffer);
1917   pp_write_text_to_stream (buffer);
1918
1919   return spc;
1920 }
1921
1922 /* Print the declaration of a variable.  */
1923
1924 static void
1925 print_declaration (pretty_printer *buffer, tree t, int spc, int flags)
1926 {
1927   INDENT (spc);
1928
1929   if (TREE_CODE (t) == TYPE_DECL)
1930     pp_string (buffer, "typedef ");
1931
1932   if (CODE_CONTAINS_STRUCT (TREE_CODE (t), TS_DECL_WRTL) && DECL_REGISTER (t))
1933     pp_string (buffer, "register ");
1934
1935   if (TREE_PUBLIC (t) && DECL_EXTERNAL (t))
1936     pp_string (buffer, "extern ");
1937   else if (TREE_STATIC (t))
1938     pp_string (buffer, "static ");
1939
1940   /* Print the type and name.  */
1941   if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
1942     {
1943       tree tmp;
1944
1945       /* Print array's type.  */
1946       tmp = TREE_TYPE (t);
1947       while (TREE_CODE (TREE_TYPE (tmp)) == ARRAY_TYPE)
1948         tmp = TREE_TYPE (tmp);
1949       dump_generic_node (buffer, TREE_TYPE (tmp), spc, flags, false);
1950
1951       /* Print variable's name.  */
1952       pp_space (buffer);
1953       dump_generic_node (buffer, t, spc, flags, false);
1954
1955       /* Print the dimensions.  */
1956       tmp = TREE_TYPE (t);
1957       while (TREE_CODE (tmp) == ARRAY_TYPE)
1958         {
1959           dump_array_domain (buffer, TYPE_DOMAIN (tmp), spc, flags);
1960           tmp = TREE_TYPE (tmp);
1961         }
1962     }
1963   else if (TREE_CODE (t) == FUNCTION_DECL)
1964     {
1965       dump_generic_node (buffer, TREE_TYPE (TREE_TYPE (t)), spc, flags, false);
1966       pp_space (buffer);
1967       dump_decl_name (buffer, t, flags);
1968       dump_function_declaration (buffer, TREE_TYPE (t), spc, flags);
1969     }
1970   else
1971     {
1972       /* Print type declaration.  */
1973       dump_generic_node (buffer, TREE_TYPE (t), spc, flags, false);
1974
1975       /* Print variable's name.  */
1976       pp_space (buffer);
1977       dump_generic_node (buffer, t, spc, flags, false);
1978     }
1979
1980   if (TREE_CODE (t) == VAR_DECL && DECL_HARD_REGISTER (t))
1981     {
1982       pp_string (buffer, " __asm__ ");
1983       pp_character (buffer, '(');
1984       dump_generic_node (buffer, DECL_ASSEMBLER_NAME (t), spc, flags, false);
1985       pp_character (buffer, ')');
1986     }
1987
1988   /* The initial value of a function serves to determine wether the function
1989      is declared or defined.  So the following does not apply to function
1990      nodes.  */
1991   if (TREE_CODE (t) != FUNCTION_DECL)
1992     {
1993       /* Print the initial value.  */
1994       if (DECL_INITIAL (t))
1995         {
1996           pp_space (buffer);
1997           pp_character (buffer, '=');
1998           pp_space (buffer);
1999           dump_generic_node (buffer, DECL_INITIAL (t), spc, flags, false);
2000         }
2001     }
2002
2003   if (TREE_CODE (t) == VAR_DECL && DECL_HAS_VALUE_EXPR_P (t))
2004     {
2005       pp_string (buffer, " [value-expr: ");
2006       dump_generic_node (buffer, DECL_VALUE_EXPR (t), spc, flags, false);
2007       pp_character (buffer, ']');
2008     }
2009
2010   pp_character (buffer, ';');
2011 }
2012
2013
2014 /* Prints a structure: name, fields, and methods.
2015    FIXME: Still incomplete.  */
2016
2017 static void
2018 print_struct_decl (pretty_printer *buffer, tree node, int spc, int flags)
2019 {
2020   /* Print the name of the structure.  */
2021   if (TYPE_NAME (node))
2022     {
2023       INDENT (spc);
2024       if (TREE_CODE (node) == RECORD_TYPE)
2025         pp_string (buffer, "struct ");
2026       else if ((TREE_CODE (node) == UNION_TYPE
2027                 || TREE_CODE (node) == QUAL_UNION_TYPE))
2028         pp_string (buffer, "union ");
2029
2030       dump_generic_node (buffer, TYPE_NAME (node), spc, 0, false);
2031     }
2032
2033   /* Print the contents of the structure.  */
2034   pp_newline (buffer);
2035   INDENT (spc);
2036   pp_character (buffer, '{');
2037   pp_newline (buffer);
2038
2039   /* Print the fields of the structure.  */
2040   {
2041     tree tmp;
2042     tmp = TYPE_FIELDS (node);
2043     while (tmp)
2044       {
2045         /* Avoid to print recursively the structure.  */
2046         /* FIXME : Not implemented correctly...,
2047            what about the case when we have a cycle in the contain graph? ...
2048            Maybe this could be solved by looking at the scope in which the
2049            structure was declared.  */
2050         if (TREE_TYPE (tmp) != node
2051             || (TREE_CODE (TREE_TYPE (tmp)) == POINTER_TYPE
2052                 && TREE_TYPE (TREE_TYPE (tmp)) != node))
2053           {
2054             print_declaration (buffer, tmp, spc+2, flags);
2055             pp_newline (buffer);
2056           }
2057         tmp = TREE_CHAIN (tmp);
2058       }
2059   }
2060   INDENT (spc);
2061   pp_character (buffer, '}');
2062 }
2063
2064 /* Return the priority of the operator OP.
2065
2066    From lowest to highest precedence with either left-to-right (L-R)
2067    or right-to-left (R-L) associativity]:
2068
2069      1  [L-R] ,
2070      2  [R-L] = += -= *= /= %= &= ^= |= <<= >>=
2071      3  [R-L] ?:
2072      4  [L-R] ||
2073      5  [L-R] &&
2074      6  [L-R] |
2075      7  [L-R] ^
2076      8  [L-R] &
2077      9  [L-R] == !=
2078     10  [L-R] < <= > >=
2079     11  [L-R] << >>
2080     12  [L-R] + -
2081     13  [L-R] * / %
2082     14  [R-L] ! ~ ++ -- + - * & (type) sizeof
2083     15  [L-R] fn() [] -> .
2084
2085    unary +, - and * have higher precedence than the corresponding binary
2086    operators.  */
2087
2088 static int
2089 op_prio (tree op)
2090 {
2091   if (op == NULL)
2092     return 9999;
2093
2094   switch (TREE_CODE (op))
2095     {
2096     case TREE_LIST:
2097     case COMPOUND_EXPR:
2098     case BIND_EXPR:
2099       return 1;
2100
2101     case MODIFY_EXPR:
2102     case INIT_EXPR:
2103       return 2;
2104
2105     case COND_EXPR:
2106       return 3;
2107
2108     case TRUTH_OR_EXPR:
2109     case TRUTH_ORIF_EXPR:
2110       return 4;
2111
2112     case TRUTH_AND_EXPR:
2113     case TRUTH_ANDIF_EXPR:
2114       return 5;
2115
2116     case BIT_IOR_EXPR:
2117       return 6;
2118
2119     case BIT_XOR_EXPR:
2120     case TRUTH_XOR_EXPR:
2121       return 7;
2122
2123     case BIT_AND_EXPR:
2124       return 8;
2125
2126     case EQ_EXPR:
2127     case NE_EXPR:
2128       return 9;
2129
2130     case UNLT_EXPR:
2131     case UNLE_EXPR:
2132     case UNGT_EXPR:
2133     case UNGE_EXPR:
2134     case UNEQ_EXPR:
2135     case LTGT_EXPR:
2136     case ORDERED_EXPR:
2137     case UNORDERED_EXPR:
2138     case LT_EXPR:
2139     case LE_EXPR:
2140     case GT_EXPR:
2141     case GE_EXPR:
2142       return 10;
2143
2144     case LSHIFT_EXPR:
2145     case RSHIFT_EXPR:
2146     case LROTATE_EXPR:
2147     case RROTATE_EXPR:
2148       return 11;
2149
2150     case WIDEN_SUM_EXPR:
2151     case PLUS_EXPR:
2152     case MINUS_EXPR:
2153       return 12;
2154
2155     case WIDEN_MULT_EXPR:
2156     case DOT_PROD_EXPR:
2157     case MULT_EXPR:
2158     case TRUNC_DIV_EXPR:
2159     case CEIL_DIV_EXPR:
2160     case FLOOR_DIV_EXPR:
2161     case ROUND_DIV_EXPR:
2162     case RDIV_EXPR:
2163     case EXACT_DIV_EXPR:
2164     case TRUNC_MOD_EXPR:
2165     case CEIL_MOD_EXPR:
2166     case FLOOR_MOD_EXPR:
2167     case ROUND_MOD_EXPR:
2168       return 13;
2169
2170     case TRUTH_NOT_EXPR:
2171     case BIT_NOT_EXPR:
2172     case POSTINCREMENT_EXPR:
2173     case POSTDECREMENT_EXPR:
2174     case PREINCREMENT_EXPR:
2175     case PREDECREMENT_EXPR:
2176     case NEGATE_EXPR:
2177     case ALIGN_INDIRECT_REF:
2178     case MISALIGNED_INDIRECT_REF:
2179     case INDIRECT_REF:
2180     case ADDR_EXPR:
2181     case FLOAT_EXPR:
2182     case NOP_EXPR:
2183     case CONVERT_EXPR:
2184     case FIX_TRUNC_EXPR:
2185     case FIX_CEIL_EXPR:
2186     case FIX_FLOOR_EXPR:
2187     case FIX_ROUND_EXPR:
2188     case TARGET_EXPR:
2189       return 14;
2190
2191     case CALL_EXPR:
2192     case ARRAY_REF:
2193     case ARRAY_RANGE_REF:
2194     case COMPONENT_REF:
2195       return 15;
2196
2197       /* Special expressions.  */
2198     case MIN_EXPR:
2199     case MAX_EXPR:
2200     case ABS_EXPR:
2201     case REALPART_EXPR:
2202     case IMAGPART_EXPR:
2203     case REDUC_MAX_EXPR:
2204     case REDUC_MIN_EXPR:
2205     case REDUC_PLUS_EXPR:
2206     case VEC_LSHIFT_EXPR:
2207     case VEC_RSHIFT_EXPR:
2208       return 16;
2209
2210     case SAVE_EXPR:
2211     case NON_LVALUE_EXPR:
2212       return op_prio (TREE_OPERAND (op, 0));
2213
2214     default:
2215       /* Return an arbitrarily high precedence to avoid surrounding single
2216          VAR_DECLs in ()s.  */
2217       return 9999;
2218     }
2219 }
2220
2221
2222 /* Return the symbol associated with operator OP.  */
2223
2224 static const char *
2225 op_symbol_1 (enum tree_code code)
2226 {
2227   switch (code)
2228     {
2229     case MODIFY_EXPR:
2230       return "=";
2231
2232     case TRUTH_OR_EXPR:
2233     case TRUTH_ORIF_EXPR:
2234       return "||";
2235
2236     case TRUTH_AND_EXPR:
2237     case TRUTH_ANDIF_EXPR:
2238       return "&&";
2239
2240     case BIT_IOR_EXPR:
2241       return "|";
2242
2243     case TRUTH_XOR_EXPR:
2244     case BIT_XOR_EXPR:
2245       return "^";
2246
2247     case ADDR_EXPR:
2248     case BIT_AND_EXPR:
2249       return "&";
2250
2251     case ORDERED_EXPR:
2252       return "ord";
2253     case UNORDERED_EXPR:
2254       return "unord";
2255
2256     case EQ_EXPR:
2257       return "==";
2258     case UNEQ_EXPR:
2259       return "u==";
2260
2261     case NE_EXPR:
2262       return "!=";
2263
2264     case LT_EXPR:
2265       return "<";
2266     case UNLT_EXPR:
2267       return "u<";
2268
2269     case LE_EXPR:
2270       return "<=";
2271     case UNLE_EXPR:
2272       return "u<=";
2273
2274     case GT_EXPR:
2275       return ">";
2276     case UNGT_EXPR:
2277       return "u>";
2278
2279     case GE_EXPR:
2280       return ">=";
2281     case UNGE_EXPR:
2282       return "u>=";
2283
2284     case LTGT_EXPR:
2285       return "<>";
2286
2287     case LSHIFT_EXPR:
2288       return "<<";
2289
2290     case RSHIFT_EXPR:
2291       return ">>";
2292
2293     case LROTATE_EXPR:
2294       return "r<<";
2295
2296     case RROTATE_EXPR:
2297       return "r>>";
2298
2299     case VEC_LSHIFT_EXPR:
2300       return "v<<";
2301
2302     case VEC_RSHIFT_EXPR:
2303       return "v>>";
2304  
2305     case PLUS_EXPR:
2306       return "+";
2307
2308     case REDUC_PLUS_EXPR:
2309       return "r+";
2310
2311     case WIDEN_SUM_EXPR:
2312       return "w+";
2313
2314     case WIDEN_MULT_EXPR:
2315       return "w*";
2316
2317     case NEGATE_EXPR:
2318     case MINUS_EXPR:
2319       return "-";
2320
2321     case BIT_NOT_EXPR:
2322       return "~";
2323
2324     case TRUTH_NOT_EXPR:
2325       return "!";
2326
2327     case MULT_EXPR:
2328     case INDIRECT_REF:
2329       return "*";
2330
2331     case ALIGN_INDIRECT_REF:
2332       return "A*";
2333
2334     case MISALIGNED_INDIRECT_REF:
2335       return "M*";
2336
2337     case TRUNC_DIV_EXPR:
2338     case RDIV_EXPR:
2339       return "/";
2340
2341     case CEIL_DIV_EXPR:
2342       return "/[cl]";
2343
2344     case FLOOR_DIV_EXPR:
2345       return "/[fl]";
2346
2347     case ROUND_DIV_EXPR:
2348       return "/[rd]";
2349
2350     case EXACT_DIV_EXPR:
2351       return "/[ex]";
2352
2353     case TRUNC_MOD_EXPR:
2354       return "%";
2355
2356     case CEIL_MOD_EXPR:
2357       return "%[cl]";
2358
2359     case FLOOR_MOD_EXPR:
2360       return "%[fl]";
2361
2362     case ROUND_MOD_EXPR:
2363       return "%[rd]";
2364
2365     case PREDECREMENT_EXPR:
2366       return " --";
2367
2368     case PREINCREMENT_EXPR:
2369       return " ++";
2370
2371     case POSTDECREMENT_EXPR:
2372       return "-- ";
2373
2374     case POSTINCREMENT_EXPR:
2375       return "++ ";
2376
2377     case MAX_EXPR:
2378       return "max";
2379
2380     case MIN_EXPR:
2381       return "min";
2382
2383     default:
2384       return "<<< ??? >>>";
2385     }
2386 }
2387
2388 static const char *
2389 op_symbol (tree op)
2390 {
2391   return op_symbol_1 (TREE_CODE (op));
2392 }
2393
2394 /* Prints the name of a CALL_EXPR.  */
2395
2396 static void
2397 print_call_name (pretty_printer *buffer, tree node)
2398 {
2399   tree op0;
2400
2401   gcc_assert (TREE_CODE (node) == CALL_EXPR);
2402
2403   op0 = TREE_OPERAND (node, 0);
2404
2405   if (TREE_CODE (op0) == NON_LVALUE_EXPR)
2406     op0 = TREE_OPERAND (op0, 0);
2407
2408   switch (TREE_CODE (op0))
2409     {
2410     case VAR_DECL:
2411     case PARM_DECL:
2412       dump_function_name (buffer, op0);
2413       break;
2414
2415     case ADDR_EXPR:
2416     case INDIRECT_REF:
2417     case NOP_EXPR:
2418       dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
2419       break;
2420
2421     case COND_EXPR:
2422       pp_string (buffer, "(");
2423       dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
2424       pp_string (buffer, ") ? ");
2425       dump_generic_node (buffer, TREE_OPERAND (op0, 1), 0, 0, false);
2426       pp_string (buffer, " : ");
2427       dump_generic_node (buffer, TREE_OPERAND (op0, 2), 0, 0, false);
2428       break;
2429
2430     case COMPONENT_REF:
2431       /* The function is a pointer contained in a structure.  */
2432       if (TREE_CODE (TREE_OPERAND (op0, 0)) == INDIRECT_REF ||
2433           TREE_CODE (TREE_OPERAND (op0, 0)) == VAR_DECL)
2434         dump_function_name (buffer, TREE_OPERAND (op0, 1));
2435       else
2436         dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
2437       /* else
2438          We can have several levels of structures and a function
2439          pointer inside.  This is not implemented yet...  */
2440       /*                  NIY;*/
2441       break;
2442
2443     case ARRAY_REF:
2444       if (TREE_CODE (TREE_OPERAND (op0, 0)) == VAR_DECL)
2445         dump_function_name (buffer, TREE_OPERAND (op0, 0));
2446       else
2447         dump_generic_node (buffer, op0, 0, 0, false);
2448       break;
2449
2450     case SSA_NAME:
2451     case OBJ_TYPE_REF:
2452       dump_generic_node (buffer, op0, 0, 0, false);
2453       break;
2454
2455     default:
2456       NIY;
2457     }
2458 }
2459
2460 /* Parses the string STR and replaces new-lines by '\n', tabs by '\t', ...  */
2461
2462 static void
2463 pretty_print_string (pretty_printer *buffer, const char *str)
2464 {
2465   if (str == NULL)
2466     return;
2467
2468   while (*str)
2469     {
2470       switch (str[0])
2471         {
2472         case '\b':
2473           pp_string (buffer, "\\b");
2474           break;
2475
2476         case '\f':
2477           pp_string (buffer, "\\f");
2478           break;
2479
2480         case '\n':
2481           pp_string (buffer, "\\n");
2482           break;
2483
2484         case '\r':
2485           pp_string (buffer, "\\r");
2486           break;
2487
2488         case '\t':
2489           pp_string (buffer, "\\t");
2490           break;
2491
2492         case '\v':
2493           pp_string (buffer, "\\v");
2494           break;
2495
2496         case '\\':
2497           pp_string (buffer, "\\\\");
2498           break;
2499
2500         case '\"':
2501           pp_string (buffer, "\\\"");
2502           break;
2503
2504         case '\'':
2505           pp_string (buffer, "\\'");
2506           break;
2507
2508         case '\0':
2509           pp_string (buffer, "\\0");
2510           break;
2511
2512         case '\1':
2513           pp_string (buffer, "\\1");
2514           break;
2515
2516         case '\2':
2517           pp_string (buffer, "\\2");
2518           break;
2519
2520         case '\3':
2521           pp_string (buffer, "\\3");
2522           break;
2523
2524         case '\4':
2525           pp_string (buffer, "\\4");
2526           break;
2527
2528         case '\5':
2529           pp_string (buffer, "\\5");
2530           break;
2531
2532         case '\6':
2533           pp_string (buffer, "\\6");
2534           break;
2535
2536         case '\7':
2537           pp_string (buffer, "\\7");
2538           break;
2539
2540         default:
2541           pp_character (buffer, str[0]);
2542           break;
2543         }
2544       str++;
2545     }
2546 }
2547
2548 static void
2549 maybe_init_pretty_print (FILE *file)
2550 {
2551   if (!initialized)
2552     {
2553       pp_construct (&buffer, /* prefix */NULL, /* line-width */0);
2554       pp_needs_newline (&buffer) = true;
2555       initialized = 1;
2556     }
2557
2558   buffer.buffer->stream = file;
2559 }
2560
2561 static void
2562 newline_and_indent (pretty_printer *buffer, int spc)
2563 {
2564   pp_newline (buffer);
2565   INDENT (spc);
2566 }
2567
2568 static void
2569 dump_vops (pretty_printer *buffer, tree stmt, int spc, int flags)
2570 {
2571   tree use;
2572   use_operand_p use_p;
2573   def_operand_p def_p;
2574   use_operand_p kill_p;
2575   ssa_op_iter iter;
2576
2577   if (!ssa_operands_active ())
2578     return;
2579
2580   FOR_EACH_SSA_MAYDEF_OPERAND (def_p, use_p, stmt, iter)
2581     {
2582       pp_string (buffer, "#   ");
2583       dump_generic_node (buffer, DEF_FROM_PTR (def_p),
2584                          spc + 2, flags, false);
2585       pp_string (buffer, " = V_MAY_DEF <");
2586       dump_generic_node (buffer, USE_FROM_PTR (use_p),
2587                          spc + 2, flags, false);
2588       pp_string (buffer, ">;");
2589       newline_and_indent (buffer, spc);
2590     }
2591
2592   FOR_EACH_SSA_MUSTDEF_OPERAND (def_p, kill_p, stmt, iter)
2593     {
2594       pp_string (buffer, "#   ");
2595       dump_generic_node (buffer, DEF_FROM_PTR (def_p),
2596                          spc + 2, flags, false);
2597       pp_string (buffer, " = V_MUST_DEF <");
2598       dump_generic_node (buffer, USE_FROM_PTR (kill_p),
2599                          spc + 2, flags, false);
2600       pp_string (buffer, ">;");
2601       newline_and_indent (buffer, spc);
2602     }
2603
2604   FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_VUSE)
2605     {
2606       pp_string (buffer, "#   VUSE <");
2607       dump_generic_node (buffer, use, spc + 2, flags, false);
2608       pp_string (buffer, ">;");
2609       newline_and_indent (buffer, spc);
2610     }
2611 }
2612
2613 /* Dumps basic block BB to FILE with details described by FLAGS and
2614    indented by INDENT spaces.  */
2615
2616 void
2617 dump_generic_bb (FILE *file, basic_block bb, int indent, int flags)
2618 {
2619   maybe_init_pretty_print (file);
2620   dump_generic_bb_buff (&buffer, bb, indent, flags);
2621   pp_flush (&buffer);
2622 }
2623
2624 /* Dumps header of basic block BB to buffer BUFFER indented by INDENT
2625    spaces and details described by flags.  */
2626
2627 static void
2628 dump_bb_header (pretty_printer *buffer, basic_block bb, int indent, int flags)
2629 {
2630   edge e;
2631   tree stmt;
2632   edge_iterator ei;
2633
2634   if (flags & TDF_BLOCKS)
2635     {
2636       INDENT (indent);
2637       pp_string (buffer, "# BLOCK ");
2638       pp_decimal_int (buffer, bb->index);
2639       if (bb->frequency)
2640         {
2641           pp_string (buffer, " freq:");
2642           pp_decimal_int (buffer, bb->frequency);
2643         }
2644       if (bb->count)
2645         {
2646           pp_string (buffer, " count:");
2647           pp_widest_integer (buffer, bb->count);
2648         }
2649
2650       if (flags & TDF_LINENO)
2651         {
2652           block_stmt_iterator bsi;
2653
2654           for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
2655             if (get_lineno (bsi_stmt (bsi)) != -1)
2656               {
2657                 pp_string (buffer, ", starting at line ");
2658                 pp_decimal_int (buffer, get_lineno (bsi_stmt (bsi)));
2659                 break;
2660               }
2661         }
2662       newline_and_indent (buffer, indent);
2663
2664       pp_string (buffer, "# PRED:");
2665       pp_write_text_to_stream (buffer);
2666       FOR_EACH_EDGE (e, ei, bb->preds)
2667         if (flags & TDF_SLIM)
2668           {
2669             pp_string (buffer, " ");
2670             if (e->src == ENTRY_BLOCK_PTR)
2671               pp_string (buffer, "ENTRY");
2672             else
2673               pp_decimal_int (buffer, e->src->index);
2674           }
2675         else
2676           dump_edge_info (buffer->buffer->stream, e, 0);
2677       pp_newline (buffer);
2678     }
2679   else
2680     {
2681       stmt = first_stmt (bb);
2682       if (!stmt || TREE_CODE (stmt) != LABEL_EXPR)
2683         {
2684           INDENT (indent - 2);
2685           pp_string (buffer, "<bb ");
2686           pp_decimal_int (buffer, bb->index);
2687           pp_string (buffer, ">:");
2688           pp_newline (buffer);
2689         }
2690     }
2691   pp_write_text_to_stream (buffer);
2692   check_bb_profile (bb, buffer->buffer->stream);
2693 }
2694
2695 /* Dumps end of basic block BB to buffer BUFFER indented by INDENT
2696    spaces.  */
2697
2698 static void
2699 dump_bb_end (pretty_printer *buffer, basic_block bb, int indent, int flags)
2700 {
2701   edge e;
2702   edge_iterator ei;
2703
2704   INDENT (indent);
2705   pp_string (buffer, "# SUCC:");
2706   pp_write_text_to_stream (buffer);
2707   FOR_EACH_EDGE (e, ei, bb->succs)
2708     if (flags & TDF_SLIM)
2709       {
2710         pp_string (buffer, " ");
2711         if (e->dest == EXIT_BLOCK_PTR)
2712           pp_string (buffer, "EXIT");
2713         else
2714           pp_decimal_int (buffer, e->dest->index);
2715       }
2716     else
2717       dump_edge_info (buffer->buffer->stream, e, 1);
2718   pp_newline (buffer);
2719 }
2720
2721 /* Dumps phi nodes of basic block BB to buffer BUFFER with details described by
2722    FLAGS indented by INDENT spaces.  */
2723
2724 static void
2725 dump_phi_nodes (pretty_printer *buffer, basic_block bb, int indent, int flags)
2726 {
2727   tree phi = phi_nodes (bb);
2728   if (!phi)
2729     return;
2730
2731   for (; phi; phi = PHI_CHAIN (phi))
2732     {
2733       if (is_gimple_reg (PHI_RESULT (phi)) || (flags & TDF_VOPS))
2734         {
2735           INDENT (indent);
2736           pp_string (buffer, "# ");
2737           dump_generic_node (buffer, phi, indent, flags, false);
2738           pp_newline (buffer);
2739         }
2740     }
2741 }
2742
2743 /* Dump jump to basic block BB that is represented implicitly in the cfg
2744    to BUFFER.  */
2745
2746 static void
2747 pp_cfg_jump (pretty_printer *buffer, basic_block bb)
2748 {
2749   tree stmt;
2750
2751   stmt = first_stmt (bb);
2752
2753   pp_string (buffer, "goto <bb ");
2754   pp_decimal_int (buffer, bb->index);
2755   pp_string (buffer, ">");
2756   if (stmt && TREE_CODE (stmt) == LABEL_EXPR)
2757     {
2758       pp_string (buffer, " (");
2759       dump_generic_node (buffer, LABEL_EXPR_LABEL (stmt), 0, 0, false);
2760       pp_string (buffer, ")");
2761     }
2762   pp_semicolon (buffer);
2763 }
2764
2765 /* Dump edges represented implicitly in basic block BB to BUFFER, indented
2766    by INDENT spaces, with details given by FLAGS.  */
2767
2768 static void
2769 dump_implicit_edges (pretty_printer *buffer, basic_block bb, int indent,
2770                      int flags)
2771 {
2772   edge e;
2773   edge_iterator ei;
2774
2775   /* If there is a fallthru edge, we may need to add an artificial goto to the
2776      dump.  */
2777   FOR_EACH_EDGE (e, ei, bb->succs)
2778     if (e->flags & EDGE_FALLTHRU)
2779       break;
2780   if (e && e->dest != bb->next_bb)
2781     {
2782       INDENT (indent);
2783
2784       if ((flags & TDF_LINENO)
2785 #ifdef USE_MAPPED_LOCATION
2786           && e->goto_locus != UNKNOWN_LOCATION
2787 #else
2788           && e->goto_locus
2789 #endif
2790           )
2791         {
2792           expanded_location goto_xloc;
2793 #ifdef USE_MAPPED_LOCATION
2794           goto_xloc = expand_location (e->goto_locus);
2795 #else
2796           goto_xloc = *e->goto_locus;
2797 #endif
2798           pp_character (buffer, '[');
2799           if (goto_xloc.file)
2800             {
2801               pp_string (buffer, goto_xloc.file);
2802               pp_string (buffer, " : ");
2803             }
2804           pp_decimal_int (buffer, goto_xloc.line);
2805           pp_string (buffer, "] ");
2806         }
2807
2808       pp_cfg_jump (buffer, e->dest);
2809       pp_newline (buffer);
2810     }
2811 }
2812
2813 /* Dumps basic block BB to buffer BUFFER with details described by FLAGS and
2814    indented by INDENT spaces.  */
2815
2816 static void
2817 dump_generic_bb_buff (pretty_printer *buffer, basic_block bb,
2818                       int indent, int flags)
2819 {
2820   block_stmt_iterator bsi;
2821   tree stmt;
2822   int label_indent = indent - 2;
2823
2824   if (label_indent < 0)
2825     label_indent = 0;
2826
2827   dump_bb_header (buffer, bb, indent, flags);
2828
2829   dump_phi_nodes (buffer, bb, indent, flags);
2830
2831   for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
2832     {
2833       int curr_indent;
2834
2835       stmt = bsi_stmt (bsi);
2836
2837       curr_indent = TREE_CODE (stmt) == LABEL_EXPR ? label_indent : indent;
2838
2839       INDENT (curr_indent);
2840       dump_generic_node (buffer, stmt, curr_indent, flags, true);
2841       pp_newline (buffer);
2842     }
2843
2844   dump_implicit_edges (buffer, bb, indent, flags);
2845
2846   if (flags & TDF_BLOCKS)
2847     dump_bb_end (buffer, bb, indent, flags);
2848 }