1/*
2 * Copyright (C) 2011, 2012, 2014 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#ifndef WTF_Compiler_h
27#define WTF_Compiler_h
28
29/* COMPILER() - the compiler being used to build the project */
30#define COMPILER(WTF_FEATURE) (defined WTF_COMPILER_##WTF_FEATURE && WTF_COMPILER_##WTF_FEATURE)
31
32/* COMPILER_SUPPORTS() - whether the compiler being used to build the project supports the given feature. */
33#define COMPILER_SUPPORTS(WTF_COMPILER_FEATURE) (defined WTF_COMPILER_SUPPORTS_##WTF_COMPILER_FEATURE && WTF_COMPILER_SUPPORTS_##WTF_COMPILER_FEATURE)
34
35/* COMPILER_QUIRK() - whether the compiler being used to build the project requires a given quirk. */
36#define COMPILER_QUIRK(WTF_COMPILER_QUIRK) (defined WTF_COMPILER_QUIRK_##WTF_COMPILER_QUIRK && WTF_COMPILER_QUIRK_##WTF_COMPILER_QUIRK)
37
38/* COMPILER_HAS_CLANG_BUILTIN() - wether the compiler supports a particular clang builtin. */
39#ifdef __has_builtin
40#define COMPILER_HAS_CLANG_BUILTIN(x) __has_builtin(x)
41#else
42#define COMPILER_HAS_CLANG_BUILTIN(x) 0
43#endif
44
45/* ==== COMPILER() - primary detection of the compiler being used to build the project, in alphabetical order ==== */
46
47/* COMPILER(CLANG) - Clang */
48
49#if defined(__clang__)
50#define WTF_COMPILER_CLANG 1
51#define WTF_COMPILER_SUPPORTS_BLOCKS __has_feature(blocks)
52#define WTF_COMPILER_SUPPORTS_C_STATIC_ASSERT __has_feature(c_static_assert)
53#define WTF_COMPILER_SUPPORTS_CXX_REFERENCE_QUALIFIED_FUNCTIONS __has_feature(cxx_reference_qualified_functions)
54#define WTF_COMPILER_SUPPORTS_CXX_USER_LITERALS __has_feature(cxx_user_literals)
55#endif
56
57/* COMPILER(GCC_OR_CLANG) - GNU Compiler Collection or Clang */
58#if defined(__GNUC__)
59#define WTF_COMPILER_GCC_OR_CLANG 1
60#endif
61
62/* COMPILER(GCC) - GNU Compiler Collection */
63/* Note: This section must come after the Clang section since we check !COMPILER(CLANG) here. */
64#if COMPILER(GCC_OR_CLANG) && !COMPILER(CLANG)
65#define WTF_COMPILER_GCC 1
66#define WTF_COMPILER_SUPPORTS_CXX_USER_LITERALS 1
67#define WTF_COMPILER_SUPPORTS_CXX_REFERENCE_QUALIFIED_FUNCTIONS 1
68
69#define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
70#define GCC_VERSION_AT_LEAST(major, minor, patch) (GCC_VERSION >= (major * 10000 + minor * 100 + patch))
71
72#if !GCC_VERSION_AT_LEAST(4, 8, 0)
73#error "Please use a newer version of GCC. WebKit requires GCC 4.8.0 or newer to compile."
74#endif
75
76#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
77#define WTF_COMPILER_SUPPORTS_C_STATIC_ASSERT 1
78#endif
79
80#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
81
82#endif /* COMPILER(GCC) */
83
84/* COMPILER(MINGW) - MinGW GCC */
85
86#if defined(__MINGW32__)
87#define WTF_COMPILER_MINGW 1
88#include <_mingw.h>
89#endif
90
91/* COMPILER(MINGW64) - mingw-w64 GCC - used as additional check to exclude mingw.org specific functions */
92
93/* Note: This section must come after the MinGW section since we check COMPILER(MINGW) here. */
94
95#if COMPILER(MINGW) && defined(__MINGW64_VERSION_MAJOR) /* best way to check for mingw-w64 vs mingw.org */
96#define WTF_COMPILER_MINGW64 1
97#endif
98
99/* COMPILER(MSVC) - Microsoft Visual C++ */
100
101#if defined(_MSC_VER)
102
103#define WTF_COMPILER_MSVC 1
104#define WTF_COMPILER_SUPPORTS_CXX_REFERENCE_QUALIFIED_FUNCTIONS 1
105#define WTF_COMPILER_SUPPORTS_CXX_USER_LITERALS 1
106
107#if _MSC_VER < 1900
108#error "Please use a newer version of Visual Studio. WebKit requires VS2015 or newer to compile."
109#endif
110
111#endif
112
113/* COMPILER(SUNCC) */
114
115#if defined(__SUNPRO_CC) || defined(__SUNPRO_C)
116#define WTF_COMPILER_SUNCC 1
117#endif
118
119#if !COMPILER(CLANG) && !COMPILER(MSVC)
120#define WTF_COMPILER_QUIRK_CONSIDERS_UNREACHABLE_CODE 1
121#endif
122
123/* ==== COMPILER_SUPPORTS - additional compiler feature detection, in alphabetical order ==== */
124
125/* COMPILER_SUPPORTS(EABI) */
126
127#if defined(__ARM_EABI__) || defined(__EABI__)
128#define WTF_COMPILER_SUPPORTS_EABI 1
129#endif
130
131#if defined(__has_feature)
132#define ASAN_ENABLED __has_feature(address_sanitizer)
133#else
134#define ASAN_ENABLED 0
135#endif
136
137#if ASAN_ENABLED
138#define SUPPRESS_ASAN __attribute__((no_sanitize_address))
139#else
140#define SUPPRESS_ASAN
141#endif
142
143/* ==== Compiler-independent macros for various compiler features, in alphabetical order ==== */
144
145/* ALWAYS_INLINE */
146
147#if !defined(ALWAYS_INLINE) && COMPILER(GCC_OR_CLANG) && defined(NDEBUG) && !COMPILER(MINGW)
148#define ALWAYS_INLINE inline __attribute__((__always_inline__))
149#endif
150
151#if !defined(ALWAYS_INLINE) && COMPILER(MSVC) && defined(NDEBUG)
152#define ALWAYS_INLINE __forceinline
153#endif
154
155#if !defined(ALWAYS_INLINE)
156#define ALWAYS_INLINE inline
157#endif
158
159/* WTF_EXTERN_C_{BEGIN, END} */
160
161#ifdef __cplusplus
162#define WTF_EXTERN_C_BEGIN extern "C" {
163#define WTF_EXTERN_C_END }
164#else
165#define WTF_EXTERN_C_BEGIN
166#define WTF_EXTERN_C_END
167#endif
168
169/* FIXME: Remove this once we have transitioned to WTF_EXTERN_C_BEGIN/WTF_EXTERN_C_END. */
170#ifdef __cplusplus
171#define EXTERN_C extern "C"
172#else
173#define EXTERN_C extern
174#endif
175
176/* FALLTHROUGH */
177
178#if !defined(FALLTHROUGH) && defined(__cplusplus) && defined(__has_cpp_attribute)
179
180#if __has_cpp_attribute(fallthrough)
181#define FALLTHROUGH [[fallthrough]]
182#elif __has_cpp_attribute(clang::fallthrough)
183#define FALLTHROUGH [[clang::fallthrough]]
184#elif __has_cpp_attribute(gnu::fallthrough)
185#define FALLTHROUGH [[gnu::fallthrough]]
186#endif
187
188#endif // !defined(FALLTHROUGH) && defined(__cplusplus) && defined(__has_cpp_attribute)
189
190#if !defined(FALLTHROUGH)
191#define FALLTHROUGH
192#endif
193
194/* LIKELY */
195
196#if !defined(LIKELY) && COMPILER(GCC_OR_CLANG)
197#define LIKELY(x) __builtin_expect(!!(x), 1)
198#endif
199
200#if !defined(LIKELY)
201#define LIKELY(x) (x)
202#endif
203
204/* NEVER_INLINE */
205
206#if !defined(NEVER_INLINE) && COMPILER(GCC_OR_CLANG)
207#define NEVER_INLINE __attribute__((__noinline__))
208#endif
209
210#if !defined(NEVER_INLINE) && COMPILER(MSVC)
211#define NEVER_INLINE __declspec(noinline)
212#endif
213
214#if !defined(NEVER_INLINE)
215#define NEVER_INLINE
216#endif
217
218/* NO_RETURN */
219
220#if !defined(NO_RETURN) && COMPILER(GCC_OR_CLANG)
221#define NO_RETURN __attribute((__noreturn__))
222#endif
223
224#if !defined(NO_RETURN) && COMPILER(MSVC)
225#define NO_RETURN __declspec(noreturn)
226#endif
227
228#if !defined(NO_RETURN)
229#define NO_RETURN
230#endif
231
232/* NO_RETURN_WITH_VALUE */
233
234#if !defined(NO_RETURN_WITH_VALUE) && !COMPILER(MSVC)
235#define NO_RETURN_WITH_VALUE NO_RETURN
236#endif
237
238#if !defined(NO_RETURN_WITH_VALUE)
239#define NO_RETURN_WITH_VALUE
240#endif
241
242/* OBJC_CLASS */
243
244#if !defined(OBJC_CLASS) && defined(__OBJC__)
245#define OBJC_CLASS @class
246#endif
247
248#if !defined(OBJC_CLASS)
249#define OBJC_CLASS class
250#endif
251
252/* PURE_FUNCTION */
253
254#if !defined(PURE_FUNCTION) && COMPILER(GCC_OR_CLANG)
255#define PURE_FUNCTION __attribute__((__pure__))
256#endif
257
258#if !defined(PURE_FUNCTION)
259#define PURE_FUNCTION
260#endif
261
262/* REFERENCED_FROM_ASM */
263
264#if !defined(REFERENCED_FROM_ASM) && COMPILER(GCC_OR_CLANG)
265#define REFERENCED_FROM_ASM __attribute__((__used__))
266#endif
267
268#if !defined(REFERENCED_FROM_ASM)
269#define REFERENCED_FROM_ASM
270#endif
271
272/* UNLIKELY */
273
274#if !defined(UNLIKELY) && COMPILER(GCC_OR_CLANG)
275#define UNLIKELY(x) __builtin_expect(!!(x), 0)
276#endif
277
278#if !defined(UNLIKELY)
279#define UNLIKELY(x) (x)
280#endif
281
282/* UNUSED_LABEL */
283
284/* Keep the compiler from complaining for a local label that is defined but not referenced. */
285/* Helpful when mixing hand-written and autogenerated code. */
286
287#if !defined(UNUSED_LABEL) && COMPILER(MSVC)
288#define UNUSED_LABEL(label) if (false) goto label
289#endif
290
291#if !defined(UNUSED_LABEL)
292#define UNUSED_LABEL(label) UNUSED_PARAM(&& label)
293#endif
294
295/* UNUSED_PARAM */
296
297#if !defined(UNUSED_PARAM) && COMPILER(MSVC)
298#define UNUSED_PARAM(variable) (void)&variable
299#endif
300
301#if !defined(UNUSED_PARAM)
302#define UNUSED_PARAM(variable) (void)variable
303#endif
304
305/* WARN_UNUSED_RETURN */
306
307#if !defined(WARN_UNUSED_RETURN) && COMPILER(GCC_OR_CLANG)
308#define WARN_UNUSED_RETURN __attribute__((__warn_unused_result__))
309#endif
310
311#if !defined(WARN_UNUSED_RETURN)
312#define WARN_UNUSED_RETURN
313#endif
314
315#if !defined(__has_include) && COMPILER(MSVC)
316#define __has_include(path) 0
317#endif
318
319#endif /* WTF_Compiler_h */
320