1 /* 2 ============================================================================== 3 4 This file is part of the JUCE library. 5 Copyright (c) 2020 - Raw Material Software Limited 6 7 JUCE is an open source library subject to commercial or open-source 8 licensing. 9 10 The code included in this file is provided under the terms of the ISC license 11 http://www.isc.org/downloads/software-support-policy/isc-license. Permission 12 To use, copy, modify, and/or distribute this software for any purpose with or 13 without fee is hereby granted provided that the above copyright notice and 14 this permission notice appear in all copies. 15 16 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER 17 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE 18 DISCLAIMED. 19 20 ============================================================================== 21 */ 22 23 #pragma once 24 25 namespace juce 26 { 27 28 //============================================================================== 29 /* This file defines miscellaneous macros for debugging, assertions, etc. 30 */ 31 32 //============================================================================== 33 #ifdef JUCE_FORCE_DEBUG 34 #undef JUCE_DEBUG 35 36 #if JUCE_FORCE_DEBUG 37 #define JUCE_DEBUG 1 38 #endif 39 #endif 40 41 /** This macro defines the C calling convention used as the standard for JUCE calls. */ 42 #if JUCE_WINDOWS 43 #define JUCE_CALLTYPE __stdcall 44 #define JUCE_CDECL __cdecl 45 #else 46 #define JUCE_CALLTYPE 47 #define JUCE_CDECL 48 #endif 49 50 //============================================================================== 51 // Debugging and assertion macros 52 53 #ifndef JUCE_LOG_CURRENT_ASSERTION 54 #if JUCE_LOG_ASSERTIONS || JUCE_DEBUG 55 #define JUCE_LOG_CURRENT_ASSERTION juce::logAssertion (__FILE__, __LINE__); 56 #else 57 #define JUCE_LOG_CURRENT_ASSERTION 58 #endif 59 #endif 60 61 //============================================================================== 62 #if JUCE_IOS || (JUCE_MAC && JUCE_ARM) || (JUCE_LINUX || JUCE_BSD) 63 /** This will try to break into the debugger if the app is currently being debugged. 64 If called by an app that's not being debugged, the behaviour isn't defined - it may 65 crash or not, depending on the platform. 66 @see jassert() 67 */ 68 #define JUCE_BREAK_IN_DEBUGGER { ::kill (0, SIGTRAP); } 69 #elif JUCE_MSVC 70 #ifndef __INTEL_COMPILER 71 #pragma intrinsic (__debugbreak) 72 #endif 73 #define JUCE_BREAK_IN_DEBUGGER { __debugbreak(); } 74 #elif JUCE_INTEL && (JUCE_GCC || JUCE_MAC) 75 #if JUCE_NO_INLINE_ASM 76 #define JUCE_BREAK_IN_DEBUGGER { } 77 #else 78 #define JUCE_BREAK_IN_DEBUGGER { asm ("int $3"); } 79 #endif 80 #elif JUCE_ANDROID 81 #define JUCE_BREAK_IN_DEBUGGER { __builtin_trap(); } 82 #else 83 #define JUCE_BREAK_IN_DEBUGGER { __asm int 3 } 84 #endif 85 86 #if JUCE_CLANG && defined (__has_feature) && ! defined (JUCE_ANALYZER_NORETURN) 87 #if __has_feature (attribute_analyzer_noreturn) juce_assert_noreturn()88 inline void __attribute__((analyzer_noreturn)) juce_assert_noreturn() {} 89 #define JUCE_ANALYZER_NORETURN juce::juce_assert_noreturn(); 90 #endif 91 #endif 92 93 #ifndef JUCE_ANALYZER_NORETURN 94 #define JUCE_ANALYZER_NORETURN 95 #endif 96 97 /** Used to silence Wimplicit-fallthrough on Clang and GCC where available 98 as there are a few places in the codebase where we need to do this 99 deliberately and want to ignore the warning. 100 */ 101 #if JUCE_CLANG 102 #if __has_cpp_attribute(clang::fallthrough) 103 #define JUCE_FALLTHROUGH [[clang::fallthrough]]; 104 #else 105 #define JUCE_FALLTHROUGH 106 #endif 107 #elif JUCE_GCC 108 #if __GNUC__ >= 7 109 #define JUCE_FALLTHROUGH [[gnu::fallthrough]]; 110 #else 111 #define JUCE_FALLTHROUGH 112 #endif 113 #else 114 #define JUCE_FALLTHROUGH 115 #endif 116 117 //============================================================================== 118 #if JUCE_MSVC && ! DOXYGEN 119 #define JUCE_BLOCK_WITH_FORCED_SEMICOLON(x) \ 120 __pragma(warning(push)) \ 121 __pragma(warning(disable:4127)) \ 122 do { x } while (false) \ 123 __pragma(warning(pop)) 124 #else 125 /** This is the good old C++ trick for creating a macro that forces the user to put 126 a semicolon after it when they use it. 127 */ 128 #define JUCE_BLOCK_WITH_FORCED_SEMICOLON(x) do { x } while (false) 129 #endif 130 131 //============================================================================== 132 #if (JUCE_DEBUG && ! JUCE_DISABLE_ASSERTIONS) || DOXYGEN 133 /** Writes a string to the standard error stream. 134 Note that as well as a single string, you can use this to write multiple items 135 as a stream, e.g. 136 @code 137 DBG ("foo = " << foo << "bar = " << bar); 138 @endcode 139 The macro is only enabled in a debug build, so be careful not to use it with expressions 140 that have important side-effects! 141 @see Logger::outputDebugString 142 */ 143 #define DBG(textToWrite) JUCE_BLOCK_WITH_FORCED_SEMICOLON (juce::String tempDbgBuf; tempDbgBuf << textToWrite; juce::Logger::outputDebugString (tempDbgBuf);) 144 145 //============================================================================== 146 /** This will always cause an assertion failure. 147 It is only compiled in a debug build, (unless JUCE_LOG_ASSERTIONS is enabled for your build). 148 @see jassert 149 */ 150 #define jassertfalse JUCE_BLOCK_WITH_FORCED_SEMICOLON (JUCE_LOG_CURRENT_ASSERTION; if (juce::juce_isRunningUnderDebugger()) JUCE_BREAK_IN_DEBUGGER; JUCE_ANALYZER_NORETURN) 151 152 //============================================================================== 153 /** Platform-independent assertion macro. 154 155 This macro gets turned into a no-op when you're building with debugging turned off, so be 156 careful that the expression you pass to it doesn't perform any actions that are vital for the 157 correct behaviour of your program! 158 @see jassertfalse 159 */ 160 #define jassert(expression) JUCE_BLOCK_WITH_FORCED_SEMICOLON (if (! (expression)) jassertfalse;) 161 162 #else 163 //============================================================================== 164 // If debugging is disabled, these dummy debug and assertion macros are used.. 165 166 #define DBG(textToWrite) 167 #define jassertfalse JUCE_BLOCK_WITH_FORCED_SEMICOLON (JUCE_LOG_CURRENT_ASSERTION) 168 169 #if JUCE_LOG_ASSERTIONS 170 #define jassert(expression) JUCE_BLOCK_WITH_FORCED_SEMICOLON (if (! (expression)) jassertfalse;) 171 #else 172 #define jassert(expression) JUCE_BLOCK_WITH_FORCED_SEMICOLON ( ; ) 173 #endif 174 175 #endif 176 177 //============================================================================== 178 #if ! DOXYGEN 179 #define JUCE_JOIN_MACRO_HELPER(a, b) a ## b 180 #define JUCE_STRINGIFY_MACRO_HELPER(a) #a 181 #endif 182 183 /** A good old-fashioned C macro concatenation helper. 184 This combines two items (which may themselves be macros) into a single string, 185 avoiding the pitfalls of the ## macro operator. 186 */ 187 #define JUCE_JOIN_MACRO(item1, item2) JUCE_JOIN_MACRO_HELPER (item1, item2) 188 189 /** A handy C macro for stringifying any symbol, rather than just a macro parameter. */ 190 #define JUCE_STRINGIFY(item) JUCE_STRINGIFY_MACRO_HELPER (item) 191 192 //============================================================================== 193 /** This is a shorthand macro for deleting a class's copy constructor and 194 copy assignment operator. 195 196 For example, instead of 197 @code 198 class MyClass 199 { 200 etc.. 201 202 private: 203 MyClass (const MyClass&); 204 MyClass& operator= (const MyClass&); 205 };@endcode 206 207 ..you can just write: 208 209 @code 210 class MyClass 211 { 212 etc.. 213 214 private: 215 JUCE_DECLARE_NON_COPYABLE (MyClass) 216 };@endcode 217 */ 218 #define JUCE_DECLARE_NON_COPYABLE(className) \ 219 className (const className&) = delete;\ 220 className& operator= (const className&) = delete; 221 222 /** This is a shorthand macro for deleting a class's move constructor and 223 move assignment operator. 224 */ 225 #define JUCE_DECLARE_NON_MOVEABLE(className) \ 226 className (className&&) = delete;\ 227 className& operator= (className&&) = delete; 228 229 /** This is a shorthand way of writing both a JUCE_DECLARE_NON_COPYABLE and 230 JUCE_LEAK_DETECTOR macro for a class. 231 */ 232 #define JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(className) \ 233 JUCE_DECLARE_NON_COPYABLE(className) \ 234 JUCE_LEAK_DETECTOR(className) 235 236 /** This macro can be added to class definitions to disable the use of new/delete to 237 allocate the object on the heap, forcing it to only be used as a stack or member variable. 238 */ 239 #define JUCE_PREVENT_HEAP_ALLOCATION \ 240 private: \ 241 static void* operator new (size_t) = delete; \ 242 static void operator delete (void*) = delete; 243 244 //============================================================================== 245 #if JUCE_MSVC && ! defined (DOXYGEN) 246 #define JUCE_WARNING_HELPER(file, line, mess) message(file "(" JUCE_STRINGIFY (line) ") : Warning: " #mess) 247 #define JUCE_COMPILER_WARNING(message) __pragma(JUCE_WARNING_HELPER (__FILE__, __LINE__, message)) 248 #else 249 #ifndef DOXYGEN 250 #define JUCE_WARNING_HELPER(mess) message(#mess) 251 #endif 252 253 /** This macro allows you to emit a custom compiler warning message. 254 Very handy for marking bits of code as "to-do" items, or for shaming 255 code written by your co-workers in a way that's hard to ignore. 256 257 GCC and Clang provide the \#warning directive, but MSVC doesn't, so this macro 258 is a cross-compiler way to get the same functionality as \#warning. 259 */ 260 #define JUCE_COMPILER_WARNING(message) _Pragma(JUCE_STRINGIFY (JUCE_WARNING_HELPER (message))) 261 #endif 262 263 264 //============================================================================== 265 #if JUCE_DEBUG || DOXYGEN 266 /** A platform-independent way of forcing an inline function. 267 Use the syntax: @code 268 forcedinline void myfunction (int x) 269 @endcode 270 */ 271 #define forcedinline inline 272 #else 273 #if JUCE_MSVC 274 #define forcedinline __forceinline 275 #else 276 #define forcedinline inline __attribute__((always_inline)) 277 #endif 278 #endif 279 280 #if JUCE_MSVC || DOXYGEN 281 /** This can be placed before a stack or member variable declaration to tell the compiler 282 to align it to the specified number of bytes. */ 283 #define JUCE_ALIGN(bytes) __declspec (align (bytes)) 284 #else 285 #define JUCE_ALIGN(bytes) __attribute__ ((aligned (bytes))) 286 #endif 287 288 //============================================================================== 289 // Cross-compiler deprecation macros.. 290 #ifdef DOXYGEN 291 /** This macro can be used to wrap a function which has been deprecated. */ 292 #define JUCE_DEPRECATED(functionDef) 293 #define JUCE_DEPRECATED_WITH_BODY(functionDef, body) 294 #elif JUCE_MSVC && ! JUCE_NO_DEPRECATION_WARNINGS 295 #define JUCE_DEPRECATED_ATTRIBUTE __declspec(deprecated) 296 #define JUCE_DEPRECATED(functionDef) JUCE_DEPRECATED_ATTRIBUTE functionDef 297 #define JUCE_DEPRECATED_WITH_BODY(functionDef, body) JUCE_DEPRECATED_ATTRIBUTE functionDef body 298 #elif (JUCE_GCC || JUCE_CLANG) && ! JUCE_NO_DEPRECATION_WARNINGS 299 #define JUCE_DEPRECATED_ATTRIBUTE __attribute__ ((deprecated)) 300 #define JUCE_DEPRECATED(functionDef) functionDef JUCE_DEPRECATED_ATTRIBUTE 301 #define JUCE_DEPRECATED_WITH_BODY(functionDef, body) functionDef JUCE_DEPRECATED_ATTRIBUTE body 302 #else 303 #define JUCE_DEPRECATED_ATTRIBUTE 304 #define JUCE_DEPRECATED(functionDef) functionDef 305 #define JUCE_DEPRECATED_WITH_BODY(functionDef, body) functionDef body 306 #endif 307 308 #if JUCE_ALLOW_STATIC_NULL_VARIABLES 309 #if ! (defined (DOXYGEN) || defined (JUCE_GCC) || (JUCE_MSVC && _MSC_VER <= 1900)) 310 #define JUCE_DEPRECATED_STATIC(valueDef) JUCE_DEPRECATED_ATTRIBUTE valueDef 311 312 #if JUCE_MSVC 313 #define JUCE_DECLARE_DEPRECATED_STATIC(valueDef) \ 314 __pragma(warning(push)) \ 315 __pragma(warning(disable:4996)) \ 316 valueDef \ 317 __pragma(warning(pop)) 318 #else 319 #define JUCE_DECLARE_DEPRECATED_STATIC(valueDef) valueDef 320 #endif 321 #else 322 #define JUCE_DEPRECATED_STATIC(valueDef) valueDef 323 #define JUCE_DECLARE_DEPRECATED_STATIC(valueDef) valueDef 324 #endif 325 #else 326 #define JUCE_DEPRECATED_STATIC(valueDef) 327 #define JUCE_DECLARE_DEPRECATED_STATIC(valueDef) 328 #endif 329 330 //============================================================================== 331 #if JUCE_ANDROID && ! DOXYGEN 332 #define JUCE_MODAL_LOOPS_PERMITTED 0 333 #elif ! defined (JUCE_MODAL_LOOPS_PERMITTED) 334 /** Some operating environments don't provide a modal loop mechanism, so this flag can be 335 used to disable any functions that try to run a modal loop. */ 336 #define JUCE_MODAL_LOOPS_PERMITTED 1 337 #endif 338 339 //============================================================================== 340 #if JUCE_GCC || JUCE_CLANG 341 #define JUCE_PACKED __attribute__((packed)) 342 #elif ! DOXYGEN 343 #define JUCE_PACKED 344 #endif 345 346 //============================================================================== 347 #if JUCE_GCC || DOXYGEN 348 /** This can be appended to a function declaration to tell gcc to disable associative 349 math optimisations which break some floating point algorithms. */ 350 #define JUCE_NO_ASSOCIATIVE_MATH_OPTIMISATIONS __attribute__((__optimize__("no-associative-math"))) 351 #else 352 #define JUCE_NO_ASSOCIATIVE_MATH_OPTIMISATIONS 353 #endif 354 355 } // namespace juce 356