* testsuite/libgomp.fortran/vla7.f90: Add -w to options.
[official-gcc.git] / gcc / tree-pretty-print.c
blob62b58992460a2d923bd01285efae8970b783053f
1 /* Pretty formatting of GENERIC trees in C syntax.
2 Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006
3 Free Software Foundation, Inc.
4 Adapted from c-pretty-print.c by Diego Novillo <dnovillo@redhat.com>
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 2, or (at your option) any later
11 version.
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 for more details.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING. If not, write to the Free
20 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
21 02110-1301, USA. */
23 #include "config.h"
24 #include "system.h"
25 #include "coretypes.h"
26 #include "tm.h"
27 #include "tree.h"
28 #include "diagnostic.h"
29 #include "real.h"
30 #include "hashtab.h"
31 #include "tree-flow.h"
32 #include "langhooks.h"
33 #include "tree-iterator.h"
34 #include "tree-chrec.h"
35 #include "tree-pass.h"
37 /* Local functions, macros and variables. */
38 static int op_prio (tree);
39 static const char *op_symbol_1 (enum tree_code);
40 static const char *op_symbol (tree);
41 static void pretty_print_string (pretty_printer *, const char*);
42 static void print_call_name (pretty_printer *, tree);
43 static void newline_and_indent (pretty_printer *, int);
44 static void maybe_init_pretty_print (FILE *);
45 static void print_declaration (pretty_printer *, tree, int, int);
46 static void print_struct_decl (pretty_printer *, tree, int, int);
47 static void do_niy (pretty_printer *, tree);
48 static void dump_vops (pretty_printer *, tree, int, int);
49 static void dump_generic_bb_buff (pretty_printer *, basic_block, int, int);
51 #define INDENT(SPACE) do { \
52 int i; for (i = 0; i<SPACE; i++) pp_space (buffer); } while (0)
54 #define NIY do_niy(buffer,node)
56 #define PRINT_FUNCTION_NAME(NODE) pp_printf \
57 (buffer, "%s", TREE_CODE (NODE) == NOP_EXPR ? \
58 lang_hooks.decl_printable_name (TREE_OPERAND (NODE, 0), 1) : \
59 lang_hooks.decl_printable_name (NODE, 1))
61 static pretty_printer buffer;
62 static int initialized = 0;
64 /* Try to print something for an unknown tree code. */
66 static void
67 do_niy (pretty_printer *buffer, tree node)
69 int i, len;
71 pp_string (buffer, "<<< Unknown tree: ");
72 pp_string (buffer, tree_code_name[(int) TREE_CODE (node)]);
74 if (EXPR_P (node))
76 len = TREE_CODE_LENGTH (TREE_CODE (node));
77 for (i = 0; i < len; ++i)
79 newline_and_indent (buffer, 2);
80 dump_generic_node (buffer, TREE_OPERAND (node, i), 2, 0, false);
84 pp_string (buffer, " >>>\n");
87 void
88 debug_generic_expr (tree t)
90 print_generic_expr (stderr, t, TDF_VOPS|TDF_UID);
91 fprintf (stderr, "\n");
94 void
95 debug_generic_stmt (tree t)
97 print_generic_stmt (stderr, t, TDF_VOPS|TDF_UID);
98 fprintf (stderr, "\n");
101 void
102 debug_tree_chain (tree t)
104 print_generic_expr (stderr, t, TDF_VOPS|TDF_UID|TDF_CHAIN);
105 fprintf (stderr, "\n");
108 /* Prints declaration DECL to the FILE with details specified by FLAGS. */
109 void
110 print_generic_decl (FILE *file, tree decl, int flags)
112 maybe_init_pretty_print (file);
113 print_declaration (&buffer, decl, 2, flags);
114 pp_write_text_to_stream (&buffer);
117 /* Print tree T, and its successors, on file FILE. FLAGS specifies details
118 to show in the dump. See TDF_* in tree.h. */
120 void
121 print_generic_stmt (FILE *file, tree t, int flags)
123 maybe_init_pretty_print (file);
124 dump_generic_node (&buffer, t, 0, flags, true);
125 pp_flush (&buffer);
128 /* Print tree T, and its successors, on file FILE. FLAGS specifies details
129 to show in the dump. See TDF_* in tree.h. The output is indented by
130 INDENT spaces. */
132 void
133 print_generic_stmt_indented (FILE *file, tree t, int flags, int indent)
135 int i;
137 maybe_init_pretty_print (file);
139 for (i = 0; i < indent; i++)
140 pp_space (&buffer);
141 dump_generic_node (&buffer, t, indent, flags, true);
142 pp_flush (&buffer);
145 /* Print a single expression T on file FILE. FLAGS specifies details to show
146 in the dump. See TDF_* in tree.h. */
148 void
149 print_generic_expr (FILE *file, tree t, int flags)
151 maybe_init_pretty_print (file);
152 dump_generic_node (&buffer, t, 0, flags, false);
155 /* Dump the name of a _DECL node and its DECL_UID if TDF_UID is set
156 in FLAGS. */
158 static void
159 dump_decl_name (pretty_printer *buffer, tree node, int flags)
161 tree t = node;
163 while (t)
165 if (DECL_NAME (t))
166 pp_tree_identifier (buffer, DECL_NAME (t));
168 if ((flags & TDF_UID)
169 || DECL_NAME (t) == NULL_TREE)
171 if (TREE_CODE (t) == LABEL_DECL
172 && LABEL_DECL_UID (t) != -1)
173 pp_printf (buffer, "L." HOST_WIDE_INT_PRINT_DEC,
174 LABEL_DECL_UID (t));
175 else
177 char c = TREE_CODE (t) == CONST_DECL ? 'C' : 'D';
178 pp_printf (buffer, "%c.%u", c, DECL_UID (t));
182 if (flags & TDF_CHAIN)
184 t = TREE_CHAIN (t);
185 pp_string (buffer, " ");
187 else
188 t = NULL_TREE;
192 /* Like the above, but used for pretty printing function calls. */
194 static void
195 dump_function_name (pretty_printer *buffer, tree node)
197 if (DECL_NAME (node))
198 PRINT_FUNCTION_NAME (node);
199 else
200 dump_decl_name (buffer, node, 0);
203 /* Dump a function declaration. NODE is the FUNCTION_TYPE. BUFFER, SPC and
204 FLAGS are as in dump_generic_node. */
206 static void
207 dump_function_declaration (pretty_printer *buffer, tree node,
208 int spc, int flags)
210 bool wrote_arg = false;
211 tree arg;
213 pp_space (buffer);
214 pp_character (buffer, '(');
216 /* Print the argument types. The last element in the list is a VOID_TYPE.
217 The following avoids printing the last element. */
218 arg = TYPE_ARG_TYPES (node);
219 while (arg && TREE_CHAIN (arg) && arg != error_mark_node)
221 wrote_arg = true;
222 dump_generic_node (buffer, TREE_VALUE (arg), spc, flags, false);
223 arg = TREE_CHAIN (arg);
224 if (TREE_CHAIN (arg) && TREE_CODE (TREE_CHAIN (arg)) == TREE_LIST)
226 pp_character (buffer, ',');
227 pp_space (buffer);
231 if (!wrote_arg)
232 pp_string (buffer, "void");
234 pp_character (buffer, ')');
237 /* Dump the domain associated with an array. */
239 static void
240 dump_array_domain (pretty_printer *buffer, tree domain, int spc, int flags)
242 pp_character (buffer, '[');
243 if (domain)
245 tree min = TYPE_MIN_VALUE (domain);
246 tree max = TYPE_MAX_VALUE (domain);
248 if (min && max
249 && integer_zerop (min)
250 && host_integerp (max, 0))
251 pp_wide_integer (buffer, TREE_INT_CST_LOW (max) + 1);
252 else
254 if (min)
255 dump_generic_node (buffer, min, spc, flags, false);
256 pp_character (buffer, ':');
257 if (max)
258 dump_generic_node (buffer, max, spc, flags, false);
261 else
262 pp_string (buffer, "<unknown>");
263 pp_character (buffer, ']');
267 /* Dump OpenMP clause CLAUSE. BUFFER, CLAUSE, SPC and FLAGS are as in
268 dump_generic_node. */
270 static void
271 dump_omp_clause (pretty_printer *buffer, tree clause, int spc, int flags)
273 const char *name;
275 switch (OMP_CLAUSE_CODE (clause))
277 case OMP_CLAUSE_PRIVATE:
278 name = "private";
279 goto print_remap;
280 case OMP_CLAUSE_SHARED:
281 name = "shared";
282 goto print_remap;
283 case OMP_CLAUSE_FIRSTPRIVATE:
284 name = "firstprivate";
285 goto print_remap;
286 case OMP_CLAUSE_LASTPRIVATE:
287 name = "lastprivate";
288 goto print_remap;
289 case OMP_CLAUSE_COPYIN:
290 name = "copyin";
291 goto print_remap;
292 case OMP_CLAUSE_COPYPRIVATE:
293 name = "copyprivate";
294 goto print_remap;
295 print_remap:
296 pp_string (buffer, name);
297 pp_character (buffer, '(');
298 dump_generic_node (buffer, OMP_CLAUSE_DECL (clause),
299 spc, flags, false);
300 pp_character (buffer, ')');
301 break;
303 case OMP_CLAUSE_REDUCTION:
304 pp_string (buffer, "reduction(");
305 pp_string (buffer, op_symbol_1 (OMP_CLAUSE_REDUCTION_CODE (clause)));
306 pp_character (buffer, ':');
307 dump_generic_node (buffer, OMP_CLAUSE_DECL (clause),
308 spc, flags, false);
309 pp_character (buffer, ')');
310 break;
312 case OMP_CLAUSE_IF:
313 pp_string (buffer, "if(");
314 dump_generic_node (buffer, OMP_CLAUSE_IF_EXPR (clause),
315 spc, flags, false);
316 pp_character (buffer, ')');
317 break;
319 case OMP_CLAUSE_NUM_THREADS:
320 pp_string (buffer, "num_threads(");
321 dump_generic_node (buffer, OMP_CLAUSE_NUM_THREADS_EXPR (clause),
322 spc, flags, false);
323 pp_character (buffer, ')');
324 break;
326 case OMP_CLAUSE_NOWAIT:
327 pp_string (buffer, "nowait");
328 break;
329 case OMP_CLAUSE_ORDERED:
330 pp_string (buffer, "ordered");
331 break;
333 case OMP_CLAUSE_DEFAULT:
334 pp_string (buffer, "default(");
335 switch (OMP_CLAUSE_DEFAULT_KIND (clause))
337 case OMP_CLAUSE_DEFAULT_UNSPECIFIED:
338 break;
339 case OMP_CLAUSE_DEFAULT_SHARED:
340 pp_string (buffer, "shared");
341 break;
342 case OMP_CLAUSE_DEFAULT_NONE:
343 pp_string (buffer, "none");
344 break;
345 case OMP_CLAUSE_DEFAULT_PRIVATE:
346 pp_string (buffer, "private");
347 break;
348 default:
349 gcc_unreachable ();
351 pp_character (buffer, ')');
352 break;
354 case OMP_CLAUSE_SCHEDULE:
355 pp_string (buffer, "schedule(");
356 switch (OMP_CLAUSE_SCHEDULE_KIND (clause))
358 case OMP_CLAUSE_SCHEDULE_STATIC:
359 pp_string (buffer, "static");
360 break;
361 case OMP_CLAUSE_SCHEDULE_DYNAMIC:
362 pp_string (buffer, "dynamic");
363 break;
364 case OMP_CLAUSE_SCHEDULE_GUIDED:
365 pp_string (buffer, "guided");
366 break;
367 case OMP_CLAUSE_SCHEDULE_RUNTIME:
368 pp_string (buffer, "runtime");
369 break;
370 default:
371 gcc_unreachable ();
373 if (OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (clause))
375 pp_character (buffer, ',');
376 dump_generic_node (buffer,
377 OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (clause),
378 spc, flags, false);
380 pp_character (buffer, ')');
381 break;
383 default:
384 /* Should never happen. */
385 dump_generic_node (buffer, clause, spc, flags, false);
386 break;
391 /* Dump the list of OpenMP clauses. BUFFER, SPC and FLAGS are as in
392 dump_generic_node. */
394 static void
395 dump_omp_clauses (pretty_printer *buffer, tree clause, int spc, int flags)
397 if (clause == NULL)
398 return;
400 pp_space (buffer);
401 while (1)
403 dump_omp_clause (buffer, clause, spc, flags);
404 clause = OMP_CLAUSE_CHAIN (clause);
405 if (clause == NULL)
406 return;
407 pp_space (buffer);
412 /* Dump the node NODE on the pretty_printer BUFFER, SPC spaces of indent.
413 FLAGS specifies details to show in the dump (see TDF_* in tree.h). If
414 IS_STMT is true, the object printed is considered to be a statement
415 and it is terminated by ';' if appropriate. */
418 dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
419 bool is_stmt)
421 tree type;
422 tree op0, op1;
423 const char *str;
424 bool is_expr;
426 if (node == NULL_TREE)
427 return spc;
429 is_expr = EXPR_P (node);
431 if (TREE_CODE (node) != ERROR_MARK
432 && is_gimple_stmt (node)
433 && (flags & TDF_VOPS)
434 && stmt_ann (node)
435 && TREE_CODE (node) != PHI_NODE)
436 dump_vops (buffer, node, spc, flags);
438 if (is_stmt && (flags & TDF_STMTADDR))
439 pp_printf (buffer, "<&%p> ", (void *)node);
441 if ((flags & TDF_LINENO) && EXPR_HAS_LOCATION (node))
443 expanded_location xloc = expand_location (EXPR_LOCATION (node));
444 pp_character (buffer, '[');
445 if (xloc.file)
447 pp_string (buffer, xloc.file);
448 pp_string (buffer, " : ");
450 pp_decimal_int (buffer, xloc.line);
451 pp_string (buffer, "] ");
454 switch (TREE_CODE (node))
456 case ERROR_MARK:
457 pp_string (buffer, "<<< error >>>");
458 break;
460 case IDENTIFIER_NODE:
461 pp_tree_identifier (buffer, node);
462 break;
464 case TREE_LIST:
465 while (node && node != error_mark_node)
467 if (TREE_PURPOSE (node))
469 dump_generic_node (buffer, TREE_PURPOSE (node), spc, flags, false);
470 pp_space (buffer);
472 dump_generic_node (buffer, TREE_VALUE (node), spc, flags, false);
473 node = TREE_CHAIN (node);
474 if (node && TREE_CODE (node) == TREE_LIST)
476 pp_character (buffer, ',');
477 pp_space (buffer);
480 break;
482 case TREE_BINFO:
483 dump_generic_node (buffer, BINFO_TYPE (node), spc, flags, false);
485 case TREE_VEC:
487 size_t i;
488 if (TREE_VEC_LENGTH (node) > 0)
490 size_t len = TREE_VEC_LENGTH (node);
491 for (i = 0; i < len - 1; i++)
493 dump_generic_node (buffer, TREE_VEC_ELT (node, i), spc, flags,
494 false);
495 pp_character (buffer, ',');
496 pp_space (buffer);
498 dump_generic_node (buffer, TREE_VEC_ELT (node, len - 1), spc,
499 flags, false);
502 break;
504 case VOID_TYPE:
505 case INTEGER_TYPE:
506 case REAL_TYPE:
507 case COMPLEX_TYPE:
508 case VECTOR_TYPE:
509 case ENUMERAL_TYPE:
510 case BOOLEAN_TYPE:
511 case CHAR_TYPE:
513 unsigned int quals = TYPE_QUALS (node);
514 enum tree_code_class class;
516 if (quals & TYPE_QUAL_CONST)
517 pp_string (buffer, "const ");
518 else if (quals & TYPE_QUAL_VOLATILE)
519 pp_string (buffer, "volatile ");
520 else if (quals & TYPE_QUAL_RESTRICT)
521 pp_string (buffer, "restrict ");
523 class = TREE_CODE_CLASS (TREE_CODE (node));
525 if (class == tcc_declaration)
527 if (DECL_NAME (node))
528 dump_decl_name (buffer, node, flags);
529 else
530 pp_string (buffer, "<unnamed type decl>");
532 else if (class == tcc_type)
534 if (TYPE_NAME (node))
536 if (TREE_CODE (TYPE_NAME (node)) == IDENTIFIER_NODE)
537 pp_tree_identifier (buffer, TYPE_NAME (node));
538 else if (TREE_CODE (TYPE_NAME (node)) == TYPE_DECL
539 && DECL_NAME (TYPE_NAME (node)))
540 dump_decl_name (buffer, TYPE_NAME (node), flags);
541 else
542 pp_string (buffer, "<unnamed type>");
544 else if (TREE_CODE (node) == VECTOR_TYPE)
546 pp_string (buffer, "vector ");
547 dump_generic_node (buffer, TREE_TYPE (node),
548 spc, flags, false);
550 else
551 pp_string (buffer, "<unnamed type>");
553 break;
556 case POINTER_TYPE:
557 case REFERENCE_TYPE:
558 str = (TREE_CODE (node) == POINTER_TYPE ? "*" : "&");
560 if (TREE_CODE (TREE_TYPE (node)) == FUNCTION_TYPE)
562 tree fnode = TREE_TYPE (node);
564 dump_generic_node (buffer, TREE_TYPE (fnode), spc, flags, false);
565 pp_space (buffer);
566 pp_character (buffer, '(');
567 pp_string (buffer, str);
568 if (TYPE_NAME (node) && DECL_NAME (TYPE_NAME (node)))
569 dump_decl_name (buffer, TYPE_NAME (node), flags);
570 else
571 pp_printf (buffer, "<T%x>", TYPE_UID (node));
573 pp_character (buffer, ')');
574 dump_function_declaration (buffer, fnode, spc, flags);
576 else
578 unsigned int quals = TYPE_QUALS (node);
580 dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
581 pp_space (buffer);
582 pp_string (buffer, str);
584 if (quals & TYPE_QUAL_CONST)
585 pp_string (buffer, " const");
586 else if (quals & TYPE_QUAL_VOLATILE)
587 pp_string (buffer, "volatile");
588 else if (quals & TYPE_QUAL_RESTRICT)
589 pp_string (buffer, " restrict");
591 if (TYPE_REF_CAN_ALIAS_ALL (node))
592 pp_string (buffer, " {ref-all}");
594 break;
596 case OFFSET_TYPE:
597 NIY;
598 break;
600 case METHOD_TYPE:
601 dump_decl_name (buffer, TYPE_NAME (TYPE_METHOD_BASETYPE (node)), flags);
602 pp_string (buffer, "::");
603 break;
605 case TARGET_MEM_REF:
607 const char *sep = "";
608 tree tmp;
610 pp_string (buffer, "MEM[");
612 tmp = TMR_SYMBOL (node);
613 if (tmp)
615 pp_string (buffer, sep);
616 sep = ", ";
617 pp_string (buffer, "symbol: ");
618 dump_generic_node (buffer, tmp, spc, flags, false);
620 tmp = TMR_BASE (node);
621 if (tmp)
623 pp_string (buffer, sep);
624 sep = ", ";
625 pp_string (buffer, "base: ");
626 dump_generic_node (buffer, tmp, spc, flags, false);
628 tmp = TMR_INDEX (node);
629 if (tmp)
631 pp_string (buffer, sep);
632 sep = ", ";
633 pp_string (buffer, "index: ");
634 dump_generic_node (buffer, tmp, spc, flags, false);
636 tmp = TMR_STEP (node);
637 if (tmp)
639 pp_string (buffer, sep);
640 sep = ", ";
641 pp_string (buffer, "step: ");
642 dump_generic_node (buffer, tmp, spc, flags, false);
644 tmp = TMR_OFFSET (node);
645 if (tmp)
647 pp_string (buffer, sep);
648 sep = ", ";
649 pp_string (buffer, "offset: ");
650 dump_generic_node (buffer, tmp, spc, flags, false);
652 pp_string (buffer, "]");
653 if (flags & TDF_DETAILS)
655 pp_string (buffer, "{");
656 dump_generic_node (buffer, TMR_ORIGINAL (node), spc, flags,
657 false);
658 pp_string (buffer, "}");
661 break;
663 case ARRAY_TYPE:
665 tree tmp;
667 /* Print the innermost component type. */
668 for (tmp = TREE_TYPE (node); TREE_CODE (tmp) == ARRAY_TYPE;
669 tmp = TREE_TYPE (tmp))
671 dump_generic_node (buffer, tmp, spc, flags, false);
673 /* Print the dimensions. */
674 for (tmp = node; TREE_CODE (tmp) == ARRAY_TYPE; tmp = TREE_TYPE (tmp))
675 dump_array_domain (buffer, TYPE_DOMAIN (tmp), spc, flags);
676 break;
679 case RECORD_TYPE:
680 case UNION_TYPE:
681 case QUAL_UNION_TYPE:
682 /* Print the name of the structure. */
683 if (TREE_CODE (node) == RECORD_TYPE)
684 pp_string (buffer, "struct ");
685 else if (TREE_CODE (node) == UNION_TYPE)
686 pp_string (buffer, "union ");
688 if (TYPE_NAME (node))
689 dump_generic_node (buffer, TYPE_NAME (node), spc, flags, false);
690 else
691 print_struct_decl (buffer, node, spc, flags);
692 break;
694 case LANG_TYPE:
695 NIY;
696 break;
698 case INTEGER_CST:
699 if (TREE_CODE (TREE_TYPE (node)) == POINTER_TYPE)
701 /* In the case of a pointer, one may want to divide by the
702 size of the pointed-to type. Unfortunately, this not
703 straightforward. The C front-end maps expressions
705 (int *) 5
706 int *p; (p + 5)
708 in such a way that the two INTEGER_CST nodes for "5" have
709 different values but identical types. In the latter
710 case, the 5 is multiplied by sizeof (int) in c-common.c
711 (pointer_int_sum) to convert it to a byte address, and
712 yet the type of the node is left unchanged. Argh. What
713 is consistent though is that the number value corresponds
714 to bytes (UNITS) offset.
716 NB: Neither of the following divisors can be trivially
717 used to recover the original literal:
719 TREE_INT_CST_LOW (TYPE_SIZE_UNIT (TREE_TYPE (node)))
720 TYPE_PRECISION (TREE_TYPE (TREE_TYPE (node))) */
721 pp_wide_integer (buffer, TREE_INT_CST_LOW (node));
722 pp_string (buffer, "B"); /* pseudo-unit */
724 else if (! host_integerp (node, 0))
726 tree val = node;
728 if (tree_int_cst_sgn (val) < 0)
730 pp_character (buffer, '-');
731 val = build_int_cst_wide (NULL_TREE,
732 -TREE_INT_CST_LOW (val),
733 ~TREE_INT_CST_HIGH (val)
734 + !TREE_INT_CST_LOW (val));
736 /* Would "%x%0*x" or "%x%*0x" get zero-padding on all
737 systems? */
739 static char format[10]; /* "%x%09999x\0" */
740 if (!format[0])
741 sprintf (format, "%%x%%0%dx", HOST_BITS_PER_INT / 4);
742 sprintf (pp_buffer (buffer)->digit_buffer, format,
743 TREE_INT_CST_HIGH (val),
744 TREE_INT_CST_LOW (val));
745 pp_string (buffer, pp_buffer (buffer)->digit_buffer);
748 else
749 pp_wide_integer (buffer, TREE_INT_CST_LOW (node));
750 break;
752 case REAL_CST:
753 /* Code copied from print_node. */
755 REAL_VALUE_TYPE d;
756 if (TREE_OVERFLOW (node))
757 pp_string (buffer, " overflow");
759 #if !defined(REAL_IS_NOT_DOUBLE) || defined(REAL_ARITHMETIC)
760 d = TREE_REAL_CST (node);
761 if (REAL_VALUE_ISINF (d))
762 pp_string (buffer, " Inf");
763 else if (REAL_VALUE_ISNAN (d))
764 pp_string (buffer, " Nan");
765 else
767 char string[100];
768 real_to_decimal (string, &d, sizeof (string), 0, 1);
769 pp_string (buffer, string);
771 #else
773 HOST_WIDE_INT i;
774 unsigned char *p = (unsigned char *) &TREE_REAL_CST (node);
775 pp_string (buffer, "0x");
776 for (i = 0; i < sizeof TREE_REAL_CST (node); i++)
777 output_formatted_integer (buffer, "%02x", *p++);
779 #endif
780 break;
783 case COMPLEX_CST:
784 pp_string (buffer, "__complex__ (");
785 dump_generic_node (buffer, TREE_REALPART (node), spc, flags, false);
786 pp_string (buffer, ", ");
787 dump_generic_node (buffer, TREE_IMAGPART (node), spc, flags, false);
788 pp_string (buffer, ")");
789 break;
791 case STRING_CST:
792 pp_string (buffer, "\"");
793 pretty_print_string (buffer, TREE_STRING_POINTER (node));
794 pp_string (buffer, "\"");
795 break;
797 case VECTOR_CST:
799 tree elt;
800 pp_string (buffer, "{ ");
801 for (elt = TREE_VECTOR_CST_ELTS (node); elt; elt = TREE_CHAIN (elt))
803 dump_generic_node (buffer, TREE_VALUE (elt), spc, flags, false);
804 if (TREE_CHAIN (elt))
805 pp_string (buffer, ", ");
807 pp_string (buffer, " }");
809 break;
811 case FUNCTION_TYPE:
812 break;
814 case FUNCTION_DECL:
815 case CONST_DECL:
816 dump_decl_name (buffer, node, flags);
817 break;
819 case LABEL_DECL:
820 if (DECL_NAME (node))
821 dump_decl_name (buffer, node, flags);
822 else if (LABEL_DECL_UID (node) != -1)
823 pp_printf (buffer, "<L" HOST_WIDE_INT_PRINT_DEC ">",
824 LABEL_DECL_UID (node));
825 else
826 pp_printf (buffer, "<D%u>", DECL_UID (node));
827 break;
829 case TYPE_DECL:
830 if (DECL_IS_BUILTIN (node))
832 /* Don't print the declaration of built-in types. */
833 break;
835 if (DECL_NAME (node))
836 dump_decl_name (buffer, node, flags);
837 else
839 if ((TREE_CODE (TREE_TYPE (node)) == RECORD_TYPE
840 || TREE_CODE (TREE_TYPE (node)) == UNION_TYPE)
841 && TYPE_METHODS (TREE_TYPE (node)))
843 /* The type is a c++ class: all structures have at least
844 4 methods. */
845 pp_string (buffer, "class ");
846 dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
848 else
850 pp_string (buffer,
851 (TREE_CODE (TREE_TYPE (node)) == UNION_TYPE
852 ? "union" : "struct "));
853 dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
856 break;
858 case TYPE_MEMORY_TAG:
859 case NAME_MEMORY_TAG:
860 case STRUCT_FIELD_TAG:
861 case VAR_DECL:
862 case PARM_DECL:
863 case FIELD_DECL:
864 case NAMESPACE_DECL:
865 dump_decl_name (buffer, node, flags);
866 break;
868 case RESULT_DECL:
869 pp_string (buffer, "<retval>");
870 break;
872 case COMPONENT_REF:
873 op0 = TREE_OPERAND (node, 0);
874 str = ".";
875 if (TREE_CODE (op0) == INDIRECT_REF)
877 op0 = TREE_OPERAND (op0, 0);
878 str = "->";
880 if (op_prio (op0) < op_prio (node))
881 pp_character (buffer, '(');
882 dump_generic_node (buffer, op0, spc, flags, false);
883 if (op_prio (op0) < op_prio (node))
884 pp_character (buffer, ')');
885 pp_string (buffer, str);
886 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
888 if (TREE_CODE (op0) != VALUE_HANDLE)
890 op0 = component_ref_field_offset (node);
891 if (op0 && TREE_CODE (op0) != INTEGER_CST)
893 pp_string (buffer, "{off: ");
894 dump_generic_node (buffer, op0, spc, flags, false);
895 pp_character (buffer, '}');
898 break;
900 case BIT_FIELD_REF:
901 pp_string (buffer, "BIT_FIELD_REF <");
902 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
903 pp_string (buffer, ", ");
904 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
905 pp_string (buffer, ", ");
906 dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
907 pp_string (buffer, ">");
908 break;
910 case ARRAY_REF:
911 case ARRAY_RANGE_REF:
912 op0 = TREE_OPERAND (node, 0);
913 if (op_prio (op0) < op_prio (node))
914 pp_character (buffer, '(');
915 dump_generic_node (buffer, op0, spc, flags, false);
916 if (op_prio (op0) < op_prio (node))
917 pp_character (buffer, ')');
918 pp_character (buffer, '[');
919 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
920 if (TREE_CODE (node) == ARRAY_RANGE_REF)
921 pp_string (buffer, " ...");
922 pp_character (buffer, ']');
924 op0 = array_ref_low_bound (node);
925 op1 = array_ref_element_size (node);
927 if (!integer_zerop (op0)
928 || (TYPE_SIZE_UNIT (TREE_TYPE (node))
929 && !operand_equal_p (op1, TYPE_SIZE_UNIT (TREE_TYPE (node)), 0)))
931 pp_string (buffer, "{lb: ");
932 dump_generic_node (buffer, op0, spc, flags, false);
933 pp_string (buffer, " sz: ");
934 dump_generic_node (buffer, op1, spc, flags, false);
935 pp_character (buffer, '}');
937 break;
939 case CONSTRUCTOR:
941 unsigned HOST_WIDE_INT ix;
942 tree field, val;
943 bool is_struct_init = FALSE;
944 pp_character (buffer, '{');
945 if (TREE_CODE (TREE_TYPE (node)) == RECORD_TYPE
946 || TREE_CODE (TREE_TYPE (node)) == UNION_TYPE)
947 is_struct_init = TRUE;
948 FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (node), ix, field, val)
950 if (field && is_struct_init)
952 pp_character (buffer, '.');
953 dump_generic_node (buffer, field, spc, flags, false);
954 pp_string (buffer, "=");
956 if (val && TREE_CODE (val) == ADDR_EXPR)
957 if (TREE_CODE (TREE_OPERAND (val, 0)) == FUNCTION_DECL)
958 val = TREE_OPERAND (val, 0);
959 if (val && TREE_CODE (val) == FUNCTION_DECL)
960 dump_decl_name (buffer, val, flags);
961 else
962 dump_generic_node (buffer, val, spc, flags, false);
963 if (ix != VEC_length (constructor_elt, CONSTRUCTOR_ELTS (node)) - 1)
965 pp_character (buffer, ',');
966 pp_space (buffer);
969 pp_character (buffer, '}');
971 break;
973 case COMPOUND_EXPR:
975 tree *tp;
976 if (flags & TDF_SLIM)
978 pp_string (buffer, "<COMPOUND_EXPR>");
979 break;
982 dump_generic_node (buffer, TREE_OPERAND (node, 0),
983 spc, flags, !(flags & TDF_SLIM));
984 if (flags & TDF_SLIM)
985 newline_and_indent (buffer, spc);
986 else
988 pp_character (buffer, ',');
989 pp_space (buffer);
992 for (tp = &TREE_OPERAND (node, 1);
993 TREE_CODE (*tp) == COMPOUND_EXPR;
994 tp = &TREE_OPERAND (*tp, 1))
996 dump_generic_node (buffer, TREE_OPERAND (*tp, 0),
997 spc, flags, !(flags & TDF_SLIM));
998 if (flags & TDF_SLIM)
999 newline_and_indent (buffer, spc);
1000 else
1002 pp_character (buffer, ',');
1003 pp_space (buffer);
1007 dump_generic_node (buffer, *tp, spc, flags, !(flags & TDF_SLIM));
1009 break;
1011 case STATEMENT_LIST:
1013 tree_stmt_iterator si;
1014 bool first = true;
1016 if (flags & TDF_SLIM)
1018 pp_string (buffer, "<STATEMENT_LIST>");
1019 break;
1022 for (si = tsi_start (node); !tsi_end_p (si); tsi_next (&si))
1024 if (!first)
1025 newline_and_indent (buffer, spc);
1026 else
1027 first = false;
1028 dump_generic_node (buffer, tsi_stmt (si), spc, flags, true);
1031 break;
1033 case MODIFY_EXPR:
1034 case INIT_EXPR:
1035 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1036 pp_space (buffer);
1037 pp_character (buffer, '=');
1038 pp_space (buffer);
1039 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1040 break;
1042 case TARGET_EXPR:
1043 pp_string (buffer, "TARGET_EXPR <");
1044 dump_generic_node (buffer, TARGET_EXPR_SLOT (node), spc, flags, false);
1045 pp_character (buffer, ',');
1046 pp_space (buffer);
1047 dump_generic_node (buffer, TARGET_EXPR_INITIAL (node), spc, flags, false);
1048 pp_character (buffer, '>');
1049 break;
1051 case DECL_EXPR:
1052 print_declaration (buffer, DECL_EXPR_DECL (node), spc, flags);
1053 is_stmt = false;
1054 break;
1056 case COND_EXPR:
1057 if (TREE_TYPE (node) == NULL || TREE_TYPE (node) == void_type_node)
1059 pp_string (buffer, "if (");
1060 dump_generic_node (buffer, COND_EXPR_COND (node), spc, flags, false);
1061 pp_character (buffer, ')');
1062 /* The lowered cond_exprs should always be printed in full. */
1063 if (COND_EXPR_THEN (node)
1064 && (IS_EMPTY_STMT (COND_EXPR_THEN (node))
1065 || TREE_CODE (COND_EXPR_THEN (node)) == GOTO_EXPR)
1066 && COND_EXPR_ELSE (node)
1067 && (IS_EMPTY_STMT (COND_EXPR_ELSE (node))
1068 || TREE_CODE (COND_EXPR_ELSE (node)) == GOTO_EXPR))
1070 pp_space (buffer);
1071 dump_generic_node (buffer, COND_EXPR_THEN (node), 0, flags, true);
1072 pp_string (buffer, " else ");
1073 dump_generic_node (buffer, COND_EXPR_ELSE (node), 0, flags, true);
1075 else if (!(flags & TDF_SLIM))
1077 /* Output COND_EXPR_THEN. */
1078 if (COND_EXPR_THEN (node))
1080 newline_and_indent (buffer, spc+2);
1081 pp_character (buffer, '{');
1082 newline_and_indent (buffer, spc+4);
1083 dump_generic_node (buffer, COND_EXPR_THEN (node), spc+4,
1084 flags, true);
1085 newline_and_indent (buffer, spc+2);
1086 pp_character (buffer, '}');
1089 /* Output COND_EXPR_ELSE. */
1090 if (COND_EXPR_ELSE (node))
1092 newline_and_indent (buffer, spc);
1093 pp_string (buffer, "else");
1094 newline_and_indent (buffer, spc+2);
1095 pp_character (buffer, '{');
1096 newline_and_indent (buffer, spc+4);
1097 dump_generic_node (buffer, COND_EXPR_ELSE (node), spc+4,
1098 flags, true);
1099 newline_and_indent (buffer, spc+2);
1100 pp_character (buffer, '}');
1103 is_expr = false;
1105 else
1107 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1108 pp_space (buffer);
1109 pp_character (buffer, '?');
1110 pp_space (buffer);
1111 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1112 pp_space (buffer);
1113 pp_character (buffer, ':');
1114 pp_space (buffer);
1115 dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
1117 break;
1119 case BIND_EXPR:
1120 pp_character (buffer, '{');
1121 if (!(flags & TDF_SLIM))
1123 if (BIND_EXPR_VARS (node))
1125 pp_newline (buffer);
1127 for (op0 = BIND_EXPR_VARS (node); op0; op0 = TREE_CHAIN (op0))
1129 print_declaration (buffer, op0, spc+2, flags);
1130 pp_newline (buffer);
1134 newline_and_indent (buffer, spc+2);
1135 dump_generic_node (buffer, BIND_EXPR_BODY (node), spc+2, flags, true);
1136 newline_and_indent (buffer, spc);
1137 pp_character (buffer, '}');
1139 is_expr = false;
1140 break;
1142 case CALL_EXPR:
1143 print_call_name (buffer, node);
1145 /* Print parameters. */
1146 pp_space (buffer);
1147 pp_character (buffer, '(');
1148 op1 = TREE_OPERAND (node, 1);
1149 if (op1)
1150 dump_generic_node (buffer, op1, spc, flags, false);
1151 pp_character (buffer, ')');
1153 op1 = TREE_OPERAND (node, 2);
1154 if (op1)
1156 pp_string (buffer, " [static-chain: ");
1157 dump_generic_node (buffer, op1, spc, flags, false);
1158 pp_character (buffer, ']');
1161 if (CALL_EXPR_RETURN_SLOT_OPT (node))
1162 pp_string (buffer, " [return slot optimization]");
1163 if (CALL_EXPR_TAILCALL (node))
1164 pp_string (buffer, " [tail call]");
1165 break;
1167 case WITH_CLEANUP_EXPR:
1168 NIY;
1169 break;
1171 case CLEANUP_POINT_EXPR:
1172 pp_string (buffer, "<<cleanup_point ");
1173 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1174 pp_string (buffer, ">>");
1175 break;
1177 case PLACEHOLDER_EXPR:
1178 pp_string (buffer, "<PLACEHOLDER_EXPR ");
1179 dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
1180 pp_character (buffer, '>');
1181 break;
1183 /* Binary arithmetic and logic expressions. */
1184 case WIDEN_SUM_EXPR:
1185 case WIDEN_MULT_EXPR:
1186 case MULT_EXPR:
1187 case PLUS_EXPR:
1188 case MINUS_EXPR:
1189 case TRUNC_DIV_EXPR:
1190 case CEIL_DIV_EXPR:
1191 case FLOOR_DIV_EXPR:
1192 case ROUND_DIV_EXPR:
1193 case TRUNC_MOD_EXPR:
1194 case CEIL_MOD_EXPR:
1195 case FLOOR_MOD_EXPR:
1196 case ROUND_MOD_EXPR:
1197 case RDIV_EXPR:
1198 case EXACT_DIV_EXPR:
1199 case LSHIFT_EXPR:
1200 case RSHIFT_EXPR:
1201 case LROTATE_EXPR:
1202 case RROTATE_EXPR:
1203 case VEC_LSHIFT_EXPR:
1204 case VEC_RSHIFT_EXPR:
1205 case BIT_IOR_EXPR:
1206 case BIT_XOR_EXPR:
1207 case BIT_AND_EXPR:
1208 case TRUTH_ANDIF_EXPR:
1209 case TRUTH_ORIF_EXPR:
1210 case TRUTH_AND_EXPR:
1211 case TRUTH_OR_EXPR:
1212 case TRUTH_XOR_EXPR:
1213 case LT_EXPR:
1214 case LE_EXPR:
1215 case GT_EXPR:
1216 case GE_EXPR:
1217 case EQ_EXPR:
1218 case NE_EXPR:
1219 case UNLT_EXPR:
1220 case UNLE_EXPR:
1221 case UNGT_EXPR:
1222 case UNGE_EXPR:
1223 case UNEQ_EXPR:
1224 case LTGT_EXPR:
1225 case ORDERED_EXPR:
1226 case UNORDERED_EXPR:
1228 const char *op = op_symbol (node);
1229 op0 = TREE_OPERAND (node, 0);
1230 op1 = TREE_OPERAND (node, 1);
1232 /* When the operands are expressions with less priority,
1233 keep semantics of the tree representation. */
1234 if (op_prio (op0) < op_prio (node))
1236 pp_character (buffer, '(');
1237 dump_generic_node (buffer, op0, spc, flags, false);
1238 pp_character (buffer, ')');
1240 else
1241 dump_generic_node (buffer, op0, spc, flags, false);
1243 pp_space (buffer);
1244 pp_string (buffer, op);
1245 pp_space (buffer);
1247 /* When the operands are expressions with less priority,
1248 keep semantics of the tree representation. */
1249 if (op_prio (op1) < op_prio (node))
1251 pp_character (buffer, '(');
1252 dump_generic_node (buffer, op1, spc, flags, false);
1253 pp_character (buffer, ')');
1255 else
1256 dump_generic_node (buffer, op1, spc, flags, false);
1258 break;
1260 /* Unary arithmetic and logic expressions. */
1261 case NEGATE_EXPR:
1262 case BIT_NOT_EXPR:
1263 case TRUTH_NOT_EXPR:
1264 case ADDR_EXPR:
1265 case PREDECREMENT_EXPR:
1266 case PREINCREMENT_EXPR:
1267 case ALIGN_INDIRECT_REF:
1268 case MISALIGNED_INDIRECT_REF:
1269 case INDIRECT_REF:
1270 if (TREE_CODE (node) == ADDR_EXPR
1271 && (TREE_CODE (TREE_OPERAND (node, 0)) == STRING_CST
1272 || TREE_CODE (TREE_OPERAND (node, 0)) == FUNCTION_DECL))
1273 ; /* Do not output '&' for strings and function pointers. */
1274 else
1275 pp_string (buffer, op_symbol (node));
1277 if (op_prio (TREE_OPERAND (node, 0)) < op_prio (node))
1279 pp_character (buffer, '(');
1280 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1281 pp_character (buffer, ')');
1283 else
1284 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1286 if (TREE_CODE (node) == MISALIGNED_INDIRECT_REF)
1288 pp_string (buffer, "{misalignment: ");
1289 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1290 pp_character (buffer, '}');
1292 break;
1294 case POSTDECREMENT_EXPR:
1295 case POSTINCREMENT_EXPR:
1296 if (op_prio (TREE_OPERAND (node, 0)) < op_prio (node))
1298 pp_character (buffer, '(');
1299 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1300 pp_character (buffer, ')');
1302 else
1303 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1304 pp_string (buffer, op_symbol (node));
1305 break;
1307 case MIN_EXPR:
1308 pp_string (buffer, "MIN_EXPR <");
1309 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1310 pp_string (buffer, ", ");
1311 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1312 pp_character (buffer, '>');
1313 break;
1315 case MAX_EXPR:
1316 pp_string (buffer, "MAX_EXPR <");
1317 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1318 pp_string (buffer, ", ");
1319 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1320 pp_character (buffer, '>');
1321 break;
1323 case ABS_EXPR:
1324 pp_string (buffer, "ABS_EXPR <");
1325 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1326 pp_character (buffer, '>');
1327 break;
1329 case RANGE_EXPR:
1330 NIY;
1331 break;
1333 case FIX_TRUNC_EXPR:
1334 case FIX_CEIL_EXPR:
1335 case FIX_FLOOR_EXPR:
1336 case FIX_ROUND_EXPR:
1337 case FLOAT_EXPR:
1338 case CONVERT_EXPR:
1339 case NOP_EXPR:
1340 type = TREE_TYPE (node);
1341 op0 = TREE_OPERAND (node, 0);
1342 if (type != TREE_TYPE (op0))
1344 pp_character (buffer, '(');
1345 dump_generic_node (buffer, type, spc, flags, false);
1346 pp_string (buffer, ") ");
1348 if (op_prio (op0) < op_prio (node))
1349 pp_character (buffer, '(');
1350 dump_generic_node (buffer, op0, spc, flags, false);
1351 if (op_prio (op0) < op_prio (node))
1352 pp_character (buffer, ')');
1353 break;
1355 case VIEW_CONVERT_EXPR:
1356 pp_string (buffer, "VIEW_CONVERT_EXPR<");
1357 dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
1358 pp_string (buffer, ">(");
1359 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1360 pp_character (buffer, ')');
1361 break;
1363 case NON_LVALUE_EXPR:
1364 pp_string (buffer, "NON_LVALUE_EXPR <");
1365 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1366 pp_character (buffer, '>');
1367 break;
1369 case SAVE_EXPR:
1370 pp_string (buffer, "SAVE_EXPR <");
1371 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1372 pp_character (buffer, '>');
1373 break;
1375 case COMPLEX_EXPR:
1376 pp_string (buffer, "COMPLEX_EXPR <");
1377 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1378 pp_string (buffer, ", ");
1379 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1380 pp_string (buffer, ">");
1381 break;
1383 case CONJ_EXPR:
1384 pp_string (buffer, "CONJ_EXPR <");
1385 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1386 pp_string (buffer, ">");
1387 break;
1389 case REALPART_EXPR:
1390 pp_string (buffer, "REALPART_EXPR <");
1391 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1392 pp_string (buffer, ">");
1393 break;
1395 case IMAGPART_EXPR:
1396 pp_string (buffer, "IMAGPART_EXPR <");
1397 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1398 pp_string (buffer, ">");
1399 break;
1401 case VA_ARG_EXPR:
1402 pp_string (buffer, "VA_ARG_EXPR <");
1403 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1404 pp_string (buffer, ">");
1405 break;
1407 case TRY_FINALLY_EXPR:
1408 case TRY_CATCH_EXPR:
1409 pp_string (buffer, "try");
1410 newline_and_indent (buffer, spc+2);
1411 pp_string (buffer, "{");
1412 newline_and_indent (buffer, spc+4);
1413 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc+4, flags, true);
1414 newline_and_indent (buffer, spc+2);
1415 pp_string (buffer, "}");
1416 newline_and_indent (buffer, spc);
1417 pp_string (buffer,
1418 (TREE_CODE (node) == TRY_CATCH_EXPR) ? "catch" : "finally");
1419 newline_and_indent (buffer, spc+2);
1420 pp_string (buffer, "{");
1421 newline_and_indent (buffer, spc+4);
1422 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc+4, flags, true);
1423 newline_and_indent (buffer, spc+2);
1424 pp_string (buffer, "}");
1425 is_expr = false;
1426 break;
1428 case CATCH_EXPR:
1429 pp_string (buffer, "catch (");
1430 dump_generic_node (buffer, CATCH_TYPES (node), spc+2, flags, false);
1431 pp_string (buffer, ")");
1432 newline_and_indent (buffer, spc+2);
1433 pp_string (buffer, "{");
1434 newline_and_indent (buffer, spc+4);
1435 dump_generic_node (buffer, CATCH_BODY (node), spc+4, flags, true);
1436 newline_and_indent (buffer, spc+2);
1437 pp_string (buffer, "}");
1438 is_expr = false;
1439 break;
1441 case EH_FILTER_EXPR:
1442 pp_string (buffer, "<<<eh_filter (");
1443 dump_generic_node (buffer, EH_FILTER_TYPES (node), spc+2, flags, false);
1444 pp_string (buffer, ")>>>");
1445 newline_and_indent (buffer, spc+2);
1446 pp_string (buffer, "{");
1447 newline_and_indent (buffer, spc+4);
1448 dump_generic_node (buffer, EH_FILTER_FAILURE (node), spc+4, flags, true);
1449 newline_and_indent (buffer, spc+2);
1450 pp_string (buffer, "}");
1451 is_expr = false;
1452 break;
1454 case LABEL_EXPR:
1455 op0 = TREE_OPERAND (node, 0);
1456 /* If this is for break or continue, don't bother printing it. */
1457 if (DECL_NAME (op0))
1459 const char *name = IDENTIFIER_POINTER (DECL_NAME (op0));
1460 if (strcmp (name, "break") == 0
1461 || strcmp (name, "continue") == 0)
1462 break;
1464 dump_generic_node (buffer, op0, spc, flags, false);
1465 pp_character (buffer, ':');
1466 if (DECL_NONLOCAL (op0))
1467 pp_string (buffer, " [non-local]");
1468 break;
1470 case EXC_PTR_EXPR:
1471 pp_string (buffer, "<<<exception object>>>");
1472 break;
1474 case FILTER_EXPR:
1475 pp_string (buffer, "<<<filter object>>>");
1476 break;
1478 case LOOP_EXPR:
1479 pp_string (buffer, "while (1)");
1480 if (!(flags & TDF_SLIM))
1482 newline_and_indent (buffer, spc+2);
1483 pp_character (buffer, '{');
1484 newline_and_indent (buffer, spc+4);
1485 dump_generic_node (buffer, LOOP_EXPR_BODY (node), spc+4, flags, true);
1486 newline_and_indent (buffer, spc+2);
1487 pp_character (buffer, '}');
1489 is_expr = false;
1490 break;
1492 case RETURN_EXPR:
1493 pp_string (buffer, "return");
1494 op0 = TREE_OPERAND (node, 0);
1495 if (op0)
1497 pp_space (buffer);
1498 if (TREE_CODE (op0) == MODIFY_EXPR)
1499 dump_generic_node (buffer, TREE_OPERAND (op0, 1), spc, flags, false);
1500 else
1501 dump_generic_node (buffer, op0, spc, flags, false);
1503 break;
1505 case EXIT_EXPR:
1506 pp_string (buffer, "if (");
1507 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1508 pp_string (buffer, ") break");
1509 break;
1511 case SWITCH_EXPR:
1512 pp_string (buffer, "switch (");
1513 dump_generic_node (buffer, SWITCH_COND (node), spc, flags, false);
1514 pp_character (buffer, ')');
1515 if (!(flags & TDF_SLIM))
1517 newline_and_indent (buffer, spc+2);
1518 pp_character (buffer, '{');
1519 if (SWITCH_BODY (node))
1521 newline_and_indent (buffer, spc+4);
1522 dump_generic_node (buffer, SWITCH_BODY (node), spc+4, flags,
1523 true);
1525 else
1527 tree vec = SWITCH_LABELS (node);
1528 size_t i, n = TREE_VEC_LENGTH (vec);
1529 for (i = 0; i < n; ++i)
1531 tree elt = TREE_VEC_ELT (vec, i);
1532 newline_and_indent (buffer, spc+4);
1533 if (elt)
1535 dump_generic_node (buffer, elt, spc+4, flags, false);
1536 pp_string (buffer, " goto ");
1537 dump_generic_node (buffer, CASE_LABEL (elt), spc+4,
1538 flags, true);
1539 pp_semicolon (buffer);
1541 else
1542 pp_string (buffer, "case ???: goto ???;");
1545 newline_and_indent (buffer, spc+2);
1546 pp_character (buffer, '}');
1548 is_expr = false;
1549 break;
1551 case GOTO_EXPR:
1552 op0 = GOTO_DESTINATION (node);
1553 if (TREE_CODE (op0) != SSA_NAME && DECL_P (op0) && DECL_NAME (op0))
1555 const char *name = IDENTIFIER_POINTER (DECL_NAME (op0));
1556 if (strcmp (name, "break") == 0
1557 || strcmp (name, "continue") == 0)
1559 pp_string (buffer, name);
1560 break;
1563 pp_string (buffer, "goto ");
1564 dump_generic_node (buffer, op0, spc, flags, false);
1565 break;
1567 case RESX_EXPR:
1568 pp_string (buffer, "resx");
1569 /* ??? Any sensible way to present the eh region? */
1570 break;
1572 case ASM_EXPR:
1573 pp_string (buffer, "__asm__");
1574 if (ASM_VOLATILE_P (node))
1575 pp_string (buffer, " __volatile__");
1576 pp_character (buffer, '(');
1577 dump_generic_node (buffer, ASM_STRING (node), spc, flags, false);
1578 pp_character (buffer, ':');
1579 dump_generic_node (buffer, ASM_OUTPUTS (node), spc, flags, false);
1580 pp_character (buffer, ':');
1581 dump_generic_node (buffer, ASM_INPUTS (node), spc, flags, false);
1582 if (ASM_CLOBBERS (node))
1584 pp_character (buffer, ':');
1585 dump_generic_node (buffer, ASM_CLOBBERS (node), spc, flags, false);
1587 pp_string (buffer, ")");
1588 break;
1590 case CASE_LABEL_EXPR:
1591 if (CASE_LOW (node) && CASE_HIGH (node))
1593 pp_string (buffer, "case ");
1594 dump_generic_node (buffer, CASE_LOW (node), spc, flags, false);
1595 pp_string (buffer, " ... ");
1596 dump_generic_node (buffer, CASE_HIGH (node), spc, flags, false);
1598 else if (CASE_LOW (node))
1600 pp_string (buffer, "case ");
1601 dump_generic_node (buffer, CASE_LOW (node), spc, flags, false);
1603 else
1604 pp_string (buffer, "default ");
1605 pp_character (buffer, ':');
1606 break;
1608 case OBJ_TYPE_REF:
1609 pp_string (buffer, "OBJ_TYPE_REF(");
1610 dump_generic_node (buffer, OBJ_TYPE_REF_EXPR (node), spc, flags, false);
1611 pp_character (buffer, ';');
1612 dump_generic_node (buffer, OBJ_TYPE_REF_OBJECT (node), spc, flags, false);
1613 pp_character (buffer, '-');
1614 pp_character (buffer, '>');
1615 dump_generic_node (buffer, OBJ_TYPE_REF_TOKEN (node), spc, flags, false);
1616 pp_character (buffer, ')');
1617 break;
1619 case PHI_NODE:
1621 int i;
1623 dump_generic_node (buffer, PHI_RESULT (node), spc, flags, false);
1624 pp_string (buffer, " = PHI <");
1625 for (i = 0; i < PHI_NUM_ARGS (node); i++)
1627 dump_generic_node (buffer, PHI_ARG_DEF (node, i), spc, flags, false);
1628 pp_string (buffer, "(");
1629 pp_decimal_int (buffer, PHI_ARG_EDGE (node, i)->src->index);
1630 pp_string (buffer, ")");
1631 if (i < PHI_NUM_ARGS (node) - 1)
1632 pp_string (buffer, ", ");
1634 pp_string (buffer, ">;");
1636 break;
1638 case SSA_NAME:
1639 dump_generic_node (buffer, SSA_NAME_VAR (node), spc, flags, false);
1640 pp_string (buffer, "_");
1641 pp_decimal_int (buffer, SSA_NAME_VERSION (node));
1642 if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (node))
1643 pp_string (buffer, "(ab)");
1644 break;
1646 case WITH_SIZE_EXPR:
1647 pp_string (buffer, "WITH_SIZE_EXPR <");
1648 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1649 pp_string (buffer, ", ");
1650 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1651 pp_string (buffer, ">");
1652 break;
1654 case VALUE_HANDLE:
1655 pp_printf (buffer, "VH.%d", VALUE_HANDLE_ID (node));
1656 break;
1658 case ASSERT_EXPR:
1659 pp_string (buffer, "ASSERT_EXPR <");
1660 dump_generic_node (buffer, ASSERT_EXPR_VAR (node), spc, flags, false);
1661 pp_string (buffer, ", ");
1662 dump_generic_node (buffer, ASSERT_EXPR_COND (node), spc, flags, false);
1663 pp_string (buffer, ">");
1664 break;
1666 case SCEV_KNOWN:
1667 pp_string (buffer, "scev_known");
1668 break;
1670 case SCEV_NOT_KNOWN:
1671 pp_string (buffer, "scev_not_known");
1672 break;
1674 case POLYNOMIAL_CHREC:
1675 pp_string (buffer, "{");
1676 dump_generic_node (buffer, CHREC_LEFT (node), spc, flags, false);
1677 pp_string (buffer, ", +, ");
1678 dump_generic_node (buffer, CHREC_RIGHT (node), spc, flags, false);
1679 pp_string (buffer, "}_");
1680 dump_generic_node (buffer, CHREC_VAR (node), spc, flags, false);
1681 is_stmt = false;
1682 break;
1684 case REALIGN_LOAD_EXPR:
1685 pp_string (buffer, "REALIGN_LOAD <");
1686 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1687 pp_string (buffer, ", ");
1688 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1689 pp_string (buffer, ", ");
1690 dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
1691 pp_string (buffer, ">");
1692 break;
1694 case VEC_COND_EXPR:
1695 pp_string (buffer, " VEC_COND_EXPR < ");
1696 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1697 pp_string (buffer, " , ");
1698 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1699 pp_string (buffer, " , ");
1700 dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
1701 pp_string (buffer, " > ");
1702 break;
1704 case DOT_PROD_EXPR:
1705 pp_string (buffer, " DOT_PROD_EXPR < ");
1706 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1707 pp_string (buffer, " , ");
1708 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1709 pp_string (buffer, " , ");
1710 dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
1711 pp_string (buffer, " > ");
1712 break;
1714 case OMP_PARALLEL:
1715 pp_string (buffer, "#pragma omp parallel");
1716 dump_omp_clauses (buffer, OMP_PARALLEL_CLAUSES (node), spc, flags);
1717 if (OMP_PARALLEL_FN (node))
1719 pp_string (buffer, " [child fn: ");
1720 dump_generic_node (buffer, OMP_PARALLEL_FN (node), spc, flags, false);
1722 pp_string (buffer, " (");
1724 if (OMP_PARALLEL_DATA_ARG (node))
1725 dump_generic_node (buffer, OMP_PARALLEL_DATA_ARG (node), spc, flags,
1726 false);
1727 else
1728 pp_string (buffer, "???");
1730 pp_string (buffer, ")]");
1733 dump_omp_body:
1734 if (!(flags & TDF_SLIM) && OMP_BODY (node))
1736 newline_and_indent (buffer, spc + 2);
1737 pp_character (buffer, '{');
1738 newline_and_indent (buffer, spc + 4);
1739 dump_generic_node (buffer, OMP_BODY (node), spc + 4, flags, false);
1740 newline_and_indent (buffer, spc + 2);
1741 pp_character (buffer, '}');
1743 is_expr = false;
1744 break;
1746 case OMP_FOR:
1747 pp_string (buffer, "#pragma omp for");
1748 dump_omp_clauses (buffer, OMP_FOR_CLAUSES (node), spc, flags);
1750 if (!(flags & TDF_SLIM))
1752 if (OMP_FOR_PRE_BODY (node))
1754 newline_and_indent (buffer, spc + 2);
1755 pp_character (buffer, '{');
1756 spc += 4;
1757 newline_and_indent (buffer, spc);
1758 dump_generic_node (buffer, OMP_FOR_PRE_BODY (node),
1759 spc, flags, false);
1761 newline_and_indent (buffer, spc);
1762 pp_string (buffer, "for (");
1763 dump_generic_node (buffer, OMP_FOR_INIT (node), spc, flags, false);
1764 pp_string (buffer, "; ");
1765 dump_generic_node (buffer, OMP_FOR_COND (node), spc, flags, false);
1766 pp_string (buffer, "; ");
1767 dump_generic_node (buffer, OMP_FOR_INCR (node), spc, flags, false);
1768 pp_string (buffer, ")");
1769 if (OMP_FOR_BODY (node))
1771 newline_and_indent (buffer, spc + 2);
1772 pp_character (buffer, '{');
1773 newline_and_indent (buffer, spc + 4);
1774 dump_generic_node (buffer, OMP_FOR_BODY (node), spc + 4, flags,
1775 false);
1776 newline_and_indent (buffer, spc + 2);
1777 pp_character (buffer, '}');
1779 if (OMP_FOR_PRE_BODY (node))
1781 spc -= 4;
1782 newline_and_indent (buffer, spc + 2);
1783 pp_character (buffer, '}');
1786 is_expr = false;
1787 break;
1789 case OMP_SECTIONS:
1790 pp_string (buffer, "#pragma omp sections");
1791 dump_omp_clauses (buffer, OMP_SECTIONS_CLAUSES (node), spc, flags);
1792 goto dump_omp_body;
1794 case OMP_SECTION:
1795 pp_string (buffer, "#pragma omp section");
1796 goto dump_omp_body;
1798 case OMP_MASTER:
1799 pp_string (buffer, "#pragma omp master");
1800 goto dump_omp_body;
1802 case OMP_ORDERED:
1803 pp_string (buffer, "#pragma omp ordered");
1804 goto dump_omp_body;
1806 case OMP_CRITICAL:
1807 pp_string (buffer, "#pragma omp critical");
1808 if (OMP_CRITICAL_NAME (node))
1810 pp_space (buffer);
1811 pp_character (buffer, '(');
1812 dump_generic_node (buffer, OMP_CRITICAL_NAME (node), spc,
1813 flags, false);
1814 pp_character (buffer, ')');
1816 goto dump_omp_body;
1818 case OMP_ATOMIC:
1819 pp_string (buffer, "#pragma omp atomic");
1820 newline_and_indent (buffer, spc + 2);
1821 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1822 pp_space (buffer);
1823 pp_character (buffer, '=');
1824 pp_space (buffer);
1825 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1826 break;
1828 case OMP_SINGLE:
1829 pp_string (buffer, "#pragma omp single");
1830 dump_omp_clauses (buffer, OMP_SINGLE_CLAUSES (node), spc, flags);
1831 goto dump_omp_body;
1833 case OMP_RETURN_EXPR:
1834 pp_string (buffer, "OMP_RETURN");
1835 is_expr = false;
1836 break;
1838 case OMP_CLAUSE:
1839 dump_omp_clause (buffer, node, spc, flags);
1840 is_expr = false;
1841 break;
1843 case REDUC_MAX_EXPR:
1844 pp_string (buffer, " REDUC_MAX_EXPR < ");
1845 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1846 pp_string (buffer, " > ");
1847 break;
1849 case REDUC_MIN_EXPR:
1850 pp_string (buffer, " REDUC_MIN_EXPR < ");
1851 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1852 pp_string (buffer, " > ");
1853 break;
1855 case REDUC_PLUS_EXPR:
1856 pp_string (buffer, " REDUC_PLUS_EXPR < ");
1857 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1858 pp_string (buffer, " > ");
1859 break;
1861 case BLOCK:
1863 tree t;
1864 pp_string (buffer, "BLOCK");
1866 if (BLOCK_ABSTRACT (node))
1867 pp_string (buffer, " [abstract]");
1869 if (TREE_ASM_WRITTEN (node))
1870 pp_string (buffer, " [written]");
1872 newline_and_indent (buffer, spc + 2);
1874 if (BLOCK_SUPERCONTEXT (node))
1876 pp_string (buffer, "SUPERCONTEXT: ");
1877 if (TREE_CODE (BLOCK_SUPERCONTEXT (node)) == BLOCK)
1878 pp_printf (buffer, "BLOCK %p",
1879 (void *)BLOCK_SUPERCONTEXT (node));
1880 else
1881 dump_generic_node (buffer, BLOCK_SUPERCONTEXT (node), 0, flags,
1882 false);
1883 newline_and_indent (buffer, spc + 2);
1886 if (BLOCK_SUBBLOCKS (node))
1888 pp_string (buffer, "SUBBLOCKS: ");
1889 for (t = BLOCK_SUBBLOCKS (node); t; t = BLOCK_CHAIN (t))
1890 pp_printf (buffer, "%p ", (void *)t);
1891 newline_and_indent (buffer, spc + 2);
1894 if (BLOCK_VARS (node))
1896 pp_string (buffer, "VARS: ");
1897 for (t = BLOCK_VARS (node); t; t = TREE_CHAIN (t))
1899 dump_generic_node (buffer, t, 0, flags, false);
1900 pp_string (buffer, " ");
1902 newline_and_indent (buffer, spc + 2);
1905 if (BLOCK_ABSTRACT_ORIGIN (node))
1907 pp_string (buffer, "ABSTRACT_ORIGIN: ");
1908 if (TREE_CODE (BLOCK_ABSTRACT_ORIGIN (node)) == BLOCK)
1909 pp_printf (buffer, "BLOCK %p",
1910 (void *)BLOCK_ABSTRACT_ORIGIN (node));
1911 else
1912 dump_generic_node (buffer, BLOCK_ABSTRACT_ORIGIN (node), 0, flags,
1913 false);
1914 newline_and_indent (buffer, spc + 2);
1917 break;
1919 default:
1920 NIY;
1923 if (is_stmt && is_expr)
1924 pp_semicolon (buffer);
1925 pp_write_text_to_stream (buffer);
1927 return spc;
1930 /* Print the declaration of a variable. */
1932 static void
1933 print_declaration (pretty_printer *buffer, tree t, int spc, int flags)
1935 INDENT (spc);
1937 if (TREE_CODE (t) == TYPE_DECL)
1938 pp_string (buffer, "typedef ");
1940 if (CODE_CONTAINS_STRUCT (TREE_CODE (t), TS_DECL_WRTL) && DECL_REGISTER (t))
1941 pp_string (buffer, "register ");
1943 if (TREE_PUBLIC (t) && DECL_EXTERNAL (t))
1944 pp_string (buffer, "extern ");
1945 else if (TREE_STATIC (t))
1946 pp_string (buffer, "static ");
1948 /* Print the type and name. */
1949 if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
1951 tree tmp;
1953 /* Print array's type. */
1954 tmp = TREE_TYPE (t);
1955 while (TREE_CODE (TREE_TYPE (tmp)) == ARRAY_TYPE)
1956 tmp = TREE_TYPE (tmp);
1957 dump_generic_node (buffer, TREE_TYPE (tmp), spc, flags, false);
1959 /* Print variable's name. */
1960 pp_space (buffer);
1961 dump_generic_node (buffer, t, spc, flags, false);
1963 /* Print the dimensions. */
1964 tmp = TREE_TYPE (t);
1965 while (TREE_CODE (tmp) == ARRAY_TYPE)
1967 dump_array_domain (buffer, TYPE_DOMAIN (tmp), spc, flags);
1968 tmp = TREE_TYPE (tmp);
1971 else if (TREE_CODE (t) == FUNCTION_DECL)
1973 dump_generic_node (buffer, TREE_TYPE (TREE_TYPE (t)), spc, flags, false);
1974 pp_space (buffer);
1975 dump_decl_name (buffer, t, flags);
1976 dump_function_declaration (buffer, TREE_TYPE (t), spc, flags);
1978 else
1980 /* Print type declaration. */
1981 dump_generic_node (buffer, TREE_TYPE (t), spc, flags, false);
1983 /* Print variable's name. */
1984 pp_space (buffer);
1985 dump_generic_node (buffer, t, spc, flags, false);
1988 if (TREE_CODE (t) == VAR_DECL && DECL_HARD_REGISTER (t))
1990 pp_string (buffer, " __asm__ ");
1991 pp_character (buffer, '(');
1992 dump_generic_node (buffer, DECL_ASSEMBLER_NAME (t), spc, flags, false);
1993 pp_character (buffer, ')');
1996 /* The initial value of a function serves to determine wether the function
1997 is declared or defined. So the following does not apply to function
1998 nodes. */
1999 if (TREE_CODE (t) != FUNCTION_DECL)
2001 /* Print the initial value. */
2002 if (DECL_INITIAL (t))
2004 pp_space (buffer);
2005 pp_character (buffer, '=');
2006 pp_space (buffer);
2007 dump_generic_node (buffer, DECL_INITIAL (t), spc, flags, false);
2011 if (TREE_CODE (t) == VAR_DECL && DECL_HAS_VALUE_EXPR_P (t))
2013 pp_string (buffer, " [value-expr: ");
2014 dump_generic_node (buffer, DECL_VALUE_EXPR (t), spc, flags, false);
2015 pp_character (buffer, ']');
2018 pp_character (buffer, ';');
2022 /* Prints a structure: name, fields, and methods.
2023 FIXME: Still incomplete. */
2025 static void
2026 print_struct_decl (pretty_printer *buffer, tree node, int spc, int flags)
2028 /* Print the name of the structure. */
2029 if (TYPE_NAME (node))
2031 INDENT (spc);
2032 if (TREE_CODE (node) == RECORD_TYPE)
2033 pp_string (buffer, "struct ");
2034 else if ((TREE_CODE (node) == UNION_TYPE
2035 || TREE_CODE (node) == QUAL_UNION_TYPE))
2036 pp_string (buffer, "union ");
2038 dump_generic_node (buffer, TYPE_NAME (node), spc, 0, false);
2041 /* Print the contents of the structure. */
2042 pp_newline (buffer);
2043 INDENT (spc);
2044 pp_character (buffer, '{');
2045 pp_newline (buffer);
2047 /* Print the fields of the structure. */
2049 tree tmp;
2050 tmp = TYPE_FIELDS (node);
2051 while (tmp)
2053 /* Avoid to print recursively the structure. */
2054 /* FIXME : Not implemented correctly...,
2055 what about the case when we have a cycle in the contain graph? ...
2056 Maybe this could be solved by looking at the scope in which the
2057 structure was declared. */
2058 if (TREE_TYPE (tmp) != node
2059 || (TREE_CODE (TREE_TYPE (tmp)) == POINTER_TYPE
2060 && TREE_TYPE (TREE_TYPE (tmp)) != node))
2062 print_declaration (buffer, tmp, spc+2, flags);
2063 pp_newline (buffer);
2065 tmp = TREE_CHAIN (tmp);
2068 INDENT (spc);
2069 pp_character (buffer, '}');
2072 /* Return the priority of the operator OP.
2074 From lowest to highest precedence with either left-to-right (L-R)
2075 or right-to-left (R-L) associativity]:
2077 1 [L-R] ,
2078 2 [R-L] = += -= *= /= %= &= ^= |= <<= >>=
2079 3 [R-L] ?:
2080 4 [L-R] ||
2081 5 [L-R] &&
2082 6 [L-R] |
2083 7 [L-R] ^
2084 8 [L-R] &
2085 9 [L-R] == !=
2086 10 [L-R] < <= > >=
2087 11 [L-R] << >>
2088 12 [L-R] + -
2089 13 [L-R] * / %
2090 14 [R-L] ! ~ ++ -- + - * & (type) sizeof
2091 15 [L-R] fn() [] -> .
2093 unary +, - and * have higher precedence than the corresponding binary
2094 operators. */
2096 static int
2097 op_prio (tree op)
2099 if (op == NULL)
2100 return 9999;
2102 switch (TREE_CODE (op))
2104 case TREE_LIST:
2105 case COMPOUND_EXPR:
2106 case BIND_EXPR:
2107 return 1;
2109 case MODIFY_EXPR:
2110 case INIT_EXPR:
2111 return 2;
2113 case COND_EXPR:
2114 return 3;
2116 case TRUTH_OR_EXPR:
2117 case TRUTH_ORIF_EXPR:
2118 return 4;
2120 case TRUTH_AND_EXPR:
2121 case TRUTH_ANDIF_EXPR:
2122 return 5;
2124 case BIT_IOR_EXPR:
2125 return 6;
2127 case BIT_XOR_EXPR:
2128 case TRUTH_XOR_EXPR:
2129 return 7;
2131 case BIT_AND_EXPR:
2132 return 8;
2134 case EQ_EXPR:
2135 case NE_EXPR:
2136 return 9;
2138 case UNLT_EXPR:
2139 case UNLE_EXPR:
2140 case UNGT_EXPR:
2141 case UNGE_EXPR:
2142 case UNEQ_EXPR:
2143 case LTGT_EXPR:
2144 case ORDERED_EXPR:
2145 case UNORDERED_EXPR:
2146 case LT_EXPR:
2147 case LE_EXPR:
2148 case GT_EXPR:
2149 case GE_EXPR:
2150 return 10;
2152 case LSHIFT_EXPR:
2153 case RSHIFT_EXPR:
2154 case LROTATE_EXPR:
2155 case RROTATE_EXPR:
2156 return 11;
2158 case WIDEN_SUM_EXPR:
2159 case PLUS_EXPR:
2160 case MINUS_EXPR:
2161 return 12;
2163 case WIDEN_MULT_EXPR:
2164 case DOT_PROD_EXPR:
2165 case MULT_EXPR:
2166 case TRUNC_DIV_EXPR:
2167 case CEIL_DIV_EXPR:
2168 case FLOOR_DIV_EXPR:
2169 case ROUND_DIV_EXPR:
2170 case RDIV_EXPR:
2171 case EXACT_DIV_EXPR:
2172 case TRUNC_MOD_EXPR:
2173 case CEIL_MOD_EXPR:
2174 case FLOOR_MOD_EXPR:
2175 case ROUND_MOD_EXPR:
2176 return 13;
2178 case TRUTH_NOT_EXPR:
2179 case BIT_NOT_EXPR:
2180 case POSTINCREMENT_EXPR:
2181 case POSTDECREMENT_EXPR:
2182 case PREINCREMENT_EXPR:
2183 case PREDECREMENT_EXPR:
2184 case NEGATE_EXPR:
2185 case ALIGN_INDIRECT_REF:
2186 case MISALIGNED_INDIRECT_REF:
2187 case INDIRECT_REF:
2188 case ADDR_EXPR:
2189 case FLOAT_EXPR:
2190 case NOP_EXPR:
2191 case CONVERT_EXPR:
2192 case FIX_TRUNC_EXPR:
2193 case FIX_CEIL_EXPR:
2194 case FIX_FLOOR_EXPR:
2195 case FIX_ROUND_EXPR:
2196 case TARGET_EXPR:
2197 return 14;
2199 case CALL_EXPR:
2200 case ARRAY_REF:
2201 case ARRAY_RANGE_REF:
2202 case COMPONENT_REF:
2203 return 15;
2205 /* Special expressions. */
2206 case MIN_EXPR:
2207 case MAX_EXPR:
2208 case ABS_EXPR:
2209 case REALPART_EXPR:
2210 case IMAGPART_EXPR:
2211 case REDUC_MAX_EXPR:
2212 case REDUC_MIN_EXPR:
2213 case REDUC_PLUS_EXPR:
2214 case VEC_LSHIFT_EXPR:
2215 case VEC_RSHIFT_EXPR:
2216 return 16;
2218 case SAVE_EXPR:
2219 case NON_LVALUE_EXPR:
2220 return op_prio (TREE_OPERAND (op, 0));
2222 default:
2223 /* Return an arbitrarily high precedence to avoid surrounding single
2224 VAR_DECLs in ()s. */
2225 return 9999;
2230 /* Return the symbol associated with operator OP. */
2232 static const char *
2233 op_symbol_1 (enum tree_code code)
2235 switch (code)
2237 case MODIFY_EXPR:
2238 return "=";
2240 case TRUTH_OR_EXPR:
2241 case TRUTH_ORIF_EXPR:
2242 return "||";
2244 case TRUTH_AND_EXPR:
2245 case TRUTH_ANDIF_EXPR:
2246 return "&&";
2248 case BIT_IOR_EXPR:
2249 return "|";
2251 case TRUTH_XOR_EXPR:
2252 case BIT_XOR_EXPR:
2253 return "^";
2255 case ADDR_EXPR:
2256 case BIT_AND_EXPR:
2257 return "&";
2259 case ORDERED_EXPR:
2260 return "ord";
2261 case UNORDERED_EXPR:
2262 return "unord";
2264 case EQ_EXPR:
2265 return "==";
2266 case UNEQ_EXPR:
2267 return "u==";
2269 case NE_EXPR:
2270 return "!=";
2272 case LT_EXPR:
2273 return "<";
2274 case UNLT_EXPR:
2275 return "u<";
2277 case LE_EXPR:
2278 return "<=";
2279 case UNLE_EXPR:
2280 return "u<=";
2282 case GT_EXPR:
2283 return ">";
2284 case UNGT_EXPR:
2285 return "u>";
2287 case GE_EXPR:
2288 return ">=";
2289 case UNGE_EXPR:
2290 return "u>=";
2292 case LTGT_EXPR:
2293 return "<>";
2295 case LSHIFT_EXPR:
2296 return "<<";
2298 case RSHIFT_EXPR:
2299 return ">>";
2301 case LROTATE_EXPR:
2302 return "r<<";
2304 case RROTATE_EXPR:
2305 return "r>>";
2307 case VEC_LSHIFT_EXPR:
2308 return "v<<";
2310 case VEC_RSHIFT_EXPR:
2311 return "v>>";
2313 case PLUS_EXPR:
2314 return "+";
2316 case REDUC_PLUS_EXPR:
2317 return "r+";
2319 case WIDEN_SUM_EXPR:
2320 return "w+";
2322 case WIDEN_MULT_EXPR:
2323 return "w*";
2325 case NEGATE_EXPR:
2326 case MINUS_EXPR:
2327 return "-";
2329 case BIT_NOT_EXPR:
2330 return "~";
2332 case TRUTH_NOT_EXPR:
2333 return "!";
2335 case MULT_EXPR:
2336 case INDIRECT_REF:
2337 return "*";
2339 case ALIGN_INDIRECT_REF:
2340 return "A*";
2342 case MISALIGNED_INDIRECT_REF:
2343 return "M*";
2345 case TRUNC_DIV_EXPR:
2346 case RDIV_EXPR:
2347 return "/";
2349 case CEIL_DIV_EXPR:
2350 return "/[cl]";
2352 case FLOOR_DIV_EXPR:
2353 return "/[fl]";
2355 case ROUND_DIV_EXPR:
2356 return "/[rd]";
2358 case EXACT_DIV_EXPR:
2359 return "/[ex]";
2361 case TRUNC_MOD_EXPR:
2362 return "%";
2364 case CEIL_MOD_EXPR:
2365 return "%[cl]";
2367 case FLOOR_MOD_EXPR:
2368 return "%[fl]";
2370 case ROUND_MOD_EXPR:
2371 return "%[rd]";
2373 case PREDECREMENT_EXPR:
2374 return " --";
2376 case PREINCREMENT_EXPR:
2377 return " ++";
2379 case POSTDECREMENT_EXPR:
2380 return "-- ";
2382 case POSTINCREMENT_EXPR:
2383 return "++ ";
2385 case MAX_EXPR:
2386 return "max";
2388 case MIN_EXPR:
2389 return "min";
2391 default:
2392 return "<<< ??? >>>";
2396 static const char *
2397 op_symbol (tree op)
2399 return op_symbol_1 (TREE_CODE (op));
2402 /* Prints the name of a CALL_EXPR. */
2404 static void
2405 print_call_name (pretty_printer *buffer, tree node)
2407 tree op0;
2409 gcc_assert (TREE_CODE (node) == CALL_EXPR);
2411 op0 = TREE_OPERAND (node, 0);
2413 if (TREE_CODE (op0) == NON_LVALUE_EXPR)
2414 op0 = TREE_OPERAND (op0, 0);
2416 switch (TREE_CODE (op0))
2418 case VAR_DECL:
2419 case PARM_DECL:
2420 dump_function_name (buffer, op0);
2421 break;
2423 case ADDR_EXPR:
2424 case INDIRECT_REF:
2425 case NOP_EXPR:
2426 dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
2427 break;
2429 case COND_EXPR:
2430 pp_string (buffer, "(");
2431 dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
2432 pp_string (buffer, ") ? ");
2433 dump_generic_node (buffer, TREE_OPERAND (op0, 1), 0, 0, false);
2434 pp_string (buffer, " : ");
2435 dump_generic_node (buffer, TREE_OPERAND (op0, 2), 0, 0, false);
2436 break;
2438 case COMPONENT_REF:
2439 /* The function is a pointer contained in a structure. */
2440 if (TREE_CODE (TREE_OPERAND (op0, 0)) == INDIRECT_REF ||
2441 TREE_CODE (TREE_OPERAND (op0, 0)) == VAR_DECL)
2442 dump_function_name (buffer, TREE_OPERAND (op0, 1));
2443 else
2444 dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
2445 /* else
2446 We can have several levels of structures and a function
2447 pointer inside. This is not implemented yet... */
2448 /* NIY;*/
2449 break;
2451 case ARRAY_REF:
2452 if (TREE_CODE (TREE_OPERAND (op0, 0)) == VAR_DECL)
2453 dump_function_name (buffer, TREE_OPERAND (op0, 0));
2454 else
2455 dump_generic_node (buffer, op0, 0, 0, false);
2456 break;
2458 case SSA_NAME:
2459 case OBJ_TYPE_REF:
2460 dump_generic_node (buffer, op0, 0, 0, false);
2461 break;
2463 default:
2464 NIY;
2468 /* Parses the string STR and replaces new-lines by '\n', tabs by '\t', ... */
2470 static void
2471 pretty_print_string (pretty_printer *buffer, const char *str)
2473 if (str == NULL)
2474 return;
2476 while (*str)
2478 switch (str[0])
2480 case '\b':
2481 pp_string (buffer, "\\b");
2482 break;
2484 case '\f':
2485 pp_string (buffer, "\\f");
2486 break;
2488 case '\n':
2489 pp_string (buffer, "\\n");
2490 break;
2492 case '\r':
2493 pp_string (buffer, "\\r");
2494 break;
2496 case '\t':
2497 pp_string (buffer, "\\t");
2498 break;
2500 case '\v':
2501 pp_string (buffer, "\\v");
2502 break;
2504 case '\\':
2505 pp_string (buffer, "\\\\");
2506 break;
2508 case '\"':
2509 pp_string (buffer, "\\\"");
2510 break;
2512 case '\'':
2513 pp_string (buffer, "\\'");
2514 break;
2516 case '\0':
2517 pp_string (buffer, "\\0");
2518 break;
2520 case '\1':
2521 pp_string (buffer, "\\1");
2522 break;
2524 case '\2':
2525 pp_string (buffer, "\\2");
2526 break;
2528 case '\3':
2529 pp_string (buffer, "\\3");
2530 break;
2532 case '\4':
2533 pp_string (buffer, "\\4");
2534 break;
2536 case '\5':
2537 pp_string (buffer, "\\5");
2538 break;
2540 case '\6':
2541 pp_string (buffer, "\\6");
2542 break;
2544 case '\7':
2545 pp_string (buffer, "\\7");
2546 break;
2548 default:
2549 pp_character (buffer, str[0]);
2550 break;
2552 str++;
2556 static void
2557 maybe_init_pretty_print (FILE *file)
2559 if (!initialized)
2561 pp_construct (&buffer, /* prefix */NULL, /* line-width */0);
2562 pp_needs_newline (&buffer) = true;
2563 initialized = 1;
2566 buffer.buffer->stream = file;
2569 static void
2570 newline_and_indent (pretty_printer *buffer, int spc)
2572 pp_newline (buffer);
2573 INDENT (spc);
2576 static void
2577 dump_vops (pretty_printer *buffer, tree stmt, int spc, int flags)
2579 tree use;
2580 use_operand_p use_p;
2581 def_operand_p def_p;
2582 use_operand_p kill_p;
2583 ssa_op_iter iter;
2585 if (!ssa_operands_active ())
2586 return;
2588 FOR_EACH_SSA_MAYDEF_OPERAND (def_p, use_p, stmt, iter)
2590 pp_string (buffer, "# ");
2591 dump_generic_node (buffer, DEF_FROM_PTR (def_p),
2592 spc + 2, flags, false);
2593 pp_string (buffer, " = V_MAY_DEF <");
2594 dump_generic_node (buffer, USE_FROM_PTR (use_p),
2595 spc + 2, flags, false);
2596 pp_string (buffer, ">;");
2597 newline_and_indent (buffer, spc);
2600 FOR_EACH_SSA_MUSTDEF_OPERAND (def_p, kill_p, stmt, iter)
2602 pp_string (buffer, "# ");
2603 dump_generic_node (buffer, DEF_FROM_PTR (def_p),
2604 spc + 2, flags, false);
2605 pp_string (buffer, " = V_MUST_DEF <");
2606 dump_generic_node (buffer, USE_FROM_PTR (kill_p),
2607 spc + 2, flags, false);
2608 pp_string (buffer, ">;");
2609 newline_and_indent (buffer, spc);
2612 FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_VUSE)
2614 pp_string (buffer, "# VUSE <");
2615 dump_generic_node (buffer, use, spc + 2, flags, false);
2616 pp_string (buffer, ">;");
2617 newline_and_indent (buffer, spc);
2621 /* Dumps basic block BB to FILE with details described by FLAGS and
2622 indented by INDENT spaces. */
2624 void
2625 dump_generic_bb (FILE *file, basic_block bb, int indent, int flags)
2627 maybe_init_pretty_print (file);
2628 dump_generic_bb_buff (&buffer, bb, indent, flags);
2629 pp_flush (&buffer);
2632 /* Dumps header of basic block BB to buffer BUFFER indented by INDENT
2633 spaces and details described by flags. */
2635 static void
2636 dump_bb_header (pretty_printer *buffer, basic_block bb, int indent, int flags)
2638 edge e;
2639 tree stmt;
2640 edge_iterator ei;
2642 if (flags & TDF_BLOCKS)
2644 INDENT (indent);
2645 pp_string (buffer, "# BLOCK ");
2646 pp_decimal_int (buffer, bb->index);
2647 if (bb->frequency)
2649 pp_string (buffer, " freq:");
2650 pp_decimal_int (buffer, bb->frequency);
2652 if (bb->count)
2654 pp_string (buffer, " count:");
2655 pp_widest_integer (buffer, bb->count);
2658 if (flags & TDF_LINENO)
2660 block_stmt_iterator bsi;
2662 for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
2663 if (get_lineno (bsi_stmt (bsi)) != -1)
2665 pp_string (buffer, ", starting at line ");
2666 pp_decimal_int (buffer, get_lineno (bsi_stmt (bsi)));
2667 break;
2670 newline_and_indent (buffer, indent);
2672 pp_string (buffer, "# PRED:");
2673 pp_write_text_to_stream (buffer);
2674 FOR_EACH_EDGE (e, ei, bb->preds)
2675 if (flags & TDF_SLIM)
2677 pp_string (buffer, " ");
2678 if (e->src == ENTRY_BLOCK_PTR)
2679 pp_string (buffer, "ENTRY");
2680 else
2681 pp_decimal_int (buffer, e->src->index);
2683 else
2684 dump_edge_info (buffer->buffer->stream, e, 0);
2685 pp_newline (buffer);
2687 else
2689 stmt = first_stmt (bb);
2690 if (!stmt || TREE_CODE (stmt) != LABEL_EXPR)
2692 INDENT (indent - 2);
2693 pp_string (buffer, "<bb ");
2694 pp_decimal_int (buffer, bb->index);
2695 pp_string (buffer, ">:");
2696 pp_newline (buffer);
2699 pp_write_text_to_stream (buffer);
2700 check_bb_profile (bb, buffer->buffer->stream);
2703 /* Dumps end of basic block BB to buffer BUFFER indented by INDENT
2704 spaces. */
2706 static void
2707 dump_bb_end (pretty_printer *buffer, basic_block bb, int indent, int flags)
2709 edge e;
2710 edge_iterator ei;
2712 INDENT (indent);
2713 pp_string (buffer, "# SUCC:");
2714 pp_write_text_to_stream (buffer);
2715 FOR_EACH_EDGE (e, ei, bb->succs)
2716 if (flags & TDF_SLIM)
2718 pp_string (buffer, " ");
2719 if (e->dest == EXIT_BLOCK_PTR)
2720 pp_string (buffer, "EXIT");
2721 else
2722 pp_decimal_int (buffer, e->dest->index);
2724 else
2725 dump_edge_info (buffer->buffer->stream, e, 1);
2726 pp_newline (buffer);
2729 /* Dumps phi nodes of basic block BB to buffer BUFFER with details described by
2730 FLAGS indented by INDENT spaces. */
2732 static void
2733 dump_phi_nodes (pretty_printer *buffer, basic_block bb, int indent, int flags)
2735 tree phi = phi_nodes (bb);
2736 if (!phi)
2737 return;
2739 for (; phi; phi = PHI_CHAIN (phi))
2741 if (is_gimple_reg (PHI_RESULT (phi)) || (flags & TDF_VOPS))
2743 INDENT (indent);
2744 pp_string (buffer, "# ");
2745 dump_generic_node (buffer, phi, indent, flags, false);
2746 pp_newline (buffer);
2751 /* Dump jump to basic block BB that is represented implicitly in the cfg
2752 to BUFFER. */
2754 static void
2755 pp_cfg_jump (pretty_printer *buffer, basic_block bb)
2757 tree stmt;
2759 stmt = first_stmt (bb);
2761 pp_string (buffer, "goto <bb ");
2762 pp_decimal_int (buffer, bb->index);
2763 pp_string (buffer, ">");
2764 if (stmt && TREE_CODE (stmt) == LABEL_EXPR)
2766 pp_string (buffer, " (");
2767 dump_generic_node (buffer, LABEL_EXPR_LABEL (stmt), 0, 0, false);
2768 pp_string (buffer, ")");
2770 pp_semicolon (buffer);
2773 /* Dump edges represented implicitly in basic block BB to BUFFER, indented
2774 by INDENT spaces, with details given by FLAGS. */
2776 static void
2777 dump_implicit_edges (pretty_printer *buffer, basic_block bb, int indent,
2778 int flags)
2780 edge e;
2781 edge_iterator ei;
2783 /* If there is a fallthru edge, we may need to add an artificial goto to the
2784 dump. */
2785 FOR_EACH_EDGE (e, ei, bb->succs)
2786 if (e->flags & EDGE_FALLTHRU)
2787 break;
2788 if (e && e->dest != bb->next_bb)
2790 INDENT (indent);
2792 if ((flags & TDF_LINENO)
2793 #ifdef USE_MAPPED_LOCATION
2794 && e->goto_locus != UNKNOWN_LOCATION
2795 #else
2796 && e->goto_locus
2797 #endif
2800 expanded_location goto_xloc;
2801 #ifdef USE_MAPPED_LOCATION
2802 goto_xloc = expand_location (e->goto_locus);
2803 #else
2804 goto_xloc = *e->goto_locus;
2805 #endif
2806 pp_character (buffer, '[');
2807 if (goto_xloc.file)
2809 pp_string (buffer, goto_xloc.file);
2810 pp_string (buffer, " : ");
2812 pp_decimal_int (buffer, goto_xloc.line);
2813 pp_string (buffer, "] ");
2816 pp_cfg_jump (buffer, e->dest);
2817 pp_newline (buffer);
2821 /* Dumps basic block BB to buffer BUFFER with details described by FLAGS and
2822 indented by INDENT spaces. */
2824 static void
2825 dump_generic_bb_buff (pretty_printer *buffer, basic_block bb,
2826 int indent, int flags)
2828 block_stmt_iterator bsi;
2829 tree stmt;
2830 int label_indent = indent - 2;
2832 if (label_indent < 0)
2833 label_indent = 0;
2835 dump_bb_header (buffer, bb, indent, flags);
2837 dump_phi_nodes (buffer, bb, indent, flags);
2839 for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
2841 int curr_indent;
2843 stmt = bsi_stmt (bsi);
2845 curr_indent = TREE_CODE (stmt) == LABEL_EXPR ? label_indent : indent;
2847 INDENT (curr_indent);
2848 dump_generic_node (buffer, stmt, curr_indent, flags, true);
2849 pp_newline (buffer);
2852 dump_implicit_edges (buffer, bb, indent, flags);
2854 if (flags & TDF_BLOCKS)
2855 dump_bb_end (buffer, bb, indent, flags);