OSDN Git Service

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