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