]> git.ipfire.org Git - thirdparty/gcc.git/blob - libobjc/Object.m
In gcc/: 2010-10-06 Nicola Pero <nicola.pero@meta-innovation.com>
[thirdparty/gcc.git] / libobjc / Object.m
1 /* The implementation of class Object for Objective-C.
2 Copyright (C) 1993, 1994, 1995, 1997, 2002, 2009 Free Software Foundation, Inc.
3
4 This file is part of GCC.
5
6 GCC is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 3, or (at your option) any
9 later version.
10
11 GCC is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
14 License for more details.
15
16 Under Section 7 of GPL version 3, you are granted additional
17 permissions described in the GCC Runtime Library Exception, version
18 3.1, as published by the Free Software Foundation.
19
20 You should have received a copy of the GNU General Public License and
21 a copy of the GCC Runtime Library Exception along with this program;
22 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23 <http://www.gnu.org/licenses/>. */
24
25 #include "objc-private/common.h"
26 #include <stdarg.h>
27 #include <errno.h>
28 #include "objc/Object.h"
29 #include "objc/Protocol.h"
30 #include "objc/objc-api.h"
31
32 @implementation Object
33
34 + initialize
35 {
36 return self;
37 }
38
39 - init
40 {
41 return self;
42 }
43
44 + new
45 {
46 return [[self alloc] init];
47 }
48
49 + alloc
50 {
51 return class_create_instance(self);
52 }
53
54 - free
55 {
56 return object_dispose(self);
57 }
58
59 - copy
60 {
61 return [[self shallowCopy] deepen];
62 }
63
64 - shallowCopy
65 {
66 return object_copy(self);
67 }
68
69 - deepen
70 {
71 return self;
72 }
73
74 - deepCopy
75 {
76 return [self copy];
77 }
78
79 - (Class)class
80 {
81 return object_get_class(self);
82 }
83
84 - (Class)superClass
85 {
86 return object_get_super_class(self);
87 }
88
89 - (MetaClass)metaClass
90 {
91 return object_get_meta_class(self);
92 }
93
94 - (const char *)name
95 {
96 return object_get_class_name(self);
97 }
98
99 - self
100 {
101 return self;
102 }
103
104 - (unsigned int)hash
105 {
106 return (size_t)self;
107 }
108
109 - (BOOL)isEqual:anObject
110 {
111 return self==anObject;
112 }
113
114 - (int)compare:(id)anotherObject;
115 {
116 if ([self isEqual:anotherObject])
117 return 0;
118 // Ordering objects by their address is pretty useless,
119 // so subclasses should override this is some useful way.
120 else if ((id)self > anotherObject)
121 return 1;
122 else
123 return -1;
124 }
125
126 - (BOOL)isMetaClass
127 {
128 return NO;
129 }
130
131 - (BOOL)isClass
132 {
133 return object_is_class(self);
134 }
135
136 - (BOOL)isInstance
137 {
138 return object_is_instance(self);
139 }
140
141 - (BOOL)isKindOf:(Class)aClassObject
142 {
143 Class class;
144
145 for (class = self->isa; class!=Nil; class = class_get_super_class(class))
146 if (class==aClassObject)
147 return YES;
148 return NO;
149 }
150
151 - (BOOL)isMemberOf:(Class)aClassObject
152 {
153 return self->isa==aClassObject;
154 }
155
156 - (BOOL)isKindOfClassNamed:(const char *)aClassName
157 {
158 Class class;
159
160 if (aClassName!=NULL)
161 for (class = self->isa; class!=Nil; class = class_get_super_class(class))
162 if (!strcmp(class_get_class_name(class), aClassName))
163 return YES;
164 return NO;
165 }
166
167 - (BOOL)isMemberOfClassNamed:(const char *)aClassName
168 {
169 return ((aClassName!=NULL)
170 &&!strcmp(class_get_class_name(self->isa), aClassName));
171 }
172
173 + (BOOL)instancesRespondTo:(SEL)aSel
174 {
175 return class_get_instance_method(self, aSel)!=METHOD_NULL;
176 }
177
178 - (BOOL)respondsTo:(SEL)aSel
179 {
180 return ((object_is_instance(self)
181 ?class_get_instance_method(self->isa, aSel)
182 :class_get_class_method(self->isa, aSel))!=METHOD_NULL);
183 }
184
185 + (IMP)instanceMethodFor:(SEL)aSel
186 {
187 return method_get_imp(class_get_instance_method(self, aSel));
188 }
189
190 // Indicates if the receiving class or instance conforms to the given protocol
191 // not usually overridden by subclasses
192 //
193 // Modified 9/5/94 to always search the class object's protocol list, rather
194 // than the meta class.
195
196 + (BOOL) conformsTo: (Protocol*)aProtocol
197 {
198 size_t i;
199 struct objc_protocol_list* proto_list;
200 id parent;
201
202 for (proto_list = ((Class)self)->protocols;
203 proto_list; proto_list = proto_list->next)
204 {
205 for (i=0; i < proto_list->count; i++)
206 {
207 if ([proto_list->list[i] conformsTo: aProtocol])
208 return YES;
209 }
210 }
211
212 if ((parent = [self superClass]))
213 return [parent conformsTo: aProtocol];
214 else
215 return NO;
216 }
217
218 - (BOOL) conformsTo: (Protocol*)aProtocol
219 {
220 return [[self class] conformsTo:aProtocol];
221 }
222
223 - (IMP)methodFor:(SEL)aSel
224 {
225 return (method_get_imp(object_is_instance(self)
226 ?class_get_instance_method(self->isa, aSel)
227 :class_get_class_method(self->isa, aSel)));
228 }
229
230 + (struct objc_method_description *)descriptionForInstanceMethod:(SEL)aSel
231 {
232 return ((struct objc_method_description *)
233 class_get_instance_method(self, aSel));
234 }
235
236 - (struct objc_method_description *)descriptionForMethod:(SEL)aSel
237 {
238 return ((struct objc_method_description *)
239 (object_is_instance(self)
240 ?class_get_instance_method(self->isa, aSel)
241 :class_get_class_method(self->isa, aSel)));
242 }
243
244 - perform:(SEL)aSel
245 {
246 IMP msg = objc_msg_lookup(self, aSel);
247 if (!msg)
248 return [self error:"invalid selector passed to %s", sel_get_name(_cmd)];
249 return (*msg)(self, aSel);
250 }
251
252 - perform:(SEL)aSel with:anObject
253 {
254 IMP msg = objc_msg_lookup(self, aSel);
255 if (!msg)
256 return [self error:"invalid selector passed to %s", sel_get_name(_cmd)];
257 return (*msg)(self, aSel, anObject);
258 }
259
260 - perform:(SEL)aSel with:anObject1 with:anObject2
261 {
262 IMP msg = objc_msg_lookup(self, aSel);
263 if (!msg)
264 return [self error:"invalid selector passed to %s", sel_get_name(_cmd)];
265 return (*msg)(self, aSel, anObject1, anObject2);
266 }
267
268 - (retval_t)forward:(SEL)aSel :(arglist_t)argFrame
269 {
270 (void) argFrame; /* UNUSED */
271 return (retval_t)[self doesNotRecognize: aSel];
272 }
273
274 - (retval_t)performv:(SEL)aSel :(arglist_t)argFrame
275 {
276 return objc_msg_sendv(self, aSel, argFrame);
277 }
278
279 + poseAs:(Class)aClassObject
280 {
281 return class_pose_as(self, aClassObject);
282 }
283
284 - (Class)transmuteClassTo:(Class)aClassObject
285 {
286 if (object_is_instance(self))
287 if (class_is_class(aClassObject))
288 if (class_get_instance_size(aClassObject)==class_get_instance_size(isa))
289 if ([self isKindOf:aClassObject])
290 {
291 Class old_isa = isa;
292 isa = aClassObject;
293 return old_isa;
294 }
295 return nil;
296 }
297
298 - subclassResponsibility:(SEL)aSel
299 {
300 return [self error:"subclass should override %s", sel_get_name(aSel)];
301 }
302
303 - notImplemented:(SEL)aSel
304 {
305 return [self error:"method %s not implemented", sel_get_name(aSel)];
306 }
307
308 - shouldNotImplement:(SEL)aSel
309 {
310 return [self error:"%s should not implement %s",
311 object_get_class_name(self), sel_get_name(aSel)];
312 }
313
314 - doesNotRecognize:(SEL)aSel
315 {
316 return [self error:"%s does not recognize %s",
317 object_get_class_name(self), sel_get_name(aSel)];
318 }
319
320 - error:(const char *)aString, ...
321 {
322 #define FMT "error: %s (%s)\n%s\n"
323 char fmt[(strlen((char*)FMT)+strlen((char*)object_get_class_name(self))
324 +((aString!=NULL)?strlen((char*)aString):0)+8)];
325 va_list ap;
326
327 sprintf(fmt, FMT, object_get_class_name(self),
328 object_is_instance(self)?"instance":"class",
329 (aString!=NULL)?aString:"");
330 va_start(ap, aString);
331 objc_verror(self, OBJC_ERR_UNKNOWN, fmt, ap);
332 va_end(ap);
333 return nil;
334 #undef FMT
335 }
336
337 + (int)version
338 {
339 return class_get_version(self);
340 }
341
342 + setVersion:(int)aVersion
343 {
344 class_set_version(self, aVersion);
345 return self;
346 }
347 @end
348
349 /* The following methods were deprecated in GCC 4.6.0 and will be
350 removed in the next GCC release.
351 */
352
353 @implementation Object (Deprecated)
354
355 + (int)streamVersion: (TypedStream*)aStream
356 {
357 if (aStream->mode == OBJC_READONLY)
358 return objc_get_stream_class_version (aStream, self);
359 else
360 return class_get_version (self);
361 }
362
363 // These are used to write or read the instance variables
364 // declared in this particular part of the object. Subclasses
365 // should extend these, by calling [super read/write: aStream]
366 // before doing their own archiving. These methods are private, in
367 // the sense that they should only be called from subclasses.
368
369 - read: (TypedStream*)aStream
370 {
371 (void) aStream; /* UNUSED */
372 // [super read: aStream];
373 return self;
374 }
375
376 - write: (TypedStream*)aStream
377 {
378 (void) aStream; /* UNUSED */
379 // [super write: aStream];
380 return self;
381 }
382
383 - awake
384 {
385 // [super awake];
386 return self;
387 }
388
389 @end