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_ASSERT_H_ 16 #define COMMON_ASSERT_H_ 17 18 #include "common/Compiler.h" 19 20 // Dawn asserts to be used instead of the regular C stdlib assert function (if you don't use assert 21 // yet, you should start now!). In debug ASSERT(condition) will trigger an error, otherwise in 22 // release it does nothing at runtime. 23 // 24 // In case of name clashes (with for example a testing library), you can define the 25 // DAWN_SKIP_ASSERT_SHORTHANDS to only define the DAWN_ prefixed macros. 26 // 27 // These asserts feature: 28 // - Logging of the error with file, line and function information. 29 // - Breaking in the debugger when an assert is triggered and a debugger is attached. 30 // - Use the assert information to help the compiler optimizer in release builds. 31 32 // MSVC triggers a warning in /W4 for do {} while(0). SDL worked around this by using (0,0) and 33 // points out that it looks like an owl face. 34 #if defined(DAWN_COMPILER_MSVC) 35 # define DAWN_ASSERT_LOOP_CONDITION (0, 0) 36 #else 37 # define DAWN_ASSERT_LOOP_CONDITION (0) 38 #endif 39 40 // DAWN_ASSERT_CALLSITE_HELPER generates the actual assert code. In Debug it does what you would 41 // expect of an assert and in release it tries to give hints to make the compiler generate better 42 // code. 43 #if defined(DAWN_ENABLE_ASSERTS) 44 # define DAWN_ASSERT_CALLSITE_HELPER(file, func, line, condition) \ 45 do { \ 46 if (!(condition)) { \ 47 HandleAssertionFailure(file, func, line, #condition); \ 48 } \ 49 } while (DAWN_ASSERT_LOOP_CONDITION) 50 #else 51 # if defined(DAWN_COMPILER_MSVC) 52 # define DAWN_ASSERT_CALLSITE_HELPER(file, func, line, condition) __assume(condition) 53 # elif defined(DAWN_COMPILER_CLANG) && defined(__builtin_assume) 54 # define DAWN_ASSERT_CALLSITE_HELPER(file, func, line, condition) __builtin_assume(condition) 55 # else 56 # define DAWN_ASSERT_CALLSITE_HELPER(file, func, line, condition) \ 57 do { \ 58 DAWN_UNUSED(sizeof(condition)); \ 59 } while (DAWN_ASSERT_LOOP_CONDITION) 60 # endif 61 #endif 62 63 #define DAWN_ASSERT(condition) DAWN_ASSERT_CALLSITE_HELPER(__FILE__, __func__, __LINE__, condition) 64 #define DAWN_UNREACHABLE() \ 65 do { \ 66 DAWN_ASSERT(DAWN_ASSERT_LOOP_CONDITION && "Unreachable code hit"); \ 67 DAWN_BUILTIN_UNREACHABLE(); \ 68 } while (DAWN_ASSERT_LOOP_CONDITION) 69 70 #if !defined(DAWN_SKIP_ASSERT_SHORTHANDS) 71 # define ASSERT DAWN_ASSERT 72 # define UNREACHABLE DAWN_UNREACHABLE 73 #endif 74 75 void HandleAssertionFailure(const char* file, 76 const char* function, 77 int line, 78 const char* condition); 79 80 #endif // COMMON_ASSERT_H_ 81