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