OSDN Git Service

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