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 65 // MSVC 66 #elif defined(_MSC_VER) 67 # define DAWN_COMPILER_MSVC 68 69 extern void __cdecl __debugbreak(void); 70 # define DAWN_BREAKPOINT() __debugbreak() 71 72 # define DAWN_BUILTIN_UNREACHABLE() __assume(false) 73 74 // Visual Studio 2017 15.3 adds support for [[nodiscard]] 75 # if _MSC_VER >= 1911 && DAWN_CPP_VERSION >= 17 76 # define DAWN_NO_DISCARD [[nodiscard]] 77 # endif 78 79 # define DAWN_DECLARE_UNUSED 80 81 #else 82 # error "Unsupported compiler" 83 #endif 84 85 // It seems that (void) EXPR works on all compilers to silence the unused variable warning. 86 #define DAWN_UNUSED(EXPR) (void)EXPR 87 // Likewise using static asserting on sizeof(&FUNC) seems to make it tagged as used 88 #define DAWN_UNUSED_FUNC(FUNC) static_assert(sizeof(&FUNC) == sizeof(void (*)()), "") 89 90 // Add noop replacements for macros for features that aren't supported by the compiler. 91 #if !defined(DAWN_LIKELY) 92 # define DAWN_LIKELY(X) X 93 #endif 94 #if !defined(DAWN_UNLIKELY) 95 # define DAWN_UNLIKELY(X) X 96 #endif 97 #if !defined(DAWN_NO_DISCARD) 98 # define DAWN_NO_DISCARD 99 #endif 100 101 #endif // COMMON_COMPILER_H_ 102