/src/llvm-project/clang/lib/APINotes/APINotesFormat.h
Line | Count | Source (jump to first uncovered line) |
1 | | //===-- APINotesWriter.h - API Notes Writer ---------------------*- C++ -*-===// |
2 | | // |
3 | | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | | // See https://llvm.org/LICENSE.txt for license information. |
5 | | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | | // |
7 | | //===----------------------------------------------------------------------===// |
8 | | |
9 | | #ifndef LLVM_CLANG_LIB_APINOTES_APINOTESFORMAT_H |
10 | | #define LLVM_CLANG_LIB_APINOTES_APINOTESFORMAT_H |
11 | | |
12 | | #include "clang/APINotes/Types.h" |
13 | | #include "llvm/ADT/PointerEmbeddedInt.h" |
14 | | #include "llvm/Bitcode/BitcodeConvenience.h" |
15 | | |
16 | | namespace clang { |
17 | | namespace api_notes { |
18 | | /// Magic number for API notes files. |
19 | | const unsigned char API_NOTES_SIGNATURE[] = {0xE2, 0x9C, 0xA8, 0x01}; |
20 | | |
21 | | /// API notes file major version number. |
22 | | const uint16_t VERSION_MAJOR = 0; |
23 | | |
24 | | /// API notes file minor version number. |
25 | | /// |
26 | | /// When the format changes IN ANY WAY, this number should be incremented. |
27 | | const uint16_t VERSION_MINOR = 25; // SwiftImportAs |
28 | | |
29 | | using IdentifierID = llvm::PointerEmbeddedInt<unsigned, 31>; |
30 | | using IdentifierIDField = llvm::BCVBR<16>; |
31 | | |
32 | | using SelectorID = llvm::PointerEmbeddedInt<unsigned, 31>; |
33 | | using SelectorIDField = llvm::BCVBR<16>; |
34 | | |
35 | | /// The various types of blocks that can occur within a API notes file. |
36 | | /// |
37 | | /// These IDs must \em not be renumbered or reordered without incrementing |
38 | | /// VERSION_MAJOR. |
39 | | enum BlockID { |
40 | | /// The control block, which contains all of the information that needs to |
41 | | /// be validated prior to committing to loading the API notes file. |
42 | | /// |
43 | | /// \sa control_block |
44 | | CONTROL_BLOCK_ID = llvm::bitc::FIRST_APPLICATION_BLOCKID, |
45 | | |
46 | | /// The identifier data block, which maps identifier strings to IDs. |
47 | | IDENTIFIER_BLOCK_ID, |
48 | | |
49 | | /// The Objective-C context data block, which contains information about |
50 | | /// Objective-C classes and protocols. |
51 | | OBJC_CONTEXT_BLOCK_ID, |
52 | | |
53 | | /// The Objective-C property data block, which maps Objective-C |
54 | | /// (class name, property name) pairs to information about the |
55 | | /// property. |
56 | | OBJC_PROPERTY_BLOCK_ID, |
57 | | |
58 | | /// The Objective-C property data block, which maps Objective-C |
59 | | /// (class name, selector, is_instance_method) tuples to information |
60 | | /// about the method. |
61 | | OBJC_METHOD_BLOCK_ID, |
62 | | |
63 | | /// The Objective-C selector data block, which maps Objective-C |
64 | | /// selector names (# of pieces, identifier IDs) to the selector ID |
65 | | /// used in other tables. |
66 | | OBJC_SELECTOR_BLOCK_ID, |
67 | | |
68 | | /// The global variables data block, which maps global variable names to |
69 | | /// information about the global variable. |
70 | | GLOBAL_VARIABLE_BLOCK_ID, |
71 | | |
72 | | /// The (global) functions data block, which maps global function names to |
73 | | /// information about the global function. |
74 | | GLOBAL_FUNCTION_BLOCK_ID, |
75 | | |
76 | | /// The tag data block, which maps tag names to information about |
77 | | /// the tags. |
78 | | TAG_BLOCK_ID, |
79 | | |
80 | | /// The typedef data block, which maps typedef names to information about |
81 | | /// the typedefs. |
82 | | TYPEDEF_BLOCK_ID, |
83 | | |
84 | | /// The enum constant data block, which maps enumerator names to |
85 | | /// information about the enumerators. |
86 | | ENUM_CONSTANT_BLOCK_ID, |
87 | | }; |
88 | | |
89 | | namespace control_block { |
90 | | // These IDs must \em not be renumbered or reordered without incrementing |
91 | | // VERSION_MAJOR. |
92 | | enum { |
93 | | METADATA = 1, |
94 | | MODULE_NAME = 2, |
95 | | MODULE_OPTIONS = 3, |
96 | | SOURCE_FILE = 4, |
97 | | }; |
98 | | |
99 | | using MetadataLayout = |
100 | | llvm::BCRecordLayout<METADATA, // ID |
101 | | llvm::BCFixed<16>, // Module format major version |
102 | | llvm::BCFixed<16> // Module format minor version |
103 | | >; |
104 | | |
105 | | using ModuleNameLayout = llvm::BCRecordLayout<MODULE_NAME, |
106 | | llvm::BCBlob // Module name |
107 | | >; |
108 | | |
109 | | using ModuleOptionsLayout = |
110 | | llvm::BCRecordLayout<MODULE_OPTIONS, |
111 | | llvm::BCFixed<1> // SwiftInferImportAsMember |
112 | | >; |
113 | | |
114 | | using SourceFileLayout = llvm::BCRecordLayout<SOURCE_FILE, |
115 | | llvm::BCVBR<16>, // file size |
116 | | llvm::BCVBR<16> // creation time |
117 | | >; |
118 | | } // namespace control_block |
119 | | |
120 | | namespace identifier_block { |
121 | | enum { |
122 | | IDENTIFIER_DATA = 1, |
123 | | }; |
124 | | |
125 | | using IdentifierDataLayout = llvm::BCRecordLayout< |
126 | | IDENTIFIER_DATA, // record ID |
127 | | llvm::BCVBR<16>, // table offset within the blob (see below) |
128 | | llvm::BCBlob // map from identifier strings to decl kinds / decl IDs |
129 | | >; |
130 | | } // namespace identifier_block |
131 | | |
132 | | namespace objc_context_block { |
133 | | enum { |
134 | | OBJC_CONTEXT_ID_DATA = 1, |
135 | | OBJC_CONTEXT_INFO_DATA = 2, |
136 | | }; |
137 | | |
138 | | using ObjCContextIDLayout = |
139 | | llvm::BCRecordLayout<OBJC_CONTEXT_ID_DATA, // record ID |
140 | | llvm::BCVBR<16>, // table offset within the blob (see |
141 | | // below) |
142 | | llvm::BCBlob // map from ObjC class names/protocol (as |
143 | | // IDs) to context IDs |
144 | | >; |
145 | | |
146 | | using ObjCContextInfoLayout = llvm::BCRecordLayout< |
147 | | OBJC_CONTEXT_INFO_DATA, // record ID |
148 | | llvm::BCVBR<16>, // table offset within the blob (see below) |
149 | | llvm::BCBlob // map from ObjC context IDs to context information. |
150 | | >; |
151 | | } // namespace objc_context_block |
152 | | |
153 | | namespace objc_property_block { |
154 | | enum { |
155 | | OBJC_PROPERTY_DATA = 1, |
156 | | }; |
157 | | |
158 | | using ObjCPropertyDataLayout = llvm::BCRecordLayout< |
159 | | OBJC_PROPERTY_DATA, // record ID |
160 | | llvm::BCVBR<16>, // table offset within the blob (see below) |
161 | | llvm::BCBlob // map from ObjC (class name, property name) pairs to |
162 | | // ObjC property information |
163 | | >; |
164 | | } // namespace objc_property_block |
165 | | |
166 | | namespace objc_method_block { |
167 | | enum { |
168 | | OBJC_METHOD_DATA = 1, |
169 | | }; |
170 | | |
171 | | using ObjCMethodDataLayout = |
172 | | llvm::BCRecordLayout<OBJC_METHOD_DATA, // record ID |
173 | | llvm::BCVBR<16>, // table offset within the blob (see |
174 | | // below) |
175 | | llvm::BCBlob // map from ObjC (class names, selector, |
176 | | // is-instance-method) tuples to ObjC |
177 | | // method information |
178 | | >; |
179 | | } // namespace objc_method_block |
180 | | |
181 | | namespace objc_selector_block { |
182 | | enum { |
183 | | OBJC_SELECTOR_DATA = 1, |
184 | | }; |
185 | | |
186 | | using ObjCSelectorDataLayout = |
187 | | llvm::BCRecordLayout<OBJC_SELECTOR_DATA, // record ID |
188 | | llvm::BCVBR<16>, // table offset within the blob (see |
189 | | // below) |
190 | | llvm::BCBlob // map from (# pieces, identifier IDs) to |
191 | | // Objective-C selector ID. |
192 | | >; |
193 | | } // namespace objc_selector_block |
194 | | |
195 | | namespace global_variable_block { |
196 | | enum { GLOBAL_VARIABLE_DATA = 1 }; |
197 | | |
198 | | using GlobalVariableDataLayout = llvm::BCRecordLayout< |
199 | | GLOBAL_VARIABLE_DATA, // record ID |
200 | | llvm::BCVBR<16>, // table offset within the blob (see below) |
201 | | llvm::BCBlob // map from name to global variable information |
202 | | >; |
203 | | } // namespace global_variable_block |
204 | | |
205 | | namespace global_function_block { |
206 | | enum { GLOBAL_FUNCTION_DATA = 1 }; |
207 | | |
208 | | using GlobalFunctionDataLayout = llvm::BCRecordLayout< |
209 | | GLOBAL_FUNCTION_DATA, // record ID |
210 | | llvm::BCVBR<16>, // table offset within the blob (see below) |
211 | | llvm::BCBlob // map from name to global function information |
212 | | >; |
213 | | } // namespace global_function_block |
214 | | |
215 | | namespace tag_block { |
216 | | enum { TAG_DATA = 1 }; |
217 | | |
218 | | using TagDataLayout = |
219 | | llvm::BCRecordLayout<TAG_DATA, // record ID |
220 | | llvm::BCVBR<16>, // table offset within the blob (see |
221 | | // below) |
222 | | llvm::BCBlob // map from name to tag information |
223 | | >; |
224 | | } // namespace tag_block |
225 | | |
226 | | namespace typedef_block { |
227 | | enum { TYPEDEF_DATA = 1 }; |
228 | | |
229 | | using TypedefDataLayout = |
230 | | llvm::BCRecordLayout<TYPEDEF_DATA, // record ID |
231 | | llvm::BCVBR<16>, // table offset within the blob (see |
232 | | // below) |
233 | | llvm::BCBlob // map from name to typedef information |
234 | | >; |
235 | | } // namespace typedef_block |
236 | | |
237 | | namespace enum_constant_block { |
238 | | enum { ENUM_CONSTANT_DATA = 1 }; |
239 | | |
240 | | using EnumConstantDataLayout = |
241 | | llvm::BCRecordLayout<ENUM_CONSTANT_DATA, // record ID |
242 | | llvm::BCVBR<16>, // table offset within the blob (see |
243 | | // below) |
244 | | llvm::BCBlob // map from name to enumerator information |
245 | | >; |
246 | | } // namespace enum_constant_block |
247 | | |
248 | | /// A stored Objective-C selector. |
249 | | struct StoredObjCSelector { |
250 | | unsigned NumArgs; |
251 | | llvm::SmallVector<IdentifierID, 2> Identifiers; |
252 | | }; |
253 | | |
254 | | /// A stored Objective-C or C++ context, represented by the ID of its parent |
255 | | /// context, the kind of this context (Objective-C class / C++ namespace / etc), |
256 | | /// and the ID of this context. |
257 | | struct ContextTableKey { |
258 | | uint32_t parentContextID; |
259 | | uint8_t contextKind; |
260 | | uint32_t contextID; |
261 | | |
262 | 0 | ContextTableKey() : parentContextID(-1), contextKind(-1), contextID(-1) {} |
263 | | |
264 | | ContextTableKey(uint32_t parentContextID, uint8_t contextKind, |
265 | | uint32_t contextID) |
266 | | : parentContextID(parentContextID), contextKind(contextKind), |
267 | 0 | contextID(contextID) {} |
268 | | |
269 | | ContextTableKey(std::optional<Context> context, IdentifierID nameID) |
270 | | : parentContextID(context ? context->id.Value : (uint32_t)-1), |
271 | | contextKind(context ? static_cast<uint8_t>(context->kind) |
272 | | : static_cast<uint8_t>(-1)), |
273 | 0 | contextID(nameID) {} |
274 | | |
275 | 0 | llvm::hash_code hashValue() const { |
276 | 0 | return llvm::hash_value( |
277 | 0 | std::tuple{parentContextID, contextKind, contextID}); |
278 | 0 | } |
279 | | }; |
280 | | |
281 | 0 | inline bool operator==(const ContextTableKey &lhs, const ContextTableKey &rhs) { |
282 | 0 | return lhs.parentContextID == rhs.parentContextID && |
283 | 0 | lhs.contextKind == rhs.contextKind && lhs.contextID == rhs.contextID; |
284 | 0 | } |
285 | | |
286 | | } // namespace api_notes |
287 | | } // namespace clang |
288 | | |
289 | | namespace llvm { |
290 | | template <> struct DenseMapInfo<clang::api_notes::StoredObjCSelector> { |
291 | | typedef DenseMapInfo<unsigned> UnsignedInfo; |
292 | | |
293 | 0 | static inline clang::api_notes::StoredObjCSelector getEmptyKey() { |
294 | 0 | return clang::api_notes::StoredObjCSelector{UnsignedInfo::getEmptyKey(), |
295 | 0 | {}}; |
296 | 0 | } |
297 | | |
298 | 0 | static inline clang::api_notes::StoredObjCSelector getTombstoneKey() { |
299 | 0 | return clang::api_notes::StoredObjCSelector{UnsignedInfo::getTombstoneKey(), |
300 | 0 | {}}; |
301 | 0 | } |
302 | | |
303 | | static unsigned |
304 | 0 | getHashValue(const clang::api_notes::StoredObjCSelector &Selector) { |
305 | 0 | auto hash = llvm::hash_value(Selector.NumArgs); |
306 | 0 | hash = hash_combine(hash, Selector.Identifiers.size()); |
307 | 0 | for (auto piece : Selector.Identifiers) |
308 | 0 | hash = hash_combine(hash, static_cast<unsigned>(piece)); |
309 | | // FIXME: Mix upper/lower 32-bit values together to produce |
310 | | // unsigned rather than truncating. |
311 | 0 | return hash; |
312 | 0 | } |
313 | | |
314 | | static bool isEqual(const clang::api_notes::StoredObjCSelector &LHS, |
315 | 0 | const clang::api_notes::StoredObjCSelector &RHS) { |
316 | 0 | return LHS.NumArgs == RHS.NumArgs && LHS.Identifiers == RHS.Identifiers; |
317 | 0 | } |
318 | | }; |
319 | | |
320 | | template <> struct DenseMapInfo<clang::api_notes::ContextTableKey> { |
321 | 0 | static inline clang::api_notes::ContextTableKey getEmptyKey() { |
322 | 0 | return clang::api_notes::ContextTableKey(); |
323 | 0 | } |
324 | | |
325 | 0 | static inline clang::api_notes::ContextTableKey getTombstoneKey() { |
326 | 0 | return clang::api_notes::ContextTableKey{ |
327 | 0 | DenseMapInfo<uint32_t>::getTombstoneKey(), |
328 | 0 | DenseMapInfo<uint8_t>::getTombstoneKey(), |
329 | 0 | DenseMapInfo<uint32_t>::getTombstoneKey()}; |
330 | 0 | } |
331 | | |
332 | 0 | static unsigned getHashValue(const clang::api_notes::ContextTableKey &value) { |
333 | 0 | return value.hashValue(); |
334 | 0 | } |
335 | | |
336 | | static bool isEqual(const clang::api_notes::ContextTableKey &lhs, |
337 | 0 | const clang::api_notes::ContextTableKey &rhs) { |
338 | 0 | return lhs == rhs; |
339 | 0 | } |
340 | | }; |
341 | | } // namespace llvm |
342 | | |
343 | | #endif |