Pyrogenesis
trunk
Main Page
Related Pages
Namespaces
Classes
Files
File List
File Members
source
lib
code_annotation.h
Go to the documentation of this file.
1
/* Copyright (c) 2015 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
/**
61
* indicate a function will not throw any synchronous exceptions,
62
* thus hopefully generating smaller and more efficient code.
63
*
64
* must be placed BEFORE return types because "The [VC++] compiler
65
* ignores, without warning, any __declspec keywords placed after *".
66
* such syntax is apparently also legal in GCC, per the example
67
* "__attribute__((noreturn)) void d0 (void)".
68
*
69
* example:
70
* NOTHROW_DECLARE void function();
71
* NOTHROW_DEFINE void function() {}
72
**/
73
#if GCC_VERSION
74
# define NOTHROW_DECLARE __attribute__((nothrow))
75
# define NOTHROW_DEFINE // not supported for definitions
76
#elif MSC_VERSION
77
// Kevin Frei, 2006-03-23: "I work on the Visual C++ compiler team,
78
// and agree completely with Paul Parks: don't use throw(), because
79
// there's a chance that we'll eventually implement it according to the standard".
80
# define NOTHROW_DECLARE __declspec(nothrow)
81
# define NOTHROW_DEFINE __declspec(nothrow)
82
#else
83
// don't use throw() because it might result in ADDITIONAL checks
84
// (the standard mandates calling unexpected())
85
# define NOTHROW_DECLARE
86
# define NOTHROW_DEFINE
87
#endif
88
89
90
/**
91
* mark a function as noreturn for static analyzer purposes.
92
* currently only for clang-analyzer.
93
*/
94
#if __has_feature(attribute_analyzer_noreturn)
95
# define ANALYZER_NORETURN __attribute__((analyzer_noreturn))
96
#else
97
# define ANALYZER_NORETURN
98
#endif
99
100
101
/**
102
* "unreachable code" helpers
103
*
104
* unreachable lines of code are often the source or symptom of subtle bugs.
105
* they are flagged by compiler warnings; however, the opposite problem -
106
* erroneously reaching certain spots (e.g. due to missing return statement)
107
* is worse and not detected automatically.
108
*
109
* to defend against this, the programmer can annotate their code to
110
* indicate to humans that a particular spot should never be reached.
111
* however, that isn't much help; better is a sentinel that raises an
112
* error if if it is actually reached. hence, the UNREACHABLE macro.
113
*
114
* ironically, if the code guarded by UNREACHABLE works as it should,
115
* compilers may flag the macro's code as unreachable. this would
116
* distract from genuine warnings, which is unacceptable.
117
*
118
* even worse, compilers differ in their code checking: GCC only complains if
119
* non-void functions end without returning a value (i.e. missing return
120
* statement), while VC checks if lines are unreachable (e.g. if they are
121
* preceded by a return on all paths).
122
*
123
* the implementation below enables optimization and automated checking
124
* without raising warnings.
125
**/
126
#define UNREACHABLE // actually defined below.. this is for
127
# undef UNREACHABLE // CppDoc's benefit only.
128
129
// this macro should not generate any fallback code; it is merely the
130
// compiler-specific backend for UNREACHABLE.
131
// #define it to nothing if the compiler doesn't support such a hint.
132
#define HAVE_ASSUME_UNREACHABLE 1
133
#if MSC_VERSION && !ICC_VERSION // (ICC ignores this)
134
# define ASSUME_UNREACHABLE __assume(0)
135
#elif GCC_VERSION
136
# define ASSUME_UNREACHABLE __builtin_unreachable()
137
#else
138
# define ASSUME_UNREACHABLE
139
# undef HAVE_ASSUME_UNREACHABLE
140
# define HAVE_ASSUME_UNREACHABLE 0
141
#endif
142
143
// compiler supports ASSUME_UNREACHABLE => allow it to assume the code is
144
// never reached (improves optimization at the cost of undefined behavior
145
// if the annotation turns out to be incorrect).
146
#if HAVE_ASSUME_UNREACHABLE && !CONFIG_ENABLE_CHECKS
147
# define UNREACHABLE ASSUME_UNREACHABLE
148
// otherwise (or if CONFIG_ENABLE_CHECKS is set), add a user-visible
149
// warning if the code is reached. note that abort() fails to stop
150
// ICC from warning about the lack of a return statement, so we
151
// use an infinite loop instead.
152
#else
153
# define UNREACHABLE\
154
STMT(\
155
DEBUG_WARN_ERR(ERR::LOGIC);
/* hit supposedly unreachable code */
\
156
for(;;){};\
157
)
158
#endif
159
160
/**
161
convenient specialization of UNREACHABLE for switch statements whose
162
default can never be reached. example usage:
163
int x;
164
switch(x % 2)
165
{
166
case 0: break;
167
case 1: break;
168
NODEFAULT;
169
}
170
**/
171
#define NODEFAULT default: UNREACHABLE
172
173
174
// generate a symbol containing the line number of the macro invocation.
175
// used to give a unique name (per file) to types or variables.
176
// we can't prepend __FILE__ to make it globally unique - the filename
177
// may be enclosed in quotes. PASTE3_HIDDEN__ is needed to make sure
178
// __LINE__ is expanded correctly.
179
#define PASTE3_HIDDEN__(a, b, c) a ## b ## c
180
#define PASTE3__(a, b, c) PASTE3_HIDDEN__(a, b, c)
181
#define UID__ PASTE3__(LINE_, __LINE__, _)
182
#define UID2__ PASTE3__(LINE_, __LINE__, _2)
183
184
185
//-----------------------------------------------------------------------------
186
// cassert
187
188
/**
189
* Compile-time assertion. Causes a compile error if the expression
190
* evaluates to zero/false.
191
*
192
* No runtime overhead; may be used anywhere, including file scope.
193
* Especially useful for testing sizeof types.
194
*
195
* @param expr Expression that is expected to evaluate to non-zero at compile-time.
196
**/
197
#define cassert(expr) static_assert((expr), #expr)
198
199
200
/**
201
* Indicates that a class is noncopyable (usually due to const or reference
202
* members, or because the class works as a singleton).
203
*
204
* For example:
205
*
206
* @code
207
* class ClassName {
208
* NONCOPYABLE(ClassName);
209
* public: // etc.
210
* };
211
* @endcode
212
*
213
* This is preferable to inheritance from boost::noncopyable because it avoids
214
* ICC 11 W4 warnings about non-virtual dtors and suppression of the copy
215
* assignment operator.
216
*/
217
#define NONCOPYABLE(className)\
218
public:\
219
className(const className&) = delete;\
220
const className& operator=(const className&) = delete;\
221
private:
222
223
#if ICC_VERSION
224
# define ASSUME_ALIGNED(ptr, multiple) __assume_aligned(ptr, multiple)
225
#else
226
# define ASSUME_ALIGNED(ptr, multiple)
227
#endif
228
229
// annotate printf-style functions for compile-time type checking.
230
// fmtpos is the index of the format argument, counting from 1 or
231
// (if it's a non-static class function) 2; the '...' is assumed
232
// to come directly after it.
233
#if GCC_VERSION
234
# define PRINTF_ARGS(fmtpos) __attribute__ ((format (printf, fmtpos, fmtpos+1)))
235
# define VPRINTF_ARGS(fmtpos) __attribute__ ((format (printf, fmtpos, 0)))
236
# if CONFIG_DEHYDRA
237
# define WPRINTF_ARGS(fmtpos) __attribute__ ((user("format, w, printf, " #fmtpos ", +1")))
238
# else
239
# define WPRINTF_ARGS(fmtpos)
/* not currently supported in GCC */
240
# endif
241
# define VWPRINTF_ARGS(fmtpos)
/* not currently supported in GCC */
242
#else
243
# define PRINTF_ARGS(fmtpos)
244
# define VPRINTF_ARGS(fmtpos)
245
# define WPRINTF_ARGS(fmtpos)
246
# define VWPRINTF_ARGS(fmtpos)
247
// TODO: support _Printf_format_string_ for VC9+
248
#endif
249
250
// annotate vararg functions that expect to end with an explicit NULL
251
#if GCC_VERSION
252
# define SENTINEL_ARG __attribute__ ((sentinel))
253
#else
254
# define SENTINEL_ARG
255
#endif
256
257
/**
258
* prevent the compiler from reordering loads or stores across this point.
259
**/
260
#if ICC_VERSION
261
# define COMPILER_FENCE __memory_barrier()
262
#elif MSC_VERSION
263
# include <intrin.h>
264
# pragma intrinsic(_ReadWriteBarrier)
265
# define COMPILER_FENCE _ReadWriteBarrier()
266
#elif GCC_VERSION
267
# define COMPILER_FENCE asm volatile("" : : : "memory")
268
#else
269
# define COMPILER_FENCE
270
#endif
271
272
273
// try to define _W64, if not already done
274
// (this is useful for catching pointer size bugs)
275
#ifndef _W64
276
# if MSC_VERSION
277
# define _W64 __w64
278
# elif GCC_VERSION
279
# define _W64 __attribute__((mode (__pointer__)))
280
# else
281
# define _W64
282
# endif
283
#endif
284
285
286
// C99-like restrict (non-standard in C++, but widely supported in various forms).
287
//
288
// May be used on pointers. May also be used on member functions to indicate
289
// that 'this' is unaliased (e.g. "void C::m() RESTRICT { ... }").
290
// Must not be used on references - GCC supports that but VC doesn't.
291
//
292
// We call this "RESTRICT" to avoid conflicts with VC's __declspec(restrict),
293
// and because it's not really the same as C99's restrict.
294
//
295
// To be safe and satisfy the compilers' stated requirements: an object accessed
296
// by a restricted pointer must not be accessed by any other pointer within the
297
// lifetime of the restricted pointer, if the object is modified.
298
// To maximise the chance of optimisation, any pointers that could potentially
299
// alias with the restricted one should be marked as restricted too.
300
//
301
// It would probably be a good idea to write test cases for any code that uses
302
// this in an even very slightly unclear way, in case it causes obscure problems
303
// in a rare compiler due to differing semantics.
304
//
305
// .. GCC
306
#if GCC_VERSION
307
# define RESTRICT __restrict__
308
// .. VC8 provides __restrict
309
#elif MSC_VERSION
310
# define RESTRICT __restrict
311
// .. ICC supports the keyword 'restrict' when run with the /Qrestrict option,
312
// but it always also supports __restrict__ or __restrict to be compatible
313
// with GCC/MSVC, so we'll use the underscored version. One of {GCC,MSC}_VERSION
314
// should have been defined in addition to ICC_VERSION, so we should be using
315
// one of the above cases (unless it's an old VS7.1-emulating ICC).
316
#elif ICC_VERSION
317
# error ICC_VERSION defined without either GCC_VERSION or an adequate MSC_VERSION
318
// .. unsupported; remove it from code
319
#else
320
# define RESTRICT
321
#endif
322
323
324
//
325
// number of array elements
326
//
327
328
// (function taking a reference to an array and returning a pointer to
329
// an array of characters. it's only declared and never defined; we just
330
// need it to determine n, the size of the array that was passed.)
331
template
<
typename
T,
size_t
n> char (*
ArraySizeDeducer
(
T
(&)[n]))[n];
332
333
// (although requiring C++, this method is much better than the standard
334
// sizeof(name) / sizeof(name[0]) because it doesn't compile when a
335
// pointer is passed, which can easily happen under maintenance.)
336
#define ARRAY_SIZE(name) (sizeof(*ArraySizeDeducer(name)))
337
338
339
// C99-style __func__
340
// .. newer GCC already have it
341
#if GCC_VERSION
342
// nothing need be done
343
// .. MSVC have __FUNCTION__
344
#elif MSC_VERSION
345
# define __func__ __FUNCTION__
346
// .. unsupported
347
#else
348
# define __func__ "(unknown)"
349
#endif
350
351
352
// extern "C", but does the right thing in pure-C mode
353
#if defined(__cplusplus)
354
# define EXTERN_C extern "C"
355
#else
356
# define EXTERN_C extern
357
#endif
358
359
360
#if MSC_VERSION
361
# define INLINE __forceinline
362
#else
363
# define INLINE inline
364
#endif
365
366
367
#if MSC_VERSION
368
# define CALL_CONV __cdecl
369
#else
370
# define CALL_CONV
371
#endif
372
373
374
#if MSC_VERSION && !ARCH_AMD64
375
# define DECORATED_NAME(name) _##name
376
#else
377
# define DECORATED_NAME(name) name
378
#endif
379
380
381
// workaround for preprocessor limitation: macro args aren't expanded
382
// before being pasted.
383
#define STRINGIZE2(id) # id
384
#define STRINGIZE(id) STRINGIZE2(id)
385
386
// for widening non-literals (e.g. __FILE__)
387
// note: C99 says __func__ is a magic *variable*, and GCC doesn't allow
388
// widening it via preprocessor.
389
#define WIDEN2(x) L ## x
390
#define WIDEN(x) WIDEN2(x)
391
392
#endif // #ifndef INCLUDED_CODE_ANNOTATION
compiler.h
T
#define T(string_literal)
Definition:
secure_crt.cpp:76
ArraySizeDeducer
char(* ArraySizeDeducer(T(&)[n]))[n]
arch.h
Generated by
1.8.11