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 = 35; // SwiftDefaultOwnership |
28 | |
29 | const uint8_t kSwiftConforms = 1; |
30 | const uint8_t kSwiftDoesNotConform = 2; |
31 | |
32 | using IdentifierID = llvm::PointerEmbeddedInt<unsigned, 31>; |
33 | using IdentifierIDField = llvm::BCVBR<16>; |
34 | |
35 | using SelectorID = llvm::PointerEmbeddedInt<unsigned, 31>; |
36 | using SelectorIDField = llvm::BCVBR<16>; |
37 | |
38 | /// The various types of blocks that can occur within a API notes file. |
39 | /// |
40 | /// These IDs must \em not be renumbered or reordered without incrementing |
41 | /// VERSION_MAJOR. |
42 | enum BlockID { |
43 | /// The control block, which contains all of the information that needs to |
44 | /// be validated prior to committing to loading the API notes file. |
45 | /// |
46 | /// \sa control_block |
47 | CONTROL_BLOCK_ID = llvm::bitc::FIRST_APPLICATION_BLOCKID, |
48 | |
49 | /// The identifier data block, which maps identifier strings to IDs. |
50 | IDENTIFIER_BLOCK_ID, |
51 | |
52 | /// The Objective-C context data block, which contains information about |
53 | /// Objective-C classes and protocols. |
54 | OBJC_CONTEXT_BLOCK_ID, |
55 | |
56 | /// The Objective-C property data block, which maps Objective-C |
57 | /// (class name, property name) pairs to information about the |
58 | /// property. |
59 | OBJC_PROPERTY_BLOCK_ID, |
60 | |
61 | /// The Objective-C property data block, which maps Objective-C |
62 | /// (class name, selector, is_instance_method) tuples to information |
63 | /// about the method. |
64 | OBJC_METHOD_BLOCK_ID, |
65 | |
66 | /// The C++ method data block, which maps C++ (context id, method name) pairs |
67 | /// to information about the method. |
68 | CXX_METHOD_BLOCK_ID, |
69 | |
70 | /// The Objective-C selector data block, which maps Objective-C |
71 | /// selector names (# of pieces, identifier IDs) to the selector ID |
72 | /// used in other tables. |
73 | OBJC_SELECTOR_BLOCK_ID, |
74 | |
75 | /// The fields data block, which maps names fields of C records to |
76 | /// information about the field. |
77 | FIELD_BLOCK_ID, |
78 | |
79 | /// The global variables data block, which maps global variable names to |
80 | /// information about the global variable. |
81 | GLOBAL_VARIABLE_BLOCK_ID, |
82 | |
83 | /// The (global) functions data block, which maps global function names to |
84 | /// information about the global function. |
85 | GLOBAL_FUNCTION_BLOCK_ID, |
86 | |
87 | /// The tag data block, which maps tag names to information about |
88 | /// the tags. |
89 | TAG_BLOCK_ID, |
90 | |
91 | /// The typedef data block, which maps typedef names to information about |
92 | /// the typedefs. |
93 | TYPEDEF_BLOCK_ID, |
94 | |
95 | /// The enum constant data block, which maps enumerator names to |
96 | /// information about the enumerators. |
97 | ENUM_CONSTANT_BLOCK_ID, |
98 | }; |
99 | |
100 | namespace control_block { |
101 | // These IDs must \em not be renumbered or reordered without incrementing |
102 | // VERSION_MAJOR. |
103 | enum { |
104 | METADATA = 1, |
105 | MODULE_NAME = 2, |
106 | MODULE_OPTIONS = 3, |
107 | SOURCE_FILE = 4, |
108 | }; |
109 | |
110 | using MetadataLayout = |
111 | llvm::BCRecordLayout<METADATA, // ID |
112 | llvm::BCFixed<16>, // Module format major version |
113 | llvm::BCFixed<16> // Module format minor version |
114 | >; |
115 | |
116 | using ModuleNameLayout = llvm::BCRecordLayout<MODULE_NAME, |
117 | llvm::BCBlob // Module name |
118 | >; |
119 | |
120 | using ModuleOptionsLayout = |
121 | llvm::BCRecordLayout<MODULE_OPTIONS, |
122 | llvm::BCFixed<1> // SwiftInferImportAsMember |
123 | >; |
124 | |
125 | using SourceFileLayout = llvm::BCRecordLayout<SOURCE_FILE, |
126 | llvm::BCVBR<16>, // file size |
127 | llvm::BCVBR<16> // creation time |
128 | >; |
129 | } // namespace control_block |
130 | |
131 | namespace identifier_block { |
132 | enum { |
133 | IDENTIFIER_DATA = 1, |
134 | }; |
135 | |
136 | using IdentifierDataLayout = llvm::BCRecordLayout< |
137 | IDENTIFIER_DATA, // record ID |
138 | llvm::BCVBR<16>, // table offset within the blob (see below) |
139 | llvm::BCBlob // map from identifier strings to decl kinds / decl IDs |
140 | >; |
141 | } // namespace identifier_block |
142 | |
143 | namespace context_block { |
144 | enum { |
145 | CONTEXT_ID_DATA = 1, |
146 | CONTEXT_INFO_DATA = 2, |
147 | }; |
148 | |
149 | using ContextIDLayout = |
150 | llvm::BCRecordLayout<CONTEXT_ID_DATA, // record ID |
151 | llvm::BCVBR<16>, // table offset within the blob (see |
152 | // below) |
153 | llvm::BCBlob // map from ObjC class names/protocol (as |
154 | // IDs) to context IDs |
155 | >; |
156 | |
157 | using ContextInfoLayout = llvm::BCRecordLayout< |
158 | CONTEXT_INFO_DATA, // record ID |
159 | llvm::BCVBR<16>, // table offset within the blob (see below) |
160 | llvm::BCBlob // map from ObjC context IDs to context information. |
161 | >; |
162 | } // namespace context_block |
163 | |
164 | namespace objc_property_block { |
165 | enum { |
166 | OBJC_PROPERTY_DATA = 1, |
167 | }; |
168 | |
169 | using ObjCPropertyDataLayout = llvm::BCRecordLayout< |
170 | OBJC_PROPERTY_DATA, // record ID |
171 | llvm::BCVBR<16>, // table offset within the blob (see below) |
172 | llvm::BCBlob // map from ObjC (class name, property name) pairs to |
173 | // ObjC property information |
174 | >; |
175 | } // namespace objc_property_block |
176 | |
177 | namespace objc_method_block { |
178 | enum { |
179 | OBJC_METHOD_DATA = 1, |
180 | }; |
181 | |
182 | using ObjCMethodDataLayout = |
183 | llvm::BCRecordLayout<OBJC_METHOD_DATA, // record ID |
184 | llvm::BCVBR<16>, // table offset within the blob (see |
185 | // below) |
186 | llvm::BCBlob // map from ObjC (class names, selector, |
187 | // is-instance-method) tuples to ObjC |
188 | // method information |
189 | >; |
190 | } // namespace objc_method_block |
191 | |
192 | namespace cxx_method_block { |
193 | enum { |
194 | CXX_METHOD_DATA = 1, |
195 | }; |
196 | |
197 | using CXXMethodDataLayout = |
198 | llvm::BCRecordLayout<CXX_METHOD_DATA, // record ID |
199 | llvm::BCVBR<16>, // table offset within the blob (see |
200 | // below) |
201 | llvm::BCBlob // map from C++ (context id, name) |
202 | // tuples to C++ method information |
203 | >; |
204 | } // namespace cxx_method_block |
205 | |
206 | namespace field_block { |
207 | enum { |
208 | FIELD_DATA = 1, |
209 | }; |
210 | |
211 | using FieldDataLayout = |
212 | llvm::BCRecordLayout<FIELD_DATA, // record ID |
213 | llvm::BCVBR<16>, // table offset within the blob (see |
214 | // below) |
215 | llvm::BCBlob // map from C (context id, name) |
216 | // tuples to C field information |
217 | >; |
218 | } // namespace field_block |
219 | |
220 | namespace objc_selector_block { |
221 | enum { |
222 | OBJC_SELECTOR_DATA = 1, |
223 | }; |
224 | |
225 | using ObjCSelectorDataLayout = |
226 | llvm::BCRecordLayout<OBJC_SELECTOR_DATA, // record ID |
227 | llvm::BCVBR<16>, // table offset within the blob (see |
228 | // below) |
229 | llvm::BCBlob // map from (# pieces, identifier IDs) to |
230 | // Objective-C selector ID. |
231 | >; |
232 | } // namespace objc_selector_block |
233 | |
234 | namespace global_variable_block { |
235 | enum { GLOBAL_VARIABLE_DATA = 1 }; |
236 | |
237 | using GlobalVariableDataLayout = llvm::BCRecordLayout< |
238 | GLOBAL_VARIABLE_DATA, // record ID |
239 | llvm::BCVBR<16>, // table offset within the blob (see below) |
240 | llvm::BCBlob // map from name to global variable information |
241 | >; |
242 | } // namespace global_variable_block |
243 | |
244 | namespace global_function_block { |
245 | enum { GLOBAL_FUNCTION_DATA = 1 }; |
246 | |
247 | using GlobalFunctionDataLayout = llvm::BCRecordLayout< |
248 | GLOBAL_FUNCTION_DATA, // record ID |
249 | llvm::BCVBR<16>, // table offset within the blob (see below) |
250 | llvm::BCBlob // map from name to global function information |
251 | >; |
252 | } // namespace global_function_block |
253 | |
254 | namespace tag_block { |
255 | enum { TAG_DATA = 1 }; |
256 | |
257 | using TagDataLayout = |
258 | llvm::BCRecordLayout<TAG_DATA, // record ID |
259 | llvm::BCVBR<16>, // table offset within the blob (see |
260 | // below) |
261 | llvm::BCBlob // map from name to tag information |
262 | >; |
263 | } // namespace tag_block |
264 | |
265 | namespace typedef_block { |
266 | enum { TYPEDEF_DATA = 1 }; |
267 | |
268 | using TypedefDataLayout = |
269 | llvm::BCRecordLayout<TYPEDEF_DATA, // record ID |
270 | llvm::BCVBR<16>, // table offset within the blob (see |
271 | // below) |
272 | llvm::BCBlob // map from name to typedef information |
273 | >; |
274 | } // namespace typedef_block |
275 | |
276 | namespace enum_constant_block { |
277 | enum { ENUM_CONSTANT_DATA = 1 }; |
278 | |
279 | using EnumConstantDataLayout = |
280 | llvm::BCRecordLayout<ENUM_CONSTANT_DATA, // record ID |
281 | llvm::BCVBR<16>, // table offset within the blob (see |
282 | // below) |
283 | llvm::BCBlob // map from name to enumerator information |
284 | >; |
285 | } // namespace enum_constant_block |
286 | |
287 | /// A stored Objective-C selector. |
288 | struct StoredObjCSelector { |
289 | unsigned NumArgs; |
290 | llvm::SmallVector<IdentifierID, 2> Identifiers; |
291 | }; |
292 | |
293 | /// A stored Objective-C or C++ context, represented by the ID of its parent |
294 | /// context, the kind of this context (Objective-C class / C++ namespace / etc), |
295 | /// and the ID of this context. |
296 | struct ContextTableKey { |
297 | uint32_t parentContextID; |
298 | uint8_t contextKind; |
299 | uint32_t contextID; |
300 | |
301 | ContextTableKey() : parentContextID(-1), contextKind(-1), contextID(-1) {} |
302 | |
303 | ContextTableKey(uint32_t parentContextID, uint8_t contextKind, |
304 | uint32_t contextID) |
305 | : parentContextID(parentContextID), contextKind(contextKind), |
306 | contextID(contextID) {} |
307 | |
308 | ContextTableKey(std::optional<ContextID> ParentContextID, ContextKind Kind, |
309 | uint32_t ContextID) |
310 | : parentContextID(ParentContextID ? ParentContextID->Value : -1), |
311 | contextKind(static_cast<uint8_t>(Kind)), contextID(ContextID) {} |
312 | |
313 | ContextTableKey(std::optional<Context> ParentContext, ContextKind Kind, |
314 | uint32_t ContextID) |
315 | : ContextTableKey(ParentContext ? std::make_optional(t&: ParentContext->id) |
316 | : std::nullopt, |
317 | Kind, ContextID) {} |
318 | |
319 | llvm::hash_code hashValue() const { |
320 | return llvm::hash_value( |
321 | arg: std::tuple{parentContextID, contextKind, contextID}); |
322 | } |
323 | }; |
324 | |
325 | inline bool operator==(const ContextTableKey &lhs, const ContextTableKey &rhs) { |
326 | return lhs.parentContextID == rhs.parentContextID && |
327 | lhs.contextKind == rhs.contextKind && lhs.contextID == rhs.contextID; |
328 | } |
329 | |
330 | /// A stored Objective-C or C++ declaration, represented by the ID of its parent |
331 | /// context, and the name of the declaration. |
332 | struct SingleDeclTableKey { |
333 | uint32_t parentContextID; |
334 | uint32_t nameID; |
335 | |
336 | SingleDeclTableKey() : parentContextID(-1), nameID(-1) {} |
337 | |
338 | SingleDeclTableKey(uint32_t ParentContextID, uint32_t NameID) |
339 | : parentContextID(ParentContextID), nameID(NameID) {} |
340 | |
341 | SingleDeclTableKey(std::optional<Context> ParentCtx, IdentifierID NameID) |
342 | : parentContextID(ParentCtx ? ParentCtx->id.Value |
343 | : static_cast<uint32_t>(-1)), |
344 | nameID(NameID) {} |
345 | |
346 | llvm::hash_code hashValue() const { |
347 | return llvm::hash_value(arg: std::make_pair(x: parentContextID, y: nameID)); |
348 | } |
349 | }; |
350 | |
351 | inline bool operator==(const SingleDeclTableKey &lhs, |
352 | const SingleDeclTableKey &rhs) { |
353 | return lhs.parentContextID == rhs.parentContextID && lhs.nameID == rhs.nameID; |
354 | } |
355 | |
356 | } // namespace api_notes |
357 | } // namespace clang |
358 | |
359 | namespace llvm { |
360 | template <> struct DenseMapInfo<clang::api_notes::StoredObjCSelector> { |
361 | typedef DenseMapInfo<unsigned> UnsignedInfo; |
362 | |
363 | static inline clang::api_notes::StoredObjCSelector getEmptyKey() { |
364 | return clang::api_notes::StoredObjCSelector{.NumArgs: UnsignedInfo::getEmptyKey(), |
365 | .Identifiers: {}}; |
366 | } |
367 | |
368 | static inline clang::api_notes::StoredObjCSelector getTombstoneKey() { |
369 | return clang::api_notes::StoredObjCSelector{.NumArgs: UnsignedInfo::getTombstoneKey(), |
370 | .Identifiers: {}}; |
371 | } |
372 | |
373 | static unsigned |
374 | getHashValue(const clang::api_notes::StoredObjCSelector &Selector) { |
375 | auto hash = llvm::hash_value(value: Selector.NumArgs); |
376 | hash = hash_combine(args: hash, args: Selector.Identifiers.size()); |
377 | for (auto piece : Selector.Identifiers) |
378 | hash = hash_combine(args: hash, args: static_cast<unsigned>(piece)); |
379 | // FIXME: Mix upper/lower 32-bit values together to produce |
380 | // unsigned rather than truncating. |
381 | return hash; |
382 | } |
383 | |
384 | static bool isEqual(const clang::api_notes::StoredObjCSelector &LHS, |
385 | const clang::api_notes::StoredObjCSelector &RHS) { |
386 | return LHS.NumArgs == RHS.NumArgs && LHS.Identifiers == RHS.Identifiers; |
387 | } |
388 | }; |
389 | |
390 | template <> struct DenseMapInfo<clang::api_notes::ContextTableKey> { |
391 | static inline clang::api_notes::ContextTableKey getEmptyKey() { |
392 | return clang::api_notes::ContextTableKey(); |
393 | } |
394 | |
395 | static inline clang::api_notes::ContextTableKey getTombstoneKey() { |
396 | return clang::api_notes::ContextTableKey{ |
397 | DenseMapInfo<uint32_t>::getTombstoneKey(), |
398 | DenseMapInfo<uint8_t>::getTombstoneKey(), |
399 | DenseMapInfo<uint32_t>::getTombstoneKey()}; |
400 | } |
401 | |
402 | static unsigned getHashValue(const clang::api_notes::ContextTableKey &value) { |
403 | return value.hashValue(); |
404 | } |
405 | |
406 | static bool isEqual(const clang::api_notes::ContextTableKey &lhs, |
407 | const clang::api_notes::ContextTableKey &rhs) { |
408 | return lhs == rhs; |
409 | } |
410 | }; |
411 | |
412 | template <> struct DenseMapInfo<clang::api_notes::SingleDeclTableKey> { |
413 | static inline clang::api_notes::SingleDeclTableKey getEmptyKey() { |
414 | return clang::api_notes::SingleDeclTableKey(); |
415 | } |
416 | |
417 | static inline clang::api_notes::SingleDeclTableKey getTombstoneKey() { |
418 | return clang::api_notes::SingleDeclTableKey{ |
419 | DenseMapInfo<uint32_t>::getTombstoneKey(), |
420 | DenseMapInfo<uint32_t>::getTombstoneKey()}; |
421 | } |
422 | |
423 | static unsigned |
424 | getHashValue(const clang::api_notes::SingleDeclTableKey &value) { |
425 | return value.hashValue(); |
426 | } |
427 | |
428 | static bool isEqual(const clang::api_notes::SingleDeclTableKey &lhs, |
429 | const clang::api_notes::SingleDeclTableKey &rhs) { |
430 | return lhs == rhs; |
431 | } |
432 | }; |
433 | |
434 | } // namespace llvm |
435 | |
436 | #endif |
437 |
Definitions
- API_NOTES_SIGNATURE
- VERSION_MAJOR
- VERSION_MINOR
- kSwiftConforms
- kSwiftDoesNotConform
- BlockID
- StoredObjCSelector
- ContextTableKey
- ContextTableKey
- ContextTableKey
- ContextTableKey
- ContextTableKey
- hashValue
- operator==
- SingleDeclTableKey
- SingleDeclTableKey
- SingleDeclTableKey
- SingleDeclTableKey
- hashValue
- operator==
- DenseMapInfo
- getEmptyKey
- getTombstoneKey
- getHashValue
- isEqual
- DenseMapInfo
- getEmptyKey
- getTombstoneKey
- getHashValue
- isEqual
- DenseMapInfo
- getEmptyKey
- getTombstoneKey
- getHashValue
Improve your Profiling and Debugging skills
Find out more