/* 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. */
+#define GCJ_CURRENT_BC_ABI_VERSION \
+ (4 * 10000 + 0 * 10 + GCJ_BINARYCOMPAT_ADDITION)
+
/* The ABI version number. */
tree gcj_abi_version;
&& LOCAL_SLOT_P (tmp) == 0
&& (pc == -1
|| (pc >= DECL_LOCAL_START_PC (tmp)
- && pc <= DECL_LOCAL_END_PC (tmp)))
+ && pc < DECL_LOCAL_END_PC (tmp)))
+ /* This test is < (rather than <=) because there's no point
+ updating an alias that's about to die at the end of this
+ instruction. */
&& (tmp_type == decl_type
|| (INTEGRAL_TYPE_P (tmp_type)
&& INTEGRAL_TYPE_P (decl_type)
(objects generated by different version of gcj), but will
probably always require strict matching for ordinary ABI. */
if (flag_indirect_dispatch)
- abi_version += GCJ_BINARYCOMPAT_ADDITION;
+ abi_version = GCJ_CURRENT_BC_ABI_VERSION;
gcj_abi_version = build_int_cstu (ptr_type_node, abi_version);
}
endlink = end_params_node = tree_cons (NULL_TREE, void_type_node, NULL_TREE);
- t = tree_cons (NULL_TREE, class_ptr_type,
- tree_cons (NULL_TREE, int_type_node, endlink));
+ t = tree_cons (NULL_TREE, class_ptr_type, endlink);
alloc_object_node = builtin_function ("_Jv_AllocObject",
build_function_type (ptr_type_node, t),
0, NOT_BUILT_IN, NULL, NULL_TREE);
0, NOT_BUILT_IN, NULL, NULL_TREE);
throw_node = builtin_function ("_Jv_Throw",
- build_function_type (ptr_type_node, t),
+ build_function_type (void_type_node, t),
0, NOT_BUILT_IN, NULL, NULL_TREE);
/* Mark throw_nodes as `noreturn' functions with side effects. */
TREE_THIS_VOLATILE (throw_node) = 1;
TREE_SIDE_EFFECTS (throw_node) = 1;
- t = build_function_type (int_type_node, endlink);
+ t = build_function_type (void_type_node, tree_cons (NULL_TREE, ptr_type_node,
+ endlink));
soft_monitorenter_node
= builtin_function ("_Jv_MonitorEnter", t, 0, NOT_BUILT_IN,
NULL, NULL_TREE);
soft_monitorexit_node
= builtin_function ("_Jv_MonitorExit", t, 0, NOT_BUILT_IN,
NULL, NULL_TREE);
-
- t = tree_cons (NULL_TREE, int_type_node,
+
+ t = tree_cons (NULL_TREE, ptr_type_node,
tree_cons (NULL_TREE, int_type_node, endlink));
soft_newarray_node
= builtin_function ("_Jv_NewPrimArray",
- build_function_type(ptr_type_node, t),
+ build_function_type (ptr_type_node, t),
0, NOT_BUILT_IN, NULL, NULL_TREE);
DECL_IS_MALLOC (soft_newarray_node) = 1;
t = tree_cons (NULL_TREE, int_type_node,
tree_cons (NULL_TREE, class_ptr_type,
- tree_cons (NULL_TREE, object_ptr_type_node, endlink)));
+ tree_cons (NULL_TREE, object_ptr_type_node,
+ endlink)));
soft_anewarray_node
= builtin_function ("_Jv_NewObjectArray",
build_function_type (ptr_type_node, t),
0, NOT_BUILT_IN, NULL, NULL_TREE);
soft_jnipopsystemframe_node
= builtin_function ("_Jv_JNI_PopSystemFrame",
- build_function_type (ptr_type_node, t),
+ build_function_type (void_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
= builtin_function ("_Jv_divI",
build_function_type (int_type_node, t),
build_function_type (int_type_node, t),
0, NOT_BUILT_IN, NULL, NULL_TREE);
+ t = tree_cons (NULL_TREE, long_type_node,
+ tree_cons (NULL_TREE, long_type_node, endlink));
soft_ldiv_node
= builtin_function ("_Jv_divJ",
build_function_type (long_type_node, t),
current_pc = pc;
#endif
+ /* FIXME: I'm pretty sure that this is wrong. Variable scopes are
+ inclusive, so a variable is live if pc == end_pc. Here, we
+ terminate a range if the current pc is equal to the end of the
+ range, and this is *before* we have generated code for the
+ instruction at end_pc. We're closing a binding level one
+ instruction too early.*/
while (current_binding_level->end_pc <= pc)
poplevel (1, 0, 0);
}
build2 (TRY_FINALLY_EXPR, void_type_node, *tp, exit));
}
+ /* Ensure non-abstract non-static non-private members are defined only once
+ when linking. This is an issue when using CNI to interface with C++ object
+ files. */
+ if (! METHOD_STATIC (fndecl) && ! METHOD_PRIVATE (fndecl)
+ && ! METHOD_ABSTRACT (fndecl) && ! METHOD_FINAL (fndecl))
+ make_decl_one_only (fndecl);
+
/* Prepend class initialization for static methods reachable from
other classes. */
- if (METHOD_STATIC (fndecl) && ! METHOD_PRIVATE (fndecl)
+ if (METHOD_STATIC (fndecl)
+ && (! METHOD_PRIVATE (fndecl)
+ || INNER_CLASS_P (DECL_CONTEXT (fndecl)))
&& ! DECL_CLINIT_P (fndecl)
&& ! CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (fndecl))))
{