OSDN Git Service

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