diff options
author | Alexandre Petit-Bianco <apbianco@gcc.gnu.org> | 2000-03-06 22:25:14 -0800 |
---|---|---|
committer | Alexandre Petit-Bianco <apbianco@gcc.gnu.org> | 2000-03-06 22:25:14 -0800 |
commit | 614eaae0a5de347b8fed549b0acdab2ef1b141d9 (patch) | |
tree | 21007f6e90dfbf502b8219c186d62fdeefad01e2 /gcc | |
parent | 141b58108437ef9f1984b78f194933f5b68bab22 (diff) | |
download | gcc-614eaae0a5de347b8fed549b0acdab2ef1b141d9.zip gcc-614eaae0a5de347b8fed549b0acdab2ef1b141d9.tar.gz gcc-614eaae0a5de347b8fed549b0acdab2ef1b141d9.tar.bz2 |
[multiple changes]
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.
From-SVN: r32376
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/java/ChangeLog | 22 | ||||
-rw-r--r-- | gcc/java/java-tree.h | 2 | ||||
-rw-r--r-- | gcc/java/parse.h | 1 | ||||
-rw-r--r-- | gcc/java/parse.y | 37 | ||||
-rw-r--r-- | gcc/java/typeck.c | 140 |
5 files changed, 132 insertions, 70 deletions
diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog index bd93e72..ce13683 100644 --- a/gcc/java/ChangeLog +++ b/gcc/java/ChangeLog @@ -1,3 +1,25 @@ +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. + 2000-03-06 Tom Tromey <tromey@cygnus.com> * Make-lang.in (JAVA_SRCS): Added boehm.c, lex.c. diff --git a/gcc/java/java-tree.h b/gcc/java/java-tree.h index 146893a..629061f 100644 --- a/gcc/java/java-tree.h +++ b/gcc/java/java-tree.h @@ -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 *, struct JCF *, int, const 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)); diff --git a/gcc/java/parse.h b/gcc/java/parse.h index ddc8fc1..04d8685 100644 --- a/gcc/java/parse.h +++ b/gcc/java/parse.h @@ -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)); diff --git a/gcc/java/parse.y b/gcc/java/parse.y index 35ab269..5406a3b 100644 --- a/gcc/java/parse.y +++ b/gcc/java/parse.y @@ -4762,7 +4762,7 @@ check_abstract_method_definitions (do_interface, class_decl, type) } } -/* 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, diff --git a/gcc/java/typeck.c b/gcc/java/typeck.c index aba0e20..4a46d42 100644 --- a/gcc/java/typeck.c +++ b/gcc/java/typeck.c @@ -37,6 +37,7 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */ 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; + 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; } |