X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fjava%2Flang.c;h=22fe4ffd09b0476bf68e20c5478ab92c6fcd6a48;hb=02433bf7f097de2d710298811b1626a969f61060;hp=8c3578eba6a037aaee913245e5593fe677fc592c;hpb=468fe9576d01ab475ae31f7df4b65dac7a1da449;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/java/lang.c b/gcc/java/lang.c index 8c3578eba6a..22fe4ffd09b 100644 --- a/gcc/java/lang.c +++ b/gcc/java/lang.c @@ -1,12 +1,12 @@ /* Java(TM) language-specific utility routines. - Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 - Free Software Foundation, Inc. + Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, + 2005, 2006, 2007, 2008 Free Software Foundation, Inc. This file is part of GCC. GCC is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) +the Free Software Foundation; either version 3, or (at your option) any later version. GCC is distributed in the hope that it will be useful, @@ -15,9 +15,8 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. +along with GCC; see the file COPYING3. If not see +. Java and all Java-based marks are trademarks or registered trademarks of Sun Microsystems, Inc. in the United States and other countries. @@ -39,153 +38,69 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */ #include "langhooks.h" #include "langhooks-def.h" #include "flags.h" -#include "xref.h" #include "ggc.h" #include "diagnostic.h" #include "tree-inline.h" #include "splay-tree.h" #include "tree-dump.h" #include "opts.h" -#include "j-options.h" +#include "options.h" +#include "except.h" static bool java_init (void); static void java_finish (void); -static int java_init_options (void); +static unsigned int java_init_options (unsigned int, const char **); static bool java_post_options (const char **); static int java_handle_option (size_t scode, const char *arg, int value); static void put_decl_string (const char *, int); -static void put_decl_node (tree); -static void java_print_error_function (diagnostic_context *, const char *); -static tree java_tree_inlining_walk_subtrees (tree *, int *, walk_tree_fn, - void *, void *); -static int java_unsafe_for_reeval (tree); +static void put_decl_node (tree, int); +static void java_print_error_function (diagnostic_context *, const char *, + diagnostic_info *); static int merge_init_test_initialization (void * *, void *); static int inline_init_test_initialization (void * *, void *); -static bool java_can_use_bit_fields_p (void); static bool java_dump_tree (void *, tree); static void dump_compound_expr (dump_info_p, tree); -static bool java_decl_ok_for_sibcall (tree); +static bool java_decl_ok_for_sibcall (const_tree); + +static enum classify_record java_classify_record (tree type); + +static tree java_eh_personality (void); #ifndef TARGET_OBJECT_SUFFIX # define TARGET_OBJECT_SUFFIX ".o" #endif -/* Table indexed by tree code giving a string containing a character - classifying the tree code. Possibilities are - t, d, s, c, r, <, 1 and 2. See java/java-tree.def for details. */ - -#define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE, - -const char tree_code_type[] = { -#include "tree.def" - 'x', -#include "java-tree.def" -}; -#undef DEFTREECODE - -/* Table indexed by tree code giving number of expression - operands beyond the fixed part of the node structure. - Not used for types or decls. */ - -#define DEFTREECODE(SYM, NAME, TYPE, LENGTH) LENGTH, - -const unsigned char tree_code_length[] = { -#include "tree.def" - 0, -#include "java-tree.def" -}; -#undef DEFTREECODE - -/* Names of tree components. - Used for printing out the tree and error messages. */ -#define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME, - -const char *const tree_code_name[] = { -#include "tree.def" - "@@dummy", -#include "java-tree.def" +/* Table of machine-independent attributes. */ +const struct attribute_spec java_attribute_table[] = +{ + { "nonnull", 0, -1, false, true, true, + NULL }, + { NULL, 0, 0, false, false, false, NULL } }; -#undef DEFTREECODE /* Used to avoid printing error messages with bogus function prototypes. Starts out false. */ static bool inhibit_error_function_printing; -int compiling_from_source; - const char *resource_name; -int flag_emit_class_files = 0; - -/* Nonzero if input file is a file with a list of filenames to compile. */ - -int flag_filelist_file = 0; - -/* When nonzero, we emit xref strings. Values of the flag for xref - backends are defined in xref_flag_table, xref.c. */ - -int flag_emit_xref = 0; - /* When nonzero, -Wall was turned on. */ int flag_wall = 0; -/* When nonzero, check for redundant modifier uses. */ -int flag_redundant = 0; - -/* When nonzero, call a library routine to do integer divisions. */ -int flag_use_divide_subroutine = 1; - -/* When nonzero, generate code for the Boehm GC. */ -int flag_use_boehm_gc = 0; - -/* When nonzero, assume the runtime uses a hash table to map an - object to its synchronization structure. */ -int flag_hash_synchronization; - -/* When nonzero, permit the use of the assert keyword. */ -int flag_assert = 1; - -/* When nonzero, assume all native functions are implemented with - JNI, not CNI. */ -int flag_jni = 0; - -/* When nonzero, warn when source file is newer than matching class - file. */ -int flag_newer = 1; - -/* When nonzero, generate checks for references to NULL. */ -int flag_check_references = 0; - -/* The encoding of the source file. */ -const char *current_encoding = NULL; - -/* When nonzero, report the now deprecated empty statements. */ -int flag_extraneous_semicolon; - /* When nonzero, report use of deprecated classes, methods, or fields. */ int flag_deprecated = 1; -/* When nonzero, always check for a non gcj generated classes archive. */ -int flag_force_classes_archive_check; - /* When zero, don't optimize static class initialization. This flag shouldn't be tested alone, use STATIC_CLASS_INITIALIZATION_OPTIMIZATION_P instead. */ -int flag_optimize_sci = 1; - -/* When nonzero, use offset tables for virtual method calls - in order to improve binary compatibility. */ -int flag_indirect_dispatch = 0; +/* FIXME: Make this work with gimplify. */ +/* int flag_optimize_sci = 0; */ -/* When zero, don't generate runtime array store checks. */ -int flag_store_check = 1; +/* Don't attempt to verify invocations. */ +int flag_verify_invocations = 0; /* When nonzero, print extra version information. */ -static int version_flag = 0; - -/* Set nonzero if the user specified -finline-functions on the command - line. */ -int flag_really_inline = 0; +static int v_flag = 0; JCF *current_jcf; @@ -199,8 +114,7 @@ static int dependency_tracking = 0; #define DEPEND_TARGET_SET 4 #define DEPEND_FILE_ALREADY_SET 8 -struct language_function GTY(()) -{ +struct GTY(()) language_function { int unused; }; @@ -218,45 +132,43 @@ struct language_function GTY(()) #define LANG_HOOKS_POST_OPTIONS java_post_options #undef LANG_HOOKS_PARSE_FILE #define LANG_HOOKS_PARSE_FILE java_parse_file -#undef LANG_HOOKS_UNSAFE_FOR_REEVAL -#define LANG_HOOKS_UNSAFE_FOR_REEVAL java_unsafe_for_reeval -#undef LANG_HOOKS_MARK_ADDRESSABLE -#define LANG_HOOKS_MARK_ADDRESSABLE java_mark_addressable -#undef LANG_HOOKS_EXPAND_EXPR -#define LANG_HOOKS_EXPAND_EXPR java_expand_expr -#undef LANG_HOOKS_TRUTHVALUE_CONVERSION -#define LANG_HOOKS_TRUTHVALUE_CONVERSION java_truthvalue_conversion #undef LANG_HOOKS_DUP_LANG_SPECIFIC_DECL #define LANG_HOOKS_DUP_LANG_SPECIFIC_DECL java_dup_lang_specific_decl #undef LANG_HOOKS_DECL_PRINTABLE_NAME #define LANG_HOOKS_DECL_PRINTABLE_NAME lang_printable_name #undef LANG_HOOKS_PRINT_ERROR_FUNCTION #define LANG_HOOKS_PRINT_ERROR_FUNCTION java_print_error_function -#undef LANG_HOOKS_CAN_USE_BIT_FIELDS_P -#define LANG_HOOKS_CAN_USE_BIT_FIELDS_P java_can_use_bit_fields_p #undef LANG_HOOKS_TYPE_FOR_MODE #define LANG_HOOKS_TYPE_FOR_MODE java_type_for_mode #undef LANG_HOOKS_TYPE_FOR_SIZE #define LANG_HOOKS_TYPE_FOR_SIZE java_type_for_size -#undef LANG_HOOKS_SIGNED_TYPE -#define LANG_HOOKS_SIGNED_TYPE java_signed_type -#undef LANG_HOOKS_UNSIGNED_TYPE -#define LANG_HOOKS_UNSIGNED_TYPE java_unsigned_type -#undef LANG_HOOKS_SIGNED_OR_UNSIGNED_TYPE -#define LANG_HOOKS_SIGNED_OR_UNSIGNED_TYPE java_signed_or_unsigned_type - -#undef LANG_HOOKS_TREE_INLINING_WALK_SUBTREES -#define LANG_HOOKS_TREE_INLINING_WALK_SUBTREES java_tree_inlining_walk_subtrees +#undef LANG_HOOKS_CLASSIFY_RECORD +#define LANG_HOOKS_CLASSIFY_RECORD java_classify_record #undef LANG_HOOKS_TREE_DUMP_DUMP_TREE_FN #define LANG_HOOKS_TREE_DUMP_DUMP_TREE_FN java_dump_tree +#undef LANG_HOOKS_GIMPLIFY_EXPR +#define LANG_HOOKS_GIMPLIFY_EXPR java_gimplify_expr + #undef LANG_HOOKS_DECL_OK_FOR_SIBCALL #define LANG_HOOKS_DECL_OK_FOR_SIBCALL java_decl_ok_for_sibcall +#undef LANG_HOOKS_SET_DECL_ASSEMBLER_NAME +#define LANG_HOOKS_SET_DECL_ASSEMBLER_NAME java_mangle_decl + +#undef LANG_HOOKS_ATTRIBUTE_TABLE +#define LANG_HOOKS_ATTRIBUTE_TABLE java_attribute_table + +#undef LANG_HOOKS_EH_PERSONALITY +#define LANG_HOOKS_EH_PERSONALITY java_eh_personality + +#undef LANG_HOOKS_EH_USE_CXA_END_CLEANUP +#define LANG_HOOKS_EH_USE_CXA_END_CLEANUP true + /* Each front end provides its own. */ -const struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER; +struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER; /* * process java-specific compiler command-line options @@ -265,33 +177,10 @@ const struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER; static int java_handle_option (size_t scode, const char *arg, int value) { - const struct cl_option *option = &cl_options[scode]; enum opt_code code = (enum opt_code) scode; - /* Ignore file names. */ - if (code == N_OPTS) - return 1; - - if (arg == NULL && (option->flags & (CL_JOINED | CL_SEPARATE))) - { - /* These can take an empty argument. */ - if (code == OPT_fassume_compiled_ - || code == OPT_fclasspath_ - || code == OPT_fCLASSPATH_ - || code == OPT_fbootclasspath_) - arg = ""; - else - { - error ("missing argument to \"-%s\"", option->opt_text); - return 1; - } - } - switch (code) { - default: - return 0; - case OPT_I: jcf_path_include_arg (arg); break; @@ -301,13 +190,14 @@ java_handle_option (size_t scode, const char *arg, int value) dependency_tracking |= DEPEND_ENABLE; break; - case OPT_MD: + case OPT_MD_: jcf_dependency_init (1); dependency_tracking |= DEPEND_SET_FILE | DEPEND_ENABLE; break; case OPT_MF: jcf_dependency_set_dep_file (arg); + dependency_tracking |= DEPEND_FILE_ALREADY_SET; break; case OPT_MM: @@ -315,7 +205,7 @@ java_handle_option (size_t scode, const char *arg, int value) dependency_tracking |= DEPEND_ENABLE; break; - case OPT_MMD: + case OPT_MMD_: jcf_dependency_init (0); dependency_tracking |= DEPEND_SET_FILE | DEPEND_ENABLE; break; @@ -331,31 +221,25 @@ java_handle_option (size_t scode, const char *arg, int value) case OPT_Wall: flag_wall = value; - flag_redundant = value; - flag_extraneous_semicolon = value; /* When -Wall given, enable -Wunused. We do this because the C compiler does it, and people expect it. */ - set_Wunused (value); + warn_unused = value; break; - case OPT_Wdeprecated: - flag_deprecated = value; + case OPT_fenable_assertions_: + add_enable_assert (arg, value); break; - case OPT_Wextraneous_semicolon: - flag_extraneous_semicolon = value; + case OPT_fenable_assertions: + add_enable_assert ("", value); break; - case OPT_Wout_of_date: - flag_newer = value; + case OPT_fdisable_assertions_: + add_enable_assert (arg, !value); break; - case OPT_Wredundant_modifiers: - flag_redundant = value; - break; - - case OPT_fassert: - flag_assert = value; + case OPT_fdisable_assertions: + add_enable_assert ("", !value); break; case OPT_fassume_compiled_: @@ -370,10 +254,7 @@ java_handle_option (size_t scode, const char *arg, int value) jcf_path_bootclasspath_arg (arg); break; - case OPT_fcheck_references: - flag_check_references = value; - break; - + case OPT_faux_classpath: case OPT_fclasspath_: case OPT_fCLASSPATH_: jcf_path_classpath_arg (arg); @@ -384,71 +265,34 @@ java_handle_option (size_t scode, const char *arg, int value) break; case OPT_fdump_: - if (!dump_switch_p (option->opt_text + strlen ("f"))) + if (!dump_switch_p (arg)) return 0; break; - case OPT_femit_class_file: - case OPT_femit_class_files: - flag_emit_class_files = value; - break; - case OPT_fencoding_: - current_encoding = arg; + /* Nothing. */ break; case OPT_fextdirs_: jcf_path_extdirs_arg (arg); break; - case OPT_ffilelist_file: - flag_filelist_file = value; - break; - - case OPT_fforce_classes_archive_check: - flag_force_classes_archive_check = value; - break; - - case OPT_fhash_synchronization: - flag_hash_synchronization = value; - break; - - case OPT_findirect_dispatch: - flag_indirect_dispatch = value; - break; - - case OPT_finline_functions: - flag_inline_functions = value; - flag_really_inline = value; - break; - - case OPT_fjni: - flag_jni = value; - break; - - case OPT_foptimize_static_class_initialization: - flag_optimize_sci = value; - break; - case OPT_foutput_class_dir_: - jcf_write_base_directory = arg; - break; - - case OPT_fstore_check: - flag_store_check = value; - break; - - case OPT_fuse_boehm_gc: - flag_use_boehm_gc = value; - break; - - case OPT_fuse_divide_subroutine: - flag_use_divide_subroutine = value; + /* FIXME: remove; this is handled by ecj1 now. */ break; case OPT_version: - version_flag = 1; + v_flag = 1; break; + + case OPT_fsource_filename_: + java_read_sourcefilenames (arg); + break; + + default: + if (cl_options[code].flags & CL_Java) + break; + gcc_unreachable (); } return 1; @@ -460,22 +304,15 @@ FILE *finput; static bool java_init (void) { -#if 0 - extern int flag_minimal_debug; - flag_minimal_debug = 0; -#endif + /* FIXME: Indirect dispatch isn't yet compatible with static class + init optimization. */ + if (flag_indirect_dispatch) + always_initialize_class_p = true; - if (flag_inline_functions) - flag_inline_trees = 1; + if (!flag_indirect_dispatch) + flag_indirect_classes = false; - /* Force minimum function alignment if g++ uses the least significant - bit of function pointers to store the virtual bit. This is required - to keep vtables compatible. */ - if (TARGET_PTRMEMFUNC_VBIT_LOCATION == ptrmemfunc_vbit_in_pfn - && force_align_functions_log < 1) - force_align_functions_log = 1; - - jcf_path_seal (version_flag); + jcf_path_seal (v_flag); java_init_decl_processing (); @@ -512,22 +349,25 @@ put_decl_string (const char *str, int len) if (decl_buf == NULL) { decl_buflen = len + 100; - decl_buf = xmalloc (decl_buflen); + decl_buf = XNEWVEC (char, decl_buflen); } else { decl_buflen *= 2; - decl_buf = xrealloc (decl_buf, decl_buflen); + decl_buf = XRESIZEVAR (char, decl_buf, decl_buflen); } } strcpy (decl_buf + decl_bufpos, str); decl_bufpos += len; } -/* Append to decl_buf a printable name for NODE. */ +/* Append to decl_buf a printable name for NODE. + Depending on VERBOSITY, more information about NODE + is printed. Read the comments of decl_printable_name in + langhooks.h for more. */ static void -put_decl_node (tree node) +put_decl_node (tree node, int verbosity) { int was_pointer = 0; if (TREE_CODE (node) == POINTER_TYPE) @@ -535,22 +375,36 @@ put_decl_node (tree node) node = TREE_TYPE (node); was_pointer = 1; } - if (TREE_CODE_CLASS (TREE_CODE (node)) == 'd' - && DECL_NAME (node) != NULL_TREE) + if (DECL_P (node) && DECL_NAME (node) != NULL_TREE) { if (TREE_CODE (node) == FUNCTION_DECL) { + if (verbosity == 0 && DECL_NAME (node)) + /* We have been instructed to just print the bare name + of the function. */ + { + put_decl_node (DECL_NAME (node), 0); + return; + } + /* We want to print the type the DECL belongs to. We don't do that when we handle constructors. */ if (! DECL_CONSTRUCTOR_P (node) - && ! DECL_ARTIFICIAL (node) && DECL_CONTEXT (node)) + && ! DECL_ARTIFICIAL (node) && DECL_CONTEXT (node) + /* We want to print qualified DECL names only + if verbosity is higher than 1. */ + && verbosity >= 1) { - put_decl_node (TYPE_NAME (DECL_CONTEXT (node))); + put_decl_node (TYPE_NAME (DECL_CONTEXT (node)), + verbosity); put_decl_string (".", 1); } if (! DECL_CONSTRUCTOR_P (node)) - put_decl_node (DECL_NAME (node)); - if (TREE_TYPE (node) != NULL_TREE) + put_decl_node (DECL_NAME (node), verbosity); + if (TREE_TYPE (node) != NULL_TREE + /* We want to print function parameters only if verbosity + is higher than 2. */ + && verbosity >= 2) { int i = 0; tree args = TYPE_ARG_TYPES (TREE_TYPE (node)); @@ -561,20 +415,22 @@ put_decl_node (tree node) { if (i > 0) put_decl_string (",", 1); - put_decl_node (TREE_VALUE (args)); + put_decl_node (TREE_VALUE (args), verbosity); } put_decl_string (")", 1); } } else - put_decl_node (DECL_NAME (node)); + put_decl_node (DECL_NAME (node), verbosity); } - else if (TREE_CODE_CLASS (TREE_CODE (node)) == 't' - && TYPE_NAME (node) != NULL_TREE) + else if (TYPE_P (node) && TYPE_NAME (node) != NULL_TREE) { - if (TREE_CODE (node) == RECORD_TYPE && TYPE_ARRAY_P (node)) + if (TREE_CODE (node) == RECORD_TYPE && TYPE_ARRAY_P (node) + /* Print detailed array information only if verbosity is higher + than 2. */ + && verbosity >= 2) { - put_decl_node (TYPE_ARRAY_ELEMENT (node)); + put_decl_node (TYPE_ARRAY_ELEMENT (node), verbosity); put_decl_string("[]", 2); } else if (node == promoted_byte_type_node) @@ -588,7 +444,7 @@ put_decl_node (tree node) else if (node == void_type_node && was_pointer) put_decl_string ("null", 4); else - put_decl_node (TYPE_NAME (node)); + put_decl_node (TYPE_NAME (node), verbosity); } else if (TREE_CODE (node) == IDENTIFIER_NODE) put_decl_string (IDENTIFIER_POINTER (node), IDENTIFIER_LENGTH (node)); @@ -602,27 +458,14 @@ put_decl_node (tree node) which is also called directly by java_print_error_function. */ const char * -lang_printable_name (tree decl, int v __attribute__ ((__unused__))) +lang_printable_name (tree decl, int v) { decl_bufpos = 0; - put_decl_node (decl); + put_decl_node (decl, v); put_decl_string ("", 1); return decl_buf; } -/* Does the same thing that lang_printable_name, but add a leading - space to the DECL name string -- With Leading Space. */ - -const char * -lang_printable_name_wls (tree decl, int v __attribute__ ((__unused__))) -{ - decl_bufpos = 1; - put_decl_node (decl); - put_decl_string ("", 1); - decl_buf [0] = ' '; - return decl_buf; -} - /* Print on stderr the current class and method context. This function is the value of the hook print_error_function. */ @@ -630,7 +473,8 @@ static GTY(()) tree last_error_function_context; static GTY(()) tree last_error_function; static void java_print_error_function (diagnostic_context *context ATTRIBUTE_UNUSED, - const char *file) + const char *file, + diagnostic_info *diagnostic ATTRIBUTE_UNUSED) { /* Don't print error messages with bogus function prototypes. */ if (inhibit_error_function_printing) @@ -643,7 +487,7 @@ java_print_error_function (diagnostic_context *context ATTRIBUTE_UNUSED, fprintf (stderr, "%s: ", file); last_error_function_context = DECL_CONTEXT (current_function_decl); - fprintf (stderr, "In class `%s':\n", + fprintf (stderr, "In class '%s':\n", lang_printable_name (last_error_function_context, 0)); } if (last_error_function != current_function_decl) @@ -656,8 +500,8 @@ java_print_error_function (diagnostic_context *context ATTRIBUTE_UNUSED, else { const char *name = lang_printable_name (current_function_decl, 2); - fprintf (stderr, "In %s `%s':\n", - (DECL_CONSTRUCTOR_P (current_function_decl) ? "constructor" + fprintf (stderr, "In %s '%s':\n", + (DECL_CONSTRUCTOR_P (current_function_decl) ? "constructor" : "method"), name); } @@ -674,13 +518,15 @@ java_print_error_function (diagnostic_context *context ATTRIBUTE_UNUSED, 2, function prototypes are fully resolved and can be printed when reporting errors. */ -void lang_init_source (int level) +void +lang_init_source (int level) { inhibit_error_function_printing = (level == 1); } -static int -java_init_options (void) +static unsigned int +java_init_options (unsigned int argc ATTRIBUTE_UNUSED, + const char **argv ATTRIBUTE_UNUSED) { flag_bounds_check = 1; flag_exceptions = 1; @@ -692,17 +538,12 @@ java_init_options (void) /* In Java arithmetic overflow always wraps around. */ flag_wrapv = 1; + /* Java requires left-to-right evaluation of subexpressions. */ + flag_evaluation_order = 1; + jcf_path_init (); - return 0; -} - -static bool -java_can_use_bit_fields_p (void) -{ - /* The bit-field optimizations cause problems when generating class - files. */ - return flag_emit_class_files ? false : true; + return CL_Java; } /* Post-switch processing. */ @@ -711,17 +552,25 @@ java_post_options (const char **pfilename) { const char *filename = *pfilename; - /* Use tree inlining if possible. Function instrumentation is only - done in the RTL level, so we disable tree inlining. */ - if (! flag_instrument_function_entry_exit) + /* Excess precision other than "fast" requires front-end + support. */ + if (flag_excess_precision_cmdline == EXCESS_PRECISION_STANDARD + && TARGET_FLT_EVAL_METHOD_NON_DEFAULT) + sorry ("-fexcess-precision=standard for Java"); + flag_excess_precision_cmdline = EXCESS_PRECISION_FAST; + + /* An absolute requirement: if we're not using indirect dispatch, we + must always verify everything. */ + if (! flag_indirect_dispatch) + flag_verify_invocations = true; + + if (flag_reduced_reflection) { - if (!flag_no_inline) - flag_no_inline = 1; - if (flag_inline_functions) - { - flag_inline_trees = 2; - flag_inline_functions = 0; - } + if (flag_indirect_dispatch) + error ("-findirect-dispatch is incompatible " + "with -freduced-reflection"); + if (flag_jni) + error ("-fjni is incompatible with -freduced-reflection"); } /* Open input file. */ @@ -738,7 +587,7 @@ java_post_options (const char **pfilename) { if (dependency_tracking) { - char *dot; + const char *dot; /* If the target is set and the output filename is set, then there's no processing to do here. Otherwise we must @@ -751,7 +600,7 @@ java_post_options (const char **pfilename) error ("couldn't determine target name for dependency tracking"); else { - char *buf = xmalloc (dot - filename + + char *buf = XNEWVEC (char, dot - filename + 3 + sizeof (TARGET_OBJECT_SUFFIX)); strncpy (buf, filename, dot - filename); @@ -761,8 +610,6 @@ java_post_options (const char **pfilename) target name here. */ if ((dependency_tracking & DEPEND_TARGET_SET)) ; /* Nothing. */ - else if (flag_emit_class_files) - jcf_dependency_set_target (NULL); else { strcpy (buf + (dot - filename), TARGET_OBJECT_SUFFIX); @@ -784,6 +631,8 @@ java_post_options (const char **pfilename) } } } + linemap_add (line_table, LC_ENTER, false, filename, 0); + linemap_add (line_table, LC_RENAME, false, "", 0); /* Initialize the compiler back end. */ return false; @@ -811,84 +660,19 @@ decl_constant_value (tree decl) return decl; } -/* Walk the language specific tree nodes during inlining. */ - -static tree -java_tree_inlining_walk_subtrees (tree *tp ATTRIBUTE_UNUSED, - int *subtrees ATTRIBUTE_UNUSED, - walk_tree_fn func ATTRIBUTE_UNUSED, - void *data ATTRIBUTE_UNUSED, - void *htab ATTRIBUTE_UNUSED) -{ - enum tree_code code; - tree result; - -#define WALK_SUBTREE(NODE) \ - do \ - { \ - result = walk_tree (&(NODE), func, data, htab); \ - if (result) \ - return result; \ - } \ - while (0) - - tree t = *tp; - if (!t) - return NULL_TREE; - - code = TREE_CODE (t); - switch (code) - { - case BLOCK: - if (BLOCK_EXPR_BODY (t)) - { - tree *prev = &BLOCK_EXPR_BODY (*tp); - while (*prev) - { - WALK_SUBTREE (*prev); - prev = &TREE_CHAIN (*prev); - } - } - return NULL_TREE; - break; - - default: - return NULL_TREE; - } -} - -/* Called from unsafe_for_reeval. */ -static int -java_unsafe_for_reeval (tree t) -{ - switch (TREE_CODE (t)) - { - case BLOCK: - /* Our expander tries to expand the variables twice. Boom. */ - if (BLOCK_EXPR_DECLS (t) != NULL) - return 2; - return unsafe_for_reeval (BLOCK_EXPR_BODY (t)); - - default: - break; - } - - return -1; -} - /* Every call to a static constructor has an associated boolean variable which is in the outermost scope of the calling method. This variable is used to avoid multiple calls to the static - constructor for each class. + constructor for each class. It looks something like this: foo () { boolean dummy = OtherClass.is_initialized; - + ... - + if (! dummy) OtherClass.initialize(); @@ -911,12 +695,11 @@ merge_init_test_initialization (void **entry, void *x) splay_tree decl_map = (splay_tree)x; splay_tree_node n; tree *init_test_decl; - + /* See if we have remapped this declaration. If we haven't there's a bug in the inliner. */ n = splay_tree_lookup (decl_map, (splay_tree_key) ite->value); - if (! n) - abort (); + gcc_assert (n); /* Create a new entry for the class and its remapped boolean variable. If we already have a mapping for this class we've @@ -926,6 +709,24 @@ merge_init_test_initialization (void **entry, void *x) if (!*init_test_decl) *init_test_decl = (tree)n->value; + /* This fixes a weird case. + + The front end assumes that once we have called a method that + initializes some class, we can assume the class is initialized. It + does this by setting the DECL_INITIAL of the init_test_decl for that + class, and no initializations are emitted for that class. + + However, what if the method that is supposed to do the initialization + is itself inlined in the caller? When expanding the called method + we'll assume that the class initialization has already been done, + because the DECL_INITIAL of the init_test_decl is set. + + To fix this we remove the DECL_INITIAL (in the caller scope) of all + the init_test_decls corresponding to classes initialized by the + inlined method. This makes the caller no longer assume that the + method being inlined does any class initializations. */ + DECL_INITIAL (*init_test_decl) = NULL; + return true; } @@ -935,7 +736,7 @@ merge_init_test_initialization (void **entry, void *x) void java_inlining_merge_static_initializers (tree fn, void *decl_map) { - htab_traverse + htab_traverse (DECL_FUNCTION_INIT_TEST_TABLE (fn), merge_init_test_initialization, decl_map); } @@ -951,16 +752,14 @@ inline_init_test_initialization (void **entry, void *x) { struct treetreehash_entry *ite = (struct treetreehash_entry *) *entry; splay_tree decl_map = (splay_tree)x; - - tree h = java_treetreehash_find + + tree h = java_treetreehash_find (DECL_FUNCTION_INIT_TEST_TABLE (current_function_decl), ite->key); if (! h) return true; - splay_tree_insert (decl_map, (splay_tree_key) ite->value, (splay_tree_value) h); - return true; } @@ -972,7 +771,7 @@ inline_init_test_initialization (void **entry, void *x) void java_inlining_map_static_initializers (tree fn, void *decl_map) { - htab_traverse + htab_traverse (DECL_FUNCTION_INIT_TEST_TABLE (fn), inline_init_test_initialization, decl_map); } @@ -992,19 +791,12 @@ dump_compound_expr (dump_info_p di, tree t) dump_compound_expr (di, TREE_OPERAND (t, i)); break; - case EXPR_WITH_FILE_LOCATION: - { - tree wfl_node = EXPR_WFL_NODE (TREE_OPERAND (t, i)); - dump_child ("expr", wfl_node); - break; - } - default: dump_child ("expr", TREE_OPERAND (t, i)); } } } - + static bool java_dump_tree (void *dump_info, tree t) { @@ -1024,8 +816,6 @@ java_dump_tree (void *dump_info, tree t) dump_string (di, "extern"); else dump_string (di, "static"); - if (DECL_LANG_SPECIFIC (t)) - dump_child ("body", DECL_FUNCTION_BODY (t)); if (DECL_LANG_SPECIFIC (t) && !dump_flag (di, TDF_SLIM, t)) dump_child ("inline body", DECL_SAVED_TREE (t)); return true; @@ -1042,16 +832,6 @@ java_dump_tree (void *dump_info, tree t) dump_child ("label", TREE_OPERAND (t, 0)); return true; - case LABELED_BLOCK_EXPR: - dump_child ("label", TREE_OPERAND (t, 0)); - dump_child ("block", TREE_OPERAND (t, 1)); - return true; - - case EXIT_BLOCK_EXPR: - dump_child ("block", TREE_OPERAND (t, 0)); - dump_child ("val", TREE_OPERAND (t, 1)); - return true; - case BLOCK: if (BLOCK_EXPR_BODY (t)) { @@ -1062,7 +842,7 @@ java_dump_tree (void *dump_info, tree t) dump_child ("var", local); local = next; } - + { tree block = BLOCK_EXPR_BODY (t); dump_child ("body", block); @@ -1070,7 +850,7 @@ java_dump_tree (void *dump_info, tree t) } } return true; - + case COMPOUND_EXPR: if (!dump_flag (di, TDF_SLIM, t)) return false; @@ -1089,9 +869,38 @@ java_dump_tree (void *dump_info, tree t) SecurityManager.getClassContext(). */ static bool -java_decl_ok_for_sibcall (tree decl) +java_decl_ok_for_sibcall (const_tree decl) +{ + return (decl != NULL && DECL_CONTEXT (decl) == output_class + && !DECL_UNINLINABLE (decl)); +} + +static enum classify_record +java_classify_record (tree type) +{ + if (! CLASS_P (type)) + return RECORD_IS_STRUCT; + + /* ??? GDB does not support DW_TAG_interface_type as of December, + 2007. Re-enable this at a later time. */ + if (0 && CLASS_INTERFACE (TYPE_NAME (type))) + return RECORD_IS_INTERFACE; + + return RECORD_IS_CLASS; +} + +static GTY(()) tree java_eh_personality_decl; + +static tree +java_eh_personality (void) { - return decl != NULL && DECL_CONTEXT (decl) == current_class; + if (!java_eh_personality_decl) + java_eh_personality_decl + = build_personality_function (USING_SJLJ_EXCEPTIONS + ? "__gcj_personality_sj0" + : "__gcj_personality_v0"); + + return java_eh_personality_decl; } #include "gt-java-lang.h"