}
}
-/* Check that CLASS_DECL somehoow implements all inherited abstract
+/* Check that CLASS_DECL somehow implements all inherited abstract
methods. */
static void
int saw_constructor = 0;
tree method;
tree class = CLASS_TO_HANDLE_TYPE (TREE_TYPE (class_decl));
- tree super_class = CLASSTYPE_SUPER (class);
tree saved_found_wfl = NULL_TREE, found = NULL_TREE;
tree mthrows;
}
sig = build_java_argument_signature (TREE_TYPE (method));
- found = lookup_argument_method (super_class, DECL_NAME (method), sig);
+ found = lookup_argument_method2 (class, DECL_NAME (method), sig);
/* Nothing overrides or it's a private method. */
if (!found)
saved_found_wfl = DECL_NAME (found);
reset_method_name (found);
+ /* If `found' is declared in an interface, make sure the
+ modifier matches. */
+ if (CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (found)))
+ && clinit_identifier_node != DECL_NAME (found)
+ && !METHOD_PUBLIC (method))
+ {
+ tree found_decl = TYPE_NAME (DECL_CONTEXT (found));
+ parse_error_context (method_wfl, "Class `%s' must override `%s' with a public method in order to implement interface `%s'",
+ IDENTIFIER_POINTER (DECL_NAME (class_decl)),
+ lang_printable_name (method, 0),
+ IDENTIFIER_POINTER (DECL_NAME (found_decl)));
+ }
+
/* Can't override a method with the same name and different return
types. */
if (TREE_TYPE (TREE_TYPE (found)) != TREE_TYPE (TREE_TYPE (method)))
{
- char *t = xstrdup (lang_printable_name (TREE_TYPE (TREE_TYPE (found)),
- 0));
+ char *t = xstrdup
+ (lang_printable_name (TREE_TYPE (TREE_TYPE (found)), 0));
parse_error_context
(method_wfl,
"Method `%s' was defined with return type `%s' in class `%s'",
- Overriding/hiding protected must be protected or public
- If the overriden or hidden method has default (package)
access, then the overriding or hiding method must not be
- private; otherwise, a compile-time error occurs */
- if ((METHOD_PUBLIC (found) && !METHOD_PUBLIC (method))
- || (METHOD_PROTECTED (found)
- && !(METHOD_PUBLIC (method) || METHOD_PROTECTED (method)))
- || (!(aflags & (ACC_PUBLIC | ACC_PRIVATE | ACC_STATIC))
- && METHOD_PRIVATE (method)))
+ private; otherwise, a compile-time error occurs. If
+ `found' belongs to an interface, things have been already
+ taken care of. */
+ if (!CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (found)))
+ && ((METHOD_PUBLIC (found) && !METHOD_PUBLIC (method))
+ || (METHOD_PROTECTED (found)
+ && !(METHOD_PUBLIC (method) || METHOD_PROTECTED (method)))
+ || (!(aflags & (ACC_PUBLIC | ACC_PRIVATE | ACC_STATIC))
+ && METHOD_PRIVATE (method))))
{
parse_error_context
(method_wfl,
static tree convert_ieee_real_to_integer PARAMS ((tree, tree));
static tree parse_signature_type PARAMS ((const unsigned char **,
const unsigned char *));
+static tree lookup_do PARAMS ((tree, tree, tree, tree, tree (*)(tree)));
tree * type_map;
extern struct obstack permanent_obstack;
#endif
}
-/* Search in class CLAS (and its superclasses) 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 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. */
tree
-lookup_argument_method (clas, method_name, method_signature)
- tree clas, method_name, method_signature;
+lookup_argument_method (searched_class, method_name, method_signature)
+ tree searched_class, method_name, method_signature;
{
- tree method;
- while (clas != NULL_TREE)
- {
- for (method = TYPE_METHODS (clas);
- method != NULL_TREE; method = TREE_CHAIN (method))
- {
- tree method_sig = build_java_argument_signature (TREE_TYPE (method));
- tree name = DECL_NAME (method);
- if ((TREE_CODE (name) == EXPR_WITH_FILE_LOCATION ?
- EXPR_WFL_NODE (name) : name) == method_name
- && method_sig == method_signature)
- return method;
- }
- clas = CLASSTYPE_SUPER (clas);
- }
- return NULL_TREE;
+ return lookup_do (searched_class, NULL_TREE, method_name, method_signature,
+ build_java_argument_signature);
}
-/* Search in class CLAS (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.) */
+/* 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.) */
tree
-lookup_java_method (searched_class, method_name, method_signature)
+lookup_argument_method2 (searched_class, method_name, method_signature)
tree searched_class, method_name, method_signature;
{
- tree method;
- tree currently_searched = searched_class;
+ return lookup_do (CLASSTYPE_SUPER (searched_class), searched_class,
+ method_name, method_signature,
+ build_java_argument_signature);
+}
- while (currently_searched != NULL_TREE)
- {
- for (method = TYPE_METHODS (currently_searched);
- method != NULL_TREE; method = TREE_CHAIN (method))
- {
- tree method_sig = build_java_signature (TREE_TYPE (method));
- tree name = DECL_NAME (method);
+/* 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
+ SEARCHED_CLASS is an interface, search it too. */
- if ((TREE_CODE (name) == EXPR_WITH_FILE_LOCATION ?
- EXPR_WFL_NODE (name) : name) == method_name
- && method_sig == method_signature)
- return method;
- }
- currently_searched = CLASSTYPE_SUPER (currently_searched);
- }
+tree
+lookup_java_method (searched_class, method_name, method_signature)
+ tree searched_class, method_name, 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,
+ method_signature, build_java_signature);
+}
- /* If this class is an interface class, search its superinterfaces as
- * well. A superinterface is not an interface's superclass: a
- * super interface is implemented by the interface.
- */
+/* Search in class SEARCHED_CLASS (an its superclasses) for a method
+ matching METHOD_NAME and signature SIGNATURE. Also search in
+ SEARCHED_INTERFACE (an 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. */
- currently_searched = searched_class;
- if (CLASS_INTERFACE (TYPE_NAME (currently_searched)))
+static tree
+lookup_do (searched_class, searched_interface, method_name, signature, signature_builder)
+ tree searched_class, searched_interface, method_name, signature;
+ tree (*signature_builder) PARAMS ((tree));
+{
+ tree method;
+
+ if (searched_interface)
{
int i;
int interface_len =
- TREE_VEC_LENGTH (TYPE_BINFO_BASETYPES (currently_searched)) - 1;
+ TREE_VEC_LENGTH (TYPE_BINFO_BASETYPES (searched_interface)) - 1;
for (i = interface_len; i > 0; i--)
{
tree child =
- TREE_VEC_ELT (TYPE_BINFO_BASETYPES (currently_searched), i);
+ 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_LOADED_P (iclass))
- load_class (iclass, 1);
+ 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 = build_java_signature (TREE_TYPE (method));
+ tree method_sig = (*signature_builder) (TREE_TYPE (method));
tree name = DECL_NAME (method);
if ((TREE_CODE (name) == EXPR_WITH_FILE_LOCATION ?
EXPR_WFL_NODE (name) : name) == method_name
- && method_sig == method_signature)
+ && method_sig == signature)
return method;
}
/* it could be defined in a supersuperinterface */
if (CLASS_INTERFACE (TYPE_NAME (iclass)))
{
- method = lookup_java_method (iclass,
- method_name,
- method_signature);
+ method = lookup_do (iclass, iclass, method_name,
+ signature, signature_builder);
if (method != NULL_TREE)
return method;
}
}
}
+
+ 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));
+ tree name = DECL_NAME (method);
+
+ if ((TREE_CODE (name) == EXPR_WITH_FILE_LOCATION ?
+ EXPR_WFL_NODE (name) : name) == method_name
+ && method_sig == signature)
+ return method;
+ }
+ searched_class = CLASSTYPE_SUPER (searched_class);
+ }
+
return NULL_TREE;
}