OSDN Git Service

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