OSDN Git Service

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