[gcjx] Patch: FYI: member classes and generic instantiation

Tom Tromey tromey@redhat.com
Wed Nov 2 17:10:00 GMT 2005


I'm checking this in on the gcjx branch.

This fixes some problems with inheritance of member classes in an
instantiation of a generic class.  Some of the earlier tests apply,
but this change also lets us compile:

    public class ic<E>
    {
      public static class ic1<E> extends ic<E> { }
      public static class ic2<E> extends ic1<E> { }
    }

Tom

Index: ChangeLog
from  Tom Tromey  <tromey@redhat.com>

	* model/class.hh (model_class::ensure_classes_inherited):
	Declare.
	* model/classinst.hh (model_class_instance::ensure_classes_inherited):
	Declare.
	* model/classinst.cc (ensure_classes_inherited): New method.
	(resolve_member_hook): Don't create member classes.
	* model/class.cc (ensure_classes_inherited): New method
	(do_resolve_classes): Use it.

Index: model/classinst.cc
===================================================================
--- model/classinst.cc	(revision 105959)
+++ model/classinst.cc	(working copy)
@@ -22,11 +22,11 @@
 #include "typedefs.hh"
 
 void
-model_class_instance::resolve_member_hook (resolution_scope *scope)
+model_class_instance::ensure_classes_inherited (resolution_scope *scope)
 {
-  parent->resolve_members ();
+  parent->resolve_classes ();
 
-  // Create member classes.
+  // Create our variants of member classes.
   for (std::map<std::string, ref_class>::const_iterator i
 	 = parent->member_classes.begin ();
        i != parent->member_classes.end ();
@@ -39,6 +39,23 @@
       member_classes[(*i).first] = mem;
     }
 
+  for (std::multimap<std::string, model_class *>::const_iterator i
+	 = parent->all_member_classes.begin ();
+       i != parent->all_member_classes.end ();
+       ++i)
+    {
+      model_class *mem = (*i).second;
+      if (! mem->static_p ())
+	mem = mem->apply_type_map (this, type_map);
+      all_member_classes.insert (std::make_pair ((*i).first, mem));
+    }
+}
+
+void
+model_class_instance::resolve_member_hook (resolution_scope *scope)
+{
+  parent->resolve_members ();
+
   // Create fields.
   for (std::list<ref_field>::const_iterator i = parent->fields.begin ();
        i != parent->fields.end ();
Index: model/class.hh
===================================================================
--- model/class.hh	(revision 105959)
+++ model/class.hh	(working copy)
@@ -264,6 +264,8 @@
   {
   }
 
+  virtual void ensure_classes_inherited (resolution_scope *);
+
   // Helper method used when creating a parameterized instance.
   void set_this_0 (const ref_field &t0)
   {
Index: model/classinst.hh
===================================================================
--- model/classinst.hh	(revision 105959)
+++ model/classinst.hh	(working copy)
@@ -36,6 +36,7 @@
 
   void resolve_member_hook (resolution_scope *);
   std::string get_signature_map_fragment ();
+  void ensure_classes_inherited (resolution_scope *);
 
 public:
 
Index: model/class.cc
===================================================================
--- model/class.cc	(revision 105957)
+++ model/class.cc	(working copy)
@@ -1148,6 +1148,38 @@
 }
 
 void
+model_class::ensure_classes_inherited (resolution_scope *scope)
+{
+  resolution_scope::push_iscope self_holder (scope, this);
+
+  // Insert our local classes into our map, then resolve the class
+  // envelope of each one.
+  for (std::map<std::string, ref_class>::const_iterator i
+	 = member_classes.begin ();
+       i != member_classes.end ();
+       ++i)
+    {
+      all_member_classes.insert (std::make_pair ((*i).first,
+						 (*i).second.get ()));
+    }
+
+  // Note we also handle inheritance before resolving.  This allows
+  // name lookup when resolving member types to work properly.
+  std::list<model_class *> all_super_types;
+  compute_super_types (all_super_types);
+  for (std::list<model_class *>::const_iterator class_it
+	 = all_super_types.begin ();
+       class_it != all_super_types.end ();
+       ++class_it)
+    {
+      (*class_it)->resolve_classes ();
+      inherit_types (*class_it);
+    }
+
+  ::resolve_classes (scope, member_classes);
+}
+
+void
 model_class::do_resolve_classes (resolution_scope *scope)
 {
   // First make sure the compilation unit has been resolved.
@@ -1273,33 +1305,7 @@
     std::cerr << error ("subclasses of %<java.lang.Throwable%> "
 			"cannot be generic");
 
-  resolution_scope::push_iscope self_holder (scope, this);
-
-  // Insert our local classes into our map, then resolve the class
-  // envelope of each one.  FIXME: this is bogus, but it is needed
-  // since our scoping approach is somewhat broken.  See the IScope
-  // idea in TODO.
-  // Double FIXME: we have IScope.. now what?
-  for (std::map<std::string, ref_class>::const_iterator i
-	 = member_classes.begin ();
-       i != member_classes.end ();
-       ++i)
-    {
-      all_member_classes.insert (std::make_pair ((*i).first,
-						 (*i).second.get ()));
-    }
-
-  // Note we also handle inheritance before resolving.  This allows
-  // name lookup when resolving member types to work properly.
-  std::list<model_class *> all_super_types;
-  compute_super_types (all_super_types);
-  for (std::list<model_class *>::const_iterator class_it
-	 = all_super_types.begin ();
-       class_it != all_super_types.end ();
-       ++class_it)
-    inherit_types (*class_it);
-
-  ::resolve_classes (scope, member_classes);
+  ensure_classes_inherited (scope);
 }
 
 void



More information about the Java-patches mailing list