1 | /* |
2 | * Copyright 2015-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 | /** |
18 | * GCC compatible wrappers around clang attributes. |
19 | * |
20 | * @author Dominik Gabi |
21 | */ |
22 | |
23 | #pragma once |
24 | |
25 | #ifndef __has_attribute |
26 | #define FOLLY_HAS_ATTRIBUTE(x) 0 |
27 | #else |
28 | #define FOLLY_HAS_ATTRIBUTE(x) __has_attribute(x) |
29 | #endif |
30 | |
31 | #ifndef __has_cpp_attribute |
32 | #define FOLLY_HAS_CPP_ATTRIBUTE(x) 0 |
33 | #else |
34 | #define FOLLY_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x) |
35 | #endif |
36 | |
37 | #ifndef __has_extension |
38 | #define FOLLY_HAS_EXTENSION(x) 0 |
39 | #else |
40 | #define FOLLY_HAS_EXTENSION(x) __has_extension(x) |
41 | #endif |
42 | |
43 | /** |
44 | * Fallthrough to indicate that `break` was left out on purpose in a switch |
45 | * statement, e.g. |
46 | * |
47 | * switch (n) { |
48 | * case 22: |
49 | * case 33: // no warning: no statements between case labels |
50 | * f(); |
51 | * case 44: // warning: unannotated fall-through |
52 | * g(); |
53 | * FOLLY_FALLTHROUGH; // no warning: annotated fall-through |
54 | * } |
55 | */ |
56 | #if FOLLY_HAS_CPP_ATTRIBUTE(fallthrough) |
57 | #define FOLLY_FALLTHROUGH [[fallthrough]] |
58 | #elif FOLLY_HAS_CPP_ATTRIBUTE(clang::fallthrough) |
59 | #define FOLLY_FALLTHROUGH [[clang::fallthrough]] |
60 | #elif FOLLY_HAS_CPP_ATTRIBUTE(gnu::fallthrough) |
61 | #define FOLLY_FALLTHROUGH [[gnu::fallthrough]] |
62 | #else |
63 | #define FOLLY_FALLTHROUGH |
64 | #endif |
65 | |
66 | /** |
67 | * Maybe_unused indicates that a function, variable or parameter might or |
68 | * might not be used, e.g. |
69 | * |
70 | * int foo(FOLLY_MAYBE_UNUSED int x) { |
71 | * #ifdef USE_X |
72 | * return x; |
73 | * #else |
74 | * return 0; |
75 | * #endif |
76 | * } |
77 | */ |
78 | #if FOLLY_HAS_CPP_ATTRIBUTE(maybe_unused) |
79 | #define FOLLY_MAYBE_UNUSED [[maybe_unused]] |
80 | #elif FOLLY_HAS_ATTRIBUTE(__unused__) || __GNUC__ |
81 | #define FOLLY_MAYBE_UNUSED __attribute__((__unused__)) |
82 | #else |
83 | #define FOLLY_MAYBE_UNUSED |
84 | #endif |
85 | |
86 | /** |
87 | * Nullable indicates that a return value or a parameter may be a `nullptr`, |
88 | * e.g. |
89 | * |
90 | * int* FOLLY_NULLABLE foo(int* a, int* FOLLY_NULLABLE b) { |
91 | * if (*a > 0) { // safe dereference |
92 | * return nullptr; |
93 | * } |
94 | * if (*b < 0) { // unsafe dereference |
95 | * return *a; |
96 | * } |
97 | * if (b != nullptr && *b == 1) { // safe checked dereference |
98 | * return new int(1); |
99 | * } |
100 | * return nullptr; |
101 | * } |
102 | */ |
103 | #if FOLLY_HAS_EXTENSION(nullability) |
104 | #define FOLLY_NULLABLE _Nullable |
105 | #define FOLLY_NONNULL _Nonnull |
106 | #else |
107 | #define FOLLY_NULLABLE |
108 | #define FOLLY_NONNULL |
109 | #endif |
110 | |
111 | /** |
112 | * "Cold" indicates to the compiler that a function is only expected to be |
113 | * called from unlikely code paths. It can affect decisions made by the |
114 | * optimizer both when processing the function body and when analyzing |
115 | * call-sites. |
116 | */ |
117 | #if __GNUC__ |
118 | #define FOLLY_COLD __attribute__((__cold__)) |
119 | #else |
120 | #define FOLLY_COLD |
121 | #endif |
122 | |