OSDN Git Service

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