Merge from mainline
[official-gcc.git] / gcc / tree-pretty-print.c
blobfdf3f132a309186a5e675d418fe1540c5bc540df
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:
512 unsigned int quals = TYPE_QUALS (node);
513 enum tree_code_class class;
515 if (quals & TYPE_QUAL_CONST)
516 pp_string (buffer, "const ");
517 else if (quals & TYPE_QUAL_VOLATILE)
518 pp_string (buffer, "volatile ");
519 else if (quals & TYPE_QUAL_RESTRICT)
520 pp_string (buffer, "restrict ");
522 class = TREE_CODE_CLASS (TREE_CODE (node));
524 if (class == tcc_declaration)
526 if (DECL_NAME (node))
527 dump_decl_name (buffer, node, flags);
528 else
529 pp_string (buffer, "<unnamed type decl>");
531 else if (class == tcc_type)
533 if (TYPE_NAME (node))
535 if (TREE_CODE (TYPE_NAME (node)) == IDENTIFIER_NODE)
536 pp_tree_identifier (buffer, TYPE_NAME (node));
537 else if (TREE_CODE (TYPE_NAME (node)) == TYPE_DECL
538 && DECL_NAME (TYPE_NAME (node)))
539 dump_decl_name (buffer, TYPE_NAME (node), flags);
540 else
541 pp_string (buffer, "<unnamed type>");
543 else if (TREE_CODE (node) == VECTOR_TYPE)
545 pp_string (buffer, "vector ");
546 dump_generic_node (buffer, TREE_TYPE (node),
547 spc, flags, false);
549 else
550 pp_string (buffer, "<unnamed type>");
552 break;
555 case POINTER_TYPE:
556 case REFERENCE_TYPE:
557 str = (TREE_CODE (node) == POINTER_TYPE ? "*" : "&");
559 if (TREE_CODE (TREE_TYPE (node)) == FUNCTION_TYPE)
561 tree fnode = TREE_TYPE (node);
563 dump_generic_node (buffer, TREE_TYPE (fnode), spc, flags, false);
564 pp_space (buffer);
565 pp_character (buffer, '(');
566 pp_string (buffer, str);
567 if (TYPE_NAME (node) && DECL_NAME (TYPE_NAME (node)))
568 dump_decl_name (buffer, TYPE_NAME (node), flags);
569 else
570 pp_printf (buffer, "<T%x>", TYPE_UID (node));
572 pp_character (buffer, ')');
573 dump_function_declaration (buffer, fnode, spc, flags);
575 else
577 unsigned int quals = TYPE_QUALS (node);
579 dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
580 pp_space (buffer);
581 pp_string (buffer, str);
583 if (quals & TYPE_QUAL_CONST)
584 pp_string (buffer, " const");
585 else if (quals & TYPE_QUAL_VOLATILE)
586 pp_string (buffer, "volatile");
587 else if (quals & TYPE_QUAL_RESTRICT)
588 pp_string (buffer, " restrict");
590 if (TYPE_REF_CAN_ALIAS_ALL (node))
591 pp_string (buffer, " {ref-all}");
593 break;
595 case OFFSET_TYPE:
596 NIY;
597 break;
599 case METHOD_TYPE:
600 dump_decl_name (buffer, TYPE_NAME (TYPE_METHOD_BASETYPE (node)), flags);
601 pp_string (buffer, "::");
602 break;
604 case TARGET_MEM_REF:
606 const char *sep = "";
607 tree tmp;
609 pp_string (buffer, "MEM[");
611 tmp = TMR_SYMBOL (node);
612 if (tmp)
614 pp_string (buffer, sep);
615 sep = ", ";
616 pp_string (buffer, "symbol: ");
617 dump_generic_node (buffer, tmp, spc, flags, false);
619 tmp = TMR_BASE (node);
620 if (tmp)
622 pp_string (buffer, sep);
623 sep = ", ";
624 pp_string (buffer, "base: ");
625 dump_generic_node (buffer, tmp, spc, flags, false);
627 tmp = TMR_INDEX (node);
628 if (tmp)
630 pp_string (buffer, sep);
631 sep = ", ";
632 pp_string (buffer, "index: ");
633 dump_generic_node (buffer, tmp, spc, flags, false);
635 tmp = TMR_STEP (node);
636 if (tmp)
638 pp_string (buffer, sep);
639 sep = ", ";
640 pp_string (buffer, "step: ");
641 dump_generic_node (buffer, tmp, spc, flags, false);
643 tmp = TMR_OFFSET (node);
644 if (tmp)
646 pp_string (buffer, sep);
647 sep = ", ";
648 pp_string (buffer, "offset: ");
649 dump_generic_node (buffer, tmp, spc, flags, false);
651 pp_string (buffer, "]");
652 if (flags & TDF_DETAILS)
654 pp_string (buffer, "{");
655 dump_generic_node (buffer, TMR_ORIGINAL (node), spc, flags,
656 false);
657 pp_string (buffer, "}");
660 break;
662 case ARRAY_TYPE:
664 tree tmp;
666 /* Print the innermost component type. */
667 for (tmp = TREE_TYPE (node); TREE_CODE (tmp) == ARRAY_TYPE;
668 tmp = TREE_TYPE (tmp))
670 dump_generic_node (buffer, tmp, spc, flags, false);
672 /* Print the dimensions. */
673 for (tmp = node; TREE_CODE (tmp) == ARRAY_TYPE; tmp = TREE_TYPE (tmp))
674 dump_array_domain (buffer, TYPE_DOMAIN (tmp), spc, flags);
675 break;
678 case RECORD_TYPE:
679 case UNION_TYPE:
680 case QUAL_UNION_TYPE:
681 /* Print the name of the structure. */
682 if (TREE_CODE (node) == RECORD_TYPE)
683 pp_string (buffer, "struct ");
684 else if (TREE_CODE (node) == UNION_TYPE)
685 pp_string (buffer, "union ");
687 if (TYPE_NAME (node))
688 dump_generic_node (buffer, TYPE_NAME (node), spc, flags, false);
689 else
690 print_struct_decl (buffer, node, spc, flags);
691 break;
693 case LANG_TYPE:
694 NIY;
695 break;
697 case INTEGER_CST:
698 if (TREE_CODE (TREE_TYPE (node)) == POINTER_TYPE)
700 /* In the case of a pointer, one may want to divide by the
701 size of the pointed-to type. Unfortunately, this not
702 straightforward. The C front-end maps expressions
704 (int *) 5
705 int *p; (p + 5)
707 in such a way that the two INTEGER_CST nodes for "5" have
708 different values but identical types. In the latter
709 case, the 5 is multiplied by sizeof (int) in c-common.c
710 (pointer_int_sum) to convert it to a byte address, and
711 yet the type of the node is left unchanged. Argh. What
712 is consistent though is that the number value corresponds
713 to bytes (UNITS) offset.
715 NB: Neither of the following divisors can be trivially
716 used to recover the original literal:
718 TREE_INT_CST_LOW (TYPE_SIZE_UNIT (TREE_TYPE (node)))
719 TYPE_PRECISION (TREE_TYPE (TREE_TYPE (node))) */
720 pp_wide_integer (buffer, TREE_INT_CST_LOW (node));
721 pp_string (buffer, "B"); /* pseudo-unit */
723 else if (! host_integerp (node, 0))
725 tree val = node;
727 if (tree_int_cst_sgn (val) < 0)
729 pp_character (buffer, '-');
730 val = build_int_cst_wide (NULL_TREE,
731 -TREE_INT_CST_LOW (val),
732 ~TREE_INT_CST_HIGH (val)
733 + !TREE_INT_CST_LOW (val));
735 /* Would "%x%0*x" or "%x%*0x" get zero-padding on all
736 systems? */
738 static char format[10]; /* "%x%09999x\0" */
739 if (!format[0])
740 sprintf (format, "%%x%%0%dx", HOST_BITS_PER_INT / 4);
741 sprintf (pp_buffer (buffer)->digit_buffer, format,
742 TREE_INT_CST_HIGH (val),
743 TREE_INT_CST_LOW (val));
744 pp_string (buffer, pp_buffer (buffer)->digit_buffer);
747 else
748 pp_wide_integer (buffer, TREE_INT_CST_LOW (node));
749 break;
751 case REAL_CST:
752 /* Code copied from print_node. */
754 REAL_VALUE_TYPE d;
755 if (TREE_OVERFLOW (node))
756 pp_string (buffer, " overflow");
758 #if !defined(REAL_IS_NOT_DOUBLE) || defined(REAL_ARITHMETIC)
759 d = TREE_REAL_CST (node);
760 if (REAL_VALUE_ISINF (d))
761 pp_string (buffer, " Inf");
762 else if (REAL_VALUE_ISNAN (d))
763 pp_string (buffer, " Nan");
764 else
766 char string[100];
767 real_to_decimal (string, &d, sizeof (string), 0, 1);
768 pp_string (buffer, string);
770 #else
772 HOST_WIDE_INT i;
773 unsigned char *p = (unsigned char *) &TREE_REAL_CST (node);
774 pp_string (buffer, "0x");
775 for (i = 0; i < sizeof TREE_REAL_CST (node); i++)
776 output_formatted_integer (buffer, "%02x", *p++);
778 #endif
779 break;
782 case COMPLEX_CST:
783 pp_string (buffer, "__complex__ (");
784 dump_generic_node (buffer, TREE_REALPART (node), spc, flags, false);
785 pp_string (buffer, ", ");
786 dump_generic_node (buffer, TREE_IMAGPART (node), spc, flags, false);
787 pp_string (buffer, ")");
788 break;
790 case STRING_CST:
791 pp_string (buffer, "\"");
792 pretty_print_string (buffer, TREE_STRING_POINTER (node));
793 pp_string (buffer, "\"");
794 break;
796 case VECTOR_CST:
798 tree elt;
799 pp_string (buffer, "{ ");
800 for (elt = TREE_VECTOR_CST_ELTS (node); elt; elt = TREE_CHAIN (elt))
802 dump_generic_node (buffer, TREE_VALUE (elt), spc, flags, false);
803 if (TREE_CHAIN (elt))
804 pp_string (buffer, ", ");
806 pp_string (buffer, " }");
808 break;
810 case FUNCTION_TYPE:
811 break;
813 case FUNCTION_DECL:
814 case CONST_DECL:
815 dump_decl_name (buffer, node, flags);
816 break;
818 case LABEL_DECL:
819 if (DECL_NAME (node))
820 dump_decl_name (buffer, node, flags);
821 else if (LABEL_DECL_UID (node) != -1)
822 pp_printf (buffer, "<L" HOST_WIDE_INT_PRINT_DEC ">",
823 LABEL_DECL_UID (node));
824 else
825 pp_printf (buffer, "<D%u>", DECL_UID (node));
826 break;
828 case TYPE_DECL:
829 if (DECL_IS_BUILTIN (node))
831 /* Don't print the declaration of built-in types. */
832 break;
834 if (DECL_NAME (node))
835 dump_decl_name (buffer, node, flags);
836 else
838 if ((TREE_CODE (TREE_TYPE (node)) == RECORD_TYPE
839 || TREE_CODE (TREE_TYPE (node)) == UNION_TYPE)
840 && TYPE_METHODS (TREE_TYPE (node)))
842 /* The type is a c++ class: all structures have at least
843 4 methods. */
844 pp_string (buffer, "class ");
845 dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
847 else
849 pp_string (buffer,
850 (TREE_CODE (TREE_TYPE (node)) == UNION_TYPE
851 ? "union" : "struct "));
852 dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
855 break;
857 case TYPE_MEMORY_TAG:
858 case NAME_MEMORY_TAG:
859 case STRUCT_FIELD_TAG:
860 case VAR_DECL:
861 case PARM_DECL:
862 case FIELD_DECL:
863 case NAMESPACE_DECL:
864 dump_decl_name (buffer, node, flags);
865 break;
867 case RESULT_DECL:
868 pp_string (buffer, "<retval>");
869 break;
871 case COMPONENT_REF:
872 op0 = TREE_OPERAND (node, 0);
873 str = ".";
874 if (TREE_CODE (op0) == INDIRECT_REF)
876 op0 = TREE_OPERAND (op0, 0);
877 str = "->";
879 if (op_prio (op0) < op_prio (node))
880 pp_character (buffer, '(');
881 dump_generic_node (buffer, op0, spc, flags, false);
882 if (op_prio (op0) < op_prio (node))
883 pp_character (buffer, ')');
884 pp_string (buffer, str);
885 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
887 if (TREE_CODE (op0) != VALUE_HANDLE)
889 op0 = component_ref_field_offset (node);
890 if (op0 && TREE_CODE (op0) != INTEGER_CST)
892 pp_string (buffer, "{off: ");
893 dump_generic_node (buffer, op0, spc, flags, false);
894 pp_character (buffer, '}');
897 break;
899 case BIT_FIELD_REF:
900 pp_string (buffer, "BIT_FIELD_REF <");
901 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
902 pp_string (buffer, ", ");
903 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
904 pp_string (buffer, ", ");
905 dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
906 pp_string (buffer, ">");
907 break;
909 case ARRAY_REF:
910 case ARRAY_RANGE_REF:
911 op0 = TREE_OPERAND (node, 0);
912 if (op_prio (op0) < op_prio (node))
913 pp_character (buffer, '(');
914 dump_generic_node (buffer, op0, spc, flags, false);
915 if (op_prio (op0) < op_prio (node))
916 pp_character (buffer, ')');
917 pp_character (buffer, '[');
918 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
919 if (TREE_CODE (node) == ARRAY_RANGE_REF)
920 pp_string (buffer, " ...");
921 pp_character (buffer, ']');
923 op0 = array_ref_low_bound (node);
924 op1 = array_ref_element_size (node);
926 if (!integer_zerop (op0)
927 || (TYPE_SIZE_UNIT (TREE_TYPE (node))
928 && !operand_equal_p (op1, TYPE_SIZE_UNIT (TREE_TYPE (node)), 0)))
930 pp_string (buffer, "{lb: ");
931 dump_generic_node (buffer, op0, spc, flags, false);
932 pp_string (buffer, " sz: ");
933 dump_generic_node (buffer, op1, spc, flags, false);
934 pp_character (buffer, '}');
936 break;
938 case CONSTRUCTOR:
940 unsigned HOST_WIDE_INT ix;
941 tree field, val;
942 bool is_struct_init = FALSE;
943 pp_character (buffer, '{');
944 if (TREE_CODE (TREE_TYPE (node)) == RECORD_TYPE
945 || TREE_CODE (TREE_TYPE (node)) == UNION_TYPE)
946 is_struct_init = TRUE;
947 FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (node), ix, field, val)
949 if (field && is_struct_init)
951 pp_character (buffer, '.');
952 dump_generic_node (buffer, field, spc, flags, false);
953 pp_string (buffer, "=");
955 if (val && TREE_CODE (val) == ADDR_EXPR)
956 if (TREE_CODE (TREE_OPERAND (val, 0)) == FUNCTION_DECL)
957 val = TREE_OPERAND (val, 0);
958 if (val && TREE_CODE (val) == FUNCTION_DECL)
959 dump_decl_name (buffer, val, flags);
960 else
961 dump_generic_node (buffer, val, spc, flags, false);
962 if (ix != VEC_length (constructor_elt, CONSTRUCTOR_ELTS (node)) - 1)
964 pp_character (buffer, ',');
965 pp_space (buffer);
968 pp_character (buffer, '}');
970 break;
972 case COMPOUND_EXPR:
974 tree *tp;
975 if (flags & TDF_SLIM)
977 pp_string (buffer, "<COMPOUND_EXPR>");
978 break;
981 dump_generic_node (buffer, TREE_OPERAND (node, 0),
982 spc, flags, !(flags & TDF_SLIM));
983 if (flags & TDF_SLIM)
984 newline_and_indent (buffer, spc);
985 else
987 pp_character (buffer, ',');
988 pp_space (buffer);
991 for (tp = &TREE_OPERAND (node, 1);
992 TREE_CODE (*tp) == COMPOUND_EXPR;
993 tp = &TREE_OPERAND (*tp, 1))
995 dump_generic_node (buffer, TREE_OPERAND (*tp, 0),
996 spc, flags, !(flags & TDF_SLIM));
997 if (flags & TDF_SLIM)
998 newline_and_indent (buffer, spc);
999 else
1001 pp_character (buffer, ',');
1002 pp_space (buffer);
1006 dump_generic_node (buffer, *tp, spc, flags, !(flags & TDF_SLIM));
1008 break;
1010 case STATEMENT_LIST:
1012 tree_stmt_iterator si;
1013 bool first = true;
1015 if (flags & TDF_SLIM)
1017 pp_string (buffer, "<STATEMENT_LIST>");
1018 break;
1021 for (si = tsi_start (node); !tsi_end_p (si); tsi_next (&si))
1023 if (!first)
1024 newline_and_indent (buffer, spc);
1025 else
1026 first = false;
1027 dump_generic_node (buffer, tsi_stmt (si), spc, flags, true);
1030 break;
1032 case MODIFY_EXPR:
1033 case INIT_EXPR:
1034 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1035 pp_space (buffer);
1036 pp_character (buffer, '=');
1037 pp_space (buffer);
1038 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1039 break;
1041 case TARGET_EXPR:
1042 pp_string (buffer, "TARGET_EXPR <");
1043 dump_generic_node (buffer, TARGET_EXPR_SLOT (node), spc, flags, false);
1044 pp_character (buffer, ',');
1045 pp_space (buffer);
1046 dump_generic_node (buffer, TARGET_EXPR_INITIAL (node), spc, flags, false);
1047 pp_character (buffer, '>');
1048 break;
1050 case DECL_EXPR:
1051 print_declaration (buffer, DECL_EXPR_DECL (node), spc, flags);
1052 is_stmt = false;
1053 break;
1055 case COND_EXPR:
1056 if (TREE_TYPE (node) == NULL || TREE_TYPE (node) == void_type_node)
1058 pp_string (buffer, "if (");
1059 dump_generic_node (buffer, COND_EXPR_COND (node), spc, flags, false);
1060 pp_character (buffer, ')');
1061 /* The lowered cond_exprs should always be printed in full. */
1062 if (COND_EXPR_THEN (node)
1063 && (IS_EMPTY_STMT (COND_EXPR_THEN (node))
1064 || TREE_CODE (COND_EXPR_THEN (node)) == GOTO_EXPR)
1065 && COND_EXPR_ELSE (node)
1066 && (IS_EMPTY_STMT (COND_EXPR_ELSE (node))
1067 || TREE_CODE (COND_EXPR_ELSE (node)) == GOTO_EXPR))
1069 pp_space (buffer);
1070 dump_generic_node (buffer, COND_EXPR_THEN (node), 0, flags, true);
1071 pp_string (buffer, " else ");
1072 dump_generic_node (buffer, COND_EXPR_ELSE (node), 0, flags, true);
1074 else if (!(flags & TDF_SLIM))
1076 /* Output COND_EXPR_THEN. */
1077 if (COND_EXPR_THEN (node))
1079 newline_and_indent (buffer, spc+2);
1080 pp_character (buffer, '{');
1081 newline_and_indent (buffer, spc+4);
1082 dump_generic_node (buffer, COND_EXPR_THEN (node), spc+4,
1083 flags, true);
1084 newline_and_indent (buffer, spc+2);
1085 pp_character (buffer, '}');
1088 /* Output COND_EXPR_ELSE. */
1089 if (COND_EXPR_ELSE (node))
1091 newline_and_indent (buffer, spc);
1092 pp_string (buffer, "else");
1093 newline_and_indent (buffer, spc+2);
1094 pp_character (buffer, '{');
1095 newline_and_indent (buffer, spc+4);
1096 dump_generic_node (buffer, COND_EXPR_ELSE (node), spc+4,
1097 flags, true);
1098 newline_and_indent (buffer, spc+2);
1099 pp_character (buffer, '}');
1102 is_expr = false;
1104 else
1106 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1107 pp_space (buffer);
1108 pp_character (buffer, '?');
1109 pp_space (buffer);
1110 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1111 pp_space (buffer);
1112 pp_character (buffer, ':');
1113 pp_space (buffer);
1114 dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
1116 break;
1118 case BIND_EXPR:
1119 pp_character (buffer, '{');
1120 if (!(flags & TDF_SLIM))
1122 if (BIND_EXPR_VARS (node))
1124 pp_newline (buffer);
1126 for (op0 = BIND_EXPR_VARS (node); op0; op0 = TREE_CHAIN (op0))
1128 print_declaration (buffer, op0, spc+2, flags);
1129 pp_newline (buffer);
1133 newline_and_indent (buffer, spc+2);
1134 dump_generic_node (buffer, BIND_EXPR_BODY (node), spc+2, flags, true);
1135 newline_and_indent (buffer, spc);
1136 pp_character (buffer, '}');
1138 is_expr = false;
1139 break;
1141 case CALL_EXPR:
1142 print_call_name (buffer, node);
1144 /* Print parameters. */
1145 pp_space (buffer);
1146 pp_character (buffer, '(');
1147 op1 = TREE_OPERAND (node, 1);
1148 if (op1)
1149 dump_generic_node (buffer, op1, spc, flags, false);
1150 pp_character (buffer, ')');
1152 op1 = TREE_OPERAND (node, 2);
1153 if (op1)
1155 pp_string (buffer, " [static-chain: ");
1156 dump_generic_node (buffer, op1, spc, flags, false);
1157 pp_character (buffer, ']');
1160 if (CALL_EXPR_RETURN_SLOT_OPT (node))
1161 pp_string (buffer, " [return slot optimization]");
1162 if (CALL_EXPR_TAILCALL (node))
1163 pp_string (buffer, " [tail call]");
1164 break;
1166 case WITH_CLEANUP_EXPR:
1167 NIY;
1168 break;
1170 case CLEANUP_POINT_EXPR:
1171 pp_string (buffer, "<<cleanup_point ");
1172 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1173 pp_string (buffer, ">>");
1174 break;
1176 case PLACEHOLDER_EXPR:
1177 pp_string (buffer, "<PLACEHOLDER_EXPR ");
1178 dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
1179 pp_character (buffer, '>');
1180 break;
1182 /* Binary arithmetic and logic expressions. */
1183 case WIDEN_SUM_EXPR:
1184 case WIDEN_MULT_EXPR:
1185 case MULT_EXPR:
1186 case PLUS_EXPR:
1187 case MINUS_EXPR:
1188 case TRUNC_DIV_EXPR:
1189 case CEIL_DIV_EXPR:
1190 case FLOOR_DIV_EXPR:
1191 case ROUND_DIV_EXPR:
1192 case TRUNC_MOD_EXPR:
1193 case CEIL_MOD_EXPR:
1194 case FLOOR_MOD_EXPR:
1195 case ROUND_MOD_EXPR:
1196 case RDIV_EXPR:
1197 case EXACT_DIV_EXPR:
1198 case LSHIFT_EXPR:
1199 case RSHIFT_EXPR:
1200 case LROTATE_EXPR:
1201 case RROTATE_EXPR:
1202 case VEC_LSHIFT_EXPR:
1203 case VEC_RSHIFT_EXPR:
1204 case BIT_IOR_EXPR:
1205 case BIT_XOR_EXPR:
1206 case BIT_AND_EXPR:
1207 case TRUTH_ANDIF_EXPR:
1208 case TRUTH_ORIF_EXPR:
1209 case TRUTH_AND_EXPR:
1210 case TRUTH_OR_EXPR:
1211 case TRUTH_XOR_EXPR:
1212 case LT_EXPR:
1213 case LE_EXPR:
1214 case GT_EXPR:
1215 case GE_EXPR:
1216 case EQ_EXPR:
1217 case NE_EXPR:
1218 case UNLT_EXPR:
1219 case UNLE_EXPR:
1220 case UNGT_EXPR:
1221 case UNGE_EXPR:
1222 case UNEQ_EXPR:
1223 case LTGT_EXPR:
1224 case ORDERED_EXPR:
1225 case UNORDERED_EXPR:
1227 const char *op = op_symbol (node);
1228 op0 = TREE_OPERAND (node, 0);
1229 op1 = TREE_OPERAND (node, 1);
1231 /* When the operands are expressions with less priority,
1232 keep semantics of the tree representation. */
1233 if (op_prio (op0) < op_prio (node))
1235 pp_character (buffer, '(');
1236 dump_generic_node (buffer, op0, spc, flags, false);
1237 pp_character (buffer, ')');
1239 else
1240 dump_generic_node (buffer, op0, spc, flags, false);
1242 pp_space (buffer);
1243 pp_string (buffer, op);
1244 pp_space (buffer);
1246 /* When the operands are expressions with less priority,
1247 keep semantics of the tree representation. */
1248 if (op_prio (op1) < op_prio (node))
1250 pp_character (buffer, '(');
1251 dump_generic_node (buffer, op1, spc, flags, false);
1252 pp_character (buffer, ')');
1254 else
1255 dump_generic_node (buffer, op1, spc, flags, false);
1257 break;
1259 /* Unary arithmetic and logic expressions. */
1260 case NEGATE_EXPR:
1261 case BIT_NOT_EXPR:
1262 case TRUTH_NOT_EXPR:
1263 case ADDR_EXPR:
1264 case PREDECREMENT_EXPR:
1265 case PREINCREMENT_EXPR:
1266 case ALIGN_INDIRECT_REF:
1267 case MISALIGNED_INDIRECT_REF:
1268 case INDIRECT_REF:
1269 if (TREE_CODE (node) == ADDR_EXPR
1270 && (TREE_CODE (TREE_OPERAND (node, 0)) == STRING_CST
1271 || TREE_CODE (TREE_OPERAND (node, 0)) == FUNCTION_DECL))
1272 ; /* Do not output '&' for strings and function pointers. */
1273 else
1274 pp_string (buffer, op_symbol (node));
1276 if (op_prio (TREE_OPERAND (node, 0)) < op_prio (node))
1278 pp_character (buffer, '(');
1279 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1280 pp_character (buffer, ')');
1282 else
1283 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1285 if (TREE_CODE (node) == MISALIGNED_INDIRECT_REF)
1287 pp_string (buffer, "{misalignment: ");
1288 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1289 pp_character (buffer, '}');
1291 break;
1293 case POSTDECREMENT_EXPR:
1294 case POSTINCREMENT_EXPR:
1295 if (op_prio (TREE_OPERAND (node, 0)) < op_prio (node))
1297 pp_character (buffer, '(');
1298 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1299 pp_character (buffer, ')');
1301 else
1302 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1303 pp_string (buffer, op_symbol (node));
1304 break;
1306 case MIN_EXPR:
1307 pp_string (buffer, "MIN_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 MAX_EXPR:
1315 pp_string (buffer, "MAX_EXPR <");
1316 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1317 pp_string (buffer, ", ");
1318 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1319 pp_character (buffer, '>');
1320 break;
1322 case ABS_EXPR:
1323 pp_string (buffer, "ABS_EXPR <");
1324 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1325 pp_character (buffer, '>');
1326 break;
1328 case RANGE_EXPR:
1329 NIY;
1330 break;
1332 case FIX_TRUNC_EXPR:
1333 case FIX_CEIL_EXPR:
1334 case FIX_FLOOR_EXPR:
1335 case FIX_ROUND_EXPR:
1336 case FLOAT_EXPR:
1337 case CONVERT_EXPR:
1338 case NOP_EXPR:
1339 type = TREE_TYPE (node);
1340 op0 = TREE_OPERAND (node, 0);
1341 if (type != TREE_TYPE (op0))
1343 pp_character (buffer, '(');
1344 dump_generic_node (buffer, type, spc, flags, false);
1345 pp_string (buffer, ") ");
1347 if (op_prio (op0) < op_prio (node))
1348 pp_character (buffer, '(');
1349 dump_generic_node (buffer, op0, spc, flags, false);
1350 if (op_prio (op0) < op_prio (node))
1351 pp_character (buffer, ')');
1352 break;
1354 case VIEW_CONVERT_EXPR:
1355 pp_string (buffer, "VIEW_CONVERT_EXPR<");
1356 dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
1357 pp_string (buffer, ">(");
1358 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1359 pp_character (buffer, ')');
1360 break;
1362 case NON_LVALUE_EXPR:
1363 pp_string (buffer, "NON_LVALUE_EXPR <");
1364 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1365 pp_character (buffer, '>');
1366 break;
1368 case SAVE_EXPR:
1369 pp_string (buffer, "SAVE_EXPR <");
1370 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1371 pp_character (buffer, '>');
1372 break;
1374 case COMPLEX_EXPR:
1375 pp_string (buffer, "COMPLEX_EXPR <");
1376 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1377 pp_string (buffer, ", ");
1378 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1379 pp_string (buffer, ">");
1380 break;
1382 case CONJ_EXPR:
1383 pp_string (buffer, "CONJ_EXPR <");
1384 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1385 pp_string (buffer, ">");
1386 break;
1388 case REALPART_EXPR:
1389 pp_string (buffer, "REALPART_EXPR <");
1390 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1391 pp_string (buffer, ">");
1392 break;
1394 case IMAGPART_EXPR:
1395 pp_string (buffer, "IMAGPART_EXPR <");
1396 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1397 pp_string (buffer, ">");
1398 break;
1400 case VA_ARG_EXPR:
1401 pp_string (buffer, "VA_ARG_EXPR <");
1402 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1403 pp_string (buffer, ">");
1404 break;
1406 case TRY_FINALLY_EXPR:
1407 case TRY_CATCH_EXPR:
1408 pp_string (buffer, "try");
1409 newline_and_indent (buffer, spc+2);
1410 pp_string (buffer, "{");
1411 newline_and_indent (buffer, spc+4);
1412 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc+4, flags, true);
1413 newline_and_indent (buffer, spc+2);
1414 pp_string (buffer, "}");
1415 newline_and_indent (buffer, spc);
1416 pp_string (buffer,
1417 (TREE_CODE (node) == TRY_CATCH_EXPR) ? "catch" : "finally");
1418 newline_and_indent (buffer, spc+2);
1419 pp_string (buffer, "{");
1420 newline_and_indent (buffer, spc+4);
1421 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc+4, flags, true);
1422 newline_and_indent (buffer, spc+2);
1423 pp_string (buffer, "}");
1424 is_expr = false;
1425 break;
1427 case CATCH_EXPR:
1428 pp_string (buffer, "catch (");
1429 dump_generic_node (buffer, CATCH_TYPES (node), spc+2, flags, false);
1430 pp_string (buffer, ")");
1431 newline_and_indent (buffer, spc+2);
1432 pp_string (buffer, "{");
1433 newline_and_indent (buffer, spc+4);
1434 dump_generic_node (buffer, CATCH_BODY (node), spc+4, flags, true);
1435 newline_and_indent (buffer, spc+2);
1436 pp_string (buffer, "}");
1437 is_expr = false;
1438 break;
1440 case EH_FILTER_EXPR:
1441 pp_string (buffer, "<<<eh_filter (");
1442 dump_generic_node (buffer, EH_FILTER_TYPES (node), spc+2, flags, false);
1443 pp_string (buffer, ")>>>");
1444 newline_and_indent (buffer, spc+2);
1445 pp_string (buffer, "{");
1446 newline_and_indent (buffer, spc+4);
1447 dump_generic_node (buffer, EH_FILTER_FAILURE (node), spc+4, flags, true);
1448 newline_and_indent (buffer, spc+2);
1449 pp_string (buffer, "}");
1450 is_expr = false;
1451 break;
1453 case LABEL_EXPR:
1454 op0 = TREE_OPERAND (node, 0);
1455 /* If this is for break or continue, don't bother printing it. */
1456 if (DECL_NAME (op0))
1458 const char *name = IDENTIFIER_POINTER (DECL_NAME (op0));
1459 if (strcmp (name, "break") == 0
1460 || strcmp (name, "continue") == 0)
1461 break;
1463 dump_generic_node (buffer, op0, spc, flags, false);
1464 pp_character (buffer, ':');
1465 if (DECL_NONLOCAL (op0))
1466 pp_string (buffer, " [non-local]");
1467 break;
1469 case EXC_PTR_EXPR:
1470 pp_string (buffer, "<<<exception object>>>");
1471 break;
1473 case FILTER_EXPR:
1474 pp_string (buffer, "<<<filter object>>>");
1475 break;
1477 case LOOP_EXPR:
1478 pp_string (buffer, "while (1)");
1479 if (!(flags & TDF_SLIM))
1481 newline_and_indent (buffer, spc+2);
1482 pp_character (buffer, '{');
1483 newline_and_indent (buffer, spc+4);
1484 dump_generic_node (buffer, LOOP_EXPR_BODY (node), spc+4, flags, true);
1485 newline_and_indent (buffer, spc+2);
1486 pp_character (buffer, '}');
1488 is_expr = false;
1489 break;
1491 case RETURN_EXPR:
1492 pp_string (buffer, "return");
1493 op0 = TREE_OPERAND (node, 0);
1494 if (op0)
1496 pp_space (buffer);
1497 if (TREE_CODE (op0) == MODIFY_EXPR)
1498 dump_generic_node (buffer, TREE_OPERAND (op0, 1), spc, flags, false);
1499 else
1500 dump_generic_node (buffer, op0, spc, flags, false);
1502 break;
1504 case EXIT_EXPR:
1505 pp_string (buffer, "if (");
1506 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1507 pp_string (buffer, ") break");
1508 break;
1510 case SWITCH_EXPR:
1511 pp_string (buffer, "switch (");
1512 dump_generic_node (buffer, SWITCH_COND (node), spc, flags, false);
1513 pp_character (buffer, ')');
1514 if (!(flags & TDF_SLIM))
1516 newline_and_indent (buffer, spc+2);
1517 pp_character (buffer, '{');
1518 if (SWITCH_BODY (node))
1520 newline_and_indent (buffer, spc+4);
1521 dump_generic_node (buffer, SWITCH_BODY (node), spc+4, flags,
1522 true);
1524 else
1526 tree vec = SWITCH_LABELS (node);
1527 size_t i, n = TREE_VEC_LENGTH (vec);
1528 for (i = 0; i < n; ++i)
1530 tree elt = TREE_VEC_ELT (vec, i);
1531 newline_and_indent (buffer, spc+4);
1532 if (elt)
1534 dump_generic_node (buffer, elt, spc+4, flags, false);
1535 pp_string (buffer, " goto ");
1536 dump_generic_node (buffer, CASE_LABEL (elt), spc+4,
1537 flags, true);
1538 pp_semicolon (buffer);
1540 else
1541 pp_string (buffer, "case ???: goto ???;");
1544 newline_and_indent (buffer, spc+2);
1545 pp_character (buffer, '}');
1547 is_expr = false;
1548 break;
1550 case GOTO_EXPR:
1551 op0 = GOTO_DESTINATION (node);
1552 if (TREE_CODE (op0) != SSA_NAME && DECL_P (op0) && DECL_NAME (op0))
1554 const char *name = IDENTIFIER_POINTER (DECL_NAME (op0));
1555 if (strcmp (name, "break") == 0
1556 || strcmp (name, "continue") == 0)
1558 pp_string (buffer, name);
1559 break;
1562 pp_string (buffer, "goto ");
1563 dump_generic_node (buffer, op0, spc, flags, false);
1564 break;
1566 case RESX_EXPR:
1567 pp_string (buffer, "resx");
1568 /* ??? Any sensible way to present the eh region? */
1569 break;
1571 case ASM_EXPR:
1572 pp_string (buffer, "__asm__");
1573 if (ASM_VOLATILE_P (node))
1574 pp_string (buffer, " __volatile__");
1575 pp_character (buffer, '(');
1576 dump_generic_node (buffer, ASM_STRING (node), spc, flags, false);
1577 pp_character (buffer, ':');
1578 dump_generic_node (buffer, ASM_OUTPUTS (node), spc, flags, false);
1579 pp_character (buffer, ':');
1580 dump_generic_node (buffer, ASM_INPUTS (node), spc, flags, false);
1581 if (ASM_CLOBBERS (node))
1583 pp_character (buffer, ':');
1584 dump_generic_node (buffer, ASM_CLOBBERS (node), spc, flags, false);
1586 pp_string (buffer, ")");
1587 break;
1589 case CASE_LABEL_EXPR:
1590 if (CASE_LOW (node) && CASE_HIGH (node))
1592 pp_string (buffer, "case ");
1593 dump_generic_node (buffer, CASE_LOW (node), spc, flags, false);
1594 pp_string (buffer, " ... ");
1595 dump_generic_node (buffer, CASE_HIGH (node), spc, flags, false);
1597 else if (CASE_LOW (node))
1599 pp_string (buffer, "case ");
1600 dump_generic_node (buffer, CASE_LOW (node), spc, flags, false);
1602 else
1603 pp_string (buffer, "default ");
1604 pp_character (buffer, ':');
1605 break;
1607 case OBJ_TYPE_REF:
1608 pp_string (buffer, "OBJ_TYPE_REF(");
1609 dump_generic_node (buffer, OBJ_TYPE_REF_EXPR (node), spc, flags, false);
1610 pp_character (buffer, ';');
1611 dump_generic_node (buffer, OBJ_TYPE_REF_OBJECT (node), spc, flags, false);
1612 pp_character (buffer, '-');
1613 pp_character (buffer, '>');
1614 dump_generic_node (buffer, OBJ_TYPE_REF_TOKEN (node), spc, flags, false);
1615 pp_character (buffer, ')');
1616 break;
1618 case PHI_NODE:
1620 int i;
1622 dump_generic_node (buffer, PHI_RESULT (node), spc, flags, false);
1623 pp_string (buffer, " = PHI <");
1624 for (i = 0; i < PHI_NUM_ARGS (node); i++)
1626 dump_generic_node (buffer, PHI_ARG_DEF (node, i), spc, flags, false);
1627 pp_string (buffer, "(");
1628 pp_decimal_int (buffer, PHI_ARG_EDGE (node, i)->src->index);
1629 pp_string (buffer, ")");
1630 if (i < PHI_NUM_ARGS (node) - 1)
1631 pp_string (buffer, ", ");
1633 pp_string (buffer, ">;");
1635 break;
1637 case SSA_NAME:
1638 dump_generic_node (buffer, SSA_NAME_VAR (node), spc, flags, false);
1639 pp_string (buffer, "_");
1640 pp_decimal_int (buffer, SSA_NAME_VERSION (node));
1641 if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (node))
1642 pp_string (buffer, "(ab)");
1643 break;
1645 case WITH_SIZE_EXPR:
1646 pp_string (buffer, "WITH_SIZE_EXPR <");
1647 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1648 pp_string (buffer, ", ");
1649 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1650 pp_string (buffer, ">");
1651 break;
1653 case VALUE_HANDLE:
1654 pp_printf (buffer, "VH.%d", VALUE_HANDLE_ID (node));
1655 break;
1657 case ASSERT_EXPR:
1658 pp_string (buffer, "ASSERT_EXPR <");
1659 dump_generic_node (buffer, ASSERT_EXPR_VAR (node), spc, flags, false);
1660 pp_string (buffer, ", ");
1661 dump_generic_node (buffer, ASSERT_EXPR_COND (node), spc, flags, false);
1662 pp_string (buffer, ">");
1663 break;
1665 case SCEV_KNOWN:
1666 pp_string (buffer, "scev_known");
1667 break;
1669 case SCEV_NOT_KNOWN:
1670 pp_string (buffer, "scev_not_known");
1671 break;
1673 case POLYNOMIAL_CHREC:
1674 pp_string (buffer, "{");
1675 dump_generic_node (buffer, CHREC_LEFT (node), spc, flags, false);
1676 pp_string (buffer, ", +, ");
1677 dump_generic_node (buffer, CHREC_RIGHT (node), spc, flags, false);
1678 pp_string (buffer, "}_");
1679 dump_generic_node (buffer, CHREC_VAR (node), spc, flags, false);
1680 is_stmt = false;
1681 break;
1683 case REALIGN_LOAD_EXPR:
1684 pp_string (buffer, "REALIGN_LOAD <");
1685 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1686 pp_string (buffer, ", ");
1687 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1688 pp_string (buffer, ", ");
1689 dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
1690 pp_string (buffer, ">");
1691 break;
1693 case VEC_COND_EXPR:
1694 pp_string (buffer, " VEC_COND_EXPR < ");
1695 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1696 pp_string (buffer, " , ");
1697 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1698 pp_string (buffer, " , ");
1699 dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
1700 pp_string (buffer, " > ");
1701 break;
1703 case DOT_PROD_EXPR:
1704 pp_string (buffer, " DOT_PROD_EXPR < ");
1705 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1706 pp_string (buffer, " , ");
1707 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1708 pp_string (buffer, " , ");
1709 dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
1710 pp_string (buffer, " > ");
1711 break;
1713 case OMP_PARALLEL:
1714 pp_string (buffer, "#pragma omp parallel");
1715 dump_omp_clauses (buffer, OMP_PARALLEL_CLAUSES (node), spc, flags);
1716 if (OMP_PARALLEL_FN (node))
1718 pp_string (buffer, " [child fn: ");
1719 dump_generic_node (buffer, OMP_PARALLEL_FN (node), spc, flags, false);
1721 pp_string (buffer, " (");
1723 if (OMP_PARALLEL_DATA_ARG (node))
1724 dump_generic_node (buffer, OMP_PARALLEL_DATA_ARG (node), spc, flags,
1725 false);
1726 else
1727 pp_string (buffer, "???");
1729 pp_string (buffer, ")]");
1732 dump_omp_body:
1733 if (!(flags & TDF_SLIM) && OMP_BODY (node))
1735 newline_and_indent (buffer, spc + 2);
1736 pp_character (buffer, '{');
1737 newline_and_indent (buffer, spc + 4);
1738 dump_generic_node (buffer, OMP_BODY (node), spc + 4, flags, false);
1739 newline_and_indent (buffer, spc + 2);
1740 pp_character (buffer, '}');
1742 is_expr = false;
1743 break;
1745 case OMP_FOR:
1746 pp_string (buffer, "#pragma omp for");
1747 dump_omp_clauses (buffer, OMP_FOR_CLAUSES (node), spc, flags);
1749 if (!(flags & TDF_SLIM))
1751 if (OMP_FOR_PRE_BODY (node))
1753 newline_and_indent (buffer, spc + 2);
1754 pp_character (buffer, '{');
1755 spc += 4;
1756 newline_and_indent (buffer, spc);
1757 dump_generic_node (buffer, OMP_FOR_PRE_BODY (node),
1758 spc, flags, false);
1760 newline_and_indent (buffer, spc);
1761 pp_string (buffer, "for (");
1762 dump_generic_node (buffer, OMP_FOR_INIT (node), spc, flags, false);
1763 pp_string (buffer, "; ");
1764 dump_generic_node (buffer, OMP_FOR_COND (node), spc, flags, false);
1765 pp_string (buffer, "; ");
1766 dump_generic_node (buffer, OMP_FOR_INCR (node), spc, flags, false);
1767 pp_string (buffer, ")");
1768 if (OMP_FOR_BODY (node))
1770 newline_and_indent (buffer, spc + 2);
1771 pp_character (buffer, '{');
1772 newline_and_indent (buffer, spc + 4);
1773 dump_generic_node (buffer, OMP_FOR_BODY (node), spc + 4, flags,
1774 false);
1775 newline_and_indent (buffer, spc + 2);
1776 pp_character (buffer, '}');
1778 if (OMP_FOR_PRE_BODY (node))
1780 spc -= 4;
1781 newline_and_indent (buffer, spc + 2);
1782 pp_character (buffer, '}');
1785 is_expr = false;
1786 break;
1788 case OMP_SECTIONS:
1789 pp_string (buffer, "#pragma omp sections");
1790 dump_omp_clauses (buffer, OMP_SECTIONS_CLAUSES (node), spc, flags);
1791 goto dump_omp_body;
1793 case OMP_SECTION:
1794 pp_string (buffer, "#pragma omp section");
1795 goto dump_omp_body;
1797 case OMP_MASTER:
1798 pp_string (buffer, "#pragma omp master");
1799 goto dump_omp_body;
1801 case OMP_ORDERED:
1802 pp_string (buffer, "#pragma omp ordered");
1803 goto dump_omp_body;
1805 case OMP_CRITICAL:
1806 pp_string (buffer, "#pragma omp critical");
1807 if (OMP_CRITICAL_NAME (node))
1809 pp_space (buffer);
1810 pp_character (buffer, '(');
1811 dump_generic_node (buffer, OMP_CRITICAL_NAME (node), spc,
1812 flags, false);
1813 pp_character (buffer, ')');
1815 goto dump_omp_body;
1817 case OMP_ATOMIC:
1818 pp_string (buffer, "#pragma omp atomic");
1819 newline_and_indent (buffer, spc + 2);
1820 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1821 pp_space (buffer);
1822 pp_character (buffer, '=');
1823 pp_space (buffer);
1824 dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1825 break;
1827 case OMP_SINGLE:
1828 pp_string (buffer, "#pragma omp single");
1829 dump_omp_clauses (buffer, OMP_SINGLE_CLAUSES (node), spc, flags);
1830 goto dump_omp_body;
1832 case OMP_RETURN_EXPR:
1833 pp_string (buffer, "OMP_RETURN");
1834 is_expr = false;
1835 break;
1837 case OMP_CLAUSE:
1838 dump_omp_clause (buffer, node, spc, flags);
1839 is_expr = false;
1840 break;
1842 case REDUC_MAX_EXPR:
1843 pp_string (buffer, " REDUC_MAX_EXPR < ");
1844 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1845 pp_string (buffer, " > ");
1846 break;
1848 case REDUC_MIN_EXPR:
1849 pp_string (buffer, " REDUC_MIN_EXPR < ");
1850 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1851 pp_string (buffer, " > ");
1852 break;
1854 case REDUC_PLUS_EXPR:
1855 pp_string (buffer, " REDUC_PLUS_EXPR < ");
1856 dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1857 pp_string (buffer, " > ");
1858 break;
1860 case BLOCK:
1862 tree t;
1863 pp_string (buffer, "BLOCK");
1865 if (BLOCK_ABSTRACT (node))
1866 pp_string (buffer, " [abstract]");
1868 if (TREE_ASM_WRITTEN (node))
1869 pp_string (buffer, " [written]");
1871 newline_and_indent (buffer, spc + 2);
1873 if (BLOCK_SUPERCONTEXT (node))
1875 pp_string (buffer, "SUPERCONTEXT: ");
1876 if (TREE_CODE (BLOCK_SUPERCONTEXT (node)) == BLOCK)
1877 pp_printf (buffer, "BLOCK %p",
1878 (void *)BLOCK_SUPERCONTEXT (node));
1879 else
1880 dump_generic_node (buffer, BLOCK_SUPERCONTEXT (node), 0, flags,
1881 false);
1882 newline_and_indent (buffer, spc + 2);
1885 if (BLOCK_SUBBLOCKS (node))
1887 pp_string (buffer, "SUBBLOCKS: ");
1888 for (t = BLOCK_SUBBLOCKS (node); t; t = BLOCK_CHAIN (t))
1889 pp_printf (buffer, "%p ", (void *)t);
1890 newline_and_indent (buffer, spc + 2);
1893 if (BLOCK_VARS (node))
1895 pp_string (buffer, "VARS: ");
1896 for (t = BLOCK_VARS (node); t; t = TREE_CHAIN (t))
1898 dump_generic_node (buffer, t, 0, flags, false);
1899 pp_string (buffer, " ");
1901 newline_and_indent (buffer, spc + 2);
1904 if (BLOCK_ABSTRACT_ORIGIN (node))
1906 pp_string (buffer, "ABSTRACT_ORIGIN: ");
1907 if (TREE_CODE (BLOCK_ABSTRACT_ORIGIN (node)) == BLOCK)
1908 pp_printf (buffer, "BLOCK %p",
1909 (void *)BLOCK_ABSTRACT_ORIGIN (node));
1910 else
1911 dump_generic_node (buffer, BLOCK_ABSTRACT_ORIGIN (node), 0, flags,
1912 false);
1913 newline_and_indent (buffer, spc + 2);
1916 break;
1918 default:
1919 NIY;
1922 if (is_stmt && is_expr)
1923 pp_semicolon (buffer);
1924 pp_write_text_to_stream (buffer);
1926 return spc;
1929 /* Print the declaration of a variable. */
1931 static void
1932 print_declaration (pretty_printer *buffer, tree t, int spc, int flags)
1934 INDENT (spc);
1936 if (TREE_CODE (t) == TYPE_DECL)
1937 pp_string (buffer, "typedef ");
1939 if (CODE_CONTAINS_STRUCT (TREE_CODE (t), TS_DECL_WRTL) && DECL_REGISTER (t))
1940 pp_string (buffer, "register ");
1942 if (TREE_PUBLIC (t) && DECL_EXTERNAL (t))
1943 pp_string (buffer, "extern ");
1944 else if (TREE_STATIC (t))
1945 pp_string (buffer, "static ");
1947 /* Print the type and name. */
1948 if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
1950 tree tmp;
1952 /* Print array's type. */
1953 tmp = TREE_TYPE (t);
1954 while (TREE_CODE (TREE_TYPE (tmp)) == ARRAY_TYPE)
1955 tmp = TREE_TYPE (tmp);
1956 dump_generic_node (buffer, TREE_TYPE (tmp), spc, flags, false);
1958 /* Print variable's name. */
1959 pp_space (buffer);
1960 dump_generic_node (buffer, t, spc, flags, false);
1962 /* Print the dimensions. */
1963 tmp = TREE_TYPE (t);
1964 while (TREE_CODE (tmp) == ARRAY_TYPE)
1966 dump_array_domain (buffer, TYPE_DOMAIN (tmp), spc, flags);
1967 tmp = TREE_TYPE (tmp);
1970 else if (TREE_CODE (t) == FUNCTION_DECL)
1972 dump_generic_node (buffer, TREE_TYPE (TREE_TYPE (t)), spc, flags, false);
1973 pp_space (buffer);
1974 dump_decl_name (buffer, t, flags);
1975 dump_function_declaration (buffer, TREE_TYPE (t), spc, flags);
1977 else
1979 /* Print type declaration. */
1980 dump_generic_node (buffer, TREE_TYPE (t), spc, flags, false);
1982 /* Print variable's name. */
1983 pp_space (buffer);
1984 dump_generic_node (buffer, t, spc, flags, false);
1987 if (TREE_CODE (t) == VAR_DECL && DECL_HARD_REGISTER (t))
1989 pp_string (buffer, " __asm__ ");
1990 pp_character (buffer, '(');
1991 dump_generic_node (buffer, DECL_ASSEMBLER_NAME (t), spc, flags, false);
1992 pp_character (buffer, ')');
1995 /* The initial value of a function serves to determine wether the function
1996 is declared or defined. So the following does not apply to function
1997 nodes. */
1998 if (TREE_CODE (t) != FUNCTION_DECL)
2000 /* Print the initial value. */
2001 if (DECL_INITIAL (t))
2003 pp_space (buffer);
2004 pp_character (buffer, '=');
2005 pp_space (buffer);
2006 dump_generic_node (buffer, DECL_INITIAL (t), spc, flags, false);
2010 if (TREE_CODE (t) == VAR_DECL && DECL_HAS_VALUE_EXPR_P (t))
2012 pp_string (buffer, " [value-expr: ");
2013 dump_generic_node (buffer, DECL_VALUE_EXPR (t), spc, flags, false);
2014 pp_character (buffer, ']');
2017 pp_character (buffer, ';');
2021 /* Prints a structure: name, fields, and methods.
2022 FIXME: Still incomplete. */
2024 static void
2025 print_struct_decl (pretty_printer *buffer, tree node, int spc, int flags)
2027 /* Print the name of the structure. */
2028 if (TYPE_NAME (node))
2030 INDENT (spc);
2031 if (TREE_CODE (node) == RECORD_TYPE)
2032 pp_string (buffer, "struct ");
2033 else if ((TREE_CODE (node) == UNION_TYPE
2034 || TREE_CODE (node) == QUAL_UNION_TYPE))
2035 pp_string (buffer, "union ");
2037 dump_generic_node (buffer, TYPE_NAME (node), spc, 0, false);
2040 /* Print the contents of the structure. */
2041 pp_newline (buffer);
2042 INDENT (spc);
2043 pp_character (buffer, '{');
2044 pp_newline (buffer);
2046 /* Print the fields of the structure. */
2048 tree tmp;
2049 tmp = TYPE_FIELDS (node);
2050 while (tmp)
2052 /* Avoid to print recursively the structure. */
2053 /* FIXME : Not implemented correctly...,
2054 what about the case when we have a cycle in the contain graph? ...
2055 Maybe this could be solved by looking at the scope in which the
2056 structure was declared. */
2057 if (TREE_TYPE (tmp) != node
2058 || (TREE_CODE (TREE_TYPE (tmp)) == POINTER_TYPE
2059 && TREE_TYPE (TREE_TYPE (tmp)) != node))
2061 print_declaration (buffer, tmp, spc+2, flags);
2062 pp_newline (buffer);
2064 tmp = TREE_CHAIN (tmp);
2067 INDENT (spc);
2068 pp_character (buffer, '}');
2071 /* Return the priority of the operator OP.
2073 From lowest to highest precedence with either left-to-right (L-R)
2074 or right-to-left (R-L) associativity]:
2076 1 [L-R] ,
2077 2 [R-L] = += -= *= /= %= &= ^= |= <<= >>=
2078 3 [R-L] ?:
2079 4 [L-R] ||
2080 5 [L-R] &&
2081 6 [L-R] |
2082 7 [L-R] ^
2083 8 [L-R] &
2084 9 [L-R] == !=
2085 10 [L-R] < <= > >=
2086 11 [L-R] << >>
2087 12 [L-R] + -
2088 13 [L-R] * / %
2089 14 [R-L] ! ~ ++ -- + - * & (type) sizeof
2090 15 [L-R] fn() [] -> .
2092 unary +, - and * have higher precedence than the corresponding binary
2093 operators. */
2095 static int
2096 op_prio (tree op)
2098 if (op == NULL)
2099 return 9999;
2101 switch (TREE_CODE (op))
2103 case TREE_LIST:
2104 case COMPOUND_EXPR:
2105 case BIND_EXPR:
2106 return 1;
2108 case MODIFY_EXPR:
2109 case INIT_EXPR:
2110 return 2;
2112 case COND_EXPR:
2113 return 3;
2115 case TRUTH_OR_EXPR:
2116 case TRUTH_ORIF_EXPR:
2117 return 4;
2119 case TRUTH_AND_EXPR:
2120 case TRUTH_ANDIF_EXPR:
2121 return 5;
2123 case BIT_IOR_EXPR:
2124 return 6;
2126 case BIT_XOR_EXPR:
2127 case TRUTH_XOR_EXPR:
2128 return 7;
2130 case BIT_AND_EXPR:
2131 return 8;
2133 case EQ_EXPR:
2134 case NE_EXPR:
2135 return 9;
2137 case UNLT_EXPR:
2138 case UNLE_EXPR:
2139 case UNGT_EXPR:
2140 case UNGE_EXPR:
2141 case UNEQ_EXPR:
2142 case LTGT_EXPR:
2143 case ORDERED_EXPR:
2144 case UNORDERED_EXPR:
2145 case LT_EXPR:
2146 case LE_EXPR:
2147 case GT_EXPR:
2148 case GE_EXPR:
2149 return 10;
2151 case LSHIFT_EXPR:
2152 case RSHIFT_EXPR:
2153 case LROTATE_EXPR:
2154 case RROTATE_EXPR:
2155 return 11;
2157 case WIDEN_SUM_EXPR:
2158 case PLUS_EXPR:
2159 case MINUS_EXPR:
2160 return 12;
2162 case WIDEN_MULT_EXPR:
2163 case DOT_PROD_EXPR:
2164 case MULT_EXPR:
2165 case TRUNC_DIV_EXPR:
2166 case CEIL_DIV_EXPR:
2167 case FLOOR_DIV_EXPR:
2168 case ROUND_DIV_EXPR:
2169 case RDIV_EXPR:
2170 case EXACT_DIV_EXPR:
2171 case TRUNC_MOD_EXPR:
2172 case CEIL_MOD_EXPR:
2173 case FLOOR_MOD_EXPR:
2174 case ROUND_MOD_EXPR:
2175 return 13;
2177 case TRUTH_NOT_EXPR:
2178 case BIT_NOT_EXPR:
2179 case POSTINCREMENT_EXPR:
2180 case POSTDECREMENT_EXPR:
2181 case PREINCREMENT_EXPR:
2182 case PREDECREMENT_EXPR:
2183 case NEGATE_EXPR:
2184 case ALIGN_INDIRECT_REF:
2185 case MISALIGNED_INDIRECT_REF:
2186 case INDIRECT_REF:
2187 case ADDR_EXPR:
2188 case FLOAT_EXPR:
2189 case NOP_EXPR:
2190 case CONVERT_EXPR:
2191 case FIX_TRUNC_EXPR:
2192 case FIX_CEIL_EXPR:
2193 case FIX_FLOOR_EXPR:
2194 case FIX_ROUND_EXPR:
2195 case TARGET_EXPR:
2196 return 14;
2198 case CALL_EXPR:
2199 case ARRAY_REF:
2200 case ARRAY_RANGE_REF:
2201 case COMPONENT_REF:
2202 return 15;
2204 /* Special expressions. */
2205 case MIN_EXPR:
2206 case MAX_EXPR:
2207 case ABS_EXPR:
2208 case REALPART_EXPR:
2209 case IMAGPART_EXPR:
2210 case REDUC_MAX_EXPR:
2211 case REDUC_MIN_EXPR:
2212 case REDUC_PLUS_EXPR:
2213 case VEC_LSHIFT_EXPR:
2214 case VEC_RSHIFT_EXPR:
2215 return 16;
2217 case SAVE_EXPR:
2218 case NON_LVALUE_EXPR:
2219 return op_prio (TREE_OPERAND (op, 0));
2221 default:
2222 /* Return an arbitrarily high precedence to avoid surrounding single
2223 VAR_DECLs in ()s. */
2224 return 9999;
2229 /* Return the symbol associated with operator OP. */
2231 static const char *
2232 op_symbol_1 (enum tree_code code)
2234 switch (code)
2236 case MODIFY_EXPR:
2237 return "=";
2239 case TRUTH_OR_EXPR:
2240 case TRUTH_ORIF_EXPR:
2241 return "||";
2243 case TRUTH_AND_EXPR:
2244 case TRUTH_ANDIF_EXPR:
2245 return "&&";
2247 case BIT_IOR_EXPR:
2248 return "|";
2250 case TRUTH_XOR_EXPR:
2251 case BIT_XOR_EXPR:
2252 return "^";
2254 case ADDR_EXPR:
2255 case BIT_AND_EXPR:
2256 return "&";
2258 case ORDERED_EXPR:
2259 return "ord";
2260 case UNORDERED_EXPR:
2261 return "unord";
2263 case EQ_EXPR:
2264 return "==";
2265 case UNEQ_EXPR:
2266 return "u==";
2268 case NE_EXPR:
2269 return "!=";
2271 case LT_EXPR:
2272 return "<";
2273 case UNLT_EXPR:
2274 return "u<";
2276 case LE_EXPR:
2277 return "<=";
2278 case UNLE_EXPR:
2279 return "u<=";
2281 case GT_EXPR:
2282 return ">";
2283 case UNGT_EXPR:
2284 return "u>";
2286 case GE_EXPR:
2287 return ">=";
2288 case UNGE_EXPR:
2289 return "u>=";
2291 case LTGT_EXPR:
2292 return "<>";
2294 case LSHIFT_EXPR:
2295 return "<<";
2297 case RSHIFT_EXPR:
2298 return ">>";
2300 case LROTATE_EXPR:
2301 return "r<<";
2303 case RROTATE_EXPR:
2304 return "r>>";
2306 case VEC_LSHIFT_EXPR:
2307 return "v<<";
2309 case VEC_RSHIFT_EXPR:
2310 return "v>>";
2312 case PLUS_EXPR:
2313 return "+";
2315 case REDUC_PLUS_EXPR:
2316 return "r+";
2318 case WIDEN_SUM_EXPR:
2319 return "w+";
2321 case WIDEN_MULT_EXPR:
2322 return "w*";
2324 case NEGATE_EXPR:
2325 case MINUS_EXPR:
2326 return "-";
2328 case BIT_NOT_EXPR:
2329 return "~";
2331 case TRUTH_NOT_EXPR:
2332 return "!";
2334 case MULT_EXPR:
2335 case INDIRECT_REF:
2336 return "*";
2338 case ALIGN_INDIRECT_REF:
2339 return "A*";
2341 case MISALIGNED_INDIRECT_REF:
2342 return "M*";
2344 case TRUNC_DIV_EXPR:
2345 case RDIV_EXPR:
2346 return "/";
2348 case CEIL_DIV_EXPR:
2349 return "/[cl]";
2351 case FLOOR_DIV_EXPR:
2352 return "/[fl]";
2354 case ROUND_DIV_EXPR:
2355 return "/[rd]";
2357 case EXACT_DIV_EXPR:
2358 return "/[ex]";
2360 case TRUNC_MOD_EXPR:
2361 return "%";
2363 case CEIL_MOD_EXPR:
2364 return "%[cl]";
2366 case FLOOR_MOD_EXPR:
2367 return "%[fl]";
2369 case ROUND_MOD_EXPR:
2370 return "%[rd]";
2372 case PREDECREMENT_EXPR:
2373 return " --";
2375 case PREINCREMENT_EXPR:
2376 return " ++";
2378 case POSTDECREMENT_EXPR:
2379 return "-- ";
2381 case POSTINCREMENT_EXPR:
2382 return "++ ";
2384 case MAX_EXPR:
2385 return "max";
2387 case MIN_EXPR:
2388 return "min";
2390 default:
2391 return "<<< ??? >>>";
2395 static const char *
2396 op_symbol (tree op)
2398 return op_symbol_1 (TREE_CODE (op));
2401 /* Prints the name of a CALL_EXPR. */
2403 static void
2404 print_call_name (pretty_printer *buffer, tree node)
2406 tree op0;
2408 gcc_assert (TREE_CODE (node) == CALL_EXPR);
2410 op0 = TREE_OPERAND (node, 0);
2412 if (TREE_CODE (op0) == NON_LVALUE_EXPR)
2413 op0 = TREE_OPERAND (op0, 0);
2415 switch (TREE_CODE (op0))
2417 case VAR_DECL:
2418 case PARM_DECL:
2419 dump_function_name (buffer, op0);
2420 break;
2422 case ADDR_EXPR:
2423 case INDIRECT_REF:
2424 case NOP_EXPR:
2425 dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
2426 break;
2428 case COND_EXPR:
2429 pp_string (buffer, "(");
2430 dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
2431 pp_string (buffer, ") ? ");
2432 dump_generic_node (buffer, TREE_OPERAND (op0, 1), 0, 0, false);
2433 pp_string (buffer, " : ");
2434 dump_generic_node (buffer, TREE_OPERAND (op0, 2), 0, 0, false);
2435 break;
2437 case COMPONENT_REF:
2438 /* The function is a pointer contained in a structure. */
2439 if (TREE_CODE (TREE_OPERAND (op0, 0)) == INDIRECT_REF ||
2440 TREE_CODE (TREE_OPERAND (op0, 0)) == VAR_DECL)
2441 dump_function_name (buffer, TREE_OPERAND (op0, 1));
2442 else
2443 dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
2444 /* else
2445 We can have several levels of structures and a function
2446 pointer inside. This is not implemented yet... */
2447 /* NIY;*/
2448 break;
2450 case ARRAY_REF:
2451 if (TREE_CODE (TREE_OPERAND (op0, 0)) == VAR_DECL)
2452 dump_function_name (buffer, TREE_OPERAND (op0, 0));
2453 else
2454 dump_generic_node (buffer, op0, 0, 0, false);
2455 break;
2457 case SSA_NAME:
2458 case OBJ_TYPE_REF:
2459 dump_generic_node (buffer, op0, 0, 0, false);
2460 break;
2462 default:
2463 NIY;
2467 /* Parses the string STR and replaces new-lines by '\n', tabs by '\t', ... */
2469 static void
2470 pretty_print_string (pretty_printer *buffer, const char *str)
2472 if (str == NULL)
2473 return;
2475 while (*str)
2477 switch (str[0])
2479 case '\b':
2480 pp_string (buffer, "\\b");
2481 break;
2483 case '\f':
2484 pp_string (buffer, "\\f");
2485 break;
2487 case '\n':
2488 pp_string (buffer, "\\n");
2489 break;
2491 case '\r':
2492 pp_string (buffer, "\\r");
2493 break;
2495 case '\t':
2496 pp_string (buffer, "\\t");
2497 break;
2499 case '\v':
2500 pp_string (buffer, "\\v");
2501 break;
2503 case '\\':
2504 pp_string (buffer, "\\\\");
2505 break;
2507 case '\"':
2508 pp_string (buffer, "\\\"");
2509 break;
2511 case '\'':
2512 pp_string (buffer, "\\'");
2513 break;
2515 case '\0':
2516 pp_string (buffer, "\\0");
2517 break;
2519 case '\1':
2520 pp_string (buffer, "\\1");
2521 break;
2523 case '\2':
2524 pp_string (buffer, "\\2");
2525 break;
2527 case '\3':
2528 pp_string (buffer, "\\3");
2529 break;
2531 case '\4':
2532 pp_string (buffer, "\\4");
2533 break;
2535 case '\5':
2536 pp_string (buffer, "\\5");
2537 break;
2539 case '\6':
2540 pp_string (buffer, "\\6");
2541 break;
2543 case '\7':
2544 pp_string (buffer, "\\7");
2545 break;
2547 default:
2548 pp_character (buffer, str[0]);
2549 break;
2551 str++;
2555 static void
2556 maybe_init_pretty_print (FILE *file)
2558 if (!initialized)
2560 pp_construct (&buffer, /* prefix */NULL, /* line-width */0);
2561 pp_needs_newline (&buffer) = true;
2562 initialized = 1;
2565 buffer.buffer->stream = file;
2568 static void
2569 newline_and_indent (pretty_printer *buffer, int spc)
2571 pp_newline (buffer);
2572 INDENT (spc);
2575 static void
2576 dump_vops (pretty_printer *buffer, tree stmt, int spc, int flags)
2578 tree use;
2579 use_operand_p use_p;
2580 def_operand_p def_p;
2581 use_operand_p kill_p;
2582 ssa_op_iter iter;
2584 if (!ssa_operands_active ())
2585 return;
2587 FOR_EACH_SSA_MAYDEF_OPERAND (def_p, use_p, stmt, iter)
2589 pp_string (buffer, "# ");
2590 dump_generic_node (buffer, DEF_FROM_PTR (def_p),
2591 spc + 2, flags, false);
2592 pp_string (buffer, " = V_MAY_DEF <");
2593 dump_generic_node (buffer, USE_FROM_PTR (use_p),
2594 spc + 2, flags, false);
2595 pp_string (buffer, ">;");
2596 newline_and_indent (buffer, spc);
2599 FOR_EACH_SSA_MUSTDEF_OPERAND (def_p, kill_p, stmt, iter)
2601 pp_string (buffer, "# ");
2602 dump_generic_node (buffer, DEF_FROM_PTR (def_p),
2603 spc + 2, flags, false);
2604 pp_string (buffer, " = V_MUST_DEF <");
2605 dump_generic_node (buffer, USE_FROM_PTR (kill_p),
2606 spc + 2, flags, false);
2607 pp_string (buffer, ">;");
2608 newline_and_indent (buffer, spc);
2611 FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_VUSE)
2613 pp_string (buffer, "# VUSE <");
2614 dump_generic_node (buffer, use, spc + 2, flags, false);
2615 pp_string (buffer, ">;");
2616 newline_and_indent (buffer, spc);
2620 /* Dumps basic block BB to FILE with details described by FLAGS and
2621 indented by INDENT spaces. */
2623 void
2624 dump_generic_bb (FILE *file, basic_block bb, int indent, int flags)
2626 maybe_init_pretty_print (file);
2627 dump_generic_bb_buff (&buffer, bb, indent, flags);
2628 pp_flush (&buffer);
2631 /* Dumps header of basic block BB to buffer BUFFER indented by INDENT
2632 spaces and details described by flags. */
2634 static void
2635 dump_bb_header (pretty_printer *buffer, basic_block bb, int indent, int flags)
2637 edge e;
2638 tree stmt;
2639 edge_iterator ei;
2641 if (flags & TDF_BLOCKS)
2643 INDENT (indent);
2644 pp_string (buffer, "# BLOCK ");
2645 pp_decimal_int (buffer, bb->index);
2646 if (bb->frequency)
2648 pp_string (buffer, " freq:");
2649 pp_decimal_int (buffer, bb->frequency);
2651 if (bb->count)
2653 pp_string (buffer, " count:");
2654 pp_widest_integer (buffer, bb->count);
2657 if (flags & TDF_LINENO)
2659 block_stmt_iterator bsi;
2661 for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
2662 if (get_lineno (bsi_stmt (bsi)) != -1)
2664 pp_string (buffer, ", starting at line ");
2665 pp_decimal_int (buffer, get_lineno (bsi_stmt (bsi)));
2666 break;
2669 newline_and_indent (buffer, indent);
2671 pp_string (buffer, "# PRED:");
2672 pp_write_text_to_stream (buffer);
2673 FOR_EACH_EDGE (e, ei, bb->preds)
2674 if (flags & TDF_SLIM)
2676 pp_string (buffer, " ");
2677 if (e->src == ENTRY_BLOCK_PTR)
2678 pp_string (buffer, "ENTRY");
2679 else
2680 pp_decimal_int (buffer, e->src->index);
2682 else
2683 dump_edge_info (buffer->buffer->stream, e, 0);
2684 pp_newline (buffer);
2686 else
2688 stmt = first_stmt (bb);
2689 if (!stmt || TREE_CODE (stmt) != LABEL_EXPR)
2691 INDENT (indent - 2);
2692 pp_string (buffer, "<bb ");
2693 pp_decimal_int (buffer, bb->index);
2694 pp_string (buffer, ">:");
2695 pp_newline (buffer);
2698 pp_write_text_to_stream (buffer);
2699 check_bb_profile (bb, buffer->buffer->stream);
2702 /* Dumps end of basic block BB to buffer BUFFER indented by INDENT
2703 spaces. */
2705 static void
2706 dump_bb_end (pretty_printer *buffer, basic_block bb, int indent, int flags)
2708 edge e;
2709 edge_iterator ei;
2711 INDENT (indent);
2712 pp_string (buffer, "# SUCC:");
2713 pp_write_text_to_stream (buffer);
2714 FOR_EACH_EDGE (e, ei, bb->succs)
2715 if (flags & TDF_SLIM)
2717 pp_string (buffer, " ");
2718 if (e->dest == EXIT_BLOCK_PTR)
2719 pp_string (buffer, "EXIT");
2720 else
2721 pp_decimal_int (buffer, e->dest->index);
2723 else
2724 dump_edge_info (buffer->buffer->stream, e, 1);
2725 pp_newline (buffer);
2728 /* Dumps phi nodes of basic block BB to buffer BUFFER with details described by
2729 FLAGS indented by INDENT spaces. */
2731 static void
2732 dump_phi_nodes (pretty_printer *buffer, basic_block bb, int indent, int flags)
2734 tree phi = phi_nodes (bb);
2735 if (!phi)
2736 return;
2738 for (; phi; phi = PHI_CHAIN (phi))
2740 if (is_gimple_reg (PHI_RESULT (phi)) || (flags & TDF_VOPS))
2742 INDENT (indent);
2743 pp_string (buffer, "# ");
2744 dump_generic_node (buffer, phi, indent, flags, false);
2745 pp_newline (buffer);
2750 /* Dump jump to basic block BB that is represented implicitly in the cfg
2751 to BUFFER. */
2753 static void
2754 pp_cfg_jump (pretty_printer *buffer, basic_block bb)
2756 tree stmt;
2758 stmt = first_stmt (bb);
2760 pp_string (buffer, "goto <bb ");
2761 pp_decimal_int (buffer, bb->index);
2762 pp_string (buffer, ">");
2763 if (stmt && TREE_CODE (stmt) == LABEL_EXPR)
2765 pp_string (buffer, " (");
2766 dump_generic_node (buffer, LABEL_EXPR_LABEL (stmt), 0, 0, false);
2767 pp_string (buffer, ")");
2769 pp_semicolon (buffer);
2772 /* Dump edges represented implicitly in basic block BB to BUFFER, indented
2773 by INDENT spaces, with details given by FLAGS. */
2775 static void
2776 dump_implicit_edges (pretty_printer *buffer, basic_block bb, int indent,
2777 int flags)
2779 edge e;
2780 edge_iterator ei;
2782 /* If there is a fallthru edge, we may need to add an artificial goto to the
2783 dump. */
2784 FOR_EACH_EDGE (e, ei, bb->succs)
2785 if (e->flags & EDGE_FALLTHRU)
2786 break;
2787 if (e && e->dest != bb->next_bb)
2789 INDENT (indent);
2791 if ((flags & TDF_LINENO)
2792 #ifdef USE_MAPPED_LOCATION
2793 && e->goto_locus != UNKNOWN_LOCATION
2794 #else
2795 && e->goto_locus
2796 #endif
2799 expanded_location goto_xloc;
2800 #ifdef USE_MAPPED_LOCATION
2801 goto_xloc = expand_location (e->goto_locus);
2802 #else
2803 goto_xloc = *e->goto_locus;
2804 #endif
2805 pp_character (buffer, '[');
2806 if (goto_xloc.file)
2808 pp_string (buffer, goto_xloc.file);
2809 pp_string (buffer, " : ");
2811 pp_decimal_int (buffer, goto_xloc.line);
2812 pp_string (buffer, "] ");
2815 pp_cfg_jump (buffer, e->dest);
2816 pp_newline (buffer);
2820 /* Dumps basic block BB to buffer BUFFER with details described by FLAGS and
2821 indented by INDENT spaces. */
2823 static void
2824 dump_generic_bb_buff (pretty_printer *buffer, basic_block bb,
2825 int indent, int flags)
2827 block_stmt_iterator bsi;
2828 tree stmt;
2829 int label_indent = indent - 2;
2831 if (label_indent < 0)
2832 label_indent = 0;
2834 dump_bb_header (buffer, bb, indent, flags);
2836 dump_phi_nodes (buffer, bb, indent, flags);
2838 for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
2840 int curr_indent;
2842 stmt = bsi_stmt (bsi);
2844 curr_indent = TREE_CODE (stmt) == LABEL_EXPR ? label_indent : indent;
2846 INDENT (curr_indent);
2847 dump_generic_node (buffer, stmt, curr_indent, flags, true);
2848 pp_newline (buffer);
2851 dump_implicit_edges (buffer, bb, indent, flags);
2853 if (flags & TDF_BLOCKS)
2854 dump_bb_end (buffer, bb, indent, flags);