OSDN Git Service

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