1 /* 2 * Copyright (c) Meta Platforms, Inc. and affiliates. 3 * All rights reserved. 4 * 5 * This source code is licensed under the BSD-style license found in the 6 * LICENSE file in the root directory of this source tree. 7 */ 8 9 /** 10 * @file 11 * Compiler utility macros. 12 */ 13 14 #pragma once 15 16 /* 17 * Compiler support checks. Follows the logic used by pytorch/c10/util/C++17.h 18 * but may support older versions. 19 */ 20 21 // https://gcc.gnu.org/projects/cxx-status.html#cxx17 22 #if !defined(__clang__) && !defined(_MSC_VER) && defined(__GNUC__) && \ 23 __GNUC__ < 7 24 #error \ 25 "You're trying to build ExecuTorch with a too old version of GCC. We need GCC 7 or later." 26 #endif 27 28 // https://clang.llvm.org/cxx_status.html#cxx17 29 #if defined(__clang__) && __clang_major__ < 5 30 #error \ 31 "You're trying to build ExecuTorch with a too old version of Clang. We need Clang 5 or later." 32 #endif 33 34 #if (defined(_MSC_VER) && (!defined(_MSVC_LANG) || _MSVC_LANG < 201703L)) || \ 35 (!defined(_MSC_VER) && __cplusplus < 201703L) 36 #error "You need C++17 to compile ExecuTorch" 37 #endif 38 39 #if defined(_MSC_VER) && (defined(min) || defined(max)) 40 #error \ 41 "Macro clash with min and max -- define NOMINMAX when compiling your program on Windows" 42 #endif 43 44 /* 45 * Define annotations aliasing C++ declaration attributes. 46 * See all C++ declaration attributes here: 47 * https://en.cppreference.com/w/cpp/language/attributes 48 * 49 * Note that ExecuTorch supports a lower C++ standard version than all standard 50 * attributes. Therefore, some annotations are defined using their Clang/GNU 51 * counterparts. 52 * 53 * GNU attribute definitions: 54 * https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html 55 */ 56 57 #define ET_NORETURN [[noreturn]] 58 #define ET_NOINLINE __attribute__((noinline)) 59 #define ET_INLINE __attribute__((always_inline)) inline 60 #define ET_INLINE_ATTRIBUTE __attribute__((always_inline)) 61 62 #if defined(__GNUC__) 63 64 #define ET_UNREACHABLE() __builtin_unreachable() 65 66 #elif defined(_MSC_VER) 67 68 #define ET_UNREACHABLE() __assume(0) 69 70 #else // defined(__GNUC__) 71 72 #define ET_UNREACHABLE() \ 73 while (1) \ 74 ; 75 76 #endif // defined(__GNUC__) 77 78 #define ET_DEPRECATED [[deprecated]] 79 #define ET_EXPERIMENTAL \ 80 [[deprecated("This API is experimental and may change without notice.")]] 81 #define ET_FALLTHROUGH [[fallthrough]] 82 #define ET_NODISCARD [[nodiscard]] 83 #define ET_UNUSED [[maybe_unused]] 84 85 // UNLIKELY Macro 86 // example 87 // if ET_UNLIKELY(a > 10 && b < 5) { 88 // do something 89 // } 90 #if (__cplusplus) >= 202002L 91 92 #define ET_LIKELY(expr) (expr) [[likely]] 93 #define ET_UNLIKELY(expr) (expr) [[unlikely]] 94 95 #else 96 97 #define ET_LIKELY(expr) (expr) 98 #define ET_UNLIKELY(expr) (expr) 99 100 #endif // (__cplusplus) >= 202002L 101 102 /// Define a C symbol with weak linkage. 103 #ifdef _MSC_VER 104 // There currently doesn't seem to be a great way to do this in Windows and 105 // given that weak linkage is not really critical on Windows, we'll just leave 106 // it as a stub. 107 #define ET_WEAK 108 #else 109 #define ET_WEAK __attribute__((weak)) 110 #endif 111 112 /** 113 * Annotation marking a function as printf-like, providing compiler support 114 * for format string argument checking. 115 */ 116 #ifdef _MSC_VER 117 #include <sal.h> 118 #define ET_PRINTFLIKE(_string_index, _va_index) _Printf_format_string_ 119 #else 120 #define ET_PRINTFLIKE(_string_index, _va_index) \ 121 __attribute__((format(printf, _string_index, _va_index))) 122 #endif 123 124 #ifndef __has_builtin 125 #define __has_builtin(x) (0) 126 #endif 127 128 #if __has_builtin(__builtin_strrchr) 129 /// Name of the source file without a directory string. 130 #define ET_SHORT_FILENAME (__builtin_strrchr("/" __FILE__, '/') + 1) 131 #else 132 #define ET_SHORT_FILENAME __FILE__ 133 #endif 134 135 #if __has_builtin(__builtin_LINE) 136 /// Current line as an integer. 137 #define ET_LINE __builtin_LINE() 138 #else 139 #define ET_LINE __LINE__ 140 #endif // __has_builtin(__builtin_LINE) 141 142 #if __has_builtin(__builtin_FUNCTION) 143 /// Name of the current function as a const char[]. 144 #define ET_FUNCTION __builtin_FUNCTION() 145 #else 146 #define ET_FUNCTION __FUNCTION__ 147 #endif // __has_builtin(__builtin_FUNCTION) 148 149 // Whether the compiler supports GNU statement expressions. 150 // https://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html 151 #ifndef ET_HAVE_GNU_STATEMENT_EXPRESSIONS 152 #if (defined(__GNUC__) && __GNUC__ >= 3) || defined(__clang__) 153 #define ET_HAVE_GNU_STATEMENT_EXPRESSIONS 1 154 #else 155 #define ET_HAVE_GNU_STATEMENT_EXPRESSIONS 0 156 #endif 157 #endif // ifndef 158 159 // Define size_t and ssize_t. 160 #ifndef _MSC_VER 161 #include <sys/types.h> 162 #else 163 #include <stddef.h> 164 using ssize_t = ptrdiff_t; 165 #endif 166 167 // DEPRECATED: Use the non-underscore-prefixed versions instead. 168 // TODO(T199005537): Remove these once all users have stopped using them. 169 #define __ET_DEPRECATED ET_DEPRECATED 170 #define __ET_FALLTHROUGH ET_FALLTHROUGH 171 #define __ET_FUNCTION ET_FUNCTION 172 #define __ET_HAVE_GNU_STATEMENT_EXPRESSIONS ET_HAVE_GNU_STATEMENT_EXPRESSIONS 173 #define __ET_INLINE ET_INLINE 174 #define __ET_LIKELY ET_LIKELY 175 #define __ET_LINE ET_LINE 176 #define __ET_NODISCARD ET_NODISCARD 177 #define __ET_NOINLINE ET_NOINLINE 178 #define __ET_NORETURN ET_NORETURN 179 #define __ET_PRINTFLIKE ET_PRINTFLIKE 180 #define __ET_SHORT_FILENAME ET_SHORT_FILENAME 181 #define __ET_UNLIKELY ET_UNLIKELY 182 #define __ET_UNREACHABLE ET_UNREACHABLE 183 #define __ET_UNUSED ET_UNUSED 184 #define __ET_WEAK ET_WEAK 185