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