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 // TODO: b/234877280 - compiler.h should be refactored out of pw_preprocessor as 20 // the scope is outside of the module. Perhaps it should be split up and placed 21 // under pw_compiler, e.g. pw_compiler/attributes.h & pw_compiler/builtins.h. 22 23 #include "pw_polyfill/static_assert.h" 24 25 /// @defgroup pw_preprocessor_internal 26 27 /// @defgroup pw_preprocessor_compiler 28 /// @{ 29 30 /// Marks a struct or class as packed. 31 /// 32 /// Use packed structs with extreme caution! Packed structs are rarely needed. 33 /// Instead, define the struct and `static_assert` to verify that the size and 34 /// alignement are as expected. 35 /// 36 /// Packed structs should only be used to avoid standard padding or to force 37 /// unaligned members when describing in-memory or wire format data structures. 38 /// Packed struct members should NOT be accessed directly because they may be 39 /// unaligned. Instead, `memcpy` the fields into variables. For example: 40 /// 41 /// @code{.cpp} 42 /// PW_PACKED(struct) PackedStruct { 43 /// uint8_t a; 44 /// uint32_t b; 45 /// uint16_t c; 46 /// }; 47 /// 48 /// void UsePackedStruct(const PackedStruct& packed_struct) { 49 /// uint8_t a; 50 /// uint32_t b; 51 /// uint16_t c; 52 /// std::memcpy(&a, &packed_struct.a, sizeof(a)); 53 /// std::memcpy(&b, &packed_struct.b, sizeof(b)); 54 /// std::memcpy(&c, &packed_struct.c, sizeof(c)); 55 /// } 56 /// @endcode 57 #define PW_PACKED(declaration) declaration __attribute__((packed)) 58 59 /// Marks a function or object as used, ensuring code for it is generated. 60 #define PW_USED __attribute__((used)) 61 62 /// Prevents generation of a prologue or epilogue for a function. This is 63 /// helpful when implementing the function in assembly. 64 #define PW_NO_PROLOGUE __attribute__((naked)) 65 66 /// Marks that a function declaration takes a printf-style format string and 67 /// variadic arguments. This allows the compiler to perform check the validity 68 /// of the format string and arguments. This macro must only be on the function 69 /// declaration, not the definition. 70 /// 71 /// The format_index is index of the format string parameter and parameter_index 72 /// is the starting index of the variadic arguments. Indices start at 1. For C++ 73 /// class member functions, add one to the index to account for the implicit 74 /// this parameter. 75 /// 76 /// This example shows a function where the format string is argument 2 and the 77 /// varargs start at argument 3. 78 /// 79 /// @code{.cpp} 80 /// int PrintfStyleFunction(char* buffer, const char* fmt, ...) 81 /// PW_PRINTF_FORMAT(2,3); 82 /// 83 /// int PrintfStyleFunction(char* buffer, const char* fmt, ...) { ... 84 /// implementation here ... } 85 /// @endcode 86 #define PW_PRINTF_FORMAT(format_index, parameter_index) \ 87 __attribute__((format(_PW_PRINTF_FORMAT_TYPE, format_index, parameter_index))) 88 89 /// When compiling for host using MinGW, use gnu_printf() rather than printf() 90 /// to support %z format specifiers. 91 /// @ingroup pw_preprocessor_internal 92 #ifdef __USE_MINGW_ANSI_STDIO 93 #define _PW_PRINTF_FORMAT_TYPE gnu_printf 94 #else 95 #define _PW_PRINTF_FORMAT_TYPE printf 96 #endif // __USE_MINGW_ANSI_STDIO 97 98 /// Places a variable in the specified linker section. 99 #ifdef __APPLE__ 100 #define PW_PLACE_IN_SECTION(name) __attribute__((section("__DATA," name))) 101 #else 102 #define PW_PLACE_IN_SECTION(name) __attribute__((section(name))) 103 #endif // __APPLE__ 104 105 /// Places a variable in the specified linker section and directs the compiler 106 /// to keep the variable, even if it is not used. Depending on the linker 107 /// options, the linker may still remove this section if it is not declared in 108 /// the linker script and marked `KEEP`. 109 #ifdef __APPLE__ 110 #define PW_KEEP_IN_SECTION(name) __attribute__((section("__DATA," name), used)) 111 #else 112 #define PW_KEEP_IN_SECTION(name) __attribute__((section(name), used)) 113 #endif // __APPLE__ 114 115 /// Indicate to the compiler that the annotated function won't return. Example: 116 /// 117 /// @code{.cpp} 118 /// PW_NO_RETURN void HandleAssertFailure(ErrorCode error_code); 119 /// @endcode 120 #define PW_NO_RETURN __attribute__((noreturn)) 121 122 /// Prevents the compiler from inlining a fuction. 123 #define PW_NO_INLINE __attribute__((noinline)) 124 125 /// Indicate to the compiler that the given section of code will not be reached. 126 /// Example: 127 /// 128 /// @code{.cpp} 129 /// int main() { 130 /// InitializeBoard(); 131 /// vendor_StartScheduler(); // Note: vendor forgot noreturn attribute. 132 /// PW_UNREACHABLE; 133 /// } 134 /// @endcode 135 #define PW_UNREACHABLE __builtin_unreachable() 136 137 /// Indicate to a sanitizer compiler runtime to skip the named check in the 138 /// associated function. 139 /// Example: 140 /// 141 /// @code{.cpp} 142 /// uint32_t djb2(const void* buf, size_t len) 143 /// PW_NO_SANITIZE("unsigned-integer-overflow") { 144 /// uint32_t hash = 5381; 145 /// const uint8_t* u8 = static_cast<const uint8_t*>(buf); 146 /// for (size_t i = 0; i < len; ++i) { 147 /// hash = (hash * 33) + u8[i]; /* hash * 33 + c */ 148 /// } 149 /// return hash; 150 /// } 151 /// @endcode 152 #ifdef __clang__ 153 #define PW_NO_SANITIZE(check) __attribute__((no_sanitize(check))) 154 #else 155 #define PW_NO_SANITIZE(check) 156 #endif // __clang__ 157 158 /// Wrapper around `__has_attribute`, which is defined by GCC 5+ and Clang and 159 /// evaluates to a non zero constant integer if the attribute is supported or 0 160 /// if not. 161 #ifdef __has_attribute 162 #define PW_HAVE_ATTRIBUTE(x) __has_attribute(x) 163 #else 164 #define PW_HAVE_ATTRIBUTE(x) 0 165 #endif // __has_attribute 166 167 /// A function-like feature checking macro that accepts C++11 style attributes. 168 /// It is a wrapper around `__has_cpp_attribute`, which was introduced in the <a 169 /// href="https://en.cppreference.com/w/cpp/feature_test">C++20 standard</a>. It 170 /// is supported by compilers even if C++20 is not in use. Evaluates to a 171 /// non-zero constant integer if the C++ attribute is supported or 0 if not. 172 /// 173 /// This is a copy of `ABSL_HAVE_CPP_ATTRIBUTE`. 174 #if defined(__cplusplus) && defined(__has_cpp_attribute) 175 #define PW_HAVE_CPP_ATTRIBUTE(x) __has_cpp_attribute(x) 176 #else 177 #define PW_HAVE_CPP_ATTRIBUTE(x) 0 178 #endif // defined(__cplusplus) && defined(__has_cpp_attribute) 179 180 /// @ingroup pw_preprocessor_internal 181 #define _PW_REQUIRE_SEMICOLON \ 182 static_assert(1, "This macro must be terminated with a semicolon") 183 184 /// Starts a new group of @c_macro{PW_MODIFY_DIAGNOSTIC} statements. A 185 /// @c_macro{PW_MODIFY_DIAGNOSTICS_POP} statement must follow. 186 #define PW_MODIFY_DIAGNOSTICS_PUSH() \ 187 _Pragma("GCC diagnostic push") _PW_REQUIRE_SEMICOLON 188 189 /// @c_macro{PW_MODIFY_DIAGNOSTIC} statements since the most recent 190 /// @c_macro{PW_MODIFY_DIAGNOSTICS_PUSH} no longer apply after this statement. 191 #define PW_MODIFY_DIAGNOSTICS_POP() \ 192 _Pragma("GCC diagnostic pop") _PW_REQUIRE_SEMICOLON 193 194 /// Changes how a diagnostic (warning or error) is handled. Most commonly used 195 /// to disable warnings. ``PW_MODIFY_DIAGNOSTIC`` should be used between 196 /// @c_macro{PW_MODIFY_DIAGNOSTICS_PUSH} and @c_macro{PW_MODIFY_DIAGNOSTICS_POP} 197 /// statements to avoid applying the modifications too broadly. 198 /// 199 /// ``kind`` may be ``warning``, ``error``, or ``ignored``. 200 #define PW_MODIFY_DIAGNOSTIC(kind, option) \ 201 PW_PRAGMA(GCC diagnostic kind option) _PW_REQUIRE_SEMICOLON 202 203 /// Applies ``PW_MODIFY_DIAGNOSTIC`` only for GCC. This is useful for warnings 204 /// that aren't supported by or don't need to be changed in other compilers. 205 #ifdef __clang__ 206 #define PW_MODIFY_DIAGNOSTIC_GCC(kind, option) _PW_REQUIRE_SEMICOLON 207 #else 208 #define PW_MODIFY_DIAGNOSTIC_GCC(kind, option) \ 209 PW_MODIFY_DIAGNOSTIC(kind, option) 210 #endif // __clang__ 211 212 /// Applies ``PW_MODIFY_DIAGNOSTIC`` only for Clang. This is useful for warnings 213 /// that aren't supported by or don't need to be changed in other compilers. 214 #ifdef __clang__ 215 #define PW_MODIFY_DIAGNOSTIC_CLANG(kind, option) \ 216 PW_MODIFY_DIAGNOSTIC(kind, option) 217 #else 218 #define PW_MODIFY_DIAGNOSTIC_CLANG(kind, option) _PW_REQUIRE_SEMICOLON 219 #endif // __clang__ 220 221 /// Expands to a `_Pragma` with the contents as a string. `_Pragma` must take a 222 /// single string literal; this can be used to construct a `_Pragma` argument. 223 #define PW_PRAGMA(contents) _Pragma(#contents) 224 225 /// Marks a function or object as weak, allowing the definition to be overriden. 226 /// 227 /// This can be useful when supporting third-party SDKs which may conditionally 228 /// compile in code, for example: 229 /// 230 /// @code{.cpp} 231 /// PW_WEAK void SysTick_Handler(void) { 232 /// // Default interrupt handler that might be overriden. 233 /// } 234 /// @endcode 235 #define PW_WEAK __attribute__((weak)) 236 237 /// Marks a weak function as an alias to another, allowing the definition to 238 /// be given a default and overriden. 239 /// 240 /// This can be useful when supporting third-party SDKs which may conditionally 241 /// compile in code, for example: 242 /// 243 /// @code{.cpp} 244 /// // Driver handler replaced with default unless overridden. 245 /// void USART_DriverHandler(void) PW_ALIAS(DefaultDriverHandler); 246 /// @endcode 247 #define PW_ALIAS(aliased_to) __attribute__((weak, alias(#aliased_to))) 248 249 /// `PW_ATTRIBUTE_LIFETIME_BOUND` indicates that a resource owned by a function 250 /// parameter or implicit object parameter is retained by the return value of 251 /// the annotated function (or, for a parameter of a constructor, in the value 252 /// of the constructed object). This attribute causes warnings to be produced if 253 /// a temporary object does not live long enough. 254 /// 255 /// When applied to a reference parameter, the referenced object is assumed to 256 /// be retained by the return value of the function. When applied to a 257 /// non-reference parameter (for example, a pointer or a class type), all 258 /// temporaries referenced by the parameter are assumed to be retained by the 259 /// return value of the function. 260 /// 261 /// See also the upstream documentation: 262 /// https://clang.llvm.org/docs/AttributeReference.html#lifetimebound 263 /// 264 /// This is a copy of `ABSL_ATTRIBUTE_LIFETIME_BOUND`. 265 #if PW_HAVE_CPP_ATTRIBUTE(clang::lifetimebound) 266 #define PW_ATTRIBUTE_LIFETIME_BOUND [[clang::lifetimebound]] 267 #elif PW_HAVE_ATTRIBUTE(lifetimebound) 268 #define PW_ATTRIBUTE_LIFETIME_BOUND __attribute__((lifetimebound)) 269 #else 270 #define PW_ATTRIBUTE_LIFETIME_BOUND 271 #endif // PW_ATTRIBUTE_LIFETIME_BOUND 272 273 /// `PW_ADD_OVERFLOW` adds two integers while checking for overflow. 274 /// 275 /// Returns true if the result of `a + b` overflows the type of `out`; otherwise 276 /// stores the result in `out` and returns false. 277 /// 278 /// See also `PW_CHECK_ADD`. 279 #define PW_ADD_OVERFLOW(a, b, out) __builtin_add_overflow(a, b, out) 280 281 /// `PW_SUB_OVERFLOW` subtracts an integer from another while checking for 282 /// overflow. 283 /// 284 /// Returns true if the result of `a - b` overflows the type of `out`; otherwise 285 /// stores the result in `out` and returns false. 286 /// 287 /// See also `PW_CHECK_SUB`. 288 #define PW_SUB_OVERFLOW(a, b, out) __builtin_sub_overflow(a, b, out) 289 290 /// `PW_MUL_OVERFLOW` multiplies two integers while checking for overflow. 291 /// 292 /// Returns true if the result of `a * b` overflows the type of `out`; otherwise 293 /// stores the result in `out` and returns false. 294 /// 295 /// See also `PW_CHECK_MUL`. 296 #define PW_MUL_OVERFLOW(a, b, out) __builtin_mul_overflow(a, b, out) 297 298 /// Evaluates to 1 if `__VA_OPT__` is supported, regardless of the C or C++ 299 /// standard in use. 300 #if (defined(__clang_major__) && __clang_major__ < 9) || \ 301 (defined(__GNUC__) && __GNUC__ < 12) 302 #define PW_VA_OPT_SUPPORTED() 0 // Don't bother checking on old compilers. 303 #else 304 #define PW_VA_OPT_SUPPORTED() _PW_VA_OPT_SUPPORTED() 305 /// @} 306 307 #define _PW_VA_OPT_SUPPORTED(...) _PW_VA_OPT_SUPPORTED_##__VA_OPT__() 308 #define _PW_VA_OPT_SUPPORTED_ 1 309 #define _PW_VA_OPT_SUPPORTED___VA_OPT__() 0 310 311 #endif // __clang_major__ < 9 || __GNUC__ < 12 312 313 /// `PW_NO_UNIQUE_ADDRESS` indicates that an object can have no unique 314 /// address. This is usually used to force empty member types to occupy 315 /// 0 bytes instead of 1 byte to have a unique address. 316 #if PW_HAVE_CPP_ATTRIBUTE(no_unique_address) 317 #define PW_NO_UNIQUE_ADDRESS [[no_unique_address]] 318 #else 319 #define PW_NO_UNIQUE_ADDRESS 320 #endif // PW_NO_UNIQUE_ADDRESS 321