2010-09-30 Tobias Burnus <burnus@net-b.de>
[official-gcc.git] / libobjc / Object.m
blob3a5bcb31688c1336960e0078351871357cc3a727
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 "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"
32 @implementation Object
34 + initialize
36   return self;
39 - init
41   return self;
44 + new
46   return [[self alloc] init];
49 + alloc
51   return class_create_instance(self);
54 - free
56   return object_dispose(self);
59 - copy
61   return [[self shallowCopy] deepen];
64 - shallowCopy
66   return object_copy(self);
69 - deepen
71   return self;
74 - deepCopy
76   return [self copy];
79 - (Class)class
81   return object_get_class(self);
84 - (Class)superClass
86   return object_get_super_class(self);
89 - (MetaClass)metaClass
91   return object_get_meta_class(self);
94 - (const char *)name
96   return object_get_class_name(self);
99 - self
101   return self;
104 - (unsigned int)hash
106   return (size_t)self;
109 - (BOOL)isEqual:anObject
111   return self==anObject;
114 - (int)compare:(id)anotherObject;
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;
126 - (BOOL)isMetaClass
128   return NO;
131 - (BOOL)isClass
133   return object_is_class(self);
136 - (BOOL)isInstance
138   return object_is_instance(self);
141 - (BOOL)isKindOf:(Class)aClassObject
143   Class class;
145   for (class = self->isa; class!=Nil; class = class_get_super_class(class))
146     if (class==aClassObject)
147       return YES;
148   return NO;
151 - (BOOL)isMemberOf:(Class)aClassObject
153   return self->isa==aClassObject;
156 - (BOOL)isKindOfClassNamed:(const char *)aClassName
158   Class class;
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;
167 - (BOOL)isMemberOfClassNamed:(const char *)aClassName
169   return ((aClassName!=NULL)
170           &&!strcmp(class_get_class_name(self->isa), aClassName));
173 + (BOOL)instancesRespondTo:(SEL)aSel
175   return class_get_instance_method(self, aSel)!=METHOD_NULL;
178 - (BOOL)respondsTo:(SEL)aSel
180   return ((object_is_instance(self)
181            ?class_get_instance_method(self->isa, aSel)
182            :class_get_class_method(self->isa, aSel))!=METHOD_NULL);
185 + (IMP)instanceMethodFor:(SEL)aSel
187   return method_get_imp(class_get_instance_method(self, aSel));
190 // Indicates if the receiving class or instance conforms to the given protocol
191 // not usually overridden by subclasses
193 // Modified 9/5/94 to always search the class object's protocol list, rather
194 // than the meta class.
196 + (BOOL) conformsTo: (Protocol*)aProtocol
198   size_t i;
199   struct objc_protocol_list* proto_list;
200   id parent;
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     }
212   if ((parent = [self superClass]))
213     return [parent conformsTo: aProtocol];
214   else
215     return NO;
218 - (BOOL) conformsTo: (Protocol*)aProtocol
220   return [[self class] conformsTo:aProtocol];
223 - (IMP)methodFor:(SEL)aSel
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)));
230 + (struct objc_method_description *)descriptionForInstanceMethod:(SEL)aSel
232   return ((struct objc_method_description *)
233            class_get_instance_method(self, aSel));
236 - (struct objc_method_description *)descriptionForMethod:(SEL)aSel
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)));
244 - perform:(SEL)aSel
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);
252 - perform:(SEL)aSel with:anObject
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);
260 - perform:(SEL)aSel with:anObject1 with:anObject2
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);
268 - (retval_t)forward:(SEL)aSel :(arglist_t)argFrame
270   (void) argFrame; /* UNUSED */
271   return (retval_t)[self doesNotRecognize: aSel];
274 - (retval_t)performv:(SEL)aSel :(arglist_t)argFrame
276   return objc_msg_sendv(self, aSel, argFrame);
279 + poseAs:(Class)aClassObject
281   return class_pose_as(self, aClassObject);
284 - (Class)transmuteClassTo:(Class)aClassObject
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;
298 - subclassResponsibility:(SEL)aSel
300   return [self error:"subclass should override %s", sel_get_name(aSel)];
303 - notImplemented:(SEL)aSel
305   return [self error:"method %s not implemented", sel_get_name(aSel)];
308 - shouldNotImplement:(SEL)aSel
310   return [self error:"%s should not implement %s", 
311                      object_get_class_name(self), sel_get_name(aSel)];
314 - doesNotRecognize:(SEL)aSel
316   return [self error:"%s does not recognize %s",
317                      object_get_class_name(self), sel_get_name(aSel)];
320 - error:(const char *)aString, ...
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;
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
337 + (int)version
339   return class_get_version(self);
342 + setVersion:(int)aVersion
344   class_set_version(self, aVersion);
345   return self;
347 @end
349 /* The following methods were deprecated in GCC 4.6.0 and will be
350    removed in the next GCC release.
353 @implementation Object (Deprecated)
355 + (int)streamVersion: (TypedStream*)aStream
357   if (aStream->mode == OBJC_READONLY)
358     return objc_get_stream_class_version (aStream, self);
359   else
360     return class_get_version (self);
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.
369 - read: (TypedStream*)aStream
371   (void) aStream; /* UNUSED */
372   // [super read: aStream];  
373   return self;
376 - write: (TypedStream*)aStream
378   (void) aStream; /* UNUSED */
379   // [super write: aStream];
380   return self;
383 - awake
385   // [super awake];
386   return self;
389 @end