Commit e081a9c4 by Andrew Haley Committed by Andrew Haley

re PR java/13273 (gcj generates call to abstract method)

2004-01-16  Andrew Haley  <aph@redhat.com>

	PR java/13273:
	* typeck.c (shallow_find_method): New.
	(find_method_in_superclasses): New.
	(find_method_in_interfaces): New.
	(lookup_do): Rewrite.
	* java-tree.h (SEARCH_ONLY_INTERFACE): Delete.

	* jcf-parse.c (read_class): Save and restore output_class.
	* decl.c (java_expand_body): Set output_class from fndecl.

From-SVN: r75980
parent ab8ffc79
2004-01-16 Andrew Haley <aph@redhat.com>
PR java/13273:
* typeck.c (shallow_find_method): New.
(find_method_in_superclasses): New.
(find_method_in_interfaces): New.
(lookup_do): Rewrite.
* java-tree.h (SEARCH_ONLY_INTERFACE): Delete.
* jcf-parse.c (read_class): Save and restore output_class.
* decl.c (java_expand_body): Set output_class from fndecl.
2004-01-15 Michael Chastain <mec.gnu@mindspring.com>
* class.c (gen_indirect_dispatch_tables): Fix string length
......
......@@ -1820,8 +1820,7 @@ java_expand_body (tree fndecl)
current_function_decl = fndecl;
input_location = DECL_SOURCE_LOCATION (fndecl);
output_class = DECL_CONTEXT (current_function_decl);
current_class = DECL_CONTEXT (fndecl);
output_class = current_class = DECL_CONTEXT (fndecl);
timevar_push (TV_EXPAND);
......
......@@ -1117,8 +1117,7 @@ struct lang_type GTY(())
/* Possible values to pass to lookup_argument_method_generic. */
#define SEARCH_INTERFACE 1
#define SEARCH_SUPER 2
#define SEARCH_ONLY_INTERFACE 4
#define SEARCH_VISIBLE 8
#define SEARCH_VISIBLE 4
extern void java_parse_file (int);
extern bool java_mark_addressable (tree);
......
......@@ -468,6 +468,7 @@ read_class (tree name)
JCF this_jcf, *jcf;
tree icv, class = NULL_TREE;
tree save_current_class = current_class;
tree save_output_class = output_class;
location_t save_location = input_location;
JCF *save_current_jcf = current_jcf;
......@@ -545,7 +546,8 @@ read_class (tree name)
load_inner_classes (class);
}
output_class = current_class = save_current_class;
output_class = save_output_class;
current_class = save_current_class;
input_location = save_location;
current_jcf = save_current_jcf;
return 1;
......
......@@ -735,6 +735,92 @@ has_method (tree class, tree method_name)
build_null_signature) != NULL_TREE;
}
/* Search in class SEARCHED_CLASS, but not its superclasses, for a
method matching METHOD_NAME and signature SIGNATURE. A private
helper for lookup_do. */
static tree
shallow_find_method (tree searched_class, int flags, tree method_name,
tree signature, tree (*signature_builder) (tree))
{
tree method;
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)
{
/* If the caller requires a visible method, then we
skip invisible methods here. */
if (! (flags & SEARCH_VISIBLE)
|| ! METHOD_INVISIBLE (method))
return method;
}
}
return NULL_TREE;
}
/* Search in the superclasses of SEARCHED_CLASS for a method matching
METHOD_NAME and signature SIGNATURE. A private helper for
lookup_do. */
static tree
find_method_in_superclasses (tree searched_class, int flags,
tree method_name,
tree signature, tree (*signature_builder) (tree))
{
tree klass;
for (klass = CLASSTYPE_SUPER (searched_class); klass != NULL_TREE;
klass = CLASSTYPE_SUPER (klass))
{
tree method;
method = shallow_find_method (klass, flags, method_name,
signature, signature_builder);
if (method != NULL_TREE)
return method;
}
return NULL_TREE;
}
/* Search in the interfaces of SEARCHED_CLASS and its superinterfaces
for a method matching METHOD_NAME and signature SIGNATURE. A
private helper for lookup_do. */
static tree
find_method_in_interfaces (tree searched_class, int flags, tree method_name,
tree signature, tree (*signature_builder) (tree))
{
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);
/* First, we look in ICLASS. If that doesn't work we'll
recursively look through all its superinterfaces. */
tree method = shallow_find_method (iclass, flags, method_name,
signature, signature_builder);
if (method != NULL_TREE)
return method;
method = find_method_in_interfaces
(iclass, flags, method_name, signature, signature_builder);
if (method != NULL_TREE)
return method;
}
return NULL_TREE;
}
/* Search in class SEARCHED_CLASS (and its superclasses) for a method
matching METHOD_NAME and signature SIGNATURE. FLAGS control some
parameters of the search.
......@@ -745,9 +831,6 @@ has_method (tree class, tree method_name)
SEARCH_SUPER means skip SEARCHED_CLASS and start with its
superclass.
SEARCH_ONLY_INTERFACE means don't search ordinary classes, but
instead only search interfaces and superinterfaces.
SEARCH_VISIBLE means skip methods for which METHOD_INVISIBLE is
set.
......@@ -759,74 +842,36 @@ lookup_do (tree searched_class, int flags, tree method_name,
tree signature, tree (*signature_builder) (tree))
{
tree 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;
if (searched_class == NULL_TREE)
return NULL_TREE;
while (searched_class != NULL_TREE)
if (flags & SEARCH_SUPER)
{
/* 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)
{
/* If the caller requires a visible method, then we
skip invisible methods here. */
if (! (flags & SEARCH_VISIBLE)
|| ! METHOD_INVISIBLE (method))
return method;
}
}
}
first_time = 0;
/* Search interfaces, if required. */
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);
/* Note that we don't care about SEARCH_VISIBLE here,
since an interface can never have an invisible
method. */
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);
if (searched_class == NULL_TREE)
return NULL_TREE;
}
return NULL_TREE;
/* First look in our own methods. */
method = shallow_find_method (searched_class, flags, method_name,
signature, signature_builder);
if (method)
return method;
/* Then look in our superclasses. */
if (! CLASS_INTERFACE (TYPE_NAME (searched_class)))
method = find_method_in_superclasses (searched_class, flags, method_name,
signature, signature_builder);
if (method)
return method;
/* If that doesn't work, look in our interfaces. */
if (flags & SEARCH_INTERFACE)
method = find_method_in_interfaces (searched_class, flags, method_name,
signature, signature_builder);
return method;
}
/* Search in class CLAS for a constructor matching METHOD_SIGNATURE.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment