1 // TEST_CFLAGS -framework Foundation -Wno-deprecated-declarations
2 // need Foundation to get NSObject compatibility additions for class Protocol
3 // because ARC calls [protocol retain]
8 #include <objc/runtime.h>
9 #include <objc/objc-internal.h>
12 #include <objc/Protocol.h>
16 +(id)proto1ClassMethod;
17 -(id)proto1InstanceMethod;
21 +(id)proto2ClassMethod;
22 -(id)proto2InstanceMethod;
25 @protocol Proto3 <Proto2>
26 +(id)proto3ClassMethod;
27 -(id)proto3InstanceMethod;
34 // Force some of Proto5's selectors out of address order rdar://10582325
35 SEL fn(int x) { if (x) return @selector(m12:); else return @selector(m22:); }
37 // This declaration order deliberately looks weird because it determines the
38 // selector address order on some architectures rdar://10582325
40 -(id)m11:(id<Proto1>)a;
41 -(void)m12:(id<Proto1>)a;
42 -(int)m13:(id<Proto1>)a;
43 +(void)m22:(TestRoot<Proto1>*)a;
44 +(int)m23:(TestRoot<Proto1>*)a;
45 +(TestRoot*)m21:(TestRoot<Proto1>*)a;
47 -(id(^)(id))m31:(id<Proto1>(^)(id<Proto1>))a;
48 -(void)m32:(id<Proto1>(^)(id<Proto1>))a;
49 -(int)m33:(id<Proto1>(^)(id<Proto1>))a;
50 +(void)m42:(TestRoot<Proto1>*(^)(TestRoot<Proto1>*))a;
51 +(int)m43:(TestRoot<Proto1>*(^)(TestRoot<Proto1>*))a;
52 +(TestRoot*(^)(TestRoot*))m41:(TestRoot<Proto1>*(^)(TestRoot<Proto1>*))a;
55 @protocol Proto6 <Proto5>
57 +(TestRoot*(^)(TestRoot*))n41:(TestRoot<Proto1>*(^)(TestRoot<Proto1>*))a;
65 #define SwiftV1MangledName "_TtP6Module15SwiftV1Protocol_"
69 __attribute__((objc_runtime_name(SwiftV1MangledName)))
70 @protocol SwiftV1Protocol
74 @interface Super : TestRoot <Proto1> @end
76 +(id)proto1ClassMethod { return self; }
77 -(id)proto1InstanceMethod { return self; }
80 @interface SubNoProtocols : Super @end
81 @implementation SubNoProtocols @end
83 @interface SuperNoProtocols : TestRoot @end
84 @implementation SuperNoProtocols
87 @interface SubProp : Super <Proto4> { int i; } @end
88 @implementation SubProp
96 Protocol * __unsafe_unretained *list;
97 Protocol *protocol, *empty;
99 struct objc_method_description *desc;
101 struct objc_method_description desc2;
102 objc_property_t *proplist;
105 protocol = @protocol(Proto3);
106 empty = @protocol(ProtoEmpty);
107 testassert(protocol);
111 testassert([protocol isKindOf:[Protocol class]]);
112 testassert([empty isKindOf:[Protocol class]]);
113 testassert(0 == strcmp([protocol name], "Proto3"));
114 testassert(0 == strcmp([empty name], "ProtoEmpty"));
116 testassert(0 == strcmp(protocol_getName(protocol), "Proto3"));
117 testassert(0 == strcmp(protocol_getName(empty), "ProtoEmpty"));
119 testassert(class_conformsToProtocol([Super class], @protocol(Proto1)));
120 testassert(!class_conformsToProtocol([SubProp class], @protocol(Proto1)));
121 testassert(class_conformsToProtocol([SubProp class], @protocol(Proto4)));
122 testassert(!class_conformsToProtocol([SubProp class], @protocol(Proto3)));
123 testassert(!class_conformsToProtocol([Super class], @protocol(Proto3)));
125 testassert(!protocol_conformsToProtocol(@protocol(Proto1), @protocol(Proto2)));
126 testassert(protocol_conformsToProtocol(@protocol(Proto3), @protocol(Proto2)));
127 testassert(!protocol_conformsToProtocol(@protocol(Proto2), @protocol(Proto3)));
130 testassert([@protocol(Proto1) isEqual:@protocol(Proto1)]);
131 testassert(! [@protocol(Proto1) isEqual:@protocol(Proto2)]);
133 testassert(protocol_isEqual(@protocol(Proto1), @protocol(Proto1)));
134 testassert(! protocol_isEqual(@protocol(Proto1), @protocol(Proto2)));
137 desc = [protocol descriptionForInstanceMethod:@selector(proto3InstanceMethod)];
139 testassert(desc->name == @selector(proto3InstanceMethod));
140 desc = [protocol descriptionForClassMethod:@selector(proto3ClassMethod)];
142 testassert(desc->name == @selector(proto3ClassMethod));
143 desc = [protocol descriptionForClassMethod:@selector(proto2ClassMethod)];
145 testassert(desc->name == @selector(proto2ClassMethod));
147 desc = [protocol descriptionForInstanceMethod:@selector(proto3ClassMethod)];
149 desc = [protocol descriptionForClassMethod:@selector(proto3InstanceMethod)];
151 desc = [empty descriptionForInstanceMethod:@selector(proto3ClassMethod)];
153 desc = [empty descriptionForClassMethod:@selector(proto3InstanceMethod)];
156 desc2 = protocol_getMethodDescription(protocol, @selector(proto3InstanceMethod), YES, YES);
157 testassert(desc2.name && desc2.types);
158 testassert(desc2.name == @selector(proto3InstanceMethod));
159 desc2 = protocol_getMethodDescription(protocol, @selector(proto3ClassMethod), YES, NO);
160 testassert(desc2.name && desc2.types);
161 testassert(desc2.name == @selector(proto3ClassMethod));
162 desc2 = protocol_getMethodDescription(protocol, @selector(proto2ClassMethod), YES, NO);
163 testassert(desc2.name && desc2.types);
164 testassert(desc2.name == @selector(proto2ClassMethod));
166 desc2 = protocol_getMethodDescription(protocol, @selector(proto3ClassMethod), YES, YES);
167 testassert(!desc2.name && !desc2.types);
168 desc2 = protocol_getMethodDescription(protocol, @selector(proto3InstanceMethod), YES, NO);
169 testassert(!desc2.name && !desc2.types);
170 desc2 = protocol_getMethodDescription(empty, @selector(proto3ClassMethod), YES, YES);
171 testassert(!desc2.name && !desc2.types);
172 desc2 = protocol_getMethodDescription(empty, @selector(proto3InstanceMethod), YES, NO);
173 testassert(!desc2.name && !desc2.types);
176 list = protocol_copyProtocolList(@protocol(Proto2), &count);
178 testassert(count == 0);
180 list = protocol_copyProtocolList(@protocol(Proto3), &count);
182 testassert(count == 1);
183 testassert(protocol_isEqual(list[0], @protocol(Proto2)));
184 testassert(!list[1]);
188 cls = objc_getClass("Super");
190 list = class_copyProtocolList(cls, &count);
192 testassert(list[count] == NULL);
193 testassert(count == 1);
194 testassert(0 == strcmp(protocol_getName(list[0]), "Proto1"));
198 cls = objc_getClass("SuperNoProtocols");
200 list = class_copyProtocolList(cls, &count);
202 testassert(count == 0);
205 cls = objc_getClass("SubNoProtocols");
207 list = class_copyProtocolList(cls, &count);
209 testassert(count == 0);
212 cls = objc_getClass("SuperNoProtocols");
214 list = class_copyProtocolList(cls, NULL);
217 cls = objc_getClass("Super");
219 list = class_copyProtocolList(cls, NULL);
224 list = class_copyProtocolList(NULL, &count);
226 testassert(count == 0);
229 // Check property added by protocol
230 cls = objc_getClass("SubProp");
234 list = class_copyProtocolList(cls, &count);
236 testassert(count == 1);
237 testassert(0 == strcmp(protocol_getName(list[0]), "Proto4"));
238 testassert(list[1] == NULL);
242 proplist = class_copyPropertyList(cls, &count);
243 testassert(proplist);
244 testassert(count == 1);
245 testassert(0 == strcmp(property_getName(proplist[0]), "i"));
246 testassert(proplist[1] == NULL);
249 // Check extended type encodings
250 testassert(_protocol_getMethodTypeEncoding(@protocol(Proto5), @selector(DoesNotExist), true, true) == NULL);
251 testassert(_protocol_getMethodTypeEncoding(NULL, @selector(m11), true, true) == NULL);
252 testassert(_protocol_getMethodTypeEncoding(@protocol(Proto5), @selector(m11), true, false) == NULL);
253 testassert(_protocol_getMethodTypeEncoding(@protocol(Proto5), @selector(m11), false, false) == NULL);
254 testassert(_protocol_getMethodTypeEncoding(@protocol(Proto5), @selector(m11), false, true) == NULL);
255 testassert(_protocol_getMethodTypeEncoding(@protocol(Proto5), @selector(m21), true, true) == NULL);
257 const char *types11 = "@24@0:8@\"<Proto1>\"16";
258 const char *types12 = "v24@0:8@\"<Proto1>\"16";
259 const char *types13 = "i24@0:8@\"<Proto1>\"16";
260 const char *types21 = "@\"TestRoot\"24@0:8@\"TestRoot<Proto1>\"16";
261 const char *types22 = "v24@0:8@\"TestRoot<Proto1>\"16";
262 const char *types23 = "i24@0:8@\"TestRoot<Proto1>\"16";
263 const char *types31 = "@?<@@?@>24@0:8@?<@\"<Proto1>\"@?@\"<Proto1>\">16";
264 const char *types32 = "v24@0:8@?<@\"<Proto1>\"@?@\"<Proto1>\">16";
265 const char *types33 = "i24@0:8@?<@\"<Proto1>\"@?@\"<Proto1>\">16";
266 const char *types41 = "@?<@\"TestRoot\"@?@\"TestRoot\">24@0:8@?<@\"TestRoot<Proto1>\"@?@\"TestRoot<Proto1>\">16";
267 const char *types42 = "v24@0:8@?<@\"TestRoot<Proto1>\"@?@\"TestRoot<Proto1>\">16";
268 const char *types43 = "i24@0:8@?<@\"TestRoot<Proto1>\"@?@\"TestRoot<Proto1>\">16";
270 const char *types11 = "@12@0:4@\"<Proto1>\"8";
271 const char *types12 = "v12@0:4@\"<Proto1>\"8";
272 const char *types13 = "i12@0:4@\"<Proto1>\"8";
273 const char *types21 = "@\"TestRoot\"12@0:4@\"TestRoot<Proto1>\"8";
274 const char *types22 = "v12@0:4@\"TestRoot<Proto1>\"8";
275 const char *types23 = "i12@0:4@\"TestRoot<Proto1>\"8";
276 const char *types31 = "@?<@@?@>12@0:4@?<@\"<Proto1>\"@?@\"<Proto1>\">8";
277 const char *types32 = "v12@0:4@?<@\"<Proto1>\"@?@\"<Proto1>\">8";
278 const char *types33 = "i12@0:4@?<@\"<Proto1>\"@?@\"<Proto1>\">8";
279 const char *types41 = "@?<@\"TestRoot\"@?@\"TestRoot\">12@0:4@?<@\"TestRoot<Proto1>\"@?@\"TestRoot<Proto1>\">8";
280 const char *types42 = "v12@0:4@?<@\"TestRoot<Proto1>\"@?@\"TestRoot<Proto1>\">8";
281 const char *types43 = "i12@0:4@?<@\"TestRoot<Proto1>\"@?@\"TestRoot<Proto1>\">8";
284 // Make sure some of Proto5's selectors are out of order rdar://10582325
285 // These comparisons deliberately look weird because they determine the
286 // selector order on some architectures.
287 testassert(sel_registerName("m11:") > sel_registerName("m12:") ||
288 sel_registerName("m21:") > sel_registerName("m22:") ||
289 sel_registerName("m32:") < sel_registerName("m31:") ||
290 sel_registerName("m42:") < sel_registerName("m41:") );
292 if (!_protocol_getMethodTypeEncoding(@protocol(Proto5), @selector(m11:), true, true)) {
293 fail("rdar://10492418 extended type encodings not present (is compiler old?)");
295 testassert(0 == strcmp(_protocol_getMethodTypeEncoding(@protocol(Proto5), @selector(m11:), true, true), types11));
296 testassert(0 == strcmp(_protocol_getMethodTypeEncoding(@protocol(Proto5), @selector(m12:), true, true), types12));
297 testassert(0 == strcmp(_protocol_getMethodTypeEncoding(@protocol(Proto5), @selector(m13:), true, true), types13));
298 testassert(0 == strcmp(_protocol_getMethodTypeEncoding(@protocol(Proto5), @selector(m21:), true, false), types21));
299 testassert(0 == strcmp(_protocol_getMethodTypeEncoding(@protocol(Proto5), @selector(m22:), true, false), types22));
300 testassert(0 == strcmp(_protocol_getMethodTypeEncoding(@protocol(Proto5), @selector(m23:), true, false), types23));
301 testassert(0 == strcmp(_protocol_getMethodTypeEncoding(@protocol(Proto5), @selector(m31:), false, true), types31));
302 testassert(0 == strcmp(_protocol_getMethodTypeEncoding(@protocol(Proto5), @selector(m32:), false, true), types32));
303 testassert(0 == strcmp(_protocol_getMethodTypeEncoding(@protocol(Proto5), @selector(m33:), false, true), types33));
304 testassert(0 == strcmp(_protocol_getMethodTypeEncoding(@protocol(Proto5), @selector(m41:), false, false), types41));
305 testassert(0 == strcmp(_protocol_getMethodTypeEncoding(@protocol(Proto5), @selector(m42:), false, false), types42));
306 testassert(0 == strcmp(_protocol_getMethodTypeEncoding(@protocol(Proto5), @selector(m43:), false, false), types43));
308 testassert(0 == strcmp(_protocol_getMethodTypeEncoding(@protocol(Proto6), @selector(n41:), false, false), types41));
309 testassert(0 == strcmp(_protocol_getMethodTypeEncoding(@protocol(Proto6), @selector(m41:), false, false), types41));
313 testassert(@protocol(SwiftV1Protocol) == objc_getProtocol("Module.SwiftV1Protocol"));
314 testassert(@protocol(SwiftV1Protocol) == objc_getProtocol(SwiftV1MangledName));
315 testassert(0 == strcmp(protocol_getName(@protocol(SwiftV1Protocol)), "Module.SwiftV1Protocol"));
316 testassert(!objc_getProtocol("SwiftV1Protocol"));