Commit aecf4109 by Tom Tromey Committed by Tom Tromey

parse.y (java_check_regular_methods): Typo fixes.

	* parse.y (java_check_regular_methods): Typo fixes.  Call
	check_interface_throws_clauses.  Use
	check_concrete_throws_clauses.
	(check_interface_throws_clauses): New function.
	(check_concrete_throws_clauses): New function.
	(hack_is_accessible_p): New function.
	(find_most_specific_methods_list): Added FIXME.
	* typeck.c (lookup_do): Use `flags' argument to decide what to
	do.  Reimplemented.
	(lookup_argument_method_generic): New function.
	(lookup_argument_method2): Removed.
	* 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.
	(lookup_argument_method_generic): Declare.
	(SEARCH_INTERFACE): New define.
	(SEARCH_SUPER): Likewise.
	(SEARCH_ONLY_INTERFACE): Likewise.
	(SEARCH_VISIBLE): Likewise.
	(lookup_argument_method2): Removed declaration.

From-SVN: r70388
parent b9172475
2003-08-11 Tom Tromey <tromey@redhat.com>
* parse.y (java_check_regular_methods): Typo fixes. Call
check_interface_throws_clauses. Use
check_concrete_throws_clauses.
(check_interface_throws_clauses): New function.
(check_concrete_throws_clauses): New function.
(hack_is_accessible_p): New function.
(find_most_specific_methods_list): Added FIXME.
* typeck.c (lookup_do): Use `flags' argument to decide what to
do. Reimplemented.
(lookup_argument_method_generic): New function.
(lookup_argument_method2): Removed.
* 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.
(lookup_argument_method_generic): Declare.
(SEARCH_INTERFACE): New define.
(SEARCH_SUPER): Likewise.
(SEARCH_ONLY_INTERFACE): Likewise.
(SEARCH_VISIBLE): Likewise.
(lookup_argument_method2): Removed declaration.
2003-08-05 Tom Tromey <tromey@redhat.com>
Fix for PR java/11600:
......
......@@ -57,6 +57,7 @@ static tree get_dispatch_table (tree, tree);
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);
......@@ -1034,6 +1035,8 @@ get_access_flags_from_decl (tree decl)
access_flags |= ACC_ABSTRACT;
if (METHOD_STRICTFP (decl))
access_flags |= ACC_STRICT;
if (METHOD_INVISIBLE (decl))
access_flags |= ACC_INVISIBLE;
return access_flags;
}
abort ();
......@@ -1747,14 +1750,14 @@ layout_class (tree this_class)
{
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));
......@@ -1808,8 +1811,9 @@ layout_class (tree this_class)
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);
......@@ -1837,14 +1841,61 @@ layout_class (tree this_class)
}
}
/* 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, override;
/* An interface can have <clinit>. */
if (ID_CLINIT_P (DECL_NAME (method_decl)))
continue;
sig = build_java_argument_signature (TREE_TYPE (method_decl));
override = lookup_argument_method (base_class,
DECL_NAME (method_decl), sig);
if (override == 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)
{
......@@ -1866,11 +1917,20 @@ layout_class_methods (tree this_class)
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;
......
......@@ -977,6 +977,9 @@ struct lang_decl_func GTY(())
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(())
......@@ -1071,6 +1074,12 @@ struct lang_type GTY(())
#define JCF_u4 unsigned long
#define JCF_u2 unsigned short
/* 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
extern void java_parse_file (int);
extern bool java_mark_addressable (tree);
extern tree java_type_for_mode (enum machine_mode, int);
......@@ -1084,7 +1093,7 @@ extern tree lookup_class (tree);
extern tree lookup_java_constructor (tree, tree);
extern tree lookup_java_method (tree, tree, tree);
extern tree lookup_argument_method (tree, tree, tree);
extern tree lookup_argument_method2 (tree, tree, tree);
extern tree lookup_argument_method_generic (tree, tree, tree, int);
extern int has_method (tree, tree);
extern tree promote_type (tree);
extern tree get_constant (struct JCF*, int);
......@@ -1302,6 +1311,7 @@ extern void init_resource_processing (void);
#define METHOD_NATIVE(DECL) (DECL_LANG_SPECIFIC(DECL)->u.f.native)
#define METHOD_ABSTRACT(DECL) DECL_LANG_FLAG_5 (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)
......
......@@ -2919,6 +2919,12 @@ generate_classfile (tree clas, struct jcf_partial *state)
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);
......
......@@ -230,6 +230,9 @@ typedef struct JCF GTY(()) {
#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)
......
......@@ -42,7 +42,7 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */
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);
tree * type_map;
......@@ -687,124 +687,142 @@ set_java_signature (tree type, tree sig)
#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.) */
/* Like lookup_argument_method, but lets the caller set any flags
desired. */
tree
lookup_argument_method2 (tree searched_class, tree method_name, tree method_signature)
lookup_argument_method_generic (tree searched_class, tree method_name,
tree method_signature, int flags)
{
return lookup_do (CLASSTYPE_SUPER (searched_class), searched_class,
return lookup_do (searched_class, flags,
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,
NULL_TREE, build_null_signature) != NULL_TREE;
return lookup_do (class, SEARCH_INTERFACE,
method_name, NULL_TREE,
build_null_signature) != NULL_TREE;
}
/* Search in class SEARCHED_CLASS (and its superclasses) for a method
matching METHOD_NAME and signature SIGNATURE. Also search in
SEARCHED_INTERFACE (and its superinterfaces) for a similar match.
matching METHOD_NAME and signature SIGNATURE. FLAGS control some
parameters of the search.
SEARCH_INTERFACE means also search interfaces and superinterfaces
of SEARCHED_CLASS.
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.
Return the matched method DECL or NULL_TREE. SIGNATURE_BUILDER is
used on method candidates to build their (sometimes partial)
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)
{
/* 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);
}
......
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