proxygen
CPortability.h
Go to the documentation of this file.
1 /*
2  * Copyright 2013-present Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #pragma once
18 
19 /* These definitions are in a separate file so that they
20  * may be included from C- as well as C++-based projects. */
21 
23 
27 #ifndef __GNUC_PREREQ
28 #if defined __GNUC__ && defined __GNUC_MINOR__
29 /* nolint */
30 #define __GNUC_PREREQ(maj, min) \
31  ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
32 #else
33 /* nolint */
34 #define __GNUC_PREREQ(maj, min) 0
35 #endif
36 #endif
37 
38 // portable version check for clang
39 #ifndef __CLANG_PREREQ
40 #if defined __clang__ && defined __clang_major__ && defined __clang_minor__
41 /* nolint */
42 #define __CLANG_PREREQ(maj, min) \
43  ((__clang_major__ << 16) + __clang_minor__ >= ((maj) << 16) + (min))
44 #else
45 /* nolint */
46 #define __CLANG_PREREQ(maj, min) 0
47 #endif
48 #endif
49 
50 #if defined(__has_builtin)
51 #define FOLLY_HAS_BUILTIN(...) __has_builtin(__VA_ARGS__)
52 #else
53 #define FOLLY_HAS_BUILTIN(...) 0
54 #endif
55 
56 #if defined(__has_feature)
57 #define FOLLY_HAS_FEATURE(...) __has_feature(__VA_ARGS__)
58 #else
59 #define FOLLY_HAS_FEATURE(...) 0
60 #endif
61 
62 /* FOLLY_SANITIZE_ADDRESS is defined to 1 if the current compilation unit
63  * is being compiled with ASAN enabled.
64  *
65  * Beware when using this macro in a header file: this macro may change values
66  * across compilation units if some libraries are built with ASAN enabled
67  * and some built with ASAN disabled. For instance, this may occur, if folly
68  * itself was compiled without ASAN but a downstream project that uses folly is
69  * compiling with ASAN enabled.
70  *
71  * Use FOLLY_ASAN_ENABLED (defined in folly-config.h) to check if folly itself
72  * was compiled with ASAN enabled.
73  */
74 #if FOLLY_HAS_FEATURE(address_sanitizer) || __SANITIZE_ADDRESS__
75 #define FOLLY_SANITIZE_ADDRESS 1
76 #endif
77 
78 /* Define attribute wrapper for function attribute used to disable
79  * address sanitizer instrumentation. Unfortunately, this attribute
80  * has issues when inlining is used, so disable that as well. */
81 #ifdef FOLLY_SANITIZE_ADDRESS
82 #if defined(__clang__)
83 #if __has_attribute(__no_sanitize__)
84 #define FOLLY_DISABLE_ADDRESS_SANITIZER \
85  __attribute__((__no_sanitize__("address"), __noinline__))
86 #elif __has_attribute(__no_address_safety_analysis__)
87 #define FOLLY_DISABLE_ADDRESS_SANITIZER \
88  __attribute__((__no_address_safety_analysis__, __noinline__))
89 #elif __has_attribute(__no_sanitize_address__)
90 #define FOLLY_DISABLE_ADDRESS_SANITIZER \
91  __attribute__((__no_sanitize_address__, __noinline__))
92 #endif
93 #elif defined(__GNUC__)
94 #define FOLLY_DISABLE_ADDRESS_SANITIZER \
95  __attribute__((__no_address_safety_analysis__, __noinline__))
96 #endif
97 #endif
98 #ifndef FOLLY_DISABLE_ADDRESS_SANITIZER
99 #define FOLLY_DISABLE_ADDRESS_SANITIZER
100 #endif
101 
102 /* Define a convenience macro to test when thread sanitizer is being used
103  * across the different compilers (e.g. clang, gcc) */
104 #if FOLLY_HAS_FEATURE(thread_sanitizer) || __SANITIZE_THREAD__
105 #define FOLLY_SANITIZE_THREAD 1
106 #endif
107 
112 #if defined(FOLLY_SANITIZE_ADDRESS) || defined(FOLLY_SANITIZE_THREAD)
113 #define FOLLY_SANITIZE 1
114 #endif
115 
116 #if FOLLY_SANITIZE
117 #define FOLLY_DISABLE_UNDEFINED_BEHAVIOR_SANITIZER(...) \
118  __attribute__((no_sanitize(__VA_ARGS__)))
119 #else
120 #define FOLLY_DISABLE_UNDEFINED_BEHAVIOR_SANITIZER(...)
121 #endif // FOLLY_SANITIZE
122 
126 #if defined(__GNUC__)
127 #if __GNUC_PREREQ(4, 9)
128 #define FOLLY_EXPORT [[gnu::visibility("default")]]
129 #else
130 #define FOLLY_EXPORT __attribute__((__visibility__("default")))
131 #endif
132 #else
133 #define FOLLY_EXPORT
134 #endif
135 
136 // noinline
137 #ifdef _MSC_VER
138 #define FOLLY_NOINLINE __declspec(noinline)
139 #elif defined(__clang__) || defined(__GNUC__)
140 #define FOLLY_NOINLINE __attribute__((__noinline__))
141 #else
142 #define FOLLY_NOINLINE
143 #endif
144 
145 // always inline
146 #ifdef _MSC_VER
147 #define FOLLY_ALWAYS_INLINE __forceinline
148 #elif defined(__clang__) || defined(__GNUC__)
149 #define FOLLY_ALWAYS_INLINE inline __attribute__((__always_inline__))
150 #else
151 #define FOLLY_ALWAYS_INLINE inline
152 #endif
153 
154 // attribute hidden
155 #if _MSC_VER
156 #define FOLLY_ATTR_VISIBILITY_HIDDEN
157 #elif defined(__clang__) || defined(__GNUC__)
158 #define FOLLY_ATTR_VISIBILITY_HIDDEN __attribute__((__visibility__("hidden")))
159 #else
160 #define FOLLY_ATTR_VISIBILITY_HIDDEN
161 #endif
162 
163 // An attribute for marking symbols as weak, if supported
164 #if FOLLY_HAVE_WEAK_SYMBOLS
165 #define FOLLY_ATTR_WEAK __attribute__((__weak__))
166 #else
167 #define FOLLY_ATTR_WEAK
168 #endif
169 
170 // Microsoft ABI version (can be overridden manually if necessary)
171 #ifndef FOLLY_MICROSOFT_ABI_VER
172 #ifdef _MSC_VER
173 #define FOLLY_MICROSOFT_ABI_VER _MSC_VER
174 #endif
175 #endif