Next base/macros.h cleanup step.
[platform/upstream/v8.git] / src / base / macros.h
1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef V8_BASE_MACROS_H_
6 #define V8_BASE_MACROS_H_
7
8 #include "include/v8stdint.h"
9 #include "src/base/build_config.h"
10 #include "src/base/compiler-specific.h"
11 #include "src/base/logging.h"
12
13
14 // The expression OFFSET_OF(type, field) computes the byte-offset
15 // of the specified field relative to the containing type. This
16 // corresponds to 'offsetof' (in stddef.h), except that it doesn't
17 // use 0 or NULL, which causes a problem with the compiler warnings
18 // we have enabled (which is also why 'offsetof' doesn't seem to work).
19 // Here we simply use the non-zero value 4, which seems to work.
20 #define OFFSET_OF(type, field)                                          \
21   (reinterpret_cast<intptr_t>(&(reinterpret_cast<type*>(4)->field)) - 4)
22
23
24 // ARRAYSIZE_UNSAFE performs essentially the same calculation as arraysize,
25 // but can be used on anonymous types or types defined inside
26 // functions.  It's less safe than arraysize as it accepts some
27 // (although not all) pointers.  Therefore, you should use arraysize
28 // whenever possible.
29 //
30 // The expression ARRAYSIZE_UNSAFE(a) is a compile-time constant of type
31 // size_t.
32 //
33 // ARRAYSIZE_UNSAFE catches a few type errors.  If you see a compiler error
34 //
35 //   "warning: division by zero in ..."
36 //
37 // when using ARRAYSIZE_UNSAFE, you are (wrongfully) giving it a pointer.
38 // You should only use ARRAYSIZE_UNSAFE on statically allocated arrays.
39 //
40 // The following comments are on the implementation details, and can
41 // be ignored by the users.
42 //
43 // ARRAYSIZE_UNSAFE(arr) works by inspecting sizeof(arr) (the # of bytes in
44 // the array) and sizeof(*(arr)) (the # of bytes in one array
45 // element).  If the former is divisible by the latter, perhaps arr is
46 // indeed an array, in which case the division result is the # of
47 // elements in the array.  Otherwise, arr cannot possibly be an array,
48 // and we generate a compiler error to prevent the code from
49 // compiling.
50 //
51 // Since the size of bool is implementation-defined, we need to cast
52 // !(sizeof(a) & sizeof(*(a))) to size_t in order to ensure the final
53 // result has type size_t.
54 //
55 // This macro is not perfect as it wrongfully accepts certain
56 // pointers, namely where the pointer size is divisible by the pointee
57 // size.  Since all our code has to go through a 32-bit compiler,
58 // where a pointer is 4 bytes, this means all pointers to a type whose
59 // size is 3 or greater than 4 will be (righteously) rejected.
60 #define ARRAYSIZE_UNSAFE(a)     \
61   ((sizeof(a) / sizeof(*(a))) / \
62    static_cast<size_t>(!(sizeof(a) % sizeof(*(a)))))  // NOLINT
63
64
65 #if V8_OS_NACL
66
67 // TODO(bmeurer): For some reason, the NaCl toolchain cannot handle the correct
68 // definition of arraysize() below, so we have to use the unsafe version for
69 // now.
70 #define arraysize ARRAYSIZE_UNSAFE
71
72 #else  // V8_OS_NACL
73
74 // The arraysize(arr) macro returns the # of elements in an array arr.
75 // The expression is a compile-time constant, and therefore can be
76 // used in defining new arrays, for example.  If you use arraysize on
77 // a pointer by mistake, you will get a compile-time error.
78 //
79 // One caveat is that arraysize() doesn't accept any array of an
80 // anonymous type or a type defined inside a function.  In these rare
81 // cases, you have to use the unsafe ARRAYSIZE_UNSAFE() macro below.  This is
82 // due to a limitation in C++'s template system.  The limitation might
83 // eventually be removed, but it hasn't happened yet.
84 #define arraysize(array) (sizeof(ArraySizeHelper(array)))
85
86
87 // This template function declaration is used in defining arraysize.
88 // Note that the function doesn't need an implementation, as we only
89 // use its type.
90 template <typename T, size_t N>
91 char (&ArraySizeHelper(T (&array)[N]))[N];
92
93
94 #if !V8_CC_MSVC
95 // That gcc wants both of these prototypes seems mysterious. VC, for
96 // its part, can't decide which to use (another mystery). Matching of
97 // template overloads: the final frontier.
98 template <typename T, size_t N>
99 char (&ArraySizeHelper(const T (&array)[N]))[N];
100 #endif
101
102 #endif  // V8_OS_NACL
103
104
105 // A macro to disallow the evil copy constructor and operator= functions
106 // This should be used in the private: declarations for a class
107 #define DISALLOW_COPY_AND_ASSIGN(TypeName)  \
108   TypeName(const TypeName&) V8_DELETE;      \
109   void operator=(const TypeName&) V8_DELETE
110
111
112 // A macro to disallow all the implicit constructors, namely the
113 // default constructor, copy constructor and operator= functions.
114 //
115 // This should be used in the private: declarations for a class
116 // that wants to prevent anyone from instantiating it. This is
117 // especially useful for classes containing only static methods.
118 #define DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName)  \
119   TypeName() V8_DELETE;                           \
120   DISALLOW_COPY_AND_ASSIGN(TypeName)
121
122
123 // Newly written code should use V8_INLINE and V8_NOINLINE directly.
124 #define INLINE(declarator)    V8_INLINE declarator
125 #define NO_INLINE(declarator) V8_NOINLINE declarator
126
127
128 // Newly written code should use WARN_UNUSED_RESULT.
129 #define MUST_USE_RESULT WARN_UNUSED_RESULT
130
131
132 // Define V8_USE_ADDRESS_SANITIZER macros.
133 #if defined(__has_feature)
134 #if __has_feature(address_sanitizer)
135 #define V8_USE_ADDRESS_SANITIZER 1
136 #endif
137 #endif
138
139 // Define DISABLE_ASAN macros.
140 #ifdef V8_USE_ADDRESS_SANITIZER
141 #define DISABLE_ASAN __attribute__((no_sanitize_address))
142 #else
143 #define DISABLE_ASAN
144 #endif
145
146
147 #if V8_CC_GNU
148 #define V8_IMMEDIATE_CRASH() __builtin_trap()
149 #else
150 #define V8_IMMEDIATE_CRASH() ((void(*)())0)()
151 #endif
152
153
154 // Use C++11 static_assert if possible, which gives error
155 // messages that are easier to understand on first sight.
156 #if V8_HAS_CXX11_STATIC_ASSERT
157 #define STATIC_ASSERT(test) static_assert(test, #test)
158 #else
159 // This is inspired by the static assertion facility in boost.  This
160 // is pretty magical.  If it causes you trouble on a platform you may
161 // find a fix in the boost code.
162 template <bool> class StaticAssertion;
163 template <> class StaticAssertion<true> { };
164 // This macro joins two tokens.  If one of the tokens is a macro the
165 // helper call causes it to be resolved before joining.
166 #define SEMI_STATIC_JOIN(a, b) SEMI_STATIC_JOIN_HELPER(a, b)
167 #define SEMI_STATIC_JOIN_HELPER(a, b) a##b
168 // Causes an error during compilation of the condition is not
169 // statically known to be true.  It is formulated as a typedef so that
170 // it can be used wherever a typedef can be used.  Beware that this
171 // actually causes each use to introduce a new defined type with a
172 // name depending on the source line.
173 template <int> class StaticAssertionHelper { };
174 #define STATIC_ASSERT(test)                                                    \
175   typedef                                                                     \
176     StaticAssertionHelper<sizeof(StaticAssertion<static_cast<bool>((test))>)> \
177     SEMI_STATIC_JOIN(__StaticAssertTypedef__, __LINE__) ALLOW_UNUSED
178
179 #endif
180
181
182 // The USE(x) template is used to silence C++ compiler warnings
183 // issued for (yet) unused variables (typically parameters).
184 template <typename T>
185 inline void USE(T) { }
186
187
188 #define IS_POWER_OF_TWO(x) ((x) != 0 && (((x) & ((x) - 1)) == 0))
189
190
191 // Define our own macros for writing 64-bit constants.  This is less fragile
192 // than defining __STDC_CONSTANT_MACROS before including <stdint.h>, and it
193 // works on compilers that don't have it (like MSVC).
194 #if V8_CC_MSVC
195 # define V8_UINT64_C(x)   (x ## UI64)
196 # define V8_INT64_C(x)    (x ## I64)
197 # if V8_HOST_ARCH_64_BIT
198 #  define V8_INTPTR_C(x)  (x ## I64)
199 #  define V8_PTR_PREFIX   "ll"
200 # else
201 #  define V8_INTPTR_C(x)  (x)
202 #  define V8_PTR_PREFIX   ""
203 # endif  // V8_HOST_ARCH_64_BIT
204 #elif V8_CC_MINGW64
205 # define V8_UINT64_C(x)   (x ## ULL)
206 # define V8_INT64_C(x)    (x ## LL)
207 # define V8_INTPTR_C(x)   (x ## LL)
208 # define V8_PTR_PREFIX    "I64"
209 #elif V8_HOST_ARCH_64_BIT
210 # if V8_OS_MACOSX
211 #  define V8_UINT64_C(x)   (x ## ULL)
212 #  define V8_INT64_C(x)    (x ## LL)
213 # else
214 #  define V8_UINT64_C(x)   (x ## UL)
215 #  define V8_INT64_C(x)    (x ## L)
216 # endif
217 # define V8_INTPTR_C(x)   (x ## L)
218 # define V8_PTR_PREFIX    "l"
219 #else
220 # define V8_UINT64_C(x)   (x ## ULL)
221 # define V8_INT64_C(x)    (x ## LL)
222 # define V8_INTPTR_C(x)   (x)
223 # define V8_PTR_PREFIX    ""
224 #endif
225
226 #define V8PRIxPTR V8_PTR_PREFIX "x"
227 #define V8PRIdPTR V8_PTR_PREFIX "d"
228 #define V8PRIuPTR V8_PTR_PREFIX "u"
229
230 // Fix for Mac OS X defining uintptr_t as "unsigned long":
231 #if V8_OS_MACOSX
232 #undef V8PRIxPTR
233 #define V8PRIxPTR "lx"
234 #endif
235
236 // The following macro works on both 32 and 64-bit platforms.
237 // Usage: instead of writing 0x1234567890123456
238 //      write V8_2PART_UINT64_C(0x12345678,90123456);
239 #define V8_2PART_UINT64_C(a, b) (((static_cast<uint64_t>(a) << 32) + 0x##b##u))
240
241
242 // Compute the 0-relative offset of some absolute value x of type T.
243 // This allows conversion of Addresses and integral types into
244 // 0-relative int offsets.
245 template <typename T>
246 inline intptr_t OffsetFrom(T x) {
247   return x - static_cast<T>(0);
248 }
249
250
251 // Compute the absolute value of type T for some 0-relative offset x.
252 // This allows conversion of 0-relative int offsets into Addresses and
253 // integral types.
254 template <typename T>
255 inline T AddressFrom(intptr_t x) {
256   return static_cast<T>(static_cast<T>(0) + x);
257 }
258
259
260 // Return the largest multiple of m which is <= x.
261 template <typename T>
262 inline T RoundDown(T x, intptr_t m) {
263   DCHECK(IS_POWER_OF_TWO(m));
264   return AddressFrom<T>(OffsetFrom(x) & -m);
265 }
266
267
268 // Return the smallest multiple of m which is >= x.
269 template <typename T>
270 inline T RoundUp(T x, intptr_t m) {
271   return RoundDown<T>(static_cast<T>(x + m - 1), m);
272 }
273
274 #endif   // V8_BASE_MACROS_H_