diff options
author | Jing Yu <jingyu@google.com> | 2010-07-22 14:03:48 -0700 |
---|---|---|
committer | Jing Yu <jingyu@google.com> | 2010-07-22 14:03:48 -0700 |
commit | b094d6c4bf572654a031ecc4afe675154c886dc5 (patch) | |
tree | 89394c56b05e13a5413ee60237d65b0214fd98e2 /gcc-4.4.3/libobjc/Protocol.m | |
parent | dc34721ac3bf7e3c406fba8cfe9d139393345ec5 (diff) | |
download | toolchain_gcc-b094d6c4bf572654a031ecc4afe675154c886dc5.tar.gz toolchain_gcc-b094d6c4bf572654a031ecc4afe675154c886dc5.tar.bz2 toolchain_gcc-b094d6c4bf572654a031ecc4afe675154c886dc5.zip |
commit gcc-4.4.3 which is used to build gcc-4.4.3 Android toolchain in master.
The source is based on fsf gcc-4.4.3 and contains local patches which
are recorded in gcc-4.4.3/README.google.
Change-Id: Id8c6d6927df274ae9749196a1cc24dbd9abc9887
Diffstat (limited to 'gcc-4.4.3/libobjc/Protocol.m')
-rw-r--r-- | gcc-4.4.3/libobjc/Protocol.m | 180 |
1 files changed, 180 insertions, 0 deletions
diff --git a/gcc-4.4.3/libobjc/Protocol.m b/gcc-4.4.3/libobjc/Protocol.m new file mode 100644 index 000000000..9fa7f9258 --- /dev/null +++ b/gcc-4.4.3/libobjc/Protocol.m @@ -0,0 +1,180 @@ +/* This file contains the implementation of class Protocol. + Copyright (C) 1993, 2004, 2009 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +<http://www.gnu.org/licenses/>. */ + +#include "objc/Protocol.h" +#include "objc/objc-api.h" + +/* Method description list */ +struct objc_method_description_list { + int count; + struct objc_method_description list[1]; +}; + + +@implementation Protocol +{ +@private + char *protocol_name; + struct objc_protocol_list *protocol_list; + struct objc_method_description_list *instance_methods, *class_methods; +} + +/* Obtaining attributes intrinsic to the protocol */ + +- (const char *)name +{ + return protocol_name; +} + +/* Testing protocol conformance */ + +- (BOOL) conformsTo: (Protocol *)aProtocolObject +{ + size_t i; + struct objc_protocol_list* proto_list; + + if (aProtocolObject == nil) + return NO; + + if (!strcmp(aProtocolObject->protocol_name, self->protocol_name)) + return YES; + + for (proto_list = protocol_list; proto_list; proto_list = proto_list->next) + { + for (i=0; i < proto_list->count; i++) + { + if ([proto_list->list[i] conformsTo: aProtocolObject]) + return YES; + } + } + + return NO; +} + +/* Looking up information specific to a protocol */ + +- (struct objc_method_description *) descriptionForInstanceMethod:(SEL)aSel +{ + int i; + struct objc_protocol_list* proto_list; + const char* name = sel_get_name (aSel); + struct objc_method_description *result; + + if (instance_methods) + for (i = 0; i < instance_methods->count; i++) + { + if (!strcmp ((char*)instance_methods->list[i].name, name)) + return &(instance_methods->list[i]); + } + + for (proto_list = protocol_list; proto_list; proto_list = proto_list->next) + { + size_t j; + for (j=0; j < proto_list->count; j++) + { + if ((result = [proto_list->list[j] + descriptionForInstanceMethod: aSel])) + return result; + } + } + + return NULL; +} + +- (struct objc_method_description *) descriptionForClassMethod:(SEL)aSel; +{ + int i; + struct objc_protocol_list* proto_list; + const char* name = sel_get_name (aSel); + struct objc_method_description *result; + + if (class_methods) + for (i = 0; i < class_methods->count; i++) + { + if (!strcmp ((char*)class_methods->list[i].name, name)) + return &(class_methods->list[i]); + } + + for (proto_list = protocol_list; proto_list; proto_list = proto_list->next) + { + size_t j; + for (j=0; j < proto_list->count; j++) + { + if ((result = [proto_list->list[j] + descriptionForClassMethod: aSel])) + return result; + } + } + + return NULL; +} + +- (unsigned) hash +{ + /* Compute a hash of the protocol_name; use the same hash algorithm + * that we use for class names; protocol names and class names are + * somewhat similar types of string spaces. + */ + int hash = 0, index; + + for (index = 0; protocol_name[index] != '\0'; index++) + { + hash = (hash << 4) ^ (hash >> 28) ^ protocol_name[index]; + } + + hash = (hash ^ (hash >> 10) ^ (hash >> 20)); + + return hash; +} + +/* + * Equality between formal protocols is only formal (nothing to do + * with actually checking the list of methods they have!). Two formal + * Protocols are equal if and only if they have the same name. + * + * Please note (for comparisons with other implementations) that + * checking the names is equivalent to checking that Protocol A + * conforms to Protocol B and Protocol B conforms to Protocol A, + * because this happens iff they have the same name. If they have + * different names, A conforms to B if and only if A includes B, but + * the situation where A includes B and B includes A is a circular + * dependency between Protocols which is forbidden by the compiler, so + * A conforms to B and B conforms to A with A and B having different + * names is an impossible case. + */ +- (BOOL) isEqual: (id)obj +{ + if (obj == self) + return YES; + + if ([obj isKindOf: [Protocol class]]) + { + if (strcmp (protocol_name, ((Protocol *)obj)->protocol_name) == 0) + return YES; + } + + return NO; +} +@end + |