1 /* Java(TM) language-specific utility routines.
2 Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002
3 Free Software Foundation, Inc.
5 This file is part of GNU CC.
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING. If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA.
22 Java and all Java-based marks are trademarks or registered trademarks
23 of Sun Microsystems, Inc. in the United States and other countries.
24 The Free Software Foundation is independent of Sun Microsystems, Inc. */
26 /* Hacked by Per Bothner <bothner@cygnus.com> February 1996. */
30 #include "coretypes.h"
36 #include "java-tree.h"
39 #include "langhooks.h"
40 #include "langhooks-def.h"
44 #include "diagnostic.h"
45 #include "tree-inline.h"
46 #include "splay-tree.h"
47 #include "tree-dump.h"
51 const char *const string
;
56 static const char *java_init
PARAMS ((const char *));
57 static void java_finish
PARAMS ((void));
58 static void java_init_options
PARAMS ((void));
59 static bool java_post_options
PARAMS ((void));
61 static int java_decode_option
PARAMS ((int, char **));
62 static void put_decl_string
PARAMS ((const char *, int));
63 static void put_decl_node
PARAMS ((tree
));
64 static void java_print_error_function
PARAMS ((diagnostic_context
*,
66 static int process_option_with_no
PARAMS ((const char *,
67 const struct string_option
*,
69 static tree java_tree_inlining_walk_subtrees
PARAMS ((tree
*,
74 static int java_unsafe_for_reeval
PARAMS ((tree
));
75 static int merge_init_test_initialization
PARAMS ((void * *,
77 static int inline_init_test_initialization
PARAMS ((void * *,
79 static bool java_can_use_bit_fields_p
PARAMS ((void));
80 static int java_dump_tree
PARAMS ((void *, tree
));
82 #ifndef TARGET_OBJECT_SUFFIX
83 # define TARGET_OBJECT_SUFFIX ".o"
86 /* Table indexed by tree code giving a string containing a character
87 classifying the tree code. Possibilities are
88 t, d, s, c, r, <, 1 and 2. See java/java-tree.def for details. */
90 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE,
92 const char tree_code_type
[] = {
95 #include "java-tree.def"
99 /* Table indexed by tree code giving number of expression
100 operands beyond the fixed part of the node structure.
101 Not used for types or decls. */
103 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) LENGTH,
105 const unsigned char tree_code_length
[] = {
108 #include "java-tree.def"
112 /* Names of tree components.
113 Used for printing out the tree and error messages. */
114 #define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME,
116 const char *const tree_code_name
[] = {
119 #include "java-tree.def"
123 /* Used to avoid printing error messages with bogus function
124 prototypes. Starts out false. */
125 static bool inhibit_error_function_printing
;
127 int compiling_from_source
;
129 char * resource_name
;
131 int flag_emit_class_files
= 0;
133 /* Nonzero if input file is a file with a list of filenames to compile. */
135 int flag_filelist_file
= 0;
137 /* When nonzero, we emit xref strings. Values of the flag for xref
138 backends are defined in xref_flag_table, xref.c. */
140 int flag_emit_xref
= 0;
142 /* When nonzero, -Wall was turned on. */
145 /* When nonzero, check for redundant modifier uses. */
146 int flag_redundant
= 0;
148 /* When nonzero, call a library routine to do integer divisions. */
149 int flag_use_divide_subroutine
= 1;
151 /* When nonzero, generate code for the Boehm GC. */
152 int flag_use_boehm_gc
= 0;
154 /* When nonzero, assume the runtime uses a hash table to map an
155 object to its synchronization structure. */
156 int flag_hash_synchronization
;
158 /* When nonzero, permit the use of the assert keyword. */
161 /* When nonzero, assume all native functions are implemented with
165 /* When nonzero, warn when source file is newer than matching class
169 /* When nonzero, generate checks for references to NULL. */
170 int flag_check_references
= 0;
172 /* The encoding of the source file. */
173 const char *current_encoding
= NULL
;
175 /* When nonzero, report the now deprecated empty statements. */
176 int flag_extraneous_semicolon
;
178 /* When nonzero, always check for a non gcj generated classes archive. */
179 int flag_force_classes_archive_check
;
181 /* When zero, don't optimize static class initialization. This flag shouldn't
182 be tested alone, use STATIC_CLASS_INITIALIZATION_OPTIMIZATION_P instead. */
183 int flag_optimize_sci
= 1;
185 /* When nonzero, use offset tables for virtual method calls
186 in order to improve binary compatibility. */
187 int flag_indirect_dispatch
= 0;
189 /* When zero, don't generate runtime array store checks. */
190 int flag_store_check
= 1;
192 /* When nonzero, print extra version information. */
193 static int version_flag
= 0;
195 /* Set nonzero if the user specified -finline-functions on the command
197 int flag_really_inline
= 0;
199 /* Table of language-dependent -f options.
200 STRING is the option name. VARIABLE is the address of the variable.
201 ON_VALUE is the value to store in VARIABLE
202 if `-fSTRING' is seen as an option.
203 (If `-fno-STRING' is seen as an option, the opposite value is stored.) */
205 static const struct string_option
208 {"emit-class-file", &flag_emit_class_files
, 1},
209 {"emit-class-files", &flag_emit_class_files
, 1},
210 {"filelist-file", &flag_filelist_file
, 1},
211 {"use-divide-subroutine", &flag_use_divide_subroutine
, 1},
212 {"use-boehm-gc", &flag_use_boehm_gc
, 1},
213 {"hash-synchronization", &flag_hash_synchronization
, 1},
214 {"jni", &flag_jni
, 1},
215 {"check-references", &flag_check_references
, 1},
216 {"force-classes-archive-check", &flag_force_classes_archive_check
, 1},
217 {"optimize-static-class-initialization", &flag_optimize_sci
, 1 },
218 {"indirect-dispatch", &flag_indirect_dispatch
, 1},
219 {"store-check", &flag_store_check
, 1},
220 {"assert", &flag_assert
, 1}
223 static const struct string_option
226 { "redundant-modifiers", &flag_redundant
, 1 },
227 { "extraneous-semicolon", &flag_extraneous_semicolon
, 1 },
228 { "out-of-date", &flag_newer
, 1 }
233 /* Variable controlling how dependency tracking is enabled in
235 static int dependency_tracking
= 0;
237 /* Flag values for DEPENDENCY_TRACKING. */
238 #define DEPEND_SET_FILE 1
239 #define DEPEND_ENABLE 2
240 #define DEPEND_TARGET_SET 4
241 #define DEPEND_FILE_ALREADY_SET 8
243 struct language_function
GTY(())
248 #undef LANG_HOOKS_NAME
249 #define LANG_HOOKS_NAME "GNU Java"
250 #undef LANG_HOOKS_INIT
251 #define LANG_HOOKS_INIT java_init
252 #undef LANG_HOOKS_FINISH
253 #define LANG_HOOKS_FINISH java_finish
254 #undef LANG_HOOKS_INIT_OPTIONS
255 #define LANG_HOOKS_INIT_OPTIONS java_init_options
256 #undef LANG_HOOKS_DECODE_OPTION
257 #define LANG_HOOKS_DECODE_OPTION java_decode_option
258 #undef LANG_HOOKS_POST_OPTIONS
259 #define LANG_HOOKS_POST_OPTIONS java_post_options
260 #undef LANG_HOOKS_PARSE_FILE
261 #define LANG_HOOKS_PARSE_FILE java_parse_file
262 #undef LANG_HOOKS_UNSAFE_FOR_REEVAL
263 #define LANG_HOOKS_UNSAFE_FOR_REEVAL java_unsafe_for_reeval
264 #undef LANG_HOOKS_MARK_ADDRESSABLE
265 #define LANG_HOOKS_MARK_ADDRESSABLE java_mark_addressable
266 #undef LANG_HOOKS_EXPAND_EXPR
267 #define LANG_HOOKS_EXPAND_EXPR java_expand_expr
268 #undef LANG_HOOKS_TRUTHVALUE_CONVERSION
269 #define LANG_HOOKS_TRUTHVALUE_CONVERSION java_truthvalue_conversion
270 #undef LANG_HOOKS_DUP_LANG_SPECIFIC_DECL
271 #define LANG_HOOKS_DUP_LANG_SPECIFIC_DECL java_dup_lang_specific_decl
272 #undef LANG_HOOKS_DECL_PRINTABLE_NAME
273 #define LANG_HOOKS_DECL_PRINTABLE_NAME lang_printable_name
274 #undef LANG_HOOKS_PRINT_ERROR_FUNCTION
275 #define LANG_HOOKS_PRINT_ERROR_FUNCTION java_print_error_function
276 #undef LANG_HOOKS_CAN_USE_BIT_FIELDS_P
277 #define LANG_HOOKS_CAN_USE_BIT_FIELDS_P java_can_use_bit_fields_p
279 #undef LANG_HOOKS_TYPE_FOR_MODE
280 #define LANG_HOOKS_TYPE_FOR_MODE java_type_for_mode
281 #undef LANG_HOOKS_TYPE_FOR_SIZE
282 #define LANG_HOOKS_TYPE_FOR_SIZE java_type_for_size
283 #undef LANG_HOOKS_SIGNED_TYPE
284 #define LANG_HOOKS_SIGNED_TYPE java_signed_type
285 #undef LANG_HOOKS_UNSIGNED_TYPE
286 #define LANG_HOOKS_UNSIGNED_TYPE java_unsigned_type
287 #undef LANG_HOOKS_SIGNED_OR_UNSIGNED_TYPE
288 #define LANG_HOOKS_SIGNED_OR_UNSIGNED_TYPE java_signed_or_unsigned_type
290 #undef LANG_HOOKS_TREE_INLINING_WALK_SUBTREES
291 #define LANG_HOOKS_TREE_INLINING_WALK_SUBTREES java_tree_inlining_walk_subtrees
293 #undef LANG_HOOKS_TREE_DUMP_DUMP_TREE_FN
294 #define LANG_HOOKS_TREE_DUMP_DUMP_TREE_FN java_dump_tree
296 /* Each front end provides its own. */
297 const struct lang_hooks lang_hooks
= LANG_HOOKS_INITIALIZER
;
299 /* Process an option that can accept a `no-' form.
300 Return 1 if option found, 0 otherwise. */
302 process_option_with_no (p
, table
, table_size
)
304 const struct string_option
*table
;
309 for (j
= 0; j
< table_size
; j
++)
311 if (!strcmp (p
, table
[j
].string
))
313 *table
[j
].variable
= table
[j
].on_value
;
316 if (p
[0] == 'n' && p
[1] == 'o' && p
[2] == '-'
317 && ! strcmp (p
+3, table
[j
].string
))
319 *table
[j
].variable
= ! table
[j
].on_value
;
328 * process java-specific compiler command-line options
329 * return 0, but do not complain if the option is not recognized.
332 java_decode_option (argc
, argv
)
333 int argc
__attribute__ ((__unused__
));
340 if (strcmp (p
, "-version") == 0)
343 /* We return 0 so that the caller can process this. */
347 #define CLARG "-fcompile-resource="
348 if (strncmp (p
, CLARG
, sizeof (CLARG
) - 1) == 0)
350 resource_name
= p
+ sizeof (CLARG
) - 1;
354 #define CLARG "-fassume-compiled="
355 if (strncmp (p
, CLARG
, sizeof (CLARG
) - 1) == 0)
357 add_assume_compiled (p
+ sizeof (CLARG
) - 1, 0);
361 #define CLARG "-fno-assume-compiled="
362 if (strncmp (p
, CLARG
, sizeof (CLARG
) - 1) == 0)
364 add_assume_compiled (p
+ sizeof (CLARG
) - 1, 1);
368 #define CLARG "-fassume-compiled"
369 if (strncmp (p
, CLARG
, sizeof (CLARG
) - 1) == 0)
371 add_assume_compiled ("", 0);
375 #define CLARG "-fno-assume-compiled"
376 if (strncmp (p
, CLARG
, sizeof (CLARG
) - 1) == 0)
378 add_assume_compiled ("", 1);
382 #define CLARG "-fCLASSPATH="
383 if (strncmp (p
, CLARG
, sizeof (CLARG
) - 1) == 0)
385 jcf_path_classpath_arg (p
+ sizeof (CLARG
) - 1);
389 #define CLARG "-fclasspath="
390 if (strncmp (p
, CLARG
, sizeof (CLARG
) - 1) == 0)
392 jcf_path_classpath_arg (p
+ sizeof (CLARG
) - 1);
396 #define CLARG "-fbootclasspath="
397 if (strncmp (p
, CLARG
, sizeof (CLARG
) - 1) == 0)
399 jcf_path_bootclasspath_arg (p
+ sizeof (CLARG
) - 1);
403 #define CLARG "-fextdirs="
404 if (strncmp (p
, CLARG
, sizeof (CLARG
) - 1) == 0)
406 jcf_path_extdirs_arg (p
+ sizeof (CLARG
) - 1);
410 else if (strncmp (p
, "-I", 2) == 0)
412 jcf_path_include_arg (p
+ 2);
416 #define ARG "-foutput-class-dir="
417 if (strncmp (p
, ARG
, sizeof (ARG
) - 1) == 0)
419 jcf_write_base_directory
= p
+ sizeof (ARG
) - 1;
423 #define ARG "-fencoding="
424 if (strncmp (p
, ARG
, sizeof (ARG
) - 1) == 0)
426 current_encoding
= p
+ sizeof (ARG
) - 1;
430 #define ARG "-finline-functions"
431 if (strncmp (p
, ARG
, sizeof (ARG
) - 1) == 0)
433 flag_inline_functions
= 1;
434 flag_really_inline
= 1;
439 if (p
[0] == '-' && p
[1] == 'f')
441 /* Some kind of -f option.
442 P's value is the option sans `-f'.
443 Search for it in the table of options. */
445 if (process_option_with_no (p
, lang_f_options
,
446 ARRAY_SIZE (lang_f_options
)))
448 return dump_switch_p (p
);
451 if (strcmp (p
, "-Wall") == 0)
455 flag_extraneous_semicolon
= 1;
456 /* When -Wall given, enable -Wunused. We do this because the C
457 compiler does it, and people expect it. */
462 if (p
[0] == '-' && p
[1] == 'W')
464 /* Skip `-W' and see if we accept the option or its `no-' form. */
466 return process_option_with_no (p
, lang_W_options
,
467 ARRAY_SIZE (lang_W_options
));
470 if (strcmp (p
, "-MD") == 0)
472 jcf_dependency_init (1);
473 dependency_tracking
|= DEPEND_SET_FILE
| DEPEND_ENABLE
;
476 else if (strcmp (p
, "-MMD") == 0)
478 jcf_dependency_init (0);
479 dependency_tracking
|= DEPEND_SET_FILE
| DEPEND_ENABLE
;
482 else if (strcmp (p
, "-M") == 0)
484 jcf_dependency_init (1);
485 dependency_tracking
|= DEPEND_ENABLE
;
488 else if (strcmp (p
, "-MM") == 0)
490 jcf_dependency_init (0);
491 dependency_tracking
|= DEPEND_ENABLE
;
494 else if (strcmp (p
, "-MP") == 0)
496 jcf_dependency_print_dummies ();
499 else if (strcmp (p
, "-MT") == 0)
501 jcf_dependency_set_target (argv
[1]);
502 dependency_tracking
|= DEPEND_TARGET_SET
;
505 else if (strcmp (p
, "-MF") == 0)
507 jcf_dependency_set_dep_file (argv
[1]);
508 dependency_tracking
|= DEPEND_FILE_ALREADY_SET
;
515 /* Global open file. */
520 const char *filename
;
523 extern int flag_minimal_debug
;
524 flag_minimal_debug
= 0;
527 if (flag_inline_functions
)
528 flag_inline_trees
= 1;
530 /* Force minimum function alignment if g++ uses the least significant
531 bit of function pointers to store the virtual bit. This is required
532 to keep vtables compatible. */
533 if (TARGET_PTRMEMFUNC_VBIT_LOCATION
== ptrmemfunc_vbit_in_pfn
534 && force_align_functions_log
< 1)
535 force_align_functions_log
= 1;
537 /* Open input file. */
539 if (filename
== 0 || !strcmp (filename
, "-"))
544 if (dependency_tracking
)
545 error ("can't do dependency tracking with input from stdin");
549 if (dependency_tracking
)
553 /* If the target is set and the output filename is set, then
554 there's no processing to do here. Otherwise we must
555 compute one or the other. */
556 if (! ((dependency_tracking
& DEPEND_TARGET_SET
)
557 && (dependency_tracking
& DEPEND_FILE_ALREADY_SET
)))
559 dot
= strrchr (filename
, '.');
561 error ("couldn't determine target name for dependency tracking");
564 char *buf
= xmalloc (dot
- filename
+
565 3 + sizeof (TARGET_OBJECT_SUFFIX
));
566 strncpy (buf
, filename
, dot
- filename
);
568 /* If emitting class files, we might have multiple
569 targets. The class generation code takes care of
570 registering them. Otherwise we compute the
572 if ((dependency_tracking
& DEPEND_TARGET_SET
))
574 else if (flag_emit_class_files
)
575 jcf_dependency_set_target (NULL
);
578 strcpy (buf
+ (dot
- filename
), TARGET_OBJECT_SUFFIX
);
579 jcf_dependency_set_target (buf
);
582 if ((dependency_tracking
& DEPEND_FILE_ALREADY_SET
))
584 else if ((dependency_tracking
& DEPEND_SET_FILE
))
586 strcpy (buf
+ (dot
- filename
), ".d");
587 jcf_dependency_set_dep_file (buf
);
590 jcf_dependency_set_dep_file ("-");
599 jcf_path_seal (version_flag
);
601 java_init_decl_processing ();
603 using_eh_for_cleanups ();
611 jcf_dependency_write ();
614 /* Buffer used by lang_printable_name. */
615 static char *decl_buf
= NULL
;
617 /* Allocated size of decl_buf. */
618 static int decl_buflen
= 0;
620 /* Length of used part of decl_buf; position for next character. */
621 static int decl_bufpos
= 0;
623 /* Append the string STR to decl_buf.
624 It length is given by LEN; -1 means the string is nul-terminated. */
627 put_decl_string (str
, len
)
633 if (decl_bufpos
+ len
>= decl_buflen
)
635 if (decl_buf
== NULL
)
637 decl_buflen
= len
+ 100;
638 decl_buf
= xmalloc (decl_buflen
);
643 decl_buf
= xrealloc (decl_buf
, decl_buflen
);
646 strcpy (decl_buf
+ decl_bufpos
, str
);
650 /* Append to decl_buf a printable name for NODE. */
657 if (TREE_CODE (node
) == POINTER_TYPE
)
659 node
= TREE_TYPE (node
);
662 if (TREE_CODE_CLASS (TREE_CODE (node
)) == 'd'
663 && DECL_NAME (node
) != NULL_TREE
)
665 if (TREE_CODE (node
) == FUNCTION_DECL
)
667 /* We want to print the type the DECL belongs to. We don't do
668 that when we handle constructors. */
669 if (! DECL_CONSTRUCTOR_P (node
)
670 && ! DECL_ARTIFICIAL (node
) && DECL_CONTEXT (node
))
672 put_decl_node (TYPE_NAME (DECL_CONTEXT (node
)));
673 put_decl_string (".", 1);
675 if (! DECL_CONSTRUCTOR_P (node
))
676 put_decl_node (DECL_NAME (node
));
677 if (TREE_TYPE (node
) != NULL_TREE
)
680 tree args
= TYPE_ARG_TYPES (TREE_TYPE (node
));
681 if (TREE_CODE (TREE_TYPE (node
)) == METHOD_TYPE
)
682 args
= TREE_CHAIN (args
);
683 put_decl_string ("(", 1);
684 for ( ; args
!= end_params_node
; args
= TREE_CHAIN (args
), i
++)
687 put_decl_string (",", 1);
688 put_decl_node (TREE_VALUE (args
));
690 put_decl_string (")", 1);
694 put_decl_node (DECL_NAME (node
));
696 else if (TREE_CODE_CLASS (TREE_CODE (node
)) == 't'
697 && TYPE_NAME (node
) != NULL_TREE
)
699 if (TREE_CODE (node
) == RECORD_TYPE
&& TYPE_ARRAY_P (node
))
701 put_decl_node (TYPE_ARRAY_ELEMENT (node
));
702 put_decl_string("[]", 2);
704 else if (node
== promoted_byte_type_node
)
705 put_decl_string ("byte", 4);
706 else if (node
== promoted_short_type_node
)
707 put_decl_string ("short", 5);
708 else if (node
== promoted_char_type_node
)
709 put_decl_string ("char", 4);
710 else if (node
== promoted_boolean_type_node
)
711 put_decl_string ("boolean", 7);
712 else if (node
== void_type_node
&& was_pointer
)
713 put_decl_string ("null", 4);
715 put_decl_node (TYPE_NAME (node
));
717 else if (TREE_CODE (node
) == IDENTIFIER_NODE
)
718 put_decl_string (IDENTIFIER_POINTER (node
), IDENTIFIER_LENGTH (node
));
720 put_decl_string ("<unknown>", -1);
723 /* Return a user-friendly name for DECL.
724 The resulting string is only valid until the next call.
725 The value of the hook decl_printable_name is this function,
726 which is also called directly by java_print_error_function. */
729 lang_printable_name (decl
, v
)
731 int v
__attribute__ ((__unused__
));
734 put_decl_node (decl
);
735 put_decl_string ("", 1);
739 /* Does the same thing that lang_printable_name, but add a leading
740 space to the DECL name string -- With Leading Space. */
743 lang_printable_name_wls (decl
, v
)
745 int v
__attribute__ ((__unused__
));
748 put_decl_node (decl
);
749 put_decl_string ("", 1);
754 /* Print on stderr the current class and method context. This function
755 is the value of the hook print_error_function. */
757 static GTY(()) tree last_error_function_context
;
758 static GTY(()) tree last_error_function
;
760 java_print_error_function (context
, file
)
761 diagnostic_context
*context
__attribute__((__unused__
));
764 /* Don't print error messages with bogus function prototypes. */
765 if (inhibit_error_function_printing
)
768 if (current_function_decl
!= NULL
769 && DECL_CONTEXT (current_function_decl
) != last_error_function_context
)
772 fprintf (stderr
, "%s: ", file
);
774 last_error_function_context
= DECL_CONTEXT (current_function_decl
);
775 fprintf (stderr
, "In class `%s':\n",
776 lang_printable_name (last_error_function_context
, 0));
778 if (last_error_function
!= current_function_decl
)
781 fprintf (stderr
, "%s: ", file
);
783 if (current_function_decl
== NULL
)
784 fprintf (stderr
, "At top level:\n");
787 const char *name
= lang_printable_name (current_function_decl
, 2);
788 fprintf (stderr
, "In %s `%s':\n",
789 (DECL_CONSTRUCTOR_P (current_function_decl
) ? "constructor"
794 last_error_function
= current_function_decl
;
799 /* Called to install the PRINT_ERROR_FUNCTION hook differently
800 according to LEVEL. LEVEL is 1 during early parsing, when function
801 prototypes aren't fully resolved. java_print_error_function is set
802 so it doesn't print incomplete function prototypes. When LEVEL is
803 2, function prototypes are fully resolved and can be printed when
806 void lang_init_source (level
)
809 inhibit_error_function_printing
= (level
== 1);
815 flag_bounds_check
= 1;
817 flag_non_call_exceptions
= 1;
819 /* In Java floating point operations never trap. */
820 flag_trapping_math
= 0;
824 java_can_use_bit_fields_p ()
826 /* The bit-field optimizations cause problems when generating class
828 return flag_emit_class_files
? false : true;
831 /* Post-switch processing. */
835 /* Use tree inlining if possible. Function instrumentation is only
836 done in the RTL level, so we disable tree inlining. */
837 if (! flag_instrument_function_entry_exit
)
841 if (flag_inline_functions
)
843 flag_inline_trees
= 2;
844 flag_inline_functions
= 0;
848 /* Initialize the compiler back end. */
852 /* Return either DECL or its known constant value (if it has one). */
855 decl_constant_value (decl
)
858 if (/* Don't change a variable array bound or initial value to a constant
859 in a place where a variable is invalid. */
860 current_function_decl
!= 0
861 && ! TREE_THIS_VOLATILE (decl
)
862 && TREE_READONLY (decl
)
863 && DECL_INITIAL (decl
) != 0
864 && TREE_CODE (DECL_INITIAL (decl
)) != ERROR_MARK
865 /* This is invalid if initial value is not constant.
866 If it has either a function call, a memory reference,
867 or a variable, then re-evaluating it could give different results. */
868 && TREE_CONSTANT (DECL_INITIAL (decl
))
869 /* Check for cases where this is sub-optimal, even though valid. */
870 && TREE_CODE (DECL_INITIAL (decl
)) != CONSTRUCTOR
)
871 return DECL_INITIAL (decl
);
875 /* Walk the language specific tree nodes during inlining. */
878 java_tree_inlining_walk_subtrees (tp
,subtrees
,func
,data
,htab
)
879 tree
*tp ATTRIBUTE_UNUSED
;
880 int *subtrees ATTRIBUTE_UNUSED
;
881 walk_tree_fn func ATTRIBUTE_UNUSED
;
882 void *data ATTRIBUTE_UNUSED
;
883 void *htab ATTRIBUTE_UNUSED
;
888 #define WALK_SUBTREE(NODE) \
891 result = walk_tree (&(NODE), func, data, htab); \
901 code
= TREE_CODE (t
);
905 if (BLOCK_EXPR_BODY (t
))
907 tree
*prev
= &BLOCK_EXPR_BODY (*tp
);
910 WALK_SUBTREE (*prev
);
911 prev
= &TREE_CHAIN (*prev
);
922 /* Called from unsafe_for_reeval. */
924 java_unsafe_for_reeval (t
)
927 switch (TREE_CODE (t
))
930 /* Our expander tries to expand the variables twice. Boom. */
931 if (BLOCK_EXPR_DECLS (t
) != NULL
)
933 return unsafe_for_reeval (BLOCK_EXPR_BODY (t
));
942 /* Every call to a static constructor has an associated boolean
943 variable which is in the outermost scope of the calling method.
944 This variable is used to avoid multiple calls to the static
945 constructor for each class.
947 It looks somthing like this:
951 boolean dummy = OtherClass.is_initialized;
956 OtherClass.initialize();
958 ... use OtherClass.data ...
961 Each of these boolean variables has an entry in the
962 DECL_FUNCTION_INIT_TEST_TABLE of a method. When inlining a method
963 we must merge the DECL_FUNCTION_INIT_TEST_TABLE from the function
964 being linlined and create the boolean variables in the outermost
965 scope of the method being inlined into. */
967 /* Create a mapping from a boolean variable in a method being inlined
968 to one in the scope of the method being inlined into. */
971 merge_init_test_initialization (entry
, x
)
975 struct treetreehash_entry
*ite
= (struct treetreehash_entry
*) *entry
;
976 splay_tree decl_map
= (splay_tree
)x
;
978 tree
*init_test_decl
;
980 /* See if we have remapped this declaration. If we haven't there's
981 a bug in the inliner. */
982 n
= splay_tree_lookup (decl_map
, (splay_tree_key
) ite
->value
);
986 /* Create a new entry for the class and its remapped boolean
987 variable. If we already have a mapping for this class we've
988 already initialized it, so don't overwrite the value. */
989 init_test_decl
= java_treetreehash_new
990 (DECL_FUNCTION_INIT_TEST_TABLE (current_function_decl
), ite
->key
);
991 if (!*init_test_decl
)
992 *init_test_decl
= (tree
)n
->value
;
997 /* Merge the DECL_FUNCTION_INIT_TEST_TABLE from the function we're
1001 java_inlining_merge_static_initializers (fn
, decl_map
)
1006 (DECL_FUNCTION_INIT_TEST_TABLE (fn
),
1007 merge_init_test_initialization
, decl_map
);
1010 /* Lookup a DECL_FUNCTION_INIT_TEST_TABLE entry in the method we're
1011 inlining into. If we already have a corresponding entry in that
1012 class we don't need to create another one, so we create a mapping
1013 from the variable in the inlined class to the corresponding
1014 pre-existing one. */
1017 inline_init_test_initialization (entry
, x
)
1021 struct treetreehash_entry
*ite
= (struct treetreehash_entry
*) *entry
;
1022 splay_tree decl_map
= (splay_tree
)x
;
1024 tree h
= java_treetreehash_find
1025 (DECL_FUNCTION_INIT_TEST_TABLE (current_function_decl
), ite
->key
);
1029 splay_tree_insert (decl_map
,
1030 (splay_tree_key
) ite
->value
,
1031 (splay_tree_value
) h
);
1036 /* Look up the boolean variables in the DECL_FUNCTION_INIT_TEST_TABLE
1037 of a method being inlined. For each hone, if we already have a
1038 variable associated with the same class in the method being inlined
1039 into, create a new mapping for it. */
1042 java_inlining_map_static_initializers (fn
, decl_map
)
1047 (DECL_FUNCTION_INIT_TEST_TABLE (fn
),
1048 inline_init_test_initialization
, decl_map
);
1051 /* Avoid voluminous output for deep recursion of compound exprs. */
1054 dump_compound_expr (di
, t
)
1062 switch (TREE_CODE (TREE_OPERAND (t
, i
)))
1065 dump_compound_expr (di
, TREE_OPERAND (t
, i
));
1068 case EXPR_WITH_FILE_LOCATION
:
1070 tree wfl_node
= EXPR_WFL_NODE (TREE_OPERAND (t
, i
));
1071 dump_child ("expr", wfl_node
);
1076 dump_child ("expr", TREE_OPERAND (t
, i
));
1082 java_dump_tree (dump_info
, t
)
1086 enum tree_code code
;
1087 dump_info_p di
= (dump_info_p
) dump_info
;
1089 /* Figure out what kind of node this is. */
1090 code
= TREE_CODE (t
);
1095 dump_child ("args", DECL_ARGUMENTS (t
));
1096 if (DECL_EXTERNAL (t
))
1097 dump_string (di
, "undefined");
1098 if (TREE_PUBLIC (t
))
1099 dump_string (di
, "extern");
1101 dump_string (di
, "static");
1102 if (DECL_LANG_SPECIFIC (t
))
1103 dump_child ("body", DECL_FUNCTION_BODY (t
));
1104 if (DECL_LANG_SPECIFIC (t
) && !dump_flag (di
, TDF_SLIM
, t
))
1105 dump_child ("inline body", DECL_SAVED_TREE (t
));
1109 dump_child ("expr", TREE_OPERAND (t
, 0));
1113 dump_child ("goto", TREE_OPERAND (t
, 0));
1117 dump_child ("label", TREE_OPERAND (t
, 0));
1120 case LABELED_BLOCK_EXPR
:
1121 dump_child ("label", TREE_OPERAND (t
, 0));
1122 dump_child ("block", TREE_OPERAND (t
, 1));
1125 case EXIT_BLOCK_EXPR
:
1126 dump_child ("block", TREE_OPERAND (t
, 0));
1127 dump_child ("val", TREE_OPERAND (t
, 1));
1131 if (BLOCK_EXPR_BODY (t
))
1133 tree local
= BLOCK_VARS (t
);
1136 tree next
= TREE_CHAIN (local
);
1137 dump_child ("var", local
);
1142 tree block
= BLOCK_EXPR_BODY (t
);
1143 dump_child ("body", block
);
1144 block
= TREE_CHAIN (block
);
1150 if (!dump_flag (di
, TDF_SLIM
, t
))
1152 dump_compound_expr (di
, t
);
1160 #include "gt-java-lang.h"