Note: a variant of this patch was put into gcc.gnu.org
on Tue Aug 12 2003.


Index: gcc/java/ChangeLog
from  Tom Tromey  <tromey@redhat.com>

	* parse.y (java_check_regular_methods): Typo fixes.  Call
	check_interface_throws_clauses.
	(check_interface_throws_clauses): New function.
	* typeck.c (SEARCH_INTERFACE): New define.
	(SEARCH_SUPER): Likewise.
	(SEARCH_ONLY_INTERFACE): Likewise.
	(lookup_do): Use `flags' argument to decide what to do.
	Reimplemented.
	* jcf.h (ACC_INVISIBLE): New define.
	* jcf-write.c (generate_classfile): Skip invisible methods.
	* class.c (add_miranda_methods): New function.
	(layout_class_methods): Use it.
	(get_access_flags_from_decl): Use ACC_INVISIBLE.
	* java-tree.h (METHOD_INVISIBLE): New define.
	(lang_decl_func) [invisible]: New field.

Index: gcc/java/class.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/class.c,v
retrieving revision 1.152
diff -u -r1.152 class.c
--- gcc/java/class.c 31 Jan 2003 14:46:54 -0000 1.152
+++ gcc/java/class.c 6 Feb 2003 18:55:28 -0000
@@ -57,6 +57,7 @@
 static int supers_all_compiled (tree type);
 static void add_interface_do (tree, tree, int);
 static tree maybe_layout_super_class (tree, tree);
+static void add_miranda_methods (tree, tree);
 static int assume_compiled (const char *);
 static tree build_method_symbols_entry (tree);
 
@@ -1042,6 +1043,8 @@
 	access_flags |= ACC_TRANSIENT;
       if (METHOD_STRICTFP (decl))
 	access_flags |= ACC_STRICT;
+      if (METHOD_INVISIBLE (decl))
+	access_flags |= ACC_INVISIBLE;
       return access_flags;
     }
   abort ();
@@ -1746,14 +1749,14 @@
 {
   tree super_class = CLASSTYPE_SUPER (this_class);
   tree field;
-  
+
   class_list = tree_cons (this_class, NULL_TREE, class_list);
   if (CLASS_BEING_LAIDOUT (this_class))
     {
       char buffer [1024];
       char *report;
       tree current;
-      
+
       sprintf (buffer, " with `%s'",
 	       IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (this_class))));
       obstack_grow (&temporary_obstack, buffer, strlen (buffer));
@@ -1807,8 +1810,9 @@
 
   layout_type (this_class);
 
-  /* Also recursively load/layout any superinterfaces, but only if class was
-  loaded from bytecode. The source parser will take care of this itself. */
+  /* Also recursively load/layout any superinterfaces, but only if
+     class was loaded from bytecode.  The source parser will take care
+     of this itself.  */
   if (!CLASS_FROM_SOURCE_P (this_class))
     {
       tree basetype_vec = TYPE_BINFO_BASETYPES (this_class);
@@ -1836,14 +1840,60 @@
 	}
     }
 
-  /* Convert the size back to an SI integer value */
-  TYPE_SIZE_UNIT (this_class) = 
+  /* Convert the size back to an SI integer value.  */
+  TYPE_SIZE_UNIT (this_class) =
     fold (convert (int_type_node, TYPE_SIZE_UNIT (this_class)));
 
   CLASS_BEING_LAIDOUT (this_class) = 0;
   class_list = TREE_CHAIN (class_list);
 }
 
+static void
+add_miranda_methods (tree base_class, tree search_class)
+{
+  tree basetype_vec = TYPE_BINFO_BASETYPES (search_class);
+  int i, n = TREE_VEC_LENGTH (basetype_vec);
+  for (i = 1; i < n; ++i)
+    {
+      tree method_decl;
+      tree elt = TREE_VEC_ELT (basetype_vec, i);
+      if (elt == NULL_TREE)
+	break;
+      elt = BINFO_TYPE (elt);
+
+      /* Note that order matters here.  However, all the base classes
+	 will have been laid out at this point, so the order will
+	 always be correct.  Also, this code must match similar layout
+	 code in the runtime.  */
+      for (method_decl = TYPE_METHODS (elt);
+	   method_decl; method_decl = TREE_CHAIN (method_decl))
+	{
+	  tree sig;
+
+	  /* An interface can have <clinit>.  */
+	  if (ID_CLINIT_P (DECL_NAME (method_decl)))
+	    continue;
+
+	  sig = build_java_argument_signature (TREE_TYPE (method_decl));
+	  if (lookup_argument_method (base_class, DECL_NAME (method_decl),
+				      sig) == NULL_TREE)
+	    {
+	      /* Found a Miranda method.  Add it.  */
+	      tree new_method;
+	      sig = build_java_signature (TREE_TYPE (method_decl));
+	      new_method
+		= add_method (base_class,
+			      get_access_flags_from_decl (method_decl),
+			      DECL_NAME (method_decl), sig);
+	      METHOD_INVISIBLE (new_method) = 1;
+	    }
+	}
+
+      /* Try superinterfaces.  */
+      add_miranda_methods (base_class, elt);
+    }
+}
+
 void
 layout_class_methods (tree this_class)
 {
@@ -1865,11 +1915,20 @@
   else
     dtable_count = integer_zero_node;
 
+  if (CLASS_ABSTRACT (TYPE_NAME (this_class)))
+    {
+      /* An abstract class can have methods which are declared only in
+	 an implemented interface.  These are called "Miranda
+	 methods".  We make a dummy method entry for such methods
+	 here.  */
+      add_miranda_methods (this_class, this_class);
+    }
+
   TYPE_METHODS (this_class) = nreverse (TYPE_METHODS (this_class));
 
   for (method_decl = TYPE_METHODS (this_class);
        method_decl; method_decl = TREE_CHAIN (method_decl))
-    dtable_count = layout_class_method (this_class, super_class, 
+    dtable_count = layout_class_method (this_class, super_class,
 					method_decl, dtable_count);
 
   TYPE_NVIRTUALS (this_class) = dtable_count;
Index: gcc/java/java-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/java-tree.h,v
retrieving revision 1.171
diff -u -r1.171 java-tree.h
--- gcc/java/java-tree.h 23 Jan 2003 02:38:57 -0000 1.171
+++ gcc/java/java-tree.h 6 Feb 2003 18:55:32 -0000
@@ -993,6 +993,9 @@
   unsigned int fixed_ctor : 1;
   unsigned int init_calls_this : 1;
   unsigned int strictfp : 1;
+  unsigned int invisible : 1;	/* Set for methods we generate
+				   internally but which shouldn't be
+				   written to the .class file.  */
 };
 
 struct treetreehash_entry GTY(())
@@ -1319,6 +1322,7 @@
 #define METHOD_ABSTRACT(DECL) DECL_LANG_FLAG_5 (DECL)
 #define METHOD_TRANSIENT(DECL) DECL_LANG_FLAG_6 (DECL)
 #define METHOD_STRICTFP(DECL) (DECL_LANG_SPECIFIC (DECL)->u.f.strictfp)
+#define METHOD_INVISIBLE(DECL) (DECL_LANG_SPECIFIC (DECL)->u.f.invisible)
 
 #define JAVA_FILE_P(NODE) TREE_LANG_FLAG_2 (NODE)
 #define CLASS_FILE_P(NODE) TREE_LANG_FLAG_3 (NODE)
Index: gcc/java/jcf-write.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/jcf-write.c,v
retrieving revision 1.120
diff -u -r1.120 jcf-write.c
--- gcc/java/jcf-write.c 29 Jan 2003 01:19:40 -0000 1.120
+++ gcc/java/jcf-write.c 6 Feb 2003 18:55:35 -0000
@@ -2912,6 +2912,12 @@
       tree type = TREE_TYPE (part);
       tree save_function = current_function_decl;
       int synthetic_p = 0;
+
+      /* Invisible Miranda methods shouldn't end up in the .class
+	 file.  */
+      if (METHOD_INVISIBLE (part))
+	continue;
+
       current_function_decl = part;
       ptr = append_chunk (NULL, 8, state);
       i = get_access_flags (part);  PUT2 (i);
Index: gcc/java/jcf.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/jcf.h,v
retrieving revision 1.35
diff -u -r1.35 jcf.h
--- gcc/java/jcf.h 10 Jan 2003 02:22:25 -0000 1.35
+++ gcc/java/jcf.h 6 Feb 2003 18:55:35 -0000
@@ -212,6 +212,9 @@
 #define ACC_INTERFACE 0x0200
 #define ACC_ABSTRACT 0x0400
 #define ACC_STRICT 0x0800
+/* "Invisible" refers to Miranda methods inserted into an abstract
+   #class.  It is also used in the runtime.  */
+#define ACC_INVISIBLE 0x1000
 
 #define ACC_VISIBILITY (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED)
 
Index: gcc/java/parse.y
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/parse.y,v
retrieving revision 1.421
diff -u -r1.421 parse.y
--- gcc/java/parse.y 3 Feb 2003 17:44:55 -0000 1.421
+++ gcc/java/parse.y 6 Feb 2003 18:55:47 -0000
@@ -245,6 +245,7 @@
 static int check_method_redefinition (tree, tree);
 static int check_method_types_complete (tree);
 static void java_check_regular_methods (tree);
+static void check_interface_throws_clauses (tree);
 static void java_check_abstract_methods (tree);
 static void unreachable_stmt_error (tree);
 static tree find_expr_with_wfl (tree);
@@ -6341,7 +6342,7 @@
 	    continue;
 	  parse_error_context
 	    (method_wfl,
-	     "%s methods can't be overriden. Method `%s' is %s in class `%s'",
+	     "%s methods can't be overridden. Method `%s' is %s in class `%s'",
 	     (METHOD_FINAL (found) ? "Final" : "Static"),
 	     lang_printable_name (found, 0),
 	     (METHOD_FINAL (found) ? "final" : "static"),
@@ -6355,7 +6356,7 @@
 	{
 	  parse_error_context
 	    (method_wfl,
-	     "Instance methods can't be overriden by a static method. Method `%s' is an instance method in class `%s'",
+	     "Instance methods can't be overridden by a static method. Method `%s' is an instance method in class `%s'",
 	     lang_printable_name (found, 0),
 	     IDENTIFIER_POINTER
 	       (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
@@ -6364,7 +6365,7 @@
 
       /* - Overriding/hiding public must be public
 	 - Overriding/hiding protected must be protected or public
-         - If the overriden or hidden method has default (package)
+         - If the overridden or hidden method has default (package)
            access, then the overriding or hiding method must not be
            private; otherwise, a compile-time error occurs.  If
            `found' belongs to an interface, things have been already
@@ -6389,10 +6390,10 @@
       /* Overriding methods must have compatible `throws' clauses on checked
 	 exceptions, if any */
       check_throws_clauses (method, method_wfl, found);
-
-      /* Inheriting multiple methods with the same signature. FIXME */
     }
 
+  check_interface_throws_clauses (class);
+
   if (!TYPE_NVIRTUALS (class))
     TYPE_METHODS (class) = nreverse (TYPE_METHODS (class));
 
@@ -6404,9 +6405,48 @@
     abort ();
 }
 
-/* Return a nonzero value if the `throws' clause of METHOD (if any)
-   is incompatible with the `throws' clause of FOUND (if any).  */
+/* Check to make sure that interfaces implemented by this class have
+   compatible `throws' clauses.  */
+static void
+check_interface_throws_clauses (tree class_decl)
+{
+  tree bases = TYPE_BINFO_BASETYPES (class_decl);
+  int iface_len = TREE_VEC_LENGTH (bases) - 1;
+  int i;
+
+  for (i = iface_len; i > 0; --i)
+    {
+      tree interface = BINFO_TYPE (TREE_VEC_ELT (bases, i));
+      tree iface_method;
+
+      for (iface_method = TYPE_METHODS (interface); iface_method != NULL_TREE;
+	   iface_method = TREE_CHAIN (iface_method))
+	{
+	  tree sig, method;
+
+	  /* First look for a concrete method implemented or inherited
+	     by this class.  Don't search interfaces here, since this
+	     is tricky and we handle it specially below.  */
+	  sig = build_java_argument_signature (TREE_TYPE (iface_method));
+	  method = lookup_argument_method (class_decl,
+					   DECL_NAME (iface_method),
+					   sig);
+	  /* If we don't find an implementation, that is ok.  Any
+	     potential errors from that are diagnosed elsewhere.
+	     Also, multiple inheritance with conflicting throws
+	     clauses is fine in the absence of a concrete
+	     implementation.  */
+	  if (method != NULL_TREE && !METHOD_ABSTRACT (method))
+	    {
+	      tree method_wfl = DECL_FUNCTION_WFL (method);
+	      check_throws_clauses (method, method_wfl, iface_method);
+	    }
+	}
+    }
+}
 
+/* Generate an error if the `throws' clause of METHOD (if any) is
+   incompatible with the `throws' clause of FOUND (if any).  */
 static void
 check_throws_clauses (tree method, tree method_wfl, tree found)
 {
@@ -10053,7 +10093,7 @@
   tree this_arg = NULL_TREE;
   int is_array_clone_call = 0;
 
-  /* Should be overriden if everything goes well. Otherwise, if
+  /* Should be overridden if everything goes well. Otherwise, if
      something fails, it should keep this value. It stop the
      evaluation of a bogus assignment. See java_complete_tree,
      MODIFY_EXPR: for the reasons why we sometimes want to keep on
Index: gcc/java/typeck.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/typeck.c,v
retrieving revision 1.56
diff -u -r1.56 typeck.c
--- gcc/java/typeck.c 18 Jan 2003 22:15:51 -0000 1.56
+++ gcc/java/typeck.c 6 Feb 2003 18:55:48 -0000
@@ -42,9 +42,14 @@
 static tree convert_ieee_real_to_integer (tree, tree);
 static tree parse_signature_type (const unsigned char **,
 				  const unsigned char *);
-static tree lookup_do (tree, tree, tree, tree, tree (*)(tree));
+static tree lookup_do (tree, int, tree, tree, tree (*)(tree));
 static tree build_null_signature (tree);
 
+/* Flags to pass to lookup_do.  */
+#define SEARCH_INTERFACE 1
+#define SEARCH_SUPER     2
+#define SEARCH_ONLY_INTERFACE 4
+
 tree * type_map;
 
 /* Set the type of the local variable with index SLOT to TYPE. */
@@ -687,61 +692,51 @@
 #endif
 }
 
-/* Search in class SEARCHED_CLASS (and its superclasses) for a method
-   matching METHOD_NAME and signature SIGNATURE.  If SEARCHED_INTERFACE is
-   not NULL_TREE then first search its superinterfaces for a similar match.
-   Return the matched method DECL or NULL_TREE.  SIGNATURE_BUILDER is
-   used on method candidates to build their (sometimes partial)
-   signature.  */
-
+/* Search in SEARCHED_CLASS and its superclasses for a method matching
+   METHOD_NAME and signature METHOD_SIGNATURE.  This function will
+   only search for methods declared in the class hierarchy; interfaces
+   will not be considered.  Returns NULL_TREE if the method is not
+   found.  */
 tree
-lookup_argument_method (tree searched_class, tree method_name, tree method_signature)
+lookup_argument_method (tree searched_class, tree method_name,
+			tree method_signature)
 {
-  return lookup_do (searched_class, NULL_TREE, method_name, method_signature, 
+  return lookup_do (searched_class, 0, method_name, method_signature, 
 		    build_java_argument_signature);
 }
 
-/* Search in class SEARCHED_CLASS (and its superclasses and
-   implemented interfaces) for a method matching METHOD_NAME and
-   argument signature METHOD_SIGNATURE.  Return a FUNCTION_DECL on
-   success, or NULL_TREE if none found.  (Contrast lookup_java_method,
-   which takes into account return type.) */
-
+/* Search in the interfaces of SEARCHED_CLASS, its superclass, and all
+   other ancestors (interface or not) for a method matching
+   METHOD_NAME and argument signature METHOD_SIGNATURE.  Return a
+   FUNCTION_DECL on success, or NULL_TREE if none found.  Contrast
+   lookup_java_method, which takes into account return type.  */
 tree
-lookup_argument_method2 (tree searched_class, tree method_name, tree method_signature)
+lookup_argument_method2 (tree searched_class, tree method_name,
+			 tree method_signature)
 {
-  return lookup_do (CLASSTYPE_SUPER (searched_class), searched_class,
-		    method_name, method_signature, 
+  return lookup_do (searched_class, SEARCH_SUPER | SEARCH_INTERFACE,
+		    method_name, method_signature,
 		    build_java_argument_signature);
 }
 
 /* Search in class SEARCHED_CLASS (and its superclasses) for a method
    matching METHOD_NAME and signature METHOD_SIGNATURE.  Return a
    FUNCTION_DECL on success, or NULL_TREE if none found.  (Contrast
-   lookup_argument_method, which ignores return type.) If
+   lookup_argument_method, which ignores return type.)  If
    SEARCHED_CLASS is an interface, search it too. */
-
 tree
-lookup_java_method (tree searched_class, tree method_name, tree method_signature)
+lookup_java_method (tree searched_class, tree method_name,
+		    tree method_signature)
 {
-  tree searched_interface;
-  
-  /* If this class is an interface class, search its superinterfaces
-   * first. A superinterface is not an interface's superclass: a super
-   * interface is implemented by the interface.  */
-
-  searched_interface = (CLASS_INTERFACE (TYPE_NAME (searched_class)) ?
-			searched_class : NULL_TREE);
-  return lookup_do (searched_class, searched_interface, method_name, 
+  return lookup_do (searched_class, SEARCH_INTERFACE, method_name, 
 		    method_signature, build_java_signature);
 }
 
-/* Return true iff CLASS (or its ancestors) has a method METHOD_NAME. */
-
+/* Return true iff CLASS (or its ancestors) has a method METHOD_NAME. */
 int
 has_method (tree class, tree method_name)
 {
-  return lookup_do (class, class,  method_name,
+  return lookup_do (class, SEARCH_INTERFACE,  method_name,
 		    NULL_TREE, build_null_signature) != NULL_TREE;
 }
 
@@ -753,58 +748,67 @@
    signature.  */
 
 static tree
-lookup_do (tree searched_class, tree searched_interface, tree method_name,
+lookup_do (tree searched_class, int flags, tree method_name,
 	   tree signature, tree (*signature_builder) (tree))
 {
   tree method;
-  
-  if (searched_interface)
-    {
-      int i;
-      int interface_len = 
-	TREE_VEC_LENGTH (TYPE_BINFO_BASETYPES (searched_interface)) - 1;
-
-      for (i = interface_len; i > 0; i--)
-       {
-         tree child = 
-	   TREE_VEC_ELT (TYPE_BINFO_BASETYPES (searched_interface), i);
-         tree iclass = BINFO_TYPE (child);
-
-         /* If the superinterface hasn't been loaded yet, do so now.  */
-	 if (CLASS_FROM_SOURCE_P (iclass))
-	   safe_layout_class (iclass);
-	 else if (!CLASS_LOADED_P (iclass))
-	   load_class (iclass, 1);
-
-         for (method = TYPE_METHODS (iclass);
-              method != NULL_TREE;  method = TREE_CHAIN (method))
-           {
-             tree method_sig = (*signature_builder) (TREE_TYPE (method));
-
-	     if (DECL_NAME (method) == method_name && method_sig == signature)
-               return method;
-           }
-
-         /* it could be defined in a supersuperinterface */
-         if (CLASS_INTERFACE (TYPE_NAME (iclass)))
-           {
-             method = lookup_do (iclass, iclass, method_name, 
-				 signature, signature_builder);
-             if (method != NULL_TREE) 
-	       return method;
-           }
-       }
-    }
+  int first_time = 1;
+
+  /* If the incoming class is an interface, then we will only return
+     a method declared in an interface context.  */
+  if (searched_class != NULL_TREE
+      && CLASS_INTERFACE (TYPE_NAME (searched_class)))
+    flags |= SEARCH_ONLY_INTERFACE;
 
   while (searched_class != NULL_TREE)
     {
-      for (method = TYPE_METHODS (searched_class);
-	   method != NULL_TREE;  method = TREE_CHAIN (method))
-	{
-	  tree method_sig = (*signature_builder) (TREE_TYPE (method));
-	  if (DECL_NAME (method) == method_name && method_sig == signature)
-	    return method;
-	}
+      /* First search this class.  If we're only searching the
+ 	 superclass, skip this.  */
+      if (! ((flags & SEARCH_SUPER) && first_time))
+ 	{
+ 	  for (method = TYPE_METHODS (searched_class);
+ 	       method != NULL_TREE;  method = TREE_CHAIN (method))
+ 	    {
+ 	      tree method_sig = (*signature_builder) (TREE_TYPE (method));
+ 	      if (DECL_NAME (method) == method_name && method_sig == signature)
+ 		return method;
+ 	    }
+ 	}
+      first_time = 0;
+
+      /* Search interfaces, if required.  Note that if this class is
+ 	 abstract, then we have to search its interfaces because we
+ 	 may potentially find a Miranda method.  */
+      if ((flags & SEARCH_INTERFACE))
+ 	{
+ 	  int i;
+ 	  int interface_len = 
+ 	    TREE_VEC_LENGTH (TYPE_BINFO_BASETYPES (searched_class)) - 1;
+
+ 	  for (i = interface_len; i > 0; i--)
+ 	    {
+ 	      tree child = 
+ 		TREE_VEC_ELT (TYPE_BINFO_BASETYPES (searched_class), i);
+ 	      tree iclass = BINFO_TYPE (child);
+
+ 	      /* If the superinterface hasn't been loaded yet, do so now.  */
+ 	      if (CLASS_FROM_SOURCE_P (iclass))
+ 		safe_layout_class (iclass);
+ 	      else if (!CLASS_LOADED_P (iclass))
+ 		load_class (iclass, 1);
+
+ 	      method = lookup_do (iclass, SEARCH_INTERFACE,
+				  method_name, signature, signature_builder);
+ 	      if (method != NULL_TREE) 
+ 		return method;
+ 	    }
+ 	}
+
+      /* If we're only searching for interface methods, then we've
+	 already searched all the superinterfaces.  Our superclass is
+	 Object, but we don't want to search that.  */
+      if ((flags & SEARCH_ONLY_INTERFACE))
+	break;
       searched_class = CLASSTYPE_SUPER (searched_class);
     }
 
@@ -826,6 +830,85 @@
     }
   return NULL_TREE;
 }
+
+#if 0
+/* Helper for lookup_all_methods.  If a method is found in the class
+   hierarchy, add it to the list.  Otherwise, if CLASS is abstract or
+   an interface search all its interfaces and add all (unique)
+   matching methods.  */
+bool
+lookup_all_methods_helper (tree class, tree method_name, tree method_signature,
+			   htab_t found)
+{
+  tree method, search_class;
+  tree found = NULL_TREE;
+
+  for (search_class = class; found == NULL_TREE && search_class != NULL_TREE;
+       search_class = CLASSTYPE_SUPER (search_class))
+    {
+      for (method = TYPE_METHODS (search_class);
+	   found == NULL_TREE && method != NULL_TREE;
+	   method = TREE_CHAIN (method))
+	{
+	  tree method_sig = build_java_argument_signature (TREE_TYPE (method));
+	  if (DECL_NAME (method) == method_name && method_sig == signature)
+	    {
+	      void **slot;
+	      slot = htab_find_slot (found, method, INSERT);
+	      if (*slot == NULL)
+		*slot = method;
+	      found = method;
+	    }
+	}
+    }
+
+  /* If we found a concrete method, we're done.  */
+  if (found != NULL_TREE && !METHOD_ABSTRACT (found))
+    return;
+
+  /* If we don't have an abstract class or interface class here, we're
+     done.  */
+  if (!CLASS_ABSTRACT (class) && !CLASS_INTERFACE (class))
+    return;
+
+  /* Now search all superinterfaces.  */
+  interface_len = TREE_VEC_LENGTH (TYPE_BINFO_BASETYPES (class)) - 1;
+  for (i = interface_len; i > 0; --i)
+    {
+      tree child = TREE_VEC_ELT (TYPE_BINFO_BASETYPES (class), i);
+      tree iclass = BINFO_TYPE (child);
+      lookup_all_methods_helper (iclass, method_name, method_signature,
+				 results);
+    }
+}
+
+/* Look up and return all the methods with name METHOD_NAME and
+   signature METHOD_SIGNATURE.  Returns a list of all such methods.
+   Methods defined locally in CLASS are skipped, as are `invisible'
+   methods.  */
+tree
+lookup_inherited_methods (tree class, tree method_name, tree method_signature)
+{
+  tree result = NULL_TREE;
+  int i, interface_len;
+  tree value;
+  htab_t results;
+
+  results = htab_create (10, htab_hash_pointer, htab_eq_pointer, NULL);
+  lookup_all_methods_helper (CLASSTYPE_SUPER (class),
+			     method_name, method_signature,
+			     results);
+
+  interface_len = TREE_VEC_LENGTH (TYPE_BINFO_BASETYPES (class)) - 1;
+  for (i = interface_len; i > 0; --i)
+    {
+      tree child = TREE_VEC_ELT (TYPE_BINFO_BASETYPES (class), i);
+      tree iclass = BINFO_TYPE (child);
+      lookup_all_methods_helper (iclass, method_name, method_signature,
+				 results);
+    }
+}
+#endif
 
 /* Return a type which is the Binary Numeric Promotion of the pair T1,
    T2 and convert EXP1 and/or EXP2. See 5.6.2 Binary Numeric
Index: libjava/testsuite/ChangeLog
from  Tom Tromey  <tromey@redhat.com>

	* libjava.jacks/jacks.xfail: Updated to account for new passes.
	* libjava.compile/abstr.xfail: Now can compile from bytecode.
	* libjava.compile/PR5641.xfail: Now can compile from bytecode.

Index: libjava/testsuite/libjava.compile/PR5641.xfail
===================================================================
RCS file: /cvs/gcc/gcc/libjava/testsuite/libjava.compile/PR5641.xfail,v
retrieving revision 1.1
diff -u -r1.1 PR5641.xfail
--- libjava/testsuite/libjava.compile/PR5641.xfail 11 Feb 2002 00:18:52 -0000 1.1
+++ libjava/testsuite/libjava.compile/PR5641.xfail 6 Feb 2003 19:04:47 -0000
@@ -1,2 +1 @@
 no-link
-xfail-byte
Index: libjava/testsuite/libjava.compile/abstr.xfail
===================================================================
RCS file: /cvs/gcc/gcc/libjava/testsuite/libjava.compile/abstr.xfail,v
retrieving revision 1.2
diff -u -r1.2 abstr.xfail
--- libjava/testsuite/libjava.compile/abstr.xfail 16 Dec 2000 02:06:29 -0000 1.2
+++ libjava/testsuite/libjava.compile/abstr.xfail 6 Feb 2003 19:04:47 -0000
@@ -1,2 +1 @@
 no-link
-xfail-byte
Index: libjava/testsuite/libjava.jacks/jacks.xfail
===================================================================
RCS file: /cvs/gcc/gcc/libjava/testsuite/libjava.jacks/jacks.xfail,v
retrieving revision 1.4
diff -u -r1.4 jacks.xfail
--- libjava/testsuite/libjava.jacks/jacks.xfail 28 Jan 2003 18:48:32 -0000 1.4
+++ libjava/testsuite/libjava.jacks/jacks.xfail 6 Feb 2003 19:04:47 -0000
@@ -142,8 +142,6 @@
 8.1.1.1-default-abstract-15
 8.1.1.1-default-abstract-19
 8.1.1.1-default-abstract-21
-8.1.1.1-default-abstract-22
-8.1.1.1-default-abstract-24
 8.1.1.1-default-abstract-25
 8.1.2-static-1
 8.1.2-static-11
@@ -224,9 +222,6 @@
 8.5-inheritance-3
 8.5-inheritance-6
 8.5.2-non-static-member-usage-2
-8.4.6-miranda-2
-8.4.6-miranda-3
-8.4.6-miranda-4
 8.4.6-inheritance-1
 8.4.6-inheritance-2
 8.4.6.2-hiding-3
@@ -237,8 +232,6 @@
 8.4.6.4-multiple-8
 8.4.6.4-abstract-1
 8.4.6.4-abstract-2
-8.4.6.4-abstract-4
-8.4.6.4-abstract-9
 8.4.6.4-abstract-10
 8.4.6.1-override-3
 8.4.6.3-modifier-8
@@ -253,11 +246,6 @@
 8.4.6.3-default-12
 8.4.6.3-default-14
 8.4.6.3-signature-4
-8.4.6.3-signature-7
-8.4.6.3-signature-9
-8.4.6.3-signature-10
-8.4.6.3-signature-12
-8.4.6.3-signature-15
 8.7-abrupt-1
 8.7-complete-1
 8.7-complete-3
@@ -533,7 +521,6 @@
 15.12.2.2-ambiguous-2
 15.12.2.2-ambiguous-6
 15.12.2.2-ambiguous-9
-15.12.2.2-ambiguous-10
 15.12.2.2-ambiguous-12
 15.12.2.2-ambiguous-14
 15.12.2.2-ambiguous-18
@@ -605,10 +592,7 @@
 9.2-implicit-4
 9.2-implicit-6
 9.2-implicit-7
-9.2-implicit-11
-9.2-implicit-12
 9.2-implicit-15
-9.2-implicit-17
 9.2-implicit-18
 9.2-implicit-19
 3.2-valid-1
