1 // Note that test ARCLayoutsWithoutWeak uses the same files
2 // with different build options.
7 $C{COMPILE_NOLINK_NOMEM} -c $DIR/MRCBase.m -o $T{OBJDIR}/MRCBase.o
8 $C{COMPILE_NOLINK_NOMEM} -c $DIR/MRCARC.m -o $T{OBJDIR}/MRCARC.o
9 $C{COMPILE_NOLINK} -c $DIR/ARCBase.m -o $T{OBJDIR}/ARCBase.o
10 $C{COMPILE_NOLINK} -c $DIR/ARCMRC.m -o $T{OBJDIR}/ARCMRC.o
11 $C{COMPILE} '-DNAME=\"ARCLayouts.m\"' -fobjc-arc $DIR/ARCLayouts.m -x none $T{OBJDIR}/MRCBase.o $T{OBJDIR}/MRCARC.o $T{OBJDIR}/ARCBase.o $T{OBJDIR}/ARCMRC.o -framework Foundation -o ARCLayouts.exe
17 #import <Foundation/Foundation.h>
18 #import <objc/runtime.h>
23 @interface NSObject (Layouts)
24 + (const char *)strongLayout;
25 + (const char *)weakLayout;
28 void printlayout(const char *name, const uint8_t *layout)
30 if (!testverbose()) return;
32 testprintf("%s: ", name);
34 // these use fprintf() to avoid repeated VERBOSE: in the middle of the line
36 fprintf(stderr, "NULL\n");
41 for (c = layout; *c; c++) {
42 fprintf(stderr, "%02x ", *c);
45 fprintf(stderr, "00\n");
48 @implementation NSObject (Layouts)
50 + (const char *)strongLayout {
51 const uint8_t *layout = class_getIvarLayout(self);
52 printlayout("strong", layout);
53 return (const char *)layout;
56 + (const char *)weakLayout {
57 const uint8_t *weakLayout = class_getWeakIvarLayout(self);
58 printlayout("weak", weakLayout);
59 return (const char *)weakLayout;
62 + (Ivar)instanceVariable:(const char *)name {
63 return class_getInstanceVariable(self, name);
68 void checkMM(Class cls, const char *ivarName,
69 objc_ivar_memory_management_t mmExpected)
71 Ivar ivar = [cls instanceVariable:ivarName];
72 objc_ivar_memory_management_t mm = _class_getIvarMemoryManagement(cls,ivar);
73 testprintf("%s->%s want %d, got %d\n",
74 class_getName(cls), ivarName, mmExpected, mm);
75 testassert(mmExpected == mm);
78 int main (int argc __unused, const char * argv[] __unused) {
80 testprintf("ARCMRC\n");
81 testassert(strcmp([ARCMRC strongLayout], "\x01") == 0);
82 testassert([ARCMRC weakLayout] == NULL);
85 // Verify that ARCBase->misalign and MRCBase->alignment did their thing.
86 testassert(ivar_getOffset(class_getInstanceVariable([ARCBase class], "misalign2")) & 1);
87 testassert(ivar_getOffset(class_getInstanceVariable([MRCBase class], "alignment")) > (ptrdiff_t)sizeof(void*));
89 testprintf("ARCMisalign\n");
90 testassert([ARCMisalign strongLayout] == NULL);
91 testassert([ARCMisalign weakLayout] == NULL);
93 testprintf("ARCBase\n");
94 if (strcmp([ARCBase strongLayout], "\x11\x30") == 0) {
95 testwarn("1130 layout is a compiler flaw but doesn't fail");
97 testassert(strcmp([ARCBase strongLayout], "\x11") == 0);
99 testassert(strcmp([ARCBase weakLayout], "\x31") == 0);
101 testprintf("MRCARC\n");
102 testassert([MRCARC strongLayout] == NULL);
103 testassert([MRCARC weakLayout] == NULL);
105 testprintf("MRCBase\n");
106 // MRC marks __weak only.
107 testassert([MRCBase strongLayout] == NULL);
108 if (supportsMRCWeak) {
109 testassert(strcmp([MRCBase weakLayout], "\x71") == 0);
111 testassert([MRCBase weakLayout] == nil);
114 // now check consistency between dynamic accessors and KVC, etc.
115 ARCMRC *am = [ARCMRC new];
116 MRCARC *ma = [MRCARC new];
118 NSString *amValue = [[NSString alloc] initWithFormat:@"%s %p", "ARCMRC", am];
119 NSString *amValue2 = [[NSString alloc] initWithFormat:@"%s %p", "ARCMRC", am];
120 NSString *maValue = [[NSString alloc] initWithFormat:@"%s %p", "MRCARC", ma];
121 NSString *maValue2 = [[NSString alloc] initWithFormat:@"%s %p", "MRCARC", ma];
125 object_setIvar(am, [ARCMRC instanceVariable:"object"], amValue);
126 testassert(CFGetRetainCount((__bridge CFTypeRef)amValue) == 1);
127 testassert(am.object == amValue);
129 object_setIvarWithStrongDefault(am, [ARCMRC instanceVariable:"object"], amValue2);
130 testassert(CFGetRetainCount((__bridge CFTypeRef)amValue2) == 2);
131 testassert(am.object == amValue2);
133 am.pointer = @selector(ARCMRC);
135 object_setIvar(am, [ARCMRC instanceVariable:"delegate"], ma);
136 testassert(CFGetRetainCount((__bridge CFTypeRef)ma) == 1);
137 testassert(am.delegate == ma);
139 object_setIvarWithStrongDefault(am, [ARCMRC instanceVariable:"delegate"], ma);
140 testassert(CFGetRetainCount((__bridge CFTypeRef)ma) == 1);
141 testassert(am.delegate == ma);
146 object_setIvar(ma, [MRCARC instanceVariable:"object"], maValue);
147 testassert(CFGetRetainCount((__bridge CFTypeRef)maValue) == 2);
149 testassert(ma.object == maValue);
152 object_setIvarWithStrongDefault(ma, [MRCARC instanceVariable:"object"], maValue2);
153 testassert(CFGetRetainCount((__bridge CFTypeRef)maValue2) == 2);
155 testassert(ma.object == maValue2);
158 ma.pointer = @selector(MRCARC);
161 object_setIvar(ma, [MRCARC instanceVariable:"delegate"], am);
162 testassert(CFGetRetainCount((__bridge CFTypeRef)am) == 1);
164 testassert(ma.delegate == am);
167 object_setIvarWithStrongDefault(ma, [MRCARC instanceVariable:"delegate"], am);
168 testassert(CFGetRetainCount((__bridge CFTypeRef)am) == 1);
170 testassert(ma.delegate == am);
174 // Verify that object_copy() handles ARC variables correctly.
176 MRCARC *ma2 = docopy(ma);
178 testassert(ma2 != ma);
179 testassert(CFGetRetainCount((__bridge CFTypeRef)maValue2) == 3);
180 testassert(CFGetRetainCount((__bridge CFTypeRef)am) == 1);
181 testassert(ma2.number == ma.number);
182 testassert(ma2.object == ma.object);
184 testassert(ma2.delegate == ma.delegate);
186 testassert(ma2.pointer == ma.pointer);
189 // Test _class_getIvarMemoryManagement() SPI
191 objc_ivar_memory_management_t memoryMRCWeak =
192 supportsMRCWeak ? objc_ivar_memoryWeak : objc_ivar_memoryUnknown;
193 checkMM([ARCMRC class], "number", objc_ivar_memoryUnknown);
194 checkMM([ARCMRC class], "object", objc_ivar_memoryUnknown);
195 checkMM([ARCMRC class], "pointer", objc_ivar_memoryUnknown);
196 checkMM([ARCMRC class], "delegate", memoryMRCWeak);
197 checkMM([ARCMRC class], "dataSource", objc_ivar_memoryStrong);
199 checkMM([MRCARC class], "number", objc_ivar_memoryUnretained);
200 checkMM([MRCARC class], "object", objc_ivar_memoryStrong);
201 checkMM([MRCARC class], "pointer", objc_ivar_memoryUnretained);
202 checkMM([MRCARC class], "delegate", objc_ivar_memoryWeak);
203 checkMM([MRCARC class], "dataSource", objc_ivar_memoryUnknown);
205 checkMM([ARCBase class], "number", objc_ivar_memoryUnretained);
206 checkMM([ARCBase class], "object", objc_ivar_memoryStrong);
207 checkMM([ARCBase class], "pointer", objc_ivar_memoryUnretained);
208 checkMM([ARCBase class], "delegate", objc_ivar_memoryWeak);
210 checkMM([MRCBase class], "number", objc_ivar_memoryUnknown);
211 checkMM([MRCBase class], "object", objc_ivar_memoryUnknown);
212 checkMM([MRCBase class], "pointer", objc_ivar_memoryUnknown);
213 checkMM([MRCBase class], "delegate", memoryMRCWeak);