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