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
16namespace clang {
17namespace api_notes {
18/// Magic number for API notes files.
19const unsigned char API_NOTES_SIGNATURE[] = {0xE2, 0x9C, 0xA8, 0x01};
20
21/// API notes file major version number.
22const 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.
27const uint16_t VERSION_MINOR = 35; // SwiftDefaultOwnership
28
29const uint8_t kSwiftConforms = 1;
30const uint8_t kSwiftDoesNotConform = 2;
31
32using IdentifierID = llvm::PointerEmbeddedInt<unsigned, 31>;
33using IdentifierIDField = llvm::BCVBR<16>;
34
35using SelectorID = llvm::PointerEmbeddedInt<unsigned, 31>;
36using 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.
42enum 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
100namespace control_block {
101// These IDs must \em not be renumbered or reordered without incrementing
102// VERSION_MAJOR.
103enum {
104 METADATA = 1,
105 MODULE_NAME = 2,
106 MODULE_OPTIONS = 3,
107 SOURCE_FILE = 4,
108};
109
110using MetadataLayout =
111 llvm::BCRecordLayout<METADATA, // ID
112 llvm::BCFixed<16>, // Module format major version
113 llvm::BCFixed<16> // Module format minor version
114 >;
115
116using ModuleNameLayout = llvm::BCRecordLayout<MODULE_NAME,
117 llvm::BCBlob // Module name
118 >;
119
120using ModuleOptionsLayout =
121 llvm::BCRecordLayout<MODULE_OPTIONS,
122 llvm::BCFixed<1> // SwiftInferImportAsMember
123 >;
124
125using SourceFileLayout = llvm::BCRecordLayout<SOURCE_FILE,
126 llvm::BCVBR<16>, // file size
127 llvm::BCVBR<16> // creation time
128 >;
129} // namespace control_block
130
131namespace identifier_block {
132enum {
133 IDENTIFIER_DATA = 1,
134};
135
136using 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
143namespace context_block {
144enum {
145 CONTEXT_ID_DATA = 1,
146 CONTEXT_INFO_DATA = 2,
147};
148
149using 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
157using 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
164namespace objc_property_block {
165enum {
166 OBJC_PROPERTY_DATA = 1,
167};
168
169using 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
177namespace objc_method_block {
178enum {
179 OBJC_METHOD_DATA = 1,
180};
181
182using 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
192namespace cxx_method_block {
193enum {
194 CXX_METHOD_DATA = 1,
195};
196
197using 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
206namespace field_block {
207enum {
208 FIELD_DATA = 1,
209};
210
211using 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
220namespace objc_selector_block {
221enum {
222 OBJC_SELECTOR_DATA = 1,
223};
224
225using 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
234namespace global_variable_block {
235enum { GLOBAL_VARIABLE_DATA = 1 };
236
237using 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
244namespace global_function_block {
245enum { GLOBAL_FUNCTION_DATA = 1 };
246
247using 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
254namespace tag_block {
255enum { TAG_DATA = 1 };
256
257using 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
265namespace typedef_block {
266enum { TYPEDEF_DATA = 1 };
267
268using 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
276namespace enum_constant_block {
277enum { ENUM_CONSTANT_DATA = 1 };
278
279using 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.
288struct 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.
296struct 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
325inline 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.
332struct 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
351inline 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
359namespace llvm {
360template <> 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
390template <> 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
412template <> 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

Provided by KDAB

Privacy Policy
Improve your Profiling and Debugging skills
Find out more

source code of clang/lib/APINotes/APINotesFormat.h