OSDN Git Service

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