OSDN Git Service

contrib:
[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, high, low);
788           pp_string (buffer, pp_buffer (buffer)->digit_buffer);
789         }
790       else
791         pp_wide_integer (buffer, TREE_INT_CST_LOW (node));
792       break;
793
794     case REAL_CST:
795       /* Code copied from print_node.  */
796       {
797         REAL_VALUE_TYPE d;
798         if (TREE_OVERFLOW (node))
799           pp_string (buffer, " overflow");
800
801 #if !defined(REAL_IS_NOT_DOUBLE) || defined(REAL_ARITHMETIC)
802         d = TREE_REAL_CST (node);
803         if (REAL_VALUE_ISINF (d))
804           pp_string (buffer, REAL_VALUE_NEGATIVE (d) ? " -Inf" : " Inf");
805         else if (REAL_VALUE_ISNAN (d))
806           pp_string (buffer, " Nan");
807         else
808           {
809             char string[100];
810             real_to_decimal (string, &d, sizeof (string), 0, 1);
811             pp_string (buffer, string);
812           }
813 #else
814         {
815           HOST_WIDE_INT i;
816           unsigned char *p = (unsigned char *) &TREE_REAL_CST (node);
817           pp_string (buffer, "0x");
818           for (i = 0; i < sizeof TREE_REAL_CST (node); i++)
819             output_formatted_integer (buffer, "%02x", *p++);
820         }
821 #endif
822         break;
823       }
824
825     case FIXED_CST:
826       {
827         char string[100];
828         fixed_to_decimal (string, TREE_FIXED_CST_PTR (node), sizeof (string));
829         pp_string (buffer, string);
830         break;
831       }
832
833     case COMPLEX_CST:
834       pp_string (buffer, "__complex__ (");
835       dump_generic_node (buffer, TREE_REALPART (node), spc, flags, false);
836       pp_string (buffer, ", ");
837       dump_generic_node (buffer, TREE_IMAGPART (node), spc, flags, false);
838       pp_string (buffer, ")");
839       break;
840
841     case STRING_CST:
842       pp_string (buffer, "\"");
843       pretty_print_string (buffer, TREE_STRING_POINTER (node));
844       pp_string (buffer, "\"");
845       break;
846
847     case VECTOR_CST:
848       {
849         tree elt;
850         pp_string (buffer, "{ ");
851         for (elt = TREE_VECTOR_CST_ELTS (node); elt; elt = TREE_CHAIN (elt))
852           {
853             dump_generic_node (buffer, TREE_VALUE (elt), spc, flags, false);
854             if (TREE_CHAIN (elt))
855               pp_string (buffer, ", ");
856           }
857         pp_string (buffer, " }");
858       }
859       break;
860
861     case FUNCTION_TYPE:
862       break;
863
864     case FUNCTION_DECL:
865     case CONST_DECL:
866       dump_decl_name (buffer, node, flags);
867       break;
868
869     case LABEL_DECL:
870       if (DECL_NAME (node))
871         dump_decl_name (buffer, node, flags);
872       else if (LABEL_DECL_UID (node) != -1)
873         pp_printf (buffer, "<L%d>", (int) LABEL_DECL_UID (node));
874       else
875         pp_printf (buffer, "<D.%u>", DECL_UID (node));
876       break;
877
878     case TYPE_DECL:
879       if (DECL_IS_BUILTIN (node))
880         {
881           /* Don't print the declaration of built-in types.  */
882           break;
883         }
884       if (DECL_NAME (node))
885         dump_decl_name (buffer, node, flags);
886       else
887         {
888           if ((TREE_CODE (TREE_TYPE (node)) == RECORD_TYPE
889                || TREE_CODE (TREE_TYPE (node)) == UNION_TYPE)
890               && TYPE_METHODS (TREE_TYPE (node)))
891             {
892               /* The type is a c++ class: all structures have at least
893                  4 methods.  */
894               pp_string (buffer, "class ");
895               dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
896             }
897           else
898             {
899               pp_string (buffer,
900                          (TREE_CODE (TREE_TYPE (node)) == UNION_TYPE
901                           ? "union" : "struct "));
902               dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
903             }
904         }
905       break;
906
907     case SYMBOL_MEMORY_TAG:
908     case NAME_MEMORY_TAG:
909     case STRUCT_FIELD_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_EXPR:
1426     case NOP_EXPR:
1427       type = TREE_TYPE (node);
1428       op0 = TREE_OPERAND (node, 0);
1429       if (type != TREE_TYPE (op0))
1430         {
1431           pp_character (buffer, '(');
1432           dump_generic_node (buffer, type, spc, flags, false);
1433           pp_string (buffer, ") ");
1434         }
1435       if (op_prio (op0) < op_prio (node))
1436         pp_character (buffer, '(');
1437       dump_generic_node (buffer, op0, spc, flags, false);
1438       if (op_prio (op0) < op_prio (node))
1439         pp_character (buffer, ')');
1440       break;
1441
1442     case VIEW_CONVERT_EXPR:
1443       pp_string (buffer, "VIEW_CONVERT_EXPR<");
1444       dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
1445       pp_string (buffer, ">(");
1446       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1447       pp_character (buffer, ')');
1448       break;
1449
1450     case PAREN_EXPR:
1451       pp_string (buffer, "((");
1452       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1453       pp_string (buffer, "))");
1454       break;
1455
1456     case NON_LVALUE_EXPR:
1457       pp_string (buffer, "NON_LVALUE_EXPR <");
1458       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1459       pp_character (buffer, '>');
1460       break;
1461
1462     case SAVE_EXPR:
1463       pp_string (buffer, "SAVE_EXPR <");
1464       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1465       pp_character (buffer, '>');
1466       break;
1467
1468     case COMPLEX_EXPR:
1469       pp_string (buffer, "COMPLEX_EXPR <");
1470       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1471       pp_string (buffer, ", ");
1472       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1473       pp_string (buffer, ">");
1474       break;
1475
1476     case CONJ_EXPR:
1477       pp_string (buffer, "CONJ_EXPR <");
1478       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1479       pp_string (buffer, ">");
1480       break;
1481
1482     case REALPART_EXPR:
1483       pp_string (buffer, "REALPART_EXPR <");
1484       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1485       pp_string (buffer, ">");
1486       break;
1487
1488     case IMAGPART_EXPR:
1489       pp_string (buffer, "IMAGPART_EXPR <");
1490       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1491       pp_string (buffer, ">");
1492       break;
1493
1494     case VA_ARG_EXPR:
1495       pp_string (buffer, "VA_ARG_EXPR <");
1496       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1497       pp_string (buffer, ">");
1498       break;
1499
1500     case TRY_FINALLY_EXPR:
1501     case TRY_CATCH_EXPR:
1502       pp_string (buffer, "try");
1503       newline_and_indent (buffer, spc+2);
1504       pp_string (buffer, "{");
1505       newline_and_indent (buffer, spc+4);
1506       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc+4, flags, true);
1507       newline_and_indent (buffer, spc+2);
1508       pp_string (buffer, "}");
1509       newline_and_indent (buffer, spc);
1510       pp_string (buffer,
1511                          (TREE_CODE (node) == TRY_CATCH_EXPR) ? "catch" : "finally");
1512       newline_and_indent (buffer, spc+2);
1513       pp_string (buffer, "{");
1514       newline_and_indent (buffer, spc+4);
1515       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc+4, flags, true);
1516       newline_and_indent (buffer, spc+2);
1517       pp_string (buffer, "}");
1518       is_expr = false;
1519       break;
1520
1521     case CATCH_EXPR:
1522       pp_string (buffer, "catch (");
1523       dump_generic_node (buffer, CATCH_TYPES (node), spc+2, flags, false);
1524       pp_string (buffer, ")");
1525       newline_and_indent (buffer, spc+2);
1526       pp_string (buffer, "{");
1527       newline_and_indent (buffer, spc+4);
1528       dump_generic_node (buffer, CATCH_BODY (node), spc+4, flags, true);
1529       newline_and_indent (buffer, spc+2);
1530       pp_string (buffer, "}");
1531       is_expr = false;
1532       break;
1533
1534     case EH_FILTER_EXPR:
1535       pp_string (buffer, "<<<eh_filter (");
1536       dump_generic_node (buffer, EH_FILTER_TYPES (node), spc+2, flags, false);
1537       pp_string (buffer, ")>>>");
1538       newline_and_indent (buffer, spc+2);
1539       pp_string (buffer, "{");
1540       newline_and_indent (buffer, spc+4);
1541       dump_generic_node (buffer, EH_FILTER_FAILURE (node), spc+4, flags, true);
1542       newline_and_indent (buffer, spc+2);
1543       pp_string (buffer, "}");
1544       is_expr = false;
1545       break;
1546
1547     case CHANGE_DYNAMIC_TYPE_EXPR:
1548       pp_string (buffer, "<<<change_dynamic_type (");
1549       dump_generic_node (buffer, CHANGE_DYNAMIC_TYPE_NEW_TYPE (node), spc + 2,
1550                          flags, false);
1551       pp_string (buffer, ") ");
1552       dump_generic_node (buffer, CHANGE_DYNAMIC_TYPE_LOCATION (node), spc + 2,
1553                          flags, false);
1554       pp_string (buffer, ")>>>");
1555       is_expr = false;
1556       break;
1557
1558     case LABEL_EXPR:
1559       op0 = TREE_OPERAND (node, 0);
1560       /* If this is for break or continue, don't bother printing it.  */
1561       if (DECL_NAME (op0))
1562         {
1563           const char *name = IDENTIFIER_POINTER (DECL_NAME (op0));
1564           if (strcmp (name, "break") == 0
1565               || strcmp (name, "continue") == 0)
1566             break;
1567         }
1568       dump_generic_node (buffer, op0, spc, flags, false);
1569       pp_character (buffer, ':');
1570       if (DECL_NONLOCAL (op0))
1571         pp_string (buffer, " [non-local]");
1572       break;
1573
1574     case EXC_PTR_EXPR:
1575       pp_string (buffer, "<<<exception object>>>");
1576       break;
1577
1578     case FILTER_EXPR:
1579       pp_string (buffer, "<<<filter object>>>");
1580       break;
1581
1582     case LOOP_EXPR:
1583       pp_string (buffer, "while (1)");
1584       if (!(flags & TDF_SLIM))
1585         {
1586           newline_and_indent (buffer, spc+2);
1587           pp_character (buffer, '{');
1588           newline_and_indent (buffer, spc+4);
1589           dump_generic_node (buffer, LOOP_EXPR_BODY (node), spc+4, flags, true);
1590           newline_and_indent (buffer, spc+2);
1591           pp_character (buffer, '}');
1592         }
1593       is_expr = false;
1594       break;
1595
1596     case PREDICT_EXPR:
1597       pp_string (buffer, "// predicted ");
1598       if (PREDICT_EXPR_OUTCOME (node))
1599         pp_string (buffer, "likely by ");
1600       else
1601         pp_string (buffer, "unlikely by ");
1602       pp_string (buffer, predictor_name (PREDICT_EXPR_PREDICTOR (node)));
1603       pp_string (buffer, " predictor.");
1604       break;
1605
1606     case RETURN_EXPR:
1607       pp_string (buffer, "return");
1608       op0 = TREE_OPERAND (node, 0);
1609       if (op0)
1610         {
1611           pp_space (buffer);
1612           if (TREE_CODE (op0) == MODIFY_EXPR
1613               || TREE_CODE (op0) == GIMPLE_MODIFY_STMT)
1614             dump_generic_node (buffer, GENERIC_TREE_OPERAND (op0, 1),
1615                                spc, flags, false);
1616           else
1617             dump_generic_node (buffer, op0, spc, flags, false);
1618         }
1619       break;
1620
1621     case EXIT_EXPR:
1622       pp_string (buffer, "if (");
1623       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1624       pp_string (buffer, ") break");
1625       break;
1626
1627     case SWITCH_EXPR:
1628       pp_string (buffer, "switch (");
1629       dump_generic_node (buffer, SWITCH_COND (node), spc, flags, false);
1630       pp_character (buffer, ')');
1631       if (!(flags & TDF_SLIM))
1632         {
1633           newline_and_indent (buffer, spc+2);
1634           pp_character (buffer, '{');
1635           if (SWITCH_BODY (node))
1636             {
1637               newline_and_indent (buffer, spc+4);
1638               dump_generic_node (buffer, SWITCH_BODY (node), spc+4, flags,
1639                                  true);
1640             }
1641           else
1642             {
1643               tree vec = SWITCH_LABELS (node);
1644               size_t i, n = TREE_VEC_LENGTH (vec);
1645               for (i = 0; i < n; ++i)
1646                 {
1647                   tree elt = TREE_VEC_ELT (vec, i);
1648                   newline_and_indent (buffer, spc+4);
1649                   if (elt)
1650                     {
1651                       dump_generic_node (buffer, elt, spc+4, flags, false);
1652                       pp_string (buffer, " goto ");
1653                       dump_generic_node (buffer, CASE_LABEL (elt), spc+4,
1654                                          flags, true);
1655                       pp_semicolon (buffer);
1656                     }
1657                   else
1658                     pp_string (buffer, "case ???: goto ???;");
1659                 }
1660             }
1661           newline_and_indent (buffer, spc+2);
1662           pp_character (buffer, '}');
1663         }
1664       is_expr = false;
1665       break;
1666
1667     case GOTO_EXPR:
1668       op0 = GOTO_DESTINATION (node);
1669       if (TREE_CODE (op0) != SSA_NAME && DECL_P (op0) && DECL_NAME (op0))
1670         {
1671           const char *name = IDENTIFIER_POINTER (DECL_NAME (op0));
1672           if (strcmp (name, "break") == 0
1673               || strcmp (name, "continue") == 0)
1674             {
1675               pp_string (buffer, name);
1676               break;
1677             }
1678         }
1679       pp_string (buffer, "goto ");
1680       dump_generic_node (buffer, op0, spc, flags, false);
1681       break;
1682
1683     case RESX_EXPR:
1684       pp_string (buffer, "resx ");
1685       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1686       break;
1687
1688     case ASM_EXPR:
1689       pp_string (buffer, "__asm__");
1690       if (ASM_VOLATILE_P (node))
1691         pp_string (buffer, " __volatile__");
1692       pp_character (buffer, '(');
1693       dump_generic_node (buffer, ASM_STRING (node), spc, flags, false);
1694       pp_character (buffer, ':');
1695       dump_generic_node (buffer, ASM_OUTPUTS (node), spc, flags, false);
1696       pp_character (buffer, ':');
1697       dump_generic_node (buffer, ASM_INPUTS (node), spc, flags, false);
1698       if (ASM_CLOBBERS (node))
1699         {
1700           pp_character (buffer, ':');
1701           dump_generic_node (buffer, ASM_CLOBBERS (node), spc, flags, false);
1702         }
1703       pp_string (buffer, ")");
1704       break;
1705
1706     case CASE_LABEL_EXPR:
1707       if (CASE_LOW (node) && CASE_HIGH (node))
1708         {
1709           pp_string (buffer, "case ");
1710           dump_generic_node (buffer, CASE_LOW (node), spc, flags, false);
1711           pp_string (buffer, " ... ");
1712           dump_generic_node (buffer, CASE_HIGH (node), spc, flags, false);
1713         }
1714       else if (CASE_LOW (node))
1715         {
1716           pp_string (buffer, "case ");
1717           dump_generic_node (buffer, CASE_LOW (node), spc, flags, false);
1718         }
1719       else
1720         pp_string (buffer, "default ");
1721       pp_character (buffer, ':');
1722       break;
1723
1724     case OBJ_TYPE_REF:
1725       pp_string (buffer, "OBJ_TYPE_REF(");
1726       dump_generic_node (buffer, OBJ_TYPE_REF_EXPR (node), spc, flags, false);
1727       pp_character (buffer, ';');
1728       dump_generic_node (buffer, OBJ_TYPE_REF_OBJECT (node), spc, flags, false);
1729       pp_character (buffer, '-');
1730       pp_character (buffer, '>');
1731       dump_generic_node (buffer, OBJ_TYPE_REF_TOKEN (node), spc, flags, false);
1732       pp_character (buffer, ')');
1733       break;
1734
1735     case PHI_NODE:
1736       {
1737         int i;
1738
1739         dump_generic_node (buffer, PHI_RESULT (node), spc, flags, false);
1740         pp_string (buffer, " = PHI <");
1741         for (i = 0; i < PHI_NUM_ARGS (node); i++)
1742           {
1743             dump_generic_node (buffer, PHI_ARG_DEF (node, i), spc, flags, false);
1744             pp_string (buffer, "(");
1745             pp_decimal_int (buffer, PHI_ARG_EDGE (node, i)->src->index);
1746             pp_string (buffer, ")");
1747             if (i < PHI_NUM_ARGS (node) - 1)
1748               pp_string (buffer, ", ");
1749           }
1750         pp_string (buffer, ">");
1751
1752         if (stmt_references_memory_p (node) && (flags & TDF_MEMSYMS))
1753           dump_symbols (buffer, STORED_SYMS (node), flags);
1754       }
1755       break;
1756
1757     case SSA_NAME:
1758       dump_generic_node (buffer, SSA_NAME_VAR (node), spc, flags, false);
1759       pp_string (buffer, "_");
1760       pp_decimal_int (buffer, SSA_NAME_VERSION (node));
1761       if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (node))
1762         pp_string (buffer, "(ab)");
1763       else if (SSA_NAME_IS_DEFAULT_DEF (node))
1764         pp_string (buffer, "(D)");
1765       break;
1766
1767     case WITH_SIZE_EXPR:
1768       pp_string (buffer, "WITH_SIZE_EXPR <");
1769       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1770       pp_string (buffer, ", ");
1771       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1772       pp_string (buffer, ">");
1773       break;
1774
1775     case VALUE_HANDLE:
1776       pp_printf (buffer, "VH.%d", VALUE_HANDLE_ID (node));
1777       break;
1778
1779     case ASSERT_EXPR:
1780       pp_string (buffer, "ASSERT_EXPR <");
1781       dump_generic_node (buffer, ASSERT_EXPR_VAR (node), spc, flags, false);
1782       pp_string (buffer, ", ");
1783       dump_generic_node (buffer, ASSERT_EXPR_COND (node), spc, flags, false);
1784       pp_string (buffer, ">");
1785       break;
1786
1787     case SCEV_KNOWN:
1788       pp_string (buffer, "scev_known");
1789       break;
1790
1791     case SCEV_NOT_KNOWN:
1792       pp_string (buffer, "scev_not_known");
1793       break;
1794
1795     case POLYNOMIAL_CHREC:
1796       pp_string (buffer, "{");
1797       dump_generic_node (buffer, CHREC_LEFT (node), spc, flags, false);
1798       pp_string (buffer, ", +, ");
1799       dump_generic_node (buffer, CHREC_RIGHT (node), spc, flags, false);
1800       pp_string (buffer, "}_");
1801       dump_generic_node (buffer, CHREC_VAR (node), spc, flags, false);
1802       is_stmt = false;
1803       break;
1804
1805     case REALIGN_LOAD_EXPR:
1806       pp_string (buffer, "REALIGN_LOAD <");
1807       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1808       pp_string (buffer, ", ");
1809       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1810       pp_string (buffer, ", ");
1811       dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
1812       pp_string (buffer, ">");
1813       break;
1814       
1815     case VEC_COND_EXPR:
1816       pp_string (buffer, " VEC_COND_EXPR < ");
1817       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1818       pp_string (buffer, " , ");
1819       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1820       pp_string (buffer, " , ");
1821       dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
1822       pp_string (buffer, " > ");
1823       break;
1824
1825     case DOT_PROD_EXPR:
1826       pp_string (buffer, " DOT_PROD_EXPR < ");
1827       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1828       pp_string (buffer, ", ");
1829       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1830       pp_string (buffer, ", ");
1831       dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
1832       pp_string (buffer, " > ");
1833       break;
1834
1835     case OMP_PARALLEL:
1836       pp_string (buffer, "#pragma omp parallel");
1837       dump_omp_clauses (buffer, OMP_PARALLEL_CLAUSES (node), spc, flags);
1838       if (OMP_PARALLEL_FN (node))
1839         {
1840           pp_string (buffer, " [child fn: ");
1841           dump_generic_node (buffer, OMP_PARALLEL_FN (node), spc, flags, false);
1842
1843           pp_string (buffer, " (");
1844
1845           if (OMP_PARALLEL_DATA_ARG (node))
1846             dump_generic_node (buffer, OMP_PARALLEL_DATA_ARG (node), spc, flags,
1847                                false);
1848           else
1849             pp_string (buffer, "???");
1850
1851           pp_string (buffer, ")]");
1852         }
1853
1854     dump_omp_body:
1855       if (!(flags & TDF_SLIM) && OMP_BODY (node))
1856         {
1857           newline_and_indent (buffer, spc + 2);
1858           pp_character (buffer, '{');
1859           newline_and_indent (buffer, spc + 4);
1860           dump_generic_node (buffer, OMP_BODY (node), spc + 4, flags, false);
1861           newline_and_indent (buffer, spc + 2);
1862           pp_character (buffer, '}');
1863         }
1864       is_expr = false;
1865       break;
1866
1867     case OMP_FOR:
1868       pp_string (buffer, "#pragma omp for");
1869       dump_omp_clauses (buffer, OMP_FOR_CLAUSES (node), spc, flags);
1870
1871       if (!(flags & TDF_SLIM))
1872         {
1873           if (OMP_FOR_PRE_BODY (node))
1874             {
1875               newline_and_indent (buffer, spc + 2);
1876               pp_character (buffer, '{');
1877               spc += 4;
1878               newline_and_indent (buffer, spc);
1879               dump_generic_node (buffer, OMP_FOR_PRE_BODY (node),
1880                   spc, flags, false);
1881             }
1882           newline_and_indent (buffer, spc);
1883           pp_string (buffer, "for (");
1884           dump_generic_node (buffer, OMP_FOR_INIT (node), spc, flags, false);
1885           pp_string (buffer, "; ");
1886           dump_generic_node (buffer, OMP_FOR_COND (node), spc, flags, false);
1887           pp_string (buffer, "; ");
1888           dump_generic_node (buffer, OMP_FOR_INCR (node), spc, flags, false);
1889           pp_string (buffer, ")");
1890           if (OMP_FOR_BODY (node))
1891             {
1892               newline_and_indent (buffer, spc + 2);
1893               pp_character (buffer, '{');
1894               newline_and_indent (buffer, spc + 4);
1895               dump_generic_node (buffer, OMP_FOR_BODY (node), spc + 4, flags,
1896                   false);
1897               newline_and_indent (buffer, spc + 2);
1898               pp_character (buffer, '}');
1899             }
1900           if (OMP_FOR_PRE_BODY (node))
1901             {
1902               spc -= 4;
1903               newline_and_indent (buffer, spc + 2);
1904               pp_character (buffer, '}');
1905             }
1906         }
1907       is_expr = false;
1908       break;
1909
1910     case OMP_SECTIONS:
1911       pp_string (buffer, "#pragma omp sections");
1912       if (OMP_SECTIONS_CONTROL (node))
1913         {
1914           pp_string (buffer, " <");
1915           dump_generic_node (buffer, OMP_SECTIONS_CONTROL (node), spc,
1916                              flags, false);
1917           pp_string (buffer, ">");
1918         }
1919       dump_omp_clauses (buffer, OMP_SECTIONS_CLAUSES (node), spc, flags);
1920       goto dump_omp_body;
1921
1922     case OMP_SECTIONS_SWITCH:
1923       pp_string (buffer, "OMP_SECTIONS_SWITCH");
1924       is_expr = false;
1925       break;
1926  
1927     case OMP_SECTION:
1928       pp_string (buffer, "#pragma omp section");
1929       goto dump_omp_body;
1930  
1931     case OMP_MASTER:
1932       pp_string (buffer, "#pragma omp master");
1933       goto dump_omp_body;
1934
1935     case OMP_ORDERED:
1936       pp_string (buffer, "#pragma omp ordered");
1937       goto dump_omp_body;
1938
1939     case OMP_CRITICAL:
1940       pp_string (buffer, "#pragma omp critical");
1941       if (OMP_CRITICAL_NAME (node))
1942         {
1943           pp_space (buffer);
1944           pp_character (buffer, '(');
1945           dump_generic_node (buffer, OMP_CRITICAL_NAME (node), spc,
1946                              flags, false);
1947           pp_character (buffer, ')');
1948         }
1949       goto dump_omp_body;
1950
1951     case OMP_ATOMIC:
1952       pp_string (buffer, "#pragma omp atomic");
1953       newline_and_indent (buffer, spc + 2);
1954       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1955       pp_space (buffer);
1956       pp_character (buffer, '=');
1957       pp_space (buffer);
1958       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1959       break;
1960
1961     case OMP_ATOMIC_LOAD:
1962       pp_string (buffer, "#pragma omp atomic_load");
1963       newline_and_indent (buffer, spc + 2);
1964       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1965       pp_space (buffer);
1966       pp_character (buffer, '=');
1967       pp_space (buffer);
1968       pp_character (buffer, '*');
1969       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1970       break;
1971
1972     case OMP_ATOMIC_STORE:
1973       pp_string (buffer, "#pragma omp atomic_store (");
1974       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1975       pp_character (buffer, ')');
1976       break;
1977
1978     case OMP_SINGLE:
1979       pp_string (buffer, "#pragma omp single");
1980       dump_omp_clauses (buffer, OMP_SINGLE_CLAUSES (node), spc, flags);
1981       goto dump_omp_body;
1982
1983     case OMP_RETURN:
1984       pp_string (buffer, "OMP_RETURN");
1985       if (OMP_RETURN_NOWAIT (node))
1986         pp_string (buffer, " [nowait]");
1987       is_expr = false;
1988       break;
1989
1990     case OMP_CONTINUE:
1991       pp_string (buffer, "OMP_CONTINUE <");
1992       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1993       pp_string (buffer, " <- ");
1994       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1995       pp_string (buffer, ">");
1996       is_expr = false;
1997       break;
1998
1999     case OMP_CLAUSE:
2000       dump_omp_clause (buffer, node, spc, flags);
2001       is_expr = false;
2002       break;
2003
2004     case REDUC_MAX_EXPR:
2005       pp_string (buffer, " REDUC_MAX_EXPR < ");
2006       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
2007       pp_string (buffer, " > ");
2008       break;
2009
2010     case REDUC_MIN_EXPR:
2011       pp_string (buffer, " REDUC_MIN_EXPR < ");
2012       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
2013       pp_string (buffer, " > ");
2014       break;
2015
2016     case REDUC_PLUS_EXPR:
2017       pp_string (buffer, " REDUC_PLUS_EXPR < ");
2018       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
2019       pp_string (buffer, " > ");
2020       break;
2021
2022     case VEC_WIDEN_MULT_HI_EXPR:
2023       pp_string (buffer, " VEC_WIDEN_MULT_HI_EXPR < ");
2024       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
2025       pp_string (buffer, ", ");
2026       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
2027       pp_string (buffer, " > ");
2028       break;
2029
2030     case VEC_WIDEN_MULT_LO_EXPR:
2031       pp_string (buffer, " VEC_WIDEN_MULT_LO_EXPR < ");
2032       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
2033       pp_string (buffer, ", ");
2034       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
2035       pp_string (buffer, " > ");
2036       break;
2037
2038     case VEC_UNPACK_HI_EXPR:
2039       pp_string (buffer, " VEC_UNPACK_HI_EXPR < ");
2040       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
2041       pp_string (buffer, " > ");
2042       break;
2043
2044     case VEC_UNPACK_LO_EXPR:
2045       pp_string (buffer, " VEC_UNPACK_LO_EXPR < ");
2046       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
2047       pp_string (buffer, " > ");
2048       break;
2049
2050     case VEC_UNPACK_FLOAT_HI_EXPR:
2051       pp_string (buffer, " VEC_UNPACK_FLOAT_HI_EXPR < ");
2052       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
2053       pp_string (buffer, " > ");
2054       break;
2055
2056     case VEC_UNPACK_FLOAT_LO_EXPR:
2057       pp_string (buffer, " VEC_UNPACK_FLOAT_LO_EXPR < ");
2058       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
2059       pp_string (buffer, " > ");
2060       break;
2061
2062     case VEC_PACK_TRUNC_EXPR:
2063       pp_string (buffer, " VEC_PACK_TRUNC_EXPR < ");
2064       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
2065       pp_string (buffer, ", ");
2066       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
2067       pp_string (buffer, " > ");
2068       break;
2069
2070     case VEC_PACK_SAT_EXPR:
2071       pp_string (buffer, " VEC_PACK_SAT_EXPR < ");
2072       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
2073       pp_string (buffer, ", ");
2074       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
2075       pp_string (buffer, " > ");
2076       break;
2077
2078     case VEC_PACK_FIX_TRUNC_EXPR:
2079       pp_string (buffer, " VEC_PACK_FIX_TRUNC_EXPR < ");
2080       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
2081       pp_string (buffer, ", ");
2082       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
2083       pp_string (buffer, " > ");
2084       break;
2085
2086     case BLOCK:
2087       {
2088         tree t;
2089         pp_string (buffer, "BLOCK");
2090
2091         if (BLOCK_ABSTRACT (node))
2092           pp_string (buffer, " [abstract]");
2093
2094         if (TREE_ASM_WRITTEN (node))
2095           pp_string (buffer, " [written]");
2096
2097         newline_and_indent (buffer, spc + 2);
2098
2099         if (BLOCK_SUPERCONTEXT (node))
2100           {
2101             pp_string (buffer, "SUPERCONTEXT: ");
2102             if (TREE_CODE (BLOCK_SUPERCONTEXT (node)) == BLOCK)
2103               pp_printf (buffer, "BLOCK %p",
2104                          (void *)BLOCK_SUPERCONTEXT (node));
2105             else
2106               dump_generic_node (buffer, BLOCK_SUPERCONTEXT (node), 0, flags,
2107                                  false);
2108             newline_and_indent (buffer, spc + 2);
2109           }
2110
2111         if (BLOCK_SUBBLOCKS (node))
2112           {
2113             pp_string (buffer, "SUBBLOCKS: ");
2114             for (t = BLOCK_SUBBLOCKS (node); t; t = BLOCK_CHAIN (t))
2115               pp_printf (buffer, "%p ", (void *)t);
2116             newline_and_indent (buffer, spc + 2);
2117           }
2118
2119         if (BLOCK_VARS (node))
2120           {
2121             pp_string (buffer, "VARS: ");
2122             for (t = BLOCK_VARS (node); t; t = TREE_CHAIN (t))
2123               {
2124                 dump_generic_node (buffer, t, 0, flags, false);
2125                 pp_string (buffer, " ");
2126               }
2127             newline_and_indent (buffer, spc + 2);
2128           }
2129
2130         if (BLOCK_ABSTRACT_ORIGIN (node))
2131           {
2132             pp_string (buffer, "ABSTRACT_ORIGIN: ");
2133             if (TREE_CODE (BLOCK_ABSTRACT_ORIGIN (node)) == BLOCK)
2134               pp_printf (buffer, "BLOCK %p",
2135                          (void *)BLOCK_ABSTRACT_ORIGIN (node));
2136             else
2137               dump_generic_node (buffer, BLOCK_ABSTRACT_ORIGIN (node), 0, flags,
2138                                  false);
2139             newline_and_indent (buffer, spc + 2);
2140           }
2141       }
2142     break;
2143
2144     case VEC_EXTRACT_EVEN_EXPR:
2145       pp_string (buffer, " VEC_EXTRACT_EVEN_EXPR < ");
2146       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
2147       pp_string (buffer, ", ");
2148       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
2149       pp_string (buffer, " > ");
2150       break;
2151   
2152     case VEC_EXTRACT_ODD_EXPR:
2153       pp_string (buffer, " VEC_EXTRACT_ODD_EXPR < ");
2154       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
2155       pp_string (buffer, ", ");
2156       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
2157       pp_string (buffer, " > ");
2158       break;
2159
2160     case VEC_INTERLEAVE_HIGH_EXPR:
2161       pp_string (buffer, " VEC_INTERLEAVE_HIGH_EXPR < ");
2162       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
2163       pp_string (buffer, ", ");
2164       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
2165       pp_string (buffer, " > ");
2166       break;
2167
2168     case VEC_INTERLEAVE_LOW_EXPR:
2169       pp_string (buffer, " VEC_INTERLEAVE_LOW_EXPR < ");
2170       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
2171       pp_string (buffer, ", ");
2172       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
2173       pp_string (buffer, " > ");
2174       break;
2175
2176     default:
2177       NIY;
2178     }
2179
2180   if (is_stmt && is_expr)
2181     pp_semicolon (buffer);
2182
2183   /* If we're building a diagnostic, the formatted text will be written
2184      into BUFFER's stream by the caller; otherwise, write it now.  */
2185   if (!(flags & TDF_DIAGNOSTIC))
2186     pp_write_text_to_stream (buffer);
2187
2188   return spc;
2189 }
2190
2191 /* Print the declaration of a variable.  */
2192
2193 static void
2194 print_declaration (pretty_printer *buffer, tree t, int spc, int flags)
2195 {
2196   INDENT (spc);
2197
2198   if (TREE_CODE (t) == TYPE_DECL)
2199     pp_string (buffer, "typedef ");
2200
2201   if (CODE_CONTAINS_STRUCT (TREE_CODE (t), TS_DECL_WRTL) && DECL_REGISTER (t))
2202     pp_string (buffer, "register ");
2203
2204   if (TREE_PUBLIC (t) && DECL_EXTERNAL (t))
2205     pp_string (buffer, "extern ");
2206   else if (TREE_STATIC (t))
2207     pp_string (buffer, "static ");
2208
2209   /* Print the type and name.  */
2210   if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
2211     {
2212       tree tmp;
2213
2214       /* Print array's type.  */
2215       tmp = TREE_TYPE (t);
2216       while (TREE_CODE (TREE_TYPE (tmp)) == ARRAY_TYPE)
2217         tmp = TREE_TYPE (tmp);
2218       dump_generic_node (buffer, TREE_TYPE (tmp), spc, flags, false);
2219
2220       /* Print variable's name.  */
2221       pp_space (buffer);
2222       dump_generic_node (buffer, t, spc, flags, false);
2223
2224       /* Print the dimensions.  */
2225       tmp = TREE_TYPE (t);
2226       while (TREE_CODE (tmp) == ARRAY_TYPE)
2227         {
2228           dump_array_domain (buffer, TYPE_DOMAIN (tmp), spc, flags);
2229           tmp = TREE_TYPE (tmp);
2230         }
2231     }
2232   else if (TREE_CODE (t) == FUNCTION_DECL)
2233     {
2234       dump_generic_node (buffer, TREE_TYPE (TREE_TYPE (t)), spc, flags, false);
2235       pp_space (buffer);
2236       dump_decl_name (buffer, t, flags);
2237       dump_function_declaration (buffer, TREE_TYPE (t), spc, flags);
2238     }
2239   else
2240     {
2241       /* Print type declaration.  */
2242       dump_generic_node (buffer, TREE_TYPE (t), spc, flags, false);
2243
2244       /* Print variable's name.  */
2245       pp_space (buffer);
2246       dump_generic_node (buffer, t, spc, flags, false);
2247     }
2248
2249   if (TREE_CODE (t) == VAR_DECL && DECL_HARD_REGISTER (t))
2250     {
2251       pp_string (buffer, " __asm__ ");
2252       pp_character (buffer, '(');
2253       dump_generic_node (buffer, DECL_ASSEMBLER_NAME (t), spc, flags, false);
2254       pp_character (buffer, ')');
2255     }
2256
2257   /* The initial value of a function serves to determine wether the function
2258      is declared or defined.  So the following does not apply to function
2259      nodes.  */
2260   if (TREE_CODE (t) != FUNCTION_DECL)
2261     {
2262       /* Print the initial value.  */
2263       if (DECL_INITIAL (t))
2264         {
2265           pp_space (buffer);
2266           pp_character (buffer, '=');
2267           pp_space (buffer);
2268           dump_generic_node (buffer, DECL_INITIAL (t), spc, flags, false);
2269         }
2270     }
2271
2272   if (TREE_CODE (t) == VAR_DECL && DECL_HAS_VALUE_EXPR_P (t))
2273     {
2274       pp_string (buffer, " [value-expr: ");
2275       dump_generic_node (buffer, DECL_VALUE_EXPR (t), spc, flags, false);
2276       pp_character (buffer, ']');
2277     }
2278
2279   pp_character (buffer, ';');
2280 }
2281
2282
2283 /* Prints a structure: name, fields, and methods.
2284    FIXME: Still incomplete.  */
2285
2286 static void
2287 print_struct_decl (pretty_printer *buffer, const_tree node, int spc, int flags)
2288 {
2289   /* Print the name of the structure.  */
2290   if (TYPE_NAME (node))
2291     {
2292       INDENT (spc);
2293       if (TREE_CODE (node) == RECORD_TYPE)
2294         pp_string (buffer, "struct ");
2295       else if ((TREE_CODE (node) == UNION_TYPE
2296                 || TREE_CODE (node) == QUAL_UNION_TYPE))
2297         pp_string (buffer, "union ");
2298
2299       dump_generic_node (buffer, TYPE_NAME (node), spc, 0, false);
2300     }
2301
2302   /* Print the contents of the structure.  */
2303   pp_newline (buffer);
2304   INDENT (spc);
2305   pp_character (buffer, '{');
2306   pp_newline (buffer);
2307
2308   /* Print the fields of the structure.  */
2309   {
2310     tree tmp;
2311     tmp = TYPE_FIELDS (node);
2312     while (tmp)
2313       {
2314         /* Avoid to print recursively the structure.  */
2315         /* FIXME : Not implemented correctly...,
2316            what about the case when we have a cycle in the contain graph? ...
2317            Maybe this could be solved by looking at the scope in which the
2318            structure was declared.  */
2319         if (TREE_TYPE (tmp) != node
2320             || (TREE_CODE (TREE_TYPE (tmp)) == POINTER_TYPE
2321                 && TREE_TYPE (TREE_TYPE (tmp)) != node))
2322           {
2323             print_declaration (buffer, tmp, spc+2, flags);
2324             pp_newline (buffer);
2325           }
2326         tmp = TREE_CHAIN (tmp);
2327       }
2328   }
2329   INDENT (spc);
2330   pp_character (buffer, '}');
2331 }
2332
2333 /* Return the priority of the operator OP.
2334
2335    From lowest to highest precedence with either left-to-right (L-R)
2336    or right-to-left (R-L) associativity]:
2337
2338      1  [L-R] ,
2339      2  [R-L] = += -= *= /= %= &= ^= |= <<= >>=
2340      3  [R-L] ?:
2341      4  [L-R] ||
2342      5  [L-R] &&
2343      6  [L-R] |
2344      7  [L-R] ^
2345      8  [L-R] &
2346      9  [L-R] == !=
2347     10  [L-R] < <= > >=
2348     11  [L-R] << >>
2349     12  [L-R] + -
2350     13  [L-R] * / %
2351     14  [R-L] ! ~ ++ -- + - * & (type) sizeof
2352     15  [L-R] fn() [] -> .
2353
2354    unary +, - and * have higher precedence than the corresponding binary
2355    operators.  */
2356
2357 static int
2358 op_prio (const_tree op)
2359 {
2360   if (op == NULL)
2361     return 9999;
2362
2363   switch (TREE_CODE (op))
2364     {
2365     case TREE_LIST:
2366     case COMPOUND_EXPR:
2367     case BIND_EXPR:
2368       return 1;
2369
2370     case MODIFY_EXPR:
2371     case GIMPLE_MODIFY_STMT:
2372     case INIT_EXPR:
2373       return 2;
2374
2375     case COND_EXPR:
2376       return 3;
2377
2378     case TRUTH_OR_EXPR:
2379     case TRUTH_ORIF_EXPR:
2380       return 4;
2381
2382     case TRUTH_AND_EXPR:
2383     case TRUTH_ANDIF_EXPR:
2384       return 5;
2385
2386     case BIT_IOR_EXPR:
2387       return 6;
2388
2389     case BIT_XOR_EXPR:
2390     case TRUTH_XOR_EXPR:
2391       return 7;
2392
2393     case BIT_AND_EXPR:
2394       return 8;
2395
2396     case EQ_EXPR:
2397     case NE_EXPR:
2398       return 9;
2399
2400     case UNLT_EXPR:
2401     case UNLE_EXPR:
2402     case UNGT_EXPR:
2403     case UNGE_EXPR:
2404     case UNEQ_EXPR:
2405     case LTGT_EXPR:
2406     case ORDERED_EXPR:
2407     case UNORDERED_EXPR:
2408     case LT_EXPR:
2409     case LE_EXPR:
2410     case GT_EXPR:
2411     case GE_EXPR:
2412       return 10;
2413
2414     case LSHIFT_EXPR:
2415     case RSHIFT_EXPR:
2416     case LROTATE_EXPR:
2417     case RROTATE_EXPR:
2418       return 11;
2419
2420     case WIDEN_SUM_EXPR:
2421     case PLUS_EXPR:
2422     case POINTER_PLUS_EXPR:
2423     case MINUS_EXPR:
2424       return 12;
2425
2426     case VEC_WIDEN_MULT_HI_EXPR:
2427     case VEC_WIDEN_MULT_LO_EXPR:
2428     case WIDEN_MULT_EXPR:
2429     case DOT_PROD_EXPR:
2430     case MULT_EXPR:
2431     case TRUNC_DIV_EXPR:
2432     case CEIL_DIV_EXPR:
2433     case FLOOR_DIV_EXPR:
2434     case ROUND_DIV_EXPR:
2435     case RDIV_EXPR:
2436     case EXACT_DIV_EXPR:
2437     case TRUNC_MOD_EXPR:
2438     case CEIL_MOD_EXPR:
2439     case FLOOR_MOD_EXPR:
2440     case ROUND_MOD_EXPR:
2441       return 13;
2442
2443     case TRUTH_NOT_EXPR:
2444     case BIT_NOT_EXPR:
2445     case POSTINCREMENT_EXPR:
2446     case POSTDECREMENT_EXPR:
2447     case PREINCREMENT_EXPR:
2448     case PREDECREMENT_EXPR:
2449     case NEGATE_EXPR:
2450     case ALIGN_INDIRECT_REF:
2451     case MISALIGNED_INDIRECT_REF:
2452     case INDIRECT_REF:
2453     case ADDR_EXPR:
2454     case FLOAT_EXPR:
2455     case NOP_EXPR:
2456     case CONVERT_EXPR:
2457     case FIX_TRUNC_EXPR:
2458     case TARGET_EXPR:
2459       return 14;
2460
2461     case CALL_EXPR:
2462     case ARRAY_REF:
2463     case ARRAY_RANGE_REF:
2464     case COMPONENT_REF:
2465       return 15;
2466
2467       /* Special expressions.  */
2468     case MIN_EXPR:
2469     case MAX_EXPR:
2470     case ABS_EXPR:
2471     case REALPART_EXPR:
2472     case IMAGPART_EXPR:
2473     case REDUC_MAX_EXPR:
2474     case REDUC_MIN_EXPR:
2475     case REDUC_PLUS_EXPR:
2476     case VEC_LSHIFT_EXPR:
2477     case VEC_RSHIFT_EXPR:
2478     case VEC_UNPACK_HI_EXPR:
2479     case VEC_UNPACK_LO_EXPR:
2480     case VEC_UNPACK_FLOAT_HI_EXPR:
2481     case VEC_UNPACK_FLOAT_LO_EXPR:
2482     case VEC_PACK_TRUNC_EXPR:
2483     case VEC_PACK_SAT_EXPR:
2484       return 16;
2485
2486     case SAVE_EXPR:
2487     case NON_LVALUE_EXPR:
2488       return op_prio (TREE_OPERAND (op, 0));
2489
2490     default:
2491       /* Return an arbitrarily high precedence to avoid surrounding single
2492          VAR_DECLs in ()s.  */
2493       return 9999;
2494     }
2495 }
2496
2497
2498 /* Return the symbol associated with operator CODE.  */
2499
2500 const char *
2501 op_symbol_code (enum tree_code code)
2502 {
2503   switch (code)
2504     {
2505     case MODIFY_EXPR:
2506     case GIMPLE_MODIFY_STMT:
2507       return "=";
2508
2509     case TRUTH_OR_EXPR:
2510     case TRUTH_ORIF_EXPR:
2511       return "||";
2512
2513     case TRUTH_AND_EXPR:
2514     case TRUTH_ANDIF_EXPR:
2515       return "&&";
2516
2517     case BIT_IOR_EXPR:
2518       return "|";
2519
2520     case TRUTH_XOR_EXPR:
2521     case BIT_XOR_EXPR:
2522       return "^";
2523
2524     case ADDR_EXPR:
2525     case BIT_AND_EXPR:
2526       return "&";
2527
2528     case ORDERED_EXPR:
2529       return "ord";
2530     case UNORDERED_EXPR:
2531       return "unord";
2532
2533     case EQ_EXPR:
2534       return "==";
2535     case UNEQ_EXPR:
2536       return "u==";
2537
2538     case NE_EXPR:
2539       return "!=";
2540
2541     case LT_EXPR:
2542       return "<";
2543     case UNLT_EXPR:
2544       return "u<";
2545
2546     case LE_EXPR:
2547       return "<=";
2548     case UNLE_EXPR:
2549       return "u<=";
2550
2551     case GT_EXPR:
2552       return ">";
2553     case UNGT_EXPR:
2554       return "u>";
2555
2556     case GE_EXPR:
2557       return ">=";
2558     case UNGE_EXPR:
2559       return "u>=";
2560
2561     case LTGT_EXPR:
2562       return "<>";
2563
2564     case LSHIFT_EXPR:
2565       return "<<";
2566
2567     case RSHIFT_EXPR:
2568       return ">>";
2569
2570     case LROTATE_EXPR:
2571       return "r<<";
2572
2573     case RROTATE_EXPR:
2574       return "r>>";
2575
2576     case VEC_LSHIFT_EXPR:
2577       return "v<<";
2578
2579     case VEC_RSHIFT_EXPR:
2580       return "v>>";
2581
2582     case POINTER_PLUS_EXPR:
2583       return "+";
2584  
2585     case PLUS_EXPR:
2586       return "+";
2587
2588     case REDUC_PLUS_EXPR:
2589       return "r+";
2590
2591     case WIDEN_SUM_EXPR:
2592       return "w+";
2593
2594     case WIDEN_MULT_EXPR:
2595       return "w*";
2596
2597     case NEGATE_EXPR:
2598     case MINUS_EXPR:
2599       return "-";
2600
2601     case BIT_NOT_EXPR:
2602       return "~";
2603
2604     case TRUTH_NOT_EXPR:
2605       return "!";
2606
2607     case MULT_EXPR:
2608     case INDIRECT_REF:
2609       return "*";
2610
2611     case ALIGN_INDIRECT_REF:
2612       return "A*";
2613
2614     case MISALIGNED_INDIRECT_REF:
2615       return "M*";
2616
2617     case TRUNC_DIV_EXPR:
2618     case RDIV_EXPR:
2619       return "/";
2620
2621     case CEIL_DIV_EXPR:
2622       return "/[cl]";
2623
2624     case FLOOR_DIV_EXPR:
2625       return "/[fl]";
2626
2627     case ROUND_DIV_EXPR:
2628       return "/[rd]";
2629
2630     case EXACT_DIV_EXPR:
2631       return "/[ex]";
2632
2633     case TRUNC_MOD_EXPR:
2634       return "%";
2635
2636     case CEIL_MOD_EXPR:
2637       return "%[cl]";
2638
2639     case FLOOR_MOD_EXPR:
2640       return "%[fl]";
2641
2642     case ROUND_MOD_EXPR:
2643       return "%[rd]";
2644
2645     case PREDECREMENT_EXPR:
2646       return " --";
2647
2648     case PREINCREMENT_EXPR:
2649       return " ++";
2650
2651     case POSTDECREMENT_EXPR:
2652       return "-- ";
2653
2654     case POSTINCREMENT_EXPR:
2655       return "++ ";
2656
2657     case MAX_EXPR:
2658       return "max";
2659
2660     case MIN_EXPR:
2661       return "min";
2662
2663     default:
2664       return "<<< ??? >>>";
2665     }
2666 }
2667
2668 /* Return the symbol associated with operator OP.  */
2669
2670 static const char *
2671 op_symbol (const_tree op)
2672 {
2673   return op_symbol_code (TREE_CODE (op));
2674 }
2675
2676 /* Prints the name of a CALL_EXPR.  */
2677
2678 static void
2679 print_call_name (pretty_printer *buffer, const_tree node)
2680 {
2681   tree op0;
2682
2683   gcc_assert (TREE_CODE (node) == CALL_EXPR);
2684
2685   op0 = CALL_EXPR_FN (node);
2686
2687   if (TREE_CODE (op0) == NON_LVALUE_EXPR)
2688     op0 = TREE_OPERAND (op0, 0);
2689
2690   switch (TREE_CODE (op0))
2691     {
2692     case VAR_DECL:
2693     case PARM_DECL:
2694       dump_function_name (buffer, op0);
2695       break;
2696
2697     case ADDR_EXPR:
2698     case INDIRECT_REF:
2699     case NOP_EXPR:
2700       dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
2701       break;
2702
2703     case COND_EXPR:
2704       pp_string (buffer, "(");
2705       dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
2706       pp_string (buffer, ") ? ");
2707       dump_generic_node (buffer, TREE_OPERAND (op0, 1), 0, 0, false);
2708       pp_string (buffer, " : ");
2709       dump_generic_node (buffer, TREE_OPERAND (op0, 2), 0, 0, false);
2710       break;
2711
2712     case COMPONENT_REF:
2713       /* The function is a pointer contained in a structure.  */
2714       if (TREE_CODE (TREE_OPERAND (op0, 0)) == INDIRECT_REF ||
2715           TREE_CODE (TREE_OPERAND (op0, 0)) == VAR_DECL)
2716         dump_function_name (buffer, TREE_OPERAND (op0, 1));
2717       else
2718         dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
2719       /* else
2720          We can have several levels of structures and a function
2721          pointer inside.  This is not implemented yet...  */
2722       /*                  NIY;*/
2723       break;
2724
2725     case ARRAY_REF:
2726       if (TREE_CODE (TREE_OPERAND (op0, 0)) == VAR_DECL)
2727         dump_function_name (buffer, TREE_OPERAND (op0, 0));
2728       else
2729         dump_generic_node (buffer, op0, 0, 0, false);
2730       break;
2731
2732     case SSA_NAME:
2733     case OBJ_TYPE_REF:
2734       dump_generic_node (buffer, op0, 0, 0, false);
2735       break;
2736
2737     default:
2738       NIY;
2739     }
2740 }
2741
2742 /* Parses the string STR and replaces new-lines by '\n', tabs by '\t', ...  */
2743
2744 static void
2745 pretty_print_string (pretty_printer *buffer, const char *str)
2746 {
2747   if (str == NULL)
2748     return;
2749
2750   while (*str)
2751     {
2752       switch (str[0])
2753         {
2754         case '\b':
2755           pp_string (buffer, "\\b");
2756           break;
2757
2758         case '\f':
2759           pp_string (buffer, "\\f");
2760           break;
2761
2762         case '\n':
2763           pp_string (buffer, "\\n");
2764           break;
2765
2766         case '\r':
2767           pp_string (buffer, "\\r");
2768           break;
2769
2770         case '\t':
2771           pp_string (buffer, "\\t");
2772           break;
2773
2774         case '\v':
2775           pp_string (buffer, "\\v");
2776           break;
2777
2778         case '\\':
2779           pp_string (buffer, "\\\\");
2780           break;
2781
2782         case '\"':
2783           pp_string (buffer, "\\\"");
2784           break;
2785
2786         case '\'':
2787           pp_string (buffer, "\\'");
2788           break;
2789
2790           /* No need to handle \0; the loop terminates on \0.  */
2791
2792         case '\1':
2793           pp_string (buffer, "\\1");
2794           break;
2795
2796         case '\2':
2797           pp_string (buffer, "\\2");
2798           break;
2799
2800         case '\3':
2801           pp_string (buffer, "\\3");
2802           break;
2803
2804         case '\4':
2805           pp_string (buffer, "\\4");
2806           break;
2807
2808         case '\5':
2809           pp_string (buffer, "\\5");
2810           break;
2811
2812         case '\6':
2813           pp_string (buffer, "\\6");
2814           break;
2815
2816         case '\7':
2817           pp_string (buffer, "\\7");
2818           break;
2819
2820         default:
2821           pp_character (buffer, str[0]);
2822           break;
2823         }
2824       str++;
2825     }
2826 }
2827
2828 static void
2829 maybe_init_pretty_print (FILE *file)
2830 {
2831   if (!initialized)
2832     {
2833       pp_construct (&buffer, /* prefix */NULL, /* line-width */0);
2834       pp_needs_newline (&buffer) = true;
2835       initialized = 1;
2836     }
2837
2838   buffer.buffer->stream = file;
2839 }
2840
2841 static void
2842 newline_and_indent (pretty_printer *buffer, int spc)
2843 {
2844   pp_newline (buffer);
2845   INDENT (spc);
2846 }
2847
2848
2849 static void
2850 dump_vops (pretty_printer *buffer, tree stmt, int spc, int flags)
2851 {
2852   struct voptype_d *vdefs;
2853   struct voptype_d *vuses;
2854   int i, n;
2855
2856   if (!ssa_operands_active () || !stmt_references_memory_p (stmt))
2857     return;
2858
2859   /* Even if the statement doesn't have virtual operators yet, it may
2860      contain symbol information (this happens before aliases have been
2861      computed).  */
2862   if ((flags & TDF_MEMSYMS)
2863       && VUSE_OPS (stmt) == NULL
2864       && VDEF_OPS (stmt) == NULL)
2865     {
2866       if (LOADED_SYMS (stmt))
2867         {
2868           pp_string (buffer, "# LOADS: ");
2869           dump_symbols (buffer, LOADED_SYMS (stmt), flags);
2870           newline_and_indent (buffer, spc);
2871         }
2872
2873       if (STORED_SYMS (stmt))
2874         {
2875           pp_string (buffer, "# STORES: ");
2876           dump_symbols (buffer, STORED_SYMS (stmt), flags);
2877           newline_and_indent (buffer, spc);
2878         }
2879
2880       return;
2881     }
2882
2883   vuses = VUSE_OPS (stmt);
2884   while (vuses)
2885     {
2886       pp_string (buffer, "# VUSE <");
2887
2888       n = VUSE_NUM (vuses);
2889       for (i = 0; i < n; i++)
2890         {
2891           dump_generic_node (buffer, VUSE_OP (vuses, i), spc + 2, flags, false);
2892           if (i < n - 1)
2893             pp_string (buffer, ", ");
2894         }
2895
2896       pp_string (buffer, ">");
2897
2898       if (flags & TDF_MEMSYMS)
2899         dump_symbols (buffer, LOADED_SYMS (stmt), flags);
2900
2901       newline_and_indent (buffer, spc);
2902       vuses = vuses->next;
2903     }
2904
2905   vdefs = VDEF_OPS (stmt);
2906   while (vdefs)
2907     {
2908       pp_string (buffer, "# ");
2909       dump_generic_node (buffer, VDEF_RESULT (vdefs), spc + 2, flags, false);
2910       pp_string (buffer, " = VDEF <");
2911
2912       n = VDEF_NUM (vdefs);
2913       for (i = 0; i < n; i++)
2914         {
2915           dump_generic_node (buffer, VDEF_OP (vdefs, i), spc + 2, flags, 0);
2916           if (i < n - 1)
2917             pp_string (buffer, ", ");
2918         }
2919
2920       pp_string (buffer, ">");
2921
2922       if ((flags & TDF_MEMSYMS) && vdefs->next == NULL)
2923         dump_symbols (buffer, STORED_SYMS (stmt), flags);
2924
2925       newline_and_indent (buffer, spc);
2926       vdefs = vdefs->next;
2927     }
2928 }
2929
2930
2931 /* Dumps basic block BB to FILE with details described by FLAGS and
2932    indented by INDENT spaces.  */
2933
2934 void
2935 dump_generic_bb (FILE *file, basic_block bb, int indent, int flags)
2936 {
2937   maybe_init_pretty_print (file);
2938   dump_generic_bb_buff (&buffer, bb, indent, flags);
2939   pp_flush (&buffer);
2940 }
2941
2942 /* Dumps header of basic block BB to buffer BUFFER indented by INDENT
2943    spaces and details described by flags.  */
2944
2945 static void
2946 dump_bb_header (pretty_printer *buffer, basic_block bb, int indent, int flags)
2947 {
2948   edge e;
2949   tree stmt;
2950   edge_iterator ei;
2951
2952   if (flags & TDF_BLOCKS)
2953     {
2954       INDENT (indent);
2955       pp_string (buffer, "# BLOCK ");
2956       pp_decimal_int (buffer, bb->index);
2957       if (bb->frequency)
2958         {
2959           pp_string (buffer, " freq:");
2960           pp_decimal_int (buffer, bb->frequency);
2961         }
2962       if (bb->count)
2963         {
2964           pp_string (buffer, " count:");
2965           pp_widest_integer (buffer, bb->count);
2966         }
2967
2968       if (flags & TDF_LINENO)
2969         {
2970           block_stmt_iterator bsi;
2971
2972           for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
2973             if (get_lineno (bsi_stmt (bsi)) != -1)
2974               {
2975                 pp_string (buffer, ", starting at line ");
2976                 pp_decimal_int (buffer, get_lineno (bsi_stmt (bsi)));
2977                 break;
2978               }
2979         }
2980       newline_and_indent (buffer, indent);
2981
2982       pp_string (buffer, "# PRED:");
2983       pp_write_text_to_stream (buffer);
2984       FOR_EACH_EDGE (e, ei, bb->preds)
2985         if (flags & TDF_SLIM)
2986           {
2987             pp_string (buffer, " ");
2988             if (e->src == ENTRY_BLOCK_PTR)
2989               pp_string (buffer, "ENTRY");
2990             else
2991               pp_decimal_int (buffer, e->src->index);
2992           }
2993         else
2994           dump_edge_info (buffer->buffer->stream, e, 0);
2995       pp_newline (buffer);
2996     }
2997   else
2998     {
2999       stmt = first_stmt (bb);
3000       if (!stmt || TREE_CODE (stmt) != LABEL_EXPR)
3001         {
3002           INDENT (indent - 2);
3003           pp_string (buffer, "<bb ");
3004           pp_decimal_int (buffer, bb->index);
3005           pp_string (buffer, ">:");
3006           pp_newline (buffer);
3007         }
3008     }
3009   pp_write_text_to_stream (buffer);
3010   check_bb_profile (bb, buffer->buffer->stream);
3011 }
3012
3013 /* Dumps end of basic block BB to buffer BUFFER indented by INDENT
3014    spaces.  */
3015
3016 static void
3017 dump_bb_end (pretty_printer *buffer, basic_block bb, int indent, int flags)
3018 {
3019   edge e;
3020   edge_iterator ei;
3021
3022   INDENT (indent);
3023   pp_string (buffer, "# SUCC:");
3024   pp_write_text_to_stream (buffer);
3025   FOR_EACH_EDGE (e, ei, bb->succs)
3026     if (flags & TDF_SLIM)
3027       {
3028         pp_string (buffer, " ");
3029         if (e->dest == EXIT_BLOCK_PTR)
3030           pp_string (buffer, "EXIT");
3031         else
3032           pp_decimal_int (buffer, e->dest->index);
3033       }
3034     else
3035       dump_edge_info (buffer->buffer->stream, e, 1);
3036   pp_newline (buffer);
3037 }
3038
3039 /* Dump PHI nodes of basic block BB to BUFFER with details described
3040    by FLAGS and indented by INDENT spaces.  */
3041
3042 static void
3043 dump_phi_nodes (pretty_printer *buffer, basic_block bb, int indent, int flags)
3044 {
3045   tree phi = phi_nodes (bb);
3046   if (!phi)
3047     return;
3048
3049   for (; phi; phi = PHI_CHAIN (phi))
3050     {
3051       if (is_gimple_reg (PHI_RESULT (phi)) || (flags & TDF_VOPS))
3052         {
3053           INDENT (indent);
3054           pp_string (buffer, "# ");
3055           dump_generic_node (buffer, phi, indent, flags, false);
3056           pp_newline (buffer);
3057         }
3058     }
3059 }
3060
3061
3062 /* Dump jump to basic block BB that is represented implicitly in the cfg
3063    to BUFFER.  */
3064
3065 static void
3066 pp_cfg_jump (pretty_printer *buffer, basic_block bb)
3067 {
3068   tree stmt;
3069
3070   stmt = first_stmt (bb);
3071
3072   pp_string (buffer, "goto <bb ");
3073   pp_decimal_int (buffer, bb->index);
3074   pp_string (buffer, ">");
3075   if (stmt && TREE_CODE (stmt) == LABEL_EXPR)
3076     {
3077       pp_string (buffer, " (");
3078       dump_generic_node (buffer, LABEL_EXPR_LABEL (stmt), 0, 0, false);
3079       pp_string (buffer, ")");
3080     }
3081   pp_semicolon (buffer);
3082 }
3083
3084 /* Dump edges represented implicitly in basic block BB to BUFFER, indented
3085    by INDENT spaces, with details given by FLAGS.  */
3086
3087 static void
3088 dump_implicit_edges (pretty_printer *buffer, basic_block bb, int indent,
3089                      int flags)
3090 {
3091   edge e;
3092   edge_iterator ei;
3093   tree stmt;
3094
3095   stmt = last_stmt (bb);
3096   if (stmt && TREE_CODE (stmt) == COND_EXPR)
3097     {
3098       edge true_edge, false_edge;
3099
3100       /* When we are emitting the code or changing CFG, it is possible that
3101          the edges are not yet created.  When we are using debug_bb in such
3102          a situation, we do not want it to crash.  */
3103       if (EDGE_COUNT (bb->succs) != 2)
3104         return;
3105       extract_true_false_edges_from_block (bb, &true_edge, &false_edge);
3106
3107       INDENT (indent + 2);
3108       pp_cfg_jump (buffer, true_edge->dest);
3109       newline_and_indent (buffer, indent);
3110       pp_string (buffer, "else");
3111       newline_and_indent (buffer, indent + 2);
3112       pp_cfg_jump (buffer, false_edge->dest);
3113       pp_newline (buffer);
3114       return;
3115     }
3116
3117   /* If there is a fallthru edge, we may need to add an artificial goto to the
3118      dump.  */
3119   FOR_EACH_EDGE (e, ei, bb->succs)
3120     if (e->flags & EDGE_FALLTHRU)
3121       break;
3122   if (e && e->dest != bb->next_bb)
3123     {
3124       INDENT (indent);
3125
3126       if ((flags & TDF_LINENO) && e->goto_locus != UNKNOWN_LOCATION)
3127         {
3128           expanded_location goto_xloc;
3129           goto_xloc = expand_location (e->goto_locus);
3130           pp_character (buffer, '[');
3131           if (goto_xloc.file)
3132             {
3133               pp_string (buffer, goto_xloc.file);
3134               pp_string (buffer, " : ");
3135             }
3136           pp_decimal_int (buffer, goto_xloc.line);
3137           pp_string (buffer, "] ");
3138         }
3139
3140       pp_cfg_jump (buffer, e->dest);
3141       pp_newline (buffer);
3142     }
3143 }
3144
3145 /* Dumps basic block BB to buffer BUFFER with details described by FLAGS and
3146    indented by INDENT spaces.  */
3147
3148 static void
3149 dump_generic_bb_buff (pretty_printer *buffer, basic_block bb,
3150                       int indent, int flags)
3151 {
3152   block_stmt_iterator bsi;
3153   tree stmt;
3154   int label_indent = indent - 2;
3155
3156   if (label_indent < 0)
3157     label_indent = 0;
3158
3159   dump_bb_header (buffer, bb, indent, flags);
3160
3161   dump_phi_nodes (buffer, bb, indent, flags);
3162
3163   for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
3164     {
3165       int curr_indent;
3166
3167       stmt = bsi_stmt (bsi);
3168
3169       curr_indent = TREE_CODE (stmt) == LABEL_EXPR ? label_indent : indent;
3170
3171       INDENT (curr_indent);
3172       dump_generic_node (buffer, stmt, curr_indent, flags, true);
3173       pp_newline (buffer);
3174       dump_histograms_for_stmt (cfun, buffer->buffer->stream, stmt);
3175     }
3176
3177   dump_implicit_edges (buffer, bb, indent, flags);
3178
3179   if (flags & TDF_BLOCKS)
3180     dump_bb_end (buffer, bb, indent, flags);
3181 }