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"