xref: /freebsd-src/contrib/llvm-project/clang/lib/APINotes/APINotesFormat.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1e8d8bef9SDimitry Andric //===-- APINotesWriter.h - API Notes Writer ---------------------*- C++ -*-===//
2e8d8bef9SDimitry Andric //
3e8d8bef9SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e8d8bef9SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5e8d8bef9SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6e8d8bef9SDimitry Andric //
7e8d8bef9SDimitry Andric //===----------------------------------------------------------------------===//
8e8d8bef9SDimitry Andric 
9e8d8bef9SDimitry Andric #ifndef LLVM_CLANG_LIB_APINOTES_APINOTESFORMAT_H
10e8d8bef9SDimitry Andric #define LLVM_CLANG_LIB_APINOTES_APINOTESFORMAT_H
11e8d8bef9SDimitry Andric 
125f757f3fSDimitry Andric #include "clang/APINotes/Types.h"
13e8d8bef9SDimitry Andric #include "llvm/ADT/PointerEmbeddedInt.h"
14e8d8bef9SDimitry Andric #include "llvm/Bitcode/BitcodeConvenience.h"
15e8d8bef9SDimitry Andric 
16e8d8bef9SDimitry Andric namespace clang {
17e8d8bef9SDimitry Andric namespace api_notes {
18e8d8bef9SDimitry Andric /// Magic number for API notes files.
19e8d8bef9SDimitry Andric const unsigned char API_NOTES_SIGNATURE[] = {0xE2, 0x9C, 0xA8, 0x01};
20e8d8bef9SDimitry Andric 
21e8d8bef9SDimitry Andric /// API notes file major version number.
22e8d8bef9SDimitry Andric const uint16_t VERSION_MAJOR = 0;
23e8d8bef9SDimitry Andric 
24e8d8bef9SDimitry Andric /// API notes file minor version number.
25e8d8bef9SDimitry Andric ///
26e8d8bef9SDimitry Andric /// When the format changes IN ANY WAY, this number should be incremented.
27*0fca6ea1SDimitry Andric const uint16_t VERSION_MINOR = 27; // SingleDeclTableKey
28*0fca6ea1SDimitry Andric 
29*0fca6ea1SDimitry Andric const uint8_t kSwiftCopyable = 1;
30*0fca6ea1SDimitry Andric const uint8_t kSwiftNonCopyable = 2;
31e8d8bef9SDimitry Andric 
32e8d8bef9SDimitry Andric using IdentifierID = llvm::PointerEmbeddedInt<unsigned, 31>;
33e8d8bef9SDimitry Andric using IdentifierIDField = llvm::BCVBR<16>;
34e8d8bef9SDimitry Andric 
35e8d8bef9SDimitry Andric using SelectorID = llvm::PointerEmbeddedInt<unsigned, 31>;
36e8d8bef9SDimitry Andric using SelectorIDField = llvm::BCVBR<16>;
37e8d8bef9SDimitry Andric 
38e8d8bef9SDimitry Andric /// The various types of blocks that can occur within a API notes file.
39e8d8bef9SDimitry Andric ///
40e8d8bef9SDimitry Andric /// These IDs must \em not be renumbered or reordered without incrementing
41e8d8bef9SDimitry Andric /// VERSION_MAJOR.
42e8d8bef9SDimitry Andric enum BlockID {
43e8d8bef9SDimitry Andric   /// The control block, which contains all of the information that needs to
44e8d8bef9SDimitry Andric   /// be validated prior to committing to loading the API notes file.
45e8d8bef9SDimitry Andric   ///
46e8d8bef9SDimitry Andric   /// \sa control_block
47e8d8bef9SDimitry Andric   CONTROL_BLOCK_ID = llvm::bitc::FIRST_APPLICATION_BLOCKID,
48e8d8bef9SDimitry Andric 
49e8d8bef9SDimitry Andric   /// The identifier data block, which maps identifier strings to IDs.
50e8d8bef9SDimitry Andric   IDENTIFIER_BLOCK_ID,
51e8d8bef9SDimitry Andric 
52e8d8bef9SDimitry Andric   /// The Objective-C context data block, which contains information about
53e8d8bef9SDimitry Andric   /// Objective-C classes and protocols.
54e8d8bef9SDimitry Andric   OBJC_CONTEXT_BLOCK_ID,
55e8d8bef9SDimitry Andric 
56e8d8bef9SDimitry Andric   /// The Objective-C property data block, which maps Objective-C
57e8d8bef9SDimitry Andric   /// (class name, property name) pairs to information about the
58e8d8bef9SDimitry Andric   /// property.
59e8d8bef9SDimitry Andric   OBJC_PROPERTY_BLOCK_ID,
60e8d8bef9SDimitry Andric 
61e8d8bef9SDimitry Andric   /// The Objective-C property data block, which maps Objective-C
62e8d8bef9SDimitry Andric   /// (class name, selector, is_instance_method) tuples to information
63e8d8bef9SDimitry Andric   /// about the method.
64e8d8bef9SDimitry Andric   OBJC_METHOD_BLOCK_ID,
65e8d8bef9SDimitry Andric 
66*0fca6ea1SDimitry Andric   /// The C++ method data block, which maps C++ (context id, method name) pairs
67*0fca6ea1SDimitry Andric   /// to information about the method.
68*0fca6ea1SDimitry Andric   CXX_METHOD_BLOCK_ID,
69*0fca6ea1SDimitry Andric 
70e8d8bef9SDimitry Andric   /// The Objective-C selector data block, which maps Objective-C
71e8d8bef9SDimitry Andric   /// selector names (# of pieces, identifier IDs) to the selector ID
72e8d8bef9SDimitry Andric   /// used in other tables.
73e8d8bef9SDimitry Andric   OBJC_SELECTOR_BLOCK_ID,
74e8d8bef9SDimitry Andric 
75e8d8bef9SDimitry Andric   /// The global variables data block, which maps global variable names to
76e8d8bef9SDimitry Andric   /// information about the global variable.
77e8d8bef9SDimitry Andric   GLOBAL_VARIABLE_BLOCK_ID,
78e8d8bef9SDimitry Andric 
79e8d8bef9SDimitry Andric   /// The (global) functions data block, which maps global function names to
80e8d8bef9SDimitry Andric   /// information about the global function.
81e8d8bef9SDimitry Andric   GLOBAL_FUNCTION_BLOCK_ID,
82e8d8bef9SDimitry Andric 
83e8d8bef9SDimitry Andric   /// The tag data block, which maps tag names to information about
84e8d8bef9SDimitry Andric   /// the tags.
85e8d8bef9SDimitry Andric   TAG_BLOCK_ID,
86e8d8bef9SDimitry Andric 
87e8d8bef9SDimitry Andric   /// The typedef data block, which maps typedef names to information about
88e8d8bef9SDimitry Andric   /// the typedefs.
89e8d8bef9SDimitry Andric   TYPEDEF_BLOCK_ID,
90e8d8bef9SDimitry Andric 
91e8d8bef9SDimitry Andric   /// The enum constant data block, which maps enumerator names to
92e8d8bef9SDimitry Andric   /// information about the enumerators.
93e8d8bef9SDimitry Andric   ENUM_CONSTANT_BLOCK_ID,
94e8d8bef9SDimitry Andric };
95e8d8bef9SDimitry Andric 
96e8d8bef9SDimitry Andric namespace control_block {
97e8d8bef9SDimitry Andric // These IDs must \em not be renumbered or reordered without incrementing
98e8d8bef9SDimitry Andric // VERSION_MAJOR.
99e8d8bef9SDimitry Andric enum {
100e8d8bef9SDimitry Andric   METADATA = 1,
101e8d8bef9SDimitry Andric   MODULE_NAME = 2,
102e8d8bef9SDimitry Andric   MODULE_OPTIONS = 3,
103e8d8bef9SDimitry Andric   SOURCE_FILE = 4,
104e8d8bef9SDimitry Andric };
105e8d8bef9SDimitry Andric 
106e8d8bef9SDimitry Andric using MetadataLayout =
107e8d8bef9SDimitry Andric     llvm::BCRecordLayout<METADATA,          // ID
108e8d8bef9SDimitry Andric                          llvm::BCFixed<16>, // Module format major version
109e8d8bef9SDimitry Andric                          llvm::BCFixed<16>  // Module format minor version
110e8d8bef9SDimitry Andric                          >;
111e8d8bef9SDimitry Andric 
112e8d8bef9SDimitry Andric using ModuleNameLayout = llvm::BCRecordLayout<MODULE_NAME,
113e8d8bef9SDimitry Andric                                               llvm::BCBlob // Module name
114e8d8bef9SDimitry Andric                                               >;
115e8d8bef9SDimitry Andric 
116e8d8bef9SDimitry Andric using ModuleOptionsLayout =
117e8d8bef9SDimitry Andric     llvm::BCRecordLayout<MODULE_OPTIONS,
118e8d8bef9SDimitry Andric                          llvm::BCFixed<1> // SwiftInferImportAsMember
119e8d8bef9SDimitry Andric                          >;
120e8d8bef9SDimitry Andric 
121e8d8bef9SDimitry Andric using SourceFileLayout = llvm::BCRecordLayout<SOURCE_FILE,
122e8d8bef9SDimitry Andric                                               llvm::BCVBR<16>, // file size
123e8d8bef9SDimitry Andric                                               llvm::BCVBR<16>  // creation time
124e8d8bef9SDimitry Andric                                               >;
125e8d8bef9SDimitry Andric } // namespace control_block
126e8d8bef9SDimitry Andric 
127e8d8bef9SDimitry Andric namespace identifier_block {
128e8d8bef9SDimitry Andric enum {
129e8d8bef9SDimitry Andric   IDENTIFIER_DATA = 1,
130e8d8bef9SDimitry Andric };
131e8d8bef9SDimitry Andric 
132e8d8bef9SDimitry Andric using IdentifierDataLayout = llvm::BCRecordLayout<
133e8d8bef9SDimitry Andric     IDENTIFIER_DATA, // record ID
134e8d8bef9SDimitry Andric     llvm::BCVBR<16>, // table offset within the blob (see below)
135e8d8bef9SDimitry Andric     llvm::BCBlob     // map from identifier strings to decl kinds / decl IDs
136e8d8bef9SDimitry Andric     >;
137e8d8bef9SDimitry Andric } // namespace identifier_block
138e8d8bef9SDimitry Andric 
139*0fca6ea1SDimitry Andric namespace context_block {
140e8d8bef9SDimitry Andric enum {
141*0fca6ea1SDimitry Andric   CONTEXT_ID_DATA = 1,
142*0fca6ea1SDimitry Andric   CONTEXT_INFO_DATA = 2,
143e8d8bef9SDimitry Andric };
144e8d8bef9SDimitry Andric 
145*0fca6ea1SDimitry Andric using ContextIDLayout =
146*0fca6ea1SDimitry Andric     llvm::BCRecordLayout<CONTEXT_ID_DATA, // record ID
147e8d8bef9SDimitry Andric                          llvm::BCVBR<16>, // table offset within the blob (see
148e8d8bef9SDimitry Andric                                           // below)
149e8d8bef9SDimitry Andric                          llvm::BCBlob // map from ObjC class names/protocol (as
150e8d8bef9SDimitry Andric                                       // IDs) to context IDs
151e8d8bef9SDimitry Andric                          >;
152e8d8bef9SDimitry Andric 
153*0fca6ea1SDimitry Andric using ContextInfoLayout = llvm::BCRecordLayout<
154*0fca6ea1SDimitry Andric     CONTEXT_INFO_DATA, // record ID
155e8d8bef9SDimitry Andric     llvm::BCVBR<16>,   // table offset within the blob (see below)
156e8d8bef9SDimitry Andric     llvm::BCBlob       // map from ObjC context IDs to context information.
157e8d8bef9SDimitry Andric     >;
158*0fca6ea1SDimitry Andric } // namespace context_block
159e8d8bef9SDimitry Andric 
160e8d8bef9SDimitry Andric namespace objc_property_block {
161e8d8bef9SDimitry Andric enum {
162e8d8bef9SDimitry Andric   OBJC_PROPERTY_DATA = 1,
163e8d8bef9SDimitry Andric };
164e8d8bef9SDimitry Andric 
165e8d8bef9SDimitry Andric using ObjCPropertyDataLayout = llvm::BCRecordLayout<
166e8d8bef9SDimitry Andric     OBJC_PROPERTY_DATA, // record ID
167e8d8bef9SDimitry Andric     llvm::BCVBR<16>,    // table offset within the blob (see below)
168e8d8bef9SDimitry Andric     llvm::BCBlob        // map from ObjC (class name, property name) pairs to
169e8d8bef9SDimitry Andric                         // ObjC property information
170e8d8bef9SDimitry Andric     >;
171e8d8bef9SDimitry Andric } // namespace objc_property_block
172e8d8bef9SDimitry Andric 
173e8d8bef9SDimitry Andric namespace objc_method_block {
174e8d8bef9SDimitry Andric enum {
175e8d8bef9SDimitry Andric   OBJC_METHOD_DATA = 1,
176e8d8bef9SDimitry Andric };
177e8d8bef9SDimitry Andric 
178e8d8bef9SDimitry Andric using ObjCMethodDataLayout =
179e8d8bef9SDimitry Andric     llvm::BCRecordLayout<OBJC_METHOD_DATA, // record ID
180e8d8bef9SDimitry Andric                          llvm::BCVBR<16>,  // table offset within the blob (see
181e8d8bef9SDimitry Andric                                            // below)
182e8d8bef9SDimitry Andric                          llvm::BCBlob // map from ObjC (class names, selector,
183e8d8bef9SDimitry Andric                                       // is-instance-method) tuples to ObjC
184e8d8bef9SDimitry Andric                                       // method information
185e8d8bef9SDimitry Andric                          >;
186e8d8bef9SDimitry Andric } // namespace objc_method_block
187e8d8bef9SDimitry Andric 
188*0fca6ea1SDimitry Andric namespace cxx_method_block {
189*0fca6ea1SDimitry Andric enum {
190*0fca6ea1SDimitry Andric   CXX_METHOD_DATA = 1,
191*0fca6ea1SDimitry Andric };
192*0fca6ea1SDimitry Andric 
193*0fca6ea1SDimitry Andric using CXXMethodDataLayout =
194*0fca6ea1SDimitry Andric     llvm::BCRecordLayout<CXX_METHOD_DATA, // record ID
195*0fca6ea1SDimitry Andric                          llvm::BCVBR<16>, // table offset within the blob (see
196*0fca6ea1SDimitry Andric                                           // below)
197*0fca6ea1SDimitry Andric                          llvm::BCBlob     // map from C++ (context id, name)
198*0fca6ea1SDimitry Andric                                           // tuples to C++ method information
199*0fca6ea1SDimitry Andric                          >;
200*0fca6ea1SDimitry Andric } // namespace cxx_method_block
201*0fca6ea1SDimitry Andric 
202e8d8bef9SDimitry Andric namespace objc_selector_block {
203e8d8bef9SDimitry Andric enum {
204e8d8bef9SDimitry Andric   OBJC_SELECTOR_DATA = 1,
205e8d8bef9SDimitry Andric };
206e8d8bef9SDimitry Andric 
207e8d8bef9SDimitry Andric using ObjCSelectorDataLayout =
208e8d8bef9SDimitry Andric     llvm::BCRecordLayout<OBJC_SELECTOR_DATA, // record ID
209e8d8bef9SDimitry Andric                          llvm::BCVBR<16>, // table offset within the blob (see
210e8d8bef9SDimitry Andric                                           // below)
211e8d8bef9SDimitry Andric                          llvm::BCBlob // map from (# pieces, identifier IDs) to
212e8d8bef9SDimitry Andric                                       // Objective-C selector ID.
213e8d8bef9SDimitry Andric                          >;
214e8d8bef9SDimitry Andric } // namespace objc_selector_block
215e8d8bef9SDimitry Andric 
216e8d8bef9SDimitry Andric namespace global_variable_block {
217e8d8bef9SDimitry Andric enum { GLOBAL_VARIABLE_DATA = 1 };
218e8d8bef9SDimitry Andric 
219e8d8bef9SDimitry Andric using GlobalVariableDataLayout = llvm::BCRecordLayout<
220e8d8bef9SDimitry Andric     GLOBAL_VARIABLE_DATA, // record ID
221e8d8bef9SDimitry Andric     llvm::BCVBR<16>,      // table offset within the blob (see below)
222e8d8bef9SDimitry Andric     llvm::BCBlob          // map from name to global variable information
223e8d8bef9SDimitry Andric     >;
224e8d8bef9SDimitry Andric } // namespace global_variable_block
225e8d8bef9SDimitry Andric 
226e8d8bef9SDimitry Andric namespace global_function_block {
227e8d8bef9SDimitry Andric enum { GLOBAL_FUNCTION_DATA = 1 };
228e8d8bef9SDimitry Andric 
229e8d8bef9SDimitry Andric using GlobalFunctionDataLayout = llvm::BCRecordLayout<
230e8d8bef9SDimitry Andric     GLOBAL_FUNCTION_DATA, // record ID
231e8d8bef9SDimitry Andric     llvm::BCVBR<16>,      // table offset within the blob (see below)
232e8d8bef9SDimitry Andric     llvm::BCBlob          // map from name to global function information
233e8d8bef9SDimitry Andric     >;
234e8d8bef9SDimitry Andric } // namespace global_function_block
235e8d8bef9SDimitry Andric 
236e8d8bef9SDimitry Andric namespace tag_block {
237e8d8bef9SDimitry Andric enum { TAG_DATA = 1 };
238e8d8bef9SDimitry Andric 
239e8d8bef9SDimitry Andric using TagDataLayout =
240e8d8bef9SDimitry Andric     llvm::BCRecordLayout<TAG_DATA,        // record ID
241e8d8bef9SDimitry Andric                          llvm::BCVBR<16>, // table offset within the blob (see
242e8d8bef9SDimitry Andric                                           // below)
243e8d8bef9SDimitry Andric                          llvm::BCBlob     // map from name to tag information
244e8d8bef9SDimitry Andric                          >;
24506c3fb27SDimitry Andric } // namespace tag_block
246e8d8bef9SDimitry Andric 
247e8d8bef9SDimitry Andric namespace typedef_block {
248e8d8bef9SDimitry Andric enum { TYPEDEF_DATA = 1 };
249e8d8bef9SDimitry Andric 
250e8d8bef9SDimitry Andric using TypedefDataLayout =
251e8d8bef9SDimitry Andric     llvm::BCRecordLayout<TYPEDEF_DATA,    // record ID
252e8d8bef9SDimitry Andric                          llvm::BCVBR<16>, // table offset within the blob (see
253e8d8bef9SDimitry Andric                                           // below)
254e8d8bef9SDimitry Andric                          llvm::BCBlob // map from name to typedef information
255e8d8bef9SDimitry Andric                          >;
25606c3fb27SDimitry Andric } // namespace typedef_block
257e8d8bef9SDimitry Andric 
258e8d8bef9SDimitry Andric namespace enum_constant_block {
259e8d8bef9SDimitry Andric enum { ENUM_CONSTANT_DATA = 1 };
260e8d8bef9SDimitry Andric 
261e8d8bef9SDimitry Andric using EnumConstantDataLayout =
262e8d8bef9SDimitry Andric     llvm::BCRecordLayout<ENUM_CONSTANT_DATA, // record ID
263e8d8bef9SDimitry Andric                          llvm::BCVBR<16>, // table offset within the blob (see
264e8d8bef9SDimitry Andric                                           // below)
265e8d8bef9SDimitry Andric                          llvm::BCBlob // map from name to enumerator information
266e8d8bef9SDimitry Andric                          >;
267e8d8bef9SDimitry Andric } // namespace enum_constant_block
268e8d8bef9SDimitry Andric 
269e8d8bef9SDimitry Andric /// A stored Objective-C selector.
270e8d8bef9SDimitry Andric struct StoredObjCSelector {
2715f757f3fSDimitry Andric   unsigned NumArgs;
272e8d8bef9SDimitry Andric   llvm::SmallVector<IdentifierID, 2> Identifiers;
273e8d8bef9SDimitry Andric };
2745f757f3fSDimitry Andric 
2755f757f3fSDimitry Andric /// A stored Objective-C or C++ context, represented by the ID of its parent
2765f757f3fSDimitry Andric /// context, the kind of this context (Objective-C class / C++ namespace / etc),
2775f757f3fSDimitry Andric /// and the ID of this context.
2785f757f3fSDimitry Andric struct ContextTableKey {
2795f757f3fSDimitry Andric   uint32_t parentContextID;
2805f757f3fSDimitry Andric   uint8_t contextKind;
2815f757f3fSDimitry Andric   uint32_t contextID;
2825f757f3fSDimitry Andric 
2835f757f3fSDimitry Andric   ContextTableKey() : parentContextID(-1), contextKind(-1), contextID(-1) {}
2845f757f3fSDimitry Andric 
2855f757f3fSDimitry Andric   ContextTableKey(uint32_t parentContextID, uint8_t contextKind,
2865f757f3fSDimitry Andric                   uint32_t contextID)
2875f757f3fSDimitry Andric       : parentContextID(parentContextID), contextKind(contextKind),
2885f757f3fSDimitry Andric         contextID(contextID) {}
2895f757f3fSDimitry Andric 
290*0fca6ea1SDimitry Andric   ContextTableKey(std::optional<ContextID> ParentContextID, ContextKind Kind,
291*0fca6ea1SDimitry Andric                   uint32_t ContextID)
292*0fca6ea1SDimitry Andric       : parentContextID(ParentContextID ? ParentContextID->Value : -1),
293*0fca6ea1SDimitry Andric         contextKind(static_cast<uint8_t>(Kind)), contextID(ContextID) {}
294*0fca6ea1SDimitry Andric 
295*0fca6ea1SDimitry Andric   ContextTableKey(std::optional<Context> ParentContext, ContextKind Kind,
296*0fca6ea1SDimitry Andric                   uint32_t ContextID)
297*0fca6ea1SDimitry Andric       : ContextTableKey(ParentContext ? std::make_optional(ParentContext->id)
298*0fca6ea1SDimitry Andric                                       : std::nullopt,
299*0fca6ea1SDimitry Andric                         Kind, ContextID) {}
3005f757f3fSDimitry Andric 
3015f757f3fSDimitry Andric   llvm::hash_code hashValue() const {
3025f757f3fSDimitry Andric     return llvm::hash_value(
3035f757f3fSDimitry Andric         std::tuple{parentContextID, contextKind, contextID});
3045f757f3fSDimitry Andric   }
3055f757f3fSDimitry Andric };
3065f757f3fSDimitry Andric 
3075f757f3fSDimitry Andric inline bool operator==(const ContextTableKey &lhs, const ContextTableKey &rhs) {
3085f757f3fSDimitry Andric   return lhs.parentContextID == rhs.parentContextID &&
3095f757f3fSDimitry Andric          lhs.contextKind == rhs.contextKind && lhs.contextID == rhs.contextID;
3105f757f3fSDimitry Andric }
3115f757f3fSDimitry Andric 
312*0fca6ea1SDimitry Andric /// A stored Objective-C or C++ declaration, represented by the ID of its parent
313*0fca6ea1SDimitry Andric /// context, and the name of the declaration.
314*0fca6ea1SDimitry Andric struct SingleDeclTableKey {
315*0fca6ea1SDimitry Andric   uint32_t parentContextID;
316*0fca6ea1SDimitry Andric   uint32_t nameID;
317*0fca6ea1SDimitry Andric 
318*0fca6ea1SDimitry Andric   SingleDeclTableKey() : parentContextID(-1), nameID(-1) {}
319*0fca6ea1SDimitry Andric 
320*0fca6ea1SDimitry Andric   SingleDeclTableKey(uint32_t ParentContextID, uint32_t NameID)
321*0fca6ea1SDimitry Andric       : parentContextID(ParentContextID), nameID(NameID) {}
322*0fca6ea1SDimitry Andric 
323*0fca6ea1SDimitry Andric   SingleDeclTableKey(std::optional<Context> ParentCtx, IdentifierID NameID)
324*0fca6ea1SDimitry Andric       : parentContextID(ParentCtx ? ParentCtx->id.Value
325*0fca6ea1SDimitry Andric                                   : static_cast<uint32_t>(-1)),
326*0fca6ea1SDimitry Andric         nameID(NameID) {}
327*0fca6ea1SDimitry Andric 
328*0fca6ea1SDimitry Andric   llvm::hash_code hashValue() const {
329*0fca6ea1SDimitry Andric     return llvm::hash_value(std::make_pair(parentContextID, nameID));
330*0fca6ea1SDimitry Andric   }
331*0fca6ea1SDimitry Andric };
332*0fca6ea1SDimitry Andric 
333*0fca6ea1SDimitry Andric inline bool operator==(const SingleDeclTableKey &lhs,
334*0fca6ea1SDimitry Andric                        const SingleDeclTableKey &rhs) {
335*0fca6ea1SDimitry Andric   return lhs.parentContextID == rhs.parentContextID && lhs.nameID == rhs.nameID;
336*0fca6ea1SDimitry Andric }
337*0fca6ea1SDimitry Andric 
338e8d8bef9SDimitry Andric } // namespace api_notes
339e8d8bef9SDimitry Andric } // namespace clang
340e8d8bef9SDimitry Andric 
3415f757f3fSDimitry Andric namespace llvm {
3425f757f3fSDimitry Andric template <> struct DenseMapInfo<clang::api_notes::StoredObjCSelector> {
3435f757f3fSDimitry Andric   typedef DenseMapInfo<unsigned> UnsignedInfo;
3445f757f3fSDimitry Andric 
3455f757f3fSDimitry Andric   static inline clang::api_notes::StoredObjCSelector getEmptyKey() {
3465f757f3fSDimitry Andric     return clang::api_notes::StoredObjCSelector{UnsignedInfo::getEmptyKey(),
3475f757f3fSDimitry Andric                                                 {}};
3485f757f3fSDimitry Andric   }
3495f757f3fSDimitry Andric 
3505f757f3fSDimitry Andric   static inline clang::api_notes::StoredObjCSelector getTombstoneKey() {
3515f757f3fSDimitry Andric     return clang::api_notes::StoredObjCSelector{UnsignedInfo::getTombstoneKey(),
3525f757f3fSDimitry Andric                                                 {}};
3535f757f3fSDimitry Andric   }
3545f757f3fSDimitry Andric 
3555f757f3fSDimitry Andric   static unsigned
3565f757f3fSDimitry Andric   getHashValue(const clang::api_notes::StoredObjCSelector &Selector) {
3575f757f3fSDimitry Andric     auto hash = llvm::hash_value(Selector.NumArgs);
3585f757f3fSDimitry Andric     hash = hash_combine(hash, Selector.Identifiers.size());
3595f757f3fSDimitry Andric     for (auto piece : Selector.Identifiers)
3605f757f3fSDimitry Andric       hash = hash_combine(hash, static_cast<unsigned>(piece));
3615f757f3fSDimitry Andric     // FIXME: Mix upper/lower 32-bit values together to produce
3625f757f3fSDimitry Andric     // unsigned rather than truncating.
3635f757f3fSDimitry Andric     return hash;
3645f757f3fSDimitry Andric   }
3655f757f3fSDimitry Andric 
3665f757f3fSDimitry Andric   static bool isEqual(const clang::api_notes::StoredObjCSelector &LHS,
3675f757f3fSDimitry Andric                       const clang::api_notes::StoredObjCSelector &RHS) {
3685f757f3fSDimitry Andric     return LHS.NumArgs == RHS.NumArgs && LHS.Identifiers == RHS.Identifiers;
3695f757f3fSDimitry Andric   }
3705f757f3fSDimitry Andric };
3715f757f3fSDimitry Andric 
3725f757f3fSDimitry Andric template <> struct DenseMapInfo<clang::api_notes::ContextTableKey> {
3735f757f3fSDimitry Andric   static inline clang::api_notes::ContextTableKey getEmptyKey() {
3745f757f3fSDimitry Andric     return clang::api_notes::ContextTableKey();
3755f757f3fSDimitry Andric   }
3765f757f3fSDimitry Andric 
3775f757f3fSDimitry Andric   static inline clang::api_notes::ContextTableKey getTombstoneKey() {
3785f757f3fSDimitry Andric     return clang::api_notes::ContextTableKey{
3795f757f3fSDimitry Andric         DenseMapInfo<uint32_t>::getTombstoneKey(),
3805f757f3fSDimitry Andric         DenseMapInfo<uint8_t>::getTombstoneKey(),
3815f757f3fSDimitry Andric         DenseMapInfo<uint32_t>::getTombstoneKey()};
3825f757f3fSDimitry Andric   }
3835f757f3fSDimitry Andric 
3845f757f3fSDimitry Andric   static unsigned getHashValue(const clang::api_notes::ContextTableKey &value) {
3855f757f3fSDimitry Andric     return value.hashValue();
3865f757f3fSDimitry Andric   }
3875f757f3fSDimitry Andric 
3885f757f3fSDimitry Andric   static bool isEqual(const clang::api_notes::ContextTableKey &lhs,
3895f757f3fSDimitry Andric                       const clang::api_notes::ContextTableKey &rhs) {
3905f757f3fSDimitry Andric     return lhs == rhs;
3915f757f3fSDimitry Andric   }
3925f757f3fSDimitry Andric };
393*0fca6ea1SDimitry Andric 
394*0fca6ea1SDimitry Andric template <> struct DenseMapInfo<clang::api_notes::SingleDeclTableKey> {
395*0fca6ea1SDimitry Andric   static inline clang::api_notes::SingleDeclTableKey getEmptyKey() {
396*0fca6ea1SDimitry Andric     return clang::api_notes::SingleDeclTableKey();
397*0fca6ea1SDimitry Andric   }
398*0fca6ea1SDimitry Andric 
399*0fca6ea1SDimitry Andric   static inline clang::api_notes::SingleDeclTableKey getTombstoneKey() {
400*0fca6ea1SDimitry Andric     return clang::api_notes::SingleDeclTableKey{
401*0fca6ea1SDimitry Andric         DenseMapInfo<uint32_t>::getTombstoneKey(),
402*0fca6ea1SDimitry Andric         DenseMapInfo<uint32_t>::getTombstoneKey()};
403*0fca6ea1SDimitry Andric   }
404*0fca6ea1SDimitry Andric 
405*0fca6ea1SDimitry Andric   static unsigned
406*0fca6ea1SDimitry Andric   getHashValue(const clang::api_notes::SingleDeclTableKey &value) {
407*0fca6ea1SDimitry Andric     return value.hashValue();
408*0fca6ea1SDimitry Andric   }
409*0fca6ea1SDimitry Andric 
410*0fca6ea1SDimitry Andric   static bool isEqual(const clang::api_notes::SingleDeclTableKey &lhs,
411*0fca6ea1SDimitry Andric                       const clang::api_notes::SingleDeclTableKey &rhs) {
412*0fca6ea1SDimitry Andric     return lhs == rhs;
413*0fca6ea1SDimitry Andric   }
414*0fca6ea1SDimitry Andric };
415*0fca6ea1SDimitry Andric 
4165f757f3fSDimitry Andric } // namespace llvm
4175f757f3fSDimitry Andric 
418e8d8bef9SDimitry Andric #endif
419