1 // Copyright 2019 The Pigweed Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not 4 // use this file except in compliance with the License. You may obtain a copy of 5 // the License at 6 // 7 // https://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, WITHOUT 11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 // License for the specific language governing permissions and limitations under 13 // the License. 14 // 15 // Preprocessor macros that wrap compiler-specific features. 16 // This file is used by both C++ and C code. 17 #pragma once 18 19 #include <assert.h> 20 21 // TODO(b/234877280): compiler.h should be refactored out of pw_preprocessor as 22 // the scope is outside of the module. Perhaps it should be split up and placed 23 // under pw_compiler, e.g. pw_compiler/attributes.h & pw_compiler/builtins.h. 24 25 // Marks a struct or class as packed. 26 #define PW_PACKED(declaration) declaration __attribute__((packed)) 27 28 // Marks a function or object as used, ensuring code for it is generated. 29 #define PW_USED __attribute__((used)) 30 31 // Prevents generation of a prologue or epilogue for a function. This is 32 // helpful when implementing the function in assembly. 33 #define PW_NO_PROLOGUE __attribute__((naked)) 34 35 // Marks that a function declaration takes a printf-style format string and 36 // variadic arguments. This allows the compiler to perform check the validity of 37 // the format string and arguments. This macro must only be on the function 38 // declaration, not the definition. 39 // 40 // The format_index is index of the format string parameter and parameter_index 41 // is the starting index of the variadic arguments. Indices start at 1. For C++ 42 // class member functions, add one to the index to account for the implicit this 43 // parameter. 44 // 45 // This example shows a function where the format string is argument 2 and the 46 // varargs start at argument 3. 47 // 48 // int PrintfStyleFunction(char* buffer, 49 // const char* fmt, ...) PW_PRINTF_FORMAT(2,3); 50 // 51 // int PrintfStyleFunction(char* buffer, const char* fmt, ...) { 52 // ... implementation here ... 53 // } 54 // 55 56 // When compiling for host using MinGW, use gnu_printf() rather than printf() 57 // to support %z format specifiers. 58 #ifdef __USE_MINGW_ANSI_STDIO 59 #define _PW_PRINTF_FORMAT_TYPE gnu_printf 60 #else 61 #define _PW_PRINTF_FORMAT_TYPE printf 62 #endif // __USE_MINGW_ANSI_STDIO 63 64 #define PW_PRINTF_FORMAT(format_index, parameter_index) \ 65 __attribute__((format(_PW_PRINTF_FORMAT_TYPE, format_index, parameter_index))) 66 67 // Places a variable in the specified linker section. 68 #ifdef __APPLE__ 69 #define PW_PLACE_IN_SECTION(name) __attribute__((section("__DATA," name))) 70 #else 71 #define PW_PLACE_IN_SECTION(name) __attribute__((section(name))) 72 #endif // __APPLE__ 73 74 // Places a variable in the specified linker section and directs the compiler 75 // to keep the variable, even if it is not used. Depending on the linker 76 // options, the linker may still remove this section if it is not declared in 77 // the linker script and marked KEEP. 78 #ifdef __APPLE__ 79 #define PW_KEEP_IN_SECTION(name) __attribute__((section("__DATA," name), used)) 80 #else 81 #define PW_KEEP_IN_SECTION(name) __attribute__((section(name), used)) 82 #endif // __APPLE__ 83 84 // Indicate to the compiler that the annotated function won't return. Example: 85 // 86 // PW_NO_RETURN void HandleAssertFailure(ErrorCode error_code); 87 // 88 #define PW_NO_RETURN __attribute__((noreturn)) 89 90 // Prevents the compiler from inlining a fuction. 91 #define PW_NO_INLINE __attribute__((noinline)) 92 93 // Indicate to the compiler that the given section of code will not be reached. 94 // Example: 95 // 96 // int main() { 97 // InitializeBoard(); 98 // vendor_StartScheduler(); // Note: vendor forgot noreturn attribute. 99 // PW_UNREACHABLE; 100 // } 101 // 102 #define PW_UNREACHABLE __builtin_unreachable() 103 104 // Indicate to a sanitizer compiler runtime to skip the named check in the 105 // associated function. 106 // Example: 107 // 108 // uint32_t djb2(const void* buf, size_t len) 109 // PW_NO_SANITIZE("unsigned-integer-overflow"){ 110 // uint32_t hash = 5381; 111 // const uint8_t* u8 = static_cast<const uint8_t*>(buf); 112 // for (size_t i = 0; i < len; ++i) { 113 // hash = (hash * 33) + u8[i]; /* hash * 33 + c */ 114 // } 115 // return hash; 116 // } 117 #ifdef __clang__ 118 #define PW_NO_SANITIZE(check) __attribute__((no_sanitize(check))) 119 #else 120 #define PW_NO_SANITIZE(check) 121 #endif // __clang__ 122 123 // Wrapper around `__has_attribute`, which is defined by GCC 5+ and Clang and 124 // evaluates to a non zero constant integer if the attribute is supported or 0 125 // if not. 126 #ifdef __has_attribute 127 #define PW_HAVE_ATTRIBUTE(x) __has_attribute(x) 128 #else 129 #define PW_HAVE_ATTRIBUTE(x) 0 130 #endif // __has_attribute 131 132 // A function-like feature checking macro that accepts C++11 style attributes. 133 // It's a wrapper around __has_cpp_attribute 134 // (https://en.cppreference.com/w/cpp/feature_test), borrowed from 135 // ABSL_HAVE_CPP_ATTRIBUTE. If there is no __has_cpp_attribute, evaluates to 0. 136 #if defined(__cplusplus) && defined(__has_cpp_attribute) 137 #define PW_HAVE_CPP_ATTRIBUTE(x) __has_cpp_attribute(x) 138 #else 139 #define PW_HAVE_CPP_ATTRIBUTE(x) 0 140 #endif // defined(__cplusplus) && defined(__has_cpp_attribute) 141 142 #define _PW_REQUIRE_SEMICOLON \ 143 static_assert(1, "This macro must be terminated with a semicolon") 144 145 // PW_MODIFY_DIAGNOSTICS_PUSH and PW_MODIFY_DIAGNOSTICS_POP are used to turn off 146 // or on diagnostics (warnings or errors) for a section of code. Use 147 // PW_MODIFY_DIAGNOSTICS_PUSH, use PW_MODIFY_DIAGNOSTIC as many times as needed, 148 // then use PW_MODIFY_DIAGNOSTICS_POP to restore the previous settings. 149 #define PW_MODIFY_DIAGNOSTICS_PUSH() \ 150 _Pragma("GCC diagnostic push") _PW_REQUIRE_SEMICOLON 151 #define PW_MODIFY_DIAGNOSTICS_POP() \ 152 _Pragma("GCC diagnostic pop") _PW_REQUIRE_SEMICOLON 153 154 // Changes how a diagnostic (warning or error) is handled. Most commonly used to 155 // disable warnings. PW_MODIFY_DIAGNOSTIC should be used between 156 // PW_MODIFY_DIAGNOSTICS_PUSH and PW_MODIFY_DIAGNOSTICS_POP statements to avoid 157 // applying the modifications too broadly. 158 // 159 // 'kind' must be one of warning, error, or ignored. 160 #define PW_MODIFY_DIAGNOSTIC(kind, option) \ 161 PW_PRAGMA(GCC diagnostic kind option) _PW_REQUIRE_SEMICOLON 162 163 // Applies PW_MODIFY_DIAGNOSTIC only for GCC. This is useful for warnings that 164 // aren't supported by or don't need to be changed in other compilers. 165 #ifdef __clang__ 166 #define PW_MODIFY_DIAGNOSTIC_GCC(kind, option) _PW_REQUIRE_SEMICOLON 167 #else 168 #define PW_MODIFY_DIAGNOSTIC_GCC(kind, option) \ 169 PW_MODIFY_DIAGNOSTIC(kind, option) 170 #endif // __clang__ 171 172 // Expands to a _Pragma with the contents as a string. _Pragma must take a 173 // single string literal; this can be used to construct a _Pragma argument. 174 #define PW_PRAGMA(contents) _Pragma(#contents) 175 176 // Marks a function or object as weak, allowing the definition to be overriden. 177 // 178 // This can be useful when supporting third-party SDKs which may conditionally 179 // compile in code, for example: 180 // 181 // PW_WEAK void SysTick_Handler(void) { 182 // // Default interrupt handler that might be overriden. 183 // } 184 #define PW_WEAK __attribute__((weak)) 185 186 // Marks a weak function as an alias to another, allowing the definition to 187 // be given a default and overriden. 188 // 189 // This can be useful when supporting third-party SDKs which may conditionally 190 // compile in code, for example: 191 // 192 // // Driver handler replaced with default unless overridden. 193 // void USART_DriverHandler(void) PW_ALIAS(DefaultDriverHandler); 194 #define PW_ALIAS(aliased_to) __attribute__((weak, alias(#aliased_to))) 195 196 // PW_ATTRIBUTE_LIFETIME_BOUND indicates that a resource owned by a function 197 // parameter or implicit object parameter is retained by the return value of the 198 // annotated function (or, for a parameter of a constructor, in the value of the 199 // constructed object). This attribute causes warnings to be produced if a 200 // temporary object does not live long enough. 201 // 202 // When applied to a reference parameter, the referenced object is assumed to be 203 // retained by the return value of the function. When applied to a non-reference 204 // parameter (for example, a pointer or a class type), all temporaries 205 // referenced by the parameter are assumed to be retained by the return value of 206 // the function. 207 // 208 // See also the upstream documentation: 209 // https://clang.llvm.org/docs/AttributeReference.html#lifetimebound 210 // 211 // This is a copy of ABSL_ATTRIBUTE_LIFETIME_BOUND. 212 #if PW_HAVE_CPP_ATTRIBUTE(clang::lifetimebound) 213 #define PW_ATTRIBUTE_LIFETIME_BOUND [[clang::lifetimebound]] 214 #elif PW_HAVE_ATTRIBUTE(lifetimebound) 215 #define PW_ATTRIBUTE_LIFETIME_BOUND __attribute__((lifetimebound)) 216 #else 217 #define PW_ATTRIBUTE_LIFETIME_BOUND 218 #endif // PW_ATTRIBUTE_LIFETIME_BOUND 219