OSDN Git Service

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