OSDN Git Service

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