OSDN Git Service

PR java/19870
authorrmathew <rmathew@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 16 Aug 2005 18:22:31 +0000 (18:22 +0000)
committerrmathew <rmathew@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 16 Aug 2005 18:22:31 +0000 (18:22 +0000)
* 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
gcc/java/parse.y

index b21f082..4985baa 100644 (file)
@@ -1,3 +1,19 @@
+2005-08-16  Ranjit Mathew  <rmathew@hotmail.com>
+
+       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  <tromey@redhat.com>
 
        PR java/23300.
index 363d074..b1de35f 100644 (file)
@@ -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,
 
 \f
 /* 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$<n>.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$<n>).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$<n>(this$<n>,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$<n>).x(a1,....an).
 
             Of course, this$<n> 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