Two - Elementry Questions
Alexandre Petit-Bianco
apbianco@cygnus.com
Thu Aug 16 22:43:00 GMT 2001
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);
More information about the Java
mailing list