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