OSDN Git Service

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