@@ -1,7 +1,7 @@ /* - * Copyright (c) 2008-2022 Jonathan Schleifer + * Copyright (c) 2008-2024 Jonathan Schleifer * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in @@ -99,17 +99,21 @@ # define OF_UNLIKELY(cond) (cond) # define OF_CONST_FUNC # define OF_NO_RETURN_FUNC # define OF_WEAK_REF(sym) #endif + +#ifdef __GNUC__ +# define OF_ALIGN(alignment) __attribute__((__aligned__(alignment))) +#endif #if __STDC_VERSION__ >= 201112L # define OF_ALIGNOF(type) _Alignof(type) # define OF_ALIGNAS(type) _Alignas(type) #else # define OF_ALIGNOF(type) __alignof__(type) -# define OF_ALIGNAS(type) __attribute__((__aligned__(__alignof__(type)))) +# define OF_ALIGNAS(type) OF_ALIGN(OF_ALIGNOF(type)) #endif #if __STDC_VERSION__ >= 201112L && defined(OF_HAVE_MAX_ALIGN_T) # define OF_BIGGEST_ALIGNMENT _Alignof(max_align_t) #else @@ -289,10 +293,21 @@ # define OF_DESIGNATED_INITIALIZER \ __attribute__((__objc_designated_initializer__)) #else # define OF_DESIGNATED_INITIALIZER #endif + +#if defined(__clang__) || OF_GCC_VERSION >= 405 +# define OF_DEPRECATED(project, major, minor, msg) \ + __attribute__((__deprecated__("Deprecated in " #project " " \ + #major "." #minor ": " msg))) +#elif defined(__GNUC__) +# define OF_DEPRECATED(project, major, minor, msg) \ + __attribute__((__deprecated__)) +#else +# define OF_DEPRECATED(project, major, minor, msg) +#endif #if __has_attribute(__objc_boxable__) # define OF_BOXABLE __attribute__((__objc_boxable__)) #else # define OF_BOXABLE @@ -314,34 +329,34 @@ #else # define OF_DIRECT_MEMBERS #endif #ifdef OF_APPLE_RUNTIME -# if defined(OF_X86_64) || defined(OF_X86) || defined(OF_ARM64) || \ +# if defined(OF_AMD64) || defined(OF_X86) || defined(OF_ARM64) || \ defined(OF_ARM) || defined(OF_POWERPC) # define OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR # define OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR_STRET # endif #else # if defined(OF_ELF) -# if defined(OF_X86_64) || defined(OF_X86) || \ +# if defined(OF_AMD64) || defined(OF_X86) || \ defined(OF_ARM64) || defined(OF_ARM) || defined(OF_POWERPC) || \ defined(OF_MIPS) || defined(OF_SPARC64) || defined(OF_SPARC) # define OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR # if __OBJFW_RUNTIME_ABI__ >= 800 # define OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR_STRET # endif # endif # elif defined(OF_MACH_O) -# if defined(OF_X86_64) +# if defined(OF_AMD64) # define OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR # if __OBJFW_RUNTIME_ABI__ >= 800 # define OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR_STRET # endif # endif # elif defined(OF_WINDOWS) -# if defined(OF_X86_64) || defined(OF_X86) +# if defined(OF_AMD64) || defined(OF_X86) # define OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR # if __OBJFW_RUNTIME_ABI__ >= 800 # define OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR_STRET # endif # endif @@ -357,20 +372,33 @@ objc_error("ObjFWRT @ " __FILE__ ":" \ OF_STRINGIFY(__LINE__), \ "Failed to ensure condition:\n" #cond); \ } while(0) #else +@class OFConstantString; +# ifdef __cplusplus +extern "C" { +# endif +extern void OFLog(OFConstantString *_Nonnull, ...); +# ifdef __cplusplus +} +# endif # define OFEnsure(cond) \ do { \ if OF_UNLIKELY (!(cond)) { \ - fprintf(stderr, "Failed to ensure condition " \ - "in " __FILE__ ":%d:\n" #cond "\n", \ - __LINE__); \ + OFLog(@"Failed to ensure condition in " \ + @__FILE__ ":%d: " @#cond, __LINE__); \ abort(); \ } \ } while (0) #endif + +#ifndef NDEBUG +# define OFAssert(...) OFEnsure(__VA_ARGS__) +#else +# define OFAssert(...) +#endif #define OF_UNRECOGNIZED_SELECTOR OFMethodNotFound(self, _cmd); #if __has_feature(objc_arc) # define OF_INVALID_INIT_METHOD OFMethodNotFound(self, _cmd); #else @@ -400,10 +428,34 @@ \ abort(); \ \ [super dealloc]; /* Get rid of a stupid warning */ #endif +#define OF_SINGLETON_METHODS \ + - (instancetype)autorelease \ + { \ + return self; \ + } \ + \ + - (instancetype)retain \ + { \ + return self; \ + } \ + \ + - (void)release \ + { \ + } \ + \ + - (unsigned int)retainCount \ + { \ + return OFMaxRetainCount; \ + } \ + \ + - (void)dealloc \ + { \ + OF_DEALLOC_UNSUPPORTED \ + } #define OF_CONSTRUCTOR(prio) \ static void __attribute__((__constructor__(prio))) \ OF_PREPROCESSOR_CONCAT(constructor, __LINE__)(void) #define OF_DESTRUCTOR(prio) \ @@ -441,27 +493,28 @@ static OF_INLINE uint16_t OF_CONST_FUNC OFByteSwap16NonConst(uint16_t i) { #if defined(OF_HAVE_BUILTIN_BSWAP16) return __builtin_bswap16(i); -#elif (defined(OF_X86_64) || defined(OF_X86)) && defined(__GNUC__) +#elif (defined(OF_AMD64) || defined(OF_X86)) && defined(__GNUC__) __asm__ ( - "xchgb %h0, %b0" - : "=Q"(i) - : "0"(i) + "xchg{b} { %h0, %b0 | %b0, %h0 }" + : "=Q" (i) + : "0" (i) ); #elif defined(OF_POWERPC) && defined(__GNUC__) __asm__ ( "lhbrx %0, 0, %1" - : "=r"(i) - : "r"(&i), "m"(i) + : "=r" (i) + : "r" (&i), + "m" (i) ); #elif defined(OF_ARMV6) && defined(__GNUC__) __asm__ ( "rev16 %0, %0" - : "=r"(i) - : "0"(i) + : "=r" (i) + : "0" (i) ); #else i = (i & UINT16_C(0xFF00)) >> 8 | (i & UINT16_C(0x00FF)) << 8; #endif @@ -471,27 +524,28 @@ static OF_INLINE uint32_t OF_CONST_FUNC OFByteSwap32NonConst(uint32_t i) { #if defined(OF_HAVE_BUILTIN_BSWAP32) return __builtin_bswap32(i); -#elif (defined(OF_X86_64) || defined(OF_X86)) && defined(__GNUC__) +#elif (defined(OF_AMD64) || defined(OF_X86)) && defined(__GNUC__) __asm__ ( "bswap %0" - : "=q"(i) - : "0"(i) + : "=q" (i) + : "0" (i) ); #elif defined(OF_POWERPC) && defined(__GNUC__) __asm__ ( "lwbrx %0, 0, %1" - : "=r"(i) - : "r"(&i), "m"(i) + : "=r" (i) + : "r" (&i), + "m" (i) ); #elif defined(OF_ARMV6) && defined(__GNUC__) __asm__ ( "rev %0, %0" - : "=r"(i) - : "0"(i) + : "=r" (i) + : "0" (i) ); #else i = (i & UINT32_C(0xFF000000)) >> 24 | (i & UINT32_C(0x00FF0000)) >> 8 | (i & UINT32_C(0x0000FF00)) << 8 | @@ -503,23 +557,23 @@ static OF_INLINE uint64_t OF_CONST_FUNC OFByteSwap64NonConst(uint64_t i) { #if defined(OF_HAVE_BUILTIN_BSWAP64) return __builtin_bswap64(i); -#elif defined(OF_X86_64) && defined(__GNUC__) +#elif defined(OF_AMD64) && defined(__GNUC__) __asm__ ( "bswap %0" - : "=r"(i) - : "0"(i) + : "=r" (i) + : "0" (i) ); #elif defined(OF_X86) && defined(__GNUC__) __asm__ ( - "bswap %%eax\n\t" - "bswap %%edx\n\t" - "xchgl %%eax, %%edx" - : "=A"(i) - : "0"(i) + "bswap {%%}eax\n\t" + "bswap {%%}edx\n\t" + "xchg{l} { %%eax, %%edx | edx, eax }" + : "=A" (i) + : "0" (i) ); #else i = (uint64_t)OFByteSwap32NonConst( (uint32_t)(i & UINT32_C(0xFFFFFFFF))) << 32 | OFByteSwap32NonConst((uint32_t)(i >> 32));