This is the mail archive of the java@gcc.gnu.org mailing list for the Java project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: Two - Elementry Questions



Alexandre Petit-Bianco writes:

> I'll look into the Java PR soon. The other one is a gcc PR
> (other/3970,) the last reported error needs to be investigated.

Here's a patch for the Java PR (java/4007.)

> When compiling to bytecode, which seems to be what you're aiming at,
> the only problem I see has been reported in the Java specific PR
> mentioned earlier (java/4007.)

It looks like it works now.

./A

2001-08-16  Alexandre Petit-Bianco  <apbianco@redhat.com>

	* jcf-parse.c (load_class): New locals saved and class_loaded. If
	loading a class_or_name fails, try considering an innerclass name
	and load the enclosing context.
	* parse.y (resolve_inner_class): New function.
	(find_as_inner_class): Added leading comment.
	(register_incomplete_type): Keep the current context as enclosing
	context for JDEP_FIELD dependencies.
	(do_resolve_class): Locals new_class_decl and super initialized to
	NULL. Call resolve_inner_class, explore the enclosing context
	superclass if necessary.

Index: jcf-parse.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/jcf-parse.c,v
retrieving revision 1.89
diff -u -p -r1.89 jcf-parse.c
--- jcf-parse.c	2001/07/11 20:51:46	1.89
+++ jcf-parse.c	2001/08/17 03:41:44
@@ -650,7 +650,8 @@ load_class (class_or_name, verbose)
      tree class_or_name;
      int verbose;
 {
-  tree name;
+  tree name, saved;
+  int class_loaded;
 
   /* class_or_name can be the name of the class we want to load */
   if (TREE_CODE (class_or_name) == IDENTIFIER_NODE)
@@ -663,8 +664,31 @@ load_class (class_or_name, verbose)
   else
     name = DECL_NAME (TYPE_NAME (class_or_name));
 
-  if (read_class (name) == 0 && verbose)
-    error ("Cannot find file for class %s.", IDENTIFIER_POINTER (name));
+  saved = name;
+  while (1)
+    {
+      char *dollar;
+
+      if ((class_loaded = read_class (name)))
+	break;
+
+      /* We failed loading name. Now consider that we might be looking
+	 for a inner class but it's only available in source for in
+	 its enclosing context. */
+      if ((dollar = strrchr (IDENTIFIER_POINTER (name), '$')))
+	{
+	  int c = *dollar;
+	  *dollar = '\0';
+	  name = get_identifier (IDENTIFIER_POINTER (name));
+	  *dollar = c;
+	}
+      /* Otherwise, we failed, we bail. */
+      else
+	break;
+    }
+
+  if (!class_loaded && verbose)
+    error ("Cannot find file for class %s.", IDENTIFIER_POINTER (saved));
 }
 
 /* Parse the .class file JCF. */
Index: parse.y
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/parse.y,v
retrieving revision 1.299
diff -u -p -r1.299 parse.y
--- parse.y	2001/08/09 04:19:12	1.299
+++ parse.y	2001/08/17 01:53:04
@@ -300,6 +302,8 @@ static tree maybe_make_nested_class_name
 static void make_nested_class_name PARAMS ((tree));
 static void set_nested_class_simple_name_value PARAMS ((tree, int));
 static void link_nested_class_to_enclosing PARAMS ((void));
+static tree resolve_inner_class PARAMS ((struct hash_table *, tree, tree *,
+					 tree *, tree));
 static tree find_as_inner_class PARAMS ((tree, tree, tree));
 static tree find_as_inner_class_do PARAMS ((tree, tree));
 static int check_inner_class_redefinition PARAMS ((tree, tree));
@@ -3528,6 +3529,74 @@ check_inner_class_redefinition (raw_name
   return 0;
 }
 
+/* Tries to find a decl for CLASS_TYPE within ENCLOSING. If we fail,
+   we remember ENCLOSING and SUPER.  */
+
+static tree
+resolve_inner_class (circularity_hash, cl, enclosing, super, class_type)
+     struct hash_table *circularity_hash;
+     tree cl, *enclosing, *super, class_type;
+{
+  tree local_enclosing = *enclosing;
+  tree local_super = NULL_TREE;
+
+  while (local_enclosing)
+    {
+      tree intermediate, decl;
+
+      hash_lookup (circularity_hash, 
+		   (const  hash_table_key) local_enclosing, TRUE, NULL);
+
+      if ((decl = find_as_inner_class (local_enclosing, class_type, cl)))
+	return decl;
+
+      intermediate = local_enclosing;
+      /* Explore enclosing contexts. */
+      while (INNER_CLASS_DECL_P (intermediate))
+	{
+	  intermediate = DECL_CONTEXT (intermediate);
+	  if ((decl = find_as_inner_class (intermediate, class_type, cl)))
+	    return decl;
+	}
+
+      /* Now go to the upper classes, bail out if necessary. We will
+	 analyze the returned SUPER and act accordingly (see
+	 do_resolve_class.) */
+      local_super = CLASSTYPE_SUPER (TREE_TYPE (local_enclosing));
+      if (!local_super || local_super == object_type_node)
+        break;
+
+      if (TREE_CODE (local_super) == POINTER_TYPE)
+        local_super = do_resolve_class (NULL, local_super, NULL, NULL);
+      else
+	local_super = TYPE_NAME (local_super);
+
+      /* We may not have checked for circular inheritance yet, so do so
+         here to prevent an infinite loop. */
+      if (hash_lookup (circularity_hash,
+		       (const hash_table_key) local_super, FALSE, NULL))
+        {
+          if (!cl)
+            cl = lookup_cl (local_enclosing);
+	  
+          parse_error_context
+            (cl, "Cyclic inheritance involving %s",
+	     IDENTIFIER_POINTER (DECL_NAME (local_enclosing)));
+	  local_enclosing = NULL_TREE;
+        }
+      local_enclosing = local_super;
+    }
+
+  /* We failed. Return LOCAL_SUPER and LOCAL_ENCLOSING. */
+  *super = local_super;
+  *enclosing = local_enclosing;
+
+  return NULL_TREE;
+}
+
+/* Within ENCLOSING, find a decl for NAME and return it. NAME can be
+   qualified. */
+
 static tree
 find_as_inner_class (enclosing, name, cl)
      tree enclosing, name, cl;
@@ -5095,7 +5206,7 @@ register_incomplete_type (kind, wfl, dec
   /* For some dependencies, set the enclosing class of the current
      class to be the enclosing context */
   if ((kind == JDEP_SUPER || kind == JDEP_INTERFACE 
-       || kind == JDEP_ANONYMOUS || kind == JDEP_FIELD)
+       || kind == JDEP_ANONYMOUS)
       && GET_ENCLOSING_CPC ())
     JDEP_ENCLOSING (new) = TREE_VALUE (GET_ENCLOSING_CPC ());
   else
@@ -5574,7 +5685,7 @@ tree
 do_resolve_class (enclosing, class_type, decl, cl)
      tree enclosing, class_type, decl, cl;
 {
-  tree new_class_decl, super;
+  tree new_class_decl = NULL_TREE, super = NULL_TREE;
   struct hash_table _ht, *circularity_hash = &_ht;
 
   /* This hash table is used to register the classes we're going
@@ -5590,58 +5701,25 @@ do_resolve_class (enclosing, class_type,
      being loaded from class file. FIXME. */
   while (enclosing)
     {
-      tree intermediate;
-
-      hash_lookup (circularity_hash, 
-		   (const  hash_table_key) enclosing, TRUE, NULL);
-
-      if ((new_class_decl = find_as_inner_class (enclosing, class_type, cl)))
-	{
-	  hash_table_free (circularity_hash);
-	  return new_class_decl;
-	}
-
-      intermediate = enclosing;
-      /* Explore enclosing contexts. */
-      while (INNER_CLASS_DECL_P (intermediate))
-	{
-	  intermediate = DECL_CONTEXT (intermediate);
-	  if ((new_class_decl = find_as_inner_class (intermediate, 
-						     class_type, cl)))
-	    {
-	      hash_table_free (circularity_hash);
-	      return new_class_decl;
-	    }
-	}
-
-      /* Now go to the upper classes, bail out if necessary. */
-      super = CLASSTYPE_SUPER (TREE_TYPE (enclosing));
-      if (!super || super == object_type_node)
-        break;
+      new_class_decl = resolve_inner_class (circularity_hash, cl, &enclosing,
+					    &super, class_type);
+      if (new_class_decl)
+	break;
 
-      if (TREE_CODE (super) == POINTER_TYPE)
-        super = do_resolve_class (NULL, super, NULL, NULL);
+      /* If we haven't found anything because SUPER reached Object and
+	 ENCLOSING happens to be an innerclass, try the enclosing context. */
+      if ((!super || super == object_type_node) && 
+	  enclosing && INNER_CLASS_DECL_P (enclosing))
+	enclosing = DECL_CONTEXT (enclosing);
       else
-	super = TYPE_NAME (super);
-
-      /* We may not have checked for circular inheritance yet, so do so
-         here to prevent an infinite loop. */
-      if (hash_lookup (circularity_hash,
-		       (const hash_table_key) super, FALSE, NULL))
-        {
-          if (!cl)
-            cl = lookup_cl (enclosing);
-	  
-          parse_error_context
-            (cl, "Cyclic inheritance involving %s",
-	     IDENTIFIER_POINTER (DECL_NAME (enclosing)));
-          break;
-        }
-      enclosing = super;
+	enclosing = NULL_TREE;
     }
 
   hash_table_free (circularity_hash);
 
+  if (new_class_decl)
+    return new_class_decl;
+
   /* 1- Check for the type in single imports. This will change
      TYPE_NAME() if something relevant is found */
   find_in_imports (class_type);


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]