• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2017 The Dawn Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef COMMON_COMPILER_H_
16 #define COMMON_COMPILER_H_
17 
18 // Defines macros for compiler-specific functionality
19 //  - DAWN_COMPILER_[CLANG|GCC|MSVC]: Compiler detection
20 //  - DAWN_BREAKPOINT(): Raises an exception and breaks in the debugger
21 //  - DAWN_BUILTIN_UNREACHABLE(): Hints the compiler that a code path is unreachable
22 //  - DAWN_NO_DISCARD: An attribute that is C++17 [[nodiscard]] where available
23 //  - DAWN_(UN)?LIKELY(EXPR): Where available, hints the compiler that the expression will be true
24 //      (resp. false) to help it generate code that leads to better branch prediction.
25 //  - DAWN_UNUSED(EXPR): Prevents unused variable/expression warnings on EXPR.
26 //  - DAWN_UNUSED_FUNC(FUNC): Prevents unused function warnings on FUNC.
27 //  - DAWN_DECLARE_UNUSED:    Prevents unused function warnings a subsequent declaration.
28 //  Both DAWN_UNUSED_FUNC and DAWN_DECLARE_UNUSED may be necessary, e.g. to suppress clang's
29 //  unneeded-internal-declaration warning.
30 
31 // Clang and GCC, check for __clang__ too to catch clang-cl masquarading as MSVC
32 #if defined(__GNUC__) || defined(__clang__)
33 #    if defined(__clang__)
34 #        define DAWN_COMPILER_CLANG
35 #    else
36 #        define DAWN_COMPILER_GCC
37 #    endif
38 
39 #    if defined(__i386__) || defined(__x86_64__)
40 #        define DAWN_BREAKPOINT() __asm__ __volatile__("int $3\n\t")
41 #    else
42 // TODO(cwallez@chromium.org): Implement breakpoint on all supported architectures
43 #        define DAWN_BREAKPOINT()
44 #    endif
45 
46 #    define DAWN_BUILTIN_UNREACHABLE() __builtin_unreachable()
47 #    define DAWN_LIKELY(x) __builtin_expect(!!(x), 1)
48 #    define DAWN_UNLIKELY(x) __builtin_expect(!!(x), 0)
49 
50 #    if !defined(__has_cpp_attribute)
51 #        define __has_cpp_attribute(name) 0
52 #    endif
53 
54 // Use warn_unused_result on clang otherwise we can a c++1z extension warning in C++14 mode
55 // Also avoid warn_unused_result with GCC because it is only a function attribute and not a type
56 // attribute.
57 #    if __has_cpp_attribute(warn_unused_result) && defined(__clang__)
58 #        define DAWN_NO_DISCARD __attribute__((warn_unused_result))
59 #    elif DAWN_CPP_VERSION >= 17 && __has_cpp_attribute(nodiscard)
60 #        define DAWN_NO_DISCARD [[nodiscard]]
61 #    endif
62 
63 #    define DAWN_DECLARE_UNUSED __attribute__((unused))
64 #    if defined(NDEBUG)
65 #        define DAWN_FORCE_INLINE inline __attribute__((always_inline))
66 #    endif
67 #    define DAWN_NOINLINE __attribute__((noinline))
68 
69 // MSVC
70 #elif defined(_MSC_VER)
71 #    define DAWN_COMPILER_MSVC
72 
73 extern void __cdecl __debugbreak(void);
74 #    define DAWN_BREAKPOINT() __debugbreak()
75 
76 #    define DAWN_BUILTIN_UNREACHABLE() __assume(false)
77 
78 // Visual Studio 2017 15.3 adds support for [[nodiscard]]
79 #    if _MSC_VER >= 1911 && DAWN_CPP_VERSION >= 17
80 #        define DAWN_NO_DISCARD [[nodiscard]]
81 #    endif
82 
83 #    define DAWN_DECLARE_UNUSED
84 #    if defined(NDEBUG)
85 #        define DAWN_FORCE_INLINE __forceinline
86 #    endif
87 #    define DAWN_NOINLINE __declspec(noinline)
88 
89 #else
90 #    error "Unsupported compiler"
91 #endif
92 
93 // It seems that (void) EXPR works on all compilers to silence the unused variable warning.
94 #define DAWN_UNUSED(EXPR) (void)EXPR
95 // Likewise using static asserting on sizeof(&FUNC) seems to make it tagged as used
96 #define DAWN_UNUSED_FUNC(FUNC) static_assert(sizeof(&FUNC) == sizeof(void (*)()), "")
97 
98 // Add noop replacements for macros for features that aren't supported by the compiler.
99 #if !defined(DAWN_LIKELY)
100 #    define DAWN_LIKELY(X) X
101 #endif
102 #if !defined(DAWN_UNLIKELY)
103 #    define DAWN_UNLIKELY(X) X
104 #endif
105 #if !defined(DAWN_NO_DISCARD)
106 #    define DAWN_NO_DISCARD
107 #endif
108 #if !defined(DAWN_FORCE_INLINE)
109 #    define DAWN_FORCE_INLINE inline
110 #endif
111 #if !defined(DAWN_NOINLINE)
112 #    define DAWN_NOINLINE
113 #endif
114 
115 #if defined(__clang__)
116 #    define DAWN_FALLTHROUGH [[clang::fallthrough]]
117 #else
118 #    define DAWN_FALLTHROUGH
119 #endif
120 
121 #endif  // COMMON_COMPILER_H_
122