OSDN Git Service

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