re PR java/15715 (member interfaces are always static)
authorBryce McKinlay <mckinlay@redhat.com>
Sun, 27 Jun 2004 15:30:06 +0000 (15:30 +0000)
committerBryce McKinlay <bryce@gcc.gnu.org>
Sun, 27 Jun 2004 15:30:06 +0000 (16:30 +0100)
2004-06-26  Bryce McKinlay  <mckinlay@redhat.com>

       PR java/15715.
       * parse.y (create_interface): Set correct access modifiers for
       interfaces.
       * jcf-write.c (get_classfile_modifiers): New function.
       (generate_classfile): Use get_classfile_modifiers, not
       get_access_flags.

2004-06-26  Bryce McKinlay  <mckinlay@redhat.com>

       * parse.y (register_incomplete_type): Set JDEP_ENCLOSING for "super"
       dependency to current parser context, not NULL_TREE, for top-level
       classes.
       (jdep_resolve_class): Enable member access check for all inner
       class dependencies.

From-SVN: r83734

gcc/java/ChangeLog
gcc/java/jcf-write.c
gcc/java/parse.y

index e3e1964cb55bdaf99f28a1e232218faad77039a4..e7594069ea7164ed82ad681bb6a7c15fe8e28f1c 100644 (file)
@@ -1,3 +1,20 @@
+2004-06-26  Bryce McKinlay  <mckinlay@redhat.com>
+
+       PR java/15715.
+       * parse.y (create_interface): Set correct access modifiers for
+       interfaces.
+       * jcf-write.c (get_classfile_modifiers): New function.
+       (generate_classfile): Use get_classfile_modifiers, not 
+       get_access_flags.
+
+2004-06-26  Bryce McKinlay  <mckinlay@redhat.com>
+
+       * parse.y (register_incomplete_type): Set JDEP_ENCLOSING for "super"
+       dependency to current parser context, not NULL_TREE, for top-level
+       classes.
+       (jdep_resolve_class): Enable member access check for all inner
+       class dependencies.
+
 2004-06-26  Bryce McKinlay  <mckinlay@redhat.com>
 
        * parse.y (qualify_and_find): Pass type decl, not identifier, to 
index b04d55985d9731fc2b6b79ac9c77f93ab49bbf54..8ead88661819d1a28062428be733588f52ab96d7 100644 (file)
@@ -304,6 +304,7 @@ static void perform_relocations (struct jcf_partial *);
 static void init_jcf_state (struct jcf_partial *, struct obstack *);
 static void init_jcf_method (struct jcf_partial *, tree);
 static void release_jcf_state (struct jcf_partial *);
+static int get_classfile_modifiers (tree class);
 static struct chunk * generate_classfile (tree, struct jcf_partial *);
 static struct jcf_handler *alloc_handler (struct jcf_block *,
                                          struct jcf_block *,
@@ -2886,6 +2887,32 @@ release_jcf_state (struct jcf_partial *state)
   obstack_free (state->chunk_obstack, state->first);
 }
 
+/* Get the access flags (modifiers) of a class (TYPE_DECL) to be used in the
+   access_flags field of the class file header.  */
+
+static int get_classfile_modifiers (tree class)
+{
+  /* These are the flags which are valid class file modifiers. 
+     See JVMS2 S4.1.  */
+  int valid_toplevel_class_flags = ACC_PUBLIC | ACC_FINAL | ACC_SUPER | 
+                                  ACC_INTERFACE | ACC_ABSTRACT;
+  int flags = get_access_flags (class);
+
+  /* ACC_SUPER should always be set, except for interfaces.  */
+  if (! (flags & ACC_INTERFACE))
+    flags |= ACC_SUPER;
+   
+  /* A protected member class becomes public at the top level. */
+  if (flags & ACC_PROTECTED)
+    flags |= ACC_PUBLIC;
+  /* Filter out flags that are not valid for a class or interface in the 
+     top-level access_flags field.  */
+  flags &= valid_toplevel_class_flags;
+
+  return flags;
+}
+
 /* Generate and return a list of chunks containing the class CLAS
    in the .class file representation.  The list can be written to a
    .class file using write_chunks.  Allocate chunks from obstack WORK. */
@@ -2921,9 +2948,7 @@ generate_classfile (tree clas, struct jcf_partial *state)
   else
     i = 8 + 2 * total_supers;
   ptr = append_chunk (NULL, i, state);
-  i = get_access_flags (TYPE_NAME (clas));
-  if (! (i & ACC_INTERFACE))
-    i |= ACC_SUPER;
+  i = get_classfile_modifiers (TYPE_NAME (clas));  
   PUT2 (i); /* access_flags */
   i = find_class_constant (&state->cpool, clas);  PUT2 (i);  /* this_class */
   if (clas == object_type_node)
index e4ad4cd2e2260ef7b6b0f707a30376e5f0df8d80..4d7f21865423b3c2935ea3291e999e02595551f8 100644 (file)
@@ -3852,6 +3852,13 @@ create_interface (int flags, tree id, tree super)
   /* Create a new decl if DECL is NULL, otherwise fix it */
   decl = maybe_create_class_interface_decl (decl, raw_name, q_name, id);
 
+  /* Interfaces are always abstract. */
+  flags |= ACC_ABSTRACT;
+
+  /* Inner interfaces are always static.  */
+  if (INNER_CLASS_DECL_P (decl))
+    flags |= ACC_STATIC;
+
   /* Set super info and mark the class a complete */
   set_super_info (ACC_INTERFACE | flags, TREE_TYPE (decl),
                  object_type_node, ctxp->interface_number);
@@ -5187,12 +5194,9 @@ register_incomplete_type (int kind, tree wfl, tree decl, tree ptr)
   JDEP_MISC (new) = NULL_TREE;
   /* For some dependencies, set the enclosing class of the current
      class to be the enclosing context */
-  if ((kind == JDEP_INTERFACE  || kind == JDEP_ANONYMOUS)
+  if ((kind == JDEP_INTERFACE || kind == JDEP_ANONYMOUS || kind == JDEP_SUPER)
       && GET_ENCLOSING_CPC ())
     JDEP_ENCLOSING (new) = TREE_VALUE (GET_ENCLOSING_CPC ());
-  else if (kind == JDEP_SUPER)
-    JDEP_ENCLOSING (new) = (GET_ENCLOSING_CPC () ?
-                           TREE_VALUE (GET_ENCLOSING_CPC ()) : NULL_TREE);
   else
     JDEP_ENCLOSING (new) = GET_CPC ();
   JDEP_GET_PATCH (new) = (tree *)NULL;
@@ -5512,7 +5516,7 @@ jdep_resolve_class (jdep *dep)
 
   if (!decl)
     complete_class_report_errors (dep);
-  else if (PURE_INNER_CLASS_DECL_P (decl))
+  else if (INNER_CLASS_DECL_P (decl))
     {
       tree inner = TREE_TYPE (decl);
       if (! CLASS_LOADED_P (inner))