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 // =========== TOOLCHAIN SELECTION : START =========== 114 115 #if defined(__GNUC__) || defined(__clang__) || defined(__CC_ARM) || defined(__TI_ARM__) 116 117 // https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html 118 // http://www.keil.com/support/man/docs/armcc/armcc_chr1359124973480.htm 119 120 #define OT_TOOL_PACKED_BEGIN 121 #define OT_TOOL_PACKED_FIELD __attribute__((packed)) 122 #define OT_TOOL_PACKED_END __attribute__((packed)) 123 #define OT_TOOL_WEAK __attribute__((weak)) 124 125 #elif defined(__ICCARM__) || defined(__ICC8051__) 126 127 // http://supp.iar.com/FilesPublic/UPDINFO/004916/arm/doc/EWARM_DevelopmentGuide.ENU.pdf 128 129 #include "intrinsics.h" 130 131 #define OT_TOOL_PACKED_BEGIN __packed 132 #define OT_TOOL_PACKED_FIELD 133 #define OT_TOOL_PACKED_END 134 #define OT_TOOL_WEAK __weak 135 136 #elif defined(__SDCC) 137 138 // Structures are packed by default in sdcc, as it primarily targets 8-bit MCUs. 139 140 #define OT_TOOL_PACKED_BEGIN 141 #define OT_TOOL_PACKED_FIELD 142 #define OT_TOOL_PACKED_END 143 #define OT_TOOL_WEAK 144 145 #else 146 147 #error "Error: No valid Toolchain specified" 148 149 // Symbols for Doxygen 150 151 #define OT_TOOL_PACKED_BEGIN 152 #define OT_TOOL_PACKED_FIELD 153 #define OT_TOOL_PACKED_END 154 #define OT_TOOL_WEAK 155 156 #endif 157 158 // =========== TOOLCHAIN SELECTION : END =========== 159 160 /** 161 * @def OT_UNUSED_VARIABLE 162 * 163 * Suppress unused variable warning in specific toolchains. 164 * 165 */ 166 167 /** 168 * @def OT_UNREACHABLE_CODE 169 * 170 * Suppress Unreachable code warning in specific toolchains. 171 * 172 */ 173 174 #if defined(__ICCARM__) 175 176 #include <stddef.h> 177 178 #define OT_UNUSED_VARIABLE(VARIABLE) \ 179 do \ 180 { \ 181 if (&VARIABLE == NULL) \ 182 { \ 183 } \ 184 } while (false) 185 186 #define OT_UNREACHABLE_CODE(CODE) \ 187 _Pragma("diag_suppress=Pe111") _Pragma("diag_suppress=Pe128") CODE _Pragma("diag_default=Pe111") \ 188 _Pragma("diag_default=Pe128") 189 190 #elif defined(__CC_ARM) 191 192 #include <stddef.h> 193 194 #define OT_UNUSED_VARIABLE(VARIABLE) \ 195 do \ 196 { \ 197 if (&VARIABLE == NULL) \ 198 { \ 199 } \ 200 } while (false) 201 202 #define OT_UNREACHABLE_CODE(CODE) CODE 203 204 #elif defined(__TI_ARM__) 205 206 #include <stddef.h> 207 208 #define OT_UNUSED_VARIABLE(VARIABLE) \ 209 do \ 210 { \ 211 if (&VARIABLE == NULL) \ 212 { \ 213 } \ 214 } while (false) 215 216 /* 217 * #112-D statement is unreachable 218 * #129-D loop is not reachable 219 */ 220 #define OT_UNREACHABLE_CODE(CODE) \ 221 _Pragma("diag_push") _Pragma("diag_suppress 112") _Pragma("diag_suppress 129") CODE _Pragma("diag_pop") 222 223 #else 224 225 #define OT_UNUSED_VARIABLE(VARIABLE) \ 226 do \ 227 { \ 228 (void)(VARIABLE); \ 229 } while (false) 230 231 #define OT_UNREACHABLE_CODE(CODE) CODE 232 233 #endif 234 235 /* 236 * Keil and IAR compiler doesn't provide type limits for C++. 237 */ 238 #ifdef __cplusplus 239 #if defined(__CC_ARM) || defined(__ICCARM__) 240 241 #ifndef UINT8_MAX 242 #define UINT8_MAX 0xff 243 #endif 244 245 #ifndef UINT16_MAX 246 #define UINT16_MAX 0xffff 247 #endif 248 249 #endif 250 #endif 251 252 #ifdef __APPLE__ 253 #define OT_APPLE_IGNORE_GNU_FOLDING_CONSTANT(...) \ 254 _Pragma("GCC diagnostic push") _Pragma("GCC diagnostic ignored \"-Wgnu-folding-constant\"") \ 255 __VA_ARGS__ _Pragma("GCC diagnostic pop") 256 #else 257 #define OT_APPLE_IGNORE_GNU_FOLDING_CONSTANT(...) __VA_ARGS__ 258 #endif 259 260 /** 261 * @def OT_FALL_THROUGH 262 * 263 * Suppress fall through warning in specific compiler. 264 * 265 */ 266 #if defined(__cplusplus) && (__cplusplus >= 201703L) 267 #define OT_FALL_THROUGH [[fallthrough]] 268 #elif defined(__clang__) 269 #define OT_FALL_THROUGH [[clang::fallthrough]] 270 #elif defined(__GNUC__) && (__GNUC__ >= 7) 271 #define OT_FALL_THROUGH __attribute__((fallthrough)) 272 #else 273 #define OT_FALL_THROUGH \ 274 do \ 275 { \ 276 } while (false) /* fallthrough */ 277 #endif 278 279 /** 280 * @} 281 * 282 */ 283 284 #ifdef __cplusplus 285 } // extern "C" 286 #endif 287 288 #endif // OPENTHREAD_PLATFORM_TOOLCHAIN_H_ 289