Line data Source code
1 1 : /*
2 : * Copyright (c) 2010-2014, Wind River Systems, Inc.
3 : *
4 : * SPDX-License-Identifier: Apache-2.0
5 : */
6 :
7 : /**
8 : * @file
9 : * @brief Macros to abstract toolchain specific capabilities
10 : *
11 : * This file contains various macros to abstract compiler capabilities that
12 : * utilize toolchain specific attributes and/or pragmas.
13 : */
14 :
15 : #ifndef ZEPHYR_INCLUDE_TOOLCHAIN_H_
16 : #define ZEPHYR_INCLUDE_TOOLCHAIN_H_
17 :
18 : /**
19 : * @def HAS_BUILTIN(x)
20 : * @brief Check if the compiler supports the built-in function \a x.
21 : *
22 : * This macro is for use with conditional compilation to enable code using a
23 : * builtin function that may not be available in every compiler.
24 : */
25 : #ifdef __has_builtin
26 : #define HAS_BUILTIN(x) __has_builtin(x)
27 : #else
28 : /*
29 : * The compiler doesn't provide the __has_builtin() macro, so instead we depend
30 : * on the toolchain-specific headers to define HAS_BUILTIN_x for the builtins
31 : * supported.
32 : */
33 1 : #define HAS_BUILTIN(x) HAS_BUILTIN_##x
34 : #endif
35 :
36 : #if defined(__TOOLCHAIN_CUSTOM__)
37 : /* This include line exists for off-tree definitions of compilers,
38 : * and therefore this header is not meant to exist in-tree
39 : */
40 : #include <toolchain/other.h>
41 : #elif defined(__XCC__)
42 : #include <zephyr/toolchain/xcc.h>
43 : #elif defined(__CCAC__)
44 : #include <zephyr/toolchain/mwdt.h>
45 : #elif defined(__ARMCOMPILER_VERSION)
46 : #include <zephyr/toolchain/armclang.h>
47 : #elif defined(__IAR_SYSTEMS_ICC__)
48 : #include <zephyr/toolchain/iar.h>
49 : #elif defined(__llvm__) || (defined(_LINKER) && defined(__LLD_LINKER_CMD__))
50 : #include <zephyr/toolchain/llvm.h>
51 : #elif defined(__GNUC__) || (defined(_LINKER) && defined(__GCC_LINKER_CMD__))
52 : #include <zephyr/toolchain/gcc.h>
53 : #else
54 : #error "Invalid/unknown toolchain configuration"
55 : #endif
56 :
57 : /**
58 : * @def __noasan
59 : * @brief Disable address sanitizer
60 : *
61 : * When used in the definition of a symbol, prevents that symbol (be it
62 : * a function or data) from being instrumented by the address
63 : * sanitizer feature of the compiler. Most commonly, this is used to
64 : * prevent padding around data that will be treated specially by the
65 : * Zephyr link (c.f. SYS_INIT records, STRUCT_SECTION_ITERABLE
66 : * definitions) in ways that don't understand the guard padding.
67 : */
68 : #ifndef __noasan
69 : #define __noasan /**/
70 : #endif
71 :
72 : /**
73 : * @def TOOLCHAIN_GCC_VERSION
74 : * @brief GCC version in xxyyzz for xx.yy.zz. Zero if not GCC compatible.
75 : */
76 : #ifndef TOOLCHAIN_GCC_VERSION
77 1 : #define TOOLCHAIN_GCC_VERSION 0
78 : #endif
79 :
80 : /**
81 : * @def TOOLCHAIN_CLANG_VERSION
82 : * @brief Clang version in xxyyzz for xx.yy.zz. Zero if not Clang compatible.
83 : */
84 : #ifndef TOOLCHAIN_CLANG_VERSION
85 1 : #define TOOLCHAIN_CLANG_VERSION 0
86 : #endif
87 :
88 : /**
89 : * @def TOOLCHAIN_HAS_PRAGMA_DIAG
90 : * @brief Indicate if toolchain supports \#pragma diagnostics.
91 : */
92 : #ifndef TOOLCHAIN_HAS_PRAGMA_DIAG
93 1 : #define TOOLCHAIN_HAS_PRAGMA_DIAG 0
94 : #endif
95 :
96 : /**
97 : * @def TOOLCHAIN_HAS_C_GENERIC
98 : * @brief Indicate if toolchain supports C Generic.
99 : */
100 : #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
101 : /* _Generic is introduced in C11, so it is supported. */
102 : # ifdef TOOLCHAIN_HAS_C_GENERIC
103 : # undef TOOLCHAIN_HAS_C_GENERIC
104 : # endif
105 : # define TOOLCHAIN_HAS_C_GENERIC 1
106 : #else
107 : # ifndef TOOLCHAIN_HAS_C_GENERIC
108 1 : # define TOOLCHAIN_HAS_C_GENERIC 0
109 : # endif
110 : #endif
111 :
112 : /**
113 : * @def TOOLCHAIN_HAS_C_AUTO_TYPE
114 : * @brief Indicate if toolchain supports C __auto_type.
115 : */
116 : #ifndef TOOLCHAIN_HAS_C_AUTO_TYPE
117 1 : #define TOOLCHAIN_HAS_C_AUTO_TYPE 0
118 : #endif
119 :
120 : /**
121 : * @def TOOLCHAIN_HAS_ZLA
122 : * @brief Indicate if toolchain supports Zero Length Arrays.
123 : */
124 : #ifndef TOOLCHAIN_HAS_ZLA
125 1 : #define TOOLCHAIN_HAS_ZLA 0
126 : #endif
127 :
128 : /**
129 : * @def TOOLCHAIN_PRAGMA
130 : * @brief Helper for using pragma in macros.
131 : */
132 : #ifdef TOOLCHAIN_HAS_PRAGMA_DIAG
133 1 : #define TOOLCHAIN_PRAGMA(x) _Pragma(#x)
134 : #else
135 : #define TOOLCHAIN_PRAGMA(x)
136 : #endif
137 :
138 : /**
139 : * @def TOOLCHAIN_WARNING_ADDRESS_OF_PACKED_MEMBER
140 : * @brief Toolchain-specific warning for taking the address of a packed member.
141 : *
142 : * Use this as an argument to the @ref TOOLCHAIN_DISABLE_WARNING and
143 : * @ref TOOLCHAIN_ENABLE_WARNING family of macros.
144 : */
145 : #ifndef TOOLCHAIN_WARNING_ADDRESS_OF_PACKED_MEMBER
146 1 : #define TOOLCHAIN_WARNING_ADDRESS_OF_PACKED_MEMBER
147 : #endif
148 :
149 : /**
150 : * @def TOOLCHAIN_WARNING_ARRAY_BOUNDS
151 : * @brief Toolchain-specific warning for array bounds violations.
152 : *
153 : * Use this as an argument to the @ref TOOLCHAIN_DISABLE_WARNING and
154 : * @ref TOOLCHAIN_ENABLE_WARNING family of macros.
155 : */
156 : #ifndef TOOLCHAIN_WARNING_ARRAY_BOUNDS
157 1 : #define TOOLCHAIN_WARNING_ARRAY_BOUNDS
158 : #endif
159 :
160 : /**
161 : * @def TOOLCHAIN_WARNING_ATTRIBUTES
162 : * @brief Toolchain-specific warning for unknown attributes.
163 : *
164 : * Use this as an argument to the @ref TOOLCHAIN_DISABLE_WARNING and
165 : * @ref TOOLCHAIN_ENABLE_WARNING family of macros.
166 : */
167 : #ifndef TOOLCHAIN_WARNING_ATTRIBUTES
168 1 : #define TOOLCHAIN_WARNING_ATTRIBUTES
169 : #endif
170 :
171 : /**
172 : * @def TOOLCHAIN_WARNING_DELETE_NON_VIRTUAL_DTOR
173 : * @brief Toolchain-specific warning for deleting a pointer to an object
174 : * with a non-virtual destructor.
175 : *
176 : * Use this as an argument to the @ref TOOLCHAIN_DISABLE_WARNING and
177 : * @ref TOOLCHAIN_ENABLE_WARNING family of macros.
178 : */
179 : #ifndef TOOLCHAIN_WARNING_DELETE_NON_VIRTUAL_DTOR
180 1 : #define TOOLCHAIN_WARNING_DELETE_NON_VIRTUAL_DTOR
181 : #endif
182 :
183 : /**
184 : * @def TOOLCHAIN_WARNING_EXTRA
185 : * @brief Toolchain-specific warning for extra warnings.
186 : *
187 : * Use this as an argument to the @ref TOOLCHAIN_DISABLE_WARNING and
188 : * @ref TOOLCHAIN_ENABLE_WARNING family of macros.
189 : */
190 : #ifndef TOOLCHAIN_WARNING_EXTRA
191 1 : #define TOOLCHAIN_WARNING_EXTRA
192 : #endif
193 :
194 : /**
195 : * @def TOOLCHAIN_WARNING_NONNULL
196 : * @brief Toolchain-specific warning for null pointer arguments to functions marked with "nonnull".
197 : *
198 : * Use this as an argument to the @ref TOOLCHAIN_DISABLE_WARNING and
199 : * @ref TOOLCHAIN_ENABLE_WARNING family of macros.
200 : */
201 : #ifndef TOOLCHAIN_WARNING_NONNULL
202 1 : #define TOOLCHAIN_WARNING_NONNULL
203 : #endif
204 :
205 : /**
206 : * @def TOOLCHAIN_WARNING_POINTER_ARITH
207 : * @brief Toolchain-specific warning for pointer arithmetic.
208 : *
209 : * Use this as an argument to the @ref TOOLCHAIN_DISABLE_WARNING and
210 : * @ref TOOLCHAIN_ENABLE_WARNING family of macros.
211 : */
212 : #ifndef TOOLCHAIN_WARNING_POINTER_ARITH
213 1 : #define TOOLCHAIN_WARNING_POINTER_ARITH
214 : #endif
215 :
216 : /**
217 : * @def TOOLCHAIN_WARNING_SHADOW
218 : * @brief Toolchain-specific warning for shadow variables.
219 : *
220 : * Use this as an argument to the @ref TOOLCHAIN_DISABLE_WARNING and
221 : * @ref TOOLCHAIN_ENABLE_WARNING family of macros.
222 : */
223 : #ifndef TOOLCHAIN_WARNING_SHADOW
224 1 : #define TOOLCHAIN_WARNING_SHADOW
225 : #endif
226 :
227 : /**
228 : * @def TOOLCHAIN_WARNING_UNUSED_LABEL
229 : * @brief Toolchain-specific warning for unused labels.
230 : *
231 : * Use this as an argument to the @ref TOOLCHAIN_DISABLE_WARNING and
232 : * @ref TOOLCHAIN_ENABLE_WARNING family of macros.
233 : */
234 : #ifndef TOOLCHAIN_WARNING_UNUSED_LABEL
235 1 : #define TOOLCHAIN_WARNING_UNUSED_LABEL
236 : #endif
237 :
238 : /**
239 : * @def TOOLCHAIN_WARNING_UNUSED_VARIABLE
240 : * @brief Toolchain-specific warning for unused variables.
241 : *
242 : * Use this as an argument to the @ref TOOLCHAIN_DISABLE_WARNING and
243 : * @ref TOOLCHAIN_ENABLE_WARNING family of macros.
244 : */
245 : #ifndef TOOLCHAIN_WARNING_UNUSED_VARIABLE
246 1 : #define TOOLCHAIN_WARNING_UNUSED_VARIABLE
247 : #endif
248 :
249 : /**
250 : * @def TOOLCHAIN_DISABLE_WARNING
251 : * @brief Disable the specified compiler warning for all compilers.
252 : */
253 : #ifndef TOOLCHAIN_DISABLE_WARNING
254 1 : #define TOOLCHAIN_DISABLE_WARNING(warning)
255 : #endif
256 :
257 : /**
258 : * @def TOOLCHAIN_ENABLE_WARNING
259 : * @brief Re-enable the specified compiler warning for all compilers.
260 : *
261 : * Can only be used after a call to @ref TOOLCHAIN_DISABLE_WARNING.
262 : */
263 : #ifndef TOOLCHAIN_ENABLE_WARNING
264 1 : #define TOOLCHAIN_ENABLE_WARNING(warning)
265 : #endif
266 :
267 : /**
268 : * @def TOOLCHAIN_DISABLE_CLANG_WARNING
269 : * @brief Disable the specified compiler warning for clang.
270 : */
271 : #ifndef TOOLCHAIN_DISABLE_CLANG_WARNING
272 1 : #define TOOLCHAIN_DISABLE_CLANG_WARNING(warning)
273 : #endif
274 :
275 : /**
276 : * @def TOOLCHAIN_ENABLE_CLANG_WARNING
277 : * @brief Re-enable the specified compiler warning for clang.
278 : *
279 : * Can only be used after a call to @ref TOOLCHAIN_DISABLE_CLANG_WARNING.
280 : */
281 : #ifndef TOOLCHAIN_ENABLE_CLANG_WARNING
282 1 : #define TOOLCHAIN_ENABLE_CLANG_WARNING(warning)
283 : #endif
284 :
285 : /**
286 : * @def TOOLCHAIN_DISABLE_GCC_WARNING
287 : * @brief Disable the specified compiler warning for gcc.
288 : */
289 : #ifndef TOOLCHAIN_DISABLE_GCC_WARNING
290 1 : #define TOOLCHAIN_DISABLE_GCC_WARNING(warning)
291 : #endif
292 :
293 : /**
294 : * @def TOOLCHAIN_ENABLE_GCC_WARNING
295 : * @brief Re-enable the specified compiler warning for gcc.
296 : *
297 : * Can only be used after a call to @ref TOOLCHAIN_DISABLE_GCC_WARNING.
298 : */
299 : #ifndef TOOLCHAIN_ENABLE_GCC_WARNING
300 1 : #define TOOLCHAIN_ENABLE_GCC_WARNING(warning)
301 : #endif
302 :
303 : /**
304 : * @def TOOLCHAIN_DISABLE_IAR_WARNING
305 : * @brief Disable the specified compiler warning for IAR compilers.
306 : */
307 : #ifndef TOOLCHAIN_DISABLE_IAR_WARNING
308 1 : #define TOOLCHAIN_DISABLE_IAR_WARNING(warning)
309 : #endif
310 :
311 : /**
312 : * @def TOOLCHAIN_ENABLE_IAR_WARNING
313 : * @brief Re-enable the specified compiler warning for IAR compilers.
314 : *
315 : * Can only be used after a call to @ref TOOLCHAIN_DISABLE_IAR_WARNING.
316 : */
317 : #ifndef TOOLCHAIN_ENABLE_IAR_WARNING
318 1 : #define TOOLCHAIN_ENABLE_IAR_WARNING(warning)
319 : #endif
320 :
321 : /*
322 : * Ensure that __BYTE_ORDER__ and related preprocessor definitions are defined,
323 : * and that they match the Kconfig option that is used in the code itself to
324 : * check for endianness.
325 : */
326 : #ifndef _LINKER
327 : #if !defined(__BYTE_ORDER__) || !defined(__ORDER_BIG_ENDIAN__) || \
328 : !defined(__ORDER_LITTLE_ENDIAN__)
329 :
330 : /*
331 : * Displaying values unfortunately requires #pragma message which can't
332 : * be taken for granted + STRINGIFY() which is not available in this .h
333 : * file.
334 : */
335 : #error "At least one byte _ORDER_ macro is not defined"
336 :
337 : #else
338 :
339 : #if (defined(CONFIG_BIG_ENDIAN) && (__BYTE_ORDER__ != __ORDER_BIG_ENDIAN__)) || \
340 : (defined(CONFIG_LITTLE_ENDIAN) && (__BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__))
341 :
342 : # error "Kconfig/toolchain endianness mismatch:"
343 :
344 : # if (__BYTE_ORDER__ != __ORDER_BIG_ENDIAN__) && (__BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__)
345 : # error "Unknown __BYTE_ORDER__ value"
346 : # else
347 : # ifdef CONFIG_BIG_ENDIAN
348 : # error "CONFIG_BIG_ENDIAN but __ORDER_LITTLE_ENDIAN__"
349 : # endif
350 : # ifdef CONFIG_LITTLE_ENDIAN
351 : # error "CONFIG_LITTLE_ENDIAN but __ORDER_BIG_ENDIAN__"
352 : # endif
353 : # endif
354 :
355 : #endif /* Endianness mismatch */
356 :
357 : #endif /* all _ORDER_ macros defined */
358 :
359 : #endif /* !_LINKER */
360 :
361 : #endif /* ZEPHYR_INCLUDE_TOOLCHAIN_H_ */
|