Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/clang/lib/APINotes/APINotesFormat.h
35260 views
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 = 27; // SingleDeclTableKey
28
29
const uint8_t kSwiftCopyable = 1;
30
const uint8_t kSwiftNonCopyable = 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 global variables data block, which maps global variable names to
76
/// information about the global variable.
77
GLOBAL_VARIABLE_BLOCK_ID,
78
79
/// The (global) functions data block, which maps global function names to
80
/// information about the global function.
81
GLOBAL_FUNCTION_BLOCK_ID,
82
83
/// The tag data block, which maps tag names to information about
84
/// the tags.
85
TAG_BLOCK_ID,
86
87
/// The typedef data block, which maps typedef names to information about
88
/// the typedefs.
89
TYPEDEF_BLOCK_ID,
90
91
/// The enum constant data block, which maps enumerator names to
92
/// information about the enumerators.
93
ENUM_CONSTANT_BLOCK_ID,
94
};
95
96
namespace control_block {
97
// These IDs must \em not be renumbered or reordered without incrementing
98
// VERSION_MAJOR.
99
enum {
100
METADATA = 1,
101
MODULE_NAME = 2,
102
MODULE_OPTIONS = 3,
103
SOURCE_FILE = 4,
104
};
105
106
using MetadataLayout =
107
llvm::BCRecordLayout<METADATA, // ID
108
llvm::BCFixed<16>, // Module format major version
109
llvm::BCFixed<16> // Module format minor version
110
>;
111
112
using ModuleNameLayout = llvm::BCRecordLayout<MODULE_NAME,
113
llvm::BCBlob // Module name
114
>;
115
116
using ModuleOptionsLayout =
117
llvm::BCRecordLayout<MODULE_OPTIONS,
118
llvm::BCFixed<1> // SwiftInferImportAsMember
119
>;
120
121
using SourceFileLayout = llvm::BCRecordLayout<SOURCE_FILE,
122
llvm::BCVBR<16>, // file size
123
llvm::BCVBR<16> // creation time
124
>;
125
} // namespace control_block
126
127
namespace identifier_block {
128
enum {
129
IDENTIFIER_DATA = 1,
130
};
131
132
using IdentifierDataLayout = llvm::BCRecordLayout<
133
IDENTIFIER_DATA, // record ID
134
llvm::BCVBR<16>, // table offset within the blob (see below)
135
llvm::BCBlob // map from identifier strings to decl kinds / decl IDs
136
>;
137
} // namespace identifier_block
138
139
namespace context_block {
140
enum {
141
CONTEXT_ID_DATA = 1,
142
CONTEXT_INFO_DATA = 2,
143
};
144
145
using ContextIDLayout =
146
llvm::BCRecordLayout<CONTEXT_ID_DATA, // record ID
147
llvm::BCVBR<16>, // table offset within the blob (see
148
// below)
149
llvm::BCBlob // map from ObjC class names/protocol (as
150
// IDs) to context IDs
151
>;
152
153
using ContextInfoLayout = llvm::BCRecordLayout<
154
CONTEXT_INFO_DATA, // record ID
155
llvm::BCVBR<16>, // table offset within the blob (see below)
156
llvm::BCBlob // map from ObjC context IDs to context information.
157
>;
158
} // namespace context_block
159
160
namespace objc_property_block {
161
enum {
162
OBJC_PROPERTY_DATA = 1,
163
};
164
165
using ObjCPropertyDataLayout = llvm::BCRecordLayout<
166
OBJC_PROPERTY_DATA, // record ID
167
llvm::BCVBR<16>, // table offset within the blob (see below)
168
llvm::BCBlob // map from ObjC (class name, property name) pairs to
169
// ObjC property information
170
>;
171
} // namespace objc_property_block
172
173
namespace objc_method_block {
174
enum {
175
OBJC_METHOD_DATA = 1,
176
};
177
178
using ObjCMethodDataLayout =
179
llvm::BCRecordLayout<OBJC_METHOD_DATA, // record ID
180
llvm::BCVBR<16>, // table offset within the blob (see
181
// below)
182
llvm::BCBlob // map from ObjC (class names, selector,
183
// is-instance-method) tuples to ObjC
184
// method information
185
>;
186
} // namespace objc_method_block
187
188
namespace cxx_method_block {
189
enum {
190
CXX_METHOD_DATA = 1,
191
};
192
193
using CXXMethodDataLayout =
194
llvm::BCRecordLayout<CXX_METHOD_DATA, // record ID
195
llvm::BCVBR<16>, // table offset within the blob (see
196
// below)
197
llvm::BCBlob // map from C++ (context id, name)
198
// tuples to C++ method information
199
>;
200
} // namespace cxx_method_block
201
202
namespace objc_selector_block {
203
enum {
204
OBJC_SELECTOR_DATA = 1,
205
};
206
207
using ObjCSelectorDataLayout =
208
llvm::BCRecordLayout<OBJC_SELECTOR_DATA, // record ID
209
llvm::BCVBR<16>, // table offset within the blob (see
210
// below)
211
llvm::BCBlob // map from (# pieces, identifier IDs) to
212
// Objective-C selector ID.
213
>;
214
} // namespace objc_selector_block
215
216
namespace global_variable_block {
217
enum { GLOBAL_VARIABLE_DATA = 1 };
218
219
using GlobalVariableDataLayout = llvm::BCRecordLayout<
220
GLOBAL_VARIABLE_DATA, // record ID
221
llvm::BCVBR<16>, // table offset within the blob (see below)
222
llvm::BCBlob // map from name to global variable information
223
>;
224
} // namespace global_variable_block
225
226
namespace global_function_block {
227
enum { GLOBAL_FUNCTION_DATA = 1 };
228
229
using GlobalFunctionDataLayout = llvm::BCRecordLayout<
230
GLOBAL_FUNCTION_DATA, // record ID
231
llvm::BCVBR<16>, // table offset within the blob (see below)
232
llvm::BCBlob // map from name to global function information
233
>;
234
} // namespace global_function_block
235
236
namespace tag_block {
237
enum { TAG_DATA = 1 };
238
239
using TagDataLayout =
240
llvm::BCRecordLayout<TAG_DATA, // record ID
241
llvm::BCVBR<16>, // table offset within the blob (see
242
// below)
243
llvm::BCBlob // map from name to tag information
244
>;
245
} // namespace tag_block
246
247
namespace typedef_block {
248
enum { TYPEDEF_DATA = 1 };
249
250
using TypedefDataLayout =
251
llvm::BCRecordLayout<TYPEDEF_DATA, // record ID
252
llvm::BCVBR<16>, // table offset within the blob (see
253
// below)
254
llvm::BCBlob // map from name to typedef information
255
>;
256
} // namespace typedef_block
257
258
namespace enum_constant_block {
259
enum { ENUM_CONSTANT_DATA = 1 };
260
261
using EnumConstantDataLayout =
262
llvm::BCRecordLayout<ENUM_CONSTANT_DATA, // record ID
263
llvm::BCVBR<16>, // table offset within the blob (see
264
// below)
265
llvm::BCBlob // map from name to enumerator information
266
>;
267
} // namespace enum_constant_block
268
269
/// A stored Objective-C selector.
270
struct StoredObjCSelector {
271
unsigned NumArgs;
272
llvm::SmallVector<IdentifierID, 2> Identifiers;
273
};
274
275
/// A stored Objective-C or C++ context, represented by the ID of its parent
276
/// context, the kind of this context (Objective-C class / C++ namespace / etc),
277
/// and the ID of this context.
278
struct ContextTableKey {
279
uint32_t parentContextID;
280
uint8_t contextKind;
281
uint32_t contextID;
282
283
ContextTableKey() : parentContextID(-1), contextKind(-1), contextID(-1) {}
284
285
ContextTableKey(uint32_t parentContextID, uint8_t contextKind,
286
uint32_t contextID)
287
: parentContextID(parentContextID), contextKind(contextKind),
288
contextID(contextID) {}
289
290
ContextTableKey(std::optional<ContextID> ParentContextID, ContextKind Kind,
291
uint32_t ContextID)
292
: parentContextID(ParentContextID ? ParentContextID->Value : -1),
293
contextKind(static_cast<uint8_t>(Kind)), contextID(ContextID) {}
294
295
ContextTableKey(std::optional<Context> ParentContext, ContextKind Kind,
296
uint32_t ContextID)
297
: ContextTableKey(ParentContext ? std::make_optional(ParentContext->id)
298
: std::nullopt,
299
Kind, ContextID) {}
300
301
llvm::hash_code hashValue() const {
302
return llvm::hash_value(
303
std::tuple{parentContextID, contextKind, contextID});
304
}
305
};
306
307
inline bool operator==(const ContextTableKey &lhs, const ContextTableKey &rhs) {
308
return lhs.parentContextID == rhs.parentContextID &&
309
lhs.contextKind == rhs.contextKind && lhs.contextID == rhs.contextID;
310
}
311
312
/// A stored Objective-C or C++ declaration, represented by the ID of its parent
313
/// context, and the name of the declaration.
314
struct SingleDeclTableKey {
315
uint32_t parentContextID;
316
uint32_t nameID;
317
318
SingleDeclTableKey() : parentContextID(-1), nameID(-1) {}
319
320
SingleDeclTableKey(uint32_t ParentContextID, uint32_t NameID)
321
: parentContextID(ParentContextID), nameID(NameID) {}
322
323
SingleDeclTableKey(std::optional<Context> ParentCtx, IdentifierID NameID)
324
: parentContextID(ParentCtx ? ParentCtx->id.Value
325
: static_cast<uint32_t>(-1)),
326
nameID(NameID) {}
327
328
llvm::hash_code hashValue() const {
329
return llvm::hash_value(std::make_pair(parentContextID, nameID));
330
}
331
};
332
333
inline bool operator==(const SingleDeclTableKey &lhs,
334
const SingleDeclTableKey &rhs) {
335
return lhs.parentContextID == rhs.parentContextID && lhs.nameID == rhs.nameID;
336
}
337
338
} // namespace api_notes
339
} // namespace clang
340
341
namespace llvm {
342
template <> struct DenseMapInfo<clang::api_notes::StoredObjCSelector> {
343
typedef DenseMapInfo<unsigned> UnsignedInfo;
344
345
static inline clang::api_notes::StoredObjCSelector getEmptyKey() {
346
return clang::api_notes::StoredObjCSelector{UnsignedInfo::getEmptyKey(),
347
{}};
348
}
349
350
static inline clang::api_notes::StoredObjCSelector getTombstoneKey() {
351
return clang::api_notes::StoredObjCSelector{UnsignedInfo::getTombstoneKey(),
352
{}};
353
}
354
355
static unsigned
356
getHashValue(const clang::api_notes::StoredObjCSelector &Selector) {
357
auto hash = llvm::hash_value(Selector.NumArgs);
358
hash = hash_combine(hash, Selector.Identifiers.size());
359
for (auto piece : Selector.Identifiers)
360
hash = hash_combine(hash, static_cast<unsigned>(piece));
361
// FIXME: Mix upper/lower 32-bit values together to produce
362
// unsigned rather than truncating.
363
return hash;
364
}
365
366
static bool isEqual(const clang::api_notes::StoredObjCSelector &LHS,
367
const clang::api_notes::StoredObjCSelector &RHS) {
368
return LHS.NumArgs == RHS.NumArgs && LHS.Identifiers == RHS.Identifiers;
369
}
370
};
371
372
template <> struct DenseMapInfo<clang::api_notes::ContextTableKey> {
373
static inline clang::api_notes::ContextTableKey getEmptyKey() {
374
return clang::api_notes::ContextTableKey();
375
}
376
377
static inline clang::api_notes::ContextTableKey getTombstoneKey() {
378
return clang::api_notes::ContextTableKey{
379
DenseMapInfo<uint32_t>::getTombstoneKey(),
380
DenseMapInfo<uint8_t>::getTombstoneKey(),
381
DenseMapInfo<uint32_t>::getTombstoneKey()};
382
}
383
384
static unsigned getHashValue(const clang::api_notes::ContextTableKey &value) {
385
return value.hashValue();
386
}
387
388
static bool isEqual(const clang::api_notes::ContextTableKey &lhs,
389
const clang::api_notes::ContextTableKey &rhs) {
390
return lhs == rhs;
391
}
392
};
393
394
template <> struct DenseMapInfo<clang::api_notes::SingleDeclTableKey> {
395
static inline clang::api_notes::SingleDeclTableKey getEmptyKey() {
396
return clang::api_notes::SingleDeclTableKey();
397
}
398
399
static inline clang::api_notes::SingleDeclTableKey getTombstoneKey() {
400
return clang::api_notes::SingleDeclTableKey{
401
DenseMapInfo<uint32_t>::getTombstoneKey(),
402
DenseMapInfo<uint32_t>::getTombstoneKey()};
403
}
404
405
static unsigned
406
getHashValue(const clang::api_notes::SingleDeclTableKey &value) {
407
return value.hashValue();
408
}
409
410
static bool isEqual(const clang::api_notes::SingleDeclTableKey &lhs,
411
const clang::api_notes::SingleDeclTableKey &rhs) {
412
return lhs == rhs;
413
}
414
};
415
416
} // namespace llvm
417
418
#endif
419
420