Fix for PR39557
[official-gcc.git] / libobjc / Object.m
blob38016085b4f56aeecfcc83e494016e8b1517ed4f
1 /* The implementation of class Object for Objective-C.
2    Copyright (C) 1993, 1994, 1995, 1997, 2002 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 2, 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 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING.  If not, write to
18 the Free Software Foundation, 51 Franklin Street, Fifth Floor,
19 Boston, MA 02110-1301, USA.  */
21 /* As a special exception, if you link this library with files compiled
22    with GCC to produce an executable, this does not cause the resulting
23    executable to be covered by the GNU General Public License.  This
24    exception does not however invalidate any other reasons why the
25    executable file might be covered by the GNU General Public License. */
27 #include <stdarg.h>
28 #include <errno.h>
29 #include "objc/Object.h"
30 #include "objc/Protocol.h"
31 #include "objc/objc-api.h"
33 #define MAX_CLASS_NAME_LEN 256
35 @implementation Object
37 + initialize
39   return self;
42 - init
44   return self;
47 + new
49   return [[self alloc] init];
52 + alloc
54   return class_create_instance(self);
57 - free
59   return object_dispose(self);
62 - copy
64   return [[self shallowCopy] deepen];
67 - shallowCopy
69   return object_copy(self);
72 - deepen
74   return self;
77 - deepCopy
79   return [self copy];
82 - (Class)class
84   return object_get_class(self);
87 - (Class)superClass
89   return object_get_super_class(self);
92 - (MetaClass)metaClass
94   return object_get_meta_class(self);
97 - (const char *)name
99   return object_get_class_name(self);
102 - self
104   return self;
107 - (unsigned int)hash
109   return (size_t)self;
112 - (BOOL)isEqual:anObject
114   return self==anObject;
117 - (int)compare:(id)anotherObject;
119   if ([self isEqual:anotherObject])
120     return 0;
121   // Ordering objects by their address is pretty useless, 
122   // so subclasses should override this is some useful way.
123   else if ((id)self > anotherObject)
124     return 1;
125   else 
126     return -1;
129 - (BOOL)isMetaClass
131   return NO;
134 - (BOOL)isClass
136   return object_is_class(self);
139 - (BOOL)isInstance
141   return object_is_instance(self);
144 - (BOOL)isKindOf:(Class)aClassObject
146   Class class;
148   for (class = self->isa; class!=Nil; class = class_get_super_class(class))
149     if (class==aClassObject)
150       return YES;
151   return NO;
154 - (BOOL)isMemberOf:(Class)aClassObject
156   return self->isa==aClassObject;
159 - (BOOL)isKindOfClassNamed:(const char *)aClassName
161   Class class;
163   if (aClassName!=NULL)
164     for (class = self->isa; class!=Nil; class = class_get_super_class(class))
165       if (!strcmp(class_get_class_name(class), aClassName))
166         return YES;
167   return NO;
170 - (BOOL)isMemberOfClassNamed:(const char *)aClassName
172   return ((aClassName!=NULL)
173           &&!strcmp(class_get_class_name(self->isa), aClassName));
176 + (BOOL)instancesRespondTo:(SEL)aSel
178   return class_get_instance_method(self, aSel)!=METHOD_NULL;
181 - (BOOL)respondsTo:(SEL)aSel
183   return ((object_is_instance(self)
184            ?class_get_instance_method(self->isa, aSel)
185            :class_get_class_method(self->isa, aSel))!=METHOD_NULL);
188 + (IMP)instanceMethodFor:(SEL)aSel
190   return method_get_imp(class_get_instance_method(self, aSel));
193 // Indicates if the receiving class or instance conforms to the given protocol
194 // not usually overridden by subclasses
196 // Modified 9/5/94 to always search the class object's protocol list, rather
197 // than the meta class.
199 + (BOOL) conformsTo: (Protocol*)aProtocol
201   size_t i;
202   struct objc_protocol_list* proto_list;
203   id parent;
205   for (proto_list = ((Class)self)->protocols;
206        proto_list; proto_list = proto_list->next)
207     {
208       for (i=0; i < proto_list->count; i++)
209       {
210         if ([proto_list->list[i] conformsTo: aProtocol])
211           return YES;
212       }
213     }
215   if ((parent = [self superClass]))
216     return [parent conformsTo: aProtocol];
217   else
218     return NO;
221 - (BOOL) conformsTo: (Protocol*)aProtocol
223   return [[self class] conformsTo:aProtocol];
226 - (IMP)methodFor:(SEL)aSel
228   return (method_get_imp(object_is_instance(self)
229                          ?class_get_instance_method(self->isa, aSel)
230                          :class_get_class_method(self->isa, aSel)));
233 + (struct objc_method_description *)descriptionForInstanceMethod:(SEL)aSel
235   return ((struct objc_method_description *)
236            class_get_instance_method(self, aSel));
239 - (struct objc_method_description *)descriptionForMethod:(SEL)aSel
241   return ((struct objc_method_description *)
242            (object_is_instance(self)
243             ?class_get_instance_method(self->isa, aSel)
244             :class_get_class_method(self->isa, aSel)));
247 - perform:(SEL)aSel
249   IMP msg = objc_msg_lookup(self, aSel);
250   if (!msg)
251     return [self error:"invalid selector passed to %s", sel_get_name(_cmd)];
252   return (*msg)(self, aSel);
255 - perform:(SEL)aSel with:anObject
257   IMP msg = objc_msg_lookup(self, aSel);
258   if (!msg)
259     return [self error:"invalid selector passed to %s", sel_get_name(_cmd)];
260   return (*msg)(self, aSel, anObject);
263 - perform:(SEL)aSel with:anObject1 with:anObject2
265   IMP msg = objc_msg_lookup(self, aSel);
266   if (!msg)
267     return [self error:"invalid selector passed to %s", sel_get_name(_cmd)];
268   return (*msg)(self, aSel, anObject1, anObject2);
271 - (retval_t)forward:(SEL)aSel :(arglist_t)argFrame
273   (void) argFrame; /* UNUSED */
274   return (retval_t)[self doesNotRecognize: aSel];
277 - (retval_t)performv:(SEL)aSel :(arglist_t)argFrame
279   return objc_msg_sendv(self, aSel, argFrame);
282 + poseAs:(Class)aClassObject
284   return class_pose_as(self, aClassObject);
287 - (Class)transmuteClassTo:(Class)aClassObject
289   if (object_is_instance(self))
290     if (class_is_class(aClassObject))
291       if (class_get_instance_size(aClassObject)==class_get_instance_size(isa))
292         if ([self isKindOf:aClassObject])
293           {
294             Class old_isa = isa;
295             isa = aClassObject;
296             return old_isa;
297           }
298   return nil;
301 - subclassResponsibility:(SEL)aSel
303   return [self error:"subclass should override %s", sel_get_name(aSel)];
306 - notImplemented:(SEL)aSel
308   return [self error:"method %s not implemented", sel_get_name(aSel)];
311 - shouldNotImplement:(SEL)aSel
313   return [self error:"%s should not implement %s", 
314                      object_get_class_name(self), sel_get_name(aSel)];
317 - doesNotRecognize:(SEL)aSel
319   return [self error:"%s does not recognize %s",
320                      object_get_class_name(self), sel_get_name(aSel)];
323 - error:(const char *)aString, ...
325 #define FMT "error: %s (%s)\n%s\n"
326   char fmt[(strlen((char*)FMT)+strlen((char*)object_get_class_name(self))
327             +((aString!=NULL)?strlen((char*)aString):0)+8)];
328   va_list ap;
330   sprintf(fmt, FMT, object_get_class_name(self),
331                     object_is_instance(self)?"instance":"class",
332                     (aString!=NULL)?aString:"");
333   va_start(ap, aString);
334   objc_verror(self, OBJC_ERR_UNKNOWN, fmt, ap);
335   va_end(ap);
336   return nil;
337 #undef FMT
340 + (int)version
342   return class_get_version(self);
345 + setVersion:(int)aVersion
347   class_set_version(self, aVersion);
348   return self;
351 + (int)streamVersion: (TypedStream*)aStream
353   if (aStream->mode == OBJC_READONLY)
354     return objc_get_stream_class_version (aStream, self);
355   else
356     return class_get_version (self);
359 // These are used to write or read the instance variables 
360 // declared in this particular part of the object.  Subclasses
361 // should extend these, by calling [super read/write: aStream]
362 // before doing their own archiving.  These methods are private, in
363 // the sense that they should only be called from subclasses.
365 - read: (TypedStream*)aStream
367   (void) aStream; /* UNUSED */
368   // [super read: aStream];  
369   return self;
372 - write: (TypedStream*)aStream
374   (void) aStream; /* UNUSED */
375   // [super write: aStream];
376   return self;
379 - awake
381   // [super awake];
382   return self;
385 @end