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