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 definiton 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