From a6ed1ca0294dab57bcf2a813c716dc5b7ab0573c Mon Sep 17 00:00:00 2001 From: rmathew Date: Tue, 16 Aug 2005 18:22:31 +0000 Subject: [PATCH] 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. Minor adjustments to comments. (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. Minor adjustments to comments. (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). git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@103163 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/java/ChangeLog | 16 ++++++++ gcc/java/parse.y | 113 +++++++++++++++++++++++++++++------------------------ 2 files changed, 79 insertions(+), 50 deletions(-) diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog index b21f082..4985baa 100644 --- a/gcc/java/ChangeLog +++ b/gcc/java/ChangeLog @@ -1,3 +1,19 @@ +2005-08-16 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. Minor adjustments to comments. + (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. Minor adjustments to comments. + (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). + 2005-08-15 Tom Tromey PR java/23300. diff --git a/gcc/java/parse.y b/gcc/java/parse.y index 363d074..b1de35f 100644 --- a/gcc/java/parse.y +++ b/gcc/java/parse.y @@ -326,10 +326,10 @@ static tree build_nested_field_access (tree, tree); 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); @@ -8371,20 +8371,22 @@ build_nested_field_access (tree id, tree decl) return resolve_expression_name (access, NULL); } -/* Return a nonzero value if DECL describes a field access across nested +/* Return a nonzero value if DECL describes a member access across nested class boundaries. That is, DECL is in a class that either encloses, - is enclosed by or shares a common enclosing class with, the class + is enclosed by or shares a common enclosing class with the class 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,10 +8394,12 @@ nested_field_access_p (tree type, tree decl) && 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 + member we're trying to access, then this isn't a nested member access we need to worry about. */ if (!is_static && inherits_from_p (type, decl_type)) return 0; @@ -8672,10 +8676,10 @@ build_nested_field_access_method (tree class, tree type, tree name, /* This section deals with building access function necessary for - certain kinds of method invocation from inner classes. */ + certain kinds of method invocation across nested class boundaries. */ 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; @@ -8724,8 +8728,7 @@ build_outer_method_access_method (tree decl) start_artificial_method_body (mdecl); /* The actual method invocation uses the same args. When invoking a - static methods that way, we don't want to skip the first - argument. */ + static methods that way, we don't want to skip the first argument. */ carg = args; if (!METHOD_STATIC (decl)) carg = TREE_CHAIN (carg); @@ -8744,10 +8747,10 @@ build_outer_method_access_method (tree decl) end_artificial_method_body (mdecl); current_function_decl = saved_current_function_decl; - /* Back tag the access function so it know what it accesses */ + /* Back tag the access function so it know what it accesses. */ DECL_FUNCTION_ACCESS_DECL (decl) = mdecl; - /* Tag the current method so it knows it has an access generated */ + /* Tag the current method so it knows it has an access generated. */ return DECL_FUNCTION_INNER_ACCESS (decl) = mdecl; } @@ -9572,7 +9575,7 @@ resolve_expression_name (tree id, tree *orig) /* 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 +10132,7 @@ resolve_qualified_expression_name (tree wfl, tree *found_decl, 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 +10275,7 @@ resolve_qualified_expression_name (tree wfl, tree *found_decl, 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,16 +10575,22 @@ patch_method_invocation (tree patch, tree primary, tree where, int from_super, IDENTIFIER_POINTER (name)); PATCH_METHOD_RETURN_ERROR (); } - if (list && !METHOD_STATIC (list)) + if (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 (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 @@ -10698,7 +10707,7 @@ patch_method_invocation (tree patch, tree primary, tree where, int from_super, && DECL_NAME (list) == get_identifier ("clone")) is_array_clone_call = 1; - /* Check for static reference if non static methods */ + /* Check for static reference of non static methods. */ if (check_for_static_method_reference (wfl, patch, list, class_to_search, primary)) PATCH_METHOD_RETURN_ERROR (); @@ -10718,8 +10727,8 @@ patch_method_invocation (tree patch, tree primary, tree where, int from_super, } /* Non static methods are called with the current object extra - argument. If patch a `new TYPE()', the argument is the value - returned by the object allocator. If method is resolved as a + argument. If PATCH is a `new TYPE()', the argument is the value + returned by the object allocator. If method is resolved as a primary, use the primary otherwise use the current THIS. */ args = nreverse (args); if (TREE_CODE (patch) != NEW_CLASS_EXPR) @@ -10731,16 +10740,16 @@ patch_method_invocation (tree patch, tree primary, tree where, int from_super, 1) We're not generating bytecodes: - - LIST is non static. It's invocation is transformed from + - LIST is non-static. Its invocation is transformed from x(a1,...,an) into this$.x(a1,....an). - - LIST is static. It's invocation is transformed from + - LIST is static. Its invocation is transformed from x(a1,...,an) into TYPE_OF(this$).x(a1,....an) 2) We're generating bytecodes: - - LIST is non static. It's invocation is transformed from + - LIST is non-static. Its invocation is transformed from x(a1,....,an) into access$(this$,a1,...,an). - - LIST is static. It's invocation is transformed from + - LIST is static. Its invocation is transformed from x(a1,....,an) into TYPE_OF(this$).x(a1,....an). Of course, this$ can be arbitrarily complex, ranging from @@ -10749,10 +10758,12 @@ patch_method_invocation (tree patch, tree primary, tree where, int from_super, maybe_use_access_method returns a nonzero value if the 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)) + argument list. In the meantime, the selected function + might have been replaced by a generated stub. */ + 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 */ @@ -10920,8 +10931,8 @@ check_for_static_method_reference (tree wfl, tree node, tree method, return 0; } -/* Fix the invocation of *MDECL if necessary in the case of a - invocation from an inner class. *THIS_ARG might be modified +/* Fix the invocation of *MDECL if necessary in the case of an + invocation across a nested class. *THIS_ARG might be modified appropriately and an alternative access to *MDECL might be returned. */ @@ -10929,25 +10940,26 @@ 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 - what it takes to retrieve the right this. Don't do that if we're - invoking a static method. Note that if MD's type is unrelated to + what it takes to retrieve the right `this'. Don't do that if we're + invoking a static method. Note that if MD's type is unrelated to 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))) { @@ -10973,16 +10985,17 @@ maybe_use_access_method (int is_super_init, tree *mdecl, tree *this_arg) } /* We might have to use an access method to get to MD. We can - break the method access rule as far as we're not generating - bytecode */ + break the method access rule as long as we're not generating + 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 -- 2.7.4