OSDN Git Service

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