2009-08-12 Richard Guenther <rguenther@suse.de>
[official-gcc.git] / libobjc / Object.m
blobb9eb72afc01f3e3891ae6d62288ca22dacdbb610
1 /* The implementation of class Object for Objective-C.
2    Copyright (C) 1993, 1994, 1995, 1997, 2002, 2009 Free Software Foundation, Inc.
4 This file is part of GCC.
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.
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.
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.
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/>.  */
25 #include <stdarg.h>
26 #include <errno.h>
27 #include "objc/Object.h"
28 #include "objc/Protocol.h"
29 #include "objc/objc-api.h"
31 #define MAX_CLASS_NAME_LEN 256
33 @implementation Object
35 + initialize
37   return self;
40 - init
42   return self;
45 + new
47   return [[self alloc] init];
50 + alloc
52   return class_create_instance(self);
55 - free
57   return object_dispose(self);
60 - copy
62   return [[self shallowCopy] deepen];
65 - shallowCopy
67   return object_copy(self);
70 - deepen
72   return self;
75 - deepCopy
77   return [self copy];
80 - (Class)class
82   return object_get_class(self);
85 - (Class)superClass
87   return object_get_super_class(self);
90 - (MetaClass)metaClass
92   return object_get_meta_class(self);
95 - (const char *)name
97   return object_get_class_name(self);
100 - self
102   return self;
105 - (unsigned int)hash
107   return (size_t)self;
110 - (BOOL)isEqual:anObject
112   return self==anObject;
115 - (int)compare:(id)anotherObject;
117   if ([self isEqual:anotherObject])
118     return 0;
119   // Ordering objects by their address is pretty useless, 
120   // so subclasses should override this is some useful way.
121   else if ((id)self > anotherObject)
122     return 1;
123   else 
124     return -1;
127 - (BOOL)isMetaClass
129   return NO;
132 - (BOOL)isClass
134   return object_is_class(self);
137 - (BOOL)isInstance
139   return object_is_instance(self);
142 - (BOOL)isKindOf:(Class)aClassObject
144   Class class;
146   for (class = self->isa; class!=Nil; class = class_get_super_class(class))
147     if (class==aClassObject)
148       return YES;
149   return NO;
152 - (BOOL)isMemberOf:(Class)aClassObject
154   return self->isa==aClassObject;
157 - (BOOL)isKindOfClassNamed:(const char *)aClassName
159   Class class;
161   if (aClassName!=NULL)
162     for (class = self->isa; class!=Nil; class = class_get_super_class(class))
163       if (!strcmp(class_get_class_name(class), aClassName))
164         return YES;
165   return NO;
168 - (BOOL)isMemberOfClassNamed:(const char *)aClassName
170   return ((aClassName!=NULL)
171           &&!strcmp(class_get_class_name(self->isa), aClassName));
174 + (BOOL)instancesRespondTo:(SEL)aSel
176   return class_get_instance_method(self, aSel)!=METHOD_NULL;
179 - (BOOL)respondsTo:(SEL)aSel
181   return ((object_is_instance(self)
182            ?class_get_instance_method(self->isa, aSel)
183            :class_get_class_method(self->isa, aSel))!=METHOD_NULL);
186 + (IMP)instanceMethodFor:(SEL)aSel
188   return method_get_imp(class_get_instance_method(self, aSel));
191 // Indicates if the receiving class or instance conforms to the given protocol
192 // not usually overridden by subclasses
194 // Modified 9/5/94 to always search the class object's protocol list, rather
195 // than the meta class.
197 + (BOOL) conformsTo: (Protocol*)aProtocol
199   size_t i;
200   struct objc_protocol_list* proto_list;
201   id parent;
203   for (proto_list = ((Class)self)->protocols;
204        proto_list; proto_list = proto_list->next)
205     {
206       for (i=0; i < proto_list->count; i++)
207       {
208         if ([proto_list->list[i] conformsTo: aProtocol])
209           return YES;
210       }
211     }
213   if ((parent = [self superClass]))
214     return [parent conformsTo: aProtocol];
215   else
216     return NO;
219 - (BOOL) conformsTo: (Protocol*)aProtocol
221   return [[self class] conformsTo:aProtocol];
224 - (IMP)methodFor:(SEL)aSel
226   return (method_get_imp(object_is_instance(self)
227                          ?class_get_instance_method(self->isa, aSel)
228                          :class_get_class_method(self->isa, aSel)));
231 + (struct objc_method_description *)descriptionForInstanceMethod:(SEL)aSel
233   return ((struct objc_method_description *)
234            class_get_instance_method(self, aSel));
237 - (struct objc_method_description *)descriptionForMethod:(SEL)aSel
239   return ((struct objc_method_description *)
240            (object_is_instance(self)
241             ?class_get_instance_method(self->isa, aSel)
242             :class_get_class_method(self->isa, aSel)));
245 - perform:(SEL)aSel
247   IMP msg = objc_msg_lookup(self, aSel);
248   if (!msg)
249     return [self error:"invalid selector passed to %s", sel_get_name(_cmd)];
250   return (*msg)(self, aSel);
253 - perform:(SEL)aSel with:anObject
255   IMP msg = objc_msg_lookup(self, aSel);
256   if (!msg)
257     return [self error:"invalid selector passed to %s", sel_get_name(_cmd)];
258   return (*msg)(self, aSel, anObject);
261 - perform:(SEL)aSel with:anObject1 with:anObject2
263   IMP msg = objc_msg_lookup(self, aSel);
264   if (!msg)
265     return [self error:"invalid selector passed to %s", sel_get_name(_cmd)];
266   return (*msg)(self, aSel, anObject1, anObject2);
269 - (retval_t)forward:(SEL)aSel :(arglist_t)argFrame
271   (void) argFrame; /* UNUSED */
272   return (retval_t)[self doesNotRecognize: aSel];
275 - (retval_t)performv:(SEL)aSel :(arglist_t)argFrame
277   return objc_msg_sendv(self, aSel, argFrame);
280 + poseAs:(Class)aClassObject
282   return class_pose_as(self, aClassObject);
285 - (Class)transmuteClassTo:(Class)aClassObject
287   if (object_is_instance(self))
288     if (class_is_class(aClassObject))
289       if (class_get_instance_size(aClassObject)==class_get_instance_size(isa))
290         if ([self isKindOf:aClassObject])
291           {
292             Class old_isa = isa;
293             isa = aClassObject;
294             return old_isa;
295           }
296   return nil;
299 - subclassResponsibility:(SEL)aSel
301   return [self error:"subclass should override %s", sel_get_name(aSel)];
304 - notImplemented:(SEL)aSel
306   return [self error:"method %s not implemented", sel_get_name(aSel)];
309 - shouldNotImplement:(SEL)aSel
311   return [self error:"%s should not implement %s", 
312                      object_get_class_name(self), sel_get_name(aSel)];
315 - doesNotRecognize:(SEL)aSel
317   return [self error:"%s does not recognize %s",
318                      object_get_class_name(self), sel_get_name(aSel)];
321 - error:(const char *)aString, ...
323 #define FMT "error: %s (%s)\n%s\n"
324   char fmt[(strlen((char*)FMT)+strlen((char*)object_get_class_name(self))
325             +((aString!=NULL)?strlen((char*)aString):0)+8)];
326   va_list ap;
328   sprintf(fmt, FMT, object_get_class_name(self),
329                     object_is_instance(self)?"instance":"class",
330                     (aString!=NULL)?aString:"");
331   va_start(ap, aString);
332   objc_verror(self, OBJC_ERR_UNKNOWN, fmt, ap);
333   va_end(ap);
334   return nil;
335 #undef FMT
338 + (int)version
340   return class_get_version(self);
343 + setVersion:(int)aVersion
345   class_set_version(self, aVersion);
346   return self;
349 + (int)streamVersion: (TypedStream*)aStream
351   if (aStream->mode == OBJC_READONLY)
352     return objc_get_stream_class_version (aStream, self);
353   else
354     return class_get_version (self);
357 // These are used to write or read the instance variables 
358 // declared in this particular part of the object.  Subclasses
359 // should extend these, by calling [super read/write: aStream]
360 // before doing their own archiving.  These methods are private, in
361 // the sense that they should only be called from subclasses.
363 - read: (TypedStream*)aStream
365   (void) aStream; /* UNUSED */
366   // [super read: aStream];  
367   return self;
370 - write: (TypedStream*)aStream
372   (void) aStream; /* UNUSED */
373   // [super write: aStream];
374   return self;
377 - awake
379   // [super awake];
380   return self;
383 @end