brintos

brintos / llvm-project-archived public Read only

0
0
Text · 14.8 KiB · bb423cc Raw
437 lines · c
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-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef LLVM_CLANG_LIB_APINOTES_APINOTESFORMAT_H10#define LLVM_CLANG_LIB_APINOTES_APINOTESFORMAT_H11 12#include "clang/APINotes/Types.h"13#include "llvm/ADT/PointerEmbeddedInt.h"14#include "llvm/Bitcode/BitcodeConvenience.h"15 16namespace clang {17namespace api_notes {18/// Magic number for API notes files.19const unsigned char API_NOTES_SIGNATURE[] = {0xE2, 0x9C, 0xA8, 0x01};20 21/// API notes file major version number.22const 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.27const uint16_t VERSION_MINOR = 38; // SwiftSafety28 29const uint8_t kSwiftConforms = 1;30const uint8_t kSwiftDoesNotConform = 2;31 32using IdentifierID = llvm::PointerEmbeddedInt<unsigned, 31>;33using IdentifierIDField = llvm::BCVBR<16>;34 35using SelectorID = llvm::PointerEmbeddedInt<unsigned, 31>;36using SelectorIDField = llvm::BCVBR<16>;37 38/// The various types of blocks that can occur within a API notes file.39///40/// These IDs must \em not be renumbered or reordered without incrementing41/// VERSION_MAJOR.42enum BlockID {43  /// The control block, which contains all of the information that needs to44  /// be validated prior to committing to loading the API notes file.45  ///46  /// \sa control_block47  CONTROL_BLOCK_ID = llvm::bitc::FIRST_APPLICATION_BLOCKID,48 49  /// The identifier data block, which maps identifier strings to IDs.50  IDENTIFIER_BLOCK_ID,51 52  /// The Objective-C context data block, which contains information about53  /// Objective-C classes and protocols.54  OBJC_CONTEXT_BLOCK_ID,55 56  /// The Objective-C property data block, which maps Objective-C57  /// (class name, property name) pairs to information about the58  /// property.59  OBJC_PROPERTY_BLOCK_ID,60 61  /// The Objective-C property data block, which maps Objective-C62  /// (class name, selector, is_instance_method) tuples to information63  /// about the method.64  OBJC_METHOD_BLOCK_ID,65 66  /// The C++ method data block, which maps C++ (context id, method name) pairs67  /// to information about the method.68  CXX_METHOD_BLOCK_ID,69 70  /// The Objective-C selector data block, which maps Objective-C71  /// selector names (# of pieces, identifier IDs) to the selector ID72  /// used in other tables.73  OBJC_SELECTOR_BLOCK_ID,74 75  /// The fields data block, which maps names fields of C records to76  /// information about the field.77  FIELD_BLOCK_ID,78 79  /// The global variables data block, which maps global variable names to80  /// information about the global variable.81  GLOBAL_VARIABLE_BLOCK_ID,82 83  /// The (global) functions data block, which maps global function names to84  /// information about the global function.85  GLOBAL_FUNCTION_BLOCK_ID,86 87  /// The tag data block, which maps tag names to information about88  /// the tags.89  TAG_BLOCK_ID,90 91  /// The typedef data block, which maps typedef names to information about92  /// the typedefs.93  TYPEDEF_BLOCK_ID,94 95  /// The enum constant data block, which maps enumerator names to96  /// information about the enumerators.97  ENUM_CONSTANT_BLOCK_ID,98};99 100namespace control_block {101// These IDs must \em not be renumbered or reordered without incrementing102// VERSION_MAJOR.103enum {104  METADATA = 1,105  MODULE_NAME = 2,106  MODULE_OPTIONS = 3,107  SOURCE_FILE = 4,108};109 110using MetadataLayout =111    llvm::BCRecordLayout<METADATA,          // ID112                         llvm::BCFixed<16>, // Module format major version113                         llvm::BCFixed<16>  // Module format minor version114                         >;115 116using ModuleNameLayout = llvm::BCRecordLayout<MODULE_NAME,117                                              llvm::BCBlob // Module name118                                              >;119 120using ModuleOptionsLayout =121    llvm::BCRecordLayout<MODULE_OPTIONS,122                         llvm::BCFixed<1> // SwiftInferImportAsMember123                         >;124 125using SourceFileLayout = llvm::BCRecordLayout<SOURCE_FILE,126                                              llvm::BCVBR<16>, // file size127                                              llvm::BCVBR<16>  // creation time128                                              >;129} // namespace control_block130 131namespace identifier_block {132enum {133  IDENTIFIER_DATA = 1,134};135 136using IdentifierDataLayout = llvm::BCRecordLayout<137    IDENTIFIER_DATA, // record ID138    llvm::BCVBR<16>, // table offset within the blob (see below)139    llvm::BCBlob     // map from identifier strings to decl kinds / decl IDs140    >;141} // namespace identifier_block142 143namespace context_block {144enum {145  CONTEXT_ID_DATA = 1,146  CONTEXT_INFO_DATA = 2,147};148 149using ContextIDLayout =150    llvm::BCRecordLayout<CONTEXT_ID_DATA, // record ID151                         llvm::BCVBR<16>, // table offset within the blob (see152                                          // below)153                         llvm::BCBlob // map from ObjC class names/protocol (as154                                      // IDs) to context IDs155                         >;156 157using ContextInfoLayout = llvm::BCRecordLayout<158    CONTEXT_INFO_DATA, // record ID159    llvm::BCVBR<16>,   // table offset within the blob (see below)160    llvm::BCBlob       // map from ObjC context IDs to context information.161    >;162} // namespace context_block163 164namespace objc_property_block {165enum {166  OBJC_PROPERTY_DATA = 1,167};168 169using ObjCPropertyDataLayout = llvm::BCRecordLayout<170    OBJC_PROPERTY_DATA, // record ID171    llvm::BCVBR<16>,    // table offset within the blob (see below)172    llvm::BCBlob        // map from ObjC (class name, property name) pairs to173                        // ObjC property information174    >;175} // namespace objc_property_block176 177namespace objc_method_block {178enum {179  OBJC_METHOD_DATA = 1,180};181 182using ObjCMethodDataLayout =183    llvm::BCRecordLayout<OBJC_METHOD_DATA, // record ID184                         llvm::BCVBR<16>,  // table offset within the blob (see185                                           // below)186                         llvm::BCBlob // map from ObjC (class names, selector,187                                      // is-instance-method) tuples to ObjC188                                      // method information189                         >;190} // namespace objc_method_block191 192namespace cxx_method_block {193enum {194  CXX_METHOD_DATA = 1,195};196 197using CXXMethodDataLayout =198    llvm::BCRecordLayout<CXX_METHOD_DATA, // record ID199                         llvm::BCVBR<16>, // table offset within the blob (see200                                          // below)201                         llvm::BCBlob     // map from C++ (context id, name)202                                          // tuples to C++ method information203                         >;204} // namespace cxx_method_block205 206namespace field_block {207enum {208  FIELD_DATA = 1,209};210 211using FieldDataLayout =212    llvm::BCRecordLayout<FIELD_DATA,      // record ID213                         llvm::BCVBR<16>, // table offset within the blob (see214                                          // below)215                         llvm::BCBlob     // map from C (context id, name)216                                          // tuples to C field information217                         >;218} // namespace field_block219 220namespace objc_selector_block {221enum {222  OBJC_SELECTOR_DATA = 1,223};224 225using ObjCSelectorDataLayout =226    llvm::BCRecordLayout<OBJC_SELECTOR_DATA, // record ID227                         llvm::BCVBR<16>, // table offset within the blob (see228                                          // below)229                         llvm::BCBlob // map from (# pieces, identifier IDs) to230                                      // Objective-C selector ID.231                         >;232} // namespace objc_selector_block233 234namespace global_variable_block {235enum { GLOBAL_VARIABLE_DATA = 1 };236 237using GlobalVariableDataLayout = llvm::BCRecordLayout<238    GLOBAL_VARIABLE_DATA, // record ID239    llvm::BCVBR<16>,      // table offset within the blob (see below)240    llvm::BCBlob          // map from name to global variable information241    >;242} // namespace global_variable_block243 244namespace global_function_block {245enum { GLOBAL_FUNCTION_DATA = 1 };246 247using GlobalFunctionDataLayout = llvm::BCRecordLayout<248    GLOBAL_FUNCTION_DATA, // record ID249    llvm::BCVBR<16>,      // table offset within the blob (see below)250    llvm::BCBlob          // map from name to global function information251    >;252} // namespace global_function_block253 254namespace tag_block {255enum { TAG_DATA = 1 };256 257using TagDataLayout =258    llvm::BCRecordLayout<TAG_DATA,        // record ID259                         llvm::BCVBR<16>, // table offset within the blob (see260                                          // below)261                         llvm::BCBlob     // map from name to tag information262                         >;263} // namespace tag_block264 265namespace typedef_block {266enum { TYPEDEF_DATA = 1 };267 268using TypedefDataLayout =269    llvm::BCRecordLayout<TYPEDEF_DATA,    // record ID270                         llvm::BCVBR<16>, // table offset within the blob (see271                                          // below)272                         llvm::BCBlob // map from name to typedef information273                         >;274} // namespace typedef_block275 276namespace enum_constant_block {277enum { ENUM_CONSTANT_DATA = 1 };278 279using EnumConstantDataLayout =280    llvm::BCRecordLayout<ENUM_CONSTANT_DATA, // record ID281                         llvm::BCVBR<16>, // table offset within the blob (see282                                          // below)283                         llvm::BCBlob // map from name to enumerator information284                         >;285} // namespace enum_constant_block286 287/// A stored Objective-C selector.288struct StoredObjCSelector {289  unsigned NumArgs;290  llvm::SmallVector<IdentifierID, 2> Identifiers;291};292 293/// A stored Objective-C or C++ context, represented by the ID of its parent294/// context, the kind of this context (Objective-C class / C++ namespace / etc),295/// and the ID of this context.296struct ContextTableKey {297  uint32_t parentContextID;298  uint8_t contextKind;299  uint32_t contextID;300 301  ContextTableKey() : parentContextID(-1), contextKind(-1), contextID(-1) {}302 303  ContextTableKey(uint32_t parentContextID, uint8_t contextKind,304                  uint32_t contextID)305      : parentContextID(parentContextID), contextKind(contextKind),306        contextID(contextID) {}307 308  ContextTableKey(std::optional<ContextID> ParentContextID, ContextKind Kind,309                  uint32_t ContextID)310      : parentContextID(ParentContextID ? ParentContextID->Value : -1),311        contextKind(static_cast<uint8_t>(Kind)), contextID(ContextID) {}312 313  ContextTableKey(std::optional<Context> ParentContext, ContextKind Kind,314                  uint32_t ContextID)315      : ContextTableKey(ParentContext ? std::make_optional(ParentContext->id)316                                      : std::nullopt,317                        Kind, ContextID) {}318 319  llvm::hash_code hashValue() const {320    return llvm::hash_value(321        std::tuple{parentContextID, contextKind, contextID});322  }323};324 325inline bool operator==(const ContextTableKey &lhs, const ContextTableKey &rhs) {326  return lhs.parentContextID == rhs.parentContextID &&327         lhs.contextKind == rhs.contextKind && lhs.contextID == rhs.contextID;328}329 330/// A stored Objective-C or C++ declaration, represented by the ID of its parent331/// context, and the name of the declaration.332struct SingleDeclTableKey {333  uint32_t parentContextID;334  uint32_t nameID;335 336  SingleDeclTableKey() : parentContextID(-1), nameID(-1) {}337 338  SingleDeclTableKey(uint32_t ParentContextID, uint32_t NameID)339      : parentContextID(ParentContextID), nameID(NameID) {}340 341  SingleDeclTableKey(std::optional<Context> ParentCtx, IdentifierID NameID)342      : parentContextID(ParentCtx ? ParentCtx->id.Value343                                  : static_cast<uint32_t>(-1)),344        nameID(NameID) {}345 346  llvm::hash_code hashValue() const {347    return llvm::hash_value(std::make_pair(parentContextID, nameID));348  }349};350 351inline bool operator==(const SingleDeclTableKey &lhs,352                       const SingleDeclTableKey &rhs) {353  return lhs.parentContextID == rhs.parentContextID && lhs.nameID == rhs.nameID;354}355 356} // namespace api_notes357} // namespace clang358 359namespace llvm {360template <> struct DenseMapInfo<clang::api_notes::StoredObjCSelector> {361  typedef DenseMapInfo<unsigned> UnsignedInfo;362 363  static inline clang::api_notes::StoredObjCSelector getEmptyKey() {364    return clang::api_notes::StoredObjCSelector{UnsignedInfo::getEmptyKey(),365                                                {}};366  }367 368  static inline clang::api_notes::StoredObjCSelector getTombstoneKey() {369    return clang::api_notes::StoredObjCSelector{UnsignedInfo::getTombstoneKey(),370                                                {}};371  }372 373  static unsigned374  getHashValue(const clang::api_notes::StoredObjCSelector &Selector) {375    auto hash = llvm::hash_value(Selector.NumArgs);376    hash = hash_combine(hash, Selector.Identifiers.size());377    for (auto piece : Selector.Identifiers)378      hash = hash_combine(hash, static_cast<unsigned>(piece));379    // FIXME: Mix upper/lower 32-bit values together to produce380    // unsigned rather than truncating.381    return hash;382  }383 384  static bool isEqual(const clang::api_notes::StoredObjCSelector &LHS,385                      const clang::api_notes::StoredObjCSelector &RHS) {386    return LHS.NumArgs == RHS.NumArgs && LHS.Identifiers == RHS.Identifiers;387  }388};389 390template <> struct DenseMapInfo<clang::api_notes::ContextTableKey> {391  static inline clang::api_notes::ContextTableKey getEmptyKey() {392    return clang::api_notes::ContextTableKey();393  }394 395  static inline clang::api_notes::ContextTableKey getTombstoneKey() {396    return clang::api_notes::ContextTableKey{397        DenseMapInfo<uint32_t>::getTombstoneKey(),398        DenseMapInfo<uint8_t>::getTombstoneKey(),399        DenseMapInfo<uint32_t>::getTombstoneKey()};400  }401 402  static unsigned getHashValue(const clang::api_notes::ContextTableKey &value) {403    return value.hashValue();404  }405 406  static bool isEqual(const clang::api_notes::ContextTableKey &lhs,407                      const clang::api_notes::ContextTableKey &rhs) {408    return lhs == rhs;409  }410};411 412template <> struct DenseMapInfo<clang::api_notes::SingleDeclTableKey> {413  static inline clang::api_notes::SingleDeclTableKey getEmptyKey() {414    return clang::api_notes::SingleDeclTableKey();415  }416 417  static inline clang::api_notes::SingleDeclTableKey getTombstoneKey() {418    return clang::api_notes::SingleDeclTableKey{419        DenseMapInfo<uint32_t>::getTombstoneKey(),420        DenseMapInfo<uint32_t>::getTombstoneKey()};421  }422 423  static unsigned424  getHashValue(const clang::api_notes::SingleDeclTableKey &value) {425    return value.hashValue();426  }427 428  static bool isEqual(const clang::api_notes::SingleDeclTableKey &lhs,429                      const clang::api_notes::SingleDeclTableKey &rhs) {430    return lhs == rhs;431  }432};433 434} // namespace llvm435 436#endif437