Coverage Report

Created: 2024-01-17 10:31

/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