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__) 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 * Ensure that __BYTE_ORDER__ and related preprocessor definitions are defined, 120 * and that they match the Kconfig option that is used in the code itself to 121 * check for endianness. 122 */ 123 #ifndef _LINKER 124 #if !defined(__BYTE_ORDER__) || !defined(__ORDER_BIG_ENDIAN__) || \ 125 !defined(__ORDER_LITTLE_ENDIAN__) 126 127 /* 128 * Displaying values unfortunately requires #pragma message which can't 129 * be taken for granted + STRINGIFY() which is not available in this .h 130 * file. 131 */ 132 #error "At least one byte _ORDER_ macro is not defined" 133 134 #else 135 136 #if (defined(CONFIG_BIG_ENDIAN) && (__BYTE_ORDER__ != __ORDER_BIG_ENDIAN__)) || \ 137 (defined(CONFIG_LITTLE_ENDIAN) && (__BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__)) 138 139 # error "Kconfig/toolchain endianness mismatch:" 140 141 # if (__BYTE_ORDER__ != __ORDER_BIG_ENDIAN__) && (__BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__) 142 # error "Unknown __BYTE_ORDER__ value" 143 # else 144 # ifdef CONFIG_BIG_ENDIAN 145 # error "CONFIG_BIG_ENDIAN but __ORDER_LITTLE_ENDIAN__" 146 # endif 147 # ifdef CONFIG_LITTLE_ENDIAN 148 # error "CONFIG_LITTLE_ENDIAN but __ORDER_BIG_ENDIAN__" 149 # endif 150 # endif 151 152 #endif /* Endianness mismatch */ 153 154 #endif /* all _ORDER_ macros defined */ 155 156 #endif /* !_LINKER */ 157 158 #endif /* ZEPHYR_INCLUDE_TOOLCHAIN_H_ */ 159