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