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