OSDN Git Service

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