OSDN Git Service

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