OSDN Git Service

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