xref: /aosp_15_r20/external/executorch/runtime/platform/compiler.h (revision 523fa7a60841cd1ecfb9cc4201f1ca8b03ed023a)
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