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_LINUX 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_MAC && JUCE_CLANG && JUCE_ARM 70 #define JUCE_BREAK_IN_DEBUGGER { __builtin_debugtrap(); } 71 #elif JUCE_MSVC 72 #ifndef __INTEL_COMPILER 73 #pragma intrinsic (__debugbreak) 74 #endif 75 #define JUCE_BREAK_IN_DEBUGGER { __debugbreak(); } 76 #elif JUCE_INTEL && (JUCE_GCC || JUCE_MAC) 77 #if JUCE_NO_INLINE_ASM 78 #define JUCE_BREAK_IN_DEBUGGER { } 79 #else 80 #define JUCE_BREAK_IN_DEBUGGER { asm ("int $3"); } 81 #endif 82 #elif JUCE_ANDROID 83 #define JUCE_BREAK_IN_DEBUGGER { __builtin_trap(); } 84 #else 85 #define JUCE_BREAK_IN_DEBUGGER { __asm int 3 } 86 #endif 87 88 #if JUCE_CLANG && defined (__has_feature) && ! defined (JUCE_ANALYZER_NORETURN) 89 #if __has_feature (attribute_analyzer_noreturn) juce_assert_noreturn()90 inline void __attribute__((analyzer_noreturn)) juce_assert_noreturn() {} 91 #define JUCE_ANALYZER_NORETURN juce::juce_assert_noreturn(); 92 #endif 93 #endif 94 95 #ifndef JUCE_ANALYZER_NORETURN 96 #define JUCE_ANALYZER_NORETURN 97 #endif 98 99 /** Used to silence Wimplicit-fallthrough on Clang and GCC where available 100 as there are a few places in the codebase where we need to do this 101 deliberately and want to ignore the warning. 102 */ 103 #if JUCE_CLANG 104 #define JUCE_FALLTHROUGH [[clang::fallthrough]]; 105 #elif JUCE_GCC 106 #if __GNUC__ >= 7 107 #define JUCE_FALLTHROUGH [[gnu::fallthrough]]; 108 #else 109 #define JUCE_FALLTHROUGH 110 #endif 111 #else 112 #define JUCE_FALLTHROUGH 113 #endif 114 115 //============================================================================== 116 #if JUCE_MSVC && ! DOXYGEN 117 #define JUCE_BLOCK_WITH_FORCED_SEMICOLON(x) \ 118 __pragma(warning(push)) \ 119 __pragma(warning(disable:4127)) \ 120 do { x } while (false) \ 121 __pragma(warning(pop)) 122 #else 123 /** This is the good old C++ trick for creating a macro that forces the user to put 124 a semicolon after it when they use it. 125 */ 126 #define JUCE_BLOCK_WITH_FORCED_SEMICOLON(x) do { x } while (false) 127 #endif 128 129 //============================================================================== 130 #if (JUCE_DEBUG && ! JUCE_DISABLE_ASSERTIONS) || DOXYGEN 131 /** Writes a string to the standard error stream. 132 Note that as well as a single string, you can use this to write multiple items 133 as a stream, e.g. 134 @code 135 DBG ("foo = " << foo << "bar = " << bar); 136 @endcode 137 The macro is only enabled in a debug build, so be careful not to use it with expressions 138 that have important side-effects! 139 @see Logger::outputDebugString 140 */ 141 #define DBG(textToWrite) JUCE_BLOCK_WITH_FORCED_SEMICOLON (juce::String tempDbgBuf; tempDbgBuf << textToWrite; juce::Logger::outputDebugString (tempDbgBuf);) 142 143 //============================================================================== 144 /** This will always cause an assertion failure. 145 It is only compiled in a debug build, (unless JUCE_LOG_ASSERTIONS is enabled for your build). 146 @see jassert 147 */ 148 #define jassertfalse JUCE_BLOCK_WITH_FORCED_SEMICOLON (JUCE_LOG_CURRENT_ASSERTION; if (juce::juce_isRunningUnderDebugger()) JUCE_BREAK_IN_DEBUGGER; JUCE_ANALYZER_NORETURN) 149 150 //============================================================================== 151 /** Platform-independent assertion macro. 152 153 This macro gets turned into a no-op when you're building with debugging turned off, so be 154 careful that the expression you pass to it doesn't perform any actions that are vital for the 155 correct behaviour of your program! 156 @see jassertfalse 157 */ 158 #define jassert(expression) JUCE_BLOCK_WITH_FORCED_SEMICOLON (if (! (expression)) jassertfalse;) 159 160 #else 161 //============================================================================== 162 // If debugging is disabled, these dummy debug and assertion macros are used.. 163 164 #define DBG(textToWrite) 165 #define jassertfalse JUCE_BLOCK_WITH_FORCED_SEMICOLON (JUCE_LOG_CURRENT_ASSERTION) 166 167 #if JUCE_LOG_ASSERTIONS 168 #define jassert(expression) JUCE_BLOCK_WITH_FORCED_SEMICOLON (if (! (expression)) jassertfalse;) 169 #else 170 #define jassert(expression) JUCE_BLOCK_WITH_FORCED_SEMICOLON ( ; ) 171 #endif 172 173 #endif 174 175 //============================================================================== 176 #if ! DOXYGEN 177 #define JUCE_JOIN_MACRO_HELPER(a, b) a ## b 178 #define JUCE_STRINGIFY_MACRO_HELPER(a) #a 179 #endif 180 181 /** A good old-fashioned C macro concatenation helper. 182 This combines two items (which may themselves be macros) into a single string, 183 avoiding the pitfalls of the ## macro operator. 184 */ 185 #define JUCE_JOIN_MACRO(item1, item2) JUCE_JOIN_MACRO_HELPER (item1, item2) 186 187 /** A handy C macro for stringifying any symbol, rather than just a macro parameter. */ 188 #define JUCE_STRINGIFY(item) JUCE_STRINGIFY_MACRO_HELPER (item) 189 190 //============================================================================== 191 /** This is a shorthand macro for declaring stubs for a class's copy constructor and operator=. 192 193 For example, instead of 194 @code 195 class MyClass 196 { 197 etc.. 198 199 private: 200 MyClass (const MyClass&); 201 MyClass& operator= (const MyClass&); 202 };@endcode 203 204 ..you can just write: 205 206 @code 207 class MyClass 208 { 209 etc.. 210 211 private: 212 JUCE_DECLARE_NON_COPYABLE (MyClass) 213 };@endcode 214 */ 215 #define JUCE_DECLARE_NON_COPYABLE(className) \ 216 className (const className&) = delete;\ 217 className& operator= (const className&) = delete; 218 219 /** This is a shorthand way of writing both a JUCE_DECLARE_NON_COPYABLE and 220 JUCE_LEAK_DETECTOR macro for a class. 221 */ 222 #define JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(className) \ 223 JUCE_DECLARE_NON_COPYABLE(className) \ 224 JUCE_LEAK_DETECTOR(className) 225 226 /** This macro can be added to class definitions to disable the use of new/delete to 227 allocate the object on the heap, forcing it to only be used as a stack or member variable. 228 */ 229 #define JUCE_PREVENT_HEAP_ALLOCATION \ 230 private: \ 231 static void* operator new (size_t) = delete; \ 232 static void operator delete (void*) = delete; 233 234 //============================================================================== 235 #if JUCE_MSVC && ! defined (DOXYGEN) 236 #define JUCE_WARNING_HELPER(file, line, mess) message(file "(" JUCE_STRINGIFY (line) ") : Warning: " #mess) 237 #define JUCE_COMPILER_WARNING(message) __pragma(JUCE_WARNING_HELPER (__FILE__, __LINE__, message)) 238 #else 239 #ifndef DOXYGEN 240 #define JUCE_WARNING_HELPER(mess) message(#mess) 241 #endif 242 243 /** This macro allows you to emit a custom compiler warning message. 244 Very handy for marking bits of code as "to-do" items, or for shaming 245 code written by your co-workers in a way that's hard to ignore. 246 247 GCC and Clang provide the \#warning directive, but MSVC doesn't, so this macro 248 is a cross-compiler way to get the same functionality as \#warning. 249 */ 250 #define JUCE_COMPILER_WARNING(message) _Pragma(JUCE_STRINGIFY (JUCE_WARNING_HELPER (message))) 251 #endif 252 253 254 //============================================================================== 255 #if JUCE_DEBUG || DOXYGEN 256 /** A platform-independent way of forcing an inline function. 257 Use the syntax: @code 258 forcedinline void myfunction (int x) 259 @endcode 260 */ 261 #define forcedinline inline 262 #else 263 #if JUCE_MSVC 264 #define forcedinline __forceinline 265 #else 266 #define forcedinline inline __attribute__((always_inline)) 267 #endif 268 #endif 269 270 #if JUCE_MSVC || DOXYGEN 271 /** This can be placed before a stack or member variable declaration to tell the compiler 272 to align it to the specified number of bytes. */ 273 #define JUCE_ALIGN(bytes) __declspec (align (bytes)) 274 #else 275 #define JUCE_ALIGN(bytes) __attribute__ ((aligned (bytes))) 276 #endif 277 278 //============================================================================== 279 // Cross-compiler deprecation macros.. 280 #ifdef DOXYGEN 281 /** This macro can be used to wrap a function which has been deprecated. */ 282 #define JUCE_DEPRECATED(functionDef) 283 #define JUCE_DEPRECATED_WITH_BODY(functionDef, body) 284 #elif JUCE_MSVC && ! JUCE_NO_DEPRECATION_WARNINGS 285 #define JUCE_DEPRECATED_ATTRIBUTE __declspec(deprecated) 286 #define JUCE_DEPRECATED(functionDef) JUCE_DEPRECATED_ATTRIBUTE functionDef 287 #define JUCE_DEPRECATED_WITH_BODY(functionDef, body) JUCE_DEPRECATED_ATTRIBUTE functionDef body 288 #elif (JUCE_GCC || JUCE_CLANG) && ! JUCE_NO_DEPRECATION_WARNINGS 289 #define JUCE_DEPRECATED_ATTRIBUTE __attribute__ ((deprecated)) 290 #define JUCE_DEPRECATED(functionDef) functionDef JUCE_DEPRECATED_ATTRIBUTE 291 #define JUCE_DEPRECATED_WITH_BODY(functionDef, body) functionDef JUCE_DEPRECATED_ATTRIBUTE body 292 #else 293 #define JUCE_DEPRECATED_ATTRIBUTE 294 #define JUCE_DEPRECATED(functionDef) functionDef 295 #define JUCE_DEPRECATED_WITH_BODY(functionDef, body) functionDef body 296 #endif 297 298 #if JUCE_ALLOW_STATIC_NULL_VARIABLES 299 #if ! (defined (DOXYGEN) || defined (JUCE_GCC) || (JUCE_MSVC && _MSC_VER <= 1900)) 300 #define JUCE_DEPRECATED_STATIC(valueDef) JUCE_DEPRECATED_ATTRIBUTE valueDef 301 302 #if JUCE_MSVC 303 #define JUCE_DECLARE_DEPRECATED_STATIC(valueDef) \ 304 __pragma(warning(push)) \ 305 __pragma(warning(disable:4996)) \ 306 valueDef \ 307 __pragma(warning(pop)) 308 #else 309 #define JUCE_DECLARE_DEPRECATED_STATIC(valueDef) valueDef 310 #endif 311 #else 312 #define JUCE_DEPRECATED_STATIC(valueDef) valueDef 313 #define JUCE_DECLARE_DEPRECATED_STATIC(valueDef) valueDef 314 #endif 315 #else 316 #define JUCE_DEPRECATED_STATIC(valueDef) 317 #define JUCE_DECLARE_DEPRECATED_STATIC(valueDef) 318 #endif 319 320 //============================================================================== 321 #if JUCE_ANDROID && ! DOXYGEN 322 #define JUCE_MODAL_LOOPS_PERMITTED 0 323 #elif ! defined (JUCE_MODAL_LOOPS_PERMITTED) 324 /** Some operating environments don't provide a modal loop mechanism, so this flag can be 325 used to disable any functions that try to run a modal loop. */ 326 #define JUCE_MODAL_LOOPS_PERMITTED 1 327 #endif 328 329 //============================================================================== 330 #if JUCE_GCC || JUCE_CLANG 331 #define JUCE_PACKED __attribute__((packed)) 332 #elif ! DOXYGEN 333 #define JUCE_PACKED 334 #endif 335 336 //============================================================================== 337 #if JUCE_GCC || DOXYGEN 338 /** This can be appended to a function declaration to tell gcc to disable associative 339 math optimisations which break some floating point algorithms. */ 340 #define JUCE_NO_ASSOCIATIVE_MATH_OPTIMISATIONS __attribute__((__optimize__("no-associative-math"))) 341 #else 342 #define JUCE_NO_ASSOCIATIVE_MATH_OPTIMISATIONS 343 #endif 344 345 } // namespace juce 346