mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-02-13 20:40:40 +08:00
class.c (make_local_function_alias): New function.
2004-08-18 Bryce McKinlay <mckinlay@redhat.com> * class.c (make_local_function_alias): New function. Create local alias for public method DECL. (make_method_value): Use make_local_function_alias. * parse.y (craft_constructor): Don't special-case anonymous classes. Always set ctor_name to init_identifier_node. (lookup_method_invoke): Call layout_class_method when creating anonymous class constructor. From-SVN: r86196
This commit is contained in:
parent
62164eb49e
commit
260ba9ce68
@ -1,3 +1,13 @@
|
||||
2004-08-18 Bryce McKinlay <mckinlay@redhat.com>
|
||||
|
||||
* class.c (make_local_function_alias): New function. Create local
|
||||
alias for public method DECL.
|
||||
(make_method_value): Use make_local_function_alias.
|
||||
* parse.y (craft_constructor): Don't special-case anonymous classes.
|
||||
Always set ctor_name to init_identifier_node.
|
||||
(lookup_method_invoke): Call layout_class_method when creating
|
||||
anonymous class constructor.
|
||||
|
||||
2004-08-18 Richard Henderson <rth@redhat.com>
|
||||
|
||||
* java-gimplify.c (java_gimplify_expr): Move '2' handling into
|
||||
|
@ -1198,6 +1198,46 @@ get_access_flags_from_decl (tree decl)
|
||||
abort ();
|
||||
}
|
||||
|
||||
static GTY (()) int alias_labelno = 0;
|
||||
|
||||
/* Create a private alias for METHOD. Using this alias instead of the method
|
||||
decl ensures that ncode entries in the method table point to the real function
|
||||
at runtime, not a PLT entry. */
|
||||
|
||||
static tree
|
||||
make_local_function_alias (tree method)
|
||||
{
|
||||
tree alias;
|
||||
const char *method_name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (method));
|
||||
char *name = alloca (strlen (method_name) + 1);
|
||||
char *buf = alloca (strlen (method_name) + 128);
|
||||
|
||||
/* Prefix method_name with 'L' for the alias label. */
|
||||
*name = 'L';
|
||||
strcpy (name + 1, method_name);
|
||||
|
||||
ASM_GENERATE_INTERNAL_LABEL (buf, name, alias_labelno++);
|
||||
alias = build_decl (FUNCTION_DECL, get_identifier (buf),
|
||||
TREE_TYPE (method));
|
||||
DECL_CONTEXT (alias) = NULL;
|
||||
TREE_READONLY (alias) = TREE_READONLY (method);
|
||||
TREE_THIS_VOLATILE (alias) = TREE_THIS_VOLATILE (method);
|
||||
TREE_PUBLIC (alias) = 0;
|
||||
DECL_EXTERNAL (alias) = 0;
|
||||
DECL_ARTIFICIAL (alias) = 1;
|
||||
DECL_INLINE (alias) = 0;
|
||||
DECL_INITIAL (alias) = error_mark_node;
|
||||
TREE_ADDRESSABLE (alias) = 1;
|
||||
TREE_USED (alias) = 1;
|
||||
SET_DECL_ASSEMBLER_NAME (alias, DECL_NAME (alias));
|
||||
TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (alias)) = 1;
|
||||
if (!flag_syntax_only)
|
||||
assemble_alias (alias, DECL_ASSEMBLER_NAME (method));
|
||||
return alias;
|
||||
}
|
||||
|
||||
/** Make reflection data (_Jv_Field) for field FDECL. */
|
||||
|
||||
static tree
|
||||
make_field_value (tree fdecl)
|
||||
{
|
||||
@ -1242,6 +1282,8 @@ make_field_value (tree fdecl)
|
||||
return finit;
|
||||
}
|
||||
|
||||
/** Make reflection data (_Jv_Method) for method MDECL. */
|
||||
|
||||
static tree
|
||||
make_method_value (tree mdecl)
|
||||
{
|
||||
@ -1265,7 +1307,8 @@ make_method_value (tree mdecl)
|
||||
|
||||
code = null_pointer_node;
|
||||
if (DECL_RTL_SET_P (mdecl))
|
||||
code = build1 (ADDR_EXPR, nativecode_ptr_type_node, mdecl);
|
||||
code = build1 (ADDR_EXPR, nativecode_ptr_type_node,
|
||||
make_local_function_alias (mdecl));
|
||||
START_RECORD_CONSTRUCTOR (minit, method_type_node);
|
||||
PUSH_FIELD_VALUE (minit, "name",
|
||||
build_utf8_ref (DECL_CONSTRUCTOR_P (mdecl) ?
|
||||
|
@ -5422,13 +5422,7 @@ craft_constructor (tree class_decl, tree args)
|
||||
tree decl, ctor_name;
|
||||
char buffer [80];
|
||||
|
||||
/* The constructor name is <init> unless we're dealing with an
|
||||
anonymous class, in which case the name will be fixed after having
|
||||
be expanded. */
|
||||
if (ANONYMOUS_CLASS_P (class_type))
|
||||
ctor_name = DECL_NAME (class_decl);
|
||||
else
|
||||
ctor_name = init_identifier_node;
|
||||
ctor_name = init_identifier_node;
|
||||
|
||||
/* If we're dealing with an inner class constructor, we hide the
|
||||
this$<n> decl in the name field of its parameter declaration. */
|
||||
@ -10930,12 +10924,10 @@ lookup_method_invoke (int lc, tree cl, tree class, tree name, tree arg_list)
|
||||
|
||||
if (lc && ANONYMOUS_CLASS_P (class))
|
||||
{
|
||||
tree saved_current_class;
|
||||
tree mdecl = craft_constructor (TYPE_NAME (class), atl);
|
||||
saved_current_class = current_class;
|
||||
current_class = class;
|
||||
fix_constructors (mdecl);
|
||||
current_class = saved_current_class;
|
||||
/* The anonymous class may have already been laid out, so make sure
|
||||
the new constructor is laid out here. */
|
||||
layout_class_method (class, CLASSTYPE_SUPER (class), mdecl, NULL_TREE);
|
||||
}
|
||||
|
||||
/* Find all candidates and then refine the list, searching for the
|
||||
|
Loading…
Reference in New Issue
Block a user