diff --git a/Test/CMakeLists.txt b/Test/CMakeLists.txt index ccaa548..d938432 100644 --- a/Test/CMakeLists.txt +++ b/Test/CMakeLists.txt @@ -35,6 +35,28 @@ set(TESTS exchange.m ) +# List of single-file tests that won't work with the legacy ABI and so +# shouldn't be run in legacy mode. +set(NEW_TESTS + category_properties.m +) + + +add_library(test_runtime_legacy OBJECT Test.m) +set_target_properties(test_runtime_legacy PROPERTIES + INCLUDE_DIRECTORIES "${CMAKE_SOURCE_DIR}" + COMPILE_FLAGS "-fblocks -fobjc-runtime=gnustep-1.7" + LINKER_LANGUAGE C +) + +add_library(test_runtime OBJECT Test.m) +set_target_properties(test_runtime PROPERTIES + INCLUDE_DIRECTORIES "${CMAKE_SOURCE_DIR}" + COMPILE_FLAGS "-fblocks -fobjc-runtime=gnustep-2.0" + LINKER_LANGUAGE C +) + + # Function for adding a test. This takes the name of the test and the list of # source files as arguments. function(addtest_flags TEST_NAME FLAGS TEST_SOURCE) @@ -42,8 +64,6 @@ function(addtest_flags TEST_NAME FLAGS TEST_SOURCE) # Only compile the main file with ARC set_source_files_properties(${TEST_SOURCE} COMPILE_FLAGS "-fobjc-arc") - # Add the ARC-incompatible definitions of the test class. - list(APPEND TEST_SOURCE "Test.m") endif() add_executable(${TEST_NAME} ${TEST_SOURCE}) add_test(${TEST_NAME} ${TEST_NAME}) @@ -59,24 +79,31 @@ function(addtest_flags TEST_NAME FLAGS TEST_SOURCE) target_link_libraries(${TEST_NAME} objc) endfunction(addtest_flags) -function(addtest_variants TEST TEST_SOURCE) +function(addtest_variants TEST TEST_SOURCE LEGACY) addtest_flags(${TEST} "-O0 -fobjc-runtime=gnustep-2.0 -UNDEBUG" "${TEST_SOURCE}") + target_sources(${TEST} PRIVATE $) addtest_flags("${TEST}_optimised" "-O3 -fobjc-runtime=gnustep-2.0 -UNDEBUG" "${TEST_SOURCE}") - addtest_flags("${TEST}_legacy" "-O0 -fobjc-runtime=gnustep-1.7 -UNDEBUG" "${TEST_SOURCE}") - addtest_flags("${TEST}_legacy_optimised" "-O3 -fobjc-runtime=gnustep-1.7 -UNDEBUG" "${TEST_SOURCE}") + target_sources("${TEST}_optimised" PRIVATE $) + if (LEGACY) + addtest_flags("${TEST}_legacy" "-O0 -fobjc-runtime=gnustep-1.7 -UNDEBUG" "${TEST_SOURCE}") + target_sources("${TEST}_legacy" PRIVATE $) + addtest_flags("${TEST}_legacy_optimised" "-O3 -fobjc-runtime=gnustep-1.7 -UNDEBUG" "${TEST_SOURCE}") + target_sources("${TEST}_legacy_optimised" PRIVATE $) + endif() endfunction(addtest_variants) foreach(TEST_SOURCE ${TESTS}) get_filename_component(TEST ${TEST_SOURCE} NAME_WE) - addtest_variants(${TEST} ${TEST_SOURCE}) - target_compile_definitions("${TEST}_legacy" PRIVATE SINGLE_FILE_TEST=1) - target_compile_definitions("${TEST}_legacy_optimised" PRIVATE SINGLE_FILE_TEST=1) - target_compile_definitions(${TEST} PRIVATE SINGLE_FILE_TEST=1) - target_compile_definitions("${TEST}_optimised" PRIVATE SINGLE_FILE_TEST=1) + addtest_variants(${TEST} ${TEST_SOURCE} true) +endforeach() + +foreach(TEST_SOURCE ${NEW_TESTS}) + get_filename_component(TEST ${TEST_SOURCE} NAME_WE) + addtest_variants(${TEST} ${TEST_SOURCE} false) endforeach() # Tests that are more than a single file. -addtest_variants("CXXExceptions" "CXXException.m;CXXException.cc;Test.m") +addtest_variants("CXXExceptions" "CXXException.m;CXXException.cc" true) if (ENABLE_OBJCXX) -addtest_variants(ObjCXXEHInterop "ObjCXXEHInterop.mm;ObjCXXEHInterop.m;Test.m") +addtest_variants(ObjCXXEHInterop "ObjCXXEHInterop.mm;ObjCXXEHInterop.m" true) endif() diff --git a/Test/Test.h b/Test/Test.h index e455aaa..237e416 100644 --- a/Test/Test.h +++ b/Test/Test.h @@ -26,41 +26,4 @@ __attribute__((objc_root_class)) @interface NSAutoreleasePool : Test @end -#ifdef SINGLE_FILE_TEST -#if !__has_feature(objc_arc) -@implementation Test -+ (Class)class { return self; } -+ (id)new -{ - return class_createInstance(self, 0); -} -- (void)dealloc -{ - object_dispose(self); -} -- (id)autorelease -{ - return objc_autorelease(self); -} -- (id)retain -{ - return objc_retain(self); -} -- (void)release -{ - objc_release(self); -} -- (void)_ARCCompliantRetainRelease {} -@end - -@implementation NSAutoreleasePool -- (void)_ARCCompatibleAutoreleasePool {} -+ (void)addObject:(id)anObject -{ - objc_autorelease(anObject); -} -@end -#endif - -#endif diff --git a/Test/Test.m b/Test/Test.m index 87bfcae..acf650f 100644 --- a/Test/Test.m +++ b/Test/Test.m @@ -4,7 +4,37 @@ #undef NDEBUG #endif #include -#ifndef SINGLE_FILE_TEST -#define SINGLE_FILE_TEST 1 -#endif #include "Test.h" + +@implementation Test ++ (Class)class { return self; } ++ (id)new +{ + return class_createInstance(self, 0); +} +- (void)dealloc +{ + object_dispose(self); +} +- (id)autorelease +{ + return objc_autorelease(self); +} +- (id)retain +{ + return objc_retain(self); +} +- (void)release +{ + objc_release(self); +} +- (void)_ARCCompliantRetainRelease {} +@end + +@implementation NSAutoreleasePool +- (void)_ARCCompatibleAutoreleasePool {} ++ (void)addObject:(id)anObject +{ + objc_autorelease(anObject); +} +@end diff --git a/Test/category_properties.m b/Test/category_properties.m new file mode 100644 index 0000000..836849b --- /dev/null +++ b/Test/category_properties.m @@ -0,0 +1,33 @@ +#include "Test.h" +#include +#include + +@interface Test (Property) +@property (readonly) int val; +@end + +@interface Test (Property2) +@property (readonly) int val2; +@end + + +@implementation Test (Property) +- (int)val { return 0; } +@end + +@implementation Test (Property2) +@dynamic val2; +- (int)val2 { return 0; } +@end + +int main(int argc, char** argv) +{ + Class test = objc_getClass("Test"); + objc_property_t prop = class_getProperty(test, "val"); + assert(prop); + assert(strcmp("Ti,R", property_getAttributes(prop)) == 0); + prop = class_getProperty(test, "val2"); + assert(prop); + assert(strcmp("Ti,R,D", property_getAttributes(prop)) == 0); +} + diff --git a/Test/objc_msgSend.m b/Test/objc_msgSend.m index 447ba62..db37c52 100644 --- a/Test/objc_msgSend.m +++ b/Test/objc_msgSend.m @@ -26,8 +26,8 @@ Class TestCls; __attribute__((objc_root_class)) #endif #endif -@interface Test { id isa; } @end -@interface Test (Dynamic) +@interface MsgTest { id isa; } @end +@interface MsgTest (Dynamic) + (void)manyArgs: (int)a0 : (int) a1 : (int) a2 @@ -51,7 +51,7 @@ __attribute__((objc_root_class)) : (float) f9 : (float) f10; @end -@implementation Test +@implementation MsgTest - foo { assert((id)1 == self); @@ -125,7 +125,7 @@ void fwdMany(id self, float f10) { forwardcalls++; - assert(self == objc_getClass("Test")); + assert(self == objc_getClass("MsgTest")); if (sel_isEqual(_cmd, sel_registerName("manyArgs:::::::::::::::::::::"))) assert(a0 == 0); assert(a1 == 1); @@ -158,7 +158,7 @@ void fwd(void) IMP forward(id o, SEL s) { - assert(o == objc_getClass("Test")); + assert(o == objc_getClass("MsgTest")); if (sel_isEqual(s, sel_registerName("missing"))) { return (IMP)fwd; @@ -178,7 +178,7 @@ int main(void) { __objc_msg_forward2 = forward; __objc_msg_forward3 = forward_slot; - TestCls = objc_getClass("Test"); + TestCls = objc_getClass("MsgTest"); int exceptionThrown = 0; @try { objc_msgSend(TestCls, @selector(foo)); @@ -193,11 +193,11 @@ int main(void) objc_msgSend(TestCls, @selector(missing)); assert(forwardcalls == 1); assert(0 == objc_msgSend(0, @selector(nothing))); - id a = objc_msgSend(objc_getClass("Test"), @selector(foo)); + id a = objc_msgSend(objc_getClass("MsgTest"), @selector(foo)); assert((id)0x42 == a); a = objc_msgSend(TestCls, @selector(foo)); assert((id)0x42 == a); - assert(objc_registerSmallObjectClass_np(objc_getClass("Test"), 1)); + assert(objc_registerSmallObjectClass_np(objc_getClass("MsgTest"), 1)); a = objc_msgSend((id)01, @selector(foo)); assert((id)0x42 == a); s ret = ((s(*)(id, SEL))objc_msgSend_stret)(TestCls, @selector(sret)); @@ -208,7 +208,7 @@ int main(void) assert(ret.e == 5); if (sizeof(id) == 8) { - assert(objc_registerSmallObjectClass_np(objc_getClass("Test"), 3)); + assert(objc_registerSmallObjectClass_np(objc_getClass("MsgTest"), 3)); ret = ((s(*)(id, SEL))objc_msgSend_stret)((id)3, @selector(sret)); assert(ret.a == 1); assert(ret.b == 2);