1// TEST_CONFIG
2
3#include "test.h"
4#include "testroot.i"
5#include <stdint.h>
6#include <string.h>
7#include <objc/objc-runtime.h>
8
9@interface Super : TestRoot { 
10  @public
11    char superIvar;
12}
13@end
14
15@interface Sub : Super {
16  @public 
17    id subIvar;
18}
19@end
20
21@implementation Super @end
22@implementation Sub @end
23
24 
25int main()
26{
27    /* 
28       Runtime layout of Sub:
29         [0] isa
30         [1] superIvar
31         [2] subIvar
32    */
33    
34    Ivar ivar;
35    Sub *sub = [Sub new];
36    sub->subIvar = [Sub class];
37    testassert(((Class *)objc_unretainedPointer(sub))[2] == [Sub class]);
38
39    ivar = class_getInstanceVariable([Sub class], "subIvar");
40    testassert(ivar);
41    testassert(2*sizeof(intptr_t) == (size_t)ivar_getOffset(ivar));
42    testassert(0 == strcmp(ivar_getName(ivar), "subIvar"));
43    testassert(0 == strcmp(ivar_getTypeEncoding(ivar), "@"));
44
45    ivar = class_getInstanceVariable([Super class], "superIvar");
46    testassert(ivar);
47    testassert(sizeof(intptr_t) == (size_t)ivar_getOffset(ivar));
48    testassert(0 == strcmp(ivar_getName(ivar), "superIvar"));
49    testassert(0 == strcmp(ivar_getTypeEncoding(ivar), "c"));
50    testassert(ivar == class_getInstanceVariable([Sub class], "superIvar"));
51
52    ivar = class_getInstanceVariable([Super class], "subIvar");
53    testassert(!ivar);
54
55    ivar = class_getInstanceVariable(object_getClass([Sub class]), "subIvar");
56    testassert(!ivar);
57
58    ivar = class_getInstanceVariable([Sub class], "subIvar");
59    object_setIvar(sub, ivar, sub);
60    testassert(sub->subIvar == sub);
61    testassert(sub == object_getIvar(sub, ivar));
62
63    testassert(NULL == class_getInstanceVariable(NULL, "foo"));
64    testassert(NULL == class_getInstanceVariable([Sub class], NULL));
65    testassert(NULL == class_getInstanceVariable(NULL, NULL));
66
67    testassert(NULL == object_getIvar(sub, NULL));
68    testassert(NULL == object_getIvar(NULL, ivar));
69    testassert(NULL == object_getIvar(NULL, NULL));
70
71    object_setIvar(sub, NULL, NULL);
72    object_setIvar(NULL, ivar, NULL);
73    object_setIvar(NULL, NULL, NULL);
74
75#if !__has_feature(objc_arc)
76
77    uintptr_t value;
78
79    sub->subIvar = (id)10;
80    value = 0;
81    object_getInstanceVariable(sub, "subIvar", (void **)&value);
82    testassert(value == 10);
83
84    object_setInstanceVariable(sub, "subIvar", (id)11);
85    testassert(sub->subIvar == (id)11);
86
87    ivar = class_getInstanceVariable([Sub class], "subIvar");
88    testassert(ivar == object_getInstanceVariable(sub, "subIvar", NULL));
89
90    testassert(NULL == object_getInstanceVariable(sub, NULL, NULL));
91    testassert(NULL == object_getInstanceVariable(NULL, "foo", NULL));
92    testassert(NULL == object_getInstanceVariable(NULL, NULL, NULL));
93    value = 10;
94    testassert(NULL == object_getInstanceVariable(sub, NULL, (void **)&value));
95    testassert(value == 0);
96    value = 10;
97    testassert(NULL == object_getInstanceVariable(NULL, "foo", (void **)&value));
98    testassert(value == 0);
99    value = 10;
100    testassert(NULL == object_getInstanceVariable(NULL, NULL, (void **)&value));
101    testassert(value == 0);
102
103    testassert(NULL == object_setInstanceVariable(sub, NULL, NULL));
104    testassert(NULL == object_setInstanceVariable(NULL, "foo", NULL));
105    testassert(NULL == object_setInstanceVariable(NULL, NULL, NULL));
106#endif
107
108    succeed(__FILE__);
109    return 0;
110}
111