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 57 #ifndef OPENTHREAD_PLATFORM_TOOLCHAIN_H_ 58 #define OPENTHREAD_PLATFORM_TOOLCHAIN_H_ 59 60 #include <stdbool.h> 61 #include <stdint.h> 62 63 #ifdef __cplusplus 64 extern "C" { 65 #endif 66 67 /** 68 * @def OT_MUST_USE_RESULT 69 * 70 * Compiler-specific indication that a class or enum must be used when it is 71 * the return value of a function. 72 * 73 * @note This is currently only available with clang (C++17 implements it 74 * as attribute [[nodiscard]]). 75 * @note To suppress the 'unused-result' warning/error, please use the 76 * '-Wno-unused-result' compiler option. 77 * 78 */ 79 #if defined(__clang__) && (__clang_major__ >= 4 || (__clang_major__ >= 3 && __clang_minor__ >= 9)) 80 #define OT_MUST_USE_RESULT __attribute__((warn_unused_result)) 81 #else 82 #define OT_MUST_USE_RESULT 83 #endif 84 85 /** 86 * @def OT_TOOL_PACKED_BEGIN 87 * 88 * Compiler-specific indication that a class or struct must be byte packed. 89 * 90 */ 91 92 /** 93 * @def OT_TOOL_PACKED_FIELD 94 * 95 * Indicate to the compiler a nested struct or union to be packed 96 * within byte packed class or struct. 97 * 98 */ 99 100 /** 101 * @def OT_TOOL_PACKED_END 102 * 103 * Compiler-specific indication at the end of a byte packed class or struct. 104 * 105 */ 106 107 /** 108 * @def OT_TOOL_WEAK 109 * 110 * Compiler-specific weak symbol modifier. 111 * 112 */ 113 114 /** 115 * @def OT_TOOL_PRINTF_STYLE_FORMAT_ARG_CHECK 116 * 117 * Specifies that a function or method takes `printf` style arguments and should be type-checked against 118 * a format string. 119 * 120 * Must be added after the function/method declaration. For example: 121 * 122 * `void MyPrintf(void *aObject, const char *aFormat, ...) OT_TOOL_PRINTF_STYLE_FORMAT_ARG_CHECK(2, 3);` 123 * 124 * The two argument index values indicate format string and first argument to check against it. They start at index 1 125 * for the first parameter in a function and at index 2 for the first parameter in a method. 126 * 127 * @param[in] aFmtIndex The argument index of the format string. 128 * @param[in] aStartIndex The argument index of the first argument to check against the format string. 129 * 130 */ 131 132 // =========== TOOLCHAIN SELECTION : START =========== 133 134 #if defined(__GNUC__) || defined(__clang__) || defined(__CC_ARM) || defined(__TI_ARM__) 135 136 // https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html 137 // http://www.keil.com/support/man/docs/armcc/armcc_chr1359124973480.htm 138 139 #define OT_TOOL_PACKED_BEGIN 140 #define OT_TOOL_PACKED_FIELD __attribute__((packed)) 141 #define OT_TOOL_PACKED_END __attribute__((packed)) 142 #define OT_TOOL_WEAK __attribute__((weak)) 143 144 #define OT_TOOL_PRINTF_STYLE_FORMAT_ARG_CHECK(aFmtIndex, aStartIndex) \ 145 __attribute__((format(printf, aFmtIndex, aStartIndex))) 146 147 #elif defined(__ICCARM__) || defined(__ICC8051__) 148 149 // http://supp.iar.com/FilesPublic/UPDINFO/004916/arm/doc/EWARM_DevelopmentGuide.ENU.pdf 150 151 #include "intrinsics.h" 152 153 #define OT_TOOL_PACKED_BEGIN __packed 154 #define OT_TOOL_PACKED_FIELD 155 #define OT_TOOL_PACKED_END 156 #define OT_TOOL_WEAK __weak 157 158 #define OT_TOOL_PRINTF_STYLE_FORMAT_ARG_CHECK(aFmtIndex, aStartIndex) 159 160 #elif defined(__SDCC) 161 162 // Structures are packed by default in sdcc, as it primarily targets 8-bit MCUs. 163 164 #define OT_TOOL_PACKED_BEGIN 165 #define OT_TOOL_PACKED_FIELD 166 #define OT_TOOL_PACKED_END 167 #define OT_TOOL_WEAK 168 169 #define OT_TOOL_PRINTF_STYLE_FORMAT_ARG_CHECK(aFmtIndex, aStartIndex) 170 171 #else 172 173 #error "Error: No valid Toolchain specified" 174 175 // Symbols for Doxygen 176 177 #define OT_TOOL_PACKED_BEGIN 178 #define OT_TOOL_PACKED_FIELD 179 #define OT_TOOL_PACKED_END 180 #define OT_TOOL_WEAK 181 182 #define OT_TOOL_PRINTF_STYLE_FORMAT_ARG_CHECK(aFmtIndex, aStartIndex) 183 184 #endif 185 186 // =========== TOOLCHAIN SELECTION : END =========== 187 188 /** 189 * @def OT_UNUSED_VARIABLE 190 * 191 * Suppress unused variable warning in specific toolchains. 192 * 193 */ 194 195 /** 196 * @def OT_UNREACHABLE_CODE 197 * 198 * Suppress Unreachable code warning in specific toolchains. 199 * 200 */ 201 202 #if defined(__ICCARM__) 203 204 #include <stddef.h> 205 206 #define OT_UNUSED_VARIABLE(VARIABLE) \ 207 do \ 208 { \ 209 if (&VARIABLE == NULL) \ 210 { \ 211 } \ 212 } while (false) 213 214 #define OT_UNREACHABLE_CODE(CODE) \ 215 _Pragma("diag_suppress=Pe111") _Pragma("diag_suppress=Pe128") CODE _Pragma("diag_default=Pe111") \ 216 _Pragma("diag_default=Pe128") 217 218 #elif defined(__CC_ARM) 219 220 #include <stddef.h> 221 222 #define OT_UNUSED_VARIABLE(VARIABLE) \ 223 do \ 224 { \ 225 if (&VARIABLE == NULL) \ 226 { \ 227 } \ 228 } while (false) 229 230 #define OT_UNREACHABLE_CODE(CODE) CODE 231 232 #elif defined(__TI_ARM__) 233 234 #include <stddef.h> 235 236 #define OT_UNUSED_VARIABLE(VARIABLE) \ 237 do \ 238 { \ 239 if (&VARIABLE == NULL) \ 240 { \ 241 } \ 242 } while (false) 243 244 /* 245 * #112-D statement is unreachable 246 * #129-D loop is not reachable 247 */ 248 #define OT_UNREACHABLE_CODE(CODE) \ 249 _Pragma("diag_push") _Pragma("diag_suppress 112") _Pragma("diag_suppress 129") CODE _Pragma("diag_pop") 250 251 #else 252 253 #define OT_UNUSED_VARIABLE(VARIABLE) \ 254 do \ 255 { \ 256 (void)(VARIABLE); \ 257 } while (false) 258 259 #define OT_UNREACHABLE_CODE(CODE) CODE 260 261 #endif 262 263 /* 264 * Keil and IAR compiler doesn't provide type limits for C++. 265 */ 266 #ifdef __cplusplus 267 #if defined(__CC_ARM) || defined(__ICCARM__) 268 269 #ifndef UINT8_MAX 270 #define UINT8_MAX 0xff 271 #endif 272 273 #ifndef UINT16_MAX 274 #define UINT16_MAX 0xffff 275 #endif 276 277 #endif 278 #endif 279 280 #ifdef __APPLE__ 281 #define OT_APPLE_IGNORE_GNU_FOLDING_CONSTANT(...) \ 282 _Pragma("GCC diagnostic push") _Pragma("GCC diagnostic ignored \"-Wgnu-folding-constant\"") \ 283 __VA_ARGS__ _Pragma("GCC diagnostic pop") 284 #else 285 #define OT_APPLE_IGNORE_GNU_FOLDING_CONSTANT(...) __VA_ARGS__ 286 #endif 287 288 /** 289 * @def OT_FALL_THROUGH 290 * 291 * Suppress fall through warning in specific compiler. 292 * 293 */ 294 #if defined(__cplusplus) && (__cplusplus >= 201703L) 295 #define OT_FALL_THROUGH [[fallthrough]] 296 #elif defined(__clang__) 297 #define OT_FALL_THROUGH [[clang::fallthrough]] 298 #elif defined(__GNUC__) && (__GNUC__ >= 7) 299 #define OT_FALL_THROUGH __attribute__((fallthrough)) 300 #else 301 #define OT_FALL_THROUGH \ 302 do \ 303 { \ 304 } while (false) /* fallthrough */ 305 #endif 306 307 /** 308 * @} 309 * 310 */ 311 312 #ifdef __cplusplus 313 } // extern "C" 314 #endif 315 316 #endif // OPENTHREAD_PLATFORM_TOOLCHAIN_H_ 317