]> gcc.gnu.org Git - gcc.git/blame - gcc/objc/init.c
Changed Class * to Class in order to match NEXTSTEP and OpenStep runtime.
[gcc.git] / gcc / objc / init.c
CommitLineData
c72fc2d9
TW
1/* GNU Objective C Runtime initialization
2 Copyright (C) 1993 Free Software Foundation, Inc.
3
4Author: Kresten Krab Thorup
5
6This file is part of GNU CC.
7
8GNU CC is free software; you can redistribute it and/or modify it under the
9 terms of the GNU General Public License as published by the Free Software
10 Foundation; either version 2, or (at your option) any later version.
11
12GNU CC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
15 details.
16
17You should have received a copy of the GNU General Public License along with
18 GNU CC; see the file COPYING. If not, write to the Free Software
19 Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
20
21/* As a special exception, if you link this library with files compiled with
22 GCC to produce an executable, this does not cause the resulting executable
23 to be covered by the GNU General Public License. This exception does not
24 however invalidate any other reasons why the executable file might be
25 covered by the GNU General Public License. */
26
27#include "runtime.h"
28
29/* The version number of this runtime. This must match the number
30 defined in gcc (objc-act.c) */
a39d31bc 31#define OBJC_VERSION 6
c72fc2d9
TW
32#define PROTOCOL_VERSION 2
33
34/* This list contains all modules currently loaded into the runtime */
35static struct objc_list* __objc_module_list = 0;
36
37/* This list contains all proto_list's not yet assigned class links */
38static struct objc_list* unclaimed_proto_list = 0;
39
40/* Check compiler vs runtime version */
41static void init_check_module_version(Module_t);
42
43/* Assign isa links to protos */
44static void __objc_init_protocols (struct objc_protocol_list* protos);
45
46/* Add protocol to class */
d0b57512 47static void __objc_class_add_protocols (Class*, struct objc_protocol_list*);
c72fc2d9
TW
48
49/* Is all categories/classes resolved? */
50BOOL __objc_dangling_categories = NO;
51
a39d31bc
KKT
52extern SEL
53__sel_register_typed_name (const char *name, const char *types,
54 struct objc_selector *orig);
55
56
c72fc2d9
TW
57/* This function is called by constructor functions generated for each
58 module compiled. (_GLOBAL_$I$...) The purpose of this function is to
59 gather the module pointers so that they may be processed by the
60 initialization routines as soon as possible */
61
62void
63__objc_exec_class (Module_t module)
64{
65 /* Has we processed any constructors previously? This flag used to
66 indicate that some global data structures need to be built. */
67 static BOOL previous_constructors = 0;
68
69 static struct objc_list* unclaimed_categories = 0;
70
71 /* The symbol table (defined in objc.h) generated by gcc */
72 Symtab_t symtab = module->symtab;
73
c72fc2d9
TW
74 /* Entry used to traverse hash lists */
75 struct objc_list** cell;
76
77 /* The table of selector references for this module */
a39d31bc 78 SEL selectors = symtab->refs;
c72fc2d9
TW
79
80 /* dummy counter */
81 int i;
82
83 DEBUG_PRINTF ("received module: %s\n", module->name);
84 /* check gcc version */
85 init_check_module_version(module);
86
87 /* On the first call of this routine, initialize some data structures. */
88 if (!previous_constructors)
89 {
90 __objc_init_selector_tables();
91 __objc_init_class_tables();
92 __objc_init_dispatch_tables();
93 previous_constructors = 1;
94 }
95
96 /* Save the module pointer for later processing. (not currently used) */
97 __objc_module_list = list_cons(module, __objc_module_list);
98
a39d31bc
KKT
99 /* Replace referenced selectors from names to SEL's. */
100 if (selectors)
101 {
102 for (i = 0; selectors[i].sel_id; ++i)
103 {
104 const char *name, *type;
105 name = (char*)selectors[i].sel_id;
106 type = (char*)selectors[i].sel_types;
107 __sel_register_typed_name (name, type,
108 (struct objc_selector*)&(selectors[i]));
109 }
110 }
111
c72fc2d9
TW
112 /* Parse the classes in the load module and gather selector information. */
113 DEBUG_PRINTF ("gathering selectors from module: %s\n", module->name);
114 for (i = 0; i < symtab->cls_def_cnt; ++i)
115 {
d0b57512 116 Class* class = (Class*) symtab->defs[i];
c72fc2d9
TW
117
118 /* Make sure we have what we think. */
119 assert (CLS_ISCLASS(class));
120 assert (CLS_ISMETA(class->class_pointer));
121 DEBUG_PRINTF ("phase 1, processing class: %s\n", class->name);
122
123 /* Store the class in the class table and assign class numbers. */
124 __objc_add_class_to_hash (class);
125
126 /* Register all of the selectors in the class and meta class. */
127 __objc_register_selectors_from_class (class);
d0b57512 128 __objc_register_selectors_from_class ((Class*) class->class_pointer);
c72fc2d9
TW
129
130 /* Install the fake dispatch tables */
131 __objc_install_premature_dtable(class);
132 __objc_install_premature_dtable(class->class_pointer);
133
134 if (class->protocols)
135 __objc_init_protocols (class->protocols);
136 }
137
c72fc2d9
TW
138 /* Process category information from the module. */
139 for (i = 0; i < symtab->cat_def_cnt; ++i)
140 {
141 Category_t category = symtab->defs[i + symtab->cls_def_cnt];
d0b57512 142 Class* class = objc_lookup_class (category->class_name);
c72fc2d9
TW
143
144 /* If the class for the category exists then append its methods. */
145 if (class)
146 {
147
148 DEBUG_PRINTF ("processing categories from (module,object): %s, %s\n",
149 module->name,
150 class->name);
151
152 /* Do instance methods. */
153 if (category->instance_methods)
154 class_add_method_list (class, category->instance_methods);
155
156 /* Do class methods. */
157 if (category->class_methods)
d0b57512 158 class_add_method_list ((Class*) class->class_pointer,
c72fc2d9
TW
159 category->class_methods);
160
161 if (category->protocols)
162 {
163 __objc_init_protocols (category->protocols);
164 __objc_class_add_protocols (class, category->protocols);
165 }
166
167 }
168 else
169 {
170 /* The object to which the category methods belong can't be found.
171 Save the information. */
172 unclaimed_categories = list_cons(category, unclaimed_categories);
173 }
174 }
175
176 /* Scan the unclaimed category hash. Attempt to attach any unclaimed
177 categories to objects. */
178 for (cell = &unclaimed_categories;
179 *cell;
a39d31bc 180 ({ if (*cell) cell = &(*cell)->tail; }))
c72fc2d9
TW
181 {
182 Category_t category = (*cell)->head;
d0b57512 183 Class* class = objc_lookup_class (category->class_name);
c72fc2d9
TW
184
185 if (class)
186 {
187 DEBUG_PRINTF ("attaching stored categories to object: %s\n",
188 class->name);
189
190 list_remove_head (cell);
191
192 if (category->instance_methods)
193 class_add_method_list (class, category->instance_methods);
194
195 if (category->class_methods)
d0b57512 196 class_add_method_list ((Class*) class->class_pointer,
c72fc2d9
TW
197 category->class_methods);
198
199 if (category->protocols)
200 {
201 __objc_init_protocols (category->protocols);
202 __objc_class_add_protocols (class, category->protocols);
203 }
204
205 }
206 }
207
208 if (unclaimed_proto_list && objc_lookup_class ("Protocol"))
209 {
210 list_mapcar (unclaimed_proto_list,(void(*)(void*))__objc_init_protocols);
211 list_free (unclaimed_proto_list);
212 unclaimed_proto_list = 0;
213 }
214
215}
216
217/* Sanity check the version of gcc used to compile `module'*/
218static void init_check_module_version(Module_t module)
219{
220 if ((module->version != OBJC_VERSION) || (module->size != sizeof (Module)))
221 {
222 fprintf (stderr, "Module %s version %d doesn't match runtime %d\n",
a39d31bc 223 module->name, (int)module->version, OBJC_VERSION);
c72fc2d9
TW
224 if(module->version > OBJC_VERSION)
225 fprintf (stderr, "Runtime (libobjc.a) is out of date\n");
226 else if (module->version < OBJC_VERSION)
227 fprintf (stderr, "Compiler (gcc) is out of date\n");
228 else
229 fprintf (stderr, "Objective C internal error -- bad Module size\n");
230 abort ();
231 }
232}
233
234static void
235__objc_init_protocols (struct objc_protocol_list* protos)
236{
237 int i;
eba92c95 238 static Class* proto_class = 0;
c72fc2d9
TW
239
240 if (! protos)
241 return;
242
eba92c95
RS
243 if (!proto_class)
244 proto_class = objc_lookup_class("Protocol");
c72fc2d9 245
eba92c95 246 if (!proto_class)
c72fc2d9
TW
247 {
248 unclaimed_proto_list = list_cons (protos, unclaimed_proto_list);
249 return;
250 }
251
2acb0388 252#if 0
c72fc2d9 253 assert (protos->next == 0); /* only single ones allowed */
2acb0388 254#endif
c72fc2d9
TW
255
256 for(i = 0; i < protos->count; i++)
257 {
eba92c95
RS
258 struct objc_protocol* aProto = protos->list[i];
259 if (((size_t)aProto->class_pointer) == PROTOCOL_VERSION)
260 {
261 /* assign class pointer */
262 aProto->class_pointer = proto_class;
263
264 /* init super protocols */
265 __objc_init_protocols (aProto->protocol_list);
266 }
267 else if (protos->list[i]->class_pointer != proto_class)
c72fc2d9
TW
268 {
269 fprintf (stderr,
0046ffa3 270 "Version %d doesn't match runtime protocol version %d\n",
a39d31bc 271 (int)((char*)protos->list[i]->class_pointer-(char*)0),
c72fc2d9
TW
272 PROTOCOL_VERSION);
273 abort ();
274 }
275 }
276}
277
d0b57512 278static void __objc_class_add_protocols (Class* class,
c72fc2d9
TW
279 struct objc_protocol_list* protos)
280{
c72fc2d9
TW
281 /* Well... */
282 if (! protos)
283 return;
284
285 /* Add it... */
286 protos->next = class->protocols;
287 class->protocols = protos;
288}
This page took 0.199357 seconds and 5 git commands to generate.