1 | // Copyright (c) 2012 The Chromium 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 BUTIL_COMPILER_SPECIFIC_H_ |
6 | #define BUTIL_COMPILER_SPECIFIC_H_ |
7 | |
8 | #include "butil/build_config.h" |
9 | |
10 | #if defined(COMPILER_MSVC) |
11 | |
12 | // Macros for suppressing and disabling warnings on MSVC. |
13 | // |
14 | // Warning numbers are enumerated at: |
15 | // http://msdn.microsoft.com/en-us/library/8x5x43k7(VS.80).aspx |
16 | // |
17 | // The warning pragma: |
18 | // http://msdn.microsoft.com/en-us/library/2c8f766e(VS.80).aspx |
19 | // |
20 | // Using __pragma instead of #pragma inside macros: |
21 | // http://msdn.microsoft.com/en-us/library/d9x1s805.aspx |
22 | |
23 | // MSVC_SUPPRESS_WARNING disables warning |n| for the remainder of the line and |
24 | // for the next line of the source file. |
25 | #define MSVC_SUPPRESS_WARNING(n) __pragma(warning(suppress:n)) |
26 | |
27 | // MSVC_PUSH_DISABLE_WARNING pushes |n| onto a stack of warnings to be disabled. |
28 | // The warning remains disabled until popped by MSVC_POP_WARNING. |
29 | #define MSVC_PUSH_DISABLE_WARNING(n) __pragma(warning(push)) \ |
30 | __pragma(warning(disable:n)) |
31 | |
32 | // MSVC_PUSH_WARNING_LEVEL pushes |n| as the global warning level. The level |
33 | // remains in effect until popped by MSVC_POP_WARNING(). Use 0 to disable all |
34 | // warnings. |
35 | #define MSVC_PUSH_WARNING_LEVEL(n) __pragma(warning(push, n)) |
36 | |
37 | // Pop effects of innermost MSVC_PUSH_* macro. |
38 | #define MSVC_POP_WARNING() __pragma(warning(pop)) |
39 | |
40 | #define MSVC_DISABLE_OPTIMIZE() __pragma(optimize("", off)) |
41 | #define MSVC_ENABLE_OPTIMIZE() __pragma(optimize("", on)) |
42 | |
43 | // Allows exporting a class that inherits from a non-exported base class. |
44 | // This uses suppress instead of push/pop because the delimiter after the |
45 | // declaration (either "," or "{") has to be placed before the pop macro. |
46 | // |
47 | // Example usage: |
48 | // class EXPORT_API Foo : NON_EXPORTED_BASE(public Bar) { |
49 | // |
50 | // MSVC Compiler warning C4275: |
51 | // non dll-interface class 'Bar' used as base for dll-interface class 'Foo'. |
52 | // Note that this is intended to be used only when no access to the base class' |
53 | // static data is done through derived classes or inline methods. For more info, |
54 | // see http://msdn.microsoft.com/en-us/library/3tdb471s(VS.80).aspx |
55 | #define NON_EXPORTED_BASE(code) MSVC_SUPPRESS_WARNING(4275) \ |
56 | code |
57 | |
58 | #else // Not MSVC |
59 | |
60 | #define MSVC_SUPPRESS_WARNING(n) |
61 | #define MSVC_PUSH_DISABLE_WARNING(n) |
62 | #define MSVC_PUSH_WARNING_LEVEL(n) |
63 | #define MSVC_POP_WARNING() |
64 | #define MSVC_DISABLE_OPTIMIZE() |
65 | #define MSVC_ENABLE_OPTIMIZE() |
66 | #define NON_EXPORTED_BASE(code) code |
67 | |
68 | #endif // COMPILER_MSVC |
69 | |
70 | |
71 | // The C++ standard requires that static const members have an out-of-class |
72 | // definition (in a single compilation unit), but MSVC chokes on this (when |
73 | // language extensions, which are required, are enabled). (You're only likely to |
74 | // notice the need for a definition if you take the address of the member or, |
75 | // more commonly, pass it to a function that takes it as a reference argument -- |
76 | // probably an STL function.) This macro makes MSVC do the right thing. See |
77 | // http://msdn.microsoft.com/en-us/library/34h23df8(v=vs.100).aspx for more |
78 | // information. Use like: |
79 | // |
80 | // In .h file: |
81 | // struct Foo { |
82 | // static const int kBar = 5; |
83 | // }; |
84 | // |
85 | // In .cc file: |
86 | // STATIC_CONST_MEMBER_DEFINITION const int Foo::kBar; |
87 | #if defined(COMPILER_MSVC) |
88 | #define STATIC_CONST_MEMBER_DEFINITION __declspec(selectany) |
89 | #else |
90 | #define STATIC_CONST_MEMBER_DEFINITION |
91 | #endif |
92 | |
93 | // Annotate a variable indicating it's ok if the variable is not used. |
94 | // (Typically used to silence a compiler warning when the assignment |
95 | // is important for some other reason.) |
96 | // Use like: |
97 | // int x ALLOW_UNUSED = ...; |
98 | #if defined(COMPILER_GCC) |
99 | #define ALLOW_UNUSED __attribute__((unused)) |
100 | #else |
101 | #define ALLOW_UNUSED |
102 | #endif |
103 | |
104 | // Annotate a function indicating it should not be inlined. |
105 | // Use like: |
106 | // NOINLINE void DoStuff() { ... } |
107 | #if defined(COMPILER_GCC) |
108 | #define NOINLINE __attribute__((noinline)) |
109 | #elif defined(COMPILER_MSVC) |
110 | #define NOINLINE __declspec(noinline) |
111 | #else |
112 | #define NOINLINE |
113 | #endif |
114 | |
115 | #ifndef BUTIL_FORCE_INLINE |
116 | #if defined(COMPILER_MSVC) |
117 | #define BUTIL_FORCE_INLINE __forceinline |
118 | #else |
119 | #define BUTIL_FORCE_INLINE inline __attribute__((always_inline)) |
120 | #endif |
121 | #endif // BUTIL_FORCE_INLINE |
122 | |
123 | // Specify memory alignment for structs, classes, etc. |
124 | // Use like: |
125 | // class ALIGNAS(16) MyClass { ... } |
126 | // ALIGNAS(16) int array[4]; |
127 | #if defined(COMPILER_MSVC) |
128 | #define ALIGNAS(byte_alignment) __declspec(align(byte_alignment)) |
129 | #elif defined(COMPILER_GCC) |
130 | #define ALIGNAS(byte_alignment) __attribute__((aligned(byte_alignment))) |
131 | #endif |
132 | |
133 | // Return the byte alignment of the given type (available at compile time). Use |
134 | // sizeof(type) prior to checking __alignof to workaround Visual C++ bug: |
135 | // http://goo.gl/isH0C |
136 | // Use like: |
137 | // ALIGNOF(int32_t) // this would be 4 |
138 | #if defined(COMPILER_MSVC) |
139 | #define ALIGNOF(type) (sizeof(type) - sizeof(type) + __alignof(type)) |
140 | #elif defined(COMPILER_GCC) |
141 | #define ALIGNOF(type) __alignof__(type) |
142 | #endif |
143 | |
144 | // Annotate a virtual method indicating it must be overriding a virtual |
145 | // method in the parent class. |
146 | // Use like: |
147 | // virtual void foo() OVERRIDE; |
148 | #if defined(__clang__) || defined(COMPILER_MSVC) |
149 | #define OVERRIDE override |
150 | #elif defined(COMPILER_GCC) && __cplusplus >= 201103 && \ |
151 | (__GNUC__ * 10000 + __GNUC_MINOR__ * 100) >= 40700 |
152 | // GCC 4.7 supports explicit virtual overrides when C++11 support is enabled. |
153 | #define OVERRIDE override |
154 | #else |
155 | #define OVERRIDE |
156 | #endif |
157 | |
158 | // Annotate a virtual method indicating that subclasses must not override it, |
159 | // or annotate a class to indicate that it cannot be subclassed. |
160 | // Use like: |
161 | // virtual void foo() FINAL; |
162 | // class B FINAL : public A {}; |
163 | #if defined(__clang__) || defined(COMPILER_MSVC) |
164 | #define FINAL final |
165 | #elif defined(COMPILER_GCC) && __cplusplus >= 201103 && \ |
166 | (__GNUC__ * 10000 + __GNUC_MINOR__ * 100) >= 40700 |
167 | // GCC 4.7 supports explicit virtual overrides when C++11 support is enabled. |
168 | #define FINAL final |
169 | #else |
170 | #define FINAL |
171 | #endif |
172 | |
173 | // Annotate a function indicating the caller must examine the return value. |
174 | // Use like: |
175 | // int foo() WARN_UNUSED_RESULT; |
176 | // To explicitly ignore a result, see |ignore_result()| in "butil/basictypes.h". |
177 | // FIXME(gejun): GCC 3.4 report "unused" variable incorrectly (actually used). |
178 | #if defined(COMPILER_GCC) && __cplusplus >= 201103 && \ |
179 | (__GNUC__ * 10000 + __GNUC_MINOR__ * 100) >= 40700 |
180 | #define WARN_UNUSED_RESULT __attribute__((warn_unused_result)) |
181 | #else |
182 | #define WARN_UNUSED_RESULT |
183 | #endif |
184 | |
185 | // Tell the compiler a function is using a printf-style format string. |
186 | // |format_param| is the one-based index of the format string parameter; |
187 | // |dots_param| is the one-based index of the "..." parameter. |
188 | // For v*printf functions (which take a va_list), pass 0 for dots_param. |
189 | // (This is undocumented but matches what the system C headers do.) |
190 | #if defined(COMPILER_GCC) |
191 | #define PRINTF_FORMAT(format_param, dots_param) \ |
192 | __attribute__((format(printf, format_param, dots_param))) |
193 | #else |
194 | #define PRINTF_FORMAT(format_param, dots_param) |
195 | #endif |
196 | |
197 | // WPRINTF_FORMAT is the same, but for wide format strings. |
198 | // This doesn't appear to yet be implemented in any compiler. |
199 | // See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38308 . |
200 | #define WPRINTF_FORMAT(format_param, dots_param) |
201 | // If available, it would look like: |
202 | // __attribute__((format(wprintf, format_param, dots_param))) |
203 | |
204 | // MemorySanitizer annotations. |
205 | #if defined(MEMORY_SANITIZER) && !defined(OS_NACL) |
206 | #include <sanitizer/msan_interface.h> |
207 | |
208 | // Mark a memory region fully initialized. |
209 | // Use this to annotate code that deliberately reads uninitialized data, for |
210 | // example a GC scavenging root set pointers from the stack. |
211 | #define MSAN_UNPOISON(p, s) __msan_unpoison(p, s) |
212 | #else // MEMORY_SANITIZER |
213 | #define MSAN_UNPOISON(p, s) |
214 | #endif // MEMORY_SANITIZER |
215 | |
216 | // Macro useful for writing cross-platform function pointers. |
217 | #if !defined(CDECL) |
218 | #if defined(OS_WIN) |
219 | #define CDECL __cdecl |
220 | #else // defined(OS_WIN) |
221 | #define CDECL |
222 | #endif // defined(OS_WIN) |
223 | #endif // !defined(CDECL) |
224 | |
225 | // Mark a branch likely or unlikely to be true. |
226 | // We can't remove the BAIDU_ prefix because the name is likely to conflict, |
227 | // namely kylin already has the macro. |
228 | #if defined(COMPILER_GCC) |
229 | # if defined(__cplusplus) |
230 | # define BAIDU_LIKELY(expr) (__builtin_expect((bool)(expr), true)) |
231 | # define BAIDU_UNLIKELY(expr) (__builtin_expect((bool)(expr), false)) |
232 | # else |
233 | # define BAIDU_LIKELY(expr) (__builtin_expect(!!(expr), 1)) |
234 | # define BAIDU_UNLIKELY(expr) (__builtin_expect(!!(expr), 0)) |
235 | # endif |
236 | #else |
237 | # define BAIDU_LIKELY(expr) (expr) |
238 | # define BAIDU_UNLIKELY(expr) (expr) |
239 | #endif |
240 | |
241 | // BAIDU_DEPRECATED void dont_call_me_anymore(int arg); |
242 | // ... |
243 | // warning: 'void dont_call_me_anymore(int)' is deprecated |
244 | #if defined(COMPILER_GCC) |
245 | # define BAIDU_DEPRECATED __attribute__((deprecated)) |
246 | #elif defined(COMPILER_MSVC) |
247 | # define BAIDU_DEPRECATED __declspec(deprecated) |
248 | #else |
249 | # define BAIDU_DEPRECATED |
250 | #endif |
251 | |
252 | // Mark function as weak. This is GCC only feature. |
253 | #if defined(COMPILER_GCC) |
254 | # define BAIDU_WEAK __attribute__((weak)) |
255 | #else |
256 | # define BAIDU_WEAK |
257 | #endif |
258 | |
259 | // Cacheline related -------------------------------------- |
260 | #define BAIDU_CACHELINE_SIZE 64 |
261 | |
262 | #ifdef _MSC_VER |
263 | # define BAIDU_CACHELINE_ALIGNMENT __declspec(align(BAIDU_CACHELINE_SIZE)) |
264 | #endif /* _MSC_VER */ |
265 | |
266 | #ifdef __GNUC__ |
267 | # define BAIDU_CACHELINE_ALIGNMENT __attribute__((aligned(BAIDU_CACHELINE_SIZE))) |
268 | #endif /* __GNUC__ */ |
269 | |
270 | #ifndef BAIDU_CACHELINE_ALIGNMENT |
271 | # define BAIDU_CACHELINE_ALIGNMENT /*BAIDU_CACHELINE_ALIGNMENT*/ |
272 | #endif |
273 | |
274 | #ifndef BAIDU_NOEXCEPT |
275 | # if defined(BUTIL_CXX11_ENABLED) |
276 | # define BAIDU_NOEXCEPT noexcept |
277 | # else |
278 | # define BAIDU_NOEXCEPT |
279 | # endif |
280 | #endif |
281 | |
282 | #endif // BUTIL_COMPILER_SPECIFIC_H_ |
283 | |