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