blob: ce2bcea5806732d5f021b553c56b9284e21ef19b [file] [log] [blame]
Doug Horn1427b6a2018-12-11 13:19:16 -08001// Copyright 2016 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Adam Barth57eacf52020-11-04 00:38:09 +00005#ifndef SYSROOT_ZIRCON_COMPILER_H_
6#define SYSROOT_ZIRCON_COMPILER_H_
7
8#ifndef __has_feature
9#define __has_feature(x) 0
10#endif
11
12#ifndef __has_cpp_attribute
13#define __has_cpp_attribute(x) 0
14#endif
Doug Horn1427b6a2018-12-11 13:19:16 -080015
16#ifndef __ASSEMBLER__
17
18#if !defined(__GNUC__) && !defined(__clang__)
19#error "Unrecognized compiler!"
20#endif
21
Adam Barth57eacf52020-11-04 00:38:09 +000022#define likely(x) __builtin_expect(!!(x), 1)
23#define unlikely(x) __builtin_expect(!!(x), 0)
Doug Horn1427b6a2018-12-11 13:19:16 -080024#define __UNUSED __attribute__((__unused__))
25#define __USED __attribute__((__used__))
26#define __PACKED __attribute__((packed))
27#define __ALIGNED(x) __attribute__((aligned(x)))
Adam Barth57eacf52020-11-04 00:38:09 +000028#define __PRINTFLIKE(__fmt, __varargs) __attribute__((__format__(__printf__, __fmt, __varargs)))
29#define __SCANFLIKE(__fmt, __varargs) __attribute__((__format__(__scanf__, __fmt, __varargs)))
Doug Horn1427b6a2018-12-11 13:19:16 -080030#define __SECTION(x) __attribute__((__section__(x)))
31#define __PURE __attribute__((__pure__))
32#define __CONST __attribute__((__const__))
33#define __NO_RETURN __attribute__((__noreturn__))
34#define __MALLOC __attribute__((__malloc__))
35#define __WEAK __attribute__((__weak__))
36#define __GNU_INLINE __attribute__((__gnu_inline__))
37#define __GET_CALLER(x) __builtin_return_address(0)
38#define __GET_FRAME(x) __builtin_frame_address(0)
39#define __NAKED __attribute__((__naked__))
40#define __ISCONSTANT(x) __builtin_constant_p(x)
41#define __NO_INLINE __attribute__((__noinline__))
42#define __SRAM __NO_INLINE __SECTION(".sram.text")
43#define __CONSTRUCTOR __attribute__((__constructor__))
44#define __DESTRUCTOR __attribute__((__destructor__))
45#define __RESTRICT __restrict
46
47#ifndef __clang__
48#define __LEAF_FN __attribute__((__leaf__))
49#define __OPTIMIZE(x) __attribute__((__optimize__(x)))
50#define __EXTERNALLY_VISIBLE __attribute__((__externally_visible__))
Doug Horn1427b6a2018-12-11 13:19:16 -080051#define __NO_SAFESTACK
Adam Barth57eacf52020-11-04 00:38:09 +000052#define __THREAD_ANNOTATION(x)
Doug Horn1427b6a2018-12-11 13:19:16 -080053#else
54#define __LEAF_FN
55#define __OPTIMIZE(x)
56#define __EXTERNALLY_VISIBLE
Adam Barth57eacf52020-11-04 00:38:09 +000057// The thread safety annotations are frequently used with C++ standard library
58// types in userspace, so only enable the annotations if we know that the C++
59// standard library types are annotated or if we're in kernel code.
60#if defined(_LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS) || defined(_KERNEL)
Doug Horn1427b6a2018-12-11 13:19:16 -080061#define __THREAD_ANNOTATION(x) __attribute__((x))
Adam Barth57eacf52020-11-04 00:38:09 +000062#else
63#define __THREAD_ANNOTATION(x)
64#endif // _LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS
65#define __NO_SAFESTACK __attribute__((__no_sanitize__("safe-stack", "shadow-call-stack")))
Doug Horn1427b6a2018-12-11 13:19:16 -080066#endif
67
68#define __ALWAYS_INLINE __attribute__((__always_inline__))
69#define __MAY_ALIAS __attribute__((__may_alias__))
70#define __NONNULL(x) __attribute__((__nonnull__ x))
71#define __WARN_UNUSED_RESULT __attribute__((__warn_unused_result__))
72#define __UNREACHABLE __builtin_unreachable()
73#define __WEAK_ALIAS(x) __attribute__((__weak__, __alias__(x)))
74#define __ALIAS(x) __attribute__((__alias__(x)))
Adam Barth57eacf52020-11-04 00:38:09 +000075#define __EXPORT __attribute__((__visibility__("default")))
76#define __LOCAL __attribute__((__visibility__("hidden")))
Doug Horn1427b6a2018-12-11 13:19:16 -080077#define __THREAD __thread
78#define __offsetof(type, field) __builtin_offsetof(type, field)
79
Adam Barth57eacf52020-11-04 00:38:09 +000080// Only define __NO_UNIQUE_ADDRESS for C++, since it doesn't make sense in C.
81#ifdef __cplusplus
82#if __has_cpp_attribute(no_unique_address)
83#define __NO_UNIQUE_ADDRESS [[no_unique_address]]
84#else
85#define __NO_UNIQUE_ADDRESS
86#endif
87#endif // ifdef __cplusplus
88
Doug Horn1427b6a2018-12-11 13:19:16 -080089#if defined(__cplusplus) && __cplusplus >= 201703L
90#define __FALLTHROUGH [[fallthrough]]
91#elif defined(__cplusplus) && defined(__clang__)
92#define __FALLTHROUGH [[clang::fallthrough]]
Adam Barth57eacf52020-11-04 00:38:09 +000093// The GNU style attribute is supported by Clang for C code, but __GNUC__ for
94// clang right now is 4.
95#elif __GNUC__ >= 7 || (!defined(__cplusplus) && defined(__clang__))
Doug Horn1427b6a2018-12-11 13:19:16 -080096#define __FALLTHROUGH __attribute__((__fallthrough__))
97#else
Adam Barth57eacf52020-11-04 00:38:09 +000098#define __FALLTHROUGH \
99 do { \
100 } while (0)
101#endif
102
103// C++17 onwards supports [[nodiscard]] on a constructor, warning if
104// a temporary object is created without a name. Such objects would be
105// immediately destroyed again, while the user's expectation might be
106// that it would last the scope.
107//
108// We could ideally just use [[nodiscard]] (or __WARN_UNUSED_RESULT)
109// directly, except GCC < 10.0 has a bug preventing it from being used
110// on constructors. __WARN_UNUSED_CONSTRUCTOR allows us to tag
111// constructors in supported compilers, and is simply ignored in older
112// compilers.
113#if defined(__cplusplus)
114// Clang and GCC versions >= 10.0 support [[nodiscard]] on constructors.
115#if __cplusplus >= 201703L && (defined(__clang__) || (defined(__GNUC__) && (__GNUC__ >= 10)))
116#define __WARN_UNUSED_CONSTRUCTOR [[nodiscard]]
117#else
118#define __WARN_UNUSED_CONSTRUCTOR
119#endif
Doug Horn1427b6a2018-12-11 13:19:16 -0800120#endif
121
122// Publicly exposed thread annotation macros. These have a long and ugly name to
123// minimize the chance of collision with consumers of Zircon's public headers.
124#define __TA_CAPABILITY(x) __THREAD_ANNOTATION(__capability__(x))
125#define __TA_GUARDED(x) __THREAD_ANNOTATION(__guarded_by__(x))
126#define __TA_ACQUIRE(...) __THREAD_ANNOTATION(__acquire_capability__(__VA_ARGS__))
Adam Barth57eacf52020-11-04 00:38:09 +0000127#define __TA_ACQUIRE_SHARED(...) __THREAD_ANNOTATION(__acquire_shared_capability__(__VA_ARGS__))
Doug Horn1427b6a2018-12-11 13:19:16 -0800128#define __TA_TRY_ACQUIRE(...) __THREAD_ANNOTATION(__try_acquire_capability__(__VA_ARGS__))
129#define __TA_ACQUIRED_BEFORE(...) __THREAD_ANNOTATION(__acquired_before__(__VA_ARGS__))
130#define __TA_ACQUIRED_AFTER(...) __THREAD_ANNOTATION(__acquired_after__(__VA_ARGS__))
131#define __TA_RELEASE(...) __THREAD_ANNOTATION(__release_capability__(__VA_ARGS__))
Adam Barth57eacf52020-11-04 00:38:09 +0000132#define __TA_RELEASE_SHARED(...) __THREAD_ANNOTATION(__release_shared_capability__(__VA_ARGS__))
Doug Horn1427b6a2018-12-11 13:19:16 -0800133#define __TA_REQUIRES(...) __THREAD_ANNOTATION(__requires_capability__(__VA_ARGS__))
Adam Barth57eacf52020-11-04 00:38:09 +0000134#define __TA_REQUIRES_SHARED(...) __THREAD_ANNOTATION(__requires_shared_capability__(__VA_ARGS__))
Doug Horn1427b6a2018-12-11 13:19:16 -0800135#define __TA_EXCLUDES(...) __THREAD_ANNOTATION(__locks_excluded__(__VA_ARGS__))
Adam Barth57eacf52020-11-04 00:38:09 +0000136#define __TA_ASSERT(...) __THREAD_ANNOTATION(__assert_capability__(__VA_ARGS__))
137#define __TA_ASSERT_SHARED(...) __THREAD_ANNOTATION(__assert_shared_capability__(__VA_ARGS__))
Doug Horn1427b6a2018-12-11 13:19:16 -0800138#define __TA_RETURN_CAPABILITY(x) __THREAD_ANNOTATION(__lock_returned__(x))
139#define __TA_SCOPED_CAPABILITY __THREAD_ANNOTATION(__scoped_lockable__)
140#define __TA_NO_THREAD_SAFETY_ANALYSIS __THREAD_ANNOTATION(__no_thread_safety_analysis__)
141
142#endif // ifndef __ASSEMBLER__
143
144#if !defined(__DEPRECATE)
145#define __DEPRECATE __attribute__((__deprecated__))
146#endif
147
148/* TODO: add type check */
149#if !defined(countof)
150#define countof(a) (sizeof(a) / sizeof((a)[0]))
151#endif
152
153/* CPP header guards */
154#ifdef __cplusplus
Adam Barth57eacf52020-11-04 00:38:09 +0000155#define __BEGIN_CDECLS extern "C" {
156#define __END_CDECLS }
Doug Horn1427b6a2018-12-11 13:19:16 -0800157#else
158#define __BEGIN_CDECLS
159#define __END_CDECLS
160#endif
161
162// constexpr annotation for use in static inlines usable in both C and C++
163#ifdef __cplusplus
164#define __CONSTEXPR constexpr
165#else
166#define __CONSTEXPR
167#endif
168
169#define add_overflow(a, b, c) __builtin_add_overflow(a, b, c)
170#define sub_overflow(a, b, c) __builtin_sub_overflow(a, b, c)
171#define mul_overflow(a, b, c) __builtin_mul_overflow(a, b, c)
Adam Barth57eacf52020-11-04 00:38:09 +0000172
173// A workaround to help static analyzer identify assertion failures
174#if defined(__clang__)
175#define __ANALYZER_CREATE_SINK __attribute__((analyzer_noreturn))
176#else
177#define __ANALYZER_CREATE_SINK // no-op
178#endif
179
180// Lifetime analysis
181#ifndef __OWNER
182#ifdef __clang__
183#define __OWNER(x) [[gsl::Owner(x)]]
184#define __POINTER(x) [[gsl::Pointer(x)]]
185#else
186#define __OWNER(x)
187#define __POINTER(x)
188#endif
189#endif
190
191#endif // SYSROOT_ZIRCON_COMPILER_H_