OSDN Git Service

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