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(__llvm__) || (defined(_LINKER) && defined(__LLD_LINKER_CMD__))
48 #include <zephyr/toolchain/llvm.h>
49 #elif defined(__GNUC__) || (defined(_LINKER) && defined(__GCC_LINKER_CMD__))
50 #include <zephyr/toolchain/gcc.h>
51 #else
52 #error "Invalid/unknown toolchain configuration"
53 #endif
54 
55 /**
56  * @def __noasan
57  * @brief Disable address sanitizer
58  *
59  * When used in the definition of a symbol, prevents that symbol (be it
60  * a function or data) from being instrumented by the address
61  * sanitizer feature of the compiler.  Most commonly, this is used to
62  * prevent padding around data that will be treated specially by the
63  * Zephyr link (c.f. SYS_INIT records, STRUCT_SECTION_ITERABLE
64  * definitions) in ways that don't understand the guard padding.
65  */
66 #ifndef __noasan
67 #define __noasan /**/
68 #endif
69 
70 /**
71  * @def TOOLCHAIN_GCC_VERSION
72  * @brief GCC version in xxyyzz for xx.yy.zz. Zero if not GCC compatible.
73  */
74 #ifndef TOOLCHAIN_GCC_VERSION
75 #define TOOLCHAIN_GCC_VERSION 0
76 #endif
77 
78 /**
79  * @def TOOLCHAIN_CLANG_VERSION
80  * @brief Clang version in xxyyzz for xx.yy.zz. Zero if not Clang compatible.
81  */
82 #ifndef TOOLCHAIN_CLANG_VERSION
83 #define TOOLCHAIN_CLANG_VERSION 0
84 #endif
85 
86 /**
87  * @def TOOLCHAIN_HAS_PRAGMA_DIAG
88  * @brief Indicate if toolchain supports \#pragma diagnostics.
89  */
90 #ifndef TOOLCHAIN_HAS_PRAGMA_DIAG
91 #define TOOLCHAIN_HAS_PRAGMA_DIAG 0
92 #endif
93 
94 /**
95  * @def TOOLCHAIN_HAS_C_GENERIC
96  * @brief Indicate if toolchain supports C Generic.
97  */
98 #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
99 /* _Generic is introduced in C11, so it is supported. */
100 # ifdef TOOLCHAIN_HAS_C_GENERIC
101 #  undef TOOLCHAIN_HAS_C_GENERIC
102 # endif
103 # define TOOLCHAIN_HAS_C_GENERIC 1
104 #else
105 # ifndef TOOLCHAIN_HAS_C_GENERIC
106 #  define TOOLCHAIN_HAS_C_GENERIC 0
107 # endif
108 #endif
109 
110 /**
111  * @def TOOLCHAIN_HAS_C_AUTO_TYPE
112  * @brief Indicate if toolchain supports C __auto_type.
113  */
114 #ifndef TOOLCHAIN_HAS_C_AUTO_TYPE
115 #define TOOLCHAIN_HAS_C_AUTO_TYPE 0
116 #endif
117 
118 /**
119  * @def TOOLCHAIN_HAS_ZLA
120  * @brief Indicate if toolchain supports Zero Length Arrays.
121  */
122 #ifndef TOOLCHAIN_HAS_ZLA
123 #define TOOLCHAIN_HAS_ZLA 0
124 #endif
125 
126 /**
127  * @def TOOLCHAIN_IGNORE_WSHADOW_BEGIN
128  * @brief Begin of block to ignore -Wshadow.
129  *
130  * To be used inside another macro.
131  * Only for toolchain supporting _Pragma("GCC diagnostic ...").
132  */
133 #ifndef TOOLCHAIN_IGNORE_WSHADOW_BEGIN
134 #define TOOLCHAIN_IGNORE_WSHADOW_BEGIN
135 #endif
136 
137 /**
138  * @def TOOLCHAIN_IGNORE_WSHADOW_END
139  * @brief End of block to ignore -Wshadow.
140  *
141  * To be used inside another macro.
142  * Only for toolchain supporting _Pragma("GCC diagnostic ...").
143  */
144 #ifndef TOOLCHAIN_IGNORE_WSHADOW_END
145 #define TOOLCHAIN_IGNORE_WSHADOW_END
146 #endif
147 
148 /*
149  * Ensure that __BYTE_ORDER__ and related preprocessor definitions are defined,
150  * and that they match the Kconfig option that is used in the code itself to
151  * check for endianness.
152  */
153 #ifndef _LINKER
154 #if !defined(__BYTE_ORDER__) || !defined(__ORDER_BIG_ENDIAN__) || \
155     !defined(__ORDER_LITTLE_ENDIAN__)
156 
157 /*
158  * Displaying values unfortunately requires #pragma message which can't
159  * be taken for granted + STRINGIFY() which is not available in this .h
160  * file.
161  */
162 #error "At least one byte _ORDER_ macro is not defined"
163 
164 #else
165 
166 #if (defined(CONFIG_BIG_ENDIAN) && (__BYTE_ORDER__ != __ORDER_BIG_ENDIAN__)) || \
167     (defined(CONFIG_LITTLE_ENDIAN) && (__BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__))
168 
169 #  error "Kconfig/toolchain endianness mismatch:"
170 
171 #  if (__BYTE_ORDER__ != __ORDER_BIG_ENDIAN__) && (__BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__)
172 #    error "Unknown __BYTE_ORDER__ value"
173 #  else
174 #    ifdef CONFIG_BIG_ENDIAN
175 #      error "CONFIG_BIG_ENDIAN but __ORDER_LITTLE_ENDIAN__"
176 #    endif
177 #    ifdef CONFIG_LITTLE_ENDIAN
178 #      error "CONFIG_LITTLE_ENDIAN but __ORDER_BIG_ENDIAN__"
179 #   endif
180 # endif
181 
182 #endif  /* Endianness mismatch */
183 
184 #endif /* all _ORDER_ macros defined */
185 
186 #endif /* !_LINKER */
187 
188 #endif /* ZEPHYR_INCLUDE_TOOLCHAIN_H_ */
189