1 //===-- APINotesWriter.h - API Notes Writer ---------------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 #ifndef LLVM_CLANG_LIB_APINOTES_APINOTESFORMAT_H
10 #define LLVM_CLANG_LIB_APINOTES_APINOTESFORMAT_H
12 #include "clang/APINotes/Types.h"
13 #include "llvm/ADT/PointerEmbeddedInt.h"
14 #include "llvm/Bitcode/BitcodeConvenience.h"
18 /// Magic number for API notes files.
19 const unsigned char API_NOTES_SIGNATURE
[] = {0xE2, 0x9C, 0xA8, 0x01};
21 /// API notes file major version number.
22 const uint16_t VERSION_MAJOR
= 0;
24 /// API notes file minor version number.
26 /// When the format changes IN ANY WAY, this number should be incremented.
27 const uint16_t VERSION_MINOR
= 25; // SwiftImportAs
29 using IdentifierID
= llvm::PointerEmbeddedInt
<unsigned, 31>;
30 using IdentifierIDField
= llvm::BCVBR
<16>;
32 using SelectorID
= llvm::PointerEmbeddedInt
<unsigned, 31>;
33 using SelectorIDField
= llvm::BCVBR
<16>;
35 /// The various types of blocks that can occur within a API notes file.
37 /// These IDs must \em not be renumbered or reordered without incrementing
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.
44 CONTROL_BLOCK_ID
= llvm::bitc::FIRST_APPLICATION_BLOCKID
,
46 /// The identifier data block, which maps identifier strings to IDs.
49 /// The Objective-C context data block, which contains information about
50 /// Objective-C classes and protocols.
51 OBJC_CONTEXT_BLOCK_ID
,
53 /// The Objective-C property data block, which maps Objective-C
54 /// (class name, property name) pairs to information about the
56 OBJC_PROPERTY_BLOCK_ID
,
58 /// The Objective-C property data block, which maps Objective-C
59 /// (class name, selector, is_instance_method) tuples to information
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
,
68 /// The global variables data block, which maps global variable names to
69 /// information about the global variable.
70 GLOBAL_VARIABLE_BLOCK_ID
,
72 /// The (global) functions data block, which maps global function names to
73 /// information about the global function.
74 GLOBAL_FUNCTION_BLOCK_ID
,
76 /// The tag data block, which maps tag names to information about
80 /// The typedef data block, which maps typedef names to information about
84 /// The enum constant data block, which maps enumerator names to
85 /// information about the enumerators.
86 ENUM_CONSTANT_BLOCK_ID
,
89 namespace control_block
{
90 // These IDs must \em not be renumbered or reordered without incrementing
99 using MetadataLayout
=
100 llvm::BCRecordLayout
<METADATA
, // ID
101 llvm::BCFixed
<16>, // Module format major version
102 llvm::BCFixed
<16> // Module format minor version
105 using ModuleNameLayout
= llvm::BCRecordLayout
<MODULE_NAME
,
106 llvm::BCBlob
// Module name
109 using ModuleOptionsLayout
=
110 llvm::BCRecordLayout
<MODULE_OPTIONS
,
111 llvm::BCFixed
<1> // SwiftInferImportAsMember
114 using SourceFileLayout
= llvm::BCRecordLayout
<SOURCE_FILE
,
115 llvm::BCVBR
<16>, // file size
116 llvm::BCVBR
<16> // creation time
118 } // namespace control_block
120 namespace identifier_block
{
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
130 } // namespace identifier_block
132 namespace objc_context_block
{
134 OBJC_CONTEXT_ID_DATA
= 1,
135 OBJC_CONTEXT_INFO_DATA
= 2,
138 using ObjCContextIDLayout
=
139 llvm::BCRecordLayout
<OBJC_CONTEXT_ID_DATA
, // record ID
140 llvm::BCVBR
<16>, // table offset within the blob (see
142 llvm::BCBlob
// map from ObjC class names/protocol (as
143 // IDs) to context IDs
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.
151 } // namespace objc_context_block
153 namespace objc_property_block
{
155 OBJC_PROPERTY_DATA
= 1,
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
164 } // namespace objc_property_block
166 namespace objc_method_block
{
168 OBJC_METHOD_DATA
= 1,
171 using ObjCMethodDataLayout
=
172 llvm::BCRecordLayout
<OBJC_METHOD_DATA
, // record ID
173 llvm::BCVBR
<16>, // table offset within the blob (see
175 llvm::BCBlob
// map from ObjC (class names, selector,
176 // is-instance-method) tuples to ObjC
177 // method information
179 } // namespace objc_method_block
181 namespace objc_selector_block
{
183 OBJC_SELECTOR_DATA
= 1,
186 using ObjCSelectorDataLayout
=
187 llvm::BCRecordLayout
<OBJC_SELECTOR_DATA
, // record ID
188 llvm::BCVBR
<16>, // table offset within the blob (see
190 llvm::BCBlob
// map from (# pieces, identifier IDs) to
191 // Objective-C selector ID.
193 } // namespace objc_selector_block
195 namespace global_variable_block
{
196 enum { GLOBAL_VARIABLE_DATA
= 1 };
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
203 } // namespace global_variable_block
205 namespace global_function_block
{
206 enum { GLOBAL_FUNCTION_DATA
= 1 };
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
213 } // namespace global_function_block
215 namespace tag_block
{
216 enum { TAG_DATA
= 1 };
218 using TagDataLayout
=
219 llvm::BCRecordLayout
<TAG_DATA
, // record ID
220 llvm::BCVBR
<16>, // table offset within the blob (see
222 llvm::BCBlob
// map from name to tag information
224 } // namespace tag_block
226 namespace typedef_block
{
227 enum { TYPEDEF_DATA
= 1 };
229 using TypedefDataLayout
=
230 llvm::BCRecordLayout
<TYPEDEF_DATA
, // record ID
231 llvm::BCVBR
<16>, // table offset within the blob (see
233 llvm::BCBlob
// map from name to typedef information
235 } // namespace typedef_block
237 namespace enum_constant_block
{
238 enum { ENUM_CONSTANT_DATA
= 1 };
240 using EnumConstantDataLayout
=
241 llvm::BCRecordLayout
<ENUM_CONSTANT_DATA
, // record ID
242 llvm::BCVBR
<16>, // table offset within the blob (see
244 llvm::BCBlob
// map from name to enumerator information
246 } // namespace enum_constant_block
248 /// A stored Objective-C selector.
249 struct StoredObjCSelector
{
251 llvm::SmallVector
<IdentifierID
, 2> Identifiers
;
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
;
262 ContextTableKey() : parentContextID(-1), contextKind(-1), contextID(-1) {}
264 ContextTableKey(uint32_t parentContextID
, uint8_t contextKind
,
266 : parentContextID(parentContextID
), contextKind(contextKind
),
267 contextID(contextID
) {}
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)),
275 llvm::hash_code
hashValue() const {
276 return llvm::hash_value(
277 std::tuple
{parentContextID
, contextKind
, contextID
});
281 inline bool operator==(const ContextTableKey
&lhs
, const ContextTableKey
&rhs
) {
282 return lhs
.parentContextID
== rhs
.parentContextID
&&
283 lhs
.contextKind
== rhs
.contextKind
&& lhs
.contextID
== rhs
.contextID
;
286 } // namespace api_notes
290 template <> struct DenseMapInfo
<clang::api_notes::StoredObjCSelector
> {
291 typedef DenseMapInfo
<unsigned> UnsignedInfo
;
293 static inline clang::api_notes::StoredObjCSelector
getEmptyKey() {
294 return clang::api_notes::StoredObjCSelector
{UnsignedInfo::getEmptyKey(),
298 static inline clang::api_notes::StoredObjCSelector
getTombstoneKey() {
299 return clang::api_notes::StoredObjCSelector
{UnsignedInfo::getTombstoneKey(),
304 getHashValue(const clang::api_notes::StoredObjCSelector
&Selector
) {
305 auto hash
= llvm::hash_value(Selector
.NumPieces
);
306 hash
= hash_combine(hash
, Selector
.Identifiers
.size());
307 for (auto piece
: Selector
.Identifiers
)
308 hash
= hash_combine(hash
, static_cast<unsigned>(piece
));
309 // FIXME: Mix upper/lower 32-bit values together to produce
310 // unsigned rather than truncating.
314 static bool isEqual(const clang::api_notes::StoredObjCSelector
&LHS
,
315 const clang::api_notes::StoredObjCSelector
&RHS
) {
316 return LHS
.NumPieces
== RHS
.NumPieces
&& LHS
.Identifiers
== RHS
.Identifiers
;
320 template <> struct DenseMapInfo
<clang::api_notes::ContextTableKey
> {
321 static inline clang::api_notes::ContextTableKey
getEmptyKey() {
322 return clang::api_notes::ContextTableKey();
325 static inline clang::api_notes::ContextTableKey
getTombstoneKey() {
326 return clang::api_notes::ContextTableKey
{
327 DenseMapInfo
<uint32_t>::getTombstoneKey(),
328 DenseMapInfo
<uint8_t>::getTombstoneKey(),
329 DenseMapInfo
<uint32_t>::getTombstoneKey()};
332 static unsigned getHashValue(const clang::api_notes::ContextTableKey
&value
) {
333 return value
.hashValue();
336 static bool isEqual(const clang::api_notes::ContextTableKey
&lhs
,
337 const clang::api_notes::ContextTableKey
&rhs
) {