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.
+the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA.
Java and all Java-based marks are trademarks or registered trademarks
of Sun Microsystems, Inc. in the United States and other countries.
static tree check_local_unnamed_variable (tree, tree, tree);
static void parse_version (void);
-/* Used when computing the ABI version. */
-#define GCJ_BINARYCOMPAT_ADDITION 5
-/* The version of the BC ABI that we generate. At the moment we are
- compatible with what shipped in GCC 4.0. This must be kept in sync
- with parse_version(), libgcj, and reality (if the BC format
- changes, this must change. */
+/* The following ABI flags are used in the high-order bits of the version
+ ID field. The version ID number itself should never be larger than
+ 0xfffff, so it should be safe to use top 12 bits for these flags. */
+
+#define FLAG_BINARYCOMPAT_ABI (1<<31) /* Class is built with the BC-ABI. */
+
+#define FLAG_BOOTSTRAP_LOADER (1<<30) /* Used when defining a class that
+ should be loaded by the bootstrap
+ loader. */
+
+/* If an ABI change is made within a GCC release series, rendering current
+ binaries incompatible with the old runtimes, this number can be set to
+ enforce the compatibility rules. */
+#define MINOR_BINARYCOMPAT_ABI_VERSION 0
+
+/* The runtime may recognize a variety of BC ABIs (objects generated by
+ different version of gcj), but will probably always require strict
+ matching for the ordinary (C++) ABI. */
+
+/* The version ID of the BC ABI that we generate. This must be kept in
+ sync with parse_version(), libgcj, and reality (if the BC format changes,
+ this must change). */
#define GCJ_CURRENT_BC_ABI_VERSION \
- (4 * 10000 + 0 * 10 + GCJ_BINARYCOMPAT_ADDITION)
+ (4 * 100000 + 0 * 1000 + MINOR_BINARYCOMPAT_ABI_VERSION)
/* The ABI version number. */
tree gcj_abi_version;
static GTY(()) tree pending_local_decls;
+/* The decl for "_Jv_ResolvePoolEntry". */
+tree soft_resolvepoolentry_node;
+
#if defined(DEBUG_JAVA_BINDING_LEVELS)
int binding_depth = 0;
int is_class_level = 0;
tree decl_type = TREE_TYPE (decl);
tree tmp;
- if (debug_variable_p (decl))
- abort ();
+ gcc_assert (! debug_variable_p (decl));
for (tmp = TREE_VEC_ELT (decl_map, index);
tmp != NULL_TREE;
&& TREE_CODE (decl_type) == POINTER_TYPE)))
{
tree src = build1 (NOP_EXPR, tmp_type, decl);
- if (LOCAL_VAR_OUT_OF_SCOPE_P (tmp))
- abort ();
+ gcc_assert (! LOCAL_VAR_OUT_OF_SCOPE_P (tmp));
java_add_stmt (build2 (MODIFY_EXPR, tmp_type, tmp, src));
}
}
{
tree decl_type = TREE_TYPE (decl);
- if (LOCAL_VAR_OUT_OF_SCOPE_P (decl))
- abort ();
+ gcc_assert (! LOCAL_VAR_OUT_OF_SCOPE_P (decl));
/* Use the same decl for all integer types <= 32 bits. This is
necessary because sometimes a value is stored as (for example)
int index = DECL_LOCAL_SLOT_NUMBER (var_decl);
tree base_decl = TREE_VEC_ELT (base_decl_map, index);
- if (! base_decl)
- abort ();
-
+ gcc_assert (base_decl);
if (! want_lvalue)
base_decl = build1 (NOP_EXPR, decl_type, base_decl);
TYPE_MAX_VALUE (type) = copy_node (in_max);
TREE_TYPE (TYPE_MAX_VALUE (type)) = type;
TYPE_PRECISION (type) = TYPE_PRECISION (int_type_node);
+ TYPE_STRING_FLAG (type) = TYPE_STRING_FLAG (actual_type);
layout_type (type);
pushdecl (build_decl (TYPE_DECL, get_identifier (name), type));
return type;
TREE_PUBLIC (decl) = 1;
if (library_name)
SET_DECL_ASSEMBLER_NAME (decl, get_identifier (library_name));
- make_decl_rtl (decl);
pushdecl (decl);
DECL_BUILT_IN_CLASS (decl) = cl;
DECL_FUNCTION_CODE (decl) = function_code;
++p;
}
- /* Implicit in this computation is the idea that we won't break the
- old-style binary ABI in a sub-minor release (e.g., from 4.0.0 to
- 4.0.1). */
- abi_version = 10000 * major + 10 * minor;
- /* It is helpful to distinguish BC ABI from ordinary ABI at this
- level, since at some point we will recognize a variety of BC ABIs
- (objects generated by different version of gcj), but will
- probably always require strict matching for ordinary ABI. */
if (flag_indirect_dispatch)
- abi_version = GCJ_CURRENT_BC_ABI_VERSION;
+ {
+ abi_version = GCJ_CURRENT_BC_ABI_VERSION;
+ abi_version |= FLAG_BINARYCOMPAT_ABI;
+ }
+ else /* C++ ABI */
+ {
+ /* Implicit in this computation is the idea that we won't break the
+ old-style binary ABI in a sub-minor release (e.g., from 4.0.0 to
+ 4.0.1). */
+ abi_version = 100000 * major + 1000 * minor;
+ }
+ if (flag_bootstrap_classes)
+ abi_version |= FLAG_BOOTSTRAP_LOADER;
gcj_abi_version = build_int_cstu (ptr_type_node, abi_version);
}
initializations of __FUNCTION__ and __PRETTY_FUNCTION__. */
short_array_type_node = build_prim_array_type (short_type_node, 200);
#endif
- char_type_node = make_node (CHAR_TYPE);
+ char_type_node = make_node (INTEGER_TYPE);
+ TYPE_STRING_FLAG (char_type_node) = 1;
TYPE_PRECISION (char_type_node) = 16;
fixup_unsigned_type (char_type_node);
pushdecl (build_decl (TYPE_DECL, get_identifier ("char"), char_type_node));
build_function_type (void_type_node,
t),
0, NOT_BUILT_IN, NULL, NULL_TREE);
-
+ t = tree_cons (NULL_TREE, class_ptr_type,
+ tree_cons (NULL_TREE, int_type_node, endlink));
+ soft_resolvepoolentry_node
+ = builtin_function ("_Jv_ResolvePoolEntry",
+ build_function_type (ptr_type_node, t),
+ 0,NOT_BUILT_IN, NULL, NULL_TREE);
+ DECL_IS_PURE (soft_resolvepoolentry_node) = 1;
throw_node = builtin_function ("_Jv_Throw",
build_function_type (void_type_node, t),
0, NOT_BUILT_IN, NULL, NULL_TREE);
TREE_THIS_VOLATILE (soft_nullpointer_node) = 1;
TREE_SIDE_EFFECTS (soft_nullpointer_node) = 1;
+ soft_abstractmethod_node
+ = builtin_function ("_Jv_ThrowAbstractMethodError",
+ build_function_type (void_type_node, endlink),
+ 0, NOT_BUILT_IN, NULL, NULL_TREE);
+ /* Mark soft_abstractmethod_node as a `noreturn' function with side
+ effects. */
+ TREE_THIS_VOLATILE (soft_abstractmethod_node) = 1;
+ TREE_SIDE_EFFECTS (soft_abstractmethod_node) = 1;
+
+ soft_nosuchfield_node
+ = builtin_function ("_Jv_ThrowNoSuchFieldError",
+ build_function_type (void_type_node, endlink),
+ 0, NOT_BUILT_IN, NULL, NULL_TREE);
+ /* Mark soft_nosuchfield_node as a `noreturn' function with side
+ effects. */
+ TREE_THIS_VOLATILE (soft_nosuchfield_node) = 1;
+ TREE_SIDE_EFFECTS (soft_nosuchfield_node) = 1;
+
t = tree_cons (NULL_TREE, class_ptr_type,
tree_cons (NULL_TREE, object_ptr_type_node, endlink));
soft_checkcast_node
build_function_type (void_type_node, t),
0, NOT_BUILT_IN, NULL, NULL_TREE);
+ t = tree_cons (NULL_TREE, object_ptr_type_node, endlink);
+ soft_unwrapjni_node
+ = builtin_function ("_Jv_UnwrapJNIweakReference",
+ build_function_type (object_ptr_type_node, t),
+ 0, NOT_BUILT_IN, NULL, NULL_TREE);
+
t = tree_cons (NULL_TREE, int_type_node,
tree_cons (NULL_TREE, int_type_node, endlink));
soft_idiv_node
eh_personality_libfunc = init_one_libfunc (USING_SJLJ_EXCEPTIONS
? "__gcj_personality_sj0"
: "__gcj_personality_v0");
+ default_init_unwind_resume_libfunc ();
lang_eh_runtime_type = do_nothing;
}
/* Similar to `lookup_name' but look only at current binding level and
- the previous one if its the parameter level. */
+ the previous one if it's the parameter level. */
static tree
lookup_name_current_level (tree name)
/* error_mark_node is 0 for a while during initialization! */
{
t = 0;
- error ("%J'%D' used prior to declaration", x, x);
+ error ("%q+D used prior to declaration", x);
}
/* If we're naming a hitherto-unnamed type, set its TYPE_NAME
if (DECL_INITIAL (label) == 0)
{
- error ("%Jlabel '%D' used but not defined", label, label);
+ error ("label %q+D used but not defined", label);
/* Avoid crashing later. */
define_label (input_location, DECL_NAME (label));
}
else if (warn_unused[UNUSED_LABEL] && !TREE_USED (label))
- warning (0, "%Jlabel '%D' defined but not used", label, label);
+ warning (0, "label %q+D defined but not used", label);
IDENTIFIER_LABEL_VALUE (DECL_NAME (label)) = 0;
/* Put the labels into the "variables" of the
while (current_binding_level->start_pc > start_pc)
{
if (pedantic && current_binding_level->start_pc > start_pc)
- warning (0, "%JIn %D: overlapped variable and exception ranges at %d",
- current_function_decl, current_function_decl,
+ warning (0, "In %+D: overlapped variable and exception ranges at %d",
+ current_function_decl,
current_binding_level->start_pc);
poplevel (1, 0, 0);
}
{
tree decl = TREE_VEC_ELT (decl_map, slot);
DECL_NAME (decl) = name;
- SET_DECL_ASSEMBLER_NAME (decl, name);
if (TREE_CODE (decl) != PARM_DECL || TREE_TYPE (decl) != type)
warning (0, "bad type in parameter debug info");
}
tree decl = build_decl (VAR_DECL, name, type);
if (end_pc > DECL_CODE_LENGTH (current_function_decl))
{
- warning (0, "%Jbad PC range for debug info for local '%D'",
- decl, decl);
+ warning (0, "bad PC range for debug info for local %q+D",
+ decl);
end_pc = DECL_CODE_LENGTH (current_function_decl);
}
sprintf (buffer, "ARG_%d", arg_i);
DECL_NAME (parm) = get_identifier (buffer);
}
- SET_DECL_ASSEMBLER_NAME (parm, DECL_NAME (parm));
}
}
}
{
tree parm_name = NULL_TREE, parm_decl;
tree parm_type = TREE_VALUE (tem);
- if (i >= DECL_MAX_LOCALS (fndecl))
- abort ();
+ gcc_assert (i < DECL_MAX_LOCALS (fndecl));
parm_decl = build_decl (PARM_DECL, parm_name, parm_type);
DECL_CONTEXT (parm_decl) = fndecl;
attach_init_test_initialization_flags, block_body);
}
- flag_unit_at_a_time = 0;
finish_method (fndecl);
if (! flag_unit_at_a_time)
/* If we've already constructed DECL_RTL, give encode_section_info
a second chance, now that we've changed the flags. */
+ /* ??? Ideally, we'd have flag_unit_at_a_time set, and not have done
+ anything that would have referenced DECL_RTL so far. But at the
+ moment we force flag_unit_at_a_time off due to excessive memory
+ consumption when compiling large jar files. Which probably means
+ that we need to re-order how we process jar files... */
if (DECL_RTL_SET_P (decl))
make_decl_rtl (decl);
}
+/* Given appropriate target support, G++ will emit hidden aliases for native
+ methods. Using this hidden name is required for proper operation of
+ _Jv_Method::ncode, but it doesn't hurt to use it everywhere. Look for
+ proper target support, then mark the method for aliasing. */
+
+static void
+java_mark_cni_decl_local (tree decl)
+{
+ /* Setting DECL_LOCAL_CNI_METHOD_P changes the behavior of the mangler.
+ We expect that we should not yet have referenced this decl in a
+ context that requires it. Check this invariant even if we don't have
+ support for hidden aliases. */
+ gcc_assert (!DECL_ASSEMBLER_NAME_SET_P (decl));
+
+#if !defined(HAVE_GAS_HIDDEN) || !defined(ASM_OUTPUT_DEF)
+ return;
+#endif
+
+ DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN;
+ DECL_LOCAL_CNI_METHOD_P (decl) = 1;
+}
+
+/* Use the preceding two functions and mark all members of the class. */
+
void
java_mark_class_local (tree class)
{
java_mark_decl_local (t);
for (t = TYPE_METHODS (class); t ; t = TREE_CHAIN (t))
- if (!METHOD_ABSTRACT (t) && (!METHOD_NATIVE (t) || flag_jni))
- java_mark_decl_local (t);
+ if (!METHOD_ABSTRACT (t))
+ {
+ if (METHOD_NATIVE (t) && !flag_jni)
+ java_mark_cni_decl_local (t);
+ else
+ java_mark_decl_local (t);
+ }
}
/* Add a statement to a compound_expr. */
void
register_exception_range (struct eh_range *range, int pc, int end_pc)
{
- if (current_binding_level->exception_range)
- abort ();
+ gcc_assert (! current_binding_level->exception_range);
current_binding_level->exception_range = range;
current_binding_level->end_pc = end_pc;
current_binding_level->start_pc = pc;