1 /* 2 * Copyright (c) 2016, The OpenThread Authors. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 3. Neither the name of the copyright holder nor the 13 * names of its contributors may be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 /** 30 * @addtogroup plat-toolchain 31 * 32 * @brief 33 * This module defines a toolchain abstraction layer through macros. 34 * 35 * Usage: 36 * 37 * @code 38 * 39 * typedef 40 * OT_TOOL_PACKED_BEGIN 41 * struct 42 * { 43 * char mField1; 44 * union 45 * { 46 * char mField2; 47 * long mField3; 48 * } OT_TOOL_PACKED_FIELD; 49 * } OT_TOOL_PACKED_END packed_struct_t; 50 * 51 * @endcode 52 * 53 * @{ 54 */ 55 56 #ifndef OPENTHREAD_PLATFORM_TOOLCHAIN_H_ 57 #define OPENTHREAD_PLATFORM_TOOLCHAIN_H_ 58 59 #include <stdbool.h> 60 #include <stdint.h> 61 62 #ifdef __cplusplus 63 extern "C" { 64 #endif 65 66 /** 67 * @def OT_MUST_USE_RESULT 68 * 69 * Compiler-specific indication that a class or enum must be used when it is 70 * the return value of a function. 71 * 72 * @note This is currently only available with clang (C++17 implements it 73 * as attribute [[nodiscard]]). 74 * @note To suppress the 'unused-result' warning/error, please use the 75 * '-Wno-unused-result' compiler option. 76 */ 77 #if defined(__clang__) && (__clang_major__ >= 4 || (__clang_major__ >= 3 && __clang_minor__ >= 9)) 78 #define OT_MUST_USE_RESULT __attribute__((warn_unused_result)) 79 #else 80 #define OT_MUST_USE_RESULT 81 #endif 82 83 /** 84 * @def OT_TOOL_PACKED_BEGIN 85 * 86 * Compiler-specific indication that a class or struct must be byte packed. 87 */ 88 89 /** 90 * @def OT_TOOL_PACKED_FIELD 91 * 92 * Indicate to the compiler a nested struct or union to be packed 93 * within byte packed class or struct. 94 */ 95 96 /** 97 * @def OT_TOOL_PACKED_END 98 * 99 * Compiler-specific indication at the end of a byte packed class or struct. 100 */ 101 102 /** 103 * @def OT_TOOL_WEAK 104 * 105 * Compiler-specific weak symbol modifier. 106 */ 107 108 /** 109 * @def OT_TOOL_PRINTF_STYLE_FORMAT_ARG_CHECK 110 * 111 * Specifies that a function or method takes `printf` style arguments and should be type-checked against 112 * a format string. 113 * 114 * Must be added after the function/method declaration. For example: 115 * 116 * `void MyPrintf(void *aObject, const char *aFormat, ...) OT_TOOL_PRINTF_STYLE_FORMAT_ARG_CHECK(2, 3);` 117 * 118 * The two argument index values indicate format string and first argument to check against it. They start at index 1 119 * for the first parameter in a function and at index 2 for the first parameter in a method. 120 * 121 * @param[in] aFmtIndex The argument index of the format string. 122 * @param[in] aStartIndex The argument index of the first argument to check against the format string. 123 */ 124 125 // =========== TOOLCHAIN SELECTION : START =========== 126 127 #if defined(__GNUC__) || defined(__clang__) || defined(__CC_ARM) || defined(__TI_ARM__) 128 129 // https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html 130 // http://www.keil.com/support/man/docs/armcc/armcc_chr1359124973480.htm 131 132 #define OT_TOOL_PACKED_BEGIN 133 #define OT_TOOL_PACKED_FIELD __attribute__((packed)) 134 #define OT_TOOL_PACKED_END __attribute__((packed)) 135 #define OT_TOOL_WEAK __attribute__((weak)) 136 137 #define OT_TOOL_PRINTF_STYLE_FORMAT_ARG_CHECK(aFmtIndex, aStartIndex) \ 138 __attribute__((format(printf, aFmtIndex, aStartIndex))) 139 140 #elif defined(__ICCARM__) || defined(__ICC8051__) 141 142 // http://supp.iar.com/FilesPublic/UPDINFO/004916/arm/doc/EWARM_DevelopmentGuide.ENU.pdf 143 144 #include "intrinsics.h" 145 146 #define OT_TOOL_PACKED_BEGIN __packed 147 #define OT_TOOL_PACKED_FIELD 148 #define OT_TOOL_PACKED_END 149 #define OT_TOOL_WEAK __weak 150 151 #define OT_TOOL_PRINTF_STYLE_FORMAT_ARG_CHECK(aFmtIndex, aStartIndex) 152 153 #elif defined(__SDCC) 154 155 // Structures are packed by default in sdcc, as it primarily targets 8-bit MCUs. 156 157 #define OT_TOOL_PACKED_BEGIN 158 #define OT_TOOL_PACKED_FIELD 159 #define OT_TOOL_PACKED_END 160 #define OT_TOOL_WEAK 161 162 #define OT_TOOL_PRINTF_STYLE_FORMAT_ARG_CHECK(aFmtIndex, aStartIndex) 163 164 #else 165 166 #error "Error: No valid Toolchain specified" 167 168 // Symbols for Doxygen 169 170 #define OT_TOOL_PACKED_BEGIN 171 #define OT_TOOL_PACKED_FIELD 172 #define OT_TOOL_PACKED_END 173 #define OT_TOOL_WEAK 174 175 #define OT_TOOL_PRINTF_STYLE_FORMAT_ARG_CHECK(aFmtIndex, aStartIndex) 176 177 #endif 178 179 // =========== TOOLCHAIN SELECTION : END =========== 180 181 /** 182 * @def OT_UNUSED_VARIABLE 183 * 184 * Suppress unused variable warning in specific toolchains. 185 */ 186 187 /** 188 * @def OT_UNREACHABLE_CODE 189 * 190 * Suppress Unreachable code warning in specific toolchains. 191 */ 192 193 #if defined(__ICCARM__) 194 195 #include <stddef.h> 196 197 #define OT_UNUSED_VARIABLE(VARIABLE) \ 198 do \ 199 { \ 200 if (&VARIABLE == NULL) \ 201 { \ 202 } \ 203 } while (false) 204 205 #define OT_UNREACHABLE_CODE(CODE) \ 206 _Pragma("diag_suppress=Pe111") _Pragma("diag_suppress=Pe128") CODE _Pragma("diag_default=Pe111") \ 207 _Pragma("diag_default=Pe128") 208 209 #elif defined(__CC_ARM) 210 211 #include <stddef.h> 212 213 #define OT_UNUSED_VARIABLE(VARIABLE) \ 214 do \ 215 { \ 216 if (&VARIABLE == NULL) \ 217 { \ 218 } \ 219 } while (false) 220 221 #define OT_UNREACHABLE_CODE(CODE) CODE 222 223 #elif defined(__TI_ARM__) 224 225 #include <stddef.h> 226 227 #define OT_UNUSED_VARIABLE(VARIABLE) \ 228 do \ 229 { \ 230 if (&VARIABLE == NULL) \ 231 { \ 232 } \ 233 } while (false) 234 235 /* 236 * #112-D statement is unreachable 237 * #129-D loop is not reachable 238 */ 239 #define OT_UNREACHABLE_CODE(CODE) \ 240 _Pragma("diag_push") _Pragma("diag_suppress 112") _Pragma("diag_suppress 129") CODE _Pragma("diag_pop") 241 242 #else 243 244 #define OT_UNUSED_VARIABLE(VARIABLE) \ 245 do \ 246 { \ 247 (void)(VARIABLE); \ 248 } while (false) 249 250 #define OT_UNREACHABLE_CODE(CODE) CODE 251 252 #endif 253 254 /* 255 * Keil and IAR compiler doesn't provide type limits for C++. 256 */ 257 #ifdef __cplusplus 258 #if defined(__CC_ARM) || defined(__ICCARM__) 259 260 #ifndef UINT8_MAX 261 #define UINT8_MAX 0xff 262 #endif 263 264 #ifndef UINT16_MAX 265 #define UINT16_MAX 0xffff 266 #endif 267 268 #endif 269 #endif 270 271 #ifdef __APPLE__ 272 #define OT_APPLE_IGNORE_GNU_FOLDING_CONSTANT(...) \ 273 _Pragma("GCC diagnostic push") _Pragma("GCC diagnostic ignored \"-Wgnu-folding-constant\"") \ 274 __VA_ARGS__ _Pragma("GCC diagnostic pop") 275 #else 276 #define OT_APPLE_IGNORE_GNU_FOLDING_CONSTANT(...) __VA_ARGS__ 277 #endif 278 279 /** 280 * @def OT_FALL_THROUGH 281 * 282 * Suppress fall through warning in specific compiler. 283 */ 284 #if defined(__cplusplus) && (__cplusplus >= 201703L) 285 #define OT_FALL_THROUGH [[fallthrough]] 286 #elif defined(__clang__) 287 #define OT_FALL_THROUGH [[clang::fallthrough]] 288 #elif defined(__GNUC__) && (__GNUC__ >= 7) 289 #define OT_FALL_THROUGH __attribute__((fallthrough)) 290 #else 291 #define OT_FALL_THROUGH \ 292 do \ 293 { \ 294 } while (false) /* fallthrough */ 295 #endif 296 297 /** 298 * @} 299 */ 300 301 #ifdef __cplusplus 302 } // extern "C" 303 #endif 304 305 #endif // OPENTHREAD_PLATFORM_TOOLCHAIN_H_ 306