Index: ChangeLog from Ranjit Mathew PR java/19870 * parse.y (nested_field_access_p): Rename to nested_member_access_p and expand to handle method accesses across nested classes. (build_outer_method_access_method): Rename to build_nested_method_access_method. (resolve_expression_name): Use the newly-renamed nested_member_access_p method. (resolve_qualified_expression_name): Likewise. (patch_method_invocation): Also consider static methods for access method generation. (maybe_use_access_method): Use the more general nested_memeber_access_p to determine access across nested class boundaries. Allow THIS_ARG to be NULL (for static methods). Index: parse.y =================================================================== --- parse.y 2005-08-13 11:39:50.000000000 +0530 +++ parse.y 2005-08-15 23:50:39.000000000 +0530 @@ -326,10 +326,10 @@ static tree build_nested_field_access (t static tree build_nested_field_access_methods (tree); static tree build_nested_field_access_method (tree, tree, tree, tree, tree); static tree build_nested_field_access_expr (int, tree, tree, tree, tree); -static tree build_outer_method_access_method (tree); +static tree build_nested_method_access_method (tree); static tree build_new_access_id (void); -static int nested_field_access_p (tree, tree); +static int nested_member_access_p (tree, tree); static int nested_field_expanded_access_p (tree, tree *, tree *, tree *); static tree nested_field_access_fix (tree, tree, tree); @@ -8377,14 +8377,16 @@ build_nested_field_access (tree id, tree TYPE. */ static int -nested_field_access_p (tree type, tree decl) +nested_member_access_p (tree type, tree decl) { bool is_static = false; tree decl_type = DECL_CONTEXT (decl); tree type_root, decl_type_root; if (decl_type == type - || (TREE_CODE (decl) != FIELD_DECL && TREE_CODE (decl) != VAR_DECL)) + || (TREE_CODE (decl) != FIELD_DECL + && TREE_CODE (decl) != VAR_DECL + && TREE_CODE (decl) != FUNCTION_DECL)) return 0; if (!INNER_CLASS_TYPE_P (type) @@ -8392,7 +8394,9 @@ nested_field_access_p (tree type, tree d && INNER_CLASS_TYPE_P (decl_type))) return 0; - is_static = FIELD_STATIC (decl); + is_static = (TREE_CODE (decl) == FUNCTION_DECL) + ? METHOD_STATIC (decl) + : FIELD_STATIC (decl); /* If TYPE extends the declaration context of the non-static field we're trying to access, then this isn't a nested field @@ -8675,7 +8679,7 @@ build_nested_field_access_method (tree c certain kinds of method invocation from inner classes. */ static tree -build_outer_method_access_method (tree decl) +build_nested_method_access_method (tree decl) { tree saved_current_function_decl, mdecl; tree args = NULL_TREE, call_args = NULL_TREE; @@ -9572,7 +9576,7 @@ resolve_expression_name (tree id, tree * /* If we're processing an inner class and we're trying to access a field belonging to an outer class, build the access to the field. */ - if (nested_field_access_p (current_class, decl)) + if (nested_member_access_p (current_class, decl)) { if (!fs && CLASS_STATIC (TYPE_NAME (current_class))) { @@ -10129,7 +10133,7 @@ resolve_qualified_expression_name (tree if (TREE_CODE (*where_found) == POINTER_TYPE) *where_found = TREE_TYPE (*where_found); } - if (nested_field_access_p (current_class, decl)) + if (nested_member_access_p (current_class, decl)) decl = build_nested_field_access (qual_wfl, decl); } else @@ -10272,7 +10276,7 @@ resolve_qualified_expression_name (tree if (is_static && FIELD_PRIVATE (field_decl) && flag_emit_class_files - && nested_field_access_p (current_class, field_decl)) + && nested_member_access_p (current_class, field_decl)) field_decl = build_nested_field_access (qual_wfl, field_decl); /* This is the decl found and eventually the next one to @@ -10572,17 +10576,23 @@ patch_method_invocation (tree patch, tre IDENTIFIER_POINTER (name)); PATCH_METHOD_RETURN_ERROR (); } - if (list && !METHOD_STATIC (list)) - { - char *fct_name = xstrdup (lang_printable_name (list, 2)); - parse_error_context - (identifier_wfl, - "Can't make static reference to method %<%s %s%> in class %qs", - lang_printable_name (TREE_TYPE (TREE_TYPE (list)), 0), - fct_name, IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)))); - free (fct_name); - PATCH_METHOD_RETURN_ERROR (); - } + if (list) + { + if (METHOD_STATIC (list)) + maybe_use_access_method (0, &list, NULL); + else + { + char *fct_name = xstrdup (lang_printable_name (list, 2)); + parse_error_context + (identifier_wfl, + "Can't make static reference to method %<%s %s%> in class %qs", + lang_printable_name (TREE_TYPE (TREE_TYPE (list)), 0), + fct_name, + IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)))); + free (fct_name); + PATCH_METHOD_RETURN_ERROR (); + } + } } else this_arg = primary = resolved; @@ -10751,8 +10761,10 @@ patch_method_invocation (tree patch, tre this_arg has to be moved into the (then generated) stub argument list. In the meantime, the selected function might have be replaced by a generated stub. */ - if (!primary && - maybe_use_access_method (is_super_init, &list, &this_arg)) + if (METHOD_STATIC (list)) + maybe_use_access_method (0, &list, NULL); + else if (!primary && + maybe_use_access_method (is_super_init, &list, &this_arg)) { args = tree_cons (NULL_TREE, this_arg, args); this_arg = NULL_TREE; /* So it doesn't get chained twice */ @@ -10929,15 +10941,14 @@ static int maybe_use_access_method (int is_super_init, tree *mdecl, tree *this_arg) { tree ctx; - tree md = *mdecl, ta = *this_arg; + tree md = *mdecl, ta = NULL_TREE; int to_return = 0; int non_static_context = !METHOD_STATIC (md); if (is_super_init - || DECL_CONTEXT (md) == current_class - || !PURE_INNER_CLASS_TYPE_P (current_class) || DECL_FINIT_P (md) - || DECL_INSTINIT_P (md)) + || DECL_INSTINIT_P (md) + || !nested_member_access_p (current_class, md)) return 0; /* If we're calling a method found in an enclosing class, generate @@ -10946,8 +10957,10 @@ maybe_use_access_method (int is_super_in CURRENT_CLASS, then the current this can be used. */ if (non_static_context - && !inherits_from_p (current_class, DECL_CONTEXT (md))) + && !inherits_from_p (current_class, DECL_CONTEXT (md)) + && DECL_CONTEXT (TYPE_NAME (current_class))) { + ta = *this_arg; ctx = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (current_class))); if (inherits_from_p (ctx, DECL_CONTEXT (md))) { @@ -10977,12 +10990,13 @@ maybe_use_access_method (int is_super_in bytecode */ if (METHOD_PRIVATE (md) && flag_emit_class_files) { - md = build_outer_method_access_method (md); + md = build_nested_method_access_method (md); to_return = 1; } *mdecl = md; - *this_arg = ta; + if (this_arg) + *this_arg = ta; /* Returning a nonzero value indicates we were doing a non static method invocation that is now a static invocation. It will have