OSDN Git Service

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