Path: blob/main/contrib/llvm-project/clang/lib/APINotes/APINotesFormat.h
35260 views
//===-- APINotesWriter.h - API Notes Writer ---------------------*- C++ -*-===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#ifndef LLVM_CLANG_LIB_APINOTES_APINOTESFORMAT_H9#define LLVM_CLANG_LIB_APINOTES_APINOTESFORMAT_H1011#include "clang/APINotes/Types.h"12#include "llvm/ADT/PointerEmbeddedInt.h"13#include "llvm/Bitcode/BitcodeConvenience.h"1415namespace clang {16namespace api_notes {17/// Magic number for API notes files.18const unsigned char API_NOTES_SIGNATURE[] = {0xE2, 0x9C, 0xA8, 0x01};1920/// API notes file major version number.21const uint16_t VERSION_MAJOR = 0;2223/// API notes file minor version number.24///25/// When the format changes IN ANY WAY, this number should be incremented.26const uint16_t VERSION_MINOR = 27; // SingleDeclTableKey2728const uint8_t kSwiftCopyable = 1;29const uint8_t kSwiftNonCopyable = 2;3031using IdentifierID = llvm::PointerEmbeddedInt<unsigned, 31>;32using IdentifierIDField = llvm::BCVBR<16>;3334using SelectorID = llvm::PointerEmbeddedInt<unsigned, 31>;35using SelectorIDField = llvm::BCVBR<16>;3637/// The various types of blocks that can occur within a API notes file.38///39/// These IDs must \em not be renumbered or reordered without incrementing40/// VERSION_MAJOR.41enum BlockID {42/// The control block, which contains all of the information that needs to43/// be validated prior to committing to loading the API notes file.44///45/// \sa control_block46CONTROL_BLOCK_ID = llvm::bitc::FIRST_APPLICATION_BLOCKID,4748/// The identifier data block, which maps identifier strings to IDs.49IDENTIFIER_BLOCK_ID,5051/// The Objective-C context data block, which contains information about52/// Objective-C classes and protocols.53OBJC_CONTEXT_BLOCK_ID,5455/// The Objective-C property data block, which maps Objective-C56/// (class name, property name) pairs to information about the57/// property.58OBJC_PROPERTY_BLOCK_ID,5960/// The Objective-C property data block, which maps Objective-C61/// (class name, selector, is_instance_method) tuples to information62/// about the method.63OBJC_METHOD_BLOCK_ID,6465/// The C++ method data block, which maps C++ (context id, method name) pairs66/// to information about the method.67CXX_METHOD_BLOCK_ID,6869/// The Objective-C selector data block, which maps Objective-C70/// selector names (# of pieces, identifier IDs) to the selector ID71/// used in other tables.72OBJC_SELECTOR_BLOCK_ID,7374/// The global variables data block, which maps global variable names to75/// information about the global variable.76GLOBAL_VARIABLE_BLOCK_ID,7778/// The (global) functions data block, which maps global function names to79/// information about the global function.80GLOBAL_FUNCTION_BLOCK_ID,8182/// The tag data block, which maps tag names to information about83/// the tags.84TAG_BLOCK_ID,8586/// The typedef data block, which maps typedef names to information about87/// the typedefs.88TYPEDEF_BLOCK_ID,8990/// The enum constant data block, which maps enumerator names to91/// information about the enumerators.92ENUM_CONSTANT_BLOCK_ID,93};9495namespace control_block {96// These IDs must \em not be renumbered or reordered without incrementing97// VERSION_MAJOR.98enum {99METADATA = 1,100MODULE_NAME = 2,101MODULE_OPTIONS = 3,102SOURCE_FILE = 4,103};104105using MetadataLayout =106llvm::BCRecordLayout<METADATA, // ID107llvm::BCFixed<16>, // Module format major version108llvm::BCFixed<16> // Module format minor version109>;110111using ModuleNameLayout = llvm::BCRecordLayout<MODULE_NAME,112llvm::BCBlob // Module name113>;114115using ModuleOptionsLayout =116llvm::BCRecordLayout<MODULE_OPTIONS,117llvm::BCFixed<1> // SwiftInferImportAsMember118>;119120using SourceFileLayout = llvm::BCRecordLayout<SOURCE_FILE,121llvm::BCVBR<16>, // file size122llvm::BCVBR<16> // creation time123>;124} // namespace control_block125126namespace identifier_block {127enum {128IDENTIFIER_DATA = 1,129};130131using IdentifierDataLayout = llvm::BCRecordLayout<132IDENTIFIER_DATA, // record ID133llvm::BCVBR<16>, // table offset within the blob (see below)134llvm::BCBlob // map from identifier strings to decl kinds / decl IDs135>;136} // namespace identifier_block137138namespace context_block {139enum {140CONTEXT_ID_DATA = 1,141CONTEXT_INFO_DATA = 2,142};143144using ContextIDLayout =145llvm::BCRecordLayout<CONTEXT_ID_DATA, // record ID146llvm::BCVBR<16>, // table offset within the blob (see147// below)148llvm::BCBlob // map from ObjC class names/protocol (as149// IDs) to context IDs150>;151152using ContextInfoLayout = llvm::BCRecordLayout<153CONTEXT_INFO_DATA, // record ID154llvm::BCVBR<16>, // table offset within the blob (see below)155llvm::BCBlob // map from ObjC context IDs to context information.156>;157} // namespace context_block158159namespace objc_property_block {160enum {161OBJC_PROPERTY_DATA = 1,162};163164using ObjCPropertyDataLayout = llvm::BCRecordLayout<165OBJC_PROPERTY_DATA, // record ID166llvm::BCVBR<16>, // table offset within the blob (see below)167llvm::BCBlob // map from ObjC (class name, property name) pairs to168// ObjC property information169>;170} // namespace objc_property_block171172namespace objc_method_block {173enum {174OBJC_METHOD_DATA = 1,175};176177using ObjCMethodDataLayout =178llvm::BCRecordLayout<OBJC_METHOD_DATA, // record ID179llvm::BCVBR<16>, // table offset within the blob (see180// below)181llvm::BCBlob // map from ObjC (class names, selector,182// is-instance-method) tuples to ObjC183// method information184>;185} // namespace objc_method_block186187namespace cxx_method_block {188enum {189CXX_METHOD_DATA = 1,190};191192using CXXMethodDataLayout =193llvm::BCRecordLayout<CXX_METHOD_DATA, // record ID194llvm::BCVBR<16>, // table offset within the blob (see195// below)196llvm::BCBlob // map from C++ (context id, name)197// tuples to C++ method information198>;199} // namespace cxx_method_block200201namespace objc_selector_block {202enum {203OBJC_SELECTOR_DATA = 1,204};205206using ObjCSelectorDataLayout =207llvm::BCRecordLayout<OBJC_SELECTOR_DATA, // record ID208llvm::BCVBR<16>, // table offset within the blob (see209// below)210llvm::BCBlob // map from (# pieces, identifier IDs) to211// Objective-C selector ID.212>;213} // namespace objc_selector_block214215namespace global_variable_block {216enum { GLOBAL_VARIABLE_DATA = 1 };217218using GlobalVariableDataLayout = llvm::BCRecordLayout<219GLOBAL_VARIABLE_DATA, // record ID220llvm::BCVBR<16>, // table offset within the blob (see below)221llvm::BCBlob // map from name to global variable information222>;223} // namespace global_variable_block224225namespace global_function_block {226enum { GLOBAL_FUNCTION_DATA = 1 };227228using GlobalFunctionDataLayout = llvm::BCRecordLayout<229GLOBAL_FUNCTION_DATA, // record ID230llvm::BCVBR<16>, // table offset within the blob (see below)231llvm::BCBlob // map from name to global function information232>;233} // namespace global_function_block234235namespace tag_block {236enum { TAG_DATA = 1 };237238using TagDataLayout =239llvm::BCRecordLayout<TAG_DATA, // record ID240llvm::BCVBR<16>, // table offset within the blob (see241// below)242llvm::BCBlob // map from name to tag information243>;244} // namespace tag_block245246namespace typedef_block {247enum { TYPEDEF_DATA = 1 };248249using TypedefDataLayout =250llvm::BCRecordLayout<TYPEDEF_DATA, // record ID251llvm::BCVBR<16>, // table offset within the blob (see252// below)253llvm::BCBlob // map from name to typedef information254>;255} // namespace typedef_block256257namespace enum_constant_block {258enum { ENUM_CONSTANT_DATA = 1 };259260using EnumConstantDataLayout =261llvm::BCRecordLayout<ENUM_CONSTANT_DATA, // record ID262llvm::BCVBR<16>, // table offset within the blob (see263// below)264llvm::BCBlob // map from name to enumerator information265>;266} // namespace enum_constant_block267268/// A stored Objective-C selector.269struct StoredObjCSelector {270unsigned NumArgs;271llvm::SmallVector<IdentifierID, 2> Identifiers;272};273274/// A stored Objective-C or C++ context, represented by the ID of its parent275/// context, the kind of this context (Objective-C class / C++ namespace / etc),276/// and the ID of this context.277struct ContextTableKey {278uint32_t parentContextID;279uint8_t contextKind;280uint32_t contextID;281282ContextTableKey() : parentContextID(-1), contextKind(-1), contextID(-1) {}283284ContextTableKey(uint32_t parentContextID, uint8_t contextKind,285uint32_t contextID)286: parentContextID(parentContextID), contextKind(contextKind),287contextID(contextID) {}288289ContextTableKey(std::optional<ContextID> ParentContextID, ContextKind Kind,290uint32_t ContextID)291: parentContextID(ParentContextID ? ParentContextID->Value : -1),292contextKind(static_cast<uint8_t>(Kind)), contextID(ContextID) {}293294ContextTableKey(std::optional<Context> ParentContext, ContextKind Kind,295uint32_t ContextID)296: ContextTableKey(ParentContext ? std::make_optional(ParentContext->id)297: std::nullopt,298Kind, ContextID) {}299300llvm::hash_code hashValue() const {301return llvm::hash_value(302std::tuple{parentContextID, contextKind, contextID});303}304};305306inline bool operator==(const ContextTableKey &lhs, const ContextTableKey &rhs) {307return lhs.parentContextID == rhs.parentContextID &&308lhs.contextKind == rhs.contextKind && lhs.contextID == rhs.contextID;309}310311/// A stored Objective-C or C++ declaration, represented by the ID of its parent312/// context, and the name of the declaration.313struct SingleDeclTableKey {314uint32_t parentContextID;315uint32_t nameID;316317SingleDeclTableKey() : parentContextID(-1), nameID(-1) {}318319SingleDeclTableKey(uint32_t ParentContextID, uint32_t NameID)320: parentContextID(ParentContextID), nameID(NameID) {}321322SingleDeclTableKey(std::optional<Context> ParentCtx, IdentifierID NameID)323: parentContextID(ParentCtx ? ParentCtx->id.Value324: static_cast<uint32_t>(-1)),325nameID(NameID) {}326327llvm::hash_code hashValue() const {328return llvm::hash_value(std::make_pair(parentContextID, nameID));329}330};331332inline bool operator==(const SingleDeclTableKey &lhs,333const SingleDeclTableKey &rhs) {334return lhs.parentContextID == rhs.parentContextID && lhs.nameID == rhs.nameID;335}336337} // namespace api_notes338} // namespace clang339340namespace llvm {341template <> struct DenseMapInfo<clang::api_notes::StoredObjCSelector> {342typedef DenseMapInfo<unsigned> UnsignedInfo;343344static inline clang::api_notes::StoredObjCSelector getEmptyKey() {345return clang::api_notes::StoredObjCSelector{UnsignedInfo::getEmptyKey(),346{}};347}348349static inline clang::api_notes::StoredObjCSelector getTombstoneKey() {350return clang::api_notes::StoredObjCSelector{UnsignedInfo::getTombstoneKey(),351{}};352}353354static unsigned355getHashValue(const clang::api_notes::StoredObjCSelector &Selector) {356auto hash = llvm::hash_value(Selector.NumArgs);357hash = hash_combine(hash, Selector.Identifiers.size());358for (auto piece : Selector.Identifiers)359hash = hash_combine(hash, static_cast<unsigned>(piece));360// FIXME: Mix upper/lower 32-bit values together to produce361// unsigned rather than truncating.362return hash;363}364365static bool isEqual(const clang::api_notes::StoredObjCSelector &LHS,366const clang::api_notes::StoredObjCSelector &RHS) {367return LHS.NumArgs == RHS.NumArgs && LHS.Identifiers == RHS.Identifiers;368}369};370371template <> struct DenseMapInfo<clang::api_notes::ContextTableKey> {372static inline clang::api_notes::ContextTableKey getEmptyKey() {373return clang::api_notes::ContextTableKey();374}375376static inline clang::api_notes::ContextTableKey getTombstoneKey() {377return clang::api_notes::ContextTableKey{378DenseMapInfo<uint32_t>::getTombstoneKey(),379DenseMapInfo<uint8_t>::getTombstoneKey(),380DenseMapInfo<uint32_t>::getTombstoneKey()};381}382383static unsigned getHashValue(const clang::api_notes::ContextTableKey &value) {384return value.hashValue();385}386387static bool isEqual(const clang::api_notes::ContextTableKey &lhs,388const clang::api_notes::ContextTableKey &rhs) {389return lhs == rhs;390}391};392393template <> struct DenseMapInfo<clang::api_notes::SingleDeclTableKey> {394static inline clang::api_notes::SingleDeclTableKey getEmptyKey() {395return clang::api_notes::SingleDeclTableKey();396}397398static inline clang::api_notes::SingleDeclTableKey getTombstoneKey() {399return clang::api_notes::SingleDeclTableKey{400DenseMapInfo<uint32_t>::getTombstoneKey(),401DenseMapInfo<uint32_t>::getTombstoneKey()};402}403404static unsigned405getHashValue(const clang::api_notes::SingleDeclTableKey &value) {406return value.hashValue();407}408409static bool isEqual(const clang::api_notes::SingleDeclTableKey &lhs,410const clang::api_notes::SingleDeclTableKey &rhs) {411return lhs == rhs;412}413};414415} // namespace llvm416417#endif418419420