1/* 2TEST_RUN_OUTPUT 3objc\[\d+\]: class `SwiftV1Class\' not linked into application 4objc\[\d+\]: class `DoesNotExist\' not linked into application 5OK: runtime.m 6OR 7confused by Foundation 8OK: runtime.m 9END 10*/ 11 12 13#include "test.h" 14#include "testroot.i" 15#include <string.h> 16#include <dlfcn.h> 17#include <mach-o/ldsyms.h> 18#include <objc/objc-runtime.h> 19 20#if __has_feature(objc_arc) 21 22int main() 23{ 24 testwarn("rdar://11368528 confused by Foundation"); 25 fprintf(stderr, "confused by Foundation\n"); 26 succeed(__FILE__); 27} 28 29#else 30 31@interface Sub : TestRoot @end 32@implementation Sub @end 33 34#if __OBJC2__ 35# define TEST_SWIFT 1 36#else 37# define TEST_SWIFT 0 38#endif 39 40#define SwiftV1MangledName "_TtC6Module12SwiftV1Class" 41 42#if TEST_SWIFT 43__attribute__((objc_runtime_name(SwiftV1MangledName))) 44@interface SwiftV1Class : TestRoot @end 45@implementation SwiftV1Class @end 46#endif 47 48 49int main() 50{ 51 Class list[100]; 52 Class *list2; 53 unsigned int count, count0, count2; 54 unsigned int i; 55 int foundTestRoot; 56 int foundSub; 57 int foundSwiftV1; 58 const char **names; 59 Dl_info info; 60 61 [TestRoot class]; 62 63 // This shouldn't touch any classes. 64 dladdr(&_mh_execute_header, &info); 65 names = objc_copyClassNamesForImage(info.dli_fname, &count); 66 testassert(names); 67#if TEST_SWIFT 68 testassert(count == 3); 69#else 70 testassert(count == 2); 71#endif 72 testassert(names[count] == NULL); 73 foundTestRoot = 0; 74 foundSub = 0; 75 foundSwiftV1 = 0; 76 for (i = 0; i < count; i++) { 77 if (0 == strcmp(names[i], "TestRoot")) foundTestRoot++; 78 if (0 == strcmp(names[i], "Sub")) foundSub++; 79 if (0 == strcmp(names[i], "Module.SwiftV1Class")) foundSwiftV1++; 80 } 81 testassert(foundTestRoot == 1); 82 testassert(foundSub == 1); 83#if TEST_SWIFT 84 testassert(foundSwiftV1 == 1); 85#endif 86 87 88 // class Sub hasn't been touched - make sure it's in the class list too 89 count0 = objc_getClassList(NULL, 0); 90 testassert(count0 >= 2 && count0 < 100); 91 92 list[count0-1] = NULL; 93 count = objc_getClassList(list, count0-1); 94 testassert(list[count0-1] == NULL); 95 testassert(count == count0); 96 97 count = objc_getClassList(list, count0); 98 testassert(count == count0); 99 100 for (i = 0; i < count; i++) { 101 testprintf("%s\n", class_getName(list[i])); 102 } 103 104 foundTestRoot = 0; 105 foundSub = 0; 106 foundSwiftV1 = 0; 107 for (i = 0; i < count; i++) { 108 if (0 == strcmp(class_getName(list[i]), "TestRoot")) foundTestRoot++; 109 if (0 == strcmp(class_getName(list[i]), "Sub")) foundSub++; 110 if (0 == strcmp(class_getName(list[i]), "Module.SwiftV1Class")) foundSwiftV1++; 111 // list should be non-meta classes only 112 testassert(!class_isMetaClass(list[i])); 113 } 114 testassert(foundTestRoot == 1); 115 testassert(foundSub == 1); 116#if TEST_SWIFT 117 testassert(foundSwiftV1 == 1); 118#endif 119 120 // fixme check class handler 121 testassert(objc_getClass("TestRoot") == [TestRoot class]); 122#if TEST_SWIFT 123 testassert(objc_getClass("Module.SwiftV1Class") == [SwiftV1Class class]); 124 testassert(objc_getClass(SwiftV1MangledName) == [SwiftV1Class class]); 125#endif 126 testassert(objc_getClass("SwiftV1Class") == nil); 127 testassert(objc_getClass("DoesNotExist") == nil); 128 testassert(objc_getClass(NULL) == nil); 129 130 testassert(objc_getMetaClass("TestRoot") == object_getClass([TestRoot class])); 131#if TEST_SWIFT 132 testassert(objc_getMetaClass("Module.SwiftV1Class") == object_getClass([SwiftV1Class class])); 133 testassert(objc_getMetaClass(SwiftV1MangledName) == object_getClass([SwiftV1Class class])); 134#endif 135 testassert(objc_getMetaClass("SwiftV1Class") == nil); 136 testassert(objc_getMetaClass("DoesNotExist") == nil); 137 testassert(objc_getMetaClass(NULL) == nil); 138 139 // fixme check class no handler 140 testassert(objc_lookUpClass("TestRoot") == [TestRoot class]); 141#if TEST_SWIFT 142 testassert(objc_lookUpClass("Module.SwiftV1Class") == [SwiftV1Class class]); 143 testassert(objc_lookUpClass(SwiftV1MangledName) == [SwiftV1Class class]); 144#endif 145 testassert(objc_lookUpClass("SwiftV1Class") == nil); 146 testassert(objc_lookUpClass("DoesNotExist") == nil); 147 testassert(objc_lookUpClass(NULL) == nil); 148 149 testassert(! object_isClass(nil)); 150 testassert(! object_isClass([TestRoot new])); 151 testassert(object_isClass([TestRoot class])); 152 testassert(object_isClass(object_getClass([TestRoot class]))); 153 testassert(object_isClass([Sub class])); 154 testassert(object_isClass(object_getClass([Sub class]))); 155#if TEST_SWIFT 156 testassert(object_isClass([SwiftV1Class class])); 157 testassert(object_isClass(object_getClass([SwiftV1Class class]))); 158#endif 159 160 list2 = objc_copyClassList(&count2); 161 testassert(count2 == count); 162 testassert(list2); 163 testassert(malloc_size(list2) >= (1+count2) * sizeof(Class)); 164 for (i = 0; i < count; i++) { 165 testassert(list[i] == list2[i]); 166 } 167 testassert(list2[count] == NULL); 168 free(list2); 169 free(objc_copyClassList(NULL)); 170 171 succeed(__FILE__); 172} 173 174#endif 175