1// TEST_CONFIG 
2
3#include "test.h"
4
5#if !__OBJC2__
6
7int main()
8{
9    succeed(__FILE__)
10}
11
12#else
13
14#include <objc/objc-internal.h>
15
16// Reuse evil-class-def.m as a non-evil class definition.
17
18#define EVIL_SUPER 0
19#define EVIL_SUPER_META 0
20#define EVIL_SUB 0
21#define EVIL_SUB_META 0
22
23#define OMIT_SUPER 1
24#define OMIT_NL_SUPER 1
25#define OMIT_SUB 1
26#define OMIT_NL_SUB 1
27
28#include "evil-class-def.m"
29
30int main()
31{
32    // This definition is ABI and is never allowed to change.
33    testassert(OBJC_MAX_CLASS_SIZE == 32*sizeof(void*));
34
35    struct objc_image_info ii = { 0, 0 };
36
37    // Read a root class.
38    testassert(!objc_getClass("Super"));
39
40    extern intptr_t OBJC_CLASS_$_Super[OBJC_MAX_CLASS_SIZE/sizeof(void*)];
41    Class Super = objc_readClassPair((__bridge Class)(void*)&OBJC_CLASS_$_Super, &ii);
42    testassert(Super);
43
44    testassert(objc_getClass("Super") == Super);
45    testassert(0 == strcmp(class_getName(Super), "Super"));
46    testassert(class_getSuperclass(Super) == nil);
47    testassert(class_getClassMethod(Super, @selector(load)));
48    testassert(class_getInstanceMethod(Super, @selector(load)));
49    testassert(class_getInstanceVariable(Super, "super_ivar"));
50    testassert(class_getInstanceSize(Super) == sizeof(void*));
51    [Super load];
52
53    // Read a non-root class.
54    testassert(!objc_getClass("Sub"));
55
56    extern intptr_t OBJC_CLASS_$_Sub[OBJC_MAX_CLASS_SIZE/sizeof(void*)];
57    intptr_t Sub2_buf[OBJC_MAX_CLASS_SIZE/sizeof(void*)];
58    memcpy(Sub2_buf, &OBJC_CLASS_$_Sub, sizeof(Sub2_buf));
59    Class Sub = objc_readClassPair((__bridge Class)(void*)&OBJC_CLASS_$_Sub, &ii);
60    testassert(Sub);
61
62    testassert(0 == strcmp(class_getName(Sub), "Sub"));
63    testassert(objc_getClass("Sub") == Sub);
64    testassert(class_getSuperclass(Sub) == Super);
65    testassert(class_getClassMethod(Sub, @selector(load)));
66    testassert(class_getInstanceMethod(Sub, @selector(load)));
67    testassert(class_getInstanceVariable(Sub, "sub_ivar"));
68    testassert(class_getInstanceSize(Sub) == 2*sizeof(void*));
69    [Sub load];
70
71    // Reading a class whose name already exists fails.
72    testassert(! objc_readClassPair((__bridge Class)(void*)Sub2_buf, &ii));
73
74    succeed(__FILE__);
75}
76
77#endif
78