OSDN Git Service

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