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
6This file is part of GCC.
7
8GCC is free software; you can redistribute it and/or modify it under
9the terms of the GNU General Public License as published by the Free
10Software Foundation; either version 2, or (at your option) any later
11version.
12
13GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14WARRANTY; without even the implied warranty of MERCHANTABILITY or
15FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16for more details.
17
18You should have received a copy of the GNU General Public License
19along with GCC; see the file COPYING.  If not, write to the Free
20Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
2102110-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.  */
38static int op_prio (tree);
39static const char *op_symbol_1 (enum tree_code);
40static const char *op_symbol (tree);
41static void pretty_print_string (pretty_printer *, const char*);
42static void print_call_name (pretty_printer *, tree);
43static void newline_and_indent (pretty_printer *, int);
44static void maybe_init_pretty_print (FILE *);
45static void print_declaration (pretty_printer *, tree, int, int);
46static void print_struct_decl (pretty_printer *, tree, int, int);
47static void do_niy (pretty_printer *, tree);
48static void dump_vops (pretty_printer *, tree, int, int);
49static 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
61static pretty_printer buffer;
62static int initialized = 0;
63
64/* Try to print something for an unknown tree code.  */
65
66static void
67do_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
87void
88debug_generic_expr (tree t)
89{
90  print_generic_expr (stderr, t, TDF_VOPS|TDF_UID);
91  fprintf (stderr, "\n");
92}
93
94void
95debug_generic_stmt (tree t)
96{
97  print_generic_stmt (stderr, t, TDF_VOPS|TDF_UID);
98  fprintf (stderr, "\n");
99}
100
101void
102debug_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.  */
114void
115print_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
125void
126print_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
137void
138print_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
153void
154print_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
163static void
164dump_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
187static void
188dump_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
199static void
200dump_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
232static void
233dump_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
263static void
264dump_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
387static void
388dump_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
410int
411dump_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
1931static void
1932print_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
2024static void
2025print_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
2095static int
2096op_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
2231static const char *
2232op_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
2395static const char *
2396op_symbol (tree op)
2397{
2398  return op_symbol_1 (TREE_CODE (op));
2399}
2400
2401/* Prints the name of a CALL_EXPR.  */
2402
2403static void
2404print_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
2469static void
2470pretty_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
2553static void
2554maybe_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
2566static void
2567newline_and_indent (pretty_printer *buffer, int spc)
2568{
2569  pp_newline (buffer);
2570  INDENT (spc);
2571}
2572
2573static void
2574dump_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
2621void
2622dump_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
2632static void
2633dump_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
2703static void
2704dump_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
2729static void
2730dump_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
2751static void
2752pp_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
2773static void
2774dump_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
2821static void
2822dump_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