OSDN Git Service

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