OSDN Git Service

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