X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;ds=sidebyside;f=libobjc%2Fclass.c;h=3b750829f3bc232ab9514102c0a3542ff3bae6d0;hb=47d1945f3e78f90bb7a0cb9c4744bec150530bfc;hp=3fe3561d2acceef10c29f18663d6b2de4d70e9c0;hpb=3930fde0cc1b76846fd0f4ee14fb33e4b5715911;p=pf3gnuchains%2Fgcc-fork.git diff --git a/libobjc/class.c b/libobjc/class.c index 3fe3561d2ac..3b750829f3b 100644 --- a/libobjc/class.c +++ b/libobjc/class.c @@ -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