1169689Skan/* Pretty formatting of GENERIC trees in C syntax.
2169689Skan   Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006
3169689Skan   Free Software Foundation, Inc.
4169689Skan   Adapted from c-pretty-print.c by Diego Novillo <dnovillo@redhat.com>
5169689Skan
6169689SkanThis file is part of GCC.
7169689Skan
8169689SkanGCC is free software; you can redistribute it and/or modify it under
9169689Skanthe terms of the GNU General Public License as published by the Free
10169689SkanSoftware Foundation; either version 2, or (at your option) any later
11169689Skanversion.
12169689Skan
13169689SkanGCC is distributed in the hope that it will be useful, but WITHOUT ANY
14169689SkanWARRANTY; without even the implied warranty of MERCHANTABILITY or
15169689SkanFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16169689Skanfor more details.
17169689Skan
18169689SkanYou should have received a copy of the GNU General Public License
19169689Skanalong with GCC; see the file COPYING.  If not, write to the Free
20169689SkanSoftware Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
21169689Skan02110-1301, USA.  */
22169689Skan
23169689Skan#include "config.h"
24169689Skan#include "system.h"
25169689Skan#include "coretypes.h"
26169689Skan#include "tm.h"
27169689Skan#include "tree.h"
28169689Skan#include "diagnostic.h"
29169689Skan#include "real.h"
30169689Skan#include "hashtab.h"
31169689Skan#include "tree-flow.h"
32169689Skan#include "langhooks.h"
33169689Skan#include "tree-iterator.h"
34169689Skan#include "tree-chrec.h"
35169689Skan#include "tree-pass.h"
36169689Skan
37169689Skan/* Local functions, macros and variables.  */
38169689Skanstatic int op_prio (tree);
39169689Skanstatic const char *op_symbol_1 (enum tree_code);
40169689Skanstatic const char *op_symbol (tree);
41169689Skanstatic void pretty_print_string (pretty_printer *, const char*);
42169689Skanstatic void print_call_name (pretty_printer *, tree);
43169689Skanstatic void newline_and_indent (pretty_printer *, int);
44169689Skanstatic void maybe_init_pretty_print (FILE *);
45169689Skanstatic void print_declaration (pretty_printer *, tree, int, int);
46169689Skanstatic void print_struct_decl (pretty_printer *, tree, int, int);
47169689Skanstatic void do_niy (pretty_printer *, tree);
48169689Skanstatic void dump_vops (pretty_printer *, tree, int, int);
49169689Skanstatic void dump_generic_bb_buff (pretty_printer *, basic_block, int, int);
50169689Skan
51169689Skan#define INDENT(SPACE) do { \
52169689Skan  int i; for (i = 0; i<SPACE; i++) pp_space (buffer); } while (0)
53169689Skan
54169689Skan#define NIY do_niy(buffer,node)
55169689Skan
56169689Skan#define PRINT_FUNCTION_NAME(NODE)  pp_printf             \
57169689Skan  (buffer, "%s", TREE_CODE (NODE) == NOP_EXPR ?              \
58169689Skan   lang_hooks.decl_printable_name (TREE_OPERAND (NODE, 0), 1) : \
59169689Skan   lang_hooks.decl_printable_name (NODE, 1))
60169689Skan
61169689Skanstatic pretty_printer buffer;
62169689Skanstatic int initialized = 0;
63169689Skan
64169689Skan/* Try to print something for an unknown tree code.  */
65169689Skan
66169689Skanstatic void
67169689Skando_niy (pretty_printer *buffer, tree node)
68169689Skan{
69169689Skan  int i, len;
70169689Skan
71169689Skan  pp_string (buffer, "<<< Unknown tree: ");
72169689Skan  pp_string (buffer, tree_code_name[(int) TREE_CODE (node)]);
73169689Skan
74169689Skan  if (EXPR_P (node))
75169689Skan    {
76169689Skan      len = TREE_CODE_LENGTH (TREE_CODE (node));
77169689Skan      for (i = 0; i < len; ++i)
78169689Skan	{
79169689Skan	  newline_and_indent (buffer, 2);
80169689Skan	  dump_generic_node (buffer, TREE_OPERAND (node, i), 2, 0, false);
81169689Skan	}
82169689Skan    }
83169689Skan
84169689Skan  pp_string (buffer, " >>>\n");
85169689Skan}
86169689Skan
87169689Skanvoid
88169689Skandebug_generic_expr (tree t)
89169689Skan{
90169689Skan  print_generic_expr (stderr, t, TDF_VOPS|TDF_UID);
91169689Skan  fprintf (stderr, "\n");
92169689Skan}
93169689Skan
94169689Skanvoid
95169689Skandebug_generic_stmt (tree t)
96169689Skan{
97169689Skan  print_generic_stmt (stderr, t, TDF_VOPS|TDF_UID);
98169689Skan  fprintf (stderr, "\n");
99169689Skan}
100169689Skan
101169689Skanvoid
102169689Skandebug_tree_chain (tree t)
103169689Skan{
104169689Skan  while (t)
105169689Skan  {
106169689Skan    print_generic_expr (stderr, t, TDF_VOPS|TDF_UID);
107169689Skan    fprintf(stderr, " ");
108169689Skan    t = TREE_CHAIN (t);
109169689Skan  }
110169689Skan  fprintf (stderr, "\n");
111169689Skan}
112169689Skan
113169689Skan/* Prints declaration DECL to the FILE with details specified by FLAGS.  */
114169689Skanvoid
115169689Skanprint_generic_decl (FILE *file, tree decl, int flags)
116169689Skan{
117169689Skan  maybe_init_pretty_print (file);
118169689Skan  print_declaration (&buffer, decl, 2, flags);
119169689Skan  pp_write_text_to_stream (&buffer);
120169689Skan}
121169689Skan
122169689Skan/* Print tree T, and its successors, on file FILE.  FLAGS specifies details
123169689Skan   to show in the dump.  See TDF_* in tree.h.  */
124169689Skan
125169689Skanvoid
126169689Skanprint_generic_stmt (FILE *file, tree t, int flags)
127169689Skan{
128169689Skan  maybe_init_pretty_print (file);
129169689Skan  dump_generic_node (&buffer, t, 0, flags, true);
130169689Skan  pp_flush (&buffer);
131169689Skan}
132169689Skan
133169689Skan/* Print tree T, and its successors, on file FILE.  FLAGS specifies details
134169689Skan   to show in the dump.  See TDF_* in tree.h.  The output is indented by
135169689Skan   INDENT spaces.  */
136169689Skan
137169689Skanvoid
138169689Skanprint_generic_stmt_indented (FILE *file, tree t, int flags, int indent)
139169689Skan{
140169689Skan  int i;
141169689Skan
142169689Skan  maybe_init_pretty_print (file);
143169689Skan
144169689Skan  for (i = 0; i < indent; i++)
145169689Skan    pp_space (&buffer);
146169689Skan  dump_generic_node (&buffer, t, indent, flags, true);
147169689Skan  pp_flush (&buffer);
148169689Skan}
149169689Skan
150169689Skan/* Print a single expression T on file FILE.  FLAGS specifies details to show
151169689Skan   in the dump.  See TDF_* in tree.h.  */
152169689Skan
153169689Skanvoid
154169689Skanprint_generic_expr (FILE *file, tree t, int flags)
155169689Skan{
156169689Skan  maybe_init_pretty_print (file);
157169689Skan  dump_generic_node (&buffer, t, 0, flags, false);
158169689Skan}
159169689Skan
160169689Skan/* Dump the name of a _DECL node and its DECL_UID if TDF_UID is set
161169689Skan   in FLAGS.  */
162169689Skan
163169689Skanstatic void
164169689Skandump_decl_name (pretty_printer *buffer, tree node, int flags)
165169689Skan{
166169689Skan  tree t = node;
167169689Skan
168169689Skan  if (DECL_NAME (t))
169169689Skan    pp_tree_identifier (buffer, DECL_NAME (t));
170169689Skan  if ((flags & TDF_UID)
171169689Skan      || DECL_NAME (t) == NULL_TREE)
172169689Skan    {
173169689Skan      if (TREE_CODE (t) == LABEL_DECL
174169689Skan          && LABEL_DECL_UID (t) != -1)
175169689Skan        pp_printf (buffer, "L." HOST_WIDE_INT_PRINT_DEC,
176169689Skan		   LABEL_DECL_UID (t));
177169689Skan      else
178169689Skan	{
179169689Skan	  char c = TREE_CODE (t) == CONST_DECL ? 'C' : 'D';
180169689Skan	  pp_printf (buffer, "%c.%u", c, DECL_UID (t));
181169689Skan	}
182169689Skan    }
183169689Skan}
184169689Skan
185169689Skan/* Like the above, but used for pretty printing function calls.  */
186169689Skan
187169689Skanstatic void
188169689Skandump_function_name (pretty_printer *buffer, tree node)
189169689Skan{
190169689Skan  if (DECL_NAME (node))
191169689Skan    PRINT_FUNCTION_NAME (node);
192169689Skan  else
193169689Skan    dump_decl_name (buffer, node, 0);
194169689Skan}
195169689Skan
196169689Skan/* Dump a function declaration.  NODE is the FUNCTION_TYPE.  BUFFER, SPC and
197169689Skan   FLAGS are as in dump_generic_node.  */
198169689Skan
199169689Skanstatic void
200169689Skandump_function_declaration (pretty_printer *buffer, tree node,
201169689Skan			   int spc, int flags)
202169689Skan{
203169689Skan  bool wrote_arg = false;
204169689Skan  tree arg;
205169689Skan
206169689Skan  pp_space (buffer);
207169689Skan  pp_character (buffer, '(');
208169689Skan
209169689Skan  /* Print the argument types.  The last element in the list is a VOID_TYPE.
210169689Skan     The following avoids printing the last element.  */
211169689Skan  arg = TYPE_ARG_TYPES (node);
212169689Skan  while (arg && TREE_CHAIN (arg) && arg != error_mark_node)
213169689Skan    {
214169689Skan      wrote_arg = true;
215169689Skan      dump_generic_node (buffer, TREE_VALUE (arg), spc, flags, false);
216169689Skan      arg = TREE_CHAIN (arg);
217169689Skan      if (TREE_CHAIN (arg) && TREE_CODE (TREE_CHAIN (arg)) == TREE_LIST)
218169689Skan	{
219169689Skan	  pp_character (buffer, ',');
220169689Skan	  pp_space (buffer);
221169689Skan	}
222169689Skan    }
223169689Skan
224169689Skan  if (!wrote_arg)
225169689Skan    pp_string (buffer, "void");
226169689Skan
227169689Skan  pp_character (buffer, ')');
228169689Skan}
229169689Skan
230169689Skan/* Dump the domain associated with an array.  */
231169689Skan
232169689Skanstatic void
233169689Skandump_array_domain (pretty_printer *buffer, tree domain, int spc, int flags)
234169689Skan{
235169689Skan  pp_character (buffer, '[');
236169689Skan  if (domain)
237169689Skan    {
238169689Skan      tree min = TYPE_MIN_VALUE (domain);
239169689Skan      tree max = TYPE_MAX_VALUE (domain);
240169689Skan
241169689Skan      if (min && max
242169689Skan	  && integer_zerop (min)
243169689Skan	  && host_integerp (max, 0))
244169689Skan	pp_wide_integer (buffer, TREE_INT_CST_LOW (max) + 1);
245169689Skan      else
246169689Skan	{
247169689Skan	  if (min)
248169689Skan	    dump_generic_node (buffer, min, spc, flags, false);
249169689Skan	  pp_character (buffer, ':');
250169689Skan	  if (max)
251169689Skan	    dump_generic_node (buffer, max, spc, flags, false);
252169689Skan	}
253169689Skan    }
254169689Skan  else
255169689Skan    pp_string (buffer, "<unknown>");
256169689Skan  pp_character (buffer, ']');
257169689Skan}
258169689Skan
259169689Skan
260169689Skan/* Dump OpenMP clause CLAUSE.  BUFFER, CLAUSE, SPC and FLAGS are as in
261169689Skan   dump_generic_node.  */
262169689Skan
263169689Skanstatic void
264169689Skandump_omp_clause (pretty_printer *buffer, tree clause, int spc, int flags)
265169689Skan{
266169689Skan  const char *name;
267169689Skan
268169689Skan  switch (OMP_CLAUSE_CODE (clause))
269169689Skan    {
270169689Skan    case OMP_CLAUSE_PRIVATE:
271169689Skan      name = "private";
272169689Skan      goto print_remap;
273169689Skan    case OMP_CLAUSE_SHARED:
274169689Skan      name = "shared";
275169689Skan      goto print_remap;
276169689Skan    case OMP_CLAUSE_FIRSTPRIVATE:
277169689Skan      name = "firstprivate";
278169689Skan      goto print_remap;
279169689Skan    case OMP_CLAUSE_LASTPRIVATE:
280169689Skan      name = "lastprivate";
281169689Skan      goto print_remap;
282169689Skan    case OMP_CLAUSE_COPYIN:
283169689Skan      name = "copyin";
284169689Skan      goto print_remap;
285169689Skan    case OMP_CLAUSE_COPYPRIVATE:
286169689Skan      name = "copyprivate";
287169689Skan      goto print_remap;
288169689Skan  print_remap:
289169689Skan      pp_string (buffer, name);
290169689Skan      pp_character (buffer, '(');
291169689Skan      dump_generic_node (buffer, OMP_CLAUSE_DECL (clause),
292169689Skan	  spc, flags, false);
293169689Skan      pp_character (buffer, ')');
294169689Skan      break;
295169689Skan
296169689Skan    case OMP_CLAUSE_REDUCTION:
297169689Skan      pp_string (buffer, "reduction(");
298169689Skan      pp_string (buffer, op_symbol_1 (OMP_CLAUSE_REDUCTION_CODE (clause)));
299169689Skan      pp_character (buffer, ':');
300169689Skan      dump_generic_node (buffer, OMP_CLAUSE_DECL (clause),
301169689Skan	  spc, flags, false);
302169689Skan      pp_character (buffer, ')');
303169689Skan      break;
304169689Skan
305169689Skan    case OMP_CLAUSE_IF:
306169689Skan      pp_string (buffer, "if(");
307169689Skan      dump_generic_node (buffer, OMP_CLAUSE_IF_EXPR (clause),
308169689Skan	  spc, flags, false);
309169689Skan      pp_character (buffer, ')');
310169689Skan      break;
311169689Skan
312169689Skan    case OMP_CLAUSE_NUM_THREADS:
313169689Skan      pp_string (buffer, "num_threads(");
314169689Skan      dump_generic_node (buffer, OMP_CLAUSE_NUM_THREADS_EXPR (clause),
315169689Skan	  spc, flags, false);
316169689Skan      pp_character (buffer, ')');
317169689Skan      break;
318169689Skan
319169689Skan    case OMP_CLAUSE_NOWAIT:
320169689Skan      pp_string (buffer, "nowait");
321169689Skan      break;
322169689Skan    case OMP_CLAUSE_ORDERED:
323169689Skan      pp_string (buffer, "ordered");
324169689Skan      break;
325169689Skan
326169689Skan    case OMP_CLAUSE_DEFAULT:
327169689Skan      pp_string (buffer, "default(");
328169689Skan      switch (OMP_CLAUSE_DEFAULT_KIND (clause))
329169689Skan	{
330169689Skan      case OMP_CLAUSE_DEFAULT_UNSPECIFIED:
331169689Skan	break;
332169689Skan      case OMP_CLAUSE_DEFAULT_SHARED:
333169689Skan	pp_string (buffer, "shared");
334169689Skan	break;
335169689Skan      case OMP_CLAUSE_DEFAULT_NONE:
336169689Skan	pp_string (buffer, "none");
337169689Skan	break;
338169689Skan      case OMP_CLAUSE_DEFAULT_PRIVATE:
339169689Skan	pp_string (buffer, "private");
340169689Skan	break;
341169689Skan      default:
342169689Skan	gcc_unreachable ();
343169689Skan	}
344169689Skan      pp_character (buffer, ')');
345169689Skan      break;
346169689Skan
347169689Skan    case OMP_CLAUSE_SCHEDULE:
348169689Skan      pp_string (buffer, "schedule(");
349169689Skan      switch (OMP_CLAUSE_SCHEDULE_KIND (clause))
350169689Skan	{
351169689Skan      case OMP_CLAUSE_SCHEDULE_STATIC:
352169689Skan	pp_string (buffer, "static");
353169689Skan	break;
354169689Skan      case OMP_CLAUSE_SCHEDULE_DYNAMIC:
355169689Skan	pp_string (buffer, "dynamic");
356169689Skan	break;
357169689Skan      case OMP_CLAUSE_SCHEDULE_GUIDED:
358169689Skan	pp_string (buffer, "guided");
359169689Skan	break;
360169689Skan      case OMP_CLAUSE_SCHEDULE_RUNTIME:
361169689Skan	pp_string (buffer, "runtime");
362169689Skan	break;
363169689Skan      default:
364169689Skan	gcc_unreachable ();
365169689Skan	}
366169689Skan      if (OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (clause))
367169689Skan	{
368169689Skan	  pp_character (buffer, ',');
369169689Skan	  dump_generic_node (buffer,
370169689Skan	      OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (clause),
371169689Skan	      spc, flags, false);
372169689Skan	}
373169689Skan      pp_character (buffer, ')');
374169689Skan      break;
375169689Skan
376169689Skan    default:
377169689Skan      /* Should never happen.  */
378169689Skan      dump_generic_node (buffer, clause, spc, flags, false);
379169689Skan      break;
380169689Skan    }
381169689Skan}
382169689Skan
383169689Skan
384169689Skan/* Dump the list of OpenMP clauses.  BUFFER, SPC and FLAGS are as in
385169689Skan   dump_generic_node.  */
386169689Skan
387169689Skanstatic void
388169689Skandump_omp_clauses (pretty_printer *buffer, tree clause, int spc, int flags)
389169689Skan{
390169689Skan  if (clause == NULL)
391169689Skan    return;
392169689Skan
393169689Skan  pp_space (buffer);
394169689Skan  while (1)
395169689Skan    {
396169689Skan      dump_omp_clause (buffer, clause, spc, flags);
397169689Skan      clause = OMP_CLAUSE_CHAIN (clause);
398169689Skan      if (clause == NULL)
399169689Skan	return;
400169689Skan      pp_space (buffer);
401169689Skan    }
402169689Skan}
403169689Skan
404169689Skan
405169689Skan/* Dump the node NODE on the pretty_printer BUFFER, SPC spaces of indent.
406169689Skan   FLAGS specifies details to show in the dump (see TDF_* in tree.h).  If
407169689Skan   IS_STMT is true, the object printed is considered to be a statement
408169689Skan   and it is terminated by ';' if appropriate.  */
409169689Skan
410169689Skanint
411169689Skandump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
412169689Skan		   bool is_stmt)
413169689Skan{
414169689Skan  tree type;
415169689Skan  tree op0, op1;
416169689Skan  const char *str;
417169689Skan  bool is_expr;
418169689Skan
419169689Skan  if (node == NULL_TREE)
420169689Skan    return spc;
421169689Skan
422169689Skan  is_expr = EXPR_P (node);
423169689Skan
424169689Skan  if (TREE_CODE (node) != ERROR_MARK
425169689Skan      && is_gimple_stmt (node)
426169689Skan      && (flags & TDF_VOPS)
427169689Skan      && stmt_ann (node)
428169689Skan      && TREE_CODE (node) != PHI_NODE)
429169689Skan    dump_vops (buffer, node, spc, flags);
430169689Skan
431169689Skan  if (is_stmt && (flags & TDF_STMTADDR))
432169689Skan    pp_printf (buffer, "<&%p> ", (void *)node);
433169689Skan
434169689Skan  if ((flags & TDF_LINENO) && EXPR_HAS_LOCATION (node))
435169689Skan    {
436169689Skan      expanded_location xloc = expand_location (EXPR_LOCATION (node));
437169689Skan      pp_character (buffer, '[');
438169689Skan      if (xloc.file)
439169689Skan	{
440169689Skan	  pp_string (buffer, xloc.file);
441169689Skan	  pp_string (buffer, " : ");
442169689Skan	}
443169689Skan      pp_decimal_int (buffer, xloc.line);
444169689Skan      pp_string (buffer, "] ");
445169689Skan    }
446169689Skan
447169689Skan  switch (TREE_CODE (node))
448169689Skan    {
449169689Skan    case ERROR_MARK:
450169689Skan      pp_string (buffer, "<<< error >>>");
451169689Skan      break;
452169689Skan
453169689Skan    case IDENTIFIER_NODE:
454169689Skan      pp_tree_identifier (buffer, node);
455169689Skan      break;
456169689Skan
457169689Skan    case TREE_LIST:
458169689Skan      while (node && node != error_mark_node)
459169689Skan	{
460169689Skan	  if (TREE_PURPOSE (node))
461169689Skan	    {
462169689Skan	      dump_generic_node (buffer, TREE_PURPOSE (node), spc, flags, false);
463169689Skan	      pp_space (buffer);
464169689Skan	    }
465169689Skan	  dump_generic_node (buffer, TREE_VALUE (node), spc, flags, false);
466169689Skan	  node = TREE_CHAIN (node);
467169689Skan	  if (node && TREE_CODE (node) == TREE_LIST)
468169689Skan	    {
469169689Skan	      pp_character (buffer, ',');
470169689Skan	      pp_space (buffer);
471169689Skan	    }
472169689Skan	}
473169689Skan      break;
474169689Skan
475169689Skan    case TREE_BINFO:
476169689Skan      dump_generic_node (buffer, BINFO_TYPE (node), spc, flags, false);
477169689Skan
478169689Skan    case TREE_VEC:
479169689Skan      {
480169689Skan	size_t i;
481169689Skan	if (TREE_VEC_LENGTH (node) > 0)
482169689Skan	  {
483169689Skan	    size_t len = TREE_VEC_LENGTH (node);
484169689Skan	    for (i = 0; i < len - 1; i++)
485169689Skan	      {
486169689Skan		dump_generic_node (buffer, TREE_VEC_ELT (node, i), spc, flags,
487169689Skan				   false);
488169689Skan		pp_character (buffer, ',');
489169689Skan		pp_space (buffer);
490169689Skan	      }
491169689Skan	    dump_generic_node (buffer, TREE_VEC_ELT (node, len - 1), spc,
492169689Skan			       flags, false);
493169689Skan	  }
494169689Skan      }
495169689Skan      break;
496169689Skan
497169689Skan    case VOID_TYPE:
498169689Skan    case INTEGER_TYPE:
499169689Skan    case REAL_TYPE:
500169689Skan    case COMPLEX_TYPE:
501169689Skan    case VECTOR_TYPE:
502169689Skan    case ENUMERAL_TYPE:
503169689Skan    case BOOLEAN_TYPE:
504169689Skan      {
505169689Skan	unsigned int quals = TYPE_QUALS (node);
506169689Skan	enum tree_code_class class;
507169689Skan
508169689Skan	if (quals & TYPE_QUAL_CONST)
509169689Skan	  pp_string (buffer, "const ");
510169689Skan	else if (quals & TYPE_QUAL_VOLATILE)
511169689Skan	  pp_string (buffer, "volatile ");
512169689Skan	else if (quals & TYPE_QUAL_RESTRICT)
513169689Skan	  pp_string (buffer, "restrict ");
514169689Skan
515169689Skan	class = TREE_CODE_CLASS (TREE_CODE (node));
516169689Skan
517169689Skan	if (class == tcc_declaration)
518169689Skan	  {
519169689Skan	    if (DECL_NAME (node))
520169689Skan	      dump_decl_name (buffer, node, flags);
521169689Skan	    else
522169689Skan              pp_string (buffer, "<unnamed type decl>");
523169689Skan	  }
524169689Skan	else if (class == tcc_type)
525169689Skan	  {
526169689Skan	    if (TYPE_NAME (node))
527169689Skan	      {
528169689Skan		if (TREE_CODE (TYPE_NAME (node)) == IDENTIFIER_NODE)
529169689Skan		  pp_tree_identifier (buffer, TYPE_NAME (node));
530169689Skan		else if (TREE_CODE (TYPE_NAME (node)) == TYPE_DECL
531169689Skan			 && DECL_NAME (TYPE_NAME (node)))
532169689Skan		  dump_decl_name (buffer, TYPE_NAME (node), flags);
533169689Skan		else
534169689Skan		  pp_string (buffer, "<unnamed type>");
535169689Skan	      }
536169689Skan	    else if (TREE_CODE (node) == VECTOR_TYPE)
537169689Skan	      {
538169689Skan		pp_string (buffer, "vector ");
539169689Skan		dump_generic_node (buffer, TREE_TYPE (node),
540169689Skan				   spc, flags, false);
541169689Skan	      }
542169689Skan	    else
543169689Skan              pp_string (buffer, "<unnamed type>");
544169689Skan	  }
545169689Skan	break;
546169689Skan      }
547169689Skan
548169689Skan    case POINTER_TYPE:
549169689Skan    case REFERENCE_TYPE:
550169689Skan      str = (TREE_CODE (node) == POINTER_TYPE ? "*" : "&");
551169689Skan
552169689Skan      if (TREE_CODE (TREE_TYPE (node)) == FUNCTION_TYPE)
553169689Skan        {
554169689Skan	  tree fnode = TREE_TYPE (node);
555169689Skan
556169689Skan	  dump_generic_node (buffer, TREE_TYPE (fnode), spc, flags, false);
557169689Skan	  pp_space (buffer);
558169689Skan	  pp_character (buffer, '(');
559169689Skan	  pp_string (buffer, str);
560169689Skan	  if (TYPE_NAME (node) && DECL_NAME (TYPE_NAME (node)))
561169689Skan	    dump_decl_name (buffer, TYPE_NAME (node), flags);
562169689Skan	  else
563169689Skan	    pp_printf (buffer, "<T%x>", TYPE_UID (node));
564169689Skan
565169689Skan	  pp_character (buffer, ')');
566169689Skan	  dump_function_declaration (buffer, fnode, spc, flags);
567169689Skan	}
568169689Skan      else
569169689Skan        {
570169689Skan	  unsigned int quals = TYPE_QUALS (node);
571169689Skan
572169689Skan          dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
573169689Skan	  pp_space (buffer);
574169689Skan	  pp_string (buffer, str);
575169689Skan
576169689Skan	  if (quals & TYPE_QUAL_CONST)
577169689Skan	    pp_string (buffer, " const");
578169689Skan	  else if (quals & TYPE_QUAL_VOLATILE)
579169689Skan	    pp_string (buffer,  "volatile");
580169689Skan	  else if (quals & TYPE_QUAL_RESTRICT)
581169689Skan	    pp_string (buffer, " restrict");
582169689Skan
583169689Skan	  if (TYPE_REF_CAN_ALIAS_ALL (node))
584169689Skan	    pp_string (buffer, " {ref-all}");
585169689Skan	}
586169689Skan      break;
587169689Skan
588169689Skan    case OFFSET_TYPE:
589169689Skan      NIY;
590169689Skan      break;
591169689Skan
592169689Skan    case METHOD_TYPE:
593169689Skan      dump_decl_name (buffer, TYPE_NAME (TYPE_METHOD_BASETYPE (node)), flags);
594169689Skan      pp_string (buffer, "::");
595169689Skan      break;
596169689Skan
597169689Skan    case TARGET_MEM_REF:
598169689Skan      {
599169689Skan	const char *sep = "";
600169689Skan	tree tmp;
601169689Skan
602169689Skan	pp_string (buffer, "MEM[");
603169689Skan
604169689Skan	tmp = TMR_SYMBOL (node);
605169689Skan	if (tmp)
606169689Skan	  {
607169689Skan	    pp_string (buffer, sep);
608169689Skan	    sep = ", ";
609169689Skan	    pp_string (buffer, "symbol: ");
610169689Skan	    dump_generic_node (buffer, tmp, spc, flags, false);
611169689Skan	  }
612169689Skan	tmp = TMR_BASE (node);
613169689Skan	if (tmp)
614169689Skan	  {
615169689Skan	    pp_string (buffer, sep);
616169689Skan	    sep = ", ";
617169689Skan	    pp_string (buffer, "base: ");
618169689Skan	    dump_generic_node (buffer, tmp, spc, flags, false);
619169689Skan	  }
620169689Skan	tmp = TMR_INDEX (node);
621169689Skan	if (tmp)
622169689Skan	  {
623169689Skan	    pp_string (buffer, sep);
624169689Skan	    sep = ", ";
625169689Skan	    pp_string (buffer, "index: ");
626169689Skan	    dump_generic_node (buffer, tmp, spc, flags, false);
627169689Skan	  }
628169689Skan	tmp = TMR_STEP (node);
629169689Skan	if (tmp)
630169689Skan	  {
631169689Skan	    pp_string (buffer, sep);
632169689Skan	    sep = ", ";
633169689Skan	    pp_string (buffer, "step: ");
634169689Skan	    dump_generic_node (buffer, tmp, spc, flags, false);
635169689Skan	  }
636169689Skan	tmp = TMR_OFFSET (node);
637169689Skan	if (tmp)
638169689Skan	  {
639169689Skan	    pp_string (buffer, sep);
640169689Skan	    sep = ", ";
641169689Skan	    pp_string (buffer, "offset: ");
642169689Skan	    dump_generic_node (buffer, tmp, spc, flags, false);
643169689Skan	  }
644169689Skan	pp_string (buffer, "]");
645169689Skan	if (flags & TDF_DETAILS)
646169689Skan	  {
647169689Skan	    pp_string (buffer, "{");
648169689Skan	    dump_generic_node (buffer, TMR_ORIGINAL (node), spc, flags,
649169689Skan			       false);
650169689Skan	    pp_string (buffer, "}");
651169689Skan	  }
652169689Skan      }
653169689Skan      break;
654169689Skan
655169689Skan    case ARRAY_TYPE:
656169689Skan      {
657169689Skan	tree tmp;
658169689Skan
659169689Skan	/* Print the innermost component type.  */
660169689Skan	for (tmp = TREE_TYPE (node); TREE_CODE (tmp) == ARRAY_TYPE;
661169689Skan	     tmp = TREE_TYPE (tmp))
662169689Skan	  ;
663169689Skan	dump_generic_node (buffer, tmp, spc, flags, false);
664169689Skan
665169689Skan	/* Print the dimensions.  */
666169689Skan	for (tmp = node; TREE_CODE (tmp) == ARRAY_TYPE; tmp = TREE_TYPE (tmp))
667169689Skan	  dump_array_domain (buffer, TYPE_DOMAIN (tmp), spc, flags);
668169689Skan	break;
669169689Skan      }
670169689Skan
671169689Skan    case RECORD_TYPE:
672169689Skan    case UNION_TYPE:
673169689Skan    case QUAL_UNION_TYPE:
674169689Skan      /* Print the name of the structure.  */
675169689Skan      if (TREE_CODE (node) == RECORD_TYPE)
676169689Skan	pp_string (buffer, "struct ");
677169689Skan      else if (TREE_CODE (node) == UNION_TYPE)
678169689Skan	pp_string (buffer, "union ");
679169689Skan
680169689Skan      if (TYPE_NAME (node))
681169689Skan	dump_generic_node (buffer, TYPE_NAME (node), spc, flags, false);
682169689Skan      else
683169689Skan	print_struct_decl (buffer, node, spc, flags);
684169689Skan      break;
685169689Skan
686169689Skan    case LANG_TYPE:
687169689Skan      NIY;
688169689Skan      break;
689169689Skan
690169689Skan    case INTEGER_CST:
691169689Skan      if (TREE_CODE (TREE_TYPE (node)) == POINTER_TYPE)
692169689Skan	{
693169689Skan	  /* In the case of a pointer, one may want to divide by the
694169689Skan	     size of the pointed-to type.  Unfortunately, this not
695169689Skan	     straightforward.  The C front-end maps expressions
696169689Skan
697169689Skan	     (int *) 5
698169689Skan	     int *p; (p + 5)
699169689Skan
700169689Skan	     in such a way that the two INTEGER_CST nodes for "5" have
701169689Skan	     different values but identical types.  In the latter
702169689Skan	     case, the 5 is multiplied by sizeof (int) in c-common.c
703169689Skan	     (pointer_int_sum) to convert it to a byte address, and
704169689Skan	     yet the type of the node is left unchanged.  Argh.  What
705169689Skan	     is consistent though is that the number value corresponds
706169689Skan	     to bytes (UNITS) offset.
707169689Skan
708169689Skan             NB: Neither of the following divisors can be trivially
709169689Skan             used to recover the original literal:
710169689Skan
711169689Skan             TREE_INT_CST_LOW (TYPE_SIZE_UNIT (TREE_TYPE (node)))
712169689Skan	     TYPE_PRECISION (TREE_TYPE (TREE_TYPE (node)))  */
713169689Skan	  pp_wide_integer (buffer, TREE_INT_CST_LOW (node));
714169689Skan	  pp_string (buffer, "B"); /* pseudo-unit */
715169689Skan	}
716169689Skan      else if (! host_integerp (node, 0))
717169689Skan	{
718169689Skan	  tree val = node;
719169689Skan
720169689Skan	  if (tree_int_cst_sgn (val) < 0)
721169689Skan	    {
722169689Skan	      pp_character (buffer, '-');
723169689Skan	      val = build_int_cst_wide (NULL_TREE,
724169689Skan					-TREE_INT_CST_LOW (val),
725169689Skan					~TREE_INT_CST_HIGH (val)
726169689Skan					+ !TREE_INT_CST_LOW (val));
727169689Skan	    }
728169689Skan	  /* Would "%x%0*x" or "%x%*0x" get zero-padding on all
729169689Skan	     systems?  */
730169689Skan	  {
731169689Skan	    static char format[10]; /* "%x%09999x\0" */
732169689Skan	    if (!format[0])
733169689Skan	      sprintf (format, "%%x%%0%dx", HOST_BITS_PER_INT / 4);
734169689Skan	    sprintf (pp_buffer (buffer)->digit_buffer, format,
735169689Skan		     TREE_INT_CST_HIGH (val),
736169689Skan		     TREE_INT_CST_LOW (val));
737169689Skan	    pp_string (buffer, pp_buffer (buffer)->digit_buffer);
738169689Skan	  }
739169689Skan	}
740169689Skan      else
741169689Skan	pp_wide_integer (buffer, TREE_INT_CST_LOW (node));
742169689Skan      break;
743169689Skan
744169689Skan    case REAL_CST:
745169689Skan      /* Code copied from print_node.  */
746169689Skan      {
747169689Skan	REAL_VALUE_TYPE d;
748169689Skan	if (TREE_OVERFLOW (node))
749169689Skan	  pp_string (buffer, " overflow");
750169689Skan
751169689Skan#if !defined(REAL_IS_NOT_DOUBLE) || defined(REAL_ARITHMETIC)
752169689Skan	d = TREE_REAL_CST (node);
753169689Skan	if (REAL_VALUE_ISINF (d))
754169689Skan	  pp_string (buffer, " Inf");
755169689Skan	else if (REAL_VALUE_ISNAN (d))
756169689Skan	  pp_string (buffer, " Nan");
757169689Skan	else
758169689Skan	  {
759169689Skan	    char string[100];
760169689Skan	    real_to_decimal (string, &d, sizeof (string), 0, 1);
761169689Skan	    pp_string (buffer, string);
762169689Skan	  }
763169689Skan#else
764169689Skan	{
765169689Skan	  HOST_WIDE_INT i;
766169689Skan	  unsigned char *p = (unsigned char *) &TREE_REAL_CST (node);
767169689Skan	  pp_string (buffer, "0x");
768169689Skan	  for (i = 0; i < sizeof TREE_REAL_CST (node); i++)
769169689Skan	    output_formatted_integer (buffer, "%02x", *p++);
770169689Skan	}
771169689Skan#endif
772169689Skan	break;
773169689Skan      }
774169689Skan
775169689Skan    case COMPLEX_CST:
776169689Skan      pp_string (buffer, "__complex__ (");
777169689Skan      dump_generic_node (buffer, TREE_REALPART (node), spc, flags, false);
778169689Skan      pp_string (buffer, ", ");
779169689Skan      dump_generic_node (buffer, TREE_IMAGPART (node), spc, flags, false);
780169689Skan      pp_string (buffer, ")");
781169689Skan      break;
782169689Skan
783169689Skan    case STRING_CST:
784169689Skan      pp_string (buffer, "\"");
785169689Skan      pretty_print_string (buffer, TREE_STRING_POINTER (node));
786169689Skan      pp_string (buffer, "\"");
787169689Skan      break;
788169689Skan
789169689Skan    case VECTOR_CST:
790169689Skan      {
791169689Skan	tree elt;
792169689Skan	pp_string (buffer, "{ ");
793169689Skan	for (elt = TREE_VECTOR_CST_ELTS (node); elt; elt = TREE_CHAIN (elt))
794169689Skan	  {
795169689Skan	    dump_generic_node (buffer, TREE_VALUE (elt), spc, flags, false);
796169689Skan	    if (TREE_CHAIN (elt))
797169689Skan	      pp_string (buffer, ", ");
798169689Skan	  }
799169689Skan	pp_string (buffer, " }");
800169689Skan      }
801169689Skan      break;
802169689Skan
803169689Skan    case FUNCTION_TYPE:
804169689Skan      break;
805169689Skan
806169689Skan    case FUNCTION_DECL:
807169689Skan    case CONST_DECL:
808169689Skan      dump_decl_name (buffer, node, flags);
809169689Skan      break;
810169689Skan
811169689Skan    case LABEL_DECL:
812169689Skan      if (DECL_NAME (node))
813169689Skan	dump_decl_name (buffer, node, flags);
814169689Skan      else if (LABEL_DECL_UID (node) != -1)
815169689Skan        pp_printf (buffer, "<L" HOST_WIDE_INT_PRINT_DEC ">",
816169689Skan		   LABEL_DECL_UID (node));
817169689Skan      else
818169689Skan        pp_printf (buffer, "<D%u>", DECL_UID (node));
819169689Skan      break;
820169689Skan
821169689Skan    case TYPE_DECL:
822169689Skan      if (DECL_IS_BUILTIN (node))
823169689Skan	{
824169689Skan	  /* Don't print the declaration of built-in types.  */
825169689Skan	  break;
826169689Skan	}
827169689Skan      if (DECL_NAME (node))
828169689Skan	dump_decl_name (buffer, node, flags);
829169689Skan      else
830169689Skan	{
831169689Skan	  if ((TREE_CODE (TREE_TYPE (node)) == RECORD_TYPE
832169689Skan	       || TREE_CODE (TREE_TYPE (node)) == UNION_TYPE)
833169689Skan	      && TYPE_METHODS (TREE_TYPE (node)))
834169689Skan	    {
835169689Skan	      /* The type is a c++ class: all structures have at least
836169689Skan		 4 methods.  */
837169689Skan	      pp_string (buffer, "class ");
838169689Skan	      dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
839169689Skan	    }
840169689Skan	  else
841169689Skan	    {
842169689Skan	      pp_string (buffer,
843169689Skan			 (TREE_CODE (TREE_TYPE (node)) == UNION_TYPE
844169689Skan			  ? "union" : "struct "));
845169689Skan	      dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
846169689Skan	    }
847169689Skan	}
848169689Skan      break;
849169689Skan
850169689Skan    case SYMBOL_MEMORY_TAG:
851169689Skan    case NAME_MEMORY_TAG:
852169689Skan    case STRUCT_FIELD_TAG:
853169689Skan    case VAR_DECL:
854169689Skan    case PARM_DECL:
855169689Skan    case FIELD_DECL:
856169689Skan    case NAMESPACE_DECL:
857169689Skan      dump_decl_name (buffer, node, flags);
858169689Skan      break;
859169689Skan
860169689Skan    case RESULT_DECL:
861169689Skan      pp_string (buffer, "<retval>");
862169689Skan      break;
863169689Skan
864169689Skan    case COMPONENT_REF:
865169689Skan      op0 = TREE_OPERAND (node, 0);
866169689Skan      str = ".";
867169689Skan      if (TREE_CODE (op0) == INDIRECT_REF)
868169689Skan	{
869169689Skan	  op0 = TREE_OPERAND (op0, 0);
870169689Skan	  str = "->";
871169689Skan	}
872169689Skan      if (op_prio (op0) < op_prio (node))
873169689Skan	pp_character (buffer, '(');
874169689Skan      dump_generic_node (buffer, op0, spc, flags, false);
875169689Skan      if (op_prio (op0) < op_prio (node))
876169689Skan	pp_character (buffer, ')');
877169689Skan      pp_string (buffer, str);
878169689Skan      dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
879169689Skan
880169689Skan      if (TREE_CODE (op0) != VALUE_HANDLE)
881169689Skan	{
882169689Skan	  op0 = component_ref_field_offset (node);
883169689Skan	  if (op0 && TREE_CODE (op0) != INTEGER_CST)
884169689Skan	    {
885169689Skan	      pp_string (buffer, "{off: ");
886169689Skan	      dump_generic_node (buffer, op0, spc, flags, false);
887169689Skan	      pp_character (buffer, '}');
888169689Skan	    }
889169689Skan	}
890169689Skan      break;
891169689Skan
892169689Skan    case BIT_FIELD_REF:
893169689Skan      pp_string (buffer, "BIT_FIELD_REF <");
894169689Skan      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
895169689Skan      pp_string (buffer, ", ");
896169689Skan      dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
897169689Skan      pp_string (buffer, ", ");
898169689Skan      dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
899169689Skan      pp_string (buffer, ">");
900169689Skan      break;
901169689Skan
902169689Skan    case ARRAY_REF:
903169689Skan    case ARRAY_RANGE_REF:
904169689Skan      op0 = TREE_OPERAND (node, 0);
905169689Skan      if (op_prio (op0) < op_prio (node))
906169689Skan	pp_character (buffer, '(');
907169689Skan      dump_generic_node (buffer, op0, spc, flags, false);
908169689Skan      if (op_prio (op0) < op_prio (node))
909169689Skan	pp_character (buffer, ')');
910169689Skan      pp_character (buffer, '[');
911169689Skan      dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
912169689Skan      if (TREE_CODE (node) == ARRAY_RANGE_REF)
913169689Skan	pp_string (buffer, " ...");
914169689Skan      pp_character (buffer, ']');
915169689Skan
916169689Skan      op0 = array_ref_low_bound (node);
917169689Skan      op1 = array_ref_element_size (node);
918169689Skan
919169689Skan      if (!integer_zerop (op0)
920169689Skan	  || (TYPE_SIZE_UNIT (TREE_TYPE (node))
921169689Skan	      && !operand_equal_p (op1, TYPE_SIZE_UNIT (TREE_TYPE (node)), 0)))
922169689Skan	{
923169689Skan	  pp_string (buffer, "{lb: ");
924169689Skan	  dump_generic_node (buffer, op0, spc, flags, false);
925169689Skan	  pp_string (buffer, " sz: ");
926169689Skan	  dump_generic_node (buffer, op1, spc, flags, false);
927169689Skan	  pp_character (buffer, '}');
928169689Skan	}
929169689Skan      break;
930169689Skan
931169689Skan    case CONSTRUCTOR:
932169689Skan      {
933169689Skan	unsigned HOST_WIDE_INT ix;
934169689Skan	tree field, val;
935169689Skan	bool is_struct_init = FALSE;
936169689Skan	pp_character (buffer, '{');
937169689Skan	if (TREE_CODE (TREE_TYPE (node)) == RECORD_TYPE
938169689Skan	    || TREE_CODE (TREE_TYPE (node)) == UNION_TYPE)
939169689Skan	  is_struct_init = TRUE;
940169689Skan	FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (node), ix, field, val)
941169689Skan	  {
942169689Skan	    if (field && is_struct_init)
943169689Skan	      {
944169689Skan		pp_character (buffer, '.');
945169689Skan		dump_generic_node (buffer, field, spc, flags, false);
946169689Skan		pp_string (buffer, "=");
947169689Skan	      }
948169689Skan	    if (val && TREE_CODE (val) == ADDR_EXPR)
949169689Skan	      if (TREE_CODE (TREE_OPERAND (val, 0)) == FUNCTION_DECL)
950169689Skan		val = TREE_OPERAND (val, 0);
951169689Skan	    if (val && TREE_CODE (val) == FUNCTION_DECL)
952169689Skan		dump_decl_name (buffer, val, flags);
953169689Skan	    else
954169689Skan		dump_generic_node (buffer, val, spc, flags, false);
955169689Skan	    if (ix != VEC_length (constructor_elt, CONSTRUCTOR_ELTS (node)) - 1)
956169689Skan	      {
957169689Skan		pp_character (buffer, ',');
958169689Skan		pp_space (buffer);
959169689Skan	      }
960169689Skan	  }
961169689Skan	pp_character (buffer, '}');
962169689Skan      }
963169689Skan      break;
964169689Skan
965169689Skan    case COMPOUND_EXPR:
966169689Skan      {
967169689Skan	tree *tp;
968169689Skan	if (flags & TDF_SLIM)
969169689Skan	  {
970169689Skan	    pp_string (buffer, "<COMPOUND_EXPR>");
971169689Skan	    break;
972169689Skan	  }
973169689Skan
974169689Skan	dump_generic_node (buffer, TREE_OPERAND (node, 0),
975169689Skan			   spc, flags, !(flags & TDF_SLIM));
976169689Skan	if (flags & TDF_SLIM)
977169689Skan	  newline_and_indent (buffer, spc);
978169689Skan	else
979169689Skan	  {
980169689Skan	    pp_character (buffer, ',');
981169689Skan	    pp_space (buffer);
982169689Skan	  }
983169689Skan
984169689Skan	for (tp = &TREE_OPERAND (node, 1);
985169689Skan	     TREE_CODE (*tp) == COMPOUND_EXPR;
986169689Skan	     tp = &TREE_OPERAND (*tp, 1))
987169689Skan	  {
988169689Skan	    dump_generic_node (buffer, TREE_OPERAND (*tp, 0),
989169689Skan			       spc, flags, !(flags & TDF_SLIM));
990169689Skan	    if (flags & TDF_SLIM)
991169689Skan	      newline_and_indent (buffer, spc);
992169689Skan	    else
993169689Skan	      {
994169689Skan	        pp_character (buffer, ',');
995169689Skan	        pp_space (buffer);
996169689Skan	      }
997169689Skan	  }
998169689Skan
999169689Skan	dump_generic_node (buffer, *tp, spc, flags, !(flags & TDF_SLIM));
1000169689Skan      }
1001169689Skan      break;
1002169689Skan
1003169689Skan    case STATEMENT_LIST:
1004169689Skan      {
1005169689Skan	tree_stmt_iterator si;
1006169689Skan	bool first = true;
1007169689Skan
1008169689Skan	if (flags & TDF_SLIM)
1009169689Skan	  {
1010169689Skan	    pp_string (buffer, "<STATEMENT_LIST>");
1011169689Skan	    break;
1012169689Skan	  }
1013169689Skan
1014169689Skan	for (si = tsi_start (node); !tsi_end_p (si); tsi_next (&si))
1015169689Skan	  {
1016169689Skan	    if (!first)
1017169689Skan	      newline_and_indent (buffer, spc);
1018169689Skan	    else
1019169689Skan	      first = false;
1020169689Skan	    dump_generic_node (buffer, tsi_stmt (si), spc, flags, true);
1021169689Skan	  }
1022169689Skan      }
1023169689Skan      break;
1024169689Skan
1025169689Skan    case MODIFY_EXPR:
1026169689Skan    case INIT_EXPR:
1027169689Skan      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1028169689Skan      pp_space (buffer);
1029169689Skan      pp_character (buffer, '=');
1030169689Skan      pp_space (buffer);
1031169689Skan      dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1032169689Skan      break;
1033169689Skan
1034169689Skan    case TARGET_EXPR:
1035169689Skan      pp_string (buffer, "TARGET_EXPR <");
1036169689Skan      dump_generic_node (buffer, TARGET_EXPR_SLOT (node), spc, flags, false);
1037169689Skan      pp_character (buffer, ',');
1038169689Skan      pp_space (buffer);
1039169689Skan      dump_generic_node (buffer, TARGET_EXPR_INITIAL (node), spc, flags, false);
1040169689Skan      pp_character (buffer, '>');
1041169689Skan      break;
1042169689Skan
1043169689Skan    case DECL_EXPR:
1044169689Skan      print_declaration (buffer, DECL_EXPR_DECL (node), spc, flags);
1045169689Skan      is_stmt = false;
1046169689Skan      break;
1047169689Skan
1048169689Skan    case COND_EXPR:
1049169689Skan      if (TREE_TYPE (node) == NULL || TREE_TYPE (node) == void_type_node)
1050169689Skan	{
1051169689Skan	  pp_string (buffer, "if (");
1052169689Skan	  dump_generic_node (buffer, COND_EXPR_COND (node), spc, flags, false);
1053169689Skan	  pp_character (buffer, ')');
1054169689Skan	  /* The lowered cond_exprs should always be printed in full.  */
1055169689Skan	  if (COND_EXPR_THEN (node)
1056169689Skan	      && (IS_EMPTY_STMT (COND_EXPR_THEN (node))
1057169689Skan		  || TREE_CODE (COND_EXPR_THEN (node)) == GOTO_EXPR)
1058169689Skan	      && COND_EXPR_ELSE (node)
1059169689Skan	      && (IS_EMPTY_STMT (COND_EXPR_ELSE (node))
1060169689Skan		  || TREE_CODE (COND_EXPR_ELSE (node)) == GOTO_EXPR))
1061169689Skan	    {
1062169689Skan	      pp_space (buffer);
1063169689Skan	      dump_generic_node (buffer, COND_EXPR_THEN (node), 0, flags, true);
1064169689Skan	      pp_string (buffer, " else ");
1065169689Skan	      dump_generic_node (buffer, COND_EXPR_ELSE (node), 0, flags, true);
1066169689Skan	    }
1067169689Skan	  else if (!(flags & TDF_SLIM))
1068169689Skan	    {
1069169689Skan	      /* Output COND_EXPR_THEN.  */
1070169689Skan	      if (COND_EXPR_THEN (node))
1071169689Skan		{
1072169689Skan		  newline_and_indent (buffer, spc+2);
1073169689Skan		  pp_character (buffer, '{');
1074169689Skan		  newline_and_indent (buffer, spc+4);
1075169689Skan		  dump_generic_node (buffer, COND_EXPR_THEN (node), spc+4,
1076169689Skan				     flags, true);
1077169689Skan		  newline_and_indent (buffer, spc+2);
1078169689Skan		  pp_character (buffer, '}');
1079169689Skan		}
1080169689Skan
1081169689Skan	      /* Output COND_EXPR_ELSE.  */
1082169689Skan	      if (COND_EXPR_ELSE (node))
1083169689Skan		{
1084169689Skan		  newline_and_indent (buffer, spc);
1085169689Skan		  pp_string (buffer, "else");
1086169689Skan		  newline_and_indent (buffer, spc+2);
1087169689Skan		  pp_character (buffer, '{');
1088169689Skan		  newline_and_indent (buffer, spc+4);
1089169689Skan		  dump_generic_node (buffer, COND_EXPR_ELSE (node), spc+4,
1090169689Skan			             flags, true);
1091169689Skan		  newline_and_indent (buffer, spc+2);
1092169689Skan		  pp_character (buffer, '}');
1093169689Skan		}
1094169689Skan	    }
1095169689Skan	  is_expr = false;
1096169689Skan	}
1097169689Skan      else
1098169689Skan	{
1099169689Skan	  dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1100169689Skan	  pp_space (buffer);
1101169689Skan	  pp_character (buffer, '?');
1102169689Skan	  pp_space (buffer);
1103169689Skan	  dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1104169689Skan	  pp_space (buffer);
1105169689Skan	  pp_character (buffer, ':');
1106169689Skan	  pp_space (buffer);
1107169689Skan	  dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
1108169689Skan	}
1109169689Skan      break;
1110169689Skan
1111169689Skan    case BIND_EXPR:
1112169689Skan      pp_character (buffer, '{');
1113169689Skan      if (!(flags & TDF_SLIM))
1114169689Skan	{
1115169689Skan	  if (BIND_EXPR_VARS (node))
1116169689Skan	    {
1117169689Skan	      pp_newline (buffer);
1118169689Skan
1119169689Skan	      for (op0 = BIND_EXPR_VARS (node); op0; op0 = TREE_CHAIN (op0))
1120169689Skan		{
1121169689Skan		  print_declaration (buffer, op0, spc+2, flags);
1122169689Skan		  pp_newline (buffer);
1123169689Skan		}
1124169689Skan	    }
1125169689Skan
1126169689Skan	  newline_and_indent (buffer, spc+2);
1127169689Skan	  dump_generic_node (buffer, BIND_EXPR_BODY (node), spc+2, flags, true);
1128169689Skan	  newline_and_indent (buffer, spc);
1129169689Skan	  pp_character (buffer, '}');
1130169689Skan	}
1131169689Skan      is_expr = false;
1132169689Skan      break;
1133169689Skan
1134169689Skan    case CALL_EXPR:
1135169689Skan      print_call_name (buffer, node);
1136169689Skan
1137169689Skan      /* Print parameters.  */
1138169689Skan      pp_space (buffer);
1139169689Skan      pp_character (buffer, '(');
1140169689Skan      op1 = TREE_OPERAND (node, 1);
1141169689Skan      if (op1)
1142169689Skan	dump_generic_node (buffer, op1, spc, flags, false);
1143169689Skan      pp_character (buffer, ')');
1144169689Skan
1145169689Skan      op1 = TREE_OPERAND (node, 2);
1146169689Skan      if (op1)
1147169689Skan	{
1148169689Skan	  pp_string (buffer, " [static-chain: ");
1149169689Skan	  dump_generic_node (buffer, op1, spc, flags, false);
1150169689Skan	  pp_character (buffer, ']');
1151169689Skan	}
1152169689Skan
1153169689Skan      if (CALL_EXPR_RETURN_SLOT_OPT (node))
1154169689Skan	pp_string (buffer, " [return slot optimization]");
1155169689Skan      if (CALL_EXPR_TAILCALL (node))
1156169689Skan	pp_string (buffer, " [tail call]");
1157169689Skan      break;
1158169689Skan
1159169689Skan    case WITH_CLEANUP_EXPR:
1160169689Skan      NIY;
1161169689Skan      break;
1162169689Skan
1163169689Skan    case CLEANUP_POINT_EXPR:
1164169689Skan      pp_string (buffer, "<<cleanup_point ");
1165169689Skan      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1166169689Skan      pp_string (buffer, ">>");
1167169689Skan      break;
1168169689Skan
1169169689Skan    case PLACEHOLDER_EXPR:
1170169689Skan      pp_string (buffer, "<PLACEHOLDER_EXPR ");
1171169689Skan      dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
1172169689Skan      pp_character (buffer, '>');
1173169689Skan      break;
1174169689Skan
1175169689Skan      /* Binary arithmetic and logic expressions.  */
1176169689Skan    case WIDEN_SUM_EXPR:
1177169689Skan    case WIDEN_MULT_EXPR:
1178169689Skan    case MULT_EXPR:
1179169689Skan    case PLUS_EXPR:
1180169689Skan    case MINUS_EXPR:
1181169689Skan    case TRUNC_DIV_EXPR:
1182169689Skan    case CEIL_DIV_EXPR:
1183169689Skan    case FLOOR_DIV_EXPR:
1184169689Skan    case ROUND_DIV_EXPR:
1185169689Skan    case TRUNC_MOD_EXPR:
1186169689Skan    case CEIL_MOD_EXPR:
1187169689Skan    case FLOOR_MOD_EXPR:
1188169689Skan    case ROUND_MOD_EXPR:
1189169689Skan    case RDIV_EXPR:
1190169689Skan    case EXACT_DIV_EXPR:
1191169689Skan    case LSHIFT_EXPR:
1192169689Skan    case RSHIFT_EXPR:
1193169689Skan    case LROTATE_EXPR:
1194169689Skan    case RROTATE_EXPR:
1195169689Skan    case VEC_LSHIFT_EXPR:
1196169689Skan    case VEC_RSHIFT_EXPR:
1197169689Skan    case BIT_IOR_EXPR:
1198169689Skan    case BIT_XOR_EXPR:
1199169689Skan    case BIT_AND_EXPR:
1200169689Skan    case TRUTH_ANDIF_EXPR:
1201169689Skan    case TRUTH_ORIF_EXPR:
1202169689Skan    case TRUTH_AND_EXPR:
1203169689Skan    case TRUTH_OR_EXPR:
1204169689Skan    case TRUTH_XOR_EXPR:
1205169689Skan    case LT_EXPR:
1206169689Skan    case LE_EXPR:
1207169689Skan    case GT_EXPR:
1208169689Skan    case GE_EXPR:
1209169689Skan    case EQ_EXPR:
1210169689Skan    case NE_EXPR:
1211169689Skan    case UNLT_EXPR:
1212169689Skan    case UNLE_EXPR:
1213169689Skan    case UNGT_EXPR:
1214169689Skan    case UNGE_EXPR:
1215169689Skan    case UNEQ_EXPR:
1216169689Skan    case LTGT_EXPR:
1217169689Skan    case ORDERED_EXPR:
1218169689Skan    case UNORDERED_EXPR:
1219169689Skan      {
1220169689Skan	const char *op = op_symbol (node);
1221169689Skan	op0 = TREE_OPERAND (node, 0);
1222169689Skan	op1 = TREE_OPERAND (node, 1);
1223169689Skan
1224169689Skan	/* When the operands are expressions with less priority,
1225169689Skan	   keep semantics of the tree representation.  */
1226169689Skan	if (op_prio (op0) < op_prio (node))
1227169689Skan	  {
1228169689Skan	    pp_character (buffer, '(');
1229169689Skan	    dump_generic_node (buffer, op0, spc, flags, false);
1230169689Skan	    pp_character (buffer, ')');
1231169689Skan	  }
1232169689Skan	else
1233169689Skan	  dump_generic_node (buffer, op0, spc, flags, false);
1234169689Skan
1235169689Skan	pp_space (buffer);
1236169689Skan	pp_string (buffer, op);
1237169689Skan	pp_space (buffer);
1238169689Skan
1239169689Skan	/* When the operands are expressions with less priority,
1240169689Skan	   keep semantics of the tree representation.  */
1241169689Skan	if (op_prio (op1) < op_prio (node))
1242169689Skan	  {
1243169689Skan	    pp_character (buffer, '(');
1244169689Skan	    dump_generic_node (buffer, op1, spc, flags, false);
1245169689Skan	    pp_character (buffer, ')');
1246169689Skan	  }
1247169689Skan	else
1248169689Skan	  dump_generic_node (buffer, op1, spc, flags, false);
1249169689Skan      }
1250169689Skan      break;
1251169689Skan
1252169689Skan      /* Unary arithmetic and logic expressions.  */
1253169689Skan    case NEGATE_EXPR:
1254169689Skan    case BIT_NOT_EXPR:
1255169689Skan    case TRUTH_NOT_EXPR:
1256169689Skan    case ADDR_EXPR:
1257169689Skan    case PREDECREMENT_EXPR:
1258169689Skan    case PREINCREMENT_EXPR:
1259169689Skan    case ALIGN_INDIRECT_REF:
1260169689Skan    case MISALIGNED_INDIRECT_REF:
1261169689Skan    case INDIRECT_REF:
1262169689Skan      if (TREE_CODE (node) == ADDR_EXPR
1263169689Skan	  && (TREE_CODE (TREE_OPERAND (node, 0)) == STRING_CST
1264169689Skan	      || TREE_CODE (TREE_OPERAND (node, 0)) == FUNCTION_DECL))
1265169689Skan	;	/* Do not output '&' for strings and function pointers.  */
1266169689Skan      else
1267169689Skan	pp_string (buffer, op_symbol (node));
1268169689Skan
1269169689Skan      if (op_prio (TREE_OPERAND (node, 0)) < op_prio (node))
1270169689Skan	{
1271169689Skan	  pp_character (buffer, '(');
1272169689Skan	  dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1273169689Skan	  pp_character (buffer, ')');
1274169689Skan	}
1275169689Skan      else
1276169689Skan	dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1277169689Skan
1278169689Skan      if (TREE_CODE (node) == MISALIGNED_INDIRECT_REF)
1279169689Skan        {
1280169689Skan          pp_string (buffer, "{misalignment: ");
1281169689Skan          dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1282169689Skan          pp_character (buffer, '}');
1283169689Skan        }
1284169689Skan      break;
1285169689Skan
1286169689Skan    case POSTDECREMENT_EXPR:
1287169689Skan    case POSTINCREMENT_EXPR:
1288169689Skan      if (op_prio (TREE_OPERAND (node, 0)) < op_prio (node))
1289169689Skan	{
1290169689Skan	  pp_character (buffer, '(');
1291169689Skan	  dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1292169689Skan	  pp_character (buffer, ')');
1293169689Skan	}
1294169689Skan      else
1295169689Skan	dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1296169689Skan      pp_string (buffer, op_symbol (node));
1297169689Skan      break;
1298169689Skan
1299169689Skan    case MIN_EXPR:
1300169689Skan      pp_string (buffer, "MIN_EXPR <");
1301169689Skan      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1302169689Skan      pp_string (buffer, ", ");
1303169689Skan      dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1304169689Skan      pp_character (buffer, '>');
1305169689Skan      break;
1306169689Skan
1307169689Skan    case MAX_EXPR:
1308169689Skan      pp_string (buffer, "MAX_EXPR <");
1309169689Skan      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1310169689Skan      pp_string (buffer, ", ");
1311169689Skan      dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1312169689Skan      pp_character (buffer, '>');
1313169689Skan      break;
1314169689Skan
1315169689Skan    case ABS_EXPR:
1316169689Skan      pp_string (buffer, "ABS_EXPR <");
1317169689Skan      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1318169689Skan      pp_character (buffer, '>');
1319169689Skan      break;
1320169689Skan
1321169689Skan    case RANGE_EXPR:
1322169689Skan      NIY;
1323169689Skan      break;
1324169689Skan
1325169689Skan    case FIX_TRUNC_EXPR:
1326169689Skan    case FIX_CEIL_EXPR:
1327169689Skan    case FIX_FLOOR_EXPR:
1328169689Skan    case FIX_ROUND_EXPR:
1329169689Skan    case FLOAT_EXPR:
1330169689Skan    case CONVERT_EXPR:
1331169689Skan    case NOP_EXPR:
1332169689Skan      type = TREE_TYPE (node);
1333169689Skan      op0 = TREE_OPERAND (node, 0);
1334169689Skan      if (type != TREE_TYPE (op0))
1335169689Skan	{
1336169689Skan	  pp_character (buffer, '(');
1337169689Skan	  dump_generic_node (buffer, type, spc, flags, false);
1338169689Skan	  pp_string (buffer, ") ");
1339169689Skan	}
1340169689Skan      if (op_prio (op0) < op_prio (node))
1341169689Skan	pp_character (buffer, '(');
1342169689Skan      dump_generic_node (buffer, op0, spc, flags, false);
1343169689Skan      if (op_prio (op0) < op_prio (node))
1344169689Skan	pp_character (buffer, ')');
1345169689Skan      break;
1346169689Skan
1347169689Skan    case VIEW_CONVERT_EXPR:
1348169689Skan      pp_string (buffer, "VIEW_CONVERT_EXPR<");
1349169689Skan      dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
1350169689Skan      pp_string (buffer, ">(");
1351169689Skan      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1352169689Skan      pp_character (buffer, ')');
1353169689Skan      break;
1354169689Skan
1355169689Skan    case NON_LVALUE_EXPR:
1356169689Skan      pp_string (buffer, "NON_LVALUE_EXPR <");
1357169689Skan      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1358169689Skan      pp_character (buffer, '>');
1359169689Skan      break;
1360169689Skan
1361169689Skan    case SAVE_EXPR:
1362169689Skan      pp_string (buffer, "SAVE_EXPR <");
1363169689Skan      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1364169689Skan      pp_character (buffer, '>');
1365169689Skan      break;
1366169689Skan
1367169689Skan    case COMPLEX_EXPR:
1368169689Skan      pp_string (buffer, "COMPLEX_EXPR <");
1369169689Skan      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1370169689Skan      pp_string (buffer, ", ");
1371169689Skan      dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1372169689Skan      pp_string (buffer, ">");
1373169689Skan      break;
1374169689Skan
1375169689Skan    case CONJ_EXPR:
1376169689Skan      pp_string (buffer, "CONJ_EXPR <");
1377169689Skan      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1378169689Skan      pp_string (buffer, ">");
1379169689Skan      break;
1380169689Skan
1381169689Skan    case REALPART_EXPR:
1382169689Skan      pp_string (buffer, "REALPART_EXPR <");
1383169689Skan      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1384169689Skan      pp_string (buffer, ">");
1385169689Skan      break;
1386169689Skan
1387169689Skan    case IMAGPART_EXPR:
1388169689Skan      pp_string (buffer, "IMAGPART_EXPR <");
1389169689Skan      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1390169689Skan      pp_string (buffer, ">");
1391169689Skan      break;
1392169689Skan
1393169689Skan    case VA_ARG_EXPR:
1394169689Skan      pp_string (buffer, "VA_ARG_EXPR <");
1395169689Skan      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1396169689Skan      pp_string (buffer, ">");
1397169689Skan      break;
1398169689Skan
1399169689Skan    case TRY_FINALLY_EXPR:
1400169689Skan    case TRY_CATCH_EXPR:
1401169689Skan      pp_string (buffer, "try");
1402169689Skan      newline_and_indent (buffer, spc+2);
1403169689Skan      pp_string (buffer, "{");
1404169689Skan      newline_and_indent (buffer, spc+4);
1405169689Skan      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc+4, flags, true);
1406169689Skan      newline_and_indent (buffer, spc+2);
1407169689Skan      pp_string (buffer, "}");
1408169689Skan      newline_and_indent (buffer, spc);
1409169689Skan      pp_string (buffer,
1410169689Skan			 (TREE_CODE (node) == TRY_CATCH_EXPR) ? "catch" : "finally");
1411169689Skan      newline_and_indent (buffer, spc+2);
1412169689Skan      pp_string (buffer, "{");
1413169689Skan      newline_and_indent (buffer, spc+4);
1414169689Skan      dump_generic_node (buffer, TREE_OPERAND (node, 1), spc+4, flags, true);
1415169689Skan      newline_and_indent (buffer, spc+2);
1416169689Skan      pp_string (buffer, "}");
1417169689Skan      is_expr = false;
1418169689Skan      break;
1419169689Skan
1420169689Skan    case CATCH_EXPR:
1421169689Skan      pp_string (buffer, "catch (");
1422169689Skan      dump_generic_node (buffer, CATCH_TYPES (node), spc+2, flags, false);
1423169689Skan      pp_string (buffer, ")");
1424169689Skan      newline_and_indent (buffer, spc+2);
1425169689Skan      pp_string (buffer, "{");
1426169689Skan      newline_and_indent (buffer, spc+4);
1427169689Skan      dump_generic_node (buffer, CATCH_BODY (node), spc+4, flags, true);
1428169689Skan      newline_and_indent (buffer, spc+2);
1429169689Skan      pp_string (buffer, "}");
1430169689Skan      is_expr = false;
1431169689Skan      break;
1432169689Skan
1433169689Skan    case EH_FILTER_EXPR:
1434169689Skan      pp_string (buffer, "<<<eh_filter (");
1435169689Skan      dump_generic_node (buffer, EH_FILTER_TYPES (node), spc+2, flags, false);
1436169689Skan      pp_string (buffer, ")>>>");
1437169689Skan      newline_and_indent (buffer, spc+2);
1438169689Skan      pp_string (buffer, "{");
1439169689Skan      newline_and_indent (buffer, spc+4);
1440169689Skan      dump_generic_node (buffer, EH_FILTER_FAILURE (node), spc+4, flags, true);
1441169689Skan      newline_and_indent (buffer, spc+2);
1442169689Skan      pp_string (buffer, "}");
1443169689Skan      is_expr = false;
1444169689Skan      break;
1445169689Skan
1446169689Skan    case LABEL_EXPR:
1447169689Skan      op0 = TREE_OPERAND (node, 0);
1448169689Skan      /* If this is for break or continue, don't bother printing it.  */
1449169689Skan      if (DECL_NAME (op0))
1450169689Skan	{
1451169689Skan	  const char *name = IDENTIFIER_POINTER (DECL_NAME (op0));
1452169689Skan	  if (strcmp (name, "break") == 0
1453169689Skan	      || strcmp (name, "continue") == 0)
1454169689Skan	    break;
1455169689Skan	}
1456169689Skan      dump_generic_node (buffer, op0, spc, flags, false);
1457169689Skan      pp_character (buffer, ':');
1458169689Skan      if (DECL_NONLOCAL (op0))
1459169689Skan	pp_string (buffer, " [non-local]");
1460169689Skan      break;
1461169689Skan
1462169689Skan    case EXC_PTR_EXPR:
1463169689Skan      pp_string (buffer, "<<<exception object>>>");
1464169689Skan      break;
1465169689Skan
1466169689Skan    case FILTER_EXPR:
1467169689Skan      pp_string (buffer, "<<<filter object>>>");
1468169689Skan      break;
1469169689Skan
1470169689Skan    case LOOP_EXPR:
1471169689Skan      pp_string (buffer, "while (1)");
1472169689Skan      if (!(flags & TDF_SLIM))
1473169689Skan	{
1474169689Skan	  newline_and_indent (buffer, spc+2);
1475169689Skan	  pp_character (buffer, '{');
1476169689Skan	  newline_and_indent (buffer, spc+4);
1477169689Skan	  dump_generic_node (buffer, LOOP_EXPR_BODY (node), spc+4, flags, true);
1478169689Skan	  newline_and_indent (buffer, spc+2);
1479169689Skan	  pp_character (buffer, '}');
1480169689Skan	}
1481169689Skan      is_expr = false;
1482169689Skan      break;
1483169689Skan
1484169689Skan    case RETURN_EXPR:
1485169689Skan      pp_string (buffer, "return");
1486169689Skan      op0 = TREE_OPERAND (node, 0);
1487169689Skan      if (op0)
1488169689Skan	{
1489169689Skan	  pp_space (buffer);
1490169689Skan	  if (TREE_CODE (op0) == MODIFY_EXPR)
1491169689Skan	    dump_generic_node (buffer, TREE_OPERAND (op0, 1), spc, flags, false);
1492169689Skan	  else
1493169689Skan	    dump_generic_node (buffer, op0, spc, flags, false);
1494169689Skan	}
1495169689Skan      break;
1496169689Skan
1497169689Skan    case EXIT_EXPR:
1498169689Skan      pp_string (buffer, "if (");
1499169689Skan      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1500169689Skan      pp_string (buffer, ") break");
1501169689Skan      break;
1502169689Skan
1503169689Skan    case SWITCH_EXPR:
1504169689Skan      pp_string (buffer, "switch (");
1505169689Skan      dump_generic_node (buffer, SWITCH_COND (node), spc, flags, false);
1506169689Skan      pp_character (buffer, ')');
1507169689Skan      if (!(flags & TDF_SLIM))
1508169689Skan	{
1509169689Skan	  newline_and_indent (buffer, spc+2);
1510169689Skan	  pp_character (buffer, '{');
1511169689Skan	  if (SWITCH_BODY (node))
1512169689Skan	    {
1513169689Skan	      newline_and_indent (buffer, spc+4);
1514169689Skan	      dump_generic_node (buffer, SWITCH_BODY (node), spc+4, flags,
1515169689Skan		                 true);
1516169689Skan	    }
1517169689Skan	  else
1518169689Skan	    {
1519169689Skan	      tree vec = SWITCH_LABELS (node);
1520169689Skan	      size_t i, n = TREE_VEC_LENGTH (vec);
1521169689Skan	      for (i = 0; i < n; ++i)
1522169689Skan		{
1523169689Skan		  tree elt = TREE_VEC_ELT (vec, i);
1524169689Skan		  newline_and_indent (buffer, spc+4);
1525169689Skan		  if (elt)
1526169689Skan		    {
1527169689Skan		      dump_generic_node (buffer, elt, spc+4, flags, false);
1528169689Skan		      pp_string (buffer, " goto ");
1529169689Skan		      dump_generic_node (buffer, CASE_LABEL (elt), spc+4,
1530169689Skan					 flags, true);
1531169689Skan		      pp_semicolon (buffer);
1532169689Skan		    }
1533169689Skan		  else
1534169689Skan		    pp_string (buffer, "case ???: goto ???;");
1535169689Skan		}
1536169689Skan	    }
1537169689Skan	  newline_and_indent (buffer, spc+2);
1538169689Skan	  pp_character (buffer, '}');
1539169689Skan	}
1540169689Skan      is_expr = false;
1541169689Skan      break;
1542169689Skan
1543169689Skan    case GOTO_EXPR:
1544169689Skan      op0 = GOTO_DESTINATION (node);
1545169689Skan      if (TREE_CODE (op0) != SSA_NAME && DECL_P (op0) && DECL_NAME (op0))
1546169689Skan	{
1547169689Skan	  const char *name = IDENTIFIER_POINTER (DECL_NAME (op0));
1548169689Skan	  if (strcmp (name, "break") == 0
1549169689Skan	      || strcmp (name, "continue") == 0)
1550169689Skan	    {
1551169689Skan	      pp_string (buffer, name);
1552169689Skan	      break;
1553169689Skan	    }
1554169689Skan	}
1555169689Skan      pp_string (buffer, "goto ");
1556169689Skan      dump_generic_node (buffer, op0, spc, flags, false);
1557169689Skan      break;
1558169689Skan
1559169689Skan    case RESX_EXPR:
1560169689Skan      pp_string (buffer, "resx ");
1561169689Skan      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1562169689Skan      break;
1563169689Skan
1564169689Skan    case ASM_EXPR:
1565169689Skan      pp_string (buffer, "__asm__");
1566169689Skan      if (ASM_VOLATILE_P (node))
1567169689Skan	pp_string (buffer, " __volatile__");
1568169689Skan      pp_character (buffer, '(');
1569169689Skan      dump_generic_node (buffer, ASM_STRING (node), spc, flags, false);
1570169689Skan      pp_character (buffer, ':');
1571169689Skan      dump_generic_node (buffer, ASM_OUTPUTS (node), spc, flags, false);
1572169689Skan      pp_character (buffer, ':');
1573169689Skan      dump_generic_node (buffer, ASM_INPUTS (node), spc, flags, false);
1574169689Skan      if (ASM_CLOBBERS (node))
1575169689Skan	{
1576169689Skan	  pp_character (buffer, ':');
1577169689Skan	  dump_generic_node (buffer, ASM_CLOBBERS (node), spc, flags, false);
1578169689Skan	}
1579169689Skan      pp_string (buffer, ")");
1580169689Skan      break;
1581169689Skan
1582169689Skan    case CASE_LABEL_EXPR:
1583169689Skan      if (CASE_LOW (node) && CASE_HIGH (node))
1584169689Skan	{
1585169689Skan	  pp_string (buffer, "case ");
1586169689Skan	  dump_generic_node (buffer, CASE_LOW (node), spc, flags, false);
1587169689Skan	  pp_string (buffer, " ... ");
1588169689Skan	  dump_generic_node (buffer, CASE_HIGH (node), spc, flags, false);
1589169689Skan	}
1590169689Skan      else if (CASE_LOW (node))
1591169689Skan	{
1592169689Skan	  pp_string (buffer, "case ");
1593169689Skan	  dump_generic_node (buffer, CASE_LOW (node), spc, flags, false);
1594169689Skan	}
1595169689Skan      else
1596169689Skan	pp_string (buffer, "default ");
1597169689Skan      pp_character (buffer, ':');
1598169689Skan      break;
1599169689Skan
1600169689Skan    case OBJ_TYPE_REF:
1601169689Skan      pp_string (buffer, "OBJ_TYPE_REF(");
1602169689Skan      dump_generic_node (buffer, OBJ_TYPE_REF_EXPR (node), spc, flags, false);
1603169689Skan      pp_character (buffer, ';');
1604169689Skan      dump_generic_node (buffer, OBJ_TYPE_REF_OBJECT (node), spc, flags, false);
1605169689Skan      pp_character (buffer, '-');
1606169689Skan      pp_character (buffer, '>');
1607169689Skan      dump_generic_node (buffer, OBJ_TYPE_REF_TOKEN (node), spc, flags, false);
1608169689Skan      pp_character (buffer, ')');
1609169689Skan      break;
1610169689Skan
1611169689Skan    case PHI_NODE:
1612169689Skan      {
1613169689Skan	int i;
1614169689Skan
1615169689Skan	dump_generic_node (buffer, PHI_RESULT (node), spc, flags, false);
1616169689Skan	pp_string (buffer, " = PHI <");
1617169689Skan	for (i = 0; i < PHI_NUM_ARGS (node); i++)
1618169689Skan	  {
1619169689Skan	    dump_generic_node (buffer, PHI_ARG_DEF (node, i), spc, flags, false);
1620169689Skan	    pp_string (buffer, "(");
1621169689Skan	    pp_decimal_int (buffer, PHI_ARG_EDGE (node, i)->src->index);
1622169689Skan	    pp_string (buffer, ")");
1623169689Skan	    if (i < PHI_NUM_ARGS (node) - 1)
1624169689Skan	      pp_string (buffer, ", ");
1625169689Skan	  }
1626169689Skan	pp_string (buffer, ">;");
1627169689Skan      }
1628169689Skan      break;
1629169689Skan
1630169689Skan    case SSA_NAME:
1631169689Skan      dump_generic_node (buffer, SSA_NAME_VAR (node), spc, flags, false);
1632169689Skan      pp_string (buffer, "_");
1633169689Skan      pp_decimal_int (buffer, SSA_NAME_VERSION (node));
1634169689Skan      if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (node))
1635169689Skan	pp_string (buffer, "(ab)");
1636169689Skan      break;
1637169689Skan
1638169689Skan    case WITH_SIZE_EXPR:
1639169689Skan      pp_string (buffer, "WITH_SIZE_EXPR <");
1640169689Skan      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1641169689Skan      pp_string (buffer, ", ");
1642169689Skan      dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1643169689Skan      pp_string (buffer, ">");
1644169689Skan      break;
1645169689Skan
1646169689Skan    case VALUE_HANDLE:
1647169689Skan      pp_printf (buffer, "VH.%d", VALUE_HANDLE_ID (node));
1648169689Skan      break;
1649169689Skan
1650169689Skan    case ASSERT_EXPR:
1651169689Skan      pp_string (buffer, "ASSERT_EXPR <");
1652169689Skan      dump_generic_node (buffer, ASSERT_EXPR_VAR (node), spc, flags, false);
1653169689Skan      pp_string (buffer, ", ");
1654169689Skan      dump_generic_node (buffer, ASSERT_EXPR_COND (node), spc, flags, false);
1655169689Skan      pp_string (buffer, ">");
1656169689Skan      break;
1657169689Skan
1658169689Skan    case SCEV_KNOWN:
1659169689Skan      pp_string (buffer, "scev_known");
1660169689Skan      break;
1661169689Skan
1662169689Skan    case SCEV_NOT_KNOWN:
1663169689Skan      pp_string (buffer, "scev_not_known");
1664169689Skan      break;
1665169689Skan
1666169689Skan    case POLYNOMIAL_CHREC:
1667169689Skan      pp_string (buffer, "{");
1668169689Skan      dump_generic_node (buffer, CHREC_LEFT (node), spc, flags, false);
1669169689Skan      pp_string (buffer, ", +, ");
1670169689Skan      dump_generic_node (buffer, CHREC_RIGHT (node), spc, flags, false);
1671169689Skan      pp_string (buffer, "}_");
1672169689Skan      dump_generic_node (buffer, CHREC_VAR (node), spc, flags, false);
1673169689Skan      is_stmt = false;
1674169689Skan      break;
1675169689Skan
1676169689Skan    case REALIGN_LOAD_EXPR:
1677169689Skan      pp_string (buffer, "REALIGN_LOAD <");
1678169689Skan      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1679169689Skan      pp_string (buffer, ", ");
1680169689Skan      dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1681169689Skan      pp_string (buffer, ", ");
1682169689Skan      dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
1683169689Skan      pp_string (buffer, ">");
1684169689Skan      break;
1685169689Skan
1686169689Skan    case VEC_COND_EXPR:
1687169689Skan      pp_string (buffer, " VEC_COND_EXPR < ");
1688169689Skan      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1689169689Skan      pp_string (buffer, " , ");
1690169689Skan      dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1691169689Skan      pp_string (buffer, " , ");
1692169689Skan      dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
1693169689Skan      pp_string (buffer, " > ");
1694169689Skan      break;
1695169689Skan
1696169689Skan    case DOT_PROD_EXPR:
1697169689Skan      pp_string (buffer, " DOT_PROD_EXPR < ");
1698169689Skan      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1699169689Skan      pp_string (buffer, " , ");
1700169689Skan      dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1701169689Skan      pp_string (buffer, " , ");
1702169689Skan      dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
1703169689Skan      pp_string (buffer, " > ");
1704169689Skan      break;
1705169689Skan
1706169689Skan    case OMP_PARALLEL:
1707169689Skan      pp_string (buffer, "#pragma omp parallel");
1708169689Skan      dump_omp_clauses (buffer, OMP_PARALLEL_CLAUSES (node), spc, flags);
1709169689Skan      if (OMP_PARALLEL_FN (node))
1710169689Skan	{
1711169689Skan	  pp_string (buffer, " [child fn: ");
1712169689Skan	  dump_generic_node (buffer, OMP_PARALLEL_FN (node), spc, flags, false);
1713169689Skan
1714169689Skan	  pp_string (buffer, " (");
1715169689Skan
1716169689Skan	  if (OMP_PARALLEL_DATA_ARG (node))
1717169689Skan	    dump_generic_node (buffer, OMP_PARALLEL_DATA_ARG (node), spc, flags,
1718169689Skan		               false);
1719169689Skan	  else
1720169689Skan	    pp_string (buffer, "???");
1721169689Skan
1722169689Skan	  pp_string (buffer, ")]");
1723169689Skan	}
1724169689Skan
1725169689Skan    dump_omp_body:
1726169689Skan      if (!(flags & TDF_SLIM) && OMP_BODY (node))
1727169689Skan	{
1728169689Skan	  newline_and_indent (buffer, spc + 2);
1729169689Skan	  pp_character (buffer, '{');
1730169689Skan	  newline_and_indent (buffer, spc + 4);
1731169689Skan	  dump_generic_node (buffer, OMP_BODY (node), spc + 4, flags, false);
1732169689Skan	  newline_and_indent (buffer, spc + 2);
1733169689Skan	  pp_character (buffer, '}');
1734169689Skan	}
1735169689Skan      is_expr = false;
1736169689Skan      break;
1737169689Skan
1738169689Skan    case OMP_FOR:
1739169689Skan      pp_string (buffer, "#pragma omp for");
1740169689Skan      dump_omp_clauses (buffer, OMP_FOR_CLAUSES (node), spc, flags);
1741169689Skan
1742169689Skan      if (!(flags & TDF_SLIM))
1743169689Skan	{
1744169689Skan	  if (OMP_FOR_PRE_BODY (node))
1745169689Skan	    {
1746169689Skan	      newline_and_indent (buffer, spc + 2);
1747169689Skan	      pp_character (buffer, '{');
1748169689Skan	      spc += 4;
1749169689Skan	      newline_and_indent (buffer, spc);
1750169689Skan	      dump_generic_node (buffer, OMP_FOR_PRE_BODY (node),
1751169689Skan		  spc, flags, false);
1752169689Skan	    }
1753169689Skan	  newline_and_indent (buffer, spc);
1754169689Skan	  pp_string (buffer, "for (");
1755169689Skan	  dump_generic_node (buffer, OMP_FOR_INIT (node), spc, flags, false);
1756169689Skan	  pp_string (buffer, "; ");
1757169689Skan	  dump_generic_node (buffer, OMP_FOR_COND (node), spc, flags, false);
1758169689Skan	  pp_string (buffer, "; ");
1759169689Skan	  dump_generic_node (buffer, OMP_FOR_INCR (node), spc, flags, false);
1760169689Skan	  pp_string (buffer, ")");
1761169689Skan	  if (OMP_FOR_BODY (node))
1762169689Skan	    {
1763169689Skan	      newline_and_indent (buffer, spc + 2);
1764169689Skan	      pp_character (buffer, '{');
1765169689Skan	      newline_and_indent (buffer, spc + 4);
1766169689Skan	      dump_generic_node (buffer, OMP_FOR_BODY (node), spc + 4, flags,
1767169689Skan		  false);
1768169689Skan	      newline_and_indent (buffer, spc + 2);
1769169689Skan	      pp_character (buffer, '}');
1770169689Skan	    }
1771169689Skan	  if (OMP_FOR_PRE_BODY (node))
1772169689Skan	    {
1773169689Skan	      spc -= 4;
1774169689Skan	      newline_and_indent (buffer, spc + 2);
1775169689Skan	      pp_character (buffer, '}');
1776169689Skan	    }
1777169689Skan	}
1778169689Skan      is_expr = false;
1779169689Skan      break;
1780169689Skan
1781169689Skan    case OMP_SECTIONS:
1782169689Skan      pp_string (buffer, "#pragma omp sections");
1783169689Skan      dump_omp_clauses (buffer, OMP_SECTIONS_CLAUSES (node), spc, flags);
1784169689Skan      goto dump_omp_body;
1785169689Skan
1786169689Skan    case OMP_SECTION:
1787169689Skan      pp_string (buffer, "#pragma omp section");
1788169689Skan      goto dump_omp_body;
1789169689Skan
1790169689Skan    case OMP_MASTER:
1791169689Skan      pp_string (buffer, "#pragma omp master");
1792169689Skan      goto dump_omp_body;
1793169689Skan
1794169689Skan    case OMP_ORDERED:
1795169689Skan      pp_string (buffer, "#pragma omp ordered");
1796169689Skan      goto dump_omp_body;
1797169689Skan
1798169689Skan    case OMP_CRITICAL:
1799169689Skan      pp_string (buffer, "#pragma omp critical");
1800169689Skan      if (OMP_CRITICAL_NAME (node))
1801169689Skan	{
1802169689Skan	  pp_space (buffer);
1803169689Skan	  pp_character (buffer, '(');
1804169689Skan          dump_generic_node (buffer, OMP_CRITICAL_NAME (node), spc,
1805169689Skan			     flags, false);
1806169689Skan	  pp_character (buffer, ')');
1807169689Skan	}
1808169689Skan      goto dump_omp_body;
1809169689Skan
1810169689Skan    case OMP_ATOMIC:
1811169689Skan      pp_string (buffer, "#pragma omp atomic");
1812169689Skan      newline_and_indent (buffer, spc + 2);
1813169689Skan      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1814169689Skan      pp_space (buffer);
1815169689Skan      pp_character (buffer, '=');
1816169689Skan      pp_space (buffer);
1817169689Skan      dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1818169689Skan      break;
1819169689Skan
1820169689Skan    case OMP_SINGLE:
1821169689Skan      pp_string (buffer, "#pragma omp single");
1822169689Skan      dump_omp_clauses (buffer, OMP_SINGLE_CLAUSES (node), spc, flags);
1823169689Skan      goto dump_omp_body;
1824169689Skan
1825169689Skan    case OMP_RETURN:
1826169689Skan      pp_string (buffer, "OMP_RETURN");
1827169689Skan      if (OMP_RETURN_NOWAIT (node))
1828169689Skan	pp_string (buffer, " [nowait]");
1829169689Skan      is_expr = false;
1830169689Skan      break;
1831169689Skan
1832169689Skan    case OMP_CONTINUE:
1833169689Skan      pp_string (buffer, "OMP_CONTINUE");
1834169689Skan      is_expr = false;
1835169689Skan      break;
1836169689Skan
1837169689Skan    case OMP_CLAUSE:
1838169689Skan      dump_omp_clause (buffer, node, spc, flags);
1839169689Skan      is_expr = false;
1840169689Skan      break;
1841169689Skan
1842169689Skan    case REDUC_MAX_EXPR:
1843169689Skan      pp_string (buffer, " REDUC_MAX_EXPR < ");
1844169689Skan      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1845169689Skan      pp_string (buffer, " > ");
1846169689Skan      break;
1847169689Skan
1848169689Skan    case REDUC_MIN_EXPR:
1849169689Skan      pp_string (buffer, " REDUC_MIN_EXPR < ");
1850169689Skan      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1851169689Skan      pp_string (buffer, " > ");
1852169689Skan      break;
1853169689Skan
1854169689Skan    case REDUC_PLUS_EXPR:
1855169689Skan      pp_string (buffer, " REDUC_PLUS_EXPR < ");
1856169689Skan      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1857169689Skan      pp_string (buffer, " > ");
1858169689Skan      break;
1859169689Skan
1860169689Skan    case BLOCK:
1861169689Skan      {
1862169689Skan	tree t;
1863169689Skan	pp_string (buffer, "BLOCK");
1864169689Skan
1865169689Skan	if (BLOCK_ABSTRACT (node))
1866169689Skan	  pp_string (buffer, " [abstract]");
1867169689Skan
1868169689Skan	if (TREE_ASM_WRITTEN (node))
1869169689Skan	  pp_string (buffer, " [written]");
1870169689Skan
1871169689Skan	newline_and_indent (buffer, spc + 2);
1872169689Skan
1873169689Skan	if (BLOCK_SUPERCONTEXT (node))
1874169689Skan	  {
1875169689Skan	    pp_string (buffer, "SUPERCONTEXT: ");
1876169689Skan	    if (TREE_CODE (BLOCK_SUPERCONTEXT (node)) == BLOCK)
1877169689Skan	      pp_printf (buffer, "BLOCK %p",
1878169689Skan		         (void *)BLOCK_SUPERCONTEXT (node));
1879169689Skan	    else
1880169689Skan	      dump_generic_node (buffer, BLOCK_SUPERCONTEXT (node), 0, flags,
1881169689Skan				 false);
1882169689Skan	    newline_and_indent (buffer, spc + 2);
1883169689Skan	  }
1884169689Skan
1885169689Skan	if (BLOCK_SUBBLOCKS (node))
1886169689Skan	  {
1887169689Skan	    pp_string (buffer, "SUBBLOCKS: ");
1888169689Skan	    for (t = BLOCK_SUBBLOCKS (node); t; t = BLOCK_CHAIN (t))
1889169689Skan	      pp_printf (buffer, "%p ", (void *)t);
1890169689Skan	    newline_and_indent (buffer, spc + 2);
1891169689Skan	  }
1892169689Skan
1893169689Skan	if (BLOCK_VARS (node))
1894169689Skan	  {
1895169689Skan	    pp_string (buffer, "VARS: ");
1896169689Skan	    for (t = BLOCK_VARS (node); t; t = TREE_CHAIN (t))
1897169689Skan	      {
1898169689Skan		dump_generic_node (buffer, t, 0, flags, false);
1899169689Skan		pp_string (buffer, " ");
1900169689Skan	      }
1901169689Skan	    newline_and_indent (buffer, spc + 2);
1902169689Skan	  }
1903169689Skan
1904169689Skan	if (BLOCK_ABSTRACT_ORIGIN (node))
1905169689Skan	  {
1906169689Skan	    pp_string (buffer, "ABSTRACT_ORIGIN: ");
1907169689Skan	    if (TREE_CODE (BLOCK_ABSTRACT_ORIGIN (node)) == BLOCK)
1908169689Skan	      pp_printf (buffer, "BLOCK %p",
1909169689Skan			 (void *)BLOCK_ABSTRACT_ORIGIN (node));
1910169689Skan	    else
1911169689Skan	      dump_generic_node (buffer, BLOCK_ABSTRACT_ORIGIN (node), 0, flags,
1912169689Skan				 false);
1913169689Skan	    newline_and_indent (buffer, spc + 2);
1914169689Skan	  }
1915169689Skan      }
1916169689Skan    break;
1917169689Skan
1918169689Skan    default:
1919169689Skan      NIY;
1920169689Skan    }
1921169689Skan
1922169689Skan  if (is_stmt && is_expr)
1923169689Skan    pp_semicolon (buffer);
1924169689Skan  pp_write_text_to_stream (buffer);
1925169689Skan
1926169689Skan  return spc;
1927169689Skan}
1928169689Skan
1929169689Skan/* Print the declaration of a variable.  */
1930169689Skan
1931169689Skanstatic void
1932169689Skanprint_declaration (pretty_printer *buffer, tree t, int spc, int flags)
1933169689Skan{
1934169689Skan  INDENT (spc);
1935169689Skan
1936169689Skan  if (TREE_CODE (t) == TYPE_DECL)
1937169689Skan    pp_string (buffer, "typedef ");
1938169689Skan
1939169689Skan  if (CODE_CONTAINS_STRUCT (TREE_CODE (t), TS_DECL_WRTL) && DECL_REGISTER (t))
1940169689Skan    pp_string (buffer, "register ");
1941169689Skan
1942169689Skan  if (TREE_PUBLIC (t) && DECL_EXTERNAL (t))
1943169689Skan    pp_string (buffer, "extern ");
1944169689Skan  else if (TREE_STATIC (t))
1945169689Skan    pp_string (buffer, "static ");
1946169689Skan
1947169689Skan  /* Print the type and name.  */
1948169689Skan  if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
1949169689Skan    {
1950169689Skan      tree tmp;
1951169689Skan
1952169689Skan      /* Print array's type.  */
1953169689Skan      tmp = TREE_TYPE (t);
1954169689Skan      while (TREE_CODE (TREE_TYPE (tmp)) == ARRAY_TYPE)
1955169689Skan	tmp = TREE_TYPE (tmp);
1956169689Skan      dump_generic_node (buffer, TREE_TYPE (tmp), spc, flags, false);
1957169689Skan
1958169689Skan      /* Print variable's name.  */
1959169689Skan      pp_space (buffer);
1960169689Skan      dump_generic_node (buffer, t, spc, flags, false);
1961169689Skan
1962169689Skan      /* Print the dimensions.  */
1963169689Skan      tmp = TREE_TYPE (t);
1964169689Skan      while (TREE_CODE (tmp) == ARRAY_TYPE)
1965169689Skan	{
1966169689Skan	  dump_array_domain (buffer, TYPE_DOMAIN (tmp), spc, flags);
1967169689Skan	  tmp = TREE_TYPE (tmp);
1968169689Skan	}
1969169689Skan    }
1970169689Skan  else if (TREE_CODE (t) == FUNCTION_DECL)
1971169689Skan    {
1972169689Skan      dump_generic_node (buffer, TREE_TYPE (TREE_TYPE (t)), spc, flags, false);
1973169689Skan      pp_space (buffer);
1974169689Skan      dump_decl_name (buffer, t, flags);
1975169689Skan      dump_function_declaration (buffer, TREE_TYPE (t), spc, flags);
1976169689Skan    }
1977169689Skan  else
1978169689Skan    {
1979169689Skan      /* Print type declaration.  */
1980169689Skan      dump_generic_node (buffer, TREE_TYPE (t), spc, flags, false);
1981169689Skan
1982169689Skan      /* Print variable's name.  */
1983169689Skan      pp_space (buffer);
1984169689Skan      dump_generic_node (buffer, t, spc, flags, false);
1985169689Skan    }
1986169689Skan
1987169689Skan  if (TREE_CODE (t) == VAR_DECL && DECL_HARD_REGISTER (t))
1988169689Skan    {
1989169689Skan      pp_string (buffer, " __asm__ ");
1990169689Skan      pp_character (buffer, '(');
1991169689Skan      dump_generic_node (buffer, DECL_ASSEMBLER_NAME (t), spc, flags, false);
1992169689Skan      pp_character (buffer, ')');
1993169689Skan    }
1994169689Skan
1995169689Skan  /* The initial value of a function serves to determine wether the function
1996169689Skan     is declared or defined.  So the following does not apply to function
1997169689Skan     nodes.  */
1998169689Skan  if (TREE_CODE (t) != FUNCTION_DECL)
1999169689Skan    {
2000169689Skan      /* Print the initial value.  */
2001169689Skan      if (DECL_INITIAL (t))
2002169689Skan	{
2003169689Skan	  pp_space (buffer);
2004169689Skan	  pp_character (buffer, '=');
2005169689Skan	  pp_space (buffer);
2006169689Skan	  dump_generic_node (buffer, DECL_INITIAL (t), spc, flags, false);
2007169689Skan	}
2008169689Skan    }
2009169689Skan
2010169689Skan  if (TREE_CODE (t) == VAR_DECL && DECL_HAS_VALUE_EXPR_P (t))
2011169689Skan    {
2012169689Skan      pp_string (buffer, " [value-expr: ");
2013169689Skan      dump_generic_node (buffer, DECL_VALUE_EXPR (t), spc, flags, false);
2014169689Skan      pp_character (buffer, ']');
2015169689Skan    }
2016169689Skan
2017169689Skan  pp_character (buffer, ';');
2018169689Skan}
2019169689Skan
2020169689Skan
2021169689Skan/* Prints a structure: name, fields, and methods.
2022169689Skan   FIXME: Still incomplete.  */
2023169689Skan
2024169689Skanstatic void
2025169689Skanprint_struct_decl (pretty_printer *buffer, tree node, int spc, int flags)
2026169689Skan{
2027169689Skan  /* Print the name of the structure.  */
2028169689Skan  if (TYPE_NAME (node))
2029169689Skan    {
2030169689Skan      INDENT (spc);
2031169689Skan      if (TREE_CODE (node) == RECORD_TYPE)
2032169689Skan	pp_string (buffer, "struct ");
2033169689Skan      else if ((TREE_CODE (node) == UNION_TYPE
2034169689Skan		|| TREE_CODE (node) == QUAL_UNION_TYPE))
2035169689Skan	pp_string (buffer, "union ");
2036169689Skan
2037169689Skan      dump_generic_node (buffer, TYPE_NAME (node), spc, 0, false);
2038169689Skan    }
2039169689Skan
2040169689Skan  /* Print the contents of the structure.  */
2041169689Skan  pp_newline (buffer);
2042169689Skan  INDENT (spc);
2043169689Skan  pp_character (buffer, '{');
2044169689Skan  pp_newline (buffer);
2045169689Skan
2046169689Skan  /* Print the fields of the structure.  */
2047169689Skan  {
2048169689Skan    tree tmp;
2049169689Skan    tmp = TYPE_FIELDS (node);
2050169689Skan    while (tmp)
2051169689Skan      {
2052169689Skan	/* Avoid to print recursively the structure.  */
2053169689Skan	/* FIXME : Not implemented correctly...,
2054169689Skan	   what about the case when we have a cycle in the contain graph? ...
2055169689Skan	   Maybe this could be solved by looking at the scope in which the
2056169689Skan	   structure was declared.  */
2057169689Skan	if (TREE_TYPE (tmp) != node
2058169689Skan	    || (TREE_CODE (TREE_TYPE (tmp)) == POINTER_TYPE
2059169689Skan		&& TREE_TYPE (TREE_TYPE (tmp)) != node))
2060169689Skan	  {
2061169689Skan	    print_declaration (buffer, tmp, spc+2, flags);
2062169689Skan	    pp_newline (buffer);
2063169689Skan	  }
2064169689Skan	tmp = TREE_CHAIN (tmp);
2065169689Skan      }
2066169689Skan  }
2067169689Skan  INDENT (spc);
2068169689Skan  pp_character (buffer, '}');
2069169689Skan}
2070169689Skan
2071169689Skan/* Return the priority of the operator OP.
2072169689Skan
2073169689Skan   From lowest to highest precedence with either left-to-right (L-R)
2074169689Skan   or right-to-left (R-L) associativity]:
2075169689Skan
2076169689Skan     1	[L-R] ,
2077169689Skan     2	[R-L] = += -= *= /= %= &= ^= |= <<= >>=
2078169689Skan     3	[R-L] ?:
2079169689Skan     4	[L-R] ||
2080169689Skan     5	[L-R] &&
2081169689Skan     6	[L-R] |
2082169689Skan     7	[L-R] ^
2083169689Skan     8	[L-R] &
2084169689Skan     9	[L-R] == !=
2085169689Skan    10	[L-R] < <= > >=
2086169689Skan    11	[L-R] << >>
2087169689Skan    12	[L-R] + -
2088169689Skan    13	[L-R] * / %
2089169689Skan    14	[R-L] ! ~ ++ -- + - * & (type) sizeof
2090169689Skan    15	[L-R] fn() [] -> .
2091169689Skan
2092169689Skan   unary +, - and * have higher precedence than the corresponding binary
2093169689Skan   operators.  */
2094169689Skan
2095169689Skanstatic int
2096169689Skanop_prio (tree op)
2097169689Skan{
2098169689Skan  if (op == NULL)
2099169689Skan    return 9999;
2100169689Skan
2101169689Skan  switch (TREE_CODE (op))
2102169689Skan    {
2103169689Skan    case TREE_LIST:
2104169689Skan    case COMPOUND_EXPR:
2105169689Skan    case BIND_EXPR:
2106169689Skan      return 1;
2107169689Skan
2108169689Skan    case MODIFY_EXPR:
2109169689Skan    case INIT_EXPR:
2110169689Skan      return 2;
2111169689Skan
2112169689Skan    case COND_EXPR:
2113169689Skan      return 3;
2114169689Skan
2115169689Skan    case TRUTH_OR_EXPR:
2116169689Skan    case TRUTH_ORIF_EXPR:
2117169689Skan      return 4;
2118169689Skan
2119169689Skan    case TRUTH_AND_EXPR:
2120169689Skan    case TRUTH_ANDIF_EXPR:
2121169689Skan      return 5;
2122169689Skan
2123169689Skan    case BIT_IOR_EXPR:
2124169689Skan      return 6;
2125169689Skan
2126169689Skan    case BIT_XOR_EXPR:
2127169689Skan    case TRUTH_XOR_EXPR:
2128169689Skan      return 7;
2129169689Skan
2130169689Skan    case BIT_AND_EXPR:
2131169689Skan      return 8;
2132169689Skan
2133169689Skan    case EQ_EXPR:
2134169689Skan    case NE_EXPR:
2135169689Skan      return 9;
2136169689Skan
2137169689Skan    case UNLT_EXPR:
2138169689Skan    case UNLE_EXPR:
2139169689Skan    case UNGT_EXPR:
2140169689Skan    case UNGE_EXPR:
2141169689Skan    case UNEQ_EXPR:
2142169689Skan    case LTGT_EXPR:
2143169689Skan    case ORDERED_EXPR:
2144169689Skan    case UNORDERED_EXPR:
2145169689Skan    case LT_EXPR:
2146169689Skan    case LE_EXPR:
2147169689Skan    case GT_EXPR:
2148169689Skan    case GE_EXPR:
2149169689Skan      return 10;
2150169689Skan
2151169689Skan    case LSHIFT_EXPR:
2152169689Skan    case RSHIFT_EXPR:
2153169689Skan    case LROTATE_EXPR:
2154169689Skan    case RROTATE_EXPR:
2155169689Skan      return 11;
2156169689Skan
2157169689Skan    case WIDEN_SUM_EXPR:
2158169689Skan    case PLUS_EXPR:
2159169689Skan    case MINUS_EXPR:
2160169689Skan      return 12;
2161169689Skan
2162169689Skan    case WIDEN_MULT_EXPR:
2163169689Skan    case DOT_PROD_EXPR:
2164169689Skan    case MULT_EXPR:
2165169689Skan    case TRUNC_DIV_EXPR:
2166169689Skan    case CEIL_DIV_EXPR:
2167169689Skan    case FLOOR_DIV_EXPR:
2168169689Skan    case ROUND_DIV_EXPR:
2169169689Skan    case RDIV_EXPR:
2170169689Skan    case EXACT_DIV_EXPR:
2171169689Skan    case TRUNC_MOD_EXPR:
2172169689Skan    case CEIL_MOD_EXPR:
2173169689Skan    case FLOOR_MOD_EXPR:
2174169689Skan    case ROUND_MOD_EXPR:
2175169689Skan      return 13;
2176169689Skan
2177169689Skan    case TRUTH_NOT_EXPR:
2178169689Skan    case BIT_NOT_EXPR:
2179169689Skan    case POSTINCREMENT_EXPR:
2180169689Skan    case POSTDECREMENT_EXPR:
2181169689Skan    case PREINCREMENT_EXPR:
2182169689Skan    case PREDECREMENT_EXPR:
2183169689Skan    case NEGATE_EXPR:
2184169689Skan    case ALIGN_INDIRECT_REF:
2185169689Skan    case MISALIGNED_INDIRECT_REF:
2186169689Skan    case INDIRECT_REF:
2187169689Skan    case ADDR_EXPR:
2188169689Skan    case FLOAT_EXPR:
2189169689Skan    case NOP_EXPR:
2190169689Skan    case CONVERT_EXPR:
2191169689Skan    case FIX_TRUNC_EXPR:
2192169689Skan    case FIX_CEIL_EXPR:
2193169689Skan    case FIX_FLOOR_EXPR:
2194169689Skan    case FIX_ROUND_EXPR:
2195169689Skan    case TARGET_EXPR:
2196169689Skan      return 14;
2197169689Skan
2198169689Skan    case CALL_EXPR:
2199169689Skan    case ARRAY_REF:
2200169689Skan    case ARRAY_RANGE_REF:
2201169689Skan    case COMPONENT_REF:
2202169689Skan      return 15;
2203169689Skan
2204169689Skan      /* Special expressions.  */
2205169689Skan    case MIN_EXPR:
2206169689Skan    case MAX_EXPR:
2207169689Skan    case ABS_EXPR:
2208169689Skan    case REALPART_EXPR:
2209169689Skan    case IMAGPART_EXPR:
2210169689Skan    case REDUC_MAX_EXPR:
2211169689Skan    case REDUC_MIN_EXPR:
2212169689Skan    case REDUC_PLUS_EXPR:
2213169689Skan    case VEC_LSHIFT_EXPR:
2214169689Skan    case VEC_RSHIFT_EXPR:
2215169689Skan      return 16;
2216169689Skan
2217169689Skan    case SAVE_EXPR:
2218169689Skan    case NON_LVALUE_EXPR:
2219169689Skan      return op_prio (TREE_OPERAND (op, 0));
2220169689Skan
2221169689Skan    default:
2222169689Skan      /* Return an arbitrarily high precedence to avoid surrounding single
2223169689Skan	 VAR_DECLs in ()s.  */
2224169689Skan      return 9999;
2225169689Skan    }
2226169689Skan}
2227169689Skan
2228169689Skan
2229169689Skan/* Return the symbol associated with operator OP.  */
2230169689Skan
2231169689Skanstatic const char *
2232169689Skanop_symbol_1 (enum tree_code code)
2233169689Skan{
2234169689Skan  switch (code)
2235169689Skan    {
2236169689Skan    case MODIFY_EXPR:
2237169689Skan      return "=";
2238169689Skan
2239169689Skan    case TRUTH_OR_EXPR:
2240169689Skan    case TRUTH_ORIF_EXPR:
2241169689Skan      return "||";
2242169689Skan
2243169689Skan    case TRUTH_AND_EXPR:
2244169689Skan    case TRUTH_ANDIF_EXPR:
2245169689Skan      return "&&";
2246169689Skan
2247169689Skan    case BIT_IOR_EXPR:
2248169689Skan      return "|";
2249169689Skan
2250169689Skan    case TRUTH_XOR_EXPR:
2251169689Skan    case BIT_XOR_EXPR:
2252169689Skan      return "^";
2253169689Skan
2254169689Skan    case ADDR_EXPR:
2255169689Skan    case BIT_AND_EXPR:
2256169689Skan      return "&";
2257169689Skan
2258169689Skan    case ORDERED_EXPR:
2259169689Skan      return "ord";
2260169689Skan    case UNORDERED_EXPR:
2261169689Skan      return "unord";
2262169689Skan
2263169689Skan    case EQ_EXPR:
2264169689Skan      return "==";
2265169689Skan    case UNEQ_EXPR:
2266169689Skan      return "u==";
2267169689Skan
2268169689Skan    case NE_EXPR:
2269169689Skan      return "!=";
2270169689Skan
2271169689Skan    case LT_EXPR:
2272169689Skan      return "<";
2273169689Skan    case UNLT_EXPR:
2274169689Skan      return "u<";
2275169689Skan
2276169689Skan    case LE_EXPR:
2277169689Skan      return "<=";
2278169689Skan    case UNLE_EXPR:
2279169689Skan      return "u<=";
2280169689Skan
2281169689Skan    case GT_EXPR:
2282169689Skan      return ">";
2283169689Skan    case UNGT_EXPR:
2284169689Skan      return "u>";
2285169689Skan
2286169689Skan    case GE_EXPR:
2287169689Skan      return ">=";
2288169689Skan    case UNGE_EXPR:
2289169689Skan      return "u>=";
2290169689Skan
2291169689Skan    case LTGT_EXPR:
2292169689Skan      return "<>";
2293169689Skan
2294169689Skan    case LSHIFT_EXPR:
2295169689Skan      return "<<";
2296169689Skan
2297169689Skan    case RSHIFT_EXPR:
2298169689Skan      return ">>";
2299169689Skan
2300169689Skan    case LROTATE_EXPR:
2301169689Skan      return "r<<";
2302169689Skan
2303169689Skan    case RROTATE_EXPR:
2304169689Skan      return "r>>";
2305169689Skan
2306169689Skan    case VEC_LSHIFT_EXPR:
2307169689Skan      return "v<<";
2308169689Skan
2309169689Skan    case VEC_RSHIFT_EXPR:
2310169689Skan      return "v>>";
2311169689Skan
2312169689Skan    case PLUS_EXPR:
2313169689Skan      return "+";
2314169689Skan
2315169689Skan    case REDUC_PLUS_EXPR:
2316169689Skan      return "r+";
2317169689Skan
2318169689Skan    case WIDEN_SUM_EXPR:
2319169689Skan      return "w+";
2320169689Skan
2321169689Skan    case WIDEN_MULT_EXPR:
2322169689Skan      return "w*";
2323169689Skan
2324169689Skan    case NEGATE_EXPR:
2325169689Skan    case MINUS_EXPR:
2326169689Skan      return "-";
2327169689Skan
2328169689Skan    case BIT_NOT_EXPR:
2329169689Skan      return "~";
2330169689Skan
2331169689Skan    case TRUTH_NOT_EXPR:
2332169689Skan      return "!";
2333169689Skan
2334169689Skan    case MULT_EXPR:
2335169689Skan    case INDIRECT_REF:
2336169689Skan      return "*";
2337169689Skan
2338169689Skan    case ALIGN_INDIRECT_REF:
2339169689Skan      return "A*";
2340169689Skan
2341169689Skan    case MISALIGNED_INDIRECT_REF:
2342169689Skan      return "M*";
2343169689Skan
2344169689Skan    case TRUNC_DIV_EXPR:
2345169689Skan    case RDIV_EXPR:
2346169689Skan      return "/";
2347169689Skan
2348169689Skan    case CEIL_DIV_EXPR:
2349169689Skan      return "/[cl]";
2350169689Skan
2351169689Skan    case FLOOR_DIV_EXPR:
2352169689Skan      return "/[fl]";
2353169689Skan
2354169689Skan    case ROUND_DIV_EXPR:
2355169689Skan      return "/[rd]";
2356169689Skan
2357169689Skan    case EXACT_DIV_EXPR:
2358169689Skan      return "/[ex]";
2359169689Skan
2360169689Skan    case TRUNC_MOD_EXPR:
2361169689Skan      return "%";
2362169689Skan
2363169689Skan    case CEIL_MOD_EXPR:
2364169689Skan      return "%[cl]";
2365169689Skan
2366169689Skan    case FLOOR_MOD_EXPR:
2367169689Skan      return "%[fl]";
2368169689Skan
2369169689Skan    case ROUND_MOD_EXPR:
2370169689Skan      return "%[rd]";
2371169689Skan
2372169689Skan    case PREDECREMENT_EXPR:
2373169689Skan      return " --";
2374169689Skan
2375169689Skan    case PREINCREMENT_EXPR:
2376169689Skan      return " ++";
2377169689Skan
2378169689Skan    case POSTDECREMENT_EXPR:
2379169689Skan      return "-- ";
2380169689Skan
2381169689Skan    case POSTINCREMENT_EXPR:
2382169689Skan      return "++ ";
2383169689Skan
2384169689Skan    case MAX_EXPR:
2385169689Skan      return "max";
2386169689Skan
2387169689Skan    case MIN_EXPR:
2388169689Skan      return "min";
2389169689Skan
2390169689Skan    default:
2391169689Skan      return "<<< ??? >>>";
2392169689Skan    }
2393169689Skan}
2394169689Skan
2395169689Skanstatic const char *
2396169689Skanop_symbol (tree op)
2397169689Skan{
2398169689Skan  return op_symbol_1 (TREE_CODE (op));
2399169689Skan}
2400169689Skan
2401169689Skan/* Prints the name of a CALL_EXPR.  */
2402169689Skan
2403169689Skanstatic void
2404169689Skanprint_call_name (pretty_printer *buffer, tree node)
2405169689Skan{
2406169689Skan  tree op0;
2407169689Skan
2408169689Skan  gcc_assert (TREE_CODE (node) == CALL_EXPR);
2409169689Skan
2410169689Skan  op0 = TREE_OPERAND (node, 0);
2411169689Skan
2412169689Skan  if (TREE_CODE (op0) == NON_LVALUE_EXPR)
2413169689Skan    op0 = TREE_OPERAND (op0, 0);
2414169689Skan
2415169689Skan  switch (TREE_CODE (op0))
2416169689Skan    {
2417169689Skan    case VAR_DECL:
2418169689Skan    case PARM_DECL:
2419169689Skan      dump_function_name (buffer, op0);
2420169689Skan      break;
2421169689Skan
2422169689Skan    case ADDR_EXPR:
2423169689Skan    case INDIRECT_REF:
2424169689Skan    case NOP_EXPR:
2425169689Skan      dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
2426169689Skan      break;
2427169689Skan
2428169689Skan    case COND_EXPR:
2429169689Skan      pp_string (buffer, "(");
2430169689Skan      dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
2431169689Skan      pp_string (buffer, ") ? ");
2432169689Skan      dump_generic_node (buffer, TREE_OPERAND (op0, 1), 0, 0, false);
2433169689Skan      pp_string (buffer, " : ");
2434169689Skan      dump_generic_node (buffer, TREE_OPERAND (op0, 2), 0, 0, false);
2435169689Skan      break;
2436169689Skan
2437169689Skan    case COMPONENT_REF:
2438169689Skan      /* The function is a pointer contained in a structure.  */
2439169689Skan      if (TREE_CODE (TREE_OPERAND (op0, 0)) == INDIRECT_REF ||
2440169689Skan	  TREE_CODE (TREE_OPERAND (op0, 0)) == VAR_DECL)
2441169689Skan	dump_function_name (buffer, TREE_OPERAND (op0, 1));
2442169689Skan      else
2443169689Skan	dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
2444169689Skan      /* else
2445169689Skan	 We can have several levels of structures and a function
2446169689Skan	 pointer inside.  This is not implemented yet...  */
2447169689Skan      /*		  NIY;*/
2448169689Skan      break;
2449169689Skan
2450169689Skan    case ARRAY_REF:
2451169689Skan      if (TREE_CODE (TREE_OPERAND (op0, 0)) == VAR_DECL)
2452169689Skan	dump_function_name (buffer, TREE_OPERAND (op0, 0));
2453169689Skan      else
2454169689Skan	dump_generic_node (buffer, op0, 0, 0, false);
2455169689Skan      break;
2456169689Skan
2457169689Skan    case SSA_NAME:
2458169689Skan    case OBJ_TYPE_REF:
2459169689Skan      dump_generic_node (buffer, op0, 0, 0, false);
2460169689Skan      break;
2461169689Skan
2462169689Skan    default:
2463169689Skan      NIY;
2464169689Skan    }
2465169689Skan}
2466169689Skan
2467169689Skan/* Parses the string STR and replaces new-lines by '\n', tabs by '\t', ...  */
2468169689Skan
2469169689Skanstatic void
2470169689Skanpretty_print_string (pretty_printer *buffer, const char *str)
2471169689Skan{
2472169689Skan  if (str == NULL)
2473169689Skan    return;
2474169689Skan
2475169689Skan  while (*str)
2476169689Skan    {
2477169689Skan      switch (str[0])
2478169689Skan	{
2479169689Skan	case '\b':
2480169689Skan	  pp_string (buffer, "\\b");
2481169689Skan	  break;
2482169689Skan
2483169689Skan	case '\f':
2484169689Skan	  pp_string (buffer, "\\f");
2485169689Skan	  break;
2486169689Skan
2487169689Skan	case '\n':
2488169689Skan	  pp_string (buffer, "\\n");
2489169689Skan	  break;
2490169689Skan
2491169689Skan	case '\r':
2492169689Skan	  pp_string (buffer, "\\r");
2493169689Skan	  break;
2494169689Skan
2495169689Skan	case '\t':
2496169689Skan	  pp_string (buffer, "\\t");
2497169689Skan	  break;
2498169689Skan
2499169689Skan	case '\v':
2500169689Skan	  pp_string (buffer, "\\v");
2501169689Skan	  break;
2502169689Skan
2503169689Skan	case '\\':
2504169689Skan	  pp_string (buffer, "\\\\");
2505169689Skan	  break;
2506169689Skan
2507169689Skan	case '\"':
2508169689Skan	  pp_string (buffer, "\\\"");
2509169689Skan	  break;
2510169689Skan
2511169689Skan	case '\'':
2512169689Skan	  pp_string (buffer, "\\'");
2513169689Skan	  break;
2514169689Skan
2515169689Skan	  /* No need to handle \0; the loop terminates on \0.  */
2516169689Skan
2517169689Skan	case '\1':
2518169689Skan	  pp_string (buffer, "\\1");
2519169689Skan	  break;
2520169689Skan
2521169689Skan	case '\2':
2522169689Skan	  pp_string (buffer, "\\2");
2523169689Skan	  break;
2524169689Skan
2525169689Skan	case '\3':
2526169689Skan	  pp_string (buffer, "\\3");
2527169689Skan	  break;
2528169689Skan
2529169689Skan	case '\4':
2530169689Skan	  pp_string (buffer, "\\4");
2531169689Skan	  break;
2532169689Skan
2533169689Skan	case '\5':
2534169689Skan	  pp_string (buffer, "\\5");
2535169689Skan	  break;
2536169689Skan
2537169689Skan	case '\6':
2538169689Skan	  pp_string (buffer, "\\6");
2539169689Skan	  break;
2540169689Skan
2541169689Skan	case '\7':
2542169689Skan	  pp_string (buffer, "\\7");
2543169689Skan	  break;
2544169689Skan
2545169689Skan	default:
2546169689Skan	  pp_character (buffer, str[0]);
2547169689Skan	  break;
2548169689Skan	}
2549169689Skan      str++;
2550169689Skan    }
2551169689Skan}
2552169689Skan
2553169689Skanstatic void
2554169689Skanmaybe_init_pretty_print (FILE *file)
2555169689Skan{
2556169689Skan  if (!initialized)
2557169689Skan    {
2558169689Skan      pp_construct (&buffer, /* prefix */NULL, /* line-width */0);
2559169689Skan      pp_needs_newline (&buffer) = true;
2560169689Skan      initialized = 1;
2561169689Skan    }
2562169689Skan
2563169689Skan  buffer.buffer->stream = file;
2564169689Skan}
2565169689Skan
2566169689Skanstatic void
2567169689Skannewline_and_indent (pretty_printer *buffer, int spc)
2568169689Skan{
2569169689Skan  pp_newline (buffer);
2570169689Skan  INDENT (spc);
2571169689Skan}
2572169689Skan
2573169689Skanstatic void
2574169689Skandump_vops (pretty_printer *buffer, tree stmt, int spc, int flags)
2575169689Skan{
2576169689Skan  tree use;
2577169689Skan  use_operand_p use_p;
2578169689Skan  def_operand_p def_p;
2579169689Skan  use_operand_p kill_p;
2580169689Skan  ssa_op_iter iter;
2581169689Skan
2582169689Skan  if (!ssa_operands_active ())
2583169689Skan    return;
2584169689Skan
2585169689Skan  FOR_EACH_SSA_MAYDEF_OPERAND (def_p, use_p, stmt, iter)
2586169689Skan    {
2587169689Skan      pp_string (buffer, "#   ");
2588169689Skan      dump_generic_node (buffer, DEF_FROM_PTR (def_p),
2589169689Skan                         spc + 2, flags, false);
2590169689Skan      pp_string (buffer, " = V_MAY_DEF <");
2591169689Skan      dump_generic_node (buffer, USE_FROM_PTR (use_p),
2592169689Skan                         spc + 2, flags, false);
2593169689Skan      pp_string (buffer, ">;");
2594169689Skan      newline_and_indent (buffer, spc);
2595169689Skan    }
2596169689Skan
2597169689Skan  FOR_EACH_SSA_MUSTDEF_OPERAND (def_p, kill_p, stmt, iter)
2598169689Skan    {
2599169689Skan      pp_string (buffer, "#   ");
2600169689Skan      dump_generic_node (buffer, DEF_FROM_PTR (def_p),
2601169689Skan                         spc + 2, flags, false);
2602169689Skan      pp_string (buffer, " = V_MUST_DEF <");
2603169689Skan      dump_generic_node (buffer, USE_FROM_PTR (kill_p),
2604169689Skan                         spc + 2, flags, false);
2605169689Skan      pp_string (buffer, ">;");
2606169689Skan      newline_and_indent (buffer, spc);
2607169689Skan    }
2608169689Skan
2609169689Skan  FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_VUSE)
2610169689Skan    {
2611169689Skan      pp_string (buffer, "#   VUSE <");
2612169689Skan      dump_generic_node (buffer, use, spc + 2, flags, false);
2613169689Skan      pp_string (buffer, ">;");
2614169689Skan      newline_and_indent (buffer, spc);
2615169689Skan    }
2616169689Skan}
2617169689Skan
2618169689Skan/* Dumps basic block BB to FILE with details described by FLAGS and
2619169689Skan   indented by INDENT spaces.  */
2620169689Skan
2621169689Skanvoid
2622169689Skandump_generic_bb (FILE *file, basic_block bb, int indent, int flags)
2623169689Skan{
2624169689Skan  maybe_init_pretty_print (file);
2625169689Skan  dump_generic_bb_buff (&buffer, bb, indent, flags);
2626169689Skan  pp_flush (&buffer);
2627169689Skan}
2628169689Skan
2629169689Skan/* Dumps header of basic block BB to buffer BUFFER indented by INDENT
2630169689Skan   spaces and details described by flags.  */
2631169689Skan
2632169689Skanstatic void
2633169689Skandump_bb_header (pretty_printer *buffer, basic_block bb, int indent, int flags)
2634169689Skan{
2635169689Skan  edge e;
2636169689Skan  tree stmt;
2637169689Skan  edge_iterator ei;
2638169689Skan
2639169689Skan  if (flags & TDF_BLOCKS)
2640169689Skan    {
2641169689Skan      INDENT (indent);
2642169689Skan      pp_string (buffer, "# BLOCK ");
2643169689Skan      pp_decimal_int (buffer, bb->index);
2644169689Skan      if (bb->frequency)
2645169689Skan	{
2646169689Skan          pp_string (buffer, " freq:");
2647169689Skan          pp_decimal_int (buffer, bb->frequency);
2648169689Skan	}
2649169689Skan      if (bb->count)
2650169689Skan	{
2651169689Skan          pp_string (buffer, " count:");
2652169689Skan          pp_widest_integer (buffer, bb->count);
2653169689Skan	}
2654169689Skan
2655169689Skan      if (flags & TDF_LINENO)
2656169689Skan	{
2657169689Skan	  block_stmt_iterator bsi;
2658169689Skan
2659169689Skan	  for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
2660169689Skan	    if (get_lineno (bsi_stmt (bsi)) != -1)
2661169689Skan	      {
2662169689Skan		pp_string (buffer, ", starting at line ");
2663169689Skan		pp_decimal_int (buffer, get_lineno (bsi_stmt (bsi)));
2664169689Skan		break;
2665169689Skan	      }
2666169689Skan	}
2667169689Skan      newline_and_indent (buffer, indent);
2668169689Skan
2669169689Skan      pp_string (buffer, "# PRED:");
2670169689Skan      pp_write_text_to_stream (buffer);
2671169689Skan      FOR_EACH_EDGE (e, ei, bb->preds)
2672169689Skan	if (flags & TDF_SLIM)
2673169689Skan	  {
2674169689Skan	    pp_string (buffer, " ");
2675169689Skan	    if (e->src == ENTRY_BLOCK_PTR)
2676169689Skan	      pp_string (buffer, "ENTRY");
2677169689Skan	    else
2678169689Skan	      pp_decimal_int (buffer, e->src->index);
2679169689Skan	  }
2680169689Skan	else
2681169689Skan	  dump_edge_info (buffer->buffer->stream, e, 0);
2682169689Skan      pp_newline (buffer);
2683169689Skan    }
2684169689Skan  else
2685169689Skan    {
2686169689Skan      stmt = first_stmt (bb);
2687169689Skan      if (!stmt || TREE_CODE (stmt) != LABEL_EXPR)
2688169689Skan	{
2689169689Skan	  INDENT (indent - 2);
2690169689Skan	  pp_string (buffer, "<bb ");
2691169689Skan	  pp_decimal_int (buffer, bb->index);
2692169689Skan	  pp_string (buffer, ">:");
2693169689Skan	  pp_newline (buffer);
2694169689Skan	}
2695169689Skan    }
2696169689Skan  pp_write_text_to_stream (buffer);
2697169689Skan  check_bb_profile (bb, buffer->buffer->stream);
2698169689Skan}
2699169689Skan
2700169689Skan/* Dumps end of basic block BB to buffer BUFFER indented by INDENT
2701169689Skan   spaces.  */
2702169689Skan
2703169689Skanstatic void
2704169689Skandump_bb_end (pretty_printer *buffer, basic_block bb, int indent, int flags)
2705169689Skan{
2706169689Skan  edge e;
2707169689Skan  edge_iterator ei;
2708169689Skan
2709169689Skan  INDENT (indent);
2710169689Skan  pp_string (buffer, "# SUCC:");
2711169689Skan  pp_write_text_to_stream (buffer);
2712169689Skan  FOR_EACH_EDGE (e, ei, bb->succs)
2713169689Skan    if (flags & TDF_SLIM)
2714169689Skan      {
2715169689Skan	pp_string (buffer, " ");
2716169689Skan	if (e->dest == EXIT_BLOCK_PTR)
2717169689Skan	  pp_string (buffer, "EXIT");
2718169689Skan	else
2719169689Skan	  pp_decimal_int (buffer, e->dest->index);
2720169689Skan      }
2721169689Skan    else
2722169689Skan      dump_edge_info (buffer->buffer->stream, e, 1);
2723169689Skan  pp_newline (buffer);
2724169689Skan}
2725169689Skan
2726169689Skan/* Dumps phi nodes of basic block BB to buffer BUFFER with details described by
2727169689Skan   FLAGS indented by INDENT spaces.  */
2728169689Skan
2729169689Skanstatic void
2730169689Skandump_phi_nodes (pretty_printer *buffer, basic_block bb, int indent, int flags)
2731169689Skan{
2732169689Skan  tree phi = phi_nodes (bb);
2733169689Skan  if (!phi)
2734169689Skan    return;
2735169689Skan
2736169689Skan  for (; phi; phi = PHI_CHAIN (phi))
2737169689Skan    {
2738169689Skan      if (is_gimple_reg (PHI_RESULT (phi)) || (flags & TDF_VOPS))
2739169689Skan        {
2740169689Skan          INDENT (indent);
2741169689Skan          pp_string (buffer, "# ");
2742169689Skan          dump_generic_node (buffer, phi, indent, flags, false);
2743169689Skan          pp_newline (buffer);
2744169689Skan        }
2745169689Skan    }
2746169689Skan}
2747169689Skan
2748169689Skan/* Dump jump to basic block BB that is represented implicitly in the cfg
2749169689Skan   to BUFFER.  */
2750169689Skan
2751169689Skanstatic void
2752169689Skanpp_cfg_jump (pretty_printer *buffer, basic_block bb)
2753169689Skan{
2754169689Skan  tree stmt;
2755169689Skan
2756169689Skan  stmt = first_stmt (bb);
2757169689Skan
2758169689Skan  pp_string (buffer, "goto <bb ");
2759169689Skan  pp_decimal_int (buffer, bb->index);
2760169689Skan  pp_string (buffer, ">");
2761169689Skan  if (stmt && TREE_CODE (stmt) == LABEL_EXPR)
2762169689Skan    {
2763169689Skan      pp_string (buffer, " (");
2764169689Skan      dump_generic_node (buffer, LABEL_EXPR_LABEL (stmt), 0, 0, false);
2765169689Skan      pp_string (buffer, ")");
2766169689Skan    }
2767169689Skan  pp_semicolon (buffer);
2768169689Skan}
2769169689Skan
2770169689Skan/* Dump edges represented implicitly in basic block BB to BUFFER, indented
2771169689Skan   by INDENT spaces, with details given by FLAGS.  */
2772169689Skan
2773169689Skanstatic void
2774169689Skandump_implicit_edges (pretty_printer *buffer, basic_block bb, int indent,
2775169689Skan		     int flags)
2776169689Skan{
2777169689Skan  edge e;
2778169689Skan  edge_iterator ei;
2779169689Skan
2780169689Skan  /* If there is a fallthru edge, we may need to add an artificial goto to the
2781169689Skan     dump.  */
2782169689Skan  FOR_EACH_EDGE (e, ei, bb->succs)
2783169689Skan    if (e->flags & EDGE_FALLTHRU)
2784169689Skan      break;
2785169689Skan  if (e && e->dest != bb->next_bb)
2786169689Skan    {
2787169689Skan      INDENT (indent);
2788169689Skan
2789169689Skan      if ((flags & TDF_LINENO)
2790169689Skan#ifdef USE_MAPPED_LOCATION
2791169689Skan	  && e->goto_locus != UNKNOWN_LOCATION
2792169689Skan#else
2793169689Skan	  && e->goto_locus
2794169689Skan#endif
2795169689Skan	  )
2796169689Skan	{
2797169689Skan	  expanded_location goto_xloc;
2798169689Skan#ifdef USE_MAPPED_LOCATION
2799169689Skan	  goto_xloc = expand_location (e->goto_locus);
2800169689Skan#else
2801169689Skan	  goto_xloc = *e->goto_locus;
2802169689Skan#endif
2803169689Skan	  pp_character (buffer, '[');
2804169689Skan	  if (goto_xloc.file)
2805169689Skan	    {
2806169689Skan	      pp_string (buffer, goto_xloc.file);
2807169689Skan	      pp_string (buffer, " : ");
2808169689Skan	    }
2809169689Skan	  pp_decimal_int (buffer, goto_xloc.line);
2810169689Skan	  pp_string (buffer, "] ");
2811169689Skan	}
2812169689Skan
2813169689Skan      pp_cfg_jump (buffer, e->dest);
2814169689Skan      pp_newline (buffer);
2815169689Skan    }
2816169689Skan}
2817169689Skan
2818169689Skan/* Dumps basic block BB to buffer BUFFER with details described by FLAGS and
2819169689Skan   indented by INDENT spaces.  */
2820169689Skan
2821169689Skanstatic void
2822169689Skandump_generic_bb_buff (pretty_printer *buffer, basic_block bb,
2823169689Skan		      int indent, int flags)
2824169689Skan{
2825169689Skan  block_stmt_iterator bsi;
2826169689Skan  tree stmt;
2827169689Skan  int label_indent = indent - 2;
2828169689Skan
2829169689Skan  if (label_indent < 0)
2830169689Skan    label_indent = 0;
2831169689Skan
2832169689Skan  dump_bb_header (buffer, bb, indent, flags);
2833169689Skan
2834169689Skan  dump_phi_nodes (buffer, bb, indent, flags);
2835169689Skan
2836169689Skan  for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
2837169689Skan    {
2838169689Skan      int curr_indent;
2839169689Skan
2840169689Skan      stmt = bsi_stmt (bsi);
2841169689Skan
2842169689Skan      curr_indent = TREE_CODE (stmt) == LABEL_EXPR ? label_indent : indent;
2843169689Skan
2844169689Skan      INDENT (curr_indent);
2845169689Skan      dump_generic_node (buffer, stmt, curr_indent, flags, true);
2846169689Skan      pp_newline (buffer);
2847169689Skan    }
2848169689Skan
2849169689Skan  dump_implicit_edges (buffer, bb, indent, flags);
2850169689Skan
2851169689Skan  if (flags & TDF_BLOCKS)
2852169689Skan    dump_bb_end (buffer, bb, indent, flags);
2853169689Skan}
2854