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 #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 #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 #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 #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 #  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 #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 #define TOOLCHAIN_HAS_ZLA 0
126 #endif
127 
128 /**
129  * @def TOOLCHAIN_IGNORE_WSHADOW_BEGIN
130  * @brief Begin of block to ignore -Wshadow.
131  *
132  * To be used inside another macro.
133  * Only for toolchain supporting _Pragma("GCC diagnostic ...").
134  */
135 #ifndef TOOLCHAIN_IGNORE_WSHADOW_BEGIN
136 #define TOOLCHAIN_IGNORE_WSHADOW_BEGIN
137 #endif
138 
139 /**
140  * @def TOOLCHAIN_IGNORE_WSHADOW_END
141  * @brief End of block to ignore -Wshadow.
142  *
143  * To be used inside another macro.
144  * Only for toolchain supporting _Pragma("GCC diagnostic ...").
145  */
146 #ifndef TOOLCHAIN_IGNORE_WSHADOW_END
147 #define TOOLCHAIN_IGNORE_WSHADOW_END
148 #endif
149 
150 /**
151  * @def TOOLCHAIN_PRAGMA
152  * @brief Helper for using pragma in macros.
153  */
154 #ifdef TOOLCHAIN_HAS_PRAGMA_DIAG
155 #define TOOLCHAIN_PRAGMA(x) _Pragma(#x)
156 #else
157 #define TOOLCHAIN_PRAGMA(x)
158 #endif
159 
160 /**
161  * @def TOOLCHAIN_WARNING_ADDRESS_OF_PACKED_MEMBER
162  * @brief Toolchain-specific warning for taking the address of a packed member.
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_ADDRESS_OF_PACKED_MEMBER
168 #define TOOLCHAIN_WARNING_ADDRESS_OF_PACKED_MEMBER
169 #endif
170 
171 /**
172  * @def TOOLCHAIN_WARNING_ARRAY_BOUNDS
173  * @brief Toolchain-specific warning for array bounds violations.
174  *
175  * Use this as an argument to the @ref TOOLCHAIN_DISABLE_WARNING and
176  * @ref TOOLCHAIN_ENABLE_WARNING family of macros.
177  */
178 #ifndef TOOLCHAIN_WARNING_ARRAY_BOUNDS
179 #define TOOLCHAIN_WARNING_ARRAY_BOUNDS
180 #endif
181 
182 /**
183  * @def TOOLCHAIN_WARNING_ATTRIBUTES
184  * @brief Toolchain-specific warning for unknown attributes.
185  *
186  * Use this as an argument to the @ref TOOLCHAIN_DISABLE_WARNING and
187  * @ref TOOLCHAIN_ENABLE_WARNING family of macros.
188  */
189 #ifndef TOOLCHAIN_WARNING_ATTRIBUTES
190 #define TOOLCHAIN_WARNING_ATTRIBUTES
191 #endif
192 
193 /**
194  * @def TOOLCHAIN_WARNING_DELETE_NON_VIRTUAL_DTOR
195  * @brief Toolchain-specific warning for deleting a pointer to an object
196  * with a non-virtual destructor.
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_DELETE_NON_VIRTUAL_DTOR
202 #define TOOLCHAIN_WARNING_DELETE_NON_VIRTUAL_DTOR
203 #endif
204 
205 /**
206  * @def TOOLCHAIN_WARNING_EXTRA
207  * @brief Toolchain-specific warning for extra warnings.
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_EXTRA
213 #define TOOLCHAIN_WARNING_EXTRA
214 #endif
215 
216 /**
217  * @def TOOLCHAIN_WARNING_NONNULL
218  * @brief Toolchain-specific warning for null pointer arguments to functions marked with "nonnull".
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_NONNULL
224 #define TOOLCHAIN_WARNING_NONNULL
225 #endif
226 
227 /**
228  * @def TOOLCHAIN_WARNING_POINTER_ARITH
229  * @brief Toolchain-specific warning for pointer arithmetic.
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_POINTER_ARITH
235 #define TOOLCHAIN_WARNING_POINTER_ARITH
236 #endif
237 
238 /**
239  * @def TOOLCHAIN_WARNING_SHADOW
240  * @brief Toolchain-specific warning for shadow 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_SHADOW
246 #define TOOLCHAIN_WARNING_SHADOW
247 #endif
248 
249 /**
250  * @def TOOLCHAIN_WARNING_UNUSED_LABEL
251  * @brief Toolchain-specific warning for unused labels.
252  *
253  * Use this as an argument to the @ref TOOLCHAIN_DISABLE_WARNING and
254  * @ref TOOLCHAIN_ENABLE_WARNING family of macros.
255  */
256 #ifndef TOOLCHAIN_WARNING_UNUSED_LABEL
257 #define TOOLCHAIN_WARNING_UNUSED_LABEL
258 #endif
259 
260 /**
261  * @def TOOLCHAIN_WARNING_UNUSED_VARIABLE
262  * @brief Toolchain-specific warning for unused variables.
263  *
264  * Use this as an argument to the @ref TOOLCHAIN_DISABLE_WARNING and
265  * @ref TOOLCHAIN_ENABLE_WARNING family of macros.
266  */
267 #ifndef TOOLCHAIN_WARNING_UNUSED_VARIABLE
268 #define TOOLCHAIN_WARNING_UNUSED_VARIABLE
269 #endif
270 
271 /**
272  * @def TOOLCHAIN_DISABLE_WARNING
273  * @brief Disable the specified compiler warning for all compilers.
274  */
275 #ifndef TOOLCHAIN_DISABLE_WARNING
276 #define TOOLCHAIN_DISABLE_WARNING(warning)
277 #endif
278 
279 /**
280  * @def TOOLCHAIN_ENABLE_WARNING
281  * @brief Re-enable the specified compiler warning for all compilers.
282  *
283  * Can only be used after a call to @ref TOOLCHAIN_DISABLE_WARNING.
284  */
285 #ifndef TOOLCHAIN_ENABLE_WARNING
286 #define TOOLCHAIN_ENABLE_WARNING(warning)
287 #endif
288 
289 /**
290  * @def TOOLCHAIN_DISABLE_CLANG_WARNING
291  * @brief Disable the specified compiler warning for clang.
292  */
293 #ifndef TOOLCHAIN_DISABLE_CLANG_WARNING
294 #define TOOLCHAIN_DISABLE_CLANG_WARNING(warning)
295 #endif
296 
297 /**
298  * @def TOOLCHAIN_ENABLE_CLANG_WARNING
299  * @brief Re-enable the specified compiler warning for clang.
300  *
301  * Can only be used after a call to @ref TOOLCHAIN_DISABLE_CLANG_WARNING.
302  */
303 #ifndef TOOLCHAIN_ENABLE_CLANG_WARNING
304 #define TOOLCHAIN_ENABLE_CLANG_WARNING(warning)
305 #endif
306 
307 /**
308  * @def TOOLCHAIN_DISABLE_GCC_WARNING
309  * @brief Disable the specified compiler warning for gcc.
310  */
311 #ifndef TOOLCHAIN_DISABLE_GCC_WARNING
312 #define TOOLCHAIN_DISABLE_GCC_WARNING(warning)
313 #endif
314 
315 /**
316  * @def TOOLCHAIN_ENABLE_GCC_WARNING
317  * @brief Re-enable the specified compiler warning for gcc.
318  *
319  * Can only be used after a call to @ref TOOLCHAIN_DISABLE_GCC_WARNING.
320  */
321 #ifndef TOOLCHAIN_ENABLE_GCC_WARNING
322 #define TOOLCHAIN_ENABLE_GCC_WARNING(warning)
323 #endif
324 
325 /*
326  * Ensure that __BYTE_ORDER__ and related preprocessor definitions are defined,
327  * and that they match the Kconfig option that is used in the code itself to
328  * check for endianness.
329  */
330 #ifndef _LINKER
331 #if !defined(__BYTE_ORDER__) || !defined(__ORDER_BIG_ENDIAN__) || \
332     !defined(__ORDER_LITTLE_ENDIAN__)
333 
334 /*
335  * Displaying values unfortunately requires #pragma message which can't
336  * be taken for granted + STRINGIFY() which is not available in this .h
337  * file.
338  */
339 #error "At least one byte _ORDER_ macro is not defined"
340 
341 #else
342 
343 #if (defined(CONFIG_BIG_ENDIAN) && (__BYTE_ORDER__ != __ORDER_BIG_ENDIAN__)) || \
344     (defined(CONFIG_LITTLE_ENDIAN) && (__BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__))
345 
346 #  error "Kconfig/toolchain endianness mismatch:"
347 
348 #  if (__BYTE_ORDER__ != __ORDER_BIG_ENDIAN__) && (__BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__)
349 #    error "Unknown __BYTE_ORDER__ value"
350 #  else
351 #    ifdef CONFIG_BIG_ENDIAN
352 #      error "CONFIG_BIG_ENDIAN but __ORDER_LITTLE_ENDIAN__"
353 #    endif
354 #    ifdef CONFIG_LITTLE_ENDIAN
355 #      error "CONFIG_LITTLE_ENDIAN but __ORDER_BIG_ENDIAN__"
356 #   endif
357 # endif
358 
359 #endif  /* Endianness mismatch */
360 
361 #endif /* all _ORDER_ macros defined */
362 
363 #endif /* !_LINKER */
364 
365 #endif /* ZEPHYR_INCLUDE_TOOLCHAIN_H_ */
366