diff options
author | Bryce McKinlay <mckinlay@redhat.com> | 2004-08-18 17:57:03 +0000 |
---|---|---|
committer | Bryce McKinlay <bryce@gcc.gnu.org> | 2004-08-18 18:57:03 +0100 |
commit | 260ba9ce680ed9ee88d427523e403f4667e6023e (patch) | |
tree | 0bf7d0c572a4f666bdfd34856e04e1f858b83cf2 /gcc/java/class.c | |
parent | 62164eb49e501141f015c71410f625b2bf133570 (diff) | |
download | gcc-260ba9ce680ed9ee88d427523e403f4667e6023e.zip gcc-260ba9ce680ed9ee88d427523e403f4667e6023e.tar.gz gcc-260ba9ce680ed9ee88d427523e403f4667e6023e.tar.bz2 |
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
Diffstat (limited to 'gcc/java/class.c')
-rw-r--r-- | gcc/java/class.c | 45 |
1 files changed, 44 insertions, 1 deletions
diff --git a/gcc/java/class.c b/gcc/java/class.c index b8b4c90..25f2704 100644 --- a/gcc/java/class.c +++ b/gcc/java/class.c @@ -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) ? |