//===--- APINotesFormat.h - The internals of API notes files ------*- C++ -*-===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// /// /// \file /// \brief Contains various constants and helper types to deal with API notes /// files. /// //===----------------------------------------------------------------------===// #ifndef LLVM_CLANG_API_NOTES_FORMAT_H #define LLVM_CLANG_API_NOTES_FORMAT_H #include "llvm/ADT/DenseMapInfo.h" #include "llvm/ADT/Hashing.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Bitcode/RecordLayout.h" namespace clang { namespace api_notes { using namespace llvm; /// Magic number for API notes files. const unsigned char API_NOTES_SIGNATURE[] = { 0xE2, 0x9C, 0xA8, 0x01 }; /// API notes file major version number. /// const uint16_t VERSION_MAJOR = 0; /// API notes file minor version number. /// /// When the format changes IN ANY WAY, this number should be incremented. const uint16_t VERSION_MINOR = 13; // Function/method parameters using IdentifierID = Fixnum<31>; using IdentifierIDField = BCVBR<16>; using SelectorID = Fixnum<31>; using SelectorIDField = BCVBR<16>; using StoredContextID = Fixnum<31>; /// The various types of blocks that can occur within a API notes file. /// /// These IDs must \em not be renumbered or reordered without incrementing /// VERSION_MAJOR. enum BlockID { /// The control block, which contains all of the information that needs to /// be validated prior to committing to loading the API notes file. /// /// \sa control_block CONTROL_BLOCK_ID = llvm::bitc::FIRST_APPLICATION_BLOCKID, /// The identifier data block, which maps identifier strings to IDs. IDENTIFIER_BLOCK_ID, /// The Objective-C class data block, which maps Objective-C class /// names to information about the class. OBJC_CONTEXT_BLOCK_ID, /// The Objective-C property data block, which maps Objective-C /// (class name, property name) pairs to information about the /// property. OBJC_PROPERTY_BLOCK_ID, /// The Objective-C property data block, which maps Objective-C /// (class name, selector, is_instance_method) tuples to information /// about the method. OBJC_METHOD_BLOCK_ID, /// The Objective-C selector data block, which maps Objective-C /// selector names (# of pieces, identifier IDs) to the selector ID /// used in other tables. OBJC_SELECTOR_BLOCK_ID, /// The global variables data block, which maps global variable names to /// information about the global variable. GLOBAL_VARIABLE_BLOCK_ID, /// The (global) functions data block, which maps global function names to /// information about the global function. GLOBAL_FUNCTION_BLOCK_ID, /// The tag data block, which maps tag names to information about /// the tags. TAG_BLOCK_ID, /// The typedef data block, which maps typedef names to information about /// the typedefs. TYPEDEF_BLOCK_ID, /// The enum constant data block, which maps enumerator names to /// information about the enumerators. ENUM_CONSTANT_BLOCK_ID, }; namespace control_block { // These IDs must \em not be renumbered or reordered without incrementing // VERSION_MAJOR. enum { METADATA = 1, MODULE_NAME = 2, MODULE_OPTIONS = 3 }; using MetadataLayout = BCRecordLayout< METADATA, // ID BCFixed<16>, // Module format major version BCFixed<16> // Module format minor version >; using ModuleNameLayout = BCRecordLayout< MODULE_NAME, BCBlob // Module name >; using ModuleOptionsLayout = BCRecordLayout< MODULE_OPTIONS, BCFixed<1> // SwiftInferImportAsMember >; } namespace identifier_block { enum { IDENTIFIER_DATA = 1, }; using IdentifierDataLayout = BCRecordLayout< IDENTIFIER_DATA, // record ID BCVBR<16>, // table offset within the blob (see below) BCBlob // map from identifier strings to decl kinds / decl IDs >; } namespace objc_context_block { enum { OBJC_CONTEXT_DATA = 1, }; using ObjCContextDataLayout = BCRecordLayout< OBJC_CONTEXT_DATA, // record ID BCVBR<16>, // table offset within the blob (see below) BCBlob // map from ObjC class names (as IDs) to ObjC class information >; } namespace objc_property_block { enum { OBJC_PROPERTY_DATA = 1, }; using ObjCPropertyDataLayout = BCRecordLayout< OBJC_PROPERTY_DATA, // record ID BCVBR<16>, // table offset within the blob (see below) BCBlob // map from ObjC (class name, property name) pairs to ObjC // property information >; } namespace objc_method_block { enum { OBJC_METHOD_DATA = 1, }; using ObjCMethodDataLayout = BCRecordLayout< OBJC_METHOD_DATA, // record ID BCVBR<16>, // table offset within the blob (see below) BCBlob // map from ObjC (class names, selector, // is-instance-method) tuples to ObjC method information >; } namespace objc_selector_block { enum { OBJC_SELECTOR_DATA = 1, }; using ObjCSelectorDataLayout = BCRecordLayout< OBJC_SELECTOR_DATA, // record ID BCVBR<16>, // table offset within the blob (see below) BCBlob // map from (# pieces, identifier IDs) to Objective-C selector ID. >; } namespace global_variable_block { enum { GLOBAL_VARIABLE_DATA = 1 }; using GlobalVariableDataLayout = BCRecordLayout< GLOBAL_VARIABLE_DATA, // record ID BCVBR<16>, // table offset within the blob (see below) BCBlob // map from name to global variable information >; } namespace global_function_block { enum { GLOBAL_FUNCTION_DATA = 1 }; using GlobalFunctionDataLayout = BCRecordLayout< GLOBAL_FUNCTION_DATA, // record ID BCVBR<16>, // table offset within the blob (see below) BCBlob // map from name to global function information >; } namespace tag_block { enum { TAG_DATA = 1 }; using TagDataLayout = BCRecordLayout< TAG_DATA, // record ID BCVBR<16>, // table offset within the blob (see below) BCBlob // map from name to tag information >; }; namespace typedef_block { enum { TYPEDEF_DATA = 1 }; using TypedefDataLayout = BCRecordLayout< TYPEDEF_DATA, // record ID BCVBR<16>, // table offset within the blob (see below) BCBlob // map from name to typedef information >; }; namespace enum_constant_block { enum { ENUM_CONSTANT_DATA = 1 }; using EnumConstantDataLayout = BCRecordLayout< ENUM_CONSTANT_DATA, // record ID BCVBR<16>, // table offset within the blob (see below) BCBlob // map from name to enumerator information >; } /// A stored Objective-C selector. struct StoredObjCSelector { unsigned NumPieces; llvm::SmallVector<IdentifierID, 2> Identifiers; }; } // end namespace api_notes } // end namespace clang namespace llvm { template<> struct DenseMapInfo<clang::api_notes::StoredObjCSelector> { typedef DenseMapInfo<unsigned> UnsignedInfo; static inline clang::api_notes::StoredObjCSelector getEmptyKey() { return clang::api_notes::StoredObjCSelector{ UnsignedInfo::getEmptyKey(), { } }; } static inline clang::api_notes::StoredObjCSelector getTombstoneKey() { return clang::api_notes::StoredObjCSelector{ UnsignedInfo::getTombstoneKey(), { } }; } static unsigned getHashValue( const clang::api_notes::StoredObjCSelector& value) { auto hash = llvm::hash_value(value.NumPieces); hash = hash_combine(hash, value.Identifiers.size()); for (auto piece : value.Identifiers) hash = hash_combine(hash, static_cast<unsigned>(piece)); // FIXME: Mix upper/lower 32-bit values together to produce // unsigned rather than truncating. return hash; } static bool isEqual(const clang::api_notes::StoredObjCSelector &lhs, const clang::api_notes::StoredObjCSelector &rhs) { return lhs.NumPieces == rhs.NumPieces && lhs.Identifiers == rhs.Identifiers; } }; } #endif // LLVM_CLANG_API_NOTES_FORMAT_H