class.c (make_local_function_alias): New function.
authorBryce McKinlay <mckinlay@redhat.com>
Wed, 18 Aug 2004 17:57:03 +0000 (17:57 +0000)
committerBryce McKinlay <bryce@gcc.gnu.org>
Wed, 18 Aug 2004 17:57:03 +0000 (18:57 +0100)
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

gcc/java/ChangeLog
gcc/java/class.c
gcc/java/parse.y

index 8aeeba5fa5c64308cdacd3c91702dac5ebaf2891..5fb1dedec409f7136d500f527d64a991d4b8fe70 100644 (file)
@@ -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
index b8b4c9035833f1886951641f55ec16e68f048917..25f27043827c26581e472516f899b016a2010caf 100644 (file)
@@ -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) ?
index e1012a7c485c70180c1ec0f622c512a9b7aa52b3..85be4b71bf4597351b8b56b9c340025afbd1bbcc 100644 (file)
@@ -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