OSDN Git Service

Daily bump.
[pf3gnuchains/gcc-fork.git] / libobjc / class.c
index 3fe3561..3b75082 100644 (file)
@@ -764,6 +764,15 @@ objc_get_meta_class (const char *name)
   return objc_get_class (name)->class_pointer;
 }
 
+/* This is not used by GCC, but the clang compiler seems to use it
+   when targetting the GNU runtime.  That's wrong, but we have it to
+   be compatible.  */
+Class
+objc_lookup_class (const char *name)
+{
+  return objc_getClass (name);
+}
+
 /* This is used when the implementation of a method changes.  It goes
    through all classes, looking for the ones that have these methods
    (either method_a or method_b; method_b can be NULL), and reloads
@@ -781,35 +790,57 @@ __objc_update_classes_with_methods (struct objc_method *method_a, struct objc_me
       
       while (node != NULL)
        {
-         /* Iterate over all methods in the class.  */
-         Class class = node->pointer;
-         struct objc_method_list * method_list = class->methods;
-
-         while (method_list)
+         /* We execute this loop twice: the first time, we iterate
+            over all methods in the class (instance methods), while
+            the second time we iterate over all methods in the meta
+            class (class methods).  */
+         Class class = Nil;
+         BOOL done = NO;
+
+         while (done == NO)
            {
-             int i;
+             struct objc_method_list * method_list;
 
-             for (i = 0; i < method_list->method_count; ++i)
+             if (class == Nil)
                {
-                 struct objc_method *method = &method_list->method_list[i];
+                 /* The first time, we work on the class.  */
+                 class = node->pointer;
+               }
+             else
+               {
+                 /* The second time, we work on the meta class.  */
+                 class = class->class_pointer;
+                 done = YES;
+               }
 
-                 /* If the method is one of the ones we are looking
-                    for, update the implementation.  */
-                 if (method == method_a)
-                   sarray_at_put_safe (class->dtable,
-                                       (sidx) method_a->method_name->sel_id,
-                                       method_a->method_imp);
+             method_list = class->methods;
 
-                 if (method == method_b)
+             while (method_list)
+               {
+                 int i;
+                 
+                 for (i = 0; i < method_list->method_count; ++i)
                    {
-                     if (method_b != NULL)
+                     struct objc_method *method = &method_list->method_list[i];
+                     
+                     /* If the method is one of the ones we are
+                        looking for, update the implementation.  */
+                     if (method == method_a)
                        sarray_at_put_safe (class->dtable,
-                                           (sidx) method_b->method_name->sel_id,
-                                           method_b->method_imp);
+                                           (sidx) method_a->method_name->sel_id,
+                                           method_a->method_imp);
+                     
+                     if (method == method_b)
+                       {
+                         if (method_b != NULL)
+                           sarray_at_put_safe (class->dtable,
+                                               (sidx) method_b->method_name->sel_id,
+                                               method_b->method_imp);
+                       }
                    }
+                 
+                 method_list = method_list->method_next;
                }
-         
-             method_list = method_list->method_next;
            }
          node = node->next;
        }
@@ -923,10 +954,18 @@ class_getSuperclass (Class class_)
   if (class_ == Nil)
     return Nil;
 
-  /* Classes that are in construction are not resolved and can not be
-     resolved!  */
+  /* Classes that are in construction are not resolved, and still have
+     the class name (instead of a class pointer) in the
+     class_->super_class field.  In that case we need to lookup the
+     superclass name to return the superclass.  We can not resolve the
+     class until it is registered.  */
   if (CLS_IS_IN_CONSTRUCTION (class_))
-    return Nil;
+    {
+      if (CLS_ISMETA (class_))
+       return object_getClass ((id)objc_lookUpClass ((const char *)(class_->super_class)));
+      else
+       return objc_lookUpClass ((const char *)(class_->super_class));
+    }
 
   /* If the class is not resolved yet, super_class would point to a
      string (the name of the super class) as opposed to the actual