diff --git a/.cirrus.yml b/.cirrus.yml index 9bb55f9..a868eeb 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -2,7 +2,20 @@ freebsd_instance: image: freebsd-12-0-release-amd64 task: - install_script: pkg install -y cmake ninja llvm80 + install_script: pkg install -y cmake ninja llvm80 git + + clone_script: | + if [ -z "$CIRRUS_PR" ]; then + git clone --recursive --branch=$CIRRUS_BRANCH https://x-access-token:${CIRRUS_REPO_CLONE_TOKEN}@github.com/${CIRRUS_REPO_FULL_NAME}.git $CIRRUS_WORKING_DIR + git reset --hard $CIRRUS_CHANGE_IN_REPO + else + git clone --recursive https://x-access-token:${CIRRUS_REPO_CLONE_TOKEN}@github.com/${CIRRUS_REPO_FULL_NAME}.git $CIRRUS_WORKING_DIR + git fetch origin pull/$CIRRUS_PR/head:pull/$CIRRUS_PR + git reset --hard $CIRRUS_CHANGE_IN_REPO + fi + git submodule sync + git submodule update + script: | mkdir Build cd Build diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..5f12667 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "third_party/robin-map"] + path = third_party/robin-map + url = https://github.com/Tessil/robin-map diff --git a/CMakeLists.txt b/CMakeLists.txt index beacc22..dddce40 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -25,10 +25,12 @@ add_definitions( -DGNUSTEP -D__OBJC_RUNTIME_INTERNAL__=1) set(libobjc_ASM_SRCS block_trampolines.S objc_msgSend.S) +set(libobjc_OBJCXX_SRCS + arc.mm + ) set(libobjc_OBJC_SRCS NSBlocks.m Protocol2.m - arc.m associate.m blocks_runtime.m properties.m) @@ -193,6 +195,12 @@ set_source_files_properties( COMPILE_FLAGS "${CMAKE_OBJC_FLAGS} -Xclang -x -Xclang objective-c" ) +set_source_files_properties( + ${libobjc_OBJCXX_SRCS} + COMPILE_FLAGS "${CMAKE_OBJC_FLAGS} -Xclang -x -Xclang objective-c++" +) + + # # C++ Runtime interaction # @@ -252,7 +260,7 @@ if (MSVC) endif() -add_library(objc SHARED ${libobjc_C_SRCS} ${libobjc_ASM_SRCS} ${libobjc_OBJC_SRCS} ${libobjc_ASM_OBJS}) +add_library(objc SHARED ${libobjc_C_SRCS} ${libobjc_ASM_SRCS} ${libobjc_OBJC_SRCS} ${libobjc_OBJCXX_SRCS} ${libobjc_ASM_OBJS}) if (ENABLE_OBJCXX) if (WIN32) diff --git a/arc.m b/arc.mm similarity index 83% rename from arc.m rename to arc.mm index b73276c..d653e55 100644 --- a/arc.m +++ b/arc.mm @@ -1,7 +1,10 @@ +#define _LIBCPP_NO_EXCEPTIONS 1 +#define TSL_NO_EXCEPTIONS 1 +#include #include -#include #include -#import "stdio.h" +#include "third_party/robin-map/include/tsl/robin_map.h" +#import "lock.h" #import "objc/runtime.h" #import "objc/blocks_runtime.h" #import "nsobject.h" @@ -12,7 +15,7 @@ #import "objc/objc-arc.h" #import "objc/blocks_runtime.h" -id (*_objc_weak_load)(id object); +extern "C" id (*_objc_weak_load)(id object); #if defined(_WIN32) // We're using the Fiber-Local Storage APIs on Windows @@ -54,9 +57,12 @@ static inline arc_tls_key_t arc_tls_key_create(arc_cleanup_function_t cleanupFun arc_tls_key_t ARCThreadKey; #endif -extern void _NSConcreteMallocBlock; -extern void _NSConcreteStackBlock; -extern void _NSConcreteGlobalBlock; +extern "C" +{ + extern struct objc_class _NSConcreteMallocBlock; + extern struct objc_class _NSConcreteStackBlock; + extern struct objc_class _NSConcreteGlobalBlock; +} @interface NSAutoreleasePool + (Class)class; @@ -95,15 +101,25 @@ struct arc_tls id returnRetained; }; +/** + * Type-safe wrapper around calloc. + */ +template +static inline T* new_zeroed() +{ + return static_cast(calloc(sizeof(T), 1)); +} + + static inline struct arc_tls* getARCThreadData(void) { #ifndef arc_tls_store return NULL; #else // !defined arc_tls_store - struct arc_tls *tls = arc_tls_load(ARCThreadKey); + auto tls = static_cast(arc_tls_load(ARCThreadKey)); if (NULL == tls) { - tls = calloc(sizeof(struct arc_tls), 1); + tls = new_zeroed(); arc_tls_store(ARCThreadKey, tls); } return tls; @@ -115,7 +131,7 @@ static inline void release(id obj); * Empties objects from the autorelease pool, stating at the head of the list * specified by pool and continuing until it reaches the stop point. If the stop point is NULL then */ -static void emptyPool(struct arc_tls *tls, id *stop) +static void emptyPool(struct arc_tls *tls, void *stop) { struct arc_autorelease_pool *stopPool = NULL; if (NULL != stop) @@ -211,14 +227,14 @@ static const size_t weak_mask = ((size_t)1)<<((sizeof(size_t)*8)-refcount_shift) */ static const size_t refcount_mask = ~weak_mask; -OBJC_PUBLIC size_t object_getRetainCount_np(id obj) +extern "C" OBJC_PUBLIC size_t object_getRetainCount_np(id obj) { uintptr_t *refCount = ((uintptr_t*)obj) - 1; uintptr_t refCountVal = __sync_fetch_and_add(refCount, 0); return (((size_t)refCountVal) & refcount_mask) + 1; } -OBJC_PUBLIC id objc_retain_fast_np(id obj) +extern "C" OBJC_PUBLIC id objc_retain_fast_np(id obj) { uintptr_t *refCount = ((uintptr_t*)obj) - 1; uintptr_t refCountVal = __sync_fetch_and_add(refCount, 0); @@ -291,7 +307,7 @@ static inline id retain(id obj) return [obj retain]; } -OBJC_PUBLIC BOOL objc_release_fast_no_destroy_np(id obj) +extern "C" OBJC_PUBLIC BOOL objc_release_fast_no_destroy_np(id obj) { uintptr_t *refCount = ((uintptr_t*)obj) - 1; uintptr_t refCountVal = __sync_fetch_and_add(refCount, 0); @@ -329,7 +345,7 @@ OBJC_PUBLIC BOOL objc_release_fast_no_destroy_np(id obj) return NO; } -OBJC_PUBLIC void objc_release_fast_np(id obj) +extern "C" OBJC_PUBLIC void objc_release_fast_np(id obj) { if (objc_release_fast_no_destroy_np(obj)) { @@ -341,12 +357,12 @@ static inline void release(id obj) { if (isPersistentObject(obj)) { return; } Class cls = obj->isa; - if (cls == &_NSConcreteMallocBlock) + if (cls == static_cast(&_NSConcreteMallocBlock)) { _Block_release(obj); return; } - if (cls == &_NSConcreteStackBlock) + if (cls == static_cast(&_NSConcreteStackBlock)) { return; } @@ -396,7 +412,7 @@ static inline id autorelease(id obj) struct arc_autorelease_pool *pool = tls->pool; if (NULL == pool || (pool->insert >= &pool->pool[POOL_SIZE])) { - pool = calloc(sizeof(struct arc_autorelease_pool), 1); + pool = new_zeroed(); pool->previous = tls->pool; pool->insert = pool->pool; tls->pool = pool; @@ -418,7 +434,7 @@ static inline id autorelease(id obj) return [obj autorelease]; } -OBJC_PUBLIC unsigned long objc_arc_autorelease_count_np(void) +extern "C" OBJC_PUBLIC unsigned long objc_arc_autorelease_count_np(void) { struct arc_tls* tls = getARCThreadData(); unsigned long count = 0; @@ -432,7 +448,7 @@ OBJC_PUBLIC unsigned long objc_arc_autorelease_count_np(void) } return count; } -OBJC_PUBLIC unsigned long objc_arc_autorelease_count_for_object_np(id obj) +extern "C" OBJC_PUBLIC unsigned long objc_arc_autorelease_count_for_object_np(id obj) { struct arc_tls* tls = getARCThreadData(); unsigned long count = 0; @@ -453,7 +469,7 @@ OBJC_PUBLIC unsigned long objc_arc_autorelease_count_for_object_np(id obj) return count; } -void *objc_autoreleasePoolPush(void) +extern "C" OBJC_PUBLIC void *objc_autoreleasePoolPush(void) { initAutorelease(); struct arc_tls* tls = getARCThreadData(); @@ -472,7 +488,7 @@ void *objc_autoreleasePoolPush(void) struct arc_autorelease_pool *pool = tls->pool; if (NULL == pool || (pool->insert >= &pool->pool[POOL_SIZE])) { - pool = calloc(sizeof(struct arc_autorelease_pool), 1); + pool = new_zeroed(); pool->previous = tls->pool; pool->insert = pool->pool; tls->pool = pool; @@ -486,7 +502,7 @@ void *objc_autoreleasePoolPush(void) if (0 == NewAutoreleasePool) { return NULL; } return NewAutoreleasePool(AutoreleasePool, SELECTOR(new)); } -OBJC_PUBLIC void objc_autoreleasePoolPop(void *pool) +extern "C" OBJC_PUBLIC void objc_autoreleasePoolPop(void *pool) { if (useARCAutoreleasePool) { @@ -500,7 +516,7 @@ OBJC_PUBLIC void objc_autoreleasePoolPop(void *pool) return; } } - DeleteAutoreleasePool(pool, SELECTOR(release)); + DeleteAutoreleasePool(static_cast(pool), SELECTOR(release)); struct arc_tls* tls = getARCThreadData(); if (tls && tls->returnRetained) { @@ -509,7 +525,7 @@ OBJC_PUBLIC void objc_autoreleasePoolPop(void *pool) } } -OBJC_PUBLIC id objc_autorelease(id obj) +extern "C" OBJC_PUBLIC id objc_autorelease(id obj) { if (nil != obj) { @@ -518,7 +534,7 @@ OBJC_PUBLIC id objc_autorelease(id obj) return obj; } -OBJC_PUBLIC id objc_autoreleaseReturnValue(id obj) +extern "C" OBJC_PUBLIC id objc_autoreleaseReturnValue(id obj) { if (!useARCAutoreleasePool) { @@ -533,7 +549,7 @@ OBJC_PUBLIC id objc_autoreleaseReturnValue(id obj) return objc_autorelease(obj); } -OBJC_PUBLIC id objc_retainAutoreleasedReturnValue(id obj) +extern "C" OBJC_PUBLIC id objc_retainAutoreleasedReturnValue(id obj) { // If the previous object was released with objc_autoreleaseReturnValue() // just before return, then it will not have actually been autoreleased. @@ -565,36 +581,36 @@ OBJC_PUBLIC id objc_retainAutoreleasedReturnValue(id obj) return objc_retain(obj); } -OBJC_PUBLIC id objc_retain(id obj) +extern "C" OBJC_PUBLIC id objc_retain(id obj) { if (nil == obj) { return nil; } return retain(obj); } -OBJC_PUBLIC id objc_retainAutorelease(id obj) +extern "C" OBJC_PUBLIC id objc_retainAutorelease(id obj) { return objc_autorelease(objc_retain(obj)); } -OBJC_PUBLIC id objc_retainAutoreleaseReturnValue(id obj) +extern "C" OBJC_PUBLIC id objc_retainAutoreleaseReturnValue(id obj) { if (nil == obj) { return obj; } return objc_autoreleaseReturnValue(retain(obj)); } -OBJC_PUBLIC id objc_retainBlock(id b) +extern "C" OBJC_PUBLIC id objc_retainBlock(id b) { - return _Block_copy(b); + return static_cast(_Block_copy(b)); } -OBJC_PUBLIC void objc_release(id obj) +extern "C" OBJC_PUBLIC void objc_release(id obj) { if (nil == obj) { return; } release(obj); } -OBJC_PUBLIC id objc_storeStrong(id *addr, id value) +extern "C" OBJC_PUBLIC id objc_storeStrong(id *addr, id value) { value = objc_retain(value); id oldValue = *addr; @@ -609,49 +625,78 @@ OBJC_PUBLIC id objc_storeStrong(id *addr, id value) static int weakref_class; -typedef struct objc_weak_ref +namespace { + +struct WeakRef { - void *isa; + void *isa = &weakref_class; id object; - size_t weak_count:((sizeof(size_t) * 8) - 1); - bool isDeleted:1; -} WeakRef; + struct + { + size_t weak_count:((sizeof(size_t) * 8) - 1); + bool isDeleted:1; + }; + id obj() + { + if (isDeleted) + { + return nil; + } + return object; + } + WeakRef(id o) : object(o), weak_count(1), isDeleted(false) {} +}; -id weakRefGetObj(WeakRef *ref) +template +struct malloc_allocator { - return ref->isDeleted ? nil : ref->object; -} + typedef T value_type; + T* allocate(std::size_t n) + { + return static_cast(malloc(sizeof(T) * n)); + } -static int weak_ref_compare(const id obj, const WeakRef *weak_ref) -{ - return obj == weak_ref->object; -} + void deallocate(T* p, std::size_t) + { + free(p); + } -static uint32_t ptr_hash(const void *ptr) -{ - // Bit-rotate right 4, since the lowest few bits in an object pointer will - // always be 0, which is not so useful for a hash value - return ((uintptr_t)ptr >> 4) | ((uintptr_t)ptr << ((sizeof(id) * 8) - 4)); -} -static int weak_ref_hash(const WeakRef *weak_ref) + template + malloc_allocator &operator=(const malloc_allocator&) const + { + return *this; + } + + bool operator==(const malloc_allocator &) const + { + return true; + } + + template + operator malloc_allocator() const + { + return malloc_allocator(); + } +}; + +using weak_ref_table = tsl::robin_pg_map, + std::equal_to, + malloc_allocator>>; + +weak_ref_table &weakRefs() { - return ptr_hash(weak_ref->object); + static weak_ref_table w{128}; + return w; } -#define MAP_TABLE_NAME weak_ref -#define MAP_TABLE_COMPARE_FUNCTION weak_ref_compare -#define MAP_TABLE_HASH_KEY ptr_hash -#define MAP_TABLE_HASH_VALUE weak_ref_hash -#define MAP_TABLE_SINGLE_THREAD 1 -#define MAP_TABLE_NO_LOCK 1 - -#include "hash_table.h" -static weak_ref_table *weakRefs; mutex_t weakRefLock; -PRIVATE void init_arc(void) +} + +PRIVATE extern "C" void init_arc(void) { - weak_ref_initialize(&weakRefs, 128); INIT_LOCK(weakRefLock); #ifdef arc_tls_store ARCThreadKey = arc_tls_key_create((arc_cleanup_function_t)cleanupPools); @@ -677,7 +722,7 @@ static BOOL loadWeakPointer(id *addr, id *obj, WeakRef **ref) if (classForObject(oldObj) == (Class)&weakref_class) { *ref = (WeakRef*)oldObj; - *obj = weakRefGetObj(*ref); + *obj = (*ref)->obj(); return YES; } *ref = NULL; @@ -691,14 +736,14 @@ static inline BOOL weakRefRelease(WeakRef *ref) ref->weak_count--; if (ref->weak_count == 0) { - weak_ref_remove(weakRefs, ref->object); - free(ref); + weakRefs().erase(ref->object); + delete ref; return YES; } return NO; } -void* block_load_weak(void *block); +extern "C" void* block_load_weak(void *block); static BOOL setObjectHasWeakRefs(id obj) { @@ -747,24 +792,20 @@ static BOOL setObjectHasWeakRefs(id obj) WeakRef *incrementWeakRefCount(id obj) { - WeakRef *ref = weak_ref_table_get(weakRefs, obj); - if (ref == NULL) + WeakRef *&ref = weakRefs()[obj]; + if (ref == nullptr) { - ref = calloc(1, sizeof(WeakRef)); - ref->isa = (Class)&weakref_class; - ref->object = obj; - ref->weak_count = 1; - weak_ref_insert(weakRefs, ref); + ref = new WeakRef(obj); } else { - assert(ref->object == obj); + assert(ref->obj() == obj); ref->weak_count++; } return ref; } -OBJC_PUBLIC id objc_storeWeak(id *addr, id obj) +extern "C" OBJC_PUBLIC id objc_storeWeak(id *addr, id obj) { LOCK_FOR_SCOPE(&weakRefLock); WeakRef *oldRef; @@ -802,7 +843,7 @@ OBJC_PUBLIC id objc_storeWeak(id *addr, id obj) return obj; } -OBJC_PUBLIC BOOL objc_delete_weak_refs(id obj) +extern "C" OBJC_PUBLIC BOOL objc_delete_weak_refs(id obj) { LOCK_FOR_SCOPE(&weakRefLock); if (objc_test_class_flag(classForObject(obj), objc_class_flag_fast_arc)) @@ -821,13 +862,15 @@ OBJC_PUBLIC BOOL objc_delete_weak_refs(id obj) return NO; } } - WeakRef *oldRef = weak_ref_table_get(weakRefs, obj); - if (0 != oldRef) + auto table = weakRefs(); + auto old = table.find(obj); + if (old != table.end()) { + WeakRef *oldRef = old->second; // The address of obj is likely to be reused, so remove it from // the table so that we don't accidentally alias weak // references - weak_ref_remove(weakRefs, obj); + table.erase(old); // Zero the object pointer. This prevents any other weak // accesses from loading from this. This must be done after // removing the ref from the table, because the compare operation @@ -840,7 +883,7 @@ OBJC_PUBLIC BOOL objc_delete_weak_refs(id obj) return YES; } -OBJC_PUBLIC id objc_loadWeakRetained(id* addr) +extern "C" OBJC_PUBLIC id objc_loadWeakRetained(id* addr) { LOCK_FOR_SCOPE(&weakRefLock); id obj; @@ -865,9 +908,9 @@ OBJC_PUBLIC id objc_loadWeakRetained(id* addr) return nil; } Class cls = classForObject(obj); - if (&_NSConcreteMallocBlock == cls) + if (static_cast(&_NSConcreteMallocBlock) == cls) { - obj = block_load_weak(obj); + obj = static_cast(block_load_weak(obj)); } else if (objc_test_class_flag(cls, objc_class_flag_permanent_instances)) { @@ -880,12 +923,12 @@ OBJC_PUBLIC id objc_loadWeakRetained(id* addr) return objc_retain(obj); } -OBJC_PUBLIC id objc_loadWeak(id* object) +extern "C" OBJC_PUBLIC id objc_loadWeak(id* object) { return objc_autorelease(objc_loadWeakRetained(object)); } -OBJC_PUBLIC void objc_copyWeak(id *dest, id *src) +extern "C" OBJC_PUBLIC void objc_copyWeak(id *dest, id *src) { // Don't retain or release. // `src` is a valid pointer to a __weak pointer or nil. @@ -902,7 +945,7 @@ OBJC_PUBLIC void objc_copyWeak(id *dest, id *src) } } -OBJC_PUBLIC void objc_moveWeak(id *dest, id *src) +extern "C" OBJC_PUBLIC void objc_moveWeak(id *dest, id *src) { // Don't retain or release. // `dest` is a valid pointer to uninitialized memory. @@ -919,7 +962,7 @@ OBJC_PUBLIC void objc_moveWeak(id *dest, id *src) *src = nil; } -OBJC_PUBLIC void objc_destroyWeak(id* obj) +extern "C" OBJC_PUBLIC void objc_destroyWeak(id* obj) { LOCK_FOR_SCOPE(&weakRefLock); WeakRef *oldRef; @@ -933,7 +976,7 @@ OBJC_PUBLIC void objc_destroyWeak(id* obj) } } -OBJC_PUBLIC id objc_initWeak(id *addr, id obj) +extern "C" OBJC_PUBLIC id objc_initWeak(id *addr, id obj) { if (obj == nil) { diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 8ebec39..13940c2 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -10,6 +10,8 @@ jobs: Release: BuildType: Release steps: + - checkout: self + submodules: true - script: | sudo add-apt-repository "deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-8 main" sudo apt-get update @@ -55,6 +57,8 @@ jobs: Arch: x64 Flags: -m64 steps: + - checkout: self + submodules: true - script: | choco.exe install ninja choco.exe install llvm diff --git a/blocks_runtime.m b/blocks_runtime.m index 7be65c9..9129317 100644 --- a/blocks_runtime.m +++ b/blocks_runtime.m @@ -62,7 +62,7 @@ OBJC_PUBLIC const char * _Block_signature(void *b) } OBJC_PUBLIC const char *block_getType_np(const void *b) { - return _Block_signature(b); + return _Block_signature((void*)b); } static int increment24(int *ref) diff --git a/class.h b/class.h index 44ed65f..20e8cf9 100644 --- a/class.h +++ b/class.h @@ -1,8 +1,14 @@ #ifndef __OBJC_CLASS_H_INCLUDED #define __OBJC_CLASS_H_INCLUDED #include "visibility.h" +#include "objc/runtime.h" #include +#ifdef __cplusplus +extern "C" +{ +#endif + /** * Overflow bitfield. Used for bitfields that are more than 63 bits. */ @@ -36,7 +42,6 @@ static inline BOOL objc_bitfield_test(uintptr_t bitfield, uint64_t field) return (bf->values[byte] & bit) == bit; } - // begin: objc_class struct objc_class { @@ -45,13 +50,13 @@ struct objc_class * methods use when a message is sent to the class, rather than an * instance. */ - struct objc_class *isa; + Class isa; /** * Pointer to the superclass. The compiler will set this to the name of * the superclass, the runtime will initialize it to point to the real * class. */ - struct objc_class *super_class; + Class super_class; /** * The name of this class. Set to the same value for both the class and * its associated metaclass. @@ -96,7 +101,7 @@ struct objc_class * A pointer to the first subclass for this class. Filled in by the * runtime. */ - struct objc_class *subclass_list; + Class subclass_list; /** * Pointer to the .cxx_construct method if one exists. This method needs * to be called outside of the normal dispatch mechanism. @@ -113,7 +118,7 @@ struct objc_class * then subsequently following the sibling_class pointers in the * subclasses. */ - struct objc_class *sibling_class; + Class sibling_class; /** * Metadata describing the protocols adopted by this class. Not used by @@ -143,13 +148,13 @@ struct objc_class_gsv1 * methods use when a message is sent to the class, rather than an * instance. */ - struct objc_class *isa; + Class isa; /** * Pointer to the superclass. The compiler will set this to the name of * the superclass, the runtime will initialize it to point to the real * class. */ - struct objc_class *super_class; + Class super_class; /** * The name of this class. Set to the same value for both the class and * its associated metaclass. @@ -194,14 +199,14 @@ struct objc_class_gsv1 * A pointer to the first subclass for this class. Filled in by the * runtime. */ - struct objc_class *subclass_list; + Class subclass_list; /** * A pointer to the next sibling class to this. You may find all * subclasses of a given class by following the subclass_list pointer and * then subsequently following the sibling_class pointers in the * subclasses. */ - struct objc_class *sibling_class; + Class sibling_class; /** * Metadata describing the protocols adopted by this class. Not used by @@ -277,17 +282,17 @@ struct objc_class_gsv1 */ struct objc_class_gcc { - struct objc_class *isa; - struct objc_class *super_class; + Class isa; + Class super_class; const char *name; long version; unsigned long info; long instance_size; - struct objc_ivar_list_gcc *ivars; + struct objc_ivar_list_gcc *ivars; struct objc_method_list *methods; void *dtable; - struct objc_class *subclass_list; - struct objc_class *sibling_class; + Class subclass_list; + Class sibling_class; struct objc_protocol_list *protocols; void *gc_object_type; }; @@ -357,7 +362,7 @@ enum objc_class_flags /** * Sets the specific class flag. Note: This is not atomic. */ -static inline void objc_set_class_flag(struct objc_class *aClass, +static inline void objc_set_class_flag(Class aClass, enum objc_class_flags flag) { aClass->info |= (unsigned long)flag; @@ -365,7 +370,7 @@ static inline void objc_set_class_flag(struct objc_class *aClass, /** * Unsets the specific class flag. Note: This is not atomic. */ -static inline void objc_clear_class_flag(struct objc_class *aClass, +static inline void objc_clear_class_flag(Class aClass, enum objc_class_flags flag) { aClass->info &= ~(unsigned long)flag; @@ -373,7 +378,7 @@ static inline void objc_clear_class_flag(struct objc_class *aClass, /** * Checks whether a specific class flag is set. */ -static inline BOOL objc_test_class_flag(struct objc_class *aClass, +static inline BOOL objc_test_class_flag(Class aClass, enum objc_class_flags flag) { return (aClass->info & (unsigned long)flag) == (unsigned long)flag; @@ -383,7 +388,7 @@ static inline BOOL objc_test_class_flag(struct objc_class *aClass, /** * Adds a class to the class table. */ -void class_table_insert(Class class); +void class_table_insert(Class cls); /** * Removes a class from the class table. Must be called with the runtime lock @@ -443,4 +448,7 @@ void freeIvarLists(Class aClass); */ void freeMethodLists(Class aClass); +#ifdef __cplusplus +} // extern "C" +#endif #endif //__OBJC_CLASS_H_INCLUDED diff --git a/third_party/robin-map b/third_party/robin-map new file mode 160000 index 0000000..757de82 --- /dev/null +++ b/third_party/robin-map @@ -0,0 +1 @@ +Subproject commit 757de829927489bee55ab02147484850c687b620