• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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