OSDN Git Service

PR fortran/20897
[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_OPERAND_LENGTH (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       {
1177         tree arg;
1178         call_expr_arg_iterator iter;
1179         FOR_EACH_CALL_EXPR_ARG (arg, iter, node)
1180           {
1181             dump_generic_node (buffer, arg, spc, flags, false);
1182             if (more_call_expr_args_p (&iter))
1183               {
1184                 pp_character (buffer, ',');
1185                 pp_space (buffer);
1186               }
1187           }
1188       }
1189       pp_character (buffer, ')');
1190
1191       op1 = CALL_EXPR_STATIC_CHAIN (node);
1192       if (op1)
1193         {
1194           pp_string (buffer, " [static-chain: ");
1195           dump_generic_node (buffer, op1, spc, flags, false);
1196           pp_character (buffer, ']');
1197         }
1198
1199       if (CALL_EXPR_RETURN_SLOT_OPT (node))
1200         pp_string (buffer, " [return slot optimization]");
1201       if (CALL_EXPR_TAILCALL (node))
1202         pp_string (buffer, " [tail call]");
1203       break;
1204
1205     case WITH_CLEANUP_EXPR:
1206       NIY;
1207       break;
1208
1209     case CLEANUP_POINT_EXPR:
1210       pp_string (buffer, "<<cleanup_point ");
1211       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1212       pp_string (buffer, ">>");
1213       break;
1214
1215     case PLACEHOLDER_EXPR:
1216       pp_string (buffer, "<PLACEHOLDER_EXPR ");
1217       dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
1218       pp_character (buffer, '>');
1219       break;
1220
1221       /* Binary arithmetic and logic expressions.  */
1222     case WIDEN_SUM_EXPR:
1223     case WIDEN_MULT_EXPR:
1224     case MULT_EXPR:
1225     case PLUS_EXPR:
1226     case MINUS_EXPR:
1227     case TRUNC_DIV_EXPR:
1228     case CEIL_DIV_EXPR:
1229     case FLOOR_DIV_EXPR:
1230     case ROUND_DIV_EXPR:
1231     case TRUNC_MOD_EXPR:
1232     case CEIL_MOD_EXPR:
1233     case FLOOR_MOD_EXPR:
1234     case ROUND_MOD_EXPR:
1235     case RDIV_EXPR:
1236     case EXACT_DIV_EXPR:
1237     case LSHIFT_EXPR:
1238     case RSHIFT_EXPR:
1239     case LROTATE_EXPR:
1240     case RROTATE_EXPR:
1241     case VEC_LSHIFT_EXPR:
1242     case VEC_RSHIFT_EXPR:
1243     case BIT_IOR_EXPR:
1244     case BIT_XOR_EXPR:
1245     case BIT_AND_EXPR:
1246     case TRUTH_ANDIF_EXPR:
1247     case TRUTH_ORIF_EXPR:
1248     case TRUTH_AND_EXPR:
1249     case TRUTH_OR_EXPR:
1250     case TRUTH_XOR_EXPR:
1251     case LT_EXPR:
1252     case LE_EXPR:
1253     case GT_EXPR:
1254     case GE_EXPR:
1255     case EQ_EXPR:
1256     case NE_EXPR:
1257     case UNLT_EXPR:
1258     case UNLE_EXPR:
1259     case UNGT_EXPR:
1260     case UNGE_EXPR:
1261     case UNEQ_EXPR:
1262     case LTGT_EXPR:
1263     case ORDERED_EXPR:
1264     case UNORDERED_EXPR:
1265       {
1266         const char *op = op_symbol (node);
1267         op0 = TREE_OPERAND (node, 0);
1268         op1 = TREE_OPERAND (node, 1);
1269
1270         /* When the operands are expressions with less priority,
1271            keep semantics of the tree representation.  */
1272         if (op_prio (op0) <= op_prio (node))
1273           {
1274             pp_character (buffer, '(');
1275             dump_generic_node (buffer, op0, spc, flags, false);
1276             pp_character (buffer, ')');
1277           }
1278         else
1279           dump_generic_node (buffer, op0, spc, flags, false);
1280
1281         pp_space (buffer);
1282         pp_string (buffer, op);
1283         pp_space (buffer);
1284
1285         /* When the operands are expressions with less priority,
1286            keep semantics of the tree representation.  */
1287         if (op_prio (op1) <= op_prio (node))
1288           {
1289             pp_character (buffer, '(');
1290             dump_generic_node (buffer, op1, spc, flags, false);
1291             pp_character (buffer, ')');
1292           }
1293         else
1294           dump_generic_node (buffer, op1, spc, flags, false);
1295       }
1296       break;
1297
1298       /* Unary arithmetic and logic expressions.  */
1299     case NEGATE_EXPR:
1300     case BIT_NOT_EXPR:
1301     case TRUTH_NOT_EXPR:
1302     case ADDR_EXPR:
1303     case PREDECREMENT_EXPR:
1304     case PREINCREMENT_EXPR:
1305     case ALIGN_INDIRECT_REF:
1306     case MISALIGNED_INDIRECT_REF:
1307     case INDIRECT_REF:
1308       if (TREE_CODE (node) == ADDR_EXPR
1309           && (TREE_CODE (TREE_OPERAND (node, 0)) == STRING_CST
1310               || TREE_CODE (TREE_OPERAND (node, 0)) == FUNCTION_DECL))
1311         ;       /* Do not output '&' for strings and function pointers.  */
1312       else
1313         pp_string (buffer, op_symbol (node));
1314
1315       if (op_prio (TREE_OPERAND (node, 0)) < op_prio (node))
1316         {
1317           pp_character (buffer, '(');
1318           dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1319           pp_character (buffer, ')');
1320         }
1321       else
1322         dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1323
1324       if (TREE_CODE (node) == MISALIGNED_INDIRECT_REF)
1325         {
1326           pp_string (buffer, "{misalignment: ");
1327           dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1328           pp_character (buffer, '}');
1329         }
1330       break;
1331
1332     case POSTDECREMENT_EXPR:
1333     case POSTINCREMENT_EXPR:
1334       if (op_prio (TREE_OPERAND (node, 0)) < op_prio (node))
1335         {
1336           pp_character (buffer, '(');
1337           dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1338           pp_character (buffer, ')');
1339         }
1340       else
1341         dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1342       pp_string (buffer, op_symbol (node));
1343       break;
1344
1345     case MIN_EXPR:
1346       pp_string (buffer, "MIN_EXPR <");
1347       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1348       pp_string (buffer, ", ");
1349       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1350       pp_character (buffer, '>');
1351       break;
1352
1353     case MAX_EXPR:
1354       pp_string (buffer, "MAX_EXPR <");
1355       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1356       pp_string (buffer, ", ");
1357       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1358       pp_character (buffer, '>');
1359       break;
1360
1361     case ABS_EXPR:
1362       pp_string (buffer, "ABS_EXPR <");
1363       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1364       pp_character (buffer, '>');
1365       break;
1366
1367     case RANGE_EXPR:
1368       NIY;
1369       break;
1370
1371     case FIX_TRUNC_EXPR:
1372     case FLOAT_EXPR:
1373     case CONVERT_EXPR:
1374     case NOP_EXPR:
1375       type = TREE_TYPE (node);
1376       op0 = TREE_OPERAND (node, 0);
1377       if (type != TREE_TYPE (op0))
1378         {
1379           pp_character (buffer, '(');
1380           dump_generic_node (buffer, type, spc, flags, false);
1381           pp_string (buffer, ") ");
1382         }
1383       if (op_prio (op0) < op_prio (node))
1384         pp_character (buffer, '(');
1385       dump_generic_node (buffer, op0, spc, flags, false);
1386       if (op_prio (op0) < op_prio (node))
1387         pp_character (buffer, ')');
1388       break;
1389
1390     case VIEW_CONVERT_EXPR:
1391       pp_string (buffer, "VIEW_CONVERT_EXPR<");
1392       dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
1393       pp_string (buffer, ">(");
1394       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1395       pp_character (buffer, ')');
1396       break;
1397
1398     case NON_LVALUE_EXPR:
1399       pp_string (buffer, "NON_LVALUE_EXPR <");
1400       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1401       pp_character (buffer, '>');
1402       break;
1403
1404     case SAVE_EXPR:
1405       pp_string (buffer, "SAVE_EXPR <");
1406       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1407       pp_character (buffer, '>');
1408       break;
1409
1410     case COMPLEX_EXPR:
1411       pp_string (buffer, "COMPLEX_EXPR <");
1412       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1413       pp_string (buffer, ", ");
1414       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1415       pp_string (buffer, ">");
1416       break;
1417
1418     case CONJ_EXPR:
1419       pp_string (buffer, "CONJ_EXPR <");
1420       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1421       pp_string (buffer, ">");
1422       break;
1423
1424     case REALPART_EXPR:
1425       pp_string (buffer, "REALPART_EXPR <");
1426       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1427       pp_string (buffer, ">");
1428       break;
1429
1430     case IMAGPART_EXPR:
1431       pp_string (buffer, "IMAGPART_EXPR <");
1432       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1433       pp_string (buffer, ">");
1434       break;
1435
1436     case VA_ARG_EXPR:
1437       pp_string (buffer, "VA_ARG_EXPR <");
1438       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1439       pp_string (buffer, ">");
1440       break;
1441
1442     case TRY_FINALLY_EXPR:
1443     case TRY_CATCH_EXPR:
1444       pp_string (buffer, "try");
1445       newline_and_indent (buffer, spc+2);
1446       pp_string (buffer, "{");
1447       newline_and_indent (buffer, spc+4);
1448       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc+4, flags, true);
1449       newline_and_indent (buffer, spc+2);
1450       pp_string (buffer, "}");
1451       newline_and_indent (buffer, spc);
1452       pp_string (buffer,
1453                          (TREE_CODE (node) == TRY_CATCH_EXPR) ? "catch" : "finally");
1454       newline_and_indent (buffer, spc+2);
1455       pp_string (buffer, "{");
1456       newline_and_indent (buffer, spc+4);
1457       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc+4, flags, true);
1458       newline_and_indent (buffer, spc+2);
1459       pp_string (buffer, "}");
1460       is_expr = false;
1461       break;
1462
1463     case CATCH_EXPR:
1464       pp_string (buffer, "catch (");
1465       dump_generic_node (buffer, CATCH_TYPES (node), spc+2, flags, false);
1466       pp_string (buffer, ")");
1467       newline_and_indent (buffer, spc+2);
1468       pp_string (buffer, "{");
1469       newline_and_indent (buffer, spc+4);
1470       dump_generic_node (buffer, CATCH_BODY (node), spc+4, flags, true);
1471       newline_and_indent (buffer, spc+2);
1472       pp_string (buffer, "}");
1473       is_expr = false;
1474       break;
1475
1476     case EH_FILTER_EXPR:
1477       pp_string (buffer, "<<<eh_filter (");
1478       dump_generic_node (buffer, EH_FILTER_TYPES (node), spc+2, flags, false);
1479       pp_string (buffer, ")>>>");
1480       newline_and_indent (buffer, spc+2);
1481       pp_string (buffer, "{");
1482       newline_and_indent (buffer, spc+4);
1483       dump_generic_node (buffer, EH_FILTER_FAILURE (node), spc+4, flags, true);
1484       newline_and_indent (buffer, spc+2);
1485       pp_string (buffer, "}");
1486       is_expr = false;
1487       break;
1488
1489     case LABEL_EXPR:
1490       op0 = TREE_OPERAND (node, 0);
1491       /* If this is for break or continue, don't bother printing it.  */
1492       if (DECL_NAME (op0))
1493         {
1494           const char *name = IDENTIFIER_POINTER (DECL_NAME (op0));
1495           if (strcmp (name, "break") == 0
1496               || strcmp (name, "continue") == 0)
1497             break;
1498         }
1499       dump_generic_node (buffer, op0, spc, flags, false);
1500       pp_character (buffer, ':');
1501       if (DECL_NONLOCAL (op0))
1502         pp_string (buffer, " [non-local]");
1503       break;
1504
1505     case EXC_PTR_EXPR:
1506       pp_string (buffer, "<<<exception object>>>");
1507       break;
1508
1509     case FILTER_EXPR:
1510       pp_string (buffer, "<<<filter object>>>");
1511       break;
1512
1513     case LOOP_EXPR:
1514       pp_string (buffer, "while (1)");
1515       if (!(flags & TDF_SLIM))
1516         {
1517           newline_and_indent (buffer, spc+2);
1518           pp_character (buffer, '{');
1519           newline_and_indent (buffer, spc+4);
1520           dump_generic_node (buffer, LOOP_EXPR_BODY (node), spc+4, flags, true);
1521           newline_and_indent (buffer, spc+2);
1522           pp_character (buffer, '}');
1523         }
1524       is_expr = false;
1525       break;
1526
1527     case RETURN_EXPR:
1528       pp_string (buffer, "return");
1529       op0 = TREE_OPERAND (node, 0);
1530       if (op0)
1531         {
1532           pp_space (buffer);
1533           if (TREE_CODE (op0) == MODIFY_EXPR
1534               || TREE_CODE (op0) == GIMPLE_MODIFY_STMT)
1535             dump_generic_node (buffer, GENERIC_TREE_OPERAND (op0, 1),
1536                                spc, flags, false);
1537           else
1538             dump_generic_node (buffer, op0, spc, flags, false);
1539         }
1540       break;
1541
1542     case EXIT_EXPR:
1543       pp_string (buffer, "if (");
1544       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1545       pp_string (buffer, ") break");
1546       break;
1547
1548     case SWITCH_EXPR:
1549       pp_string (buffer, "switch (");
1550       dump_generic_node (buffer, SWITCH_COND (node), spc, flags, false);
1551       pp_character (buffer, ')');
1552       if (!(flags & TDF_SLIM))
1553         {
1554           newline_and_indent (buffer, spc+2);
1555           pp_character (buffer, '{');
1556           if (SWITCH_BODY (node))
1557             {
1558               newline_and_indent (buffer, spc+4);
1559               dump_generic_node (buffer, SWITCH_BODY (node), spc+4, flags,
1560                                  true);
1561             }
1562           else
1563             {
1564               tree vec = SWITCH_LABELS (node);
1565               size_t i, n = TREE_VEC_LENGTH (vec);
1566               for (i = 0; i < n; ++i)
1567                 {
1568                   tree elt = TREE_VEC_ELT (vec, i);
1569                   newline_and_indent (buffer, spc+4);
1570                   if (elt)
1571                     {
1572                       dump_generic_node (buffer, elt, spc+4, flags, false);
1573                       pp_string (buffer, " goto ");
1574                       dump_generic_node (buffer, CASE_LABEL (elt), spc+4,
1575                                          flags, true);
1576                       pp_semicolon (buffer);
1577                     }
1578                   else
1579                     pp_string (buffer, "case ???: goto ???;");
1580                 }
1581             }
1582           newline_and_indent (buffer, spc+2);
1583           pp_character (buffer, '}');
1584         }
1585       is_expr = false;
1586       break;
1587
1588     case GOTO_EXPR:
1589       op0 = GOTO_DESTINATION (node);
1590       if (TREE_CODE (op0) != SSA_NAME && DECL_P (op0) && DECL_NAME (op0))
1591         {
1592           const char *name = IDENTIFIER_POINTER (DECL_NAME (op0));
1593           if (strcmp (name, "break") == 0
1594               || strcmp (name, "continue") == 0)
1595             {
1596               pp_string (buffer, name);
1597               break;
1598             }
1599         }
1600       pp_string (buffer, "goto ");
1601       dump_generic_node (buffer, op0, spc, flags, false);
1602       break;
1603
1604     case RESX_EXPR:
1605       pp_string (buffer, "resx ");
1606       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1607       break;
1608
1609     case ASM_EXPR:
1610       pp_string (buffer, "__asm__");
1611       if (ASM_VOLATILE_P (node))
1612         pp_string (buffer, " __volatile__");
1613       pp_character (buffer, '(');
1614       dump_generic_node (buffer, ASM_STRING (node), spc, flags, false);
1615       pp_character (buffer, ':');
1616       dump_generic_node (buffer, ASM_OUTPUTS (node), spc, flags, false);
1617       pp_character (buffer, ':');
1618       dump_generic_node (buffer, ASM_INPUTS (node), spc, flags, false);
1619       if (ASM_CLOBBERS (node))
1620         {
1621           pp_character (buffer, ':');
1622           dump_generic_node (buffer, ASM_CLOBBERS (node), spc, flags, false);
1623         }
1624       pp_string (buffer, ")");
1625       break;
1626
1627     case CASE_LABEL_EXPR:
1628       if (CASE_LOW (node) && CASE_HIGH (node))
1629         {
1630           pp_string (buffer, "case ");
1631           dump_generic_node (buffer, CASE_LOW (node), spc, flags, false);
1632           pp_string (buffer, " ... ");
1633           dump_generic_node (buffer, CASE_HIGH (node), spc, flags, false);
1634         }
1635       else if (CASE_LOW (node))
1636         {
1637           pp_string (buffer, "case ");
1638           dump_generic_node (buffer, CASE_LOW (node), spc, flags, false);
1639         }
1640       else
1641         pp_string (buffer, "default ");
1642       pp_character (buffer, ':');
1643       break;
1644
1645     case OBJ_TYPE_REF:
1646       pp_string (buffer, "OBJ_TYPE_REF(");
1647       dump_generic_node (buffer, OBJ_TYPE_REF_EXPR (node), spc, flags, false);
1648       pp_character (buffer, ';');
1649       dump_generic_node (buffer, OBJ_TYPE_REF_OBJECT (node), spc, flags, false);
1650       pp_character (buffer, '-');
1651       pp_character (buffer, '>');
1652       dump_generic_node (buffer, OBJ_TYPE_REF_TOKEN (node), spc, flags, false);
1653       pp_character (buffer, ')');
1654       break;
1655
1656     case PHI_NODE:
1657       {
1658         int i;
1659
1660         dump_generic_node (buffer, PHI_RESULT (node), spc, flags, false);
1661         pp_string (buffer, " = PHI <");
1662         for (i = 0; i < PHI_NUM_ARGS (node); i++)
1663           {
1664             dump_generic_node (buffer, PHI_ARG_DEF (node, i), spc, flags, false);
1665             pp_string (buffer, "(");
1666             pp_decimal_int (buffer, PHI_ARG_EDGE (node, i)->src->index);
1667             pp_string (buffer, ")");
1668             if (i < PHI_NUM_ARGS (node) - 1)
1669               pp_string (buffer, ", ");
1670           }
1671         pp_string (buffer, ">");
1672
1673         if (stmt_references_memory_p (node) && (flags & TDF_MEMSYMS))
1674           dump_symbols (buffer, STORED_SYMS (node), flags);
1675       }
1676       break;
1677
1678     case SSA_NAME:
1679       dump_generic_node (buffer, SSA_NAME_VAR (node), spc, flags, false);
1680       pp_string (buffer, "_");
1681       pp_decimal_int (buffer, SSA_NAME_VERSION (node));
1682       if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (node))
1683         pp_string (buffer, "(ab)");
1684       else if (SSA_NAME_IS_DEFAULT_DEF (node))
1685         pp_string (buffer, "(D)");
1686       break;
1687
1688     case WITH_SIZE_EXPR:
1689       pp_string (buffer, "WITH_SIZE_EXPR <");
1690       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1691       pp_string (buffer, ", ");
1692       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1693       pp_string (buffer, ">");
1694       break;
1695
1696     case VALUE_HANDLE:
1697       pp_printf (buffer, "VH.%d", VALUE_HANDLE_ID (node));
1698       break;
1699
1700     case ASSERT_EXPR:
1701       pp_string (buffer, "ASSERT_EXPR <");
1702       dump_generic_node (buffer, ASSERT_EXPR_VAR (node), spc, flags, false);
1703       pp_string (buffer, ", ");
1704       dump_generic_node (buffer, ASSERT_EXPR_COND (node), spc, flags, false);
1705       pp_string (buffer, ">");
1706       break;
1707
1708     case SCEV_KNOWN:
1709       pp_string (buffer, "scev_known");
1710       break;
1711
1712     case SCEV_NOT_KNOWN:
1713       pp_string (buffer, "scev_not_known");
1714       break;
1715
1716     case POLYNOMIAL_CHREC:
1717       pp_string (buffer, "{");
1718       dump_generic_node (buffer, CHREC_LEFT (node), spc, flags, false);
1719       pp_string (buffer, ", +, ");
1720       dump_generic_node (buffer, CHREC_RIGHT (node), spc, flags, false);
1721       pp_string (buffer, "}_");
1722       dump_generic_node (buffer, CHREC_VAR (node), spc, flags, false);
1723       is_stmt = false;
1724       break;
1725
1726     case REALIGN_LOAD_EXPR:
1727       pp_string (buffer, "REALIGN_LOAD <");
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 VEC_COND_EXPR:
1737       pp_string (buffer, " VEC_COND_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 DOT_PROD_EXPR:
1747       pp_string (buffer, " DOT_PROD_EXPR < ");
1748       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1749       pp_string (buffer, ", ");
1750       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1751       pp_string (buffer, ", ");
1752       dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
1753       pp_string (buffer, " > ");
1754       break;
1755
1756     case OMP_PARALLEL:
1757       pp_string (buffer, "#pragma omp parallel");
1758       dump_omp_clauses (buffer, OMP_PARALLEL_CLAUSES (node), spc, flags);
1759       if (OMP_PARALLEL_FN (node))
1760         {
1761           pp_string (buffer, " [child fn: ");
1762           dump_generic_node (buffer, OMP_PARALLEL_FN (node), spc, flags, false);
1763
1764           pp_string (buffer, " (");
1765
1766           if (OMP_PARALLEL_DATA_ARG (node))
1767             dump_generic_node (buffer, OMP_PARALLEL_DATA_ARG (node), spc, flags,
1768                                false);
1769           else
1770             pp_string (buffer, "???");
1771
1772           pp_string (buffer, ")]");
1773         }
1774
1775     dump_omp_body:
1776       if (!(flags & TDF_SLIM) && OMP_BODY (node))
1777         {
1778           newline_and_indent (buffer, spc + 2);
1779           pp_character (buffer, '{');
1780           newline_and_indent (buffer, spc + 4);
1781           dump_generic_node (buffer, OMP_BODY (node), spc + 4, flags, false);
1782           newline_and_indent (buffer, spc + 2);
1783           pp_character (buffer, '}');
1784         }
1785       is_expr = false;
1786       break;
1787
1788     case OMP_FOR:
1789       pp_string (buffer, "#pragma omp for");
1790       dump_omp_clauses (buffer, OMP_FOR_CLAUSES (node), spc, flags);
1791
1792       if (!(flags & TDF_SLIM))
1793         {
1794           if (OMP_FOR_PRE_BODY (node))
1795             {
1796               newline_and_indent (buffer, spc + 2);
1797               pp_character (buffer, '{');
1798               spc += 4;
1799               newline_and_indent (buffer, spc);
1800               dump_generic_node (buffer, OMP_FOR_PRE_BODY (node),
1801                   spc, flags, false);
1802             }
1803           newline_and_indent (buffer, spc);
1804           pp_string (buffer, "for (");
1805           dump_generic_node (buffer, OMP_FOR_INIT (node), spc, flags, false);
1806           pp_string (buffer, "; ");
1807           dump_generic_node (buffer, OMP_FOR_COND (node), spc, flags, false);
1808           pp_string (buffer, "; ");
1809           dump_generic_node (buffer, OMP_FOR_INCR (node), spc, flags, false);
1810           pp_string (buffer, ")");
1811           if (OMP_FOR_BODY (node))
1812             {
1813               newline_and_indent (buffer, spc + 2);
1814               pp_character (buffer, '{');
1815               newline_and_indent (buffer, spc + 4);
1816               dump_generic_node (buffer, OMP_FOR_BODY (node), spc + 4, flags,
1817                   false);
1818               newline_and_indent (buffer, spc + 2);
1819               pp_character (buffer, '}');
1820             }
1821           if (OMP_FOR_PRE_BODY (node))
1822             {
1823               spc -= 4;
1824               newline_and_indent (buffer, spc + 2);
1825               pp_character (buffer, '}');
1826             }
1827         }
1828       is_expr = false;
1829       break;
1830
1831     case OMP_SECTIONS:
1832       pp_string (buffer, "#pragma omp sections");
1833       dump_omp_clauses (buffer, OMP_SECTIONS_CLAUSES (node), spc, flags);
1834       goto dump_omp_body;
1835
1836     case OMP_SECTION:
1837       pp_string (buffer, "#pragma omp section");
1838       goto dump_omp_body;
1839  
1840     case OMP_MASTER:
1841       pp_string (buffer, "#pragma omp master");
1842       goto dump_omp_body;
1843
1844     case OMP_ORDERED:
1845       pp_string (buffer, "#pragma omp ordered");
1846       goto dump_omp_body;
1847
1848     case OMP_CRITICAL:
1849       pp_string (buffer, "#pragma omp critical");
1850       if (OMP_CRITICAL_NAME (node))
1851         {
1852           pp_space (buffer);
1853           pp_character (buffer, '(');
1854           dump_generic_node (buffer, OMP_CRITICAL_NAME (node), spc,
1855                              flags, false);
1856           pp_character (buffer, ')');
1857         }
1858       goto dump_omp_body;
1859
1860     case OMP_ATOMIC:
1861       pp_string (buffer, "#pragma omp atomic");
1862       newline_and_indent (buffer, spc + 2);
1863       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1864       pp_space (buffer);
1865       pp_character (buffer, '=');
1866       pp_space (buffer);
1867       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1868       break;
1869
1870     case OMP_SINGLE:
1871       pp_string (buffer, "#pragma omp single");
1872       dump_omp_clauses (buffer, OMP_SINGLE_CLAUSES (node), spc, flags);
1873       goto dump_omp_body;
1874
1875     case OMP_RETURN:
1876       pp_string (buffer, "OMP_RETURN");
1877       if (OMP_RETURN_NOWAIT (node))
1878         pp_string (buffer, " [nowait]");
1879       is_expr = false;
1880       break;
1881
1882     case OMP_CONTINUE:
1883       pp_string (buffer, "OMP_CONTINUE");
1884       is_expr = false;
1885       break;
1886
1887     case OMP_CLAUSE:
1888       dump_omp_clause (buffer, node, spc, flags);
1889       is_expr = false;
1890       break;
1891
1892     case REDUC_MAX_EXPR:
1893       pp_string (buffer, " REDUC_MAX_EXPR < ");
1894       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1895       pp_string (buffer, " > ");
1896       break;
1897
1898     case REDUC_MIN_EXPR:
1899       pp_string (buffer, " REDUC_MIN_EXPR < ");
1900       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1901       pp_string (buffer, " > ");
1902       break;
1903
1904     case REDUC_PLUS_EXPR:
1905       pp_string (buffer, " REDUC_PLUS_EXPR < ");
1906       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1907       pp_string (buffer, " > ");
1908       break;
1909
1910     case VEC_WIDEN_MULT_HI_EXPR:
1911       pp_string (buffer, " VEC_WIDEN_MULT_HI_EXPR < ");
1912       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1913       pp_string (buffer, ", ");
1914       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1915       pp_string (buffer, " > ");
1916       break;
1917
1918     case VEC_WIDEN_MULT_LO_EXPR:
1919       pp_string (buffer, " VEC_WIDEN_MULT_LO_EXPR < ");
1920       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1921       pp_string (buffer, ", ");
1922       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1923       pp_string (buffer, " > ");
1924       break;
1925
1926     case VEC_UNPACK_HI_EXPR:
1927       pp_string (buffer, " VEC_UNPACK_HI_EXPR < ");
1928       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1929       pp_string (buffer, " > ");
1930       break;
1931
1932     case VEC_UNPACK_LO_EXPR:
1933       pp_string (buffer, " VEC_UNPACK_LO_EXPR < ");
1934       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1935       pp_string (buffer, " > ");
1936       break;
1937
1938     case VEC_PACK_MOD_EXPR:
1939       pp_string (buffer, " VEC_PACK_MOD_EXPR < ");
1940       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1941       pp_string (buffer, ", ");
1942       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1943       pp_string (buffer, " > ");
1944       break;
1945                                                                                 
1946     case VEC_PACK_SAT_EXPR:
1947       pp_string (buffer, " VEC_PACK_SAT_EXPR < ");
1948       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1949       pp_string (buffer, ", ");
1950       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1951       pp_string (buffer, " > ");
1952       break;
1953                                                                                 
1954     case BLOCK:
1955       {
1956         tree t;
1957         pp_string (buffer, "BLOCK");
1958
1959         if (BLOCK_ABSTRACT (node))
1960           pp_string (buffer, " [abstract]");
1961
1962         if (TREE_ASM_WRITTEN (node))
1963           pp_string (buffer, " [written]");
1964
1965         newline_and_indent (buffer, spc + 2);
1966
1967         if (BLOCK_SUPERCONTEXT (node))
1968           {
1969             pp_string (buffer, "SUPERCONTEXT: ");
1970             if (TREE_CODE (BLOCK_SUPERCONTEXT (node)) == BLOCK)
1971               pp_printf (buffer, "BLOCK %p",
1972                          (void *)BLOCK_SUPERCONTEXT (node));
1973             else
1974               dump_generic_node (buffer, BLOCK_SUPERCONTEXT (node), 0, flags,
1975                                  false);
1976             newline_and_indent (buffer, spc + 2);
1977           }
1978
1979         if (BLOCK_SUBBLOCKS (node))
1980           {
1981             pp_string (buffer, "SUBBLOCKS: ");
1982             for (t = BLOCK_SUBBLOCKS (node); t; t = BLOCK_CHAIN (t))
1983               pp_printf (buffer, "%p ", (void *)t);
1984             newline_and_indent (buffer, spc + 2);
1985           }
1986
1987         if (BLOCK_VARS (node))
1988           {
1989             pp_string (buffer, "VARS: ");
1990             for (t = BLOCK_VARS (node); t; t = TREE_CHAIN (t))
1991               {
1992                 dump_generic_node (buffer, t, 0, flags, false);
1993                 pp_string (buffer, " ");
1994               }
1995             newline_and_indent (buffer, spc + 2);
1996           }
1997
1998         if (BLOCK_ABSTRACT_ORIGIN (node))
1999           {
2000             pp_string (buffer, "ABSTRACT_ORIGIN: ");
2001             if (TREE_CODE (BLOCK_ABSTRACT_ORIGIN (node)) == BLOCK)
2002               pp_printf (buffer, "BLOCK %p",
2003                          (void *)BLOCK_ABSTRACT_ORIGIN (node));
2004             else
2005               dump_generic_node (buffer, BLOCK_ABSTRACT_ORIGIN (node), 0, flags,
2006                                  false);
2007             newline_and_indent (buffer, spc + 2);
2008           }
2009       }
2010     break;
2011
2012     case VEC_EXTRACT_EVEN_EXPR:
2013       pp_string (buffer, " VEC_EXTRACT_EVEN_EXPR < ");
2014       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
2015       pp_string (buffer, ", ");
2016       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
2017       pp_string (buffer, " > ");
2018       break;
2019   
2020     case VEC_EXTRACT_ODD_EXPR:
2021       pp_string (buffer, " VEC_EXTRACT_ODD_EXPR < ");
2022       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
2023       pp_string (buffer, ", ");
2024       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
2025       pp_string (buffer, " > ");
2026       break;
2027
2028     case VEC_INTERLEAVE_HIGH_EXPR:
2029       pp_string (buffer, " VEC_INTERLEAVE_HIGH_EXPR < ");
2030       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
2031       pp_string (buffer, ", ");
2032       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
2033       pp_string (buffer, " > ");
2034       break;
2035
2036     case VEC_INTERLEAVE_LOW_EXPR:
2037       pp_string (buffer, " VEC_INTERLEAVE_LOW_EXPR < ");
2038       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
2039       pp_string (buffer, ", ");
2040       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
2041       pp_string (buffer, " > ");
2042       break;
2043
2044     default:
2045       NIY;
2046     }
2047
2048   if (is_stmt && is_expr)
2049     pp_semicolon (buffer);
2050   pp_write_text_to_stream (buffer);
2051
2052   return spc;
2053 }
2054
2055 /* Print the declaration of a variable.  */
2056
2057 static void
2058 print_declaration (pretty_printer *buffer, tree t, int spc, int flags)
2059 {
2060   INDENT (spc);
2061
2062   if (TREE_CODE (t) == TYPE_DECL)
2063     pp_string (buffer, "typedef ");
2064
2065   if (CODE_CONTAINS_STRUCT (TREE_CODE (t), TS_DECL_WRTL) && DECL_REGISTER (t))
2066     pp_string (buffer, "register ");
2067
2068   if (TREE_PUBLIC (t) && DECL_EXTERNAL (t))
2069     pp_string (buffer, "extern ");
2070   else if (TREE_STATIC (t))
2071     pp_string (buffer, "static ");
2072
2073   /* Print the type and name.  */
2074   if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
2075     {
2076       tree tmp;
2077
2078       /* Print array's type.  */
2079       tmp = TREE_TYPE (t);
2080       while (TREE_CODE (TREE_TYPE (tmp)) == ARRAY_TYPE)
2081         tmp = TREE_TYPE (tmp);
2082       dump_generic_node (buffer, TREE_TYPE (tmp), spc, flags, false);
2083
2084       /* Print variable's name.  */
2085       pp_space (buffer);
2086       dump_generic_node (buffer, t, spc, flags, false);
2087
2088       /* Print the dimensions.  */
2089       tmp = TREE_TYPE (t);
2090       while (TREE_CODE (tmp) == ARRAY_TYPE)
2091         {
2092           dump_array_domain (buffer, TYPE_DOMAIN (tmp), spc, flags);
2093           tmp = TREE_TYPE (tmp);
2094         }
2095     }
2096   else if (TREE_CODE (t) == FUNCTION_DECL)
2097     {
2098       dump_generic_node (buffer, TREE_TYPE (TREE_TYPE (t)), spc, flags, false);
2099       pp_space (buffer);
2100       dump_decl_name (buffer, t, flags);
2101       dump_function_declaration (buffer, TREE_TYPE (t), spc, flags);
2102     }
2103   else
2104     {
2105       /* Print type declaration.  */
2106       dump_generic_node (buffer, TREE_TYPE (t), spc, flags, false);
2107
2108       /* Print variable's name.  */
2109       pp_space (buffer);
2110       dump_generic_node (buffer, t, spc, flags, false);
2111     }
2112
2113   if (TREE_CODE (t) == VAR_DECL && DECL_HARD_REGISTER (t))
2114     {
2115       pp_string (buffer, " __asm__ ");
2116       pp_character (buffer, '(');
2117       dump_generic_node (buffer, DECL_ASSEMBLER_NAME (t), spc, flags, false);
2118       pp_character (buffer, ')');
2119     }
2120
2121   /* The initial value of a function serves to determine wether the function
2122      is declared or defined.  So the following does not apply to function
2123      nodes.  */
2124   if (TREE_CODE (t) != FUNCTION_DECL)
2125     {
2126       /* Print the initial value.  */
2127       if (DECL_INITIAL (t))
2128         {
2129           pp_space (buffer);
2130           pp_character (buffer, '=');
2131           pp_space (buffer);
2132           dump_generic_node (buffer, DECL_INITIAL (t), spc, flags, false);
2133         }
2134     }
2135
2136   if (TREE_CODE (t) == VAR_DECL && DECL_HAS_VALUE_EXPR_P (t))
2137     {
2138       pp_string (buffer, " [value-expr: ");
2139       dump_generic_node (buffer, DECL_VALUE_EXPR (t), spc, flags, false);
2140       pp_character (buffer, ']');
2141     }
2142
2143   pp_character (buffer, ';');
2144 }
2145
2146
2147 /* Prints a structure: name, fields, and methods.
2148    FIXME: Still incomplete.  */
2149
2150 static void
2151 print_struct_decl (pretty_printer *buffer, tree node, int spc, int flags)
2152 {
2153   /* Print the name of the structure.  */
2154   if (TYPE_NAME (node))
2155     {
2156       INDENT (spc);
2157       if (TREE_CODE (node) == RECORD_TYPE)
2158         pp_string (buffer, "struct ");
2159       else if ((TREE_CODE (node) == UNION_TYPE
2160                 || TREE_CODE (node) == QUAL_UNION_TYPE))
2161         pp_string (buffer, "union ");
2162
2163       dump_generic_node (buffer, TYPE_NAME (node), spc, 0, false);
2164     }
2165
2166   /* Print the contents of the structure.  */
2167   pp_newline (buffer);
2168   INDENT (spc);
2169   pp_character (buffer, '{');
2170   pp_newline (buffer);
2171
2172   /* Print the fields of the structure.  */
2173   {
2174     tree tmp;
2175     tmp = TYPE_FIELDS (node);
2176     while (tmp)
2177       {
2178         /* Avoid to print recursively the structure.  */
2179         /* FIXME : Not implemented correctly...,
2180            what about the case when we have a cycle in the contain graph? ...
2181            Maybe this could be solved by looking at the scope in which the
2182            structure was declared.  */
2183         if (TREE_TYPE (tmp) != node
2184             || (TREE_CODE (TREE_TYPE (tmp)) == POINTER_TYPE
2185                 && TREE_TYPE (TREE_TYPE (tmp)) != node))
2186           {
2187             print_declaration (buffer, tmp, spc+2, flags);
2188             pp_newline (buffer);
2189           }
2190         tmp = TREE_CHAIN (tmp);
2191       }
2192   }
2193   INDENT (spc);
2194   pp_character (buffer, '}');
2195 }
2196
2197 /* Return the priority of the operator OP.
2198
2199    From lowest to highest precedence with either left-to-right (L-R)
2200    or right-to-left (R-L) associativity]:
2201
2202      1  [L-R] ,
2203      2  [R-L] = += -= *= /= %= &= ^= |= <<= >>=
2204      3  [R-L] ?:
2205      4  [L-R] ||
2206      5  [L-R] &&
2207      6  [L-R] |
2208      7  [L-R] ^
2209      8  [L-R] &
2210      9  [L-R] == !=
2211     10  [L-R] < <= > >=
2212     11  [L-R] << >>
2213     12  [L-R] + -
2214     13  [L-R] * / %
2215     14  [R-L] ! ~ ++ -- + - * & (type) sizeof
2216     15  [L-R] fn() [] -> .
2217
2218    unary +, - and * have higher precedence than the corresponding binary
2219    operators.  */
2220
2221 static int
2222 op_prio (tree op)
2223 {
2224   if (op == NULL)
2225     return 9999;
2226
2227   switch (TREE_CODE (op))
2228     {
2229     case TREE_LIST:
2230     case COMPOUND_EXPR:
2231     case BIND_EXPR:
2232       return 1;
2233
2234     case MODIFY_EXPR:
2235     case GIMPLE_MODIFY_STMT:
2236     case INIT_EXPR:
2237       return 2;
2238
2239     case COND_EXPR:
2240       return 3;
2241
2242     case TRUTH_OR_EXPR:
2243     case TRUTH_ORIF_EXPR:
2244       return 4;
2245
2246     case TRUTH_AND_EXPR:
2247     case TRUTH_ANDIF_EXPR:
2248       return 5;
2249
2250     case BIT_IOR_EXPR:
2251       return 6;
2252
2253     case BIT_XOR_EXPR:
2254     case TRUTH_XOR_EXPR:
2255       return 7;
2256
2257     case BIT_AND_EXPR:
2258       return 8;
2259
2260     case EQ_EXPR:
2261     case NE_EXPR:
2262       return 9;
2263
2264     case UNLT_EXPR:
2265     case UNLE_EXPR:
2266     case UNGT_EXPR:
2267     case UNGE_EXPR:
2268     case UNEQ_EXPR:
2269     case LTGT_EXPR:
2270     case ORDERED_EXPR:
2271     case UNORDERED_EXPR:
2272     case LT_EXPR:
2273     case LE_EXPR:
2274     case GT_EXPR:
2275     case GE_EXPR:
2276       return 10;
2277
2278     case LSHIFT_EXPR:
2279     case RSHIFT_EXPR:
2280     case LROTATE_EXPR:
2281     case RROTATE_EXPR:
2282       return 11;
2283
2284     case WIDEN_SUM_EXPR:
2285     case PLUS_EXPR:
2286     case MINUS_EXPR:
2287       return 12;
2288
2289     case VEC_WIDEN_MULT_HI_EXPR:
2290     case VEC_WIDEN_MULT_LO_EXPR:
2291     case WIDEN_MULT_EXPR:
2292     case DOT_PROD_EXPR:
2293     case MULT_EXPR:
2294     case TRUNC_DIV_EXPR:
2295     case CEIL_DIV_EXPR:
2296     case FLOOR_DIV_EXPR:
2297     case ROUND_DIV_EXPR:
2298     case RDIV_EXPR:
2299     case EXACT_DIV_EXPR:
2300     case TRUNC_MOD_EXPR:
2301     case CEIL_MOD_EXPR:
2302     case FLOOR_MOD_EXPR:
2303     case ROUND_MOD_EXPR:
2304       return 13;
2305
2306     case TRUTH_NOT_EXPR:
2307     case BIT_NOT_EXPR:
2308     case POSTINCREMENT_EXPR:
2309     case POSTDECREMENT_EXPR:
2310     case PREINCREMENT_EXPR:
2311     case PREDECREMENT_EXPR:
2312     case NEGATE_EXPR:
2313     case ALIGN_INDIRECT_REF:
2314     case MISALIGNED_INDIRECT_REF:
2315     case INDIRECT_REF:
2316     case ADDR_EXPR:
2317     case FLOAT_EXPR:
2318     case NOP_EXPR:
2319     case CONVERT_EXPR:
2320     case FIX_TRUNC_EXPR:
2321     case TARGET_EXPR:
2322       return 14;
2323
2324     case CALL_EXPR:
2325     case ARRAY_REF:
2326     case ARRAY_RANGE_REF:
2327     case COMPONENT_REF:
2328       return 15;
2329
2330       /* Special expressions.  */
2331     case MIN_EXPR:
2332     case MAX_EXPR:
2333     case ABS_EXPR:
2334     case REALPART_EXPR:
2335     case IMAGPART_EXPR:
2336     case REDUC_MAX_EXPR:
2337     case REDUC_MIN_EXPR:
2338     case REDUC_PLUS_EXPR:
2339     case VEC_LSHIFT_EXPR:
2340     case VEC_RSHIFT_EXPR:
2341     case VEC_UNPACK_HI_EXPR:
2342     case VEC_UNPACK_LO_EXPR:
2343     case VEC_PACK_MOD_EXPR:
2344     case VEC_PACK_SAT_EXPR:
2345       return 16;
2346
2347     case SAVE_EXPR:
2348     case NON_LVALUE_EXPR:
2349       return op_prio (TREE_OPERAND (op, 0));
2350
2351     default:
2352       /* Return an arbitrarily high precedence to avoid surrounding single
2353          VAR_DECLs in ()s.  */
2354       return 9999;
2355     }
2356 }
2357
2358
2359 /* Return the symbol associated with operator OP.  */
2360
2361 static const char *
2362 op_symbol_1 (enum tree_code code)
2363 {
2364   switch (code)
2365     {
2366     case MODIFY_EXPR:
2367     case GIMPLE_MODIFY_STMT:
2368       return "=";
2369
2370     case TRUTH_OR_EXPR:
2371     case TRUTH_ORIF_EXPR:
2372       return "||";
2373
2374     case TRUTH_AND_EXPR:
2375     case TRUTH_ANDIF_EXPR:
2376       return "&&";
2377
2378     case BIT_IOR_EXPR:
2379       return "|";
2380
2381     case TRUTH_XOR_EXPR:
2382     case BIT_XOR_EXPR:
2383       return "^";
2384
2385     case ADDR_EXPR:
2386     case BIT_AND_EXPR:
2387       return "&";
2388
2389     case ORDERED_EXPR:
2390       return "ord";
2391     case UNORDERED_EXPR:
2392       return "unord";
2393
2394     case EQ_EXPR:
2395       return "==";
2396     case UNEQ_EXPR:
2397       return "u==";
2398
2399     case NE_EXPR:
2400       return "!=";
2401
2402     case LT_EXPR:
2403       return "<";
2404     case UNLT_EXPR:
2405       return "u<";
2406
2407     case LE_EXPR:
2408       return "<=";
2409     case UNLE_EXPR:
2410       return "u<=";
2411
2412     case GT_EXPR:
2413       return ">";
2414     case UNGT_EXPR:
2415       return "u>";
2416
2417     case GE_EXPR:
2418       return ">=";
2419     case UNGE_EXPR:
2420       return "u>=";
2421
2422     case LTGT_EXPR:
2423       return "<>";
2424
2425     case LSHIFT_EXPR:
2426       return "<<";
2427
2428     case RSHIFT_EXPR:
2429       return ">>";
2430
2431     case LROTATE_EXPR:
2432       return "r<<";
2433
2434     case RROTATE_EXPR:
2435       return "r>>";
2436
2437     case VEC_LSHIFT_EXPR:
2438       return "v<<";
2439
2440     case VEC_RSHIFT_EXPR:
2441       return "v>>";
2442  
2443     case PLUS_EXPR:
2444       return "+";
2445
2446     case REDUC_PLUS_EXPR:
2447       return "r+";
2448
2449     case WIDEN_SUM_EXPR:
2450       return "w+";
2451
2452     case WIDEN_MULT_EXPR:
2453       return "w*";
2454
2455     case NEGATE_EXPR:
2456     case MINUS_EXPR:
2457       return "-";
2458
2459     case BIT_NOT_EXPR:
2460       return "~";
2461
2462     case TRUTH_NOT_EXPR:
2463       return "!";
2464
2465     case MULT_EXPR:
2466     case INDIRECT_REF:
2467       return "*";
2468
2469     case ALIGN_INDIRECT_REF:
2470       return "A*";
2471
2472     case MISALIGNED_INDIRECT_REF:
2473       return "M*";
2474
2475     case TRUNC_DIV_EXPR:
2476     case RDIV_EXPR:
2477       return "/";
2478
2479     case CEIL_DIV_EXPR:
2480       return "/[cl]";
2481
2482     case FLOOR_DIV_EXPR:
2483       return "/[fl]";
2484
2485     case ROUND_DIV_EXPR:
2486       return "/[rd]";
2487
2488     case EXACT_DIV_EXPR:
2489       return "/[ex]";
2490
2491     case TRUNC_MOD_EXPR:
2492       return "%";
2493
2494     case CEIL_MOD_EXPR:
2495       return "%[cl]";
2496
2497     case FLOOR_MOD_EXPR:
2498       return "%[fl]";
2499
2500     case ROUND_MOD_EXPR:
2501       return "%[rd]";
2502
2503     case PREDECREMENT_EXPR:
2504       return " --";
2505
2506     case PREINCREMENT_EXPR:
2507       return " ++";
2508
2509     case POSTDECREMENT_EXPR:
2510       return "-- ";
2511
2512     case POSTINCREMENT_EXPR:
2513       return "++ ";
2514
2515     case MAX_EXPR:
2516       return "max";
2517
2518     case MIN_EXPR:
2519       return "min";
2520
2521     default:
2522       return "<<< ??? >>>";
2523     }
2524 }
2525
2526 static const char *
2527 op_symbol (tree op)
2528 {
2529   return op_symbol_1 (TREE_CODE (op));
2530 }
2531
2532 /* Prints the name of a CALL_EXPR.  */
2533
2534 static void
2535 print_call_name (pretty_printer *buffer, tree node)
2536 {
2537   tree op0;
2538
2539   gcc_assert (TREE_CODE (node) == CALL_EXPR);
2540
2541   op0 = CALL_EXPR_FN (node);
2542
2543   if (TREE_CODE (op0) == NON_LVALUE_EXPR)
2544     op0 = TREE_OPERAND (op0, 0);
2545
2546   switch (TREE_CODE (op0))
2547     {
2548     case VAR_DECL:
2549     case PARM_DECL:
2550       dump_function_name (buffer, op0);
2551       break;
2552
2553     case ADDR_EXPR:
2554     case INDIRECT_REF:
2555     case NOP_EXPR:
2556       dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
2557       break;
2558
2559     case COND_EXPR:
2560       pp_string (buffer, "(");
2561       dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
2562       pp_string (buffer, ") ? ");
2563       dump_generic_node (buffer, TREE_OPERAND (op0, 1), 0, 0, false);
2564       pp_string (buffer, " : ");
2565       dump_generic_node (buffer, TREE_OPERAND (op0, 2), 0, 0, false);
2566       break;
2567
2568     case COMPONENT_REF:
2569       /* The function is a pointer contained in a structure.  */
2570       if (TREE_CODE (TREE_OPERAND (op0, 0)) == INDIRECT_REF ||
2571           TREE_CODE (TREE_OPERAND (op0, 0)) == VAR_DECL)
2572         dump_function_name (buffer, TREE_OPERAND (op0, 1));
2573       else
2574         dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
2575       /* else
2576          We can have several levels of structures and a function
2577          pointer inside.  This is not implemented yet...  */
2578       /*                  NIY;*/
2579       break;
2580
2581     case ARRAY_REF:
2582       if (TREE_CODE (TREE_OPERAND (op0, 0)) == VAR_DECL)
2583         dump_function_name (buffer, TREE_OPERAND (op0, 0));
2584       else
2585         dump_generic_node (buffer, op0, 0, 0, false);
2586       break;
2587
2588     case SSA_NAME:
2589     case OBJ_TYPE_REF:
2590       dump_generic_node (buffer, op0, 0, 0, false);
2591       break;
2592
2593     default:
2594       NIY;
2595     }
2596 }
2597
2598 /* Parses the string STR and replaces new-lines by '\n', tabs by '\t', ...  */
2599
2600 static void
2601 pretty_print_string (pretty_printer *buffer, const char *str)
2602 {
2603   if (str == NULL)
2604     return;
2605
2606   while (*str)
2607     {
2608       switch (str[0])
2609         {
2610         case '\b':
2611           pp_string (buffer, "\\b");
2612           break;
2613
2614         case '\f':
2615           pp_string (buffer, "\\f");
2616           break;
2617
2618         case '\n':
2619           pp_string (buffer, "\\n");
2620           break;
2621
2622         case '\r':
2623           pp_string (buffer, "\\r");
2624           break;
2625
2626         case '\t':
2627           pp_string (buffer, "\\t");
2628           break;
2629
2630         case '\v':
2631           pp_string (buffer, "\\v");
2632           break;
2633
2634         case '\\':
2635           pp_string (buffer, "\\\\");
2636           break;
2637
2638         case '\"':
2639           pp_string (buffer, "\\\"");
2640           break;
2641
2642         case '\'':
2643           pp_string (buffer, "\\'");
2644           break;
2645
2646           /* No need to handle \0; the loop terminates on \0.  */
2647
2648         case '\1':
2649           pp_string (buffer, "\\1");
2650           break;
2651
2652         case '\2':
2653           pp_string (buffer, "\\2");
2654           break;
2655
2656         case '\3':
2657           pp_string (buffer, "\\3");
2658           break;
2659
2660         case '\4':
2661           pp_string (buffer, "\\4");
2662           break;
2663
2664         case '\5':
2665           pp_string (buffer, "\\5");
2666           break;
2667
2668         case '\6':
2669           pp_string (buffer, "\\6");
2670           break;
2671
2672         case '\7':
2673           pp_string (buffer, "\\7");
2674           break;
2675
2676         default:
2677           pp_character (buffer, str[0]);
2678           break;
2679         }
2680       str++;
2681     }
2682 }
2683
2684 static void
2685 maybe_init_pretty_print (FILE *file)
2686 {
2687   if (!initialized)
2688     {
2689       pp_construct (&buffer, /* prefix */NULL, /* line-width */0);
2690       pp_needs_newline (&buffer) = true;
2691       initialized = 1;
2692     }
2693
2694   buffer.buffer->stream = file;
2695 }
2696
2697 static void
2698 newline_and_indent (pretty_printer *buffer, int spc)
2699 {
2700   pp_newline (buffer);
2701   INDENT (spc);
2702 }
2703
2704
2705 static void
2706 dump_vops (pretty_printer *buffer, tree stmt, int spc, int flags)
2707 {
2708   struct voptype_d *vdefs;
2709   struct voptype_d *vuses;
2710   int i, n;
2711
2712   if (!ssa_operands_active () || !stmt_references_memory_p (stmt))
2713     return;
2714
2715   /* Even if the statement doesn't have virtual operators yet, it may
2716      contain symbol information (this happens before aliases have been
2717      computed).  */
2718   if ((flags & TDF_MEMSYMS)
2719       && VUSE_OPS (stmt) == NULL
2720       && VDEF_OPS (stmt) == NULL)
2721     {
2722       if (LOADED_SYMS (stmt))
2723         {
2724           pp_string (buffer, "# LOADS: ");
2725           dump_symbols (buffer, LOADED_SYMS (stmt), flags);
2726           newline_and_indent (buffer, spc);
2727         }
2728
2729       if (STORED_SYMS (stmt))
2730         {
2731           pp_string (buffer, "# STORES: ");
2732           dump_symbols (buffer, STORED_SYMS (stmt), flags);
2733           newline_and_indent (buffer, spc);
2734         }
2735
2736       return;
2737     }
2738
2739   vuses = VUSE_OPS (stmt);
2740   while (vuses)
2741     {
2742       pp_string (buffer, "# VUSE <");
2743
2744       n = VUSE_NUM (vuses);
2745       for (i = 0; i < n; i++)
2746         {
2747           dump_generic_node (buffer, VUSE_OP (vuses, i), spc + 2, flags, false);
2748           if (i < n - 1)
2749             pp_string (buffer, ", ");
2750         }
2751
2752       pp_string (buffer, ">");
2753
2754       if (flags & TDF_MEMSYMS)
2755         dump_symbols (buffer, LOADED_SYMS (stmt), flags);
2756
2757       newline_and_indent (buffer, spc);
2758       vuses = vuses->next;
2759     }
2760
2761   vdefs = VDEF_OPS (stmt);
2762   while (vdefs)
2763     {
2764       pp_string (buffer, "# ");
2765       dump_generic_node (buffer, VDEF_RESULT (vdefs), spc + 2, flags, false);
2766       pp_string (buffer, " = VDEF <");
2767
2768       n = VDEF_NUM (vdefs);
2769       for (i = 0; i < n; i++)
2770         {
2771           dump_generic_node (buffer, VDEF_OP (vdefs, i), spc + 2, flags, 0);
2772           if (i < n - 1)
2773             pp_string (buffer, ", ");
2774         }
2775
2776       pp_string (buffer, ">");
2777
2778       if ((flags & TDF_MEMSYMS) && vdefs->next == NULL)
2779         dump_symbols (buffer, STORED_SYMS (stmt), flags);
2780
2781       newline_and_indent (buffer, spc);
2782       vdefs = vdefs->next;
2783     }
2784 }
2785
2786
2787 /* Dumps basic block BB to FILE with details described by FLAGS and
2788    indented by INDENT spaces.  */
2789
2790 void
2791 dump_generic_bb (FILE *file, basic_block bb, int indent, int flags)
2792 {
2793   maybe_init_pretty_print (file);
2794   dump_generic_bb_buff (&buffer, bb, indent, flags);
2795   pp_flush (&buffer);
2796 }
2797
2798 /* Dumps header of basic block BB to buffer BUFFER indented by INDENT
2799    spaces and details described by flags.  */
2800
2801 static void
2802 dump_bb_header (pretty_printer *buffer, basic_block bb, int indent, int flags)
2803 {
2804   edge e;
2805   tree stmt;
2806   edge_iterator ei;
2807
2808   if (flags & TDF_BLOCKS)
2809     {
2810       INDENT (indent);
2811       pp_string (buffer, "# BLOCK ");
2812       pp_decimal_int (buffer, bb->index);
2813       if (bb->frequency)
2814         {
2815           pp_string (buffer, " freq:");
2816           pp_decimal_int (buffer, bb->frequency);
2817         }
2818       if (bb->count)
2819         {
2820           pp_string (buffer, " count:");
2821           pp_widest_integer (buffer, bb->count);
2822         }
2823
2824       if (flags & TDF_LINENO)
2825         {
2826           block_stmt_iterator bsi;
2827
2828           for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
2829             if (get_lineno (bsi_stmt (bsi)) != -1)
2830               {
2831                 pp_string (buffer, ", starting at line ");
2832                 pp_decimal_int (buffer, get_lineno (bsi_stmt (bsi)));
2833                 break;
2834               }
2835         }
2836       newline_and_indent (buffer, indent);
2837
2838       pp_string (buffer, "# PRED:");
2839       pp_write_text_to_stream (buffer);
2840       FOR_EACH_EDGE (e, ei, bb->preds)
2841         if (flags & TDF_SLIM)
2842           {
2843             pp_string (buffer, " ");
2844             if (e->src == ENTRY_BLOCK_PTR)
2845               pp_string (buffer, "ENTRY");
2846             else
2847               pp_decimal_int (buffer, e->src->index);
2848           }
2849         else
2850           dump_edge_info (buffer->buffer->stream, e, 0);
2851       pp_newline (buffer);
2852     }
2853   else
2854     {
2855       stmt = first_stmt (bb);
2856       if (!stmt || TREE_CODE (stmt) != LABEL_EXPR)
2857         {
2858           INDENT (indent - 2);
2859           pp_string (buffer, "<bb ");
2860           pp_decimal_int (buffer, bb->index);
2861           pp_string (buffer, ">:");
2862           pp_newline (buffer);
2863         }
2864     }
2865   pp_write_text_to_stream (buffer);
2866   check_bb_profile (bb, buffer->buffer->stream);
2867 }
2868
2869 /* Dumps end of basic block BB to buffer BUFFER indented by INDENT
2870    spaces.  */
2871
2872 static void
2873 dump_bb_end (pretty_printer *buffer, basic_block bb, int indent, int flags)
2874 {
2875   edge e;
2876   edge_iterator ei;
2877
2878   INDENT (indent);
2879   pp_string (buffer, "# SUCC:");
2880   pp_write_text_to_stream (buffer);
2881   FOR_EACH_EDGE (e, ei, bb->succs)
2882     if (flags & TDF_SLIM)
2883       {
2884         pp_string (buffer, " ");
2885         if (e->dest == EXIT_BLOCK_PTR)
2886           pp_string (buffer, "EXIT");
2887         else
2888           pp_decimal_int (buffer, e->dest->index);
2889       }
2890     else
2891       dump_edge_info (buffer->buffer->stream, e, 1);
2892   pp_newline (buffer);
2893 }
2894
2895 /* Dump PHI nodes of basic block BB to BUFFER with details described
2896    by FLAGS and indented by INDENT spaces.  */
2897
2898 static void
2899 dump_phi_nodes (pretty_printer *buffer, basic_block bb, int indent, int flags)
2900 {
2901   tree phi = phi_nodes (bb);
2902   if (!phi)
2903     return;
2904
2905   for (; phi; phi = PHI_CHAIN (phi))
2906     {
2907       if (is_gimple_reg (PHI_RESULT (phi)) || (flags & TDF_VOPS))
2908         {
2909           INDENT (indent);
2910           pp_string (buffer, "# ");
2911           dump_generic_node (buffer, phi, indent, flags, false);
2912           pp_newline (buffer);
2913         }
2914     }
2915 }
2916
2917
2918 /* Dump jump to basic block BB that is represented implicitly in the cfg
2919    to BUFFER.  */
2920
2921 static void
2922 pp_cfg_jump (pretty_printer *buffer, basic_block bb)
2923 {
2924   tree stmt;
2925
2926   stmt = first_stmt (bb);
2927
2928   pp_string (buffer, "goto <bb ");
2929   pp_decimal_int (buffer, bb->index);
2930   pp_string (buffer, ">");
2931   if (stmt && TREE_CODE (stmt) == LABEL_EXPR)
2932     {
2933       pp_string (buffer, " (");
2934       dump_generic_node (buffer, LABEL_EXPR_LABEL (stmt), 0, 0, false);
2935       pp_string (buffer, ")");
2936     }
2937   pp_semicolon (buffer);
2938 }
2939
2940 /* Dump edges represented implicitly in basic block BB to BUFFER, indented
2941    by INDENT spaces, with details given by FLAGS.  */
2942
2943 static void
2944 dump_implicit_edges (pretty_printer *buffer, basic_block bb, int indent,
2945                      int flags)
2946 {
2947   edge e;
2948   edge_iterator ei;
2949
2950   /* If there is a fallthru edge, we may need to add an artificial goto to the
2951      dump.  */
2952   FOR_EACH_EDGE (e, ei, bb->succs)
2953     if (e->flags & EDGE_FALLTHRU)
2954       break;
2955   if (e && e->dest != bb->next_bb)
2956     {
2957       INDENT (indent);
2958
2959       if ((flags & TDF_LINENO)
2960 #ifdef USE_MAPPED_LOCATION
2961           && e->goto_locus != UNKNOWN_LOCATION
2962 #else
2963           && e->goto_locus
2964 #endif
2965           )
2966         {
2967           expanded_location goto_xloc;
2968 #ifdef USE_MAPPED_LOCATION
2969           goto_xloc = expand_location (e->goto_locus);
2970 #else
2971           goto_xloc = *e->goto_locus;
2972 #endif
2973           pp_character (buffer, '[');
2974           if (goto_xloc.file)
2975             {
2976               pp_string (buffer, goto_xloc.file);
2977               pp_string (buffer, " : ");
2978             }
2979           pp_decimal_int (buffer, goto_xloc.line);
2980           pp_string (buffer, "] ");
2981         }
2982
2983       pp_cfg_jump (buffer, e->dest);
2984       pp_newline (buffer);
2985     }
2986 }
2987
2988 /* Dumps basic block BB to buffer BUFFER with details described by FLAGS and
2989    indented by INDENT spaces.  */
2990
2991 static void
2992 dump_generic_bb_buff (pretty_printer *buffer, basic_block bb,
2993                       int indent, int flags)
2994 {
2995   block_stmt_iterator bsi;
2996   tree stmt;
2997   int label_indent = indent - 2;
2998
2999   if (label_indent < 0)
3000     label_indent = 0;
3001
3002   dump_bb_header (buffer, bb, indent, flags);
3003
3004   dump_phi_nodes (buffer, bb, indent, flags);
3005
3006   for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
3007     {
3008       int curr_indent;
3009
3010       stmt = bsi_stmt (bsi);
3011
3012       curr_indent = TREE_CODE (stmt) == LABEL_EXPR ? label_indent : indent;
3013
3014       INDENT (curr_indent);
3015       dump_generic_node (buffer, stmt, curr_indent, flags, true);
3016       pp_newline (buffer);
3017       dump_histograms_for_stmt (cfun, buffer->buffer->stream, stmt);
3018     }
3019
3020   dump_implicit_edges (buffer, bb, indent, flags);
3021
3022   if (flags & TDF_BLOCKS)
3023     dump_bb_end (buffer, bb, indent, flags);
3024 }