Line data Source code
1 : /* Copyright (c) 2021 Wildfire Games.
2 : *
3 : * Permission is hereby granted, free of charge, to any person obtaining
4 : * a copy of this software and associated documentation files (the
5 : * "Software"), to deal in the Software without restriction, including
6 : * without limitation the rights to use, copy, modify, merge, publish,
7 : * distribute, sublicense, and/or sell copies of the Software, and to
8 : * permit persons to whom the Software is furnished to do so, subject to
9 : * the following conditions:
10 : *
11 : * The above copyright notice and this permission notice shall be included
12 : * in all copies or substantial portions of the Software.
13 : *
14 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 : * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 : * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17 : * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
18 : * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
19 : * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
20 : * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 : */
22 :
23 : /*
24 : * macros for code annotation.
25 : */
26 :
27 : #ifndef INCLUDED_CODE_ANNOTATION
28 : #define INCLUDED_CODE_ANNOTATION
29 :
30 : #include "lib/sysdep/compiler.h"
31 : #include "lib/sysdep/arch.h" // ARCH_AMD64
32 :
33 : /**
34 : * mark a function parameter as unused and avoid
35 : * the corresponding compiler warning.
36 : * wrap around the parameter name, e.g. void f(int UNUSED(x))
37 : **/
38 : #define UNUSED(param)
39 :
40 : /**
41 : * mark a function local variable or parameter as unused and avoid
42 : * the corresponding compiler warning.
43 : * note that UNUSED is not applicable to variable definitions that
44 : * involve initialization, nor is it sufficient in cases where
45 : * an argument is unused only in certain situations.
46 : * example: void f(int x) { ASSERT(x == 0); UNUSED2(x); }
47 : * this asserts in debug builds and avoids warnings in release.
48 : **/
49 : #if HAVE_C99 && GCC_VERSION // _Pragma from C99, unused from GCC
50 : # define UNUSED2(param) _Pragma("unused " #param)
51 : #elif ICC_VERSION
52 : // ICC 12 still doesn't recognize pragma unused, casting to void
53 : // isn't sufficient, and self-assignment doesn't work for references.
54 : # define UNUSED2(param) do{ if(¶m) {} } while(false)
55 : #else
56 : # define UNUSED2(param) ((void)(param))
57 : #endif
58 :
59 : /**
60 : * Silence the 'unused result' warning.
61 : * (void) would be sufficient but Spidermonkey still uses warn_unused_result,
62 : * and GCC is stricter about that. See https://bugzilla.mozilla.org/show_bug.cgi?id=1571631.
63 : **/
64 : template<typename T>
65 246 : inline void ignore_result(const T&) {}
66 :
67 : /**
68 : * indicate a function will not throw any synchronous exceptions,
69 : * thus hopefully generating smaller and more efficient code.
70 : *
71 : * must be placed BEFORE return types because "The [VC++] compiler
72 : * ignores, without warning, any __declspec keywords placed after *".
73 : * such syntax is apparently also legal in GCC, per the example
74 : * "__attribute__((noreturn)) void d0 (void)".
75 : *
76 : * example:
77 : * NOTHROW_DECLARE void function();
78 : * NOTHROW_DEFINE void function() {}
79 : **/
80 : #if GCC_VERSION
81 : # define NOTHROW_DECLARE __attribute__((nothrow))
82 : # define NOTHROW_DEFINE // not supported for definitions
83 : #elif CLANG_VERSION
84 : # define NOTHROW_DECLARE __attribute__((nothrow))
85 : # define NOTHROW_DEFINE // not supported for definitions
86 : #elif MSC_VERSION
87 : // Kevin Frei, 2006-03-23: "I work on the Visual C++ compiler team,
88 : // and agree completely with Paul Parks: don't use throw(), because
89 : // there's a chance that we'll eventually implement it according to the standard".
90 : # define NOTHROW_DECLARE __declspec(nothrow)
91 : # define NOTHROW_DEFINE __declspec(nothrow)
92 : #else
93 : // don't use throw() because it might result in ADDITIONAL checks
94 : // (the standard mandates calling unexpected())
95 : # define NOTHROW_DECLARE
96 : # define NOTHROW_DEFINE
97 : #endif
98 :
99 :
100 : /**
101 : * mark a function as noreturn for static analyzer purposes.
102 : * currently only for clang-analyzer.
103 : */
104 : #if __has_feature(attribute_analyzer_noreturn)
105 : # define ANALYZER_NORETURN __attribute__((analyzer_noreturn))
106 : #else
107 : # define ANALYZER_NORETURN
108 : #endif
109 :
110 :
111 : /**
112 : * "unreachable code" helpers
113 : *
114 : * unreachable lines of code are often the source or symptom of subtle bugs.
115 : * they are flagged by compiler warnings; however, the opposite problem -
116 : * erroneously reaching certain spots (e.g. due to missing return statement)
117 : * is worse and not detected automatically.
118 : *
119 : * to defend against this, the programmer can annotate their code to
120 : * indicate to humans that a particular spot should never be reached.
121 : * however, that isn't much help; better is a sentinel that raises an
122 : * error if if it is actually reached. hence, the UNREACHABLE macro.
123 : *
124 : * ironically, if the code guarded by UNREACHABLE works as it should,
125 : * compilers may flag the macro's code as unreachable. this would
126 : * distract from genuine warnings, which is unacceptable.
127 : *
128 : * even worse, compilers differ in their code checking: GCC only complains if
129 : * non-void functions end without returning a value (i.e. missing return
130 : * statement), while VC checks if lines are unreachable (e.g. if they are
131 : * preceded by a return on all paths).
132 : *
133 : * the implementation below enables optimization and automated checking
134 : * without raising warnings.
135 : **/
136 : #define UNREACHABLE // actually defined below.. this is for
137 : # undef UNREACHABLE // CppDoc's benefit only.
138 :
139 : // this macro should not generate any fallback code; it is merely the
140 : // compiler-specific backend for UNREACHABLE.
141 : // #define it to nothing if the compiler doesn't support such a hint.
142 : #define HAVE_ASSUME_UNREACHABLE 1
143 : #if MSC_VERSION && !ICC_VERSION // (ICC ignores this)
144 : # define ASSUME_UNREACHABLE __assume(0)
145 : #elif GCC_VERSION
146 : # define ASSUME_UNREACHABLE __builtin_unreachable()
147 : #else
148 : # define ASSUME_UNREACHABLE
149 : # undef HAVE_ASSUME_UNREACHABLE
150 : # define HAVE_ASSUME_UNREACHABLE 0
151 : #endif
152 :
153 : // compiler supports ASSUME_UNREACHABLE => allow it to assume the code is
154 : // never reached (improves optimization at the cost of undefined behavior
155 : // if the annotation turns out to be incorrect).
156 : #if HAVE_ASSUME_UNREACHABLE && !CONFIG_ENABLE_CHECKS
157 : # define UNREACHABLE ASSUME_UNREACHABLE
158 : // otherwise (or if CONFIG_ENABLE_CHECKS is set), add a user-visible
159 : // warning if the code is reached. note that abort() fails to stop
160 : // ICC from warning about the lack of a return statement, so we
161 : // use an infinite loop instead.
162 : #else
163 : # define UNREACHABLE\
164 : STMT(\
165 : DEBUG_WARN_ERR(ERR::LOGIC); /* hit supposedly unreachable code */\
166 : for(;;){};\
167 : )
168 : #endif
169 :
170 : /**
171 : convenient specialization of UNREACHABLE for switch statements whose
172 : default can never be reached. example usage:
173 : int x;
174 : switch(x % 2)
175 : {
176 : case 0: break;
177 : case 1: break;
178 : NODEFAULT;
179 : }
180 : **/
181 : #define NODEFAULT default: UNREACHABLE
182 :
183 :
184 : // generate a symbol containing the line number of the macro invocation.
185 : // used to give a unique name (per file) to types or variables.
186 : // we can't prepend __FILE__ to make it globally unique - the filename
187 : // may be enclosed in quotes. PASTE3_HIDDEN__ is needed to make sure
188 : // __LINE__ is expanded correctly.
189 : #define PASTE3_HIDDEN__(a, b, c) a ## b ## c
190 : #define PASTE3__(a, b, c) PASTE3_HIDDEN__(a, b, c)
191 : #define UID__ PASTE3__(LINE_, __LINE__, _)
192 : #define UID2__ PASTE3__(LINE_, __LINE__, _2)
193 :
194 :
195 : //-----------------------------------------------------------------------------
196 : // cassert
197 :
198 : /**
199 : * Compile-time assertion. Causes a compile error if the expression
200 : * evaluates to zero/false.
201 : *
202 : * No runtime overhead; may be used anywhere, including file scope.
203 : * Especially useful for testing sizeof types.
204 : *
205 : * @param expr Expression that is expected to evaluate to non-zero at compile-time.
206 : **/
207 : #define cassert(expr) static_assert((expr), #expr)
208 :
209 :
210 : /**
211 : * Indicates that a class is noncopyable (usually due to const or reference
212 : * members, or because the class works as a singleton).
213 : *
214 : * For example:
215 : *
216 : * @code
217 : * class ClassName {
218 : * NONCOPYABLE(ClassName);
219 : * public: // etc.
220 : * };
221 : * @endcode
222 : *
223 : * This is preferable to inheritance from boost::noncopyable because it avoids
224 : * ICC 11 W4 warnings about non-virtual dtors and suppression of the copy
225 : * assignment operator.
226 : */
227 : #define NONCOPYABLE(className) \
228 : className(const className&) = delete; \
229 : className& operator=(const className&) = delete
230 :
231 : /**
232 : * Indicates that move semantics can be used, so that a NONCOPYABLE class can still be assigned by taking over the reference to the value.
233 : * Make sure to use the macro with the necessary access modifier.
234 : */
235 : #define MOVABLE(className) \
236 : className(className&&) = default; \
237 : className& operator=(className&&) = default
238 :
239 : #if ICC_VERSION
240 : # define ASSUME_ALIGNED(ptr, multiple) __assume_aligned(ptr, multiple)
241 : #else
242 : # define ASSUME_ALIGNED(ptr, multiple)
243 : #endif
244 :
245 : // annotate printf-style functions for compile-time type checking.
246 : // fmtpos is the index of the format argument, counting from 1 or
247 : // (if it's a non-static class function) 2; the '...' is assumed
248 : // to come directly after it.
249 : #if GCC_VERSION
250 : # define PRINTF_ARGS(fmtpos) __attribute__ ((format (printf, fmtpos, fmtpos+1)))
251 : # define VPRINTF_ARGS(fmtpos) __attribute__ ((format (printf, fmtpos, 0)))
252 : # define WPRINTF_ARGS(fmtpos) /* not currently supported in GCC */
253 : # define VWPRINTF_ARGS(fmtpos) /* not currently supported in GCC */
254 : #else
255 : # define PRINTF_ARGS(fmtpos)
256 : # define VPRINTF_ARGS(fmtpos)
257 : # define WPRINTF_ARGS(fmtpos)
258 : # define VWPRINTF_ARGS(fmtpos)
259 : // TODO: support _Printf_format_string_ for VC9+
260 : #endif
261 :
262 : // annotate vararg functions that expect to end with an explicit NULL
263 : #if GCC_VERSION
264 : # define SENTINEL_ARG __attribute__ ((sentinel))
265 : #else
266 : # define SENTINEL_ARG
267 : #endif
268 :
269 : /**
270 : * prevent the compiler from reordering loads or stores across this point.
271 : **/
272 : #if ICC_VERSION
273 : # define COMPILER_FENCE __memory_barrier()
274 : #elif MSC_VERSION
275 : # include <intrin.h>
276 : # pragma intrinsic(_ReadWriteBarrier)
277 : # define COMPILER_FENCE _ReadWriteBarrier()
278 : #elif GCC_VERSION
279 : # define COMPILER_FENCE asm volatile("" : : : "memory")
280 : #else
281 : # define COMPILER_FENCE
282 : #endif
283 :
284 :
285 : // try to define _W64, if not already done
286 : // (this is useful for catching pointer size bugs)
287 : #ifndef _W64
288 : # if MSC_VERSION
289 : # define _W64 __w64
290 : # elif GCC_VERSION
291 : # define _W64 __attribute__((mode (__pointer__)))
292 : # else
293 : # define _W64
294 : # endif
295 : #endif
296 :
297 :
298 : // C99-like restrict (non-standard in C++, but widely supported in various forms).
299 : //
300 : // May be used on pointers. May also be used on member functions to indicate
301 : // that 'this' is unaliased (e.g. "void C::m() RESTRICT { ... }").
302 : // Must not be used on references - GCC supports that but VC doesn't.
303 : //
304 : // We call this "RESTRICT" to avoid conflicts with VC's __declspec(restrict),
305 : // and because it's not really the same as C99's restrict.
306 : //
307 : // To be safe and satisfy the compilers' stated requirements: an object accessed
308 : // by a restricted pointer must not be accessed by any other pointer within the
309 : // lifetime of the restricted pointer, if the object is modified.
310 : // To maximise the chance of optimisation, any pointers that could potentially
311 : // alias with the restricted one should be marked as restricted too.
312 : //
313 : // It would probably be a good idea to write test cases for any code that uses
314 : // this in an even very slightly unclear way, in case it causes obscure problems
315 : // in a rare compiler due to differing semantics.
316 : //
317 : // .. GCC
318 : #if GCC_VERSION
319 : # define RESTRICT __restrict__
320 : // .. VC8 provides __restrict
321 : #elif MSC_VERSION
322 : # define RESTRICT __restrict
323 : // .. ICC supports the keyword 'restrict' when run with the /Qrestrict option,
324 : // but it always also supports __restrict__ or __restrict to be compatible
325 : // with GCC/MSVC, so we'll use the underscored version. One of {GCC,MSC}_VERSION
326 : // should have been defined in addition to ICC_VERSION, so we should be using
327 : // one of the above cases (unless it's an old VS7.1-emulating ICC).
328 : #elif ICC_VERSION
329 : # error ICC_VERSION defined without either GCC_VERSION or an adequate MSC_VERSION
330 : // .. unsupported; remove it from code
331 : #else
332 : # define RESTRICT
333 : #endif
334 :
335 :
336 : //
337 : // number of array elements
338 : //
339 :
340 : // (function taking a reference to an array and returning a pointer to
341 : // an array of characters. it's only declared and never defined; we just
342 : // need it to determine n, the size of the array that was passed.)
343 : template<typename T, size_t n> char (*ArraySizeDeducer(T (&)[n]))[n];
344 :
345 : // (although requiring C++, this method is much better than the standard
346 : // sizeof(name) / sizeof(name[0]) because it doesn't compile when a
347 : // pointer is passed, which can easily happen under maintenance.)
348 : #define ARRAY_SIZE(name) (sizeof(*ArraySizeDeducer(name)))
349 :
350 :
351 : // C99-style __func__
352 : // .. newer GCC already have it
353 : #if GCC_VERSION
354 : // nothing need be done
355 : // .. MSVC have __FUNCTION__
356 : #elif MSC_VERSION
357 : # define __func__ __FUNCTION__
358 : // .. unsupported
359 : #else
360 : # define __func__ "(unknown)"
361 : #endif
362 :
363 :
364 : // extern "C", but does the right thing in pure-C mode
365 : #if defined(__cplusplus)
366 : # define EXTERN_C extern "C"
367 : #else
368 : # define EXTERN_C extern
369 : #endif
370 :
371 :
372 : #if MSC_VERSION
373 : # define INLINE __forceinline
374 : #else
375 : # define INLINE inline
376 : #endif
377 :
378 :
379 : #if MSC_VERSION
380 : # define CALL_CONV __cdecl
381 : #else
382 : # define CALL_CONV
383 : #endif
384 :
385 :
386 : #if MSC_VERSION && !ARCH_AMD64
387 : # define DECORATED_NAME(name) _##name
388 : #else
389 : # define DECORATED_NAME(name) name
390 : #endif
391 :
392 :
393 : // workaround for preprocessor limitation: macro args aren't expanded
394 : // before being pasted.
395 : #define STRINGIZE2(id) # id
396 : #define STRINGIZE(id) STRINGIZE2(id)
397 :
398 : // for widening non-literals (e.g. __FILE__)
399 : // note: C99 says __func__ is a magic *variable*, and GCC doesn't allow
400 : // widening it via preprocessor.
401 : #define WIDEN2(x) L ## x
402 : #define WIDEN(x) WIDEN2(x)
403 :
404 : // TODO: Replace this with [[fallthrough]] once we support C++17
405 : #if __has_cpp_attribute(fallthrough) || defined(__cplusplus) && __cplusplus >= 201703L
406 : # define FALLTHROUGH [[fallthrough]]
407 : #elif __has_cpp_attribute(gnu::fallthrough)
408 : # define FALLTHROUGH [[gnu::fallthrough]]
409 : #elif __has_cpp_attribute(clang::fallthrough)
410 : # define FALLTHROUGH [[clang::fallthrough]]
411 : #else
412 : # define FALLTHROUGH
413 : // TODO: Maybe use __fallthrough for the MSVC code analyzer (also figure out if we need to add some switch when switching to a newer version of VS that supports [[fallthrough]]
414 : #endif
415 :
416 : #endif // #ifndef INCLUDED_CODE_ANNOTATION
|