/src/openthread/include/openthread/platform/toolchain.h
Line | Count | Source (jump to first uncovered line) |
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 | | * This macro specifies that a function or method takes `printf` style arguments and should be type-checked against |
117 | | * a format string. |
118 | | * |
119 | | * This macro 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 | 17.2M | do \ |
254 | 17.2M | { \ |
255 | 17.2M | (void)(VARIABLE); \ |
256 | 17.2M | } while (false) |
257 | | |
258 | 0 | #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 | 17.2k | #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_ |