From: Bryce McKinlay Date: Wed, 18 Aug 2004 17:57:03 +0000 (+0000) Subject: class.c (make_local_function_alias): New function. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=260ba9ce680ed9ee88d427523e403f4667e6023e;p=gcc.git class.c (make_local_function_alias): New function. 2004-08-18 Bryce McKinlay * 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 --- diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog index 8aeeba5fa5c..5fb1dedec40 100644 --- a/gcc/java/ChangeLog +++ b/gcc/java/ChangeLog @@ -1,3 +1,13 @@ +2004-08-18 Bryce McKinlay + + * 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 * java-gimplify.c (java_gimplify_expr): Move '2' handling into diff --git a/gcc/java/class.c b/gcc/java/class.c index b8b4c903583..25f27043827 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) ? diff --git a/gcc/java/parse.y b/gcc/java/parse.y index e1012a7c485..85be4b71bf4 100644 --- a/gcc/java/parse.y +++ b/gcc/java/parse.y @@ -5422,13 +5422,7 @@ craft_constructor (tree class_decl, tree args) tree decl, ctor_name; char buffer [80]; - /* The constructor name is 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$ 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