OSDN Git Service

2006-11-08 Dorit Nuzman <dorit@il.ibm.com>
[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             static char format[10]; /* "%x%09999x\0" */
736             if (!format[0])
737               sprintf (format, "0x%%" HOST_WIDE_INT_PRINT "x"
738                        "%%0%d" HOST_WIDE_INT_PRINT "x",
739                        HOST_BITS_PER_WIDE_INT / 4);
740             sprintf (pp_buffer (buffer)->digit_buffer, format,
741                      TREE_INT_CST_HIGH (val),
742                      TREE_INT_CST_LOW (val));
743             pp_string (buffer, pp_buffer (buffer)->digit_buffer);
744           }
745         }
746       else
747         pp_wide_integer (buffer, TREE_INT_CST_LOW (node));
748       break;
749
750     case REAL_CST:
751       /* Code copied from print_node.  */
752       {
753         REAL_VALUE_TYPE d;
754         if (TREE_OVERFLOW (node))
755           pp_string (buffer, " overflow");
756
757 #if !defined(REAL_IS_NOT_DOUBLE) || defined(REAL_ARITHMETIC)
758         d = TREE_REAL_CST (node);
759         if (REAL_VALUE_ISINF (d))
760           pp_string (buffer, " Inf");
761         else if (REAL_VALUE_ISNAN (d))
762           pp_string (buffer, " Nan");
763         else
764           {
765             char string[100];
766             real_to_decimal (string, &d, sizeof (string), 0, 1);
767             pp_string (buffer, string);
768           }
769 #else
770         {
771           HOST_WIDE_INT i;
772           unsigned char *p = (unsigned char *) &TREE_REAL_CST (node);
773           pp_string (buffer, "0x");
774           for (i = 0; i < sizeof TREE_REAL_CST (node); i++)
775             output_formatted_integer (buffer, "%02x", *p++);
776         }
777 #endif
778         break;
779       }
780
781     case COMPLEX_CST:
782       pp_string (buffer, "__complex__ (");
783       dump_generic_node (buffer, TREE_REALPART (node), spc, flags, false);
784       pp_string (buffer, ", ");
785       dump_generic_node (buffer, TREE_IMAGPART (node), spc, flags, false);
786       pp_string (buffer, ")");
787       break;
788
789     case STRING_CST:
790       pp_string (buffer, "\"");
791       pretty_print_string (buffer, TREE_STRING_POINTER (node));
792       pp_string (buffer, "\"");
793       break;
794
795     case VECTOR_CST:
796       {
797         tree elt;
798         pp_string (buffer, "{ ");
799         for (elt = TREE_VECTOR_CST_ELTS (node); elt; elt = TREE_CHAIN (elt))
800           {
801             dump_generic_node (buffer, TREE_VALUE (elt), spc, flags, false);
802             if (TREE_CHAIN (elt))
803               pp_string (buffer, ", ");
804           }
805         pp_string (buffer, " }");
806       }
807       break;
808
809     case FUNCTION_TYPE:
810       break;
811
812     case FUNCTION_DECL:
813     case CONST_DECL:
814       dump_decl_name (buffer, node, flags);
815       break;
816
817     case LABEL_DECL:
818       if (DECL_NAME (node))
819         dump_decl_name (buffer, node, flags);
820       else if (LABEL_DECL_UID (node) != -1)
821         pp_printf (buffer, "<L" HOST_WIDE_INT_PRINT_DEC ">",
822                    LABEL_DECL_UID (node));
823       else
824         pp_printf (buffer, "<D%u>", DECL_UID (node));
825       break;
826
827     case TYPE_DECL:
828       if (DECL_IS_BUILTIN (node))
829         {
830           /* Don't print the declaration of built-in types.  */
831           break;
832         }
833       if (DECL_NAME (node))
834         dump_decl_name (buffer, node, flags);
835       else
836         {
837           if ((TREE_CODE (TREE_TYPE (node)) == RECORD_TYPE
838                || TREE_CODE (TREE_TYPE (node)) == UNION_TYPE)
839               && TYPE_METHODS (TREE_TYPE (node)))
840             {
841               /* The type is a c++ class: all structures have at least
842                  4 methods.  */
843               pp_string (buffer, "class ");
844               dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
845             }
846           else
847             {
848               pp_string (buffer,
849                          (TREE_CODE (TREE_TYPE (node)) == UNION_TYPE
850                           ? "union" : "struct "));
851               dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
852             }
853         }
854       break;
855
856     case SYMBOL_MEMORY_TAG:
857     case NAME_MEMORY_TAG:
858     case STRUCT_FIELD_TAG:
859     case VAR_DECL:
860     case PARM_DECL:
861     case FIELD_DECL:
862     case NAMESPACE_DECL:
863       dump_decl_name (buffer, node, flags);
864       break;
865
866     case RESULT_DECL:
867       pp_string (buffer, "<retval>");
868       break;
869
870     case COMPONENT_REF:
871       op0 = TREE_OPERAND (node, 0);
872       str = ".";
873       if (TREE_CODE (op0) == INDIRECT_REF)
874         {
875           op0 = TREE_OPERAND (op0, 0);
876           str = "->";
877         }
878       if (op_prio (op0) < op_prio (node))
879         pp_character (buffer, '(');
880       dump_generic_node (buffer, op0, spc, flags, false);
881       if (op_prio (op0) < op_prio (node))
882         pp_character (buffer, ')');
883       pp_string (buffer, str);
884       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
885
886       if (TREE_CODE (op0) != VALUE_HANDLE)
887         {
888           op0 = component_ref_field_offset (node);
889           if (op0 && TREE_CODE (op0) != INTEGER_CST)
890             {
891               pp_string (buffer, "{off: ");
892               dump_generic_node (buffer, op0, spc, flags, false);
893               pp_character (buffer, '}');
894             }
895         }
896       break;
897
898     case BIT_FIELD_REF:
899       pp_string (buffer, "BIT_FIELD_REF <");
900       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
901       pp_string (buffer, ", ");
902       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
903       pp_string (buffer, ", ");
904       dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
905       pp_string (buffer, ">");
906       break;
907
908     case ARRAY_REF:
909     case ARRAY_RANGE_REF:
910       op0 = TREE_OPERAND (node, 0);
911       if (op_prio (op0) < op_prio (node))
912         pp_character (buffer, '(');
913       dump_generic_node (buffer, op0, spc, flags, false);
914       if (op_prio (op0) < op_prio (node))
915         pp_character (buffer, ')');
916       pp_character (buffer, '[');
917       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
918       if (TREE_CODE (node) == ARRAY_RANGE_REF)
919         pp_string (buffer, " ...");
920       pp_character (buffer, ']');
921
922       op0 = array_ref_low_bound (node);
923       op1 = array_ref_element_size (node);
924
925       if (!integer_zerop (op0)
926           || (TYPE_SIZE_UNIT (TREE_TYPE (node))
927               && !operand_equal_p (op1, TYPE_SIZE_UNIT (TREE_TYPE (node)), 0)))
928         {
929           pp_string (buffer, "{lb: ");
930           dump_generic_node (buffer, op0, spc, flags, false);
931           pp_string (buffer, " sz: ");
932           dump_generic_node (buffer, op1, spc, flags, false);
933           pp_character (buffer, '}');
934         }
935       break;
936
937     case CONSTRUCTOR:
938       {
939         unsigned HOST_WIDE_INT ix;
940         tree field, val;
941         bool is_struct_init = FALSE;
942         pp_character (buffer, '{');
943         if (TREE_CODE (TREE_TYPE (node)) == RECORD_TYPE
944             || TREE_CODE (TREE_TYPE (node)) == UNION_TYPE)
945           is_struct_init = TRUE;
946         FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (node), ix, field, val)
947           {
948             if (field && is_struct_init)
949               {
950                 pp_character (buffer, '.');
951                 dump_generic_node (buffer, field, spc, flags, false);
952                 pp_string (buffer, "=");
953               }
954             if (val && TREE_CODE (val) == ADDR_EXPR)
955               if (TREE_CODE (TREE_OPERAND (val, 0)) == FUNCTION_DECL)
956                 val = TREE_OPERAND (val, 0);
957             if (val && TREE_CODE (val) == FUNCTION_DECL)
958                 dump_decl_name (buffer, val, flags);
959             else
960                 dump_generic_node (buffer, val, spc, flags, false);
961             if (ix != VEC_length (constructor_elt, CONSTRUCTOR_ELTS (node)) - 1)
962               {
963                 pp_character (buffer, ',');
964                 pp_space (buffer);
965               }
966           }
967         pp_character (buffer, '}');
968       }
969       break;
970
971     case COMPOUND_EXPR:
972       {
973         tree *tp;
974         if (flags & TDF_SLIM)
975           {
976             pp_string (buffer, "<COMPOUND_EXPR>");
977             break;
978           }
979
980         dump_generic_node (buffer, TREE_OPERAND (node, 0),
981                            spc, flags, !(flags & TDF_SLIM));
982         if (flags & TDF_SLIM)
983           newline_and_indent (buffer, spc);
984         else
985           {
986             pp_character (buffer, ',');
987             pp_space (buffer);
988           }
989
990         for (tp = &TREE_OPERAND (node, 1);
991              TREE_CODE (*tp) == COMPOUND_EXPR;
992              tp = &TREE_OPERAND (*tp, 1))
993           {
994             dump_generic_node (buffer, TREE_OPERAND (*tp, 0),
995                                spc, flags, !(flags & TDF_SLIM));
996             if (flags & TDF_SLIM)
997               newline_and_indent (buffer, spc);
998             else
999               {
1000                 pp_character (buffer, ',');
1001                 pp_space (buffer);
1002               }
1003           }
1004
1005         dump_generic_node (buffer, *tp, spc, flags, !(flags & TDF_SLIM));
1006       }
1007       break;
1008
1009     case STATEMENT_LIST:
1010       {
1011         tree_stmt_iterator si;
1012         bool first = true;
1013
1014         if (flags & TDF_SLIM)
1015           {
1016             pp_string (buffer, "<STATEMENT_LIST>");
1017             break;
1018           }
1019
1020         for (si = tsi_start (node); !tsi_end_p (si); tsi_next (&si))
1021           {
1022             if (!first)
1023               newline_and_indent (buffer, spc);
1024             else
1025               first = false;
1026             dump_generic_node (buffer, tsi_stmt (si), spc, flags, true);
1027           }
1028       }
1029       break;
1030
1031     case MODIFY_EXPR:
1032     case INIT_EXPR:
1033       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1034       pp_space (buffer);
1035       pp_character (buffer, '=');
1036       pp_space (buffer);
1037       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1038       break;
1039
1040     case TARGET_EXPR:
1041       pp_string (buffer, "TARGET_EXPR <");
1042       dump_generic_node (buffer, TARGET_EXPR_SLOT (node), spc, flags, false);
1043       pp_character (buffer, ',');
1044       pp_space (buffer);
1045       dump_generic_node (buffer, TARGET_EXPR_INITIAL (node), spc, flags, false);
1046       pp_character (buffer, '>');
1047       break;
1048
1049     case DECL_EXPR:
1050       print_declaration (buffer, DECL_EXPR_DECL (node), spc, flags);
1051       is_stmt = false;
1052       break;
1053
1054     case COND_EXPR:
1055       if (TREE_TYPE (node) == NULL || TREE_TYPE (node) == void_type_node)
1056         {
1057           pp_string (buffer, "if (");
1058           dump_generic_node (buffer, COND_EXPR_COND (node), spc, flags, false);
1059           pp_character (buffer, ')');
1060           /* The lowered cond_exprs should always be printed in full.  */
1061           if (COND_EXPR_THEN (node)
1062               && (IS_EMPTY_STMT (COND_EXPR_THEN (node))
1063                   || TREE_CODE (COND_EXPR_THEN (node)) == GOTO_EXPR)
1064               && COND_EXPR_ELSE (node)
1065               && (IS_EMPTY_STMT (COND_EXPR_ELSE (node))
1066                   || TREE_CODE (COND_EXPR_ELSE (node)) == GOTO_EXPR))
1067             {
1068               pp_space (buffer);
1069               dump_generic_node (buffer, COND_EXPR_THEN (node), 0, flags, true);
1070               pp_string (buffer, " else ");
1071               dump_generic_node (buffer, COND_EXPR_ELSE (node), 0, flags, true);
1072             }
1073           else if (!(flags & TDF_SLIM))
1074             {
1075               /* Output COND_EXPR_THEN.  */
1076               if (COND_EXPR_THEN (node))
1077                 {
1078                   newline_and_indent (buffer, spc+2);
1079                   pp_character (buffer, '{');
1080                   newline_and_indent (buffer, spc+4);
1081                   dump_generic_node (buffer, COND_EXPR_THEN (node), spc+4,
1082                                      flags, true);
1083                   newline_and_indent (buffer, spc+2);
1084                   pp_character (buffer, '}');
1085                 }
1086
1087               /* Output COND_EXPR_ELSE.  */
1088               if (COND_EXPR_ELSE (node))
1089                 {
1090                   newline_and_indent (buffer, spc);
1091                   pp_string (buffer, "else");
1092                   newline_and_indent (buffer, spc+2);
1093                   pp_character (buffer, '{');
1094                   newline_and_indent (buffer, spc+4);
1095                   dump_generic_node (buffer, COND_EXPR_ELSE (node), spc+4,
1096                                      flags, true);
1097                   newline_and_indent (buffer, spc+2);
1098                   pp_character (buffer, '}');
1099                 }
1100             }
1101           is_expr = false;
1102         }
1103       else
1104         {
1105           dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1106           pp_space (buffer);
1107           pp_character (buffer, '?');
1108           pp_space (buffer);
1109           dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1110           pp_space (buffer);
1111           pp_character (buffer, ':');
1112           pp_space (buffer);
1113           dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
1114         }
1115       break;
1116
1117     case BIND_EXPR:
1118       pp_character (buffer, '{');
1119       if (!(flags & TDF_SLIM))
1120         {
1121           if (BIND_EXPR_VARS (node))
1122             {
1123               pp_newline (buffer);
1124
1125               for (op0 = BIND_EXPR_VARS (node); op0; op0 = TREE_CHAIN (op0))
1126                 {
1127                   print_declaration (buffer, op0, spc+2, flags);
1128                   pp_newline (buffer);
1129                 }
1130             }
1131
1132           newline_and_indent (buffer, spc+2);
1133           dump_generic_node (buffer, BIND_EXPR_BODY (node), spc+2, flags, true);
1134           newline_and_indent (buffer, spc);
1135           pp_character (buffer, '}');
1136         }
1137       is_expr = false;
1138       break;
1139
1140     case CALL_EXPR:
1141       print_call_name (buffer, node);
1142
1143       /* Print parameters.  */
1144       pp_space (buffer);
1145       pp_character (buffer, '(');
1146       op1 = TREE_OPERAND (node, 1);
1147       if (op1)
1148         dump_generic_node (buffer, op1, spc, flags, false);
1149       pp_character (buffer, ')');
1150
1151       op1 = TREE_OPERAND (node, 2);
1152       if (op1)
1153         {
1154           pp_string (buffer, " [static-chain: ");
1155           dump_generic_node (buffer, op1, spc, flags, false);
1156           pp_character (buffer, ']');
1157         }
1158
1159       if (CALL_EXPR_RETURN_SLOT_OPT (node))
1160         pp_string (buffer, " [return slot optimization]");
1161       if (CALL_EXPR_TAILCALL (node))
1162         pp_string (buffer, " [tail call]");
1163       break;
1164
1165     case WITH_CLEANUP_EXPR:
1166       NIY;
1167       break;
1168
1169     case CLEANUP_POINT_EXPR:
1170       pp_string (buffer, "<<cleanup_point ");
1171       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1172       pp_string (buffer, ">>");
1173       break;
1174
1175     case PLACEHOLDER_EXPR:
1176       pp_string (buffer, "<PLACEHOLDER_EXPR ");
1177       dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
1178       pp_character (buffer, '>');
1179       break;
1180
1181       /* Binary arithmetic and logic expressions.  */
1182     case WIDEN_SUM_EXPR:
1183     case WIDEN_MULT_EXPR:
1184     case MULT_EXPR:
1185     case PLUS_EXPR:
1186     case MINUS_EXPR:
1187     case TRUNC_DIV_EXPR:
1188     case CEIL_DIV_EXPR:
1189     case FLOOR_DIV_EXPR:
1190     case ROUND_DIV_EXPR:
1191     case TRUNC_MOD_EXPR:
1192     case CEIL_MOD_EXPR:
1193     case FLOOR_MOD_EXPR:
1194     case ROUND_MOD_EXPR:
1195     case RDIV_EXPR:
1196     case EXACT_DIV_EXPR:
1197     case LSHIFT_EXPR:
1198     case RSHIFT_EXPR:
1199     case LROTATE_EXPR:
1200     case RROTATE_EXPR:
1201     case VEC_LSHIFT_EXPR:
1202     case VEC_RSHIFT_EXPR:
1203     case BIT_IOR_EXPR:
1204     case BIT_XOR_EXPR:
1205     case BIT_AND_EXPR:
1206     case TRUTH_ANDIF_EXPR:
1207     case TRUTH_ORIF_EXPR:
1208     case TRUTH_AND_EXPR:
1209     case TRUTH_OR_EXPR:
1210     case TRUTH_XOR_EXPR:
1211     case LT_EXPR:
1212     case LE_EXPR:
1213     case GT_EXPR:
1214     case GE_EXPR:
1215     case EQ_EXPR:
1216     case NE_EXPR:
1217     case UNLT_EXPR:
1218     case UNLE_EXPR:
1219     case UNGT_EXPR:
1220     case UNGE_EXPR:
1221     case UNEQ_EXPR:
1222     case LTGT_EXPR:
1223     case ORDERED_EXPR:
1224     case UNORDERED_EXPR:
1225       {
1226         const char *op = op_symbol (node);
1227         op0 = TREE_OPERAND (node, 0);
1228         op1 = TREE_OPERAND (node, 1);
1229
1230         /* When the operands are expressions with less priority,
1231            keep semantics of the tree representation.  */
1232         if (op_prio (op0) < op_prio (node))
1233           {
1234             pp_character (buffer, '(');
1235             dump_generic_node (buffer, op0, spc, flags, false);
1236             pp_character (buffer, ')');
1237           }
1238         else
1239           dump_generic_node (buffer, op0, spc, flags, false);
1240
1241         pp_space (buffer);
1242         pp_string (buffer, op);
1243         pp_space (buffer);
1244
1245         /* When the operands are expressions with less priority,
1246            keep semantics of the tree representation.  */
1247         if (op_prio (op1) < op_prio (node))
1248           {
1249             pp_character (buffer, '(');
1250             dump_generic_node (buffer, op1, spc, flags, false);
1251             pp_character (buffer, ')');
1252           }
1253         else
1254           dump_generic_node (buffer, op1, spc, flags, false);
1255       }
1256       break;
1257
1258       /* Unary arithmetic and logic expressions.  */
1259     case NEGATE_EXPR:
1260     case BIT_NOT_EXPR:
1261     case TRUTH_NOT_EXPR:
1262     case ADDR_EXPR:
1263     case PREDECREMENT_EXPR:
1264     case PREINCREMENT_EXPR:
1265     case ALIGN_INDIRECT_REF:
1266     case MISALIGNED_INDIRECT_REF:
1267     case INDIRECT_REF:
1268       if (TREE_CODE (node) == ADDR_EXPR
1269           && (TREE_CODE (TREE_OPERAND (node, 0)) == STRING_CST
1270               || TREE_CODE (TREE_OPERAND (node, 0)) == FUNCTION_DECL))
1271         ;       /* Do not output '&' for strings and function pointers.  */
1272       else
1273         pp_string (buffer, op_symbol (node));
1274
1275       if (op_prio (TREE_OPERAND (node, 0)) < op_prio (node))
1276         {
1277           pp_character (buffer, '(');
1278           dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1279           pp_character (buffer, ')');
1280         }
1281       else
1282         dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1283
1284       if (TREE_CODE (node) == MISALIGNED_INDIRECT_REF)
1285         {
1286           pp_string (buffer, "{misalignment: ");
1287           dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1288           pp_character (buffer, '}');
1289         }
1290       break;
1291
1292     case POSTDECREMENT_EXPR:
1293     case POSTINCREMENT_EXPR:
1294       if (op_prio (TREE_OPERAND (node, 0)) < op_prio (node))
1295         {
1296           pp_character (buffer, '(');
1297           dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1298           pp_character (buffer, ')');
1299         }
1300       else
1301         dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1302       pp_string (buffer, op_symbol (node));
1303       break;
1304
1305     case MIN_EXPR:
1306       pp_string (buffer, "MIN_EXPR <");
1307       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1308       pp_string (buffer, ", ");
1309       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1310       pp_character (buffer, '>');
1311       break;
1312
1313     case MAX_EXPR:
1314       pp_string (buffer, "MAX_EXPR <");
1315       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1316       pp_string (buffer, ", ");
1317       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1318       pp_character (buffer, '>');
1319       break;
1320
1321     case ABS_EXPR:
1322       pp_string (buffer, "ABS_EXPR <");
1323       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1324       pp_character (buffer, '>');
1325       break;
1326
1327     case RANGE_EXPR:
1328       NIY;
1329       break;
1330
1331     case FIX_TRUNC_EXPR:
1332     case FIX_CEIL_EXPR:
1333     case FIX_FLOOR_EXPR:
1334     case FIX_ROUND_EXPR:
1335     case FLOAT_EXPR:
1336     case CONVERT_EXPR:
1337     case NOP_EXPR:
1338       type = TREE_TYPE (node);
1339       op0 = TREE_OPERAND (node, 0);
1340       if (type != TREE_TYPE (op0))
1341         {
1342           pp_character (buffer, '(');
1343           dump_generic_node (buffer, type, spc, flags, false);
1344           pp_string (buffer, ") ");
1345         }
1346       if (op_prio (op0) < op_prio (node))
1347         pp_character (buffer, '(');
1348       dump_generic_node (buffer, op0, spc, flags, false);
1349       if (op_prio (op0) < op_prio (node))
1350         pp_character (buffer, ')');
1351       break;
1352
1353     case VIEW_CONVERT_EXPR:
1354       pp_string (buffer, "VIEW_CONVERT_EXPR<");
1355       dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
1356       pp_string (buffer, ">(");
1357       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1358       pp_character (buffer, ')');
1359       break;
1360
1361     case NON_LVALUE_EXPR:
1362       pp_string (buffer, "NON_LVALUE_EXPR <");
1363       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1364       pp_character (buffer, '>');
1365       break;
1366
1367     case SAVE_EXPR:
1368       pp_string (buffer, "SAVE_EXPR <");
1369       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1370       pp_character (buffer, '>');
1371       break;
1372
1373     case COMPLEX_EXPR:
1374       pp_string (buffer, "COMPLEX_EXPR <");
1375       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1376       pp_string (buffer, ", ");
1377       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1378       pp_string (buffer, ">");
1379       break;
1380
1381     case CONJ_EXPR:
1382       pp_string (buffer, "CONJ_EXPR <");
1383       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1384       pp_string (buffer, ">");
1385       break;
1386
1387     case REALPART_EXPR:
1388       pp_string (buffer, "REALPART_EXPR <");
1389       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1390       pp_string (buffer, ">");
1391       break;
1392
1393     case IMAGPART_EXPR:
1394       pp_string (buffer, "IMAGPART_EXPR <");
1395       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1396       pp_string (buffer, ">");
1397       break;
1398
1399     case VA_ARG_EXPR:
1400       pp_string (buffer, "VA_ARG_EXPR <");
1401       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1402       pp_string (buffer, ">");
1403       break;
1404
1405     case TRY_FINALLY_EXPR:
1406     case TRY_CATCH_EXPR:
1407       pp_string (buffer, "try");
1408       newline_and_indent (buffer, spc+2);
1409       pp_string (buffer, "{");
1410       newline_and_indent (buffer, spc+4);
1411       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc+4, flags, true);
1412       newline_and_indent (buffer, spc+2);
1413       pp_string (buffer, "}");
1414       newline_and_indent (buffer, spc);
1415       pp_string (buffer,
1416                          (TREE_CODE (node) == TRY_CATCH_EXPR) ? "catch" : "finally");
1417       newline_and_indent (buffer, spc+2);
1418       pp_string (buffer, "{");
1419       newline_and_indent (buffer, spc+4);
1420       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc+4, flags, true);
1421       newline_and_indent (buffer, spc+2);
1422       pp_string (buffer, "}");
1423       is_expr = false;
1424       break;
1425
1426     case CATCH_EXPR:
1427       pp_string (buffer, "catch (");
1428       dump_generic_node (buffer, CATCH_TYPES (node), spc+2, flags, false);
1429       pp_string (buffer, ")");
1430       newline_and_indent (buffer, spc+2);
1431       pp_string (buffer, "{");
1432       newline_and_indent (buffer, spc+4);
1433       dump_generic_node (buffer, CATCH_BODY (node), spc+4, flags, true);
1434       newline_and_indent (buffer, spc+2);
1435       pp_string (buffer, "}");
1436       is_expr = false;
1437       break;
1438
1439     case EH_FILTER_EXPR:
1440       pp_string (buffer, "<<<eh_filter (");
1441       dump_generic_node (buffer, EH_FILTER_TYPES (node), spc+2, flags, false);
1442       pp_string (buffer, ")>>>");
1443       newline_and_indent (buffer, spc+2);
1444       pp_string (buffer, "{");
1445       newline_and_indent (buffer, spc+4);
1446       dump_generic_node (buffer, EH_FILTER_FAILURE (node), spc+4, flags, true);
1447       newline_and_indent (buffer, spc+2);
1448       pp_string (buffer, "}");
1449       is_expr = false;
1450       break;
1451
1452     case LABEL_EXPR:
1453       op0 = TREE_OPERAND (node, 0);
1454       /* If this is for break or continue, don't bother printing it.  */
1455       if (DECL_NAME (op0))
1456         {
1457           const char *name = IDENTIFIER_POINTER (DECL_NAME (op0));
1458           if (strcmp (name, "break") == 0
1459               || strcmp (name, "continue") == 0)
1460             break;
1461         }
1462       dump_generic_node (buffer, op0, spc, flags, false);
1463       pp_character (buffer, ':');
1464       if (DECL_NONLOCAL (op0))
1465         pp_string (buffer, " [non-local]");
1466       break;
1467
1468     case EXC_PTR_EXPR:
1469       pp_string (buffer, "<<<exception object>>>");
1470       break;
1471
1472     case FILTER_EXPR:
1473       pp_string (buffer, "<<<filter object>>>");
1474       break;
1475
1476     case LOOP_EXPR:
1477       pp_string (buffer, "while (1)");
1478       if (!(flags & TDF_SLIM))
1479         {
1480           newline_and_indent (buffer, spc+2);
1481           pp_character (buffer, '{');
1482           newline_and_indent (buffer, spc+4);
1483           dump_generic_node (buffer, LOOP_EXPR_BODY (node), spc+4, flags, true);
1484           newline_and_indent (buffer, spc+2);
1485           pp_character (buffer, '}');
1486         }
1487       is_expr = false;
1488       break;
1489
1490     case RETURN_EXPR:
1491       pp_string (buffer, "return");
1492       op0 = TREE_OPERAND (node, 0);
1493       if (op0)
1494         {
1495           pp_space (buffer);
1496           if (TREE_CODE (op0) == MODIFY_EXPR)
1497             dump_generic_node (buffer, TREE_OPERAND (op0, 1), spc, flags, false);
1498           else
1499             dump_generic_node (buffer, op0, spc, flags, false);
1500         }
1501       break;
1502
1503     case EXIT_EXPR:
1504       pp_string (buffer, "if (");
1505       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1506       pp_string (buffer, ") break");
1507       break;
1508
1509     case SWITCH_EXPR:
1510       pp_string (buffer, "switch (");
1511       dump_generic_node (buffer, SWITCH_COND (node), spc, flags, false);
1512       pp_character (buffer, ')');
1513       if (!(flags & TDF_SLIM))
1514         {
1515           newline_and_indent (buffer, spc+2);
1516           pp_character (buffer, '{');
1517           if (SWITCH_BODY (node))
1518             {
1519               newline_and_indent (buffer, spc+4);
1520               dump_generic_node (buffer, SWITCH_BODY (node), spc+4, flags,
1521                                  true);
1522             }
1523           else
1524             {
1525               tree vec = SWITCH_LABELS (node);
1526               size_t i, n = TREE_VEC_LENGTH (vec);
1527               for (i = 0; i < n; ++i)
1528                 {
1529                   tree elt = TREE_VEC_ELT (vec, i);
1530                   newline_and_indent (buffer, spc+4);
1531                   if (elt)
1532                     {
1533                       dump_generic_node (buffer, elt, spc+4, flags, false);
1534                       pp_string (buffer, " goto ");
1535                       dump_generic_node (buffer, CASE_LABEL (elt), spc+4,
1536                                          flags, true);
1537                       pp_semicolon (buffer);
1538                     }
1539                   else
1540                     pp_string (buffer, "case ???: goto ???;");
1541                 }
1542             }
1543           newline_and_indent (buffer, spc+2);
1544           pp_character (buffer, '}');
1545         }
1546       is_expr = false;
1547       break;
1548
1549     case GOTO_EXPR:
1550       op0 = GOTO_DESTINATION (node);
1551       if (TREE_CODE (op0) != SSA_NAME && DECL_P (op0) && DECL_NAME (op0))
1552         {
1553           const char *name = IDENTIFIER_POINTER (DECL_NAME (op0));
1554           if (strcmp (name, "break") == 0
1555               || strcmp (name, "continue") == 0)
1556             {
1557               pp_string (buffer, name);
1558               break;
1559             }
1560         }
1561       pp_string (buffer, "goto ");
1562       dump_generic_node (buffer, op0, spc, flags, false);
1563       break;
1564
1565     case RESX_EXPR:
1566       pp_string (buffer, "resx ");
1567       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1568       break;
1569
1570     case ASM_EXPR:
1571       pp_string (buffer, "__asm__");
1572       if (ASM_VOLATILE_P (node))
1573         pp_string (buffer, " __volatile__");
1574       pp_character (buffer, '(');
1575       dump_generic_node (buffer, ASM_STRING (node), spc, flags, false);
1576       pp_character (buffer, ':');
1577       dump_generic_node (buffer, ASM_OUTPUTS (node), spc, flags, false);
1578       pp_character (buffer, ':');
1579       dump_generic_node (buffer, ASM_INPUTS (node), spc, flags, false);
1580       if (ASM_CLOBBERS (node))
1581         {
1582           pp_character (buffer, ':');
1583           dump_generic_node (buffer, ASM_CLOBBERS (node), spc, flags, false);
1584         }
1585       pp_string (buffer, ")");
1586       break;
1587
1588     case CASE_LABEL_EXPR:
1589       if (CASE_LOW (node) && CASE_HIGH (node))
1590         {
1591           pp_string (buffer, "case ");
1592           dump_generic_node (buffer, CASE_LOW (node), spc, flags, false);
1593           pp_string (buffer, " ... ");
1594           dump_generic_node (buffer, CASE_HIGH (node), spc, flags, false);
1595         }
1596       else if (CASE_LOW (node))
1597         {
1598           pp_string (buffer, "case ");
1599           dump_generic_node (buffer, CASE_LOW (node), spc, flags, false);
1600         }
1601       else
1602         pp_string (buffer, "default ");
1603       pp_character (buffer, ':');
1604       break;
1605
1606     case OBJ_TYPE_REF:
1607       pp_string (buffer, "OBJ_TYPE_REF(");
1608       dump_generic_node (buffer, OBJ_TYPE_REF_EXPR (node), spc, flags, false);
1609       pp_character (buffer, ';');
1610       dump_generic_node (buffer, OBJ_TYPE_REF_OBJECT (node), spc, flags, false);
1611       pp_character (buffer, '-');
1612       pp_character (buffer, '>');
1613       dump_generic_node (buffer, OBJ_TYPE_REF_TOKEN (node), spc, flags, false);
1614       pp_character (buffer, ')');
1615       break;
1616
1617     case PHI_NODE:
1618       {
1619         int i;
1620
1621         dump_generic_node (buffer, PHI_RESULT (node), spc, flags, false);
1622         pp_string (buffer, " = PHI <");
1623         for (i = 0; i < PHI_NUM_ARGS (node); i++)
1624           {
1625             dump_generic_node (buffer, PHI_ARG_DEF (node, i), spc, flags, false);
1626             pp_string (buffer, "(");
1627             pp_decimal_int (buffer, PHI_ARG_EDGE (node, i)->src->index);
1628             pp_string (buffer, ")");
1629             if (i < PHI_NUM_ARGS (node) - 1)
1630               pp_string (buffer, ", ");
1631           }
1632         pp_string (buffer, ">;");
1633       }
1634       break;
1635
1636     case SSA_NAME:
1637       dump_generic_node (buffer, SSA_NAME_VAR (node), spc, flags, false);
1638       pp_string (buffer, "_");
1639       pp_decimal_int (buffer, SSA_NAME_VERSION (node));
1640       if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (node))
1641         pp_string (buffer, "(ab)");
1642       break;
1643
1644     case WITH_SIZE_EXPR:
1645       pp_string (buffer, "WITH_SIZE_EXPR <");
1646       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1647       pp_string (buffer, ", ");
1648       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1649       pp_string (buffer, ">");
1650       break;
1651
1652     case VALUE_HANDLE:
1653       pp_printf (buffer, "VH.%d", VALUE_HANDLE_ID (node));
1654       break;
1655
1656     case ASSERT_EXPR:
1657       pp_string (buffer, "ASSERT_EXPR <");
1658       dump_generic_node (buffer, ASSERT_EXPR_VAR (node), spc, flags, false);
1659       pp_string (buffer, ", ");
1660       dump_generic_node (buffer, ASSERT_EXPR_COND (node), spc, flags, false);
1661       pp_string (buffer, ">");
1662       break;
1663
1664     case SCEV_KNOWN:
1665       pp_string (buffer, "scev_known");
1666       break;
1667
1668     case SCEV_NOT_KNOWN:
1669       pp_string (buffer, "scev_not_known");
1670       break;
1671
1672     case POLYNOMIAL_CHREC:
1673       pp_string (buffer, "{");
1674       dump_generic_node (buffer, CHREC_LEFT (node), spc, flags, false);
1675       pp_string (buffer, ", +, ");
1676       dump_generic_node (buffer, CHREC_RIGHT (node), spc, flags, false);
1677       pp_string (buffer, "}_");
1678       dump_generic_node (buffer, CHREC_VAR (node), spc, flags, false);
1679       is_stmt = false;
1680       break;
1681
1682     case REALIGN_LOAD_EXPR:
1683       pp_string (buffer, "REALIGN_LOAD <");
1684       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1685       pp_string (buffer, ", ");
1686       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1687       pp_string (buffer, ", ");
1688       dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
1689       pp_string (buffer, ">");
1690       break;
1691       
1692     case VEC_COND_EXPR:
1693       pp_string (buffer, " VEC_COND_EXPR < ");
1694       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1695       pp_string (buffer, " , ");
1696       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1697       pp_string (buffer, " , ");
1698       dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
1699       pp_string (buffer, " > ");
1700       break;
1701
1702     case DOT_PROD_EXPR:
1703       pp_string (buffer, " DOT_PROD_EXPR < ");
1704       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1705       pp_string (buffer, ", ");
1706       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1707       pp_string (buffer, ", ");
1708       dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
1709       pp_string (buffer, " > ");
1710       break;
1711
1712     case OMP_PARALLEL:
1713       pp_string (buffer, "#pragma omp parallel");
1714       dump_omp_clauses (buffer, OMP_PARALLEL_CLAUSES (node), spc, flags);
1715       if (OMP_PARALLEL_FN (node))
1716         {
1717           pp_string (buffer, " [child fn: ");
1718           dump_generic_node (buffer, OMP_PARALLEL_FN (node), spc, flags, false);
1719
1720           pp_string (buffer, " (");
1721
1722           if (OMP_PARALLEL_DATA_ARG (node))
1723             dump_generic_node (buffer, OMP_PARALLEL_DATA_ARG (node), spc, flags,
1724                                false);
1725           else
1726             pp_string (buffer, "???");
1727
1728           pp_string (buffer, ")]");
1729         }
1730
1731     dump_omp_body:
1732       if (!(flags & TDF_SLIM) && OMP_BODY (node))
1733         {
1734           newline_and_indent (buffer, spc + 2);
1735           pp_character (buffer, '{');
1736           newline_and_indent (buffer, spc + 4);
1737           dump_generic_node (buffer, OMP_BODY (node), spc + 4, flags, false);
1738           newline_and_indent (buffer, spc + 2);
1739           pp_character (buffer, '}');
1740         }
1741       is_expr = false;
1742       break;
1743
1744     case OMP_FOR:
1745       pp_string (buffer, "#pragma omp for");
1746       dump_omp_clauses (buffer, OMP_FOR_CLAUSES (node), spc, flags);
1747
1748       if (!(flags & TDF_SLIM))
1749         {
1750           if (OMP_FOR_PRE_BODY (node))
1751             {
1752               newline_and_indent (buffer, spc + 2);
1753               pp_character (buffer, '{');
1754               spc += 4;
1755               newline_and_indent (buffer, spc);
1756               dump_generic_node (buffer, OMP_FOR_PRE_BODY (node),
1757                   spc, flags, false);
1758             }
1759           newline_and_indent (buffer, spc);
1760           pp_string (buffer, "for (");
1761           dump_generic_node (buffer, OMP_FOR_INIT (node), spc, flags, false);
1762           pp_string (buffer, "; ");
1763           dump_generic_node (buffer, OMP_FOR_COND (node), spc, flags, false);
1764           pp_string (buffer, "; ");
1765           dump_generic_node (buffer, OMP_FOR_INCR (node), spc, flags, false);
1766           pp_string (buffer, ")");
1767           if (OMP_FOR_BODY (node))
1768             {
1769               newline_and_indent (buffer, spc + 2);
1770               pp_character (buffer, '{');
1771               newline_and_indent (buffer, spc + 4);
1772               dump_generic_node (buffer, OMP_FOR_BODY (node), spc + 4, flags,
1773                   false);
1774               newline_and_indent (buffer, spc + 2);
1775               pp_character (buffer, '}');
1776             }
1777           if (OMP_FOR_PRE_BODY (node))
1778             {
1779               spc -= 4;
1780               newline_and_indent (buffer, spc + 2);
1781               pp_character (buffer, '}');
1782             }
1783         }
1784       is_expr = false;
1785       break;
1786
1787     case OMP_SECTIONS:
1788       pp_string (buffer, "#pragma omp sections");
1789       dump_omp_clauses (buffer, OMP_SECTIONS_CLAUSES (node), spc, flags);
1790       goto dump_omp_body;
1791
1792     case OMP_SECTION:
1793       pp_string (buffer, "#pragma omp section");
1794       goto dump_omp_body;
1795  
1796     case OMP_MASTER:
1797       pp_string (buffer, "#pragma omp master");
1798       goto dump_omp_body;
1799
1800     case OMP_ORDERED:
1801       pp_string (buffer, "#pragma omp ordered");
1802       goto dump_omp_body;
1803
1804     case OMP_CRITICAL:
1805       pp_string (buffer, "#pragma omp critical");
1806       if (OMP_CRITICAL_NAME (node))
1807         {
1808           pp_space (buffer);
1809           pp_character (buffer, '(');
1810           dump_generic_node (buffer, OMP_CRITICAL_NAME (node), spc,
1811                              flags, false);
1812           pp_character (buffer, ')');
1813         }
1814       goto dump_omp_body;
1815
1816     case OMP_ATOMIC:
1817       pp_string (buffer, "#pragma omp atomic");
1818       newline_and_indent (buffer, spc + 2);
1819       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1820       pp_space (buffer);
1821       pp_character (buffer, '=');
1822       pp_space (buffer);
1823       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1824       break;
1825
1826     case OMP_SINGLE:
1827       pp_string (buffer, "#pragma omp single");
1828       dump_omp_clauses (buffer, OMP_SINGLE_CLAUSES (node), spc, flags);
1829       goto dump_omp_body;
1830
1831     case OMP_RETURN:
1832       pp_string (buffer, "OMP_RETURN");
1833       if (OMP_RETURN_NOWAIT (node))
1834         pp_string (buffer, " [nowait]");
1835       is_expr = false;
1836       break;
1837
1838     case OMP_CONTINUE:
1839       pp_string (buffer, "OMP_CONTINUE");
1840       is_expr = false;
1841       break;
1842
1843     case OMP_CLAUSE:
1844       dump_omp_clause (buffer, node, spc, flags);
1845       is_expr = false;
1846       break;
1847
1848     case REDUC_MAX_EXPR:
1849       pp_string (buffer, " REDUC_MAX_EXPR < ");
1850       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1851       pp_string (buffer, " > ");
1852       break;
1853
1854     case REDUC_MIN_EXPR:
1855       pp_string (buffer, " REDUC_MIN_EXPR < ");
1856       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1857       pp_string (buffer, " > ");
1858       break;
1859
1860     case REDUC_PLUS_EXPR:
1861       pp_string (buffer, " REDUC_PLUS_EXPR < ");
1862       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1863       pp_string (buffer, " > ");
1864       break;
1865
1866     case VEC_WIDEN_MULT_HI_EXPR:
1867       pp_string (buffer, " VEC_WIDEN_MULT_HI_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_WIDEN_MULT_LO_EXPR:
1875       pp_string (buffer, " VEC_WIDEN_MULT_LO_EXPR < ");
1876       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1877       pp_string (buffer, ", ");
1878       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1879       pp_string (buffer, " > ");
1880       break;
1881
1882     case VEC_UNPACK_HI_EXPR:
1883       pp_string (buffer, " VEC_UNPACK_HI_EXPR < ");
1884       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1885       pp_string (buffer, " > ");
1886       break;
1887
1888     case VEC_UNPACK_LO_EXPR:
1889       pp_string (buffer, " VEC_UNPACK_LO_EXPR < ");
1890       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1891       pp_string (buffer, " > ");
1892       break;
1893
1894     case VEC_PACK_MOD_EXPR:
1895       pp_string (buffer, " VEC_PACK_MOD_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 VEC_PACK_SAT_EXPR:
1903       pp_string (buffer, " VEC_PACK_SAT_EXPR < ");
1904       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1905       pp_string (buffer, ", ");
1906       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1907       pp_string (buffer, " > ");
1908       break;
1909                                                                                 
1910     case BLOCK:
1911       {
1912         tree t;
1913         pp_string (buffer, "BLOCK");
1914
1915         if (BLOCK_ABSTRACT (node))
1916           pp_string (buffer, " [abstract]");
1917
1918         if (TREE_ASM_WRITTEN (node))
1919           pp_string (buffer, " [written]");
1920
1921         newline_and_indent (buffer, spc + 2);
1922
1923         if (BLOCK_SUPERCONTEXT (node))
1924           {
1925             pp_string (buffer, "SUPERCONTEXT: ");
1926             if (TREE_CODE (BLOCK_SUPERCONTEXT (node)) == BLOCK)
1927               pp_printf (buffer, "BLOCK %p",
1928                          (void *)BLOCK_SUPERCONTEXT (node));
1929             else
1930               dump_generic_node (buffer, BLOCK_SUPERCONTEXT (node), 0, flags,
1931                                  false);
1932             newline_and_indent (buffer, spc + 2);
1933           }
1934
1935         if (BLOCK_SUBBLOCKS (node))
1936           {
1937             pp_string (buffer, "SUBBLOCKS: ");
1938             for (t = BLOCK_SUBBLOCKS (node); t; t = BLOCK_CHAIN (t))
1939               pp_printf (buffer, "%p ", (void *)t);
1940             newline_and_indent (buffer, spc + 2);
1941           }
1942
1943         if (BLOCK_VARS (node))
1944           {
1945             pp_string (buffer, "VARS: ");
1946             for (t = BLOCK_VARS (node); t; t = TREE_CHAIN (t))
1947               {
1948                 dump_generic_node (buffer, t, 0, flags, false);
1949                 pp_string (buffer, " ");
1950               }
1951             newline_and_indent (buffer, spc + 2);
1952           }
1953
1954         if (BLOCK_ABSTRACT_ORIGIN (node))
1955           {
1956             pp_string (buffer, "ABSTRACT_ORIGIN: ");
1957             if (TREE_CODE (BLOCK_ABSTRACT_ORIGIN (node)) == BLOCK)
1958               pp_printf (buffer, "BLOCK %p",
1959                          (void *)BLOCK_ABSTRACT_ORIGIN (node));
1960             else
1961               dump_generic_node (buffer, BLOCK_ABSTRACT_ORIGIN (node), 0, flags,
1962                                  false);
1963             newline_and_indent (buffer, spc + 2);
1964           }
1965       }
1966     break;
1967
1968     default:
1969       NIY;
1970     }
1971
1972   if (is_stmt && is_expr)
1973     pp_semicolon (buffer);
1974   pp_write_text_to_stream (buffer);
1975
1976   return spc;
1977 }
1978
1979 /* Print the declaration of a variable.  */
1980
1981 static void
1982 print_declaration (pretty_printer *buffer, tree t, int spc, int flags)
1983 {
1984   INDENT (spc);
1985
1986   if (TREE_CODE (t) == TYPE_DECL)
1987     pp_string (buffer, "typedef ");
1988
1989   if (CODE_CONTAINS_STRUCT (TREE_CODE (t), TS_DECL_WRTL) && DECL_REGISTER (t))
1990     pp_string (buffer, "register ");
1991
1992   if (TREE_PUBLIC (t) && DECL_EXTERNAL (t))
1993     pp_string (buffer, "extern ");
1994   else if (TREE_STATIC (t))
1995     pp_string (buffer, "static ");
1996
1997   /* Print the type and name.  */
1998   if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
1999     {
2000       tree tmp;
2001
2002       /* Print array's type.  */
2003       tmp = TREE_TYPE (t);
2004       while (TREE_CODE (TREE_TYPE (tmp)) == ARRAY_TYPE)
2005         tmp = TREE_TYPE (tmp);
2006       dump_generic_node (buffer, TREE_TYPE (tmp), spc, flags, false);
2007
2008       /* Print variable's name.  */
2009       pp_space (buffer);
2010       dump_generic_node (buffer, t, spc, flags, false);
2011
2012       /* Print the dimensions.  */
2013       tmp = TREE_TYPE (t);
2014       while (TREE_CODE (tmp) == ARRAY_TYPE)
2015         {
2016           dump_array_domain (buffer, TYPE_DOMAIN (tmp), spc, flags);
2017           tmp = TREE_TYPE (tmp);
2018         }
2019     }
2020   else if (TREE_CODE (t) == FUNCTION_DECL)
2021     {
2022       dump_generic_node (buffer, TREE_TYPE (TREE_TYPE (t)), spc, flags, false);
2023       pp_space (buffer);
2024       dump_decl_name (buffer, t, flags);
2025       dump_function_declaration (buffer, TREE_TYPE (t), spc, flags);
2026     }
2027   else
2028     {
2029       /* Print type declaration.  */
2030       dump_generic_node (buffer, TREE_TYPE (t), spc, flags, false);
2031
2032       /* Print variable's name.  */
2033       pp_space (buffer);
2034       dump_generic_node (buffer, t, spc, flags, false);
2035     }
2036
2037   if (TREE_CODE (t) == VAR_DECL && DECL_HARD_REGISTER (t))
2038     {
2039       pp_string (buffer, " __asm__ ");
2040       pp_character (buffer, '(');
2041       dump_generic_node (buffer, DECL_ASSEMBLER_NAME (t), spc, flags, false);
2042       pp_character (buffer, ')');
2043     }
2044
2045   /* The initial value of a function serves to determine wether the function
2046      is declared or defined.  So the following does not apply to function
2047      nodes.  */
2048   if (TREE_CODE (t) != FUNCTION_DECL)
2049     {
2050       /* Print the initial value.  */
2051       if (DECL_INITIAL (t))
2052         {
2053           pp_space (buffer);
2054           pp_character (buffer, '=');
2055           pp_space (buffer);
2056           dump_generic_node (buffer, DECL_INITIAL (t), spc, flags, false);
2057         }
2058     }
2059
2060   if (TREE_CODE (t) == VAR_DECL && DECL_HAS_VALUE_EXPR_P (t))
2061     {
2062       pp_string (buffer, " [value-expr: ");
2063       dump_generic_node (buffer, DECL_VALUE_EXPR (t), spc, flags, false);
2064       pp_character (buffer, ']');
2065     }
2066
2067   pp_character (buffer, ';');
2068 }
2069
2070
2071 /* Prints a structure: name, fields, and methods.
2072    FIXME: Still incomplete.  */
2073
2074 static void
2075 print_struct_decl (pretty_printer *buffer, tree node, int spc, int flags)
2076 {
2077   /* Print the name of the structure.  */
2078   if (TYPE_NAME (node))
2079     {
2080       INDENT (spc);
2081       if (TREE_CODE (node) == RECORD_TYPE)
2082         pp_string (buffer, "struct ");
2083       else if ((TREE_CODE (node) == UNION_TYPE
2084                 || TREE_CODE (node) == QUAL_UNION_TYPE))
2085         pp_string (buffer, "union ");
2086
2087       dump_generic_node (buffer, TYPE_NAME (node), spc, 0, false);
2088     }
2089
2090   /* Print the contents of the structure.  */
2091   pp_newline (buffer);
2092   INDENT (spc);
2093   pp_character (buffer, '{');
2094   pp_newline (buffer);
2095
2096   /* Print the fields of the structure.  */
2097   {
2098     tree tmp;
2099     tmp = TYPE_FIELDS (node);
2100     while (tmp)
2101       {
2102         /* Avoid to print recursively the structure.  */
2103         /* FIXME : Not implemented correctly...,
2104            what about the case when we have a cycle in the contain graph? ...
2105            Maybe this could be solved by looking at the scope in which the
2106            structure was declared.  */
2107         if (TREE_TYPE (tmp) != node
2108             || (TREE_CODE (TREE_TYPE (tmp)) == POINTER_TYPE
2109                 && TREE_TYPE (TREE_TYPE (tmp)) != node))
2110           {
2111             print_declaration (buffer, tmp, spc+2, flags);
2112             pp_newline (buffer);
2113           }
2114         tmp = TREE_CHAIN (tmp);
2115       }
2116   }
2117   INDENT (spc);
2118   pp_character (buffer, '}');
2119 }
2120
2121 /* Return the priority of the operator OP.
2122
2123    From lowest to highest precedence with either left-to-right (L-R)
2124    or right-to-left (R-L) associativity]:
2125
2126      1  [L-R] ,
2127      2  [R-L] = += -= *= /= %= &= ^= |= <<= >>=
2128      3  [R-L] ?:
2129      4  [L-R] ||
2130      5  [L-R] &&
2131      6  [L-R] |
2132      7  [L-R] ^
2133      8  [L-R] &
2134      9  [L-R] == !=
2135     10  [L-R] < <= > >=
2136     11  [L-R] << >>
2137     12  [L-R] + -
2138     13  [L-R] * / %
2139     14  [R-L] ! ~ ++ -- + - * & (type) sizeof
2140     15  [L-R] fn() [] -> .
2141
2142    unary +, - and * have higher precedence than the corresponding binary
2143    operators.  */
2144
2145 static int
2146 op_prio (tree op)
2147 {
2148   if (op == NULL)
2149     return 9999;
2150
2151   switch (TREE_CODE (op))
2152     {
2153     case TREE_LIST:
2154     case COMPOUND_EXPR:
2155     case BIND_EXPR:
2156       return 1;
2157
2158     case MODIFY_EXPR:
2159     case INIT_EXPR:
2160       return 2;
2161
2162     case COND_EXPR:
2163       return 3;
2164
2165     case TRUTH_OR_EXPR:
2166     case TRUTH_ORIF_EXPR:
2167       return 4;
2168
2169     case TRUTH_AND_EXPR:
2170     case TRUTH_ANDIF_EXPR:
2171       return 5;
2172
2173     case BIT_IOR_EXPR:
2174       return 6;
2175
2176     case BIT_XOR_EXPR:
2177     case TRUTH_XOR_EXPR:
2178       return 7;
2179
2180     case BIT_AND_EXPR:
2181       return 8;
2182
2183     case EQ_EXPR:
2184     case NE_EXPR:
2185       return 9;
2186
2187     case UNLT_EXPR:
2188     case UNLE_EXPR:
2189     case UNGT_EXPR:
2190     case UNGE_EXPR:
2191     case UNEQ_EXPR:
2192     case LTGT_EXPR:
2193     case ORDERED_EXPR:
2194     case UNORDERED_EXPR:
2195     case LT_EXPR:
2196     case LE_EXPR:
2197     case GT_EXPR:
2198     case GE_EXPR:
2199       return 10;
2200
2201     case LSHIFT_EXPR:
2202     case RSHIFT_EXPR:
2203     case LROTATE_EXPR:
2204     case RROTATE_EXPR:
2205       return 11;
2206
2207     case WIDEN_SUM_EXPR:
2208     case PLUS_EXPR:
2209     case MINUS_EXPR:
2210       return 12;
2211
2212     case VEC_WIDEN_MULT_HI_EXPR:
2213     case VEC_WIDEN_MULT_LO_EXPR:
2214     case WIDEN_MULT_EXPR:
2215     case DOT_PROD_EXPR:
2216     case MULT_EXPR:
2217     case TRUNC_DIV_EXPR:
2218     case CEIL_DIV_EXPR:
2219     case FLOOR_DIV_EXPR:
2220     case ROUND_DIV_EXPR:
2221     case RDIV_EXPR:
2222     case EXACT_DIV_EXPR:
2223     case TRUNC_MOD_EXPR:
2224     case CEIL_MOD_EXPR:
2225     case FLOOR_MOD_EXPR:
2226     case ROUND_MOD_EXPR:
2227       return 13;
2228
2229     case TRUTH_NOT_EXPR:
2230     case BIT_NOT_EXPR:
2231     case POSTINCREMENT_EXPR:
2232     case POSTDECREMENT_EXPR:
2233     case PREINCREMENT_EXPR:
2234     case PREDECREMENT_EXPR:
2235     case NEGATE_EXPR:
2236     case ALIGN_INDIRECT_REF:
2237     case MISALIGNED_INDIRECT_REF:
2238     case INDIRECT_REF:
2239     case ADDR_EXPR:
2240     case FLOAT_EXPR:
2241     case NOP_EXPR:
2242     case CONVERT_EXPR:
2243     case FIX_TRUNC_EXPR:
2244     case FIX_CEIL_EXPR:
2245     case FIX_FLOOR_EXPR:
2246     case FIX_ROUND_EXPR:
2247     case TARGET_EXPR:
2248       return 14;
2249
2250     case CALL_EXPR:
2251     case ARRAY_REF:
2252     case ARRAY_RANGE_REF:
2253     case COMPONENT_REF:
2254       return 15;
2255
2256       /* Special expressions.  */
2257     case MIN_EXPR:
2258     case MAX_EXPR:
2259     case ABS_EXPR:
2260     case REALPART_EXPR:
2261     case IMAGPART_EXPR:
2262     case REDUC_MAX_EXPR:
2263     case REDUC_MIN_EXPR:
2264     case REDUC_PLUS_EXPR:
2265     case VEC_LSHIFT_EXPR:
2266     case VEC_RSHIFT_EXPR:
2267     case VEC_UNPACK_HI_EXPR:
2268     case VEC_UNPACK_LO_EXPR:
2269     case VEC_PACK_MOD_EXPR:
2270     case VEC_PACK_SAT_EXPR:
2271       return 16;
2272
2273     case SAVE_EXPR:
2274     case NON_LVALUE_EXPR:
2275       return op_prio (TREE_OPERAND (op, 0));
2276
2277     default:
2278       /* Return an arbitrarily high precedence to avoid surrounding single
2279          VAR_DECLs in ()s.  */
2280       return 9999;
2281     }
2282 }
2283
2284
2285 /* Return the symbol associated with operator OP.  */
2286
2287 static const char *
2288 op_symbol_1 (enum tree_code code)
2289 {
2290   switch (code)
2291     {
2292     case MODIFY_EXPR:
2293       return "=";
2294
2295     case TRUTH_OR_EXPR:
2296     case TRUTH_ORIF_EXPR:
2297       return "||";
2298
2299     case TRUTH_AND_EXPR:
2300     case TRUTH_ANDIF_EXPR:
2301       return "&&";
2302
2303     case BIT_IOR_EXPR:
2304       return "|";
2305
2306     case TRUTH_XOR_EXPR:
2307     case BIT_XOR_EXPR:
2308       return "^";
2309
2310     case ADDR_EXPR:
2311     case BIT_AND_EXPR:
2312       return "&";
2313
2314     case ORDERED_EXPR:
2315       return "ord";
2316     case UNORDERED_EXPR:
2317       return "unord";
2318
2319     case EQ_EXPR:
2320       return "==";
2321     case UNEQ_EXPR:
2322       return "u==";
2323
2324     case NE_EXPR:
2325       return "!=";
2326
2327     case LT_EXPR:
2328       return "<";
2329     case UNLT_EXPR:
2330       return "u<";
2331
2332     case LE_EXPR:
2333       return "<=";
2334     case UNLE_EXPR:
2335       return "u<=";
2336
2337     case GT_EXPR:
2338       return ">";
2339     case UNGT_EXPR:
2340       return "u>";
2341
2342     case GE_EXPR:
2343       return ">=";
2344     case UNGE_EXPR:
2345       return "u>=";
2346
2347     case LTGT_EXPR:
2348       return "<>";
2349
2350     case LSHIFT_EXPR:
2351       return "<<";
2352
2353     case RSHIFT_EXPR:
2354       return ">>";
2355
2356     case LROTATE_EXPR:
2357       return "r<<";
2358
2359     case RROTATE_EXPR:
2360       return "r>>";
2361
2362     case VEC_LSHIFT_EXPR:
2363       return "v<<";
2364
2365     case VEC_RSHIFT_EXPR:
2366       return "v>>";
2367  
2368     case PLUS_EXPR:
2369       return "+";
2370
2371     case REDUC_PLUS_EXPR:
2372       return "r+";
2373
2374     case WIDEN_SUM_EXPR:
2375       return "w+";
2376
2377     case WIDEN_MULT_EXPR:
2378       return "w*";
2379
2380     case NEGATE_EXPR:
2381     case MINUS_EXPR:
2382       return "-";
2383
2384     case BIT_NOT_EXPR:
2385       return "~";
2386
2387     case TRUTH_NOT_EXPR:
2388       return "!";
2389
2390     case MULT_EXPR:
2391     case INDIRECT_REF:
2392       return "*";
2393
2394     case ALIGN_INDIRECT_REF:
2395       return "A*";
2396
2397     case MISALIGNED_INDIRECT_REF:
2398       return "M*";
2399
2400     case TRUNC_DIV_EXPR:
2401     case RDIV_EXPR:
2402       return "/";
2403
2404     case CEIL_DIV_EXPR:
2405       return "/[cl]";
2406
2407     case FLOOR_DIV_EXPR:
2408       return "/[fl]";
2409
2410     case ROUND_DIV_EXPR:
2411       return "/[rd]";
2412
2413     case EXACT_DIV_EXPR:
2414       return "/[ex]";
2415
2416     case TRUNC_MOD_EXPR:
2417       return "%";
2418
2419     case CEIL_MOD_EXPR:
2420       return "%[cl]";
2421
2422     case FLOOR_MOD_EXPR:
2423       return "%[fl]";
2424
2425     case ROUND_MOD_EXPR:
2426       return "%[rd]";
2427
2428     case PREDECREMENT_EXPR:
2429       return " --";
2430
2431     case PREINCREMENT_EXPR:
2432       return " ++";
2433
2434     case POSTDECREMENT_EXPR:
2435       return "-- ";
2436
2437     case POSTINCREMENT_EXPR:
2438       return "++ ";
2439
2440     case MAX_EXPR:
2441       return "max";
2442
2443     case MIN_EXPR:
2444       return "min";
2445
2446     default:
2447       return "<<< ??? >>>";
2448     }
2449 }
2450
2451 static const char *
2452 op_symbol (tree op)
2453 {
2454   return op_symbol_1 (TREE_CODE (op));
2455 }
2456
2457 /* Prints the name of a CALL_EXPR.  */
2458
2459 static void
2460 print_call_name (pretty_printer *buffer, tree node)
2461 {
2462   tree op0;
2463
2464   gcc_assert (TREE_CODE (node) == CALL_EXPR);
2465
2466   op0 = TREE_OPERAND (node, 0);
2467
2468   if (TREE_CODE (op0) == NON_LVALUE_EXPR)
2469     op0 = TREE_OPERAND (op0, 0);
2470
2471   switch (TREE_CODE (op0))
2472     {
2473     case VAR_DECL:
2474     case PARM_DECL:
2475       dump_function_name (buffer, op0);
2476       break;
2477
2478     case ADDR_EXPR:
2479     case INDIRECT_REF:
2480     case NOP_EXPR:
2481       dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
2482       break;
2483
2484     case COND_EXPR:
2485       pp_string (buffer, "(");
2486       dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
2487       pp_string (buffer, ") ? ");
2488       dump_generic_node (buffer, TREE_OPERAND (op0, 1), 0, 0, false);
2489       pp_string (buffer, " : ");
2490       dump_generic_node (buffer, TREE_OPERAND (op0, 2), 0, 0, false);
2491       break;
2492
2493     case COMPONENT_REF:
2494       /* The function is a pointer contained in a structure.  */
2495       if (TREE_CODE (TREE_OPERAND (op0, 0)) == INDIRECT_REF ||
2496           TREE_CODE (TREE_OPERAND (op0, 0)) == VAR_DECL)
2497         dump_function_name (buffer, TREE_OPERAND (op0, 1));
2498       else
2499         dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
2500       /* else
2501          We can have several levels of structures and a function
2502          pointer inside.  This is not implemented yet...  */
2503       /*                  NIY;*/
2504       break;
2505
2506     case ARRAY_REF:
2507       if (TREE_CODE (TREE_OPERAND (op0, 0)) == VAR_DECL)
2508         dump_function_name (buffer, TREE_OPERAND (op0, 0));
2509       else
2510         dump_generic_node (buffer, op0, 0, 0, false);
2511       break;
2512
2513     case SSA_NAME:
2514     case OBJ_TYPE_REF:
2515       dump_generic_node (buffer, op0, 0, 0, false);
2516       break;
2517
2518     default:
2519       NIY;
2520     }
2521 }
2522
2523 /* Parses the string STR and replaces new-lines by '\n', tabs by '\t', ...  */
2524
2525 static void
2526 pretty_print_string (pretty_printer *buffer, const char *str)
2527 {
2528   if (str == NULL)
2529     return;
2530
2531   while (*str)
2532     {
2533       switch (str[0])
2534         {
2535         case '\b':
2536           pp_string (buffer, "\\b");
2537           break;
2538
2539         case '\f':
2540           pp_string (buffer, "\\f");
2541           break;
2542
2543         case '\n':
2544           pp_string (buffer, "\\n");
2545           break;
2546
2547         case '\r':
2548           pp_string (buffer, "\\r");
2549           break;
2550
2551         case '\t':
2552           pp_string (buffer, "\\t");
2553           break;
2554
2555         case '\v':
2556           pp_string (buffer, "\\v");
2557           break;
2558
2559         case '\\':
2560           pp_string (buffer, "\\\\");
2561           break;
2562
2563         case '\"':
2564           pp_string (buffer, "\\\"");
2565           break;
2566
2567         case '\'':
2568           pp_string (buffer, "\\'");
2569           break;
2570
2571           /* No need to handle \0; the loop terminates on \0.  */
2572
2573         case '\1':
2574           pp_string (buffer, "\\1");
2575           break;
2576
2577         case '\2':
2578           pp_string (buffer, "\\2");
2579           break;
2580
2581         case '\3':
2582           pp_string (buffer, "\\3");
2583           break;
2584
2585         case '\4':
2586           pp_string (buffer, "\\4");
2587           break;
2588
2589         case '\5':
2590           pp_string (buffer, "\\5");
2591           break;
2592
2593         case '\6':
2594           pp_string (buffer, "\\6");
2595           break;
2596
2597         case '\7':
2598           pp_string (buffer, "\\7");
2599           break;
2600
2601         default:
2602           pp_character (buffer, str[0]);
2603           break;
2604         }
2605       str++;
2606     }
2607 }
2608
2609 static void
2610 maybe_init_pretty_print (FILE *file)
2611 {
2612   if (!initialized)
2613     {
2614       pp_construct (&buffer, /* prefix */NULL, /* line-width */0);
2615       pp_needs_newline (&buffer) = true;
2616       initialized = 1;
2617     }
2618
2619   buffer.buffer->stream = file;
2620 }
2621
2622 static void
2623 newline_and_indent (pretty_printer *buffer, int spc)
2624 {
2625   pp_newline (buffer);
2626   INDENT (spc);
2627 }
2628
2629 static void
2630 dump_vops (pretty_printer *buffer, tree stmt, int spc, int flags)
2631 {
2632   tree use;
2633   use_operand_p use_p;
2634   def_operand_p def_p;
2635   use_operand_p kill_p;
2636   ssa_op_iter iter;
2637
2638   if (!ssa_operands_active ())
2639     return;
2640
2641   FOR_EACH_SSA_MAYDEF_OPERAND (def_p, use_p, stmt, iter)
2642     {
2643       pp_string (buffer, "#   ");
2644       dump_generic_node (buffer, DEF_FROM_PTR (def_p),
2645                          spc + 2, flags, false);
2646       pp_string (buffer, " = V_MAY_DEF <");
2647       dump_generic_node (buffer, USE_FROM_PTR (use_p),
2648                          spc + 2, flags, false);
2649       pp_string (buffer, ">;");
2650       newline_and_indent (buffer, spc);
2651     }
2652
2653   FOR_EACH_SSA_MUSTDEF_OPERAND (def_p, kill_p, stmt, iter)
2654     {
2655       pp_string (buffer, "#   ");
2656       dump_generic_node (buffer, DEF_FROM_PTR (def_p),
2657                          spc + 2, flags, false);
2658       pp_string (buffer, " = V_MUST_DEF <");
2659       dump_generic_node (buffer, USE_FROM_PTR (kill_p),
2660                          spc + 2, flags, false);
2661       pp_string (buffer, ">;");
2662       newline_and_indent (buffer, spc);
2663     }
2664
2665   FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_VUSE)
2666     {
2667       pp_string (buffer, "#   VUSE <");
2668       dump_generic_node (buffer, use, spc + 2, flags, false);
2669       pp_string (buffer, ">;");
2670       newline_and_indent (buffer, spc);
2671     }
2672 }
2673
2674 /* Dumps basic block BB to FILE with details described by FLAGS and
2675    indented by INDENT spaces.  */
2676
2677 void
2678 dump_generic_bb (FILE *file, basic_block bb, int indent, int flags)
2679 {
2680   maybe_init_pretty_print (file);
2681   dump_generic_bb_buff (&buffer, bb, indent, flags);
2682   pp_flush (&buffer);
2683 }
2684
2685 /* Dumps header of basic block BB to buffer BUFFER indented by INDENT
2686    spaces and details described by flags.  */
2687
2688 static void
2689 dump_bb_header (pretty_printer *buffer, basic_block bb, int indent, int flags)
2690 {
2691   edge e;
2692   tree stmt;
2693   edge_iterator ei;
2694
2695   if (flags & TDF_BLOCKS)
2696     {
2697       INDENT (indent);
2698       pp_string (buffer, "# BLOCK ");
2699       pp_decimal_int (buffer, bb->index);
2700       if (bb->frequency)
2701         {
2702           pp_string (buffer, " freq:");
2703           pp_decimal_int (buffer, bb->frequency);
2704         }
2705       if (bb->count)
2706         {
2707           pp_string (buffer, " count:");
2708           pp_widest_integer (buffer, bb->count);
2709         }
2710
2711       if (flags & TDF_LINENO)
2712         {
2713           block_stmt_iterator bsi;
2714
2715           for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
2716             if (get_lineno (bsi_stmt (bsi)) != -1)
2717               {
2718                 pp_string (buffer, ", starting at line ");
2719                 pp_decimal_int (buffer, get_lineno (bsi_stmt (bsi)));
2720                 break;
2721               }
2722         }
2723       newline_and_indent (buffer, indent);
2724
2725       pp_string (buffer, "# PRED:");
2726       pp_write_text_to_stream (buffer);
2727       FOR_EACH_EDGE (e, ei, bb->preds)
2728         if (flags & TDF_SLIM)
2729           {
2730             pp_string (buffer, " ");
2731             if (e->src == ENTRY_BLOCK_PTR)
2732               pp_string (buffer, "ENTRY");
2733             else
2734               pp_decimal_int (buffer, e->src->index);
2735           }
2736         else
2737           dump_edge_info (buffer->buffer->stream, e, 0);
2738       pp_newline (buffer);
2739     }
2740   else
2741     {
2742       stmt = first_stmt (bb);
2743       if (!stmt || TREE_CODE (stmt) != LABEL_EXPR)
2744         {
2745           INDENT (indent - 2);
2746           pp_string (buffer, "<bb ");
2747           pp_decimal_int (buffer, bb->index);
2748           pp_string (buffer, ">:");
2749           pp_newline (buffer);
2750         }
2751     }
2752   pp_write_text_to_stream (buffer);
2753   check_bb_profile (bb, buffer->buffer->stream);
2754 }
2755
2756 /* Dumps end of basic block BB to buffer BUFFER indented by INDENT
2757    spaces.  */
2758
2759 static void
2760 dump_bb_end (pretty_printer *buffer, basic_block bb, int indent, int flags)
2761 {
2762   edge e;
2763   edge_iterator ei;
2764
2765   INDENT (indent);
2766   pp_string (buffer, "# SUCC:");
2767   pp_write_text_to_stream (buffer);
2768   FOR_EACH_EDGE (e, ei, bb->succs)
2769     if (flags & TDF_SLIM)
2770       {
2771         pp_string (buffer, " ");
2772         if (e->dest == EXIT_BLOCK_PTR)
2773           pp_string (buffer, "EXIT");
2774         else
2775           pp_decimal_int (buffer, e->dest->index);
2776       }
2777     else
2778       dump_edge_info (buffer->buffer->stream, e, 1);
2779   pp_newline (buffer);
2780 }
2781
2782 /* Dumps phi nodes of basic block BB to buffer BUFFER with details described by
2783    FLAGS indented by INDENT spaces.  */
2784
2785 static void
2786 dump_phi_nodes (pretty_printer *buffer, basic_block bb, int indent, int flags)
2787 {
2788   tree phi = phi_nodes (bb);
2789   if (!phi)
2790     return;
2791
2792   for (; phi; phi = PHI_CHAIN (phi))
2793     {
2794       if (is_gimple_reg (PHI_RESULT (phi)) || (flags & TDF_VOPS))
2795         {
2796           INDENT (indent);
2797           pp_string (buffer, "# ");
2798           dump_generic_node (buffer, phi, indent, flags, false);
2799           pp_newline (buffer);
2800         }
2801     }
2802 }
2803
2804 /* Dump jump to basic block BB that is represented implicitly in the cfg
2805    to BUFFER.  */
2806
2807 static void
2808 pp_cfg_jump (pretty_printer *buffer, basic_block bb)
2809 {
2810   tree stmt;
2811
2812   stmt = first_stmt (bb);
2813
2814   pp_string (buffer, "goto <bb ");
2815   pp_decimal_int (buffer, bb->index);
2816   pp_string (buffer, ">");
2817   if (stmt && TREE_CODE (stmt) == LABEL_EXPR)
2818     {
2819       pp_string (buffer, " (");
2820       dump_generic_node (buffer, LABEL_EXPR_LABEL (stmt), 0, 0, false);
2821       pp_string (buffer, ")");
2822     }
2823   pp_semicolon (buffer);
2824 }
2825
2826 /* Dump edges represented implicitly in basic block BB to BUFFER, indented
2827    by INDENT spaces, with details given by FLAGS.  */
2828
2829 static void
2830 dump_implicit_edges (pretty_printer *buffer, basic_block bb, int indent,
2831                      int flags)
2832 {
2833   edge e;
2834   edge_iterator ei;
2835
2836   /* If there is a fallthru edge, we may need to add an artificial goto to the
2837      dump.  */
2838   FOR_EACH_EDGE (e, ei, bb->succs)
2839     if (e->flags & EDGE_FALLTHRU)
2840       break;
2841   if (e && e->dest != bb->next_bb)
2842     {
2843       INDENT (indent);
2844
2845       if ((flags & TDF_LINENO)
2846 #ifdef USE_MAPPED_LOCATION
2847           && e->goto_locus != UNKNOWN_LOCATION
2848 #else
2849           && e->goto_locus
2850 #endif
2851           )
2852         {
2853           expanded_location goto_xloc;
2854 #ifdef USE_MAPPED_LOCATION
2855           goto_xloc = expand_location (e->goto_locus);
2856 #else
2857           goto_xloc = *e->goto_locus;
2858 #endif
2859           pp_character (buffer, '[');
2860           if (goto_xloc.file)
2861             {
2862               pp_string (buffer, goto_xloc.file);
2863               pp_string (buffer, " : ");
2864             }
2865           pp_decimal_int (buffer, goto_xloc.line);
2866           pp_string (buffer, "] ");
2867         }
2868
2869       pp_cfg_jump (buffer, e->dest);
2870       pp_newline (buffer);
2871     }
2872 }
2873
2874 /* Dumps basic block BB to buffer BUFFER with details described by FLAGS and
2875    indented by INDENT spaces.  */
2876
2877 static void
2878 dump_generic_bb_buff (pretty_printer *buffer, basic_block bb,
2879                       int indent, int flags)
2880 {
2881   block_stmt_iterator bsi;
2882   tree stmt;
2883   int label_indent = indent - 2;
2884
2885   if (label_indent < 0)
2886     label_indent = 0;
2887
2888   dump_bb_header (buffer, bb, indent, flags);
2889
2890   dump_phi_nodes (buffer, bb, indent, flags);
2891
2892   for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
2893     {
2894       int curr_indent;
2895
2896       stmt = bsi_stmt (bsi);
2897
2898       curr_indent = TREE_CODE (stmt) == LABEL_EXPR ? label_indent : indent;
2899
2900       INDENT (curr_indent);
2901       dump_generic_node (buffer, stmt, curr_indent, flags, true);
2902       pp_newline (buffer);
2903     }
2904
2905   dump_implicit_edges (buffer, bb, indent, flags);
2906
2907   if (flags & TDF_BLOCKS)
2908     dump_bb_end (buffer, bb, indent, flags);
2909 }