Contributed by Kresten Krab Thorup
+load support contributed by Ovidiu Predescu <ovidiu@net-community.com>
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify it under the
+GCC is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 2, or (at your option) any later version.
-GNU CC is distributed in the hope that it will be useful, but WITHOUT ANY
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
details.
You should have received a copy of the GNU General Public License along with
-GNU CC; see the file COPYING. If not, write to the Free Software
-Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+GCC; see the file COPYING. If not, write to the Free Software
+Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
/* As a special exception, if you link this library with files compiled with
GCC to produce an executable, this does not cause the resulting executable
however invalidate any other reasons why the executable file might be
covered by the GNU General Public License. */
-#include "runtime.h"
+#include "objc/runtime.h"
/* The version number of this runtime. This must match the number
defined in gcc (objc-act.c). */
should not be destroyed during the execution of the program. */
static cache_ptr __objc_load_methods = NULL;
+/* This function is used when building the class tree used to send
+ ordinately the +load message to all classes needing it. The tree
+ is really needed so that superclasses will get the message before
+ subclasses.
+
+ This tree will contain classes which are being loaded (or have just
+ being loaded), and whose super_class pointers have not yet been
+ resolved. This implies that their super_class pointers point to a
+ string with the name of the superclass; when the first message is
+ sent to the class (/an object of that class) the class links will
+ be resolved, which will replace the super_class pointers with
+ pointers to the actual superclasses.
+
+ Unfortunately, the tree might also contain classes which had been
+ loaded previously, and whose class links have already been
+ resolved.
+
+ This function returns the superclass of a class in both cases, and
+ can be used to build the determine the class relationships while
+ building the tree.
+*/
+static Class class_superclass_of_class (Class class)
+{
+ char *super_class_name;
+
+ /* If the class links have been resolved, use the resolved
+ * links. */
+ if (CLS_ISRESOLV (class))
+ return class->super_class;
+
+ /* Else, 'class' has not yet been resolved. This means that its
+ * super_class pointer is really the name of the super class (rather
+ * than a pointer to the actual superclass). */
+ super_class_name = (char *)class->super_class;
+
+ /* Return Nil for a root class. */
+ if (super_class_name == NULL)
+ return Nil;
+
+ /* Lookup the superclass of non-root classes. */
+ return objc_lookup_class (super_class_name);
+}
+
+
/* Creates a tree of classes whose topmost class is directly inherited
from `upper' and the bottom class in this tree is
`bottom_class'. The classes in this tree are super classes of
tree = objc_calloc (1, sizeof (objc_class_tree));
tree->class = superclass;
tree->subclasses = list_cons (prev, tree->subclasses);
- superclass = (superclass->super_class ?
- objc_lookup_class ((char *) superclass->super_class)
- : Nil);
+ superclass = class_superclass_of_class (superclass);
prev = tree;
}
DEBUG_PRINTF ("1. class %s was previously inserted\n", class->name);
return tree;
}
- else if ((class->super_class ?
- objc_lookup_class ((char *) class->super_class)
- : Nil)
- == tree->class)
+ else if (class_superclass_of_class (class) == tree->class)
{
/* If class is a direct subclass of tree->class then add class to the
list of subclasses. First check to see if it wasn't already
Method_t mth = &method_list->method_list[i];
if (mth->method_name && sel_eq (mth->method_name, op)
- && ! hash_is_key_in_hash (__objc_load_methods, mth->method_imp))
+ && ! objc_hash_is_key_in_hash (__objc_load_methods, mth->method_imp))
{
/* Add this method into the +load hash table */
- hash_add (&__objc_load_methods, mth->method_imp, mth->method_imp);
+ objc_hash_add (&__objc_load_methods,
+ mth->method_imp,
+ mth->method_imp);
DEBUG_PRINTF ("sending +load in class: %s\n", class->name);
{
if (class == superclass)
return YES;
- class = (class->super_class ?
- objc_lookup_class ((char *) class->super_class)
- : Nil);
+ class = class_superclass_of_class (class);
}
return NO;
__objc_init_class_tables ();
__objc_init_dispatch_tables ();
__objc_class_tree_list = list_cons (NULL, __objc_class_tree_list);
- __objc_load_methods
- = hash_new (128, (hash_func_type)hash_ptr, compare_ptrs);
+ __objc_load_methods = objc_hash_new (128,
+ (hash_func_type)objc_hash_ptr,
+ objc_compare_ptrs);
previous_constructors = 1;
}