This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Java: Fix to PR #108 + interface dispatch fix.
- To: egcs-patches at egcs dot cygnus dot com
- Subject: [PATCH] Java: Fix to PR #108 + interface dispatch fix.
- From: Alexandre Petit-Bianco <apbianco at cygnus dot com>
- Date: Mon, 6 Mar 2000 22:28:03 -0800
- Reply-to: apbianco at redhat dot com
I'm checking in this fix to PR #108, which also includes an interface
dispatch fix from Godmar Back:
http://sourceware.cygnus.com/ml/java-prs/1999-q4/msg00174.html
http://gcc.gnu.org/ml/gcc-patches/1999-12/msg00539.html
./A
2000-03-06 Bryce McKinlay <bryce@albatross.co.nz>
* typeck.c (lookup_do): Search superinterfaces first
when looking up an interface method. From Godmar Back
<gback@cs.utah.edu>
2000-03-02 Alexandre Petit-Bianco <apbianco@cygnus.com>
* java-tree.h (lookup_argument_method2): Declared.
(safe_layout_class): Prototype moved from parse.h.
* parse.h (safe_layout_class): Prototype moved to java-tree.h.
* parse.y (java_check_regular_methods): Local `super_class' gone.
Call lookup_argument_method2 instead of lookup_argument_method.
Perform modifier match for methods found declared in implemented
interfaces. Fixed indentation problem. Overriding/hiding error
report to take place only for methods found in classes.
* typeck.c (lookup_argument_method): Changed leading
comment. Re-written by calling lookup_do.
(lookup_argument_method2): New function.
(lookup_java_method): Re-written by calling lookup_do.
(lookup_do): New function.
Index: java-tree.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/java/java-tree.h,v
retrieving revision 1.56
diff -u -p -r1.56 java-tree.h
--- java-tree.h 2000/03/04 22:27:35 1.56
+++ java-tree.h 2000/03/07 06:16:24
@@ -510,6 +510,7 @@ extern tree lookup_class PARAMS ((tree))
extern tree lookup_java_constructor PARAMS ((tree, tree));
extern tree lookup_java_method PARAMS ((tree, tree, tree));
extern tree lookup_argument_method PARAMS ((tree, tree, tree));
+extern tree lookup_argument_method2 PARAMS ((tree, tree, tree));
extern tree promote_type PARAMS ((tree));
extern tree get_constant PARAMS ((struct JCF*, int));
extern tree get_name_constant PARAMS ((struct JCF*, int));
@@ -665,6 +666,7 @@ extern char* open_class PARAMS ((char *,
# endif /* JCF_USE_STDIO */
#endif
void java_debug_context PARAMS ((void));
+void safe_layout_class PARAMS ((tree));
extern tree get_boehm_type_descriptor PARAMS ((tree));
Index: parse.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/java/parse.h,v
retrieving revision 1.45
diff -u -p -r1.45 parse.h
--- parse.h 2000/02/29 02:34:48 1.45
+++ parse.h 2000/03/07 06:16:26
@@ -678,7 +678,6 @@ struct parser_ctxt {
};
#ifndef JC1_LITE
-void safe_layout_class PARAMS ((tree));
void java_complete_class PARAMS ((void));
void java_check_circular_reference PARAMS ((void));
void java_fix_constructors PARAMS ((void));
Index: parse.y
===================================================================
RCS file: /cvs/gcc/egcs/gcc/java/parse.y,v
retrieving revision 1.136
diff -u -p -r1.136 parse.y
--- parse.y 2000/02/26 02:05:35 1.136
+++ parse.y 2000/03/07 06:16:54
@@ -4762,7 +4762,7 @@ check_abstract_method_definitions (do_in
}
}
-/* Check that CLASS_DECL somehoow implements all inherited abstract
+/* Check that CLASS_DECL somehow implements all inherited abstract
methods. */
static void
@@ -4807,7 +4807,6 @@ java_check_regular_methods (class_decl)
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;
@@ -4859,7 +4858,7 @@ java_check_regular_methods (class_decl)
}
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)
@@ -4875,12 +4874,25 @@ java_check_regular_methods (class_decl)
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'",
@@ -4943,12 +4955,15 @@ java_check_regular_methods (class_decl)
- 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,
Index: typeck.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/java/typeck.c,v
retrieving revision 1.24
diff -u -p -r1.24 typeck.c
--- typeck.c 2000/02/26 19:56:23 1.24
+++ typeck.c 2000/03/07 06:16:55
@@ -37,6 +37,7 @@ The Free Software Foundation is independ
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;
@@ -713,106 +714,129 @@ set_java_signature (type, sig)
#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;
-
- 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);
+ return lookup_do (CLASSTYPE_SUPER (searched_class), searched_class,
+ method_name, method_signature,
+ build_java_argument_signature);
+}
- 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);
- }
+/* 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 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.
- */
+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);
+}
+
+/* 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;
}