1bb352b6eSEgor Zhdan //===--- APINotesReader.cpp - API Notes Reader ------------------*- C++ -*-===// 2bb352b6eSEgor Zhdan // 3bb352b6eSEgor Zhdan // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4bb352b6eSEgor Zhdan // See https://llvm.org/LICENSE.txt for license information. 5bb352b6eSEgor Zhdan // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6bb352b6eSEgor Zhdan // 7bb352b6eSEgor Zhdan //===----------------------------------------------------------------------===// 8864593b9SJan Svoboda // 9864593b9SJan Svoboda // This file implements the \c APINotesReader class that reads source 10864593b9SJan Svoboda // API notes data providing additional information about source code as 11864593b9SJan Svoboda // a separate input, such as the non-nil/nilable annotations for 12864593b9SJan Svoboda // method parameters. 13864593b9SJan Svoboda // 14864593b9SJan Svoboda //===----------------------------------------------------------------------===// 15bb352b6eSEgor Zhdan #include "clang/APINotes/APINotesReader.h" 16bb352b6eSEgor Zhdan #include "APINotesFormat.h" 175f4e3a3cSGábor Horváth #include "clang/APINotes/Types.h" 18bb352b6eSEgor Zhdan #include "llvm/ADT/Hashing.h" 19bb352b6eSEgor Zhdan #include "llvm/ADT/StringExtras.h" 20bb352b6eSEgor Zhdan #include "llvm/Bitstream/BitstreamReader.h" 21bb352b6eSEgor Zhdan #include "llvm/Support/DJB.h" 22bb352b6eSEgor Zhdan #include "llvm/Support/EndianStream.h" 23bb352b6eSEgor Zhdan #include "llvm/Support/OnDiskHashTable.h" 24bb352b6eSEgor Zhdan 25bb352b6eSEgor Zhdan namespace clang { 26bb352b6eSEgor Zhdan namespace api_notes { 27bb352b6eSEgor Zhdan using namespace llvm::support; 28bb352b6eSEgor Zhdan 29bb352b6eSEgor Zhdan namespace { 30bb352b6eSEgor Zhdan /// Deserialize a version tuple. 31bb352b6eSEgor Zhdan llvm::VersionTuple ReadVersionTuple(const uint8_t *&Data) { 32bb352b6eSEgor Zhdan uint8_t NumVersions = (*Data++) & 0x03; 33bb352b6eSEgor Zhdan 3489071f35SKazu Hirata unsigned Major = endian::readNext<uint32_t, llvm::endianness::little>(Data); 35bb352b6eSEgor Zhdan if (NumVersions == 0) 36bb352b6eSEgor Zhdan return llvm::VersionTuple(Major); 37bb352b6eSEgor Zhdan 3889071f35SKazu Hirata unsigned Minor = endian::readNext<uint32_t, llvm::endianness::little>(Data); 39bb352b6eSEgor Zhdan if (NumVersions == 1) 40bb352b6eSEgor Zhdan return llvm::VersionTuple(Major, Minor); 41bb352b6eSEgor Zhdan 42bb352b6eSEgor Zhdan unsigned Subminor = 4389071f35SKazu Hirata endian::readNext<uint32_t, llvm::endianness::little>(Data); 44bb352b6eSEgor Zhdan if (NumVersions == 2) 45bb352b6eSEgor Zhdan return llvm::VersionTuple(Major, Minor, Subminor); 46bb352b6eSEgor Zhdan 4789071f35SKazu Hirata unsigned Build = endian::readNext<uint32_t, llvm::endianness::little>(Data); 48bb352b6eSEgor Zhdan return llvm::VersionTuple(Major, Minor, Subminor, Build); 49bb352b6eSEgor Zhdan } 50bb352b6eSEgor Zhdan 51bb352b6eSEgor Zhdan /// An on-disk hash table whose data is versioned based on the Swift version. 52bb352b6eSEgor Zhdan template <typename Derived, typename KeyType, typename UnversionedDataType> 53bb352b6eSEgor Zhdan class VersionedTableInfo { 54bb352b6eSEgor Zhdan public: 55bb352b6eSEgor Zhdan using internal_key_type = KeyType; 56bb352b6eSEgor Zhdan using external_key_type = KeyType; 57bb352b6eSEgor Zhdan using data_type = 58bb352b6eSEgor Zhdan llvm::SmallVector<std::pair<llvm::VersionTuple, UnversionedDataType>, 1>; 59bb352b6eSEgor Zhdan using hash_value_type = size_t; 60bb352b6eSEgor Zhdan using offset_type = unsigned; 61bb352b6eSEgor Zhdan 62bb352b6eSEgor Zhdan internal_key_type GetInternalKey(external_key_type Key) { return Key; } 63bb352b6eSEgor Zhdan 64bb352b6eSEgor Zhdan external_key_type GetExternalKey(internal_key_type Key) { return Key; } 65bb352b6eSEgor Zhdan 66bb352b6eSEgor Zhdan static bool EqualKey(internal_key_type LHS, internal_key_type RHS) { 67bb352b6eSEgor Zhdan return LHS == RHS; 68bb352b6eSEgor Zhdan } 69bb352b6eSEgor Zhdan 70bb352b6eSEgor Zhdan static std::pair<unsigned, unsigned> ReadKeyDataLength(const uint8_t *&Data) { 71bb352b6eSEgor Zhdan unsigned KeyLength = 7289071f35SKazu Hirata endian::readNext<uint16_t, llvm::endianness::little>(Data); 73bb352b6eSEgor Zhdan unsigned DataLength = 7489071f35SKazu Hirata endian::readNext<uint16_t, llvm::endianness::little>(Data); 75bb352b6eSEgor Zhdan return {KeyLength, DataLength}; 76bb352b6eSEgor Zhdan } 77bb352b6eSEgor Zhdan 78bb352b6eSEgor Zhdan static data_type ReadData(internal_key_type Key, const uint8_t *Data, 79bb352b6eSEgor Zhdan unsigned Length) { 80bb352b6eSEgor Zhdan unsigned NumElements = 8189071f35SKazu Hirata endian::readNext<uint16_t, llvm::endianness::little>(Data); 82bb352b6eSEgor Zhdan data_type Result; 83bb352b6eSEgor Zhdan Result.reserve(NumElements); 84bb352b6eSEgor Zhdan for (unsigned i = 0; i != NumElements; ++i) { 85bb352b6eSEgor Zhdan auto version = ReadVersionTuple(Data); 86bb352b6eSEgor Zhdan const auto *DataBefore = Data; 87bb352b6eSEgor Zhdan (void)DataBefore; 885e4c4365SEgor Zhdan auto UnversionedData = Derived::readUnversioned(Key, Data); 89bb352b6eSEgor Zhdan assert(Data != DataBefore && 90bb352b6eSEgor Zhdan "Unversioned data reader didn't move pointer"); 91bb352b6eSEgor Zhdan Result.push_back({version, UnversionedData}); 92bb352b6eSEgor Zhdan } 93bb352b6eSEgor Zhdan return Result; 94bb352b6eSEgor Zhdan } 95bb352b6eSEgor Zhdan }; 96bb352b6eSEgor Zhdan 97bb352b6eSEgor Zhdan /// Read serialized CommonEntityInfo. 98bb352b6eSEgor Zhdan void ReadCommonEntityInfo(const uint8_t *&Data, CommonEntityInfo &Info) { 99bb352b6eSEgor Zhdan uint8_t UnavailableBits = *Data++; 100bb352b6eSEgor Zhdan Info.Unavailable = (UnavailableBits >> 1) & 0x01; 101bb352b6eSEgor Zhdan Info.UnavailableInSwift = UnavailableBits & 0x01; 102bb352b6eSEgor Zhdan if ((UnavailableBits >> 2) & 0x01) 103bb352b6eSEgor Zhdan Info.setSwiftPrivate(static_cast<bool>((UnavailableBits >> 3) & 0x01)); 104bb352b6eSEgor Zhdan 105bb352b6eSEgor Zhdan unsigned MsgLength = 10689071f35SKazu Hirata endian::readNext<uint16_t, llvm::endianness::little>(Data); 107bb352b6eSEgor Zhdan Info.UnavailableMsg = 108bb352b6eSEgor Zhdan std::string(reinterpret_cast<const char *>(Data), 109bb352b6eSEgor Zhdan reinterpret_cast<const char *>(Data) + MsgLength); 110bb352b6eSEgor Zhdan Data += MsgLength; 111bb352b6eSEgor Zhdan 112bb352b6eSEgor Zhdan unsigned SwiftNameLength = 11389071f35SKazu Hirata endian::readNext<uint16_t, llvm::endianness::little>(Data); 114bb352b6eSEgor Zhdan Info.SwiftName = 115bb352b6eSEgor Zhdan std::string(reinterpret_cast<const char *>(Data), 116bb352b6eSEgor Zhdan reinterpret_cast<const char *>(Data) + SwiftNameLength); 117bb352b6eSEgor Zhdan Data += SwiftNameLength; 118bb352b6eSEgor Zhdan } 119bb352b6eSEgor Zhdan 120bb352b6eSEgor Zhdan /// Read serialized CommonTypeInfo. 121bb352b6eSEgor Zhdan void ReadCommonTypeInfo(const uint8_t *&Data, CommonTypeInfo &Info) { 122bb352b6eSEgor Zhdan ReadCommonEntityInfo(Data, Info); 123bb352b6eSEgor Zhdan 124bb352b6eSEgor Zhdan unsigned SwiftBridgeLength = 12589071f35SKazu Hirata endian::readNext<uint16_t, llvm::endianness::little>(Data); 126bb352b6eSEgor Zhdan if (SwiftBridgeLength > 0) { 127bb352b6eSEgor Zhdan Info.setSwiftBridge(std::string(reinterpret_cast<const char *>(Data), 128bb352b6eSEgor Zhdan SwiftBridgeLength - 1)); 129bb352b6eSEgor Zhdan Data += SwiftBridgeLength - 1; 130bb352b6eSEgor Zhdan } 131bb352b6eSEgor Zhdan 132bb352b6eSEgor Zhdan unsigned ErrorDomainLength = 13389071f35SKazu Hirata endian::readNext<uint16_t, llvm::endianness::little>(Data); 134bb352b6eSEgor Zhdan if (ErrorDomainLength > 0) { 135bb352b6eSEgor Zhdan Info.setNSErrorDomain(std::optional<std::string>(std::string( 136bb352b6eSEgor Zhdan reinterpret_cast<const char *>(Data), ErrorDomainLength - 1))); 137bb352b6eSEgor Zhdan Data += ErrorDomainLength - 1; 138bb352b6eSEgor Zhdan } 139bb352b6eSEgor Zhdan } 140bb352b6eSEgor Zhdan 141bb352b6eSEgor Zhdan /// Used to deserialize the on-disk identifier table. 142bb352b6eSEgor Zhdan class IdentifierTableInfo { 143bb352b6eSEgor Zhdan public: 144bb352b6eSEgor Zhdan using internal_key_type = llvm::StringRef; 145bb352b6eSEgor Zhdan using external_key_type = llvm::StringRef; 146bb352b6eSEgor Zhdan using data_type = IdentifierID; 147bb352b6eSEgor Zhdan using hash_value_type = uint32_t; 148bb352b6eSEgor Zhdan using offset_type = unsigned; 149bb352b6eSEgor Zhdan 150bb352b6eSEgor Zhdan internal_key_type GetInternalKey(external_key_type Key) { return Key; } 151bb352b6eSEgor Zhdan 152bb352b6eSEgor Zhdan external_key_type GetExternalKey(internal_key_type Key) { return Key; } 153bb352b6eSEgor Zhdan 154bb352b6eSEgor Zhdan hash_value_type ComputeHash(internal_key_type Key) { 1555e4c4365SEgor Zhdan return llvm::djbHash(Key); 156bb352b6eSEgor Zhdan } 157bb352b6eSEgor Zhdan 158bb352b6eSEgor Zhdan static bool EqualKey(internal_key_type LHS, internal_key_type RHS) { 159bb352b6eSEgor Zhdan return LHS == RHS; 160bb352b6eSEgor Zhdan } 161bb352b6eSEgor Zhdan 162bb352b6eSEgor Zhdan static std::pair<unsigned, unsigned> ReadKeyDataLength(const uint8_t *&Data) { 163bb352b6eSEgor Zhdan unsigned KeyLength = 16489071f35SKazu Hirata endian::readNext<uint16_t, llvm::endianness::little>(Data); 165bb352b6eSEgor Zhdan unsigned DataLength = 16689071f35SKazu Hirata endian::readNext<uint16_t, llvm::endianness::little>(Data); 167bb352b6eSEgor Zhdan return {KeyLength, DataLength}; 168bb352b6eSEgor Zhdan } 169bb352b6eSEgor Zhdan 170bb352b6eSEgor Zhdan static internal_key_type ReadKey(const uint8_t *Data, unsigned Length) { 171bb352b6eSEgor Zhdan return llvm::StringRef(reinterpret_cast<const char *>(Data), Length); 172bb352b6eSEgor Zhdan } 173bb352b6eSEgor Zhdan 174bb352b6eSEgor Zhdan static data_type ReadData(internal_key_type key, const uint8_t *Data, 175bb352b6eSEgor Zhdan unsigned Length) { 17689071f35SKazu Hirata return endian::readNext<uint32_t, llvm::endianness::little>(Data); 177bb352b6eSEgor Zhdan } 178bb352b6eSEgor Zhdan }; 179bb352b6eSEgor Zhdan 18082ee7ae3SEgor Zhdan /// Used to deserialize the on-disk table of Objective-C classes and C++ 18182ee7ae3SEgor Zhdan /// namespaces. 18282ee7ae3SEgor Zhdan class ContextIDTableInfo { 183bb352b6eSEgor Zhdan public: 184bb352b6eSEgor Zhdan using internal_key_type = ContextTableKey; 185bb352b6eSEgor Zhdan using external_key_type = internal_key_type; 186bb352b6eSEgor Zhdan using data_type = unsigned; 187bb352b6eSEgor Zhdan using hash_value_type = size_t; 188bb352b6eSEgor Zhdan using offset_type = unsigned; 189bb352b6eSEgor Zhdan 190bb352b6eSEgor Zhdan internal_key_type GetInternalKey(external_key_type Key) { return Key; } 191bb352b6eSEgor Zhdan 192bb352b6eSEgor Zhdan external_key_type GetExternalKey(internal_key_type Key) { return Key; } 193bb352b6eSEgor Zhdan 194bb352b6eSEgor Zhdan hash_value_type ComputeHash(internal_key_type Key) { 195bb352b6eSEgor Zhdan return static_cast<size_t>(Key.hashValue()); 196bb352b6eSEgor Zhdan } 197bb352b6eSEgor Zhdan 198bb352b6eSEgor Zhdan static bool EqualKey(internal_key_type LHS, internal_key_type RHS) { 199bb352b6eSEgor Zhdan return LHS == RHS; 200bb352b6eSEgor Zhdan } 201bb352b6eSEgor Zhdan 202bb352b6eSEgor Zhdan static std::pair<unsigned, unsigned> ReadKeyDataLength(const uint8_t *&Data) { 203bb352b6eSEgor Zhdan unsigned KeyLength = 20489071f35SKazu Hirata endian::readNext<uint16_t, llvm::endianness::little>(Data); 205bb352b6eSEgor Zhdan unsigned DataLength = 20689071f35SKazu Hirata endian::readNext<uint16_t, llvm::endianness::little>(Data); 207bb352b6eSEgor Zhdan return {KeyLength, DataLength}; 208bb352b6eSEgor Zhdan } 209bb352b6eSEgor Zhdan 210bb352b6eSEgor Zhdan static internal_key_type ReadKey(const uint8_t *Data, unsigned Length) { 211bb352b6eSEgor Zhdan auto ParentCtxID = 21289071f35SKazu Hirata endian::readNext<uint32_t, llvm::endianness::little>(Data); 213bb352b6eSEgor Zhdan auto ContextKind = 21489071f35SKazu Hirata endian::readNext<uint8_t, llvm::endianness::little>(Data); 21589071f35SKazu Hirata auto NameID = endian::readNext<uint32_t, llvm::endianness::little>(Data); 216bb352b6eSEgor Zhdan return {ParentCtxID, ContextKind, NameID}; 217bb352b6eSEgor Zhdan } 218bb352b6eSEgor Zhdan 219bb352b6eSEgor Zhdan static data_type ReadData(internal_key_type Key, const uint8_t *Data, 220bb352b6eSEgor Zhdan unsigned Length) { 22189071f35SKazu Hirata return endian::readNext<uint32_t, llvm::endianness::little>(Data); 222bb352b6eSEgor Zhdan } 223bb352b6eSEgor Zhdan }; 224bb352b6eSEgor Zhdan 225bb352b6eSEgor Zhdan /// Used to deserialize the on-disk Objective-C property table. 22682ee7ae3SEgor Zhdan class ContextInfoTableInfo 22782ee7ae3SEgor Zhdan : public VersionedTableInfo<ContextInfoTableInfo, unsigned, ContextInfo> { 228bb352b6eSEgor Zhdan public: 229bb352b6eSEgor Zhdan static internal_key_type ReadKey(const uint8_t *Data, unsigned Length) { 23089071f35SKazu Hirata return endian::readNext<uint32_t, llvm::endianness::little>(Data); 231bb352b6eSEgor Zhdan } 232bb352b6eSEgor Zhdan 233bb352b6eSEgor Zhdan hash_value_type ComputeHash(internal_key_type Key) { 234bb352b6eSEgor Zhdan return static_cast<size_t>(llvm::hash_value(Key)); 235bb352b6eSEgor Zhdan } 236bb352b6eSEgor Zhdan 23782ee7ae3SEgor Zhdan static ContextInfo readUnversioned(internal_key_type Key, 238bb352b6eSEgor Zhdan const uint8_t *&Data) { 23982ee7ae3SEgor Zhdan ContextInfo Info; 240bb352b6eSEgor Zhdan ReadCommonTypeInfo(Data, Info); 241bb352b6eSEgor Zhdan uint8_t Payload = *Data++; 242bb352b6eSEgor Zhdan 243bb352b6eSEgor Zhdan if (Payload & 0x01) 244bb352b6eSEgor Zhdan Info.setHasDesignatedInits(true); 245bb352b6eSEgor Zhdan Payload = Payload >> 1; 246bb352b6eSEgor Zhdan 247bb352b6eSEgor Zhdan if (Payload & 0x4) 248bb352b6eSEgor Zhdan Info.setDefaultNullability(static_cast<NullabilityKind>(Payload & 0x03)); 249bb352b6eSEgor Zhdan Payload >>= 3; 250bb352b6eSEgor Zhdan 251bb352b6eSEgor Zhdan if (Payload & (1 << 1)) 252bb352b6eSEgor Zhdan Info.setSwiftObjCMembers(Payload & 1); 253bb352b6eSEgor Zhdan Payload >>= 2; 254bb352b6eSEgor Zhdan 255bb352b6eSEgor Zhdan if (Payload & (1 << 1)) 256bb352b6eSEgor Zhdan Info.setSwiftImportAsNonGeneric(Payload & 1); 257bb352b6eSEgor Zhdan 258bb352b6eSEgor Zhdan return Info; 259bb352b6eSEgor Zhdan } 260bb352b6eSEgor Zhdan }; 261bb352b6eSEgor Zhdan 262bb352b6eSEgor Zhdan /// Read serialized VariableInfo. 263bb352b6eSEgor Zhdan void ReadVariableInfo(const uint8_t *&Data, VariableInfo &Info) { 264bb352b6eSEgor Zhdan ReadCommonEntityInfo(Data, Info); 265bb352b6eSEgor Zhdan if (*Data++) { 266bb352b6eSEgor Zhdan Info.setNullabilityAudited(static_cast<NullabilityKind>(*Data)); 267bb352b6eSEgor Zhdan } 268bb352b6eSEgor Zhdan ++Data; 269bb352b6eSEgor Zhdan 27089071f35SKazu Hirata auto TypeLen = endian::readNext<uint16_t, llvm::endianness::little>(Data); 271bb352b6eSEgor Zhdan Info.setType(std::string(Data, Data + TypeLen)); 272bb352b6eSEgor Zhdan Data += TypeLen; 273bb352b6eSEgor Zhdan } 274bb352b6eSEgor Zhdan 275bb352b6eSEgor Zhdan /// Used to deserialize the on-disk Objective-C property table. 276bb352b6eSEgor Zhdan class ObjCPropertyTableInfo 277bb352b6eSEgor Zhdan : public VersionedTableInfo<ObjCPropertyTableInfo, 278bb352b6eSEgor Zhdan std::tuple<uint32_t, uint32_t, uint8_t>, 279bb352b6eSEgor Zhdan ObjCPropertyInfo> { 280bb352b6eSEgor Zhdan public: 281bb352b6eSEgor Zhdan static internal_key_type ReadKey(const uint8_t *Data, unsigned Length) { 28289071f35SKazu Hirata auto ClassID = endian::readNext<uint32_t, llvm::endianness::little>(Data); 28389071f35SKazu Hirata auto NameID = endian::readNext<uint32_t, llvm::endianness::little>(Data); 28489071f35SKazu Hirata char IsInstance = endian::readNext<uint8_t, llvm::endianness::little>(Data); 285bb352b6eSEgor Zhdan return {ClassID, NameID, IsInstance}; 286bb352b6eSEgor Zhdan } 287bb352b6eSEgor Zhdan 288bb352b6eSEgor Zhdan hash_value_type ComputeHash(internal_key_type Key) { 289bb352b6eSEgor Zhdan return static_cast<size_t>(llvm::hash_value(Key)); 290bb352b6eSEgor Zhdan } 291bb352b6eSEgor Zhdan 292bb352b6eSEgor Zhdan static ObjCPropertyInfo readUnversioned(internal_key_type Key, 293bb352b6eSEgor Zhdan const uint8_t *&Data) { 294bb352b6eSEgor Zhdan ObjCPropertyInfo Info; 295bb352b6eSEgor Zhdan ReadVariableInfo(Data, Info); 296bb352b6eSEgor Zhdan uint8_t Flags = *Data++; 297bb352b6eSEgor Zhdan if (Flags & (1 << 0)) 298bb352b6eSEgor Zhdan Info.setSwiftImportAsAccessors(Flags & (1 << 1)); 299bb352b6eSEgor Zhdan return Info; 300bb352b6eSEgor Zhdan } 301bb352b6eSEgor Zhdan }; 302bb352b6eSEgor Zhdan 303b8169771SEgor Zhdan /// Used to deserialize the on-disk C record field table. 304b8169771SEgor Zhdan class FieldTableInfo 305b8169771SEgor Zhdan : public VersionedTableInfo<FieldTableInfo, SingleDeclTableKey, FieldInfo> { 306b8169771SEgor Zhdan public: 307b8169771SEgor Zhdan static internal_key_type ReadKey(const uint8_t *Data, unsigned Length) { 308b8169771SEgor Zhdan auto CtxID = endian::readNext<uint32_t, llvm::endianness::little>(Data); 309b8169771SEgor Zhdan auto NameID = endian::readNext<uint32_t, llvm::endianness::little>(Data); 310b8169771SEgor Zhdan return {CtxID, NameID}; 311b8169771SEgor Zhdan } 312b8169771SEgor Zhdan 313b8169771SEgor Zhdan hash_value_type ComputeHash(internal_key_type Key) { 314b8169771SEgor Zhdan return static_cast<size_t>(Key.hashValue()); 315b8169771SEgor Zhdan } 316b8169771SEgor Zhdan 317b8169771SEgor Zhdan static FieldInfo readUnversioned(internal_key_type Key, 318b8169771SEgor Zhdan const uint8_t *&Data) { 319b8169771SEgor Zhdan FieldInfo Info; 320b8169771SEgor Zhdan ReadVariableInfo(Data, Info); 321b8169771SEgor Zhdan return Info; 322b8169771SEgor Zhdan } 323b8169771SEgor Zhdan }; 324b8169771SEgor Zhdan 325bb352b6eSEgor Zhdan /// Read serialized ParamInfo. 326bb352b6eSEgor Zhdan void ReadParamInfo(const uint8_t *&Data, ParamInfo &Info) { 327bb352b6eSEgor Zhdan ReadVariableInfo(Data, Info); 328bb352b6eSEgor Zhdan 32989071f35SKazu Hirata uint8_t Payload = endian::readNext<uint8_t, llvm::endianness::little>(Data); 330bb352b6eSEgor Zhdan if (auto RawConvention = Payload & 0x7) { 331bb352b6eSEgor Zhdan auto Convention = static_cast<RetainCountConventionKind>(RawConvention - 1); 332bb352b6eSEgor Zhdan Info.setRetainCountConvention(Convention); 333bb352b6eSEgor Zhdan } 334bb352b6eSEgor Zhdan Payload >>= 3; 335bb352b6eSEgor Zhdan if (Payload & 0x01) 3367ac78f13SGábor Horváth Info.setLifetimebound(Payload & 0x02); 3377ac78f13SGábor Horváth Payload >>= 2; 3387ac78f13SGábor Horváth if (Payload & 0x01) 339bb352b6eSEgor Zhdan Info.setNoEscape(Payload & 0x02); 340bb352b6eSEgor Zhdan Payload >>= 2; 341bb352b6eSEgor Zhdan assert(Payload == 0 && "Bad API notes"); 342bb352b6eSEgor Zhdan } 343bb352b6eSEgor Zhdan 344bb352b6eSEgor Zhdan /// Read serialized FunctionInfo. 345bb352b6eSEgor Zhdan void ReadFunctionInfo(const uint8_t *&Data, FunctionInfo &Info) { 346bb352b6eSEgor Zhdan ReadCommonEntityInfo(Data, Info); 347bb352b6eSEgor Zhdan 34889071f35SKazu Hirata uint8_t Payload = endian::readNext<uint8_t, llvm::endianness::little>(Data); 349bb352b6eSEgor Zhdan if (auto RawConvention = Payload & 0x7) { 350bb352b6eSEgor Zhdan auto Convention = static_cast<RetainCountConventionKind>(RawConvention - 1); 351bb352b6eSEgor Zhdan Info.setRetainCountConvention(Convention); 352bb352b6eSEgor Zhdan } 353bb352b6eSEgor Zhdan Payload >>= 3; 354bb352b6eSEgor Zhdan Info.NullabilityAudited = Payload & 0x1; 355bb352b6eSEgor Zhdan Payload >>= 1; 356bb352b6eSEgor Zhdan assert(Payload == 0 && "Bad API notes"); 357bb352b6eSEgor Zhdan 358bb352b6eSEgor Zhdan Info.NumAdjustedNullable = 35989071f35SKazu Hirata endian::readNext<uint8_t, llvm::endianness::little>(Data); 360bb352b6eSEgor Zhdan Info.NullabilityPayload = 36189071f35SKazu Hirata endian::readNext<uint64_t, llvm::endianness::little>(Data); 362bb352b6eSEgor Zhdan 363bb352b6eSEgor Zhdan unsigned NumParams = 36489071f35SKazu Hirata endian::readNext<uint16_t, llvm::endianness::little>(Data); 365bb352b6eSEgor Zhdan while (NumParams > 0) { 366bb352b6eSEgor Zhdan ParamInfo pi; 367bb352b6eSEgor Zhdan ReadParamInfo(Data, pi); 368bb352b6eSEgor Zhdan Info.Params.push_back(pi); 369bb352b6eSEgor Zhdan --NumParams; 370bb352b6eSEgor Zhdan } 371bb352b6eSEgor Zhdan 372bb352b6eSEgor Zhdan unsigned ResultTypeLen = 37389071f35SKazu Hirata endian::readNext<uint16_t, llvm::endianness::little>(Data); 374bb352b6eSEgor Zhdan Info.ResultType = std::string(Data, Data + ResultTypeLen); 375bb352b6eSEgor Zhdan Data += ResultTypeLen; 37648f7f63aSfahadnayyar 37748f7f63aSfahadnayyar unsigned SwiftReturnOwnershipLength = 37848f7f63aSfahadnayyar endian::readNext<uint16_t, llvm::endianness::little>(Data); 37948f7f63aSfahadnayyar Info.SwiftReturnOwnership = std::string(reinterpret_cast<const char *>(Data), 38048f7f63aSfahadnayyar reinterpret_cast<const char *>(Data) + 38148f7f63aSfahadnayyar SwiftReturnOwnershipLength); 38248f7f63aSfahadnayyar Data += SwiftReturnOwnershipLength; 383bb352b6eSEgor Zhdan } 384bb352b6eSEgor Zhdan 385bb352b6eSEgor Zhdan /// Used to deserialize the on-disk Objective-C method table. 386bb352b6eSEgor Zhdan class ObjCMethodTableInfo 387bb352b6eSEgor Zhdan : public VersionedTableInfo<ObjCMethodTableInfo, 388bb352b6eSEgor Zhdan std::tuple<uint32_t, uint32_t, uint8_t>, 389bb352b6eSEgor Zhdan ObjCMethodInfo> { 390bb352b6eSEgor Zhdan public: 391bb352b6eSEgor Zhdan static internal_key_type ReadKey(const uint8_t *Data, unsigned Length) { 39289071f35SKazu Hirata auto ClassID = endian::readNext<uint32_t, llvm::endianness::little>(Data); 393bb352b6eSEgor Zhdan auto SelectorID = 39489071f35SKazu Hirata endian::readNext<uint32_t, llvm::endianness::little>(Data); 39589071f35SKazu Hirata auto IsInstance = endian::readNext<uint8_t, llvm::endianness::little>(Data); 396bb352b6eSEgor Zhdan return {ClassID, SelectorID, IsInstance}; 397bb352b6eSEgor Zhdan } 398bb352b6eSEgor Zhdan 399bb352b6eSEgor Zhdan hash_value_type ComputeHash(internal_key_type Key) { 400bb352b6eSEgor Zhdan return static_cast<size_t>(llvm::hash_value(Key)); 401bb352b6eSEgor Zhdan } 402bb352b6eSEgor Zhdan 403bb352b6eSEgor Zhdan static ObjCMethodInfo readUnversioned(internal_key_type Key, 404bb352b6eSEgor Zhdan const uint8_t *&Data) { 405bb352b6eSEgor Zhdan ObjCMethodInfo Info; 406bb352b6eSEgor Zhdan uint8_t Payload = *Data++; 4075f4e3a3cSGábor Horváth bool HasSelf = Payload & 0x01; 4085f4e3a3cSGábor Horváth Payload >>= 1; 409bb352b6eSEgor Zhdan Info.RequiredInit = Payload & 0x01; 410bb352b6eSEgor Zhdan Payload >>= 1; 411bb352b6eSEgor Zhdan Info.DesignatedInit = Payload & 0x01; 412bb352b6eSEgor Zhdan Payload >>= 1; 4135f4e3a3cSGábor Horváth assert(Payload == 0 && "Unable to fully decode 'Payload'."); 414bb352b6eSEgor Zhdan 415bb352b6eSEgor Zhdan ReadFunctionInfo(Data, Info); 4165f4e3a3cSGábor Horváth if (HasSelf) { 4175f4e3a3cSGábor Horváth Info.Self = ParamInfo{}; 4185f4e3a3cSGábor Horváth ReadParamInfo(Data, *Info.Self); 4195f4e3a3cSGábor Horváth } 420bb352b6eSEgor Zhdan return Info; 421bb352b6eSEgor Zhdan } 422bb352b6eSEgor Zhdan }; 423bb352b6eSEgor Zhdan 424bb352b6eSEgor Zhdan /// Used to deserialize the on-disk Objective-C selector table. 425bb352b6eSEgor Zhdan class ObjCSelectorTableInfo { 426bb352b6eSEgor Zhdan public: 427bb352b6eSEgor Zhdan using internal_key_type = StoredObjCSelector; 428bb352b6eSEgor Zhdan using external_key_type = internal_key_type; 429bb352b6eSEgor Zhdan using data_type = SelectorID; 430bb352b6eSEgor Zhdan using hash_value_type = unsigned; 431bb352b6eSEgor Zhdan using offset_type = unsigned; 432bb352b6eSEgor Zhdan 433bb352b6eSEgor Zhdan internal_key_type GetInternalKey(external_key_type Key) { return Key; } 434bb352b6eSEgor Zhdan 435bb352b6eSEgor Zhdan external_key_type GetExternalKey(internal_key_type Key) { return Key; } 436bb352b6eSEgor Zhdan 437bb352b6eSEgor Zhdan hash_value_type ComputeHash(internal_key_type Key) { 438bb352b6eSEgor Zhdan return llvm::DenseMapInfo<StoredObjCSelector>::getHashValue(Key); 439bb352b6eSEgor Zhdan } 440bb352b6eSEgor Zhdan 441bb352b6eSEgor Zhdan static bool EqualKey(internal_key_type LHS, internal_key_type RHS) { 442bb352b6eSEgor Zhdan return llvm::DenseMapInfo<StoredObjCSelector>::isEqual(LHS, RHS); 443bb352b6eSEgor Zhdan } 444bb352b6eSEgor Zhdan 445bb352b6eSEgor Zhdan static std::pair<unsigned, unsigned> ReadKeyDataLength(const uint8_t *&Data) { 446bb352b6eSEgor Zhdan unsigned KeyLength = 44789071f35SKazu Hirata endian::readNext<uint16_t, llvm::endianness::little>(Data); 448bb352b6eSEgor Zhdan unsigned DataLength = 44989071f35SKazu Hirata endian::readNext<uint16_t, llvm::endianness::little>(Data); 450bb352b6eSEgor Zhdan return {KeyLength, DataLength}; 451bb352b6eSEgor Zhdan } 452bb352b6eSEgor Zhdan 453bb352b6eSEgor Zhdan static internal_key_type ReadKey(const uint8_t *Data, unsigned Length) { 454bb352b6eSEgor Zhdan internal_key_type Key; 45589071f35SKazu Hirata Key.NumArgs = endian::readNext<uint16_t, llvm::endianness::little>(Data); 456bb352b6eSEgor Zhdan unsigned NumIdents = (Length - sizeof(uint16_t)) / sizeof(uint32_t); 457bb352b6eSEgor Zhdan for (unsigned i = 0; i != NumIdents; ++i) { 458bb352b6eSEgor Zhdan Key.Identifiers.push_back( 45989071f35SKazu Hirata endian::readNext<uint32_t, llvm::endianness::little>(Data)); 460bb352b6eSEgor Zhdan } 461bb352b6eSEgor Zhdan return Key; 462bb352b6eSEgor Zhdan } 463bb352b6eSEgor Zhdan 464bb352b6eSEgor Zhdan static data_type ReadData(internal_key_type Key, const uint8_t *Data, 465bb352b6eSEgor Zhdan unsigned Length) { 46689071f35SKazu Hirata return endian::readNext<uint32_t, llvm::endianness::little>(Data); 467bb352b6eSEgor Zhdan } 468bb352b6eSEgor Zhdan }; 469bb352b6eSEgor Zhdan 470bb352b6eSEgor Zhdan /// Used to deserialize the on-disk global variable table. 471bb352b6eSEgor Zhdan class GlobalVariableTableInfo 472c5f402f9SEgor Zhdan : public VersionedTableInfo<GlobalVariableTableInfo, SingleDeclTableKey, 473bb352b6eSEgor Zhdan GlobalVariableInfo> { 474bb352b6eSEgor Zhdan public: 475bb352b6eSEgor Zhdan static internal_key_type ReadKey(const uint8_t *Data, unsigned Length) { 47689071f35SKazu Hirata auto CtxID = endian::readNext<uint32_t, llvm::endianness::little>(Data); 47789071f35SKazu Hirata auto NameID = endian::readNext<uint32_t, llvm::endianness::little>(Data); 478c5f402f9SEgor Zhdan return {CtxID, NameID}; 479bb352b6eSEgor Zhdan } 480bb352b6eSEgor Zhdan 481bb352b6eSEgor Zhdan hash_value_type ComputeHash(internal_key_type Key) { 482bb352b6eSEgor Zhdan return static_cast<size_t>(Key.hashValue()); 483bb352b6eSEgor Zhdan } 484bb352b6eSEgor Zhdan 485bb352b6eSEgor Zhdan static GlobalVariableInfo readUnversioned(internal_key_type Key, 486bb352b6eSEgor Zhdan const uint8_t *&Data) { 487bb352b6eSEgor Zhdan GlobalVariableInfo Info; 488bb352b6eSEgor Zhdan ReadVariableInfo(Data, Info); 489bb352b6eSEgor Zhdan return Info; 490bb352b6eSEgor Zhdan } 491bb352b6eSEgor Zhdan }; 492bb352b6eSEgor Zhdan 493bb352b6eSEgor Zhdan /// Used to deserialize the on-disk global function table. 494bb352b6eSEgor Zhdan class GlobalFunctionTableInfo 495c5f402f9SEgor Zhdan : public VersionedTableInfo<GlobalFunctionTableInfo, SingleDeclTableKey, 496bb352b6eSEgor Zhdan GlobalFunctionInfo> { 497bb352b6eSEgor Zhdan public: 498bb352b6eSEgor Zhdan static internal_key_type ReadKey(const uint8_t *Data, unsigned Length) { 49989071f35SKazu Hirata auto CtxID = endian::readNext<uint32_t, llvm::endianness::little>(Data); 50089071f35SKazu Hirata auto NameID = endian::readNext<uint32_t, llvm::endianness::little>(Data); 501c5f402f9SEgor Zhdan return {CtxID, NameID}; 502bb352b6eSEgor Zhdan } 503bb352b6eSEgor Zhdan 504bb352b6eSEgor Zhdan hash_value_type ComputeHash(internal_key_type Key) { 505bb352b6eSEgor Zhdan return static_cast<size_t>(Key.hashValue()); 506bb352b6eSEgor Zhdan } 507bb352b6eSEgor Zhdan 508bb352b6eSEgor Zhdan static GlobalFunctionInfo readUnversioned(internal_key_type Key, 509bb352b6eSEgor Zhdan const uint8_t *&Data) { 510bb352b6eSEgor Zhdan GlobalFunctionInfo Info; 511bb352b6eSEgor Zhdan ReadFunctionInfo(Data, Info); 512bb352b6eSEgor Zhdan return Info; 513bb352b6eSEgor Zhdan } 514bb352b6eSEgor Zhdan }; 515bb352b6eSEgor Zhdan 5168a79dc7eSEgor Zhdan /// Used to deserialize the on-disk C++ method table. 5178a79dc7eSEgor Zhdan class CXXMethodTableInfo 5188a79dc7eSEgor Zhdan : public VersionedTableInfo<CXXMethodTableInfo, SingleDeclTableKey, 5198a79dc7eSEgor Zhdan CXXMethodInfo> { 5208a79dc7eSEgor Zhdan public: 5218a79dc7eSEgor Zhdan static internal_key_type ReadKey(const uint8_t *Data, unsigned Length) { 5228a79dc7eSEgor Zhdan auto CtxID = endian::readNext<uint32_t, llvm::endianness::little>(Data); 5238a79dc7eSEgor Zhdan auto NameID = endian::readNext<uint32_t, llvm::endianness::little>(Data); 5248a79dc7eSEgor Zhdan return {CtxID, NameID}; 5258a79dc7eSEgor Zhdan } 5268a79dc7eSEgor Zhdan 5278a79dc7eSEgor Zhdan hash_value_type ComputeHash(internal_key_type Key) { 5288a79dc7eSEgor Zhdan return static_cast<size_t>(Key.hashValue()); 5298a79dc7eSEgor Zhdan } 5308a79dc7eSEgor Zhdan 5318a79dc7eSEgor Zhdan static CXXMethodInfo readUnversioned(internal_key_type Key, 5328a79dc7eSEgor Zhdan const uint8_t *&Data) { 5338a79dc7eSEgor Zhdan CXXMethodInfo Info; 5345f4e3a3cSGábor Horváth 5355f4e3a3cSGábor Horváth uint8_t Payload = *Data++; 5365f4e3a3cSGábor Horváth bool HasThis = Payload & 0x01; 5375f4e3a3cSGábor Horváth Payload >>= 1; 5385f4e3a3cSGábor Horváth assert(Payload == 0 && "Unable to fully decode 'Payload'."); 5395f4e3a3cSGábor Horváth 5408a79dc7eSEgor Zhdan ReadFunctionInfo(Data, Info); 5415f4e3a3cSGábor Horváth if (HasThis) { 5425f4e3a3cSGábor Horváth Info.This = ParamInfo{}; 5435f4e3a3cSGábor Horváth ReadParamInfo(Data, *Info.This); 5445f4e3a3cSGábor Horváth } 5458a79dc7eSEgor Zhdan return Info; 5468a79dc7eSEgor Zhdan } 5478a79dc7eSEgor Zhdan }; 5488a79dc7eSEgor Zhdan 549bb352b6eSEgor Zhdan /// Used to deserialize the on-disk enumerator table. 550bb352b6eSEgor Zhdan class EnumConstantTableInfo 551bb352b6eSEgor Zhdan : public VersionedTableInfo<EnumConstantTableInfo, uint32_t, 552bb352b6eSEgor Zhdan EnumConstantInfo> { 553bb352b6eSEgor Zhdan public: 554bb352b6eSEgor Zhdan static internal_key_type ReadKey(const uint8_t *Data, unsigned Length) { 55589071f35SKazu Hirata auto NameID = endian::readNext<uint32_t, llvm::endianness::little>(Data); 556bb352b6eSEgor Zhdan return NameID; 557bb352b6eSEgor Zhdan } 558bb352b6eSEgor Zhdan 559bb352b6eSEgor Zhdan hash_value_type ComputeHash(internal_key_type Key) { 560bb352b6eSEgor Zhdan return static_cast<size_t>(llvm::hash_value(Key)); 561bb352b6eSEgor Zhdan } 562bb352b6eSEgor Zhdan 563bb352b6eSEgor Zhdan static EnumConstantInfo readUnversioned(internal_key_type Key, 564bb352b6eSEgor Zhdan const uint8_t *&Data) { 565bb352b6eSEgor Zhdan EnumConstantInfo Info; 566bb352b6eSEgor Zhdan ReadCommonEntityInfo(Data, Info); 567bb352b6eSEgor Zhdan return Info; 568bb352b6eSEgor Zhdan } 569bb352b6eSEgor Zhdan }; 570bb352b6eSEgor Zhdan 571bb352b6eSEgor Zhdan /// Used to deserialize the on-disk tag table. 572bb352b6eSEgor Zhdan class TagTableInfo 573c5f402f9SEgor Zhdan : public VersionedTableInfo<TagTableInfo, SingleDeclTableKey, TagInfo> { 574bb352b6eSEgor Zhdan public: 575bb352b6eSEgor Zhdan static internal_key_type ReadKey(const uint8_t *Data, unsigned Length) { 57689071f35SKazu Hirata auto CtxID = endian::readNext<uint32_t, llvm::endianness::little>(Data); 577bb352b6eSEgor Zhdan auto NameID = 57889071f35SKazu Hirata endian::readNext<IdentifierID, llvm::endianness::little>(Data); 579c5f402f9SEgor Zhdan return {CtxID, NameID}; 580bb352b6eSEgor Zhdan } 581bb352b6eSEgor Zhdan 582bb352b6eSEgor Zhdan hash_value_type ComputeHash(internal_key_type Key) { 583bb352b6eSEgor Zhdan return static_cast<size_t>(Key.hashValue()); 584bb352b6eSEgor Zhdan } 585bb352b6eSEgor Zhdan 586bb352b6eSEgor Zhdan static TagInfo readUnversioned(internal_key_type Key, const uint8_t *&Data) { 587bb352b6eSEgor Zhdan TagInfo Info; 588bb352b6eSEgor Zhdan 589bb352b6eSEgor Zhdan uint8_t Payload = *Data++; 590bb352b6eSEgor Zhdan if (Payload & 1) 591bb352b6eSEgor Zhdan Info.setFlagEnum(Payload & 2); 592bb352b6eSEgor Zhdan Payload >>= 2; 593bb352b6eSEgor Zhdan if (Payload > 0) 594bb352b6eSEgor Zhdan Info.EnumExtensibility = 595bb352b6eSEgor Zhdan static_cast<EnumExtensibilityKind>((Payload & 0x3) - 1); 596bb352b6eSEgor Zhdan 597b2098db2SEgor Zhdan uint8_t Copyable = 598b2098db2SEgor Zhdan endian::readNext<uint8_t, llvm::endianness::little>(Data); 599d2db9bd7SGábor Horváth if (Copyable == kSwiftConforms || Copyable == kSwiftDoesNotConform) 600d2db9bd7SGábor Horváth Info.setSwiftCopyable(std::optional(Copyable == kSwiftConforms)); 601d2db9bd7SGábor Horváth uint8_t Escapable = 602d2db9bd7SGábor Horváth endian::readNext<uint8_t, llvm::endianness::little>(Data); 603d2db9bd7SGábor Horváth if (Escapable == kSwiftConforms || Escapable == kSwiftDoesNotConform) 604d2db9bd7SGábor Horváth Info.setSwiftEscapable(std::optional(Escapable == kSwiftConforms)); 605b2098db2SEgor Zhdan 606bb352b6eSEgor Zhdan unsigned ImportAsLength = 60789071f35SKazu Hirata endian::readNext<uint16_t, llvm::endianness::little>(Data); 608bb352b6eSEgor Zhdan if (ImportAsLength > 0) { 609bb352b6eSEgor Zhdan Info.SwiftImportAs = 610bb352b6eSEgor Zhdan std::string(reinterpret_cast<const char *>(Data), ImportAsLength - 1); 611bb352b6eSEgor Zhdan Data += ImportAsLength - 1; 612bb352b6eSEgor Zhdan } 613bb352b6eSEgor Zhdan unsigned RetainOpLength = 61489071f35SKazu Hirata endian::readNext<uint16_t, llvm::endianness::little>(Data); 615bb352b6eSEgor Zhdan if (RetainOpLength > 0) { 616bb352b6eSEgor Zhdan Info.SwiftRetainOp = 617bb352b6eSEgor Zhdan std::string(reinterpret_cast<const char *>(Data), RetainOpLength - 1); 618bb352b6eSEgor Zhdan Data += RetainOpLength - 1; 619bb352b6eSEgor Zhdan } 620bb352b6eSEgor Zhdan unsigned ReleaseOpLength = 62189071f35SKazu Hirata endian::readNext<uint16_t, llvm::endianness::little>(Data); 622bb352b6eSEgor Zhdan if (ReleaseOpLength > 0) { 623bb352b6eSEgor Zhdan Info.SwiftReleaseOp = std::string(reinterpret_cast<const char *>(Data), 624bb352b6eSEgor Zhdan ReleaseOpLength - 1); 625bb352b6eSEgor Zhdan Data += ReleaseOpLength - 1; 626bb352b6eSEgor Zhdan } 627dc8c217dSEgor Zhdan if (unsigned ConformanceLength = 628dc8c217dSEgor Zhdan endian::readNext<uint16_t, llvm::endianness::little>(Data)) { 629dc8c217dSEgor Zhdan Info.SwiftConformance = std::string(reinterpret_cast<const char *>(Data), 630dc8c217dSEgor Zhdan ConformanceLength - 1); 631dc8c217dSEgor Zhdan Data += ConformanceLength - 1; 632dc8c217dSEgor Zhdan } 633bb352b6eSEgor Zhdan 634bb352b6eSEgor Zhdan ReadCommonTypeInfo(Data, Info); 635bb352b6eSEgor Zhdan return Info; 636bb352b6eSEgor Zhdan } 637bb352b6eSEgor Zhdan }; 638bb352b6eSEgor Zhdan 639bb352b6eSEgor Zhdan /// Used to deserialize the on-disk typedef table. 640bb352b6eSEgor Zhdan class TypedefTableInfo 641c5f402f9SEgor Zhdan : public VersionedTableInfo<TypedefTableInfo, SingleDeclTableKey, 642bb352b6eSEgor Zhdan TypedefInfo> { 643bb352b6eSEgor Zhdan public: 644bb352b6eSEgor Zhdan static internal_key_type ReadKey(const uint8_t *Data, unsigned Length) { 64589071f35SKazu Hirata auto CtxID = endian::readNext<uint32_t, llvm::endianness::little>(Data); 646bb352b6eSEgor Zhdan auto nameID = 64789071f35SKazu Hirata endian::readNext<IdentifierID, llvm::endianness::little>(Data); 648c5f402f9SEgor Zhdan return {CtxID, nameID}; 649bb352b6eSEgor Zhdan } 650bb352b6eSEgor Zhdan 651bb352b6eSEgor Zhdan hash_value_type ComputeHash(internal_key_type Key) { 652bb352b6eSEgor Zhdan return static_cast<size_t>(Key.hashValue()); 653bb352b6eSEgor Zhdan } 654bb352b6eSEgor Zhdan 655bb352b6eSEgor Zhdan static TypedefInfo readUnversioned(internal_key_type Key, 656bb352b6eSEgor Zhdan const uint8_t *&Data) { 657bb352b6eSEgor Zhdan TypedefInfo Info; 658bb352b6eSEgor Zhdan 659bb352b6eSEgor Zhdan uint8_t Payload = *Data++; 660bb352b6eSEgor Zhdan if (Payload > 0) 661bb352b6eSEgor Zhdan Info.SwiftWrapper = static_cast<SwiftNewTypeKind>((Payload & 0x3) - 1); 662bb352b6eSEgor Zhdan 663bb352b6eSEgor Zhdan ReadCommonTypeInfo(Data, Info); 664bb352b6eSEgor Zhdan return Info; 665bb352b6eSEgor Zhdan } 666bb352b6eSEgor Zhdan }; 667bb352b6eSEgor Zhdan } // end anonymous namespace 668bb352b6eSEgor Zhdan 669bb352b6eSEgor Zhdan class APINotesReader::Implementation { 670bb352b6eSEgor Zhdan public: 671bb352b6eSEgor Zhdan /// The input buffer for the API notes data. 672bb352b6eSEgor Zhdan llvm::MemoryBuffer *InputBuffer; 673bb352b6eSEgor Zhdan 674bb352b6eSEgor Zhdan /// The Swift version to use for filtering. 675bb352b6eSEgor Zhdan llvm::VersionTuple SwiftVersion; 676bb352b6eSEgor Zhdan 677bb352b6eSEgor Zhdan /// The name of the module that we read from the control block. 678bb352b6eSEgor Zhdan std::string ModuleName; 679bb352b6eSEgor Zhdan 680bb352b6eSEgor Zhdan // The size and modification time of the source file from 681bb352b6eSEgor Zhdan // which this API notes file was created, if known. 682bb352b6eSEgor Zhdan std::optional<std::pair<off_t, time_t>> SourceFileSizeAndModTime; 683bb352b6eSEgor Zhdan 684bb352b6eSEgor Zhdan using SerializedIdentifierTable = 685bb352b6eSEgor Zhdan llvm::OnDiskIterableChainedHashTable<IdentifierTableInfo>; 686bb352b6eSEgor Zhdan 687bb352b6eSEgor Zhdan /// The identifier table. 688bb352b6eSEgor Zhdan std::unique_ptr<SerializedIdentifierTable> IdentifierTable; 689bb352b6eSEgor Zhdan 69082ee7ae3SEgor Zhdan using SerializedContextIDTable = 69182ee7ae3SEgor Zhdan llvm::OnDiskIterableChainedHashTable<ContextIDTableInfo>; 692bb352b6eSEgor Zhdan 69382ee7ae3SEgor Zhdan /// The Objective-C / C++ context ID table. 69482ee7ae3SEgor Zhdan std::unique_ptr<SerializedContextIDTable> ContextIDTable; 695bb352b6eSEgor Zhdan 69682ee7ae3SEgor Zhdan using SerializedContextInfoTable = 69782ee7ae3SEgor Zhdan llvm::OnDiskIterableChainedHashTable<ContextInfoTableInfo>; 698bb352b6eSEgor Zhdan 699bb352b6eSEgor Zhdan /// The Objective-C context info table. 70082ee7ae3SEgor Zhdan std::unique_ptr<SerializedContextInfoTable> ContextInfoTable; 701bb352b6eSEgor Zhdan 702bb352b6eSEgor Zhdan using SerializedObjCPropertyTable = 703bb352b6eSEgor Zhdan llvm::OnDiskIterableChainedHashTable<ObjCPropertyTableInfo>; 704bb352b6eSEgor Zhdan 705bb352b6eSEgor Zhdan /// The Objective-C property table. 706bb352b6eSEgor Zhdan std::unique_ptr<SerializedObjCPropertyTable> ObjCPropertyTable; 707bb352b6eSEgor Zhdan 708b8169771SEgor Zhdan using SerializedFieldTable = 709b8169771SEgor Zhdan llvm::OnDiskIterableChainedHashTable<FieldTableInfo>; 710b8169771SEgor Zhdan 711b8169771SEgor Zhdan /// The C record field table. 712b8169771SEgor Zhdan std::unique_ptr<SerializedFieldTable> FieldTable; 713b8169771SEgor Zhdan 714bb352b6eSEgor Zhdan using SerializedObjCMethodTable = 715bb352b6eSEgor Zhdan llvm::OnDiskIterableChainedHashTable<ObjCMethodTableInfo>; 716bb352b6eSEgor Zhdan 717bb352b6eSEgor Zhdan /// The Objective-C method table. 718bb352b6eSEgor Zhdan std::unique_ptr<SerializedObjCMethodTable> ObjCMethodTable; 719bb352b6eSEgor Zhdan 7208a79dc7eSEgor Zhdan using SerializedCXXMethodTable = 7218a79dc7eSEgor Zhdan llvm::OnDiskIterableChainedHashTable<CXXMethodTableInfo>; 7228a79dc7eSEgor Zhdan 7238a79dc7eSEgor Zhdan /// The C++ method table. 7248a79dc7eSEgor Zhdan std::unique_ptr<SerializedCXXMethodTable> CXXMethodTable; 7258a79dc7eSEgor Zhdan 726bb352b6eSEgor Zhdan using SerializedObjCSelectorTable = 727bb352b6eSEgor Zhdan llvm::OnDiskIterableChainedHashTable<ObjCSelectorTableInfo>; 728bb352b6eSEgor Zhdan 729bb352b6eSEgor Zhdan /// The Objective-C selector table. 730bb352b6eSEgor Zhdan std::unique_ptr<SerializedObjCSelectorTable> ObjCSelectorTable; 731bb352b6eSEgor Zhdan 732bb352b6eSEgor Zhdan using SerializedGlobalVariableTable = 733bb352b6eSEgor Zhdan llvm::OnDiskIterableChainedHashTable<GlobalVariableTableInfo>; 734bb352b6eSEgor Zhdan 735bb352b6eSEgor Zhdan /// The global variable table. 736bb352b6eSEgor Zhdan std::unique_ptr<SerializedGlobalVariableTable> GlobalVariableTable; 737bb352b6eSEgor Zhdan 738bb352b6eSEgor Zhdan using SerializedGlobalFunctionTable = 739bb352b6eSEgor Zhdan llvm::OnDiskIterableChainedHashTable<GlobalFunctionTableInfo>; 740bb352b6eSEgor Zhdan 741bb352b6eSEgor Zhdan /// The global function table. 742bb352b6eSEgor Zhdan std::unique_ptr<SerializedGlobalFunctionTable> GlobalFunctionTable; 743bb352b6eSEgor Zhdan 744bb352b6eSEgor Zhdan using SerializedEnumConstantTable = 745bb352b6eSEgor Zhdan llvm::OnDiskIterableChainedHashTable<EnumConstantTableInfo>; 746bb352b6eSEgor Zhdan 747bb352b6eSEgor Zhdan /// The enumerator table. 748bb352b6eSEgor Zhdan std::unique_ptr<SerializedEnumConstantTable> EnumConstantTable; 749bb352b6eSEgor Zhdan 750bb352b6eSEgor Zhdan using SerializedTagTable = llvm::OnDiskIterableChainedHashTable<TagTableInfo>; 751bb352b6eSEgor Zhdan 752bb352b6eSEgor Zhdan /// The tag table. 753bb352b6eSEgor Zhdan std::unique_ptr<SerializedTagTable> TagTable; 754bb352b6eSEgor Zhdan 755bb352b6eSEgor Zhdan using SerializedTypedefTable = 756bb352b6eSEgor Zhdan llvm::OnDiskIterableChainedHashTable<TypedefTableInfo>; 757bb352b6eSEgor Zhdan 758bb352b6eSEgor Zhdan /// The typedef table. 759bb352b6eSEgor Zhdan std::unique_ptr<SerializedTypedefTable> TypedefTable; 760bb352b6eSEgor Zhdan 761bb352b6eSEgor Zhdan /// Retrieve the identifier ID for the given string, or an empty 762bb352b6eSEgor Zhdan /// optional if the string is unknown. 763bb352b6eSEgor Zhdan std::optional<IdentifierID> getIdentifier(llvm::StringRef Str); 764bb352b6eSEgor Zhdan 765bb352b6eSEgor Zhdan /// Retrieve the selector ID for the given selector, or an empty 766bb352b6eSEgor Zhdan /// optional if the string is unknown. 767bb352b6eSEgor Zhdan std::optional<SelectorID> getSelector(ObjCSelectorRef Selector); 768bb352b6eSEgor Zhdan 769bb352b6eSEgor Zhdan bool readControlBlock(llvm::BitstreamCursor &Cursor, 770bb352b6eSEgor Zhdan llvm::SmallVectorImpl<uint64_t> &Scratch); 771bb352b6eSEgor Zhdan bool readIdentifierBlock(llvm::BitstreamCursor &Cursor, 772bb352b6eSEgor Zhdan llvm::SmallVectorImpl<uint64_t> &Scratch); 77382ee7ae3SEgor Zhdan bool readContextBlock(llvm::BitstreamCursor &Cursor, 774bb352b6eSEgor Zhdan llvm::SmallVectorImpl<uint64_t> &Scratch); 775bb352b6eSEgor Zhdan bool readObjCPropertyBlock(llvm::BitstreamCursor &Cursor, 776bb352b6eSEgor Zhdan llvm::SmallVectorImpl<uint64_t> &Scratch); 777bb352b6eSEgor Zhdan bool readObjCMethodBlock(llvm::BitstreamCursor &Cursor, 778bb352b6eSEgor Zhdan llvm::SmallVectorImpl<uint64_t> &Scratch); 7798a79dc7eSEgor Zhdan bool readCXXMethodBlock(llvm::BitstreamCursor &Cursor, 7808a79dc7eSEgor Zhdan llvm::SmallVectorImpl<uint64_t> &Scratch); 781b8169771SEgor Zhdan bool readFieldBlock(llvm::BitstreamCursor &Cursor, 782b8169771SEgor Zhdan llvm::SmallVectorImpl<uint64_t> &Scratch); 783bb352b6eSEgor Zhdan bool readObjCSelectorBlock(llvm::BitstreamCursor &Cursor, 784bb352b6eSEgor Zhdan llvm::SmallVectorImpl<uint64_t> &Scratch); 785bb352b6eSEgor Zhdan bool readGlobalVariableBlock(llvm::BitstreamCursor &Cursor, 786bb352b6eSEgor Zhdan llvm::SmallVectorImpl<uint64_t> &Scratch); 787bb352b6eSEgor Zhdan bool readGlobalFunctionBlock(llvm::BitstreamCursor &Cursor, 788bb352b6eSEgor Zhdan llvm::SmallVectorImpl<uint64_t> &Scratch); 789bb352b6eSEgor Zhdan bool readEnumConstantBlock(llvm::BitstreamCursor &Cursor, 790bb352b6eSEgor Zhdan llvm::SmallVectorImpl<uint64_t> &Scratch); 791bb352b6eSEgor Zhdan bool readTagBlock(llvm::BitstreamCursor &Cursor, 792bb352b6eSEgor Zhdan llvm::SmallVectorImpl<uint64_t> &Scratch); 793bb352b6eSEgor Zhdan bool readTypedefBlock(llvm::BitstreamCursor &Cursor, 794bb352b6eSEgor Zhdan llvm::SmallVectorImpl<uint64_t> &Scratch); 795bb352b6eSEgor Zhdan }; 796bb352b6eSEgor Zhdan 797bb352b6eSEgor Zhdan std::optional<IdentifierID> 798bb352b6eSEgor Zhdan APINotesReader::Implementation::getIdentifier(llvm::StringRef Str) { 799bb352b6eSEgor Zhdan if (!IdentifierTable) 800bb352b6eSEgor Zhdan return std::nullopt; 801bb352b6eSEgor Zhdan 802bb352b6eSEgor Zhdan if (Str.empty()) 803bb352b6eSEgor Zhdan return IdentifierID(0); 804bb352b6eSEgor Zhdan 805bb352b6eSEgor Zhdan auto Known = IdentifierTable->find(Str); 806bb352b6eSEgor Zhdan if (Known == IdentifierTable->end()) 807bb352b6eSEgor Zhdan return std::nullopt; 808bb352b6eSEgor Zhdan 809bb352b6eSEgor Zhdan return *Known; 810bb352b6eSEgor Zhdan } 811bb352b6eSEgor Zhdan 812bb352b6eSEgor Zhdan std::optional<SelectorID> 813bb352b6eSEgor Zhdan APINotesReader::Implementation::getSelector(ObjCSelectorRef Selector) { 814bb352b6eSEgor Zhdan if (!ObjCSelectorTable || !IdentifierTable) 815bb352b6eSEgor Zhdan return std::nullopt; 816bb352b6eSEgor Zhdan 817bb352b6eSEgor Zhdan // Translate the identifiers. 818bb352b6eSEgor Zhdan StoredObjCSelector Key; 81941021e8eSEgor Zhdan Key.NumArgs = Selector.NumArgs; 820bb352b6eSEgor Zhdan for (auto Ident : Selector.Identifiers) { 821bb352b6eSEgor Zhdan if (auto IdentID = getIdentifier(Ident)) { 822bb352b6eSEgor Zhdan Key.Identifiers.push_back(*IdentID); 823bb352b6eSEgor Zhdan } else { 824bb352b6eSEgor Zhdan return std::nullopt; 825bb352b6eSEgor Zhdan } 826bb352b6eSEgor Zhdan } 827bb352b6eSEgor Zhdan 828bb352b6eSEgor Zhdan auto Known = ObjCSelectorTable->find(Key); 829bb352b6eSEgor Zhdan if (Known == ObjCSelectorTable->end()) 830bb352b6eSEgor Zhdan return std::nullopt; 831bb352b6eSEgor Zhdan 832bb352b6eSEgor Zhdan return *Known; 833bb352b6eSEgor Zhdan } 834bb352b6eSEgor Zhdan 835bb352b6eSEgor Zhdan bool APINotesReader::Implementation::readControlBlock( 836bb352b6eSEgor Zhdan llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl<uint64_t> &Scratch) { 837bb352b6eSEgor Zhdan if (Cursor.EnterSubBlock(CONTROL_BLOCK_ID)) 838bb352b6eSEgor Zhdan return true; 839bb352b6eSEgor Zhdan 840bb352b6eSEgor Zhdan bool SawMetadata = false; 841bb352b6eSEgor Zhdan 842bb352b6eSEgor Zhdan llvm::Expected<llvm::BitstreamEntry> MaybeNext = Cursor.advance(); 843bb352b6eSEgor Zhdan if (!MaybeNext) { 844bb352b6eSEgor Zhdan // FIXME this drops the error on the floor. 845bb352b6eSEgor Zhdan consumeError(MaybeNext.takeError()); 846bb352b6eSEgor Zhdan return false; 847bb352b6eSEgor Zhdan } 848bb352b6eSEgor Zhdan llvm::BitstreamEntry Next = MaybeNext.get(); 849bb352b6eSEgor Zhdan 850bb352b6eSEgor Zhdan while (Next.Kind != llvm::BitstreamEntry::EndBlock) { 851bb352b6eSEgor Zhdan if (Next.Kind == llvm::BitstreamEntry::Error) 852bb352b6eSEgor Zhdan return true; 853bb352b6eSEgor Zhdan 854bb352b6eSEgor Zhdan if (Next.Kind == llvm::BitstreamEntry::SubBlock) { 855bb352b6eSEgor Zhdan // Unknown metadata sub-block, possibly for use by a future version of the 856bb352b6eSEgor Zhdan // API notes format. 857bb352b6eSEgor Zhdan if (Cursor.SkipBlock()) 858bb352b6eSEgor Zhdan return true; 859bb352b6eSEgor Zhdan 860bb352b6eSEgor Zhdan MaybeNext = Cursor.advance(); 861bb352b6eSEgor Zhdan if (!MaybeNext) { 862bb352b6eSEgor Zhdan // FIXME this drops the error on the floor. 863bb352b6eSEgor Zhdan consumeError(MaybeNext.takeError()); 864bb352b6eSEgor Zhdan return false; 865bb352b6eSEgor Zhdan } 866bb352b6eSEgor Zhdan Next = MaybeNext.get(); 867bb352b6eSEgor Zhdan continue; 868bb352b6eSEgor Zhdan } 869bb352b6eSEgor Zhdan 870bb352b6eSEgor Zhdan Scratch.clear(); 871bb352b6eSEgor Zhdan llvm::StringRef BlobData; 872bb352b6eSEgor Zhdan llvm::Expected<unsigned> MaybeKind = 873bb352b6eSEgor Zhdan Cursor.readRecord(Next.ID, Scratch, &BlobData); 874bb352b6eSEgor Zhdan if (!MaybeKind) { 875bb352b6eSEgor Zhdan // FIXME this drops the error on the floor. 876bb352b6eSEgor Zhdan consumeError(MaybeKind.takeError()); 877bb352b6eSEgor Zhdan return false; 878bb352b6eSEgor Zhdan } 879bb352b6eSEgor Zhdan unsigned Kind = MaybeKind.get(); 880bb352b6eSEgor Zhdan 881bb352b6eSEgor Zhdan switch (Kind) { 882bb352b6eSEgor Zhdan case control_block::METADATA: 883bb352b6eSEgor Zhdan // Already saw metadata. 884bb352b6eSEgor Zhdan if (SawMetadata) 885bb352b6eSEgor Zhdan return true; 886bb352b6eSEgor Zhdan 887bb352b6eSEgor Zhdan if (Scratch[0] != VERSION_MAJOR || Scratch[1] != VERSION_MINOR) 888bb352b6eSEgor Zhdan return true; 889bb352b6eSEgor Zhdan 890bb352b6eSEgor Zhdan SawMetadata = true; 891bb352b6eSEgor Zhdan break; 892bb352b6eSEgor Zhdan 893bb352b6eSEgor Zhdan case control_block::MODULE_NAME: 894bb352b6eSEgor Zhdan ModuleName = BlobData.str(); 895bb352b6eSEgor Zhdan break; 896bb352b6eSEgor Zhdan 897bb352b6eSEgor Zhdan case control_block::MODULE_OPTIONS: 898bb352b6eSEgor Zhdan break; 899bb352b6eSEgor Zhdan 900bb352b6eSEgor Zhdan case control_block::SOURCE_FILE: 901bb352b6eSEgor Zhdan SourceFileSizeAndModTime = {Scratch[0], Scratch[1]}; 902bb352b6eSEgor Zhdan break; 903bb352b6eSEgor Zhdan 904bb352b6eSEgor Zhdan default: 905bb352b6eSEgor Zhdan // Unknown metadata record, possibly for use by a future version of the 906bb352b6eSEgor Zhdan // module format. 907bb352b6eSEgor Zhdan break; 908bb352b6eSEgor Zhdan } 909bb352b6eSEgor Zhdan 910bb352b6eSEgor Zhdan MaybeNext = Cursor.advance(); 911bb352b6eSEgor Zhdan if (!MaybeNext) { 912bb352b6eSEgor Zhdan // FIXME this drops the error on the floor. 913bb352b6eSEgor Zhdan consumeError(MaybeNext.takeError()); 914bb352b6eSEgor Zhdan return false; 915bb352b6eSEgor Zhdan } 916bb352b6eSEgor Zhdan Next = MaybeNext.get(); 917bb352b6eSEgor Zhdan } 918bb352b6eSEgor Zhdan 919bb352b6eSEgor Zhdan return !SawMetadata; 920bb352b6eSEgor Zhdan } 921bb352b6eSEgor Zhdan 922bb352b6eSEgor Zhdan bool APINotesReader::Implementation::readIdentifierBlock( 923bb352b6eSEgor Zhdan llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl<uint64_t> &Scratch) { 924bb352b6eSEgor Zhdan if (Cursor.EnterSubBlock(IDENTIFIER_BLOCK_ID)) 925bb352b6eSEgor Zhdan return true; 926bb352b6eSEgor Zhdan 927bb352b6eSEgor Zhdan llvm::Expected<llvm::BitstreamEntry> MaybeNext = Cursor.advance(); 928bb352b6eSEgor Zhdan if (!MaybeNext) { 929bb352b6eSEgor Zhdan // FIXME this drops the error on the floor. 930bb352b6eSEgor Zhdan consumeError(MaybeNext.takeError()); 931bb352b6eSEgor Zhdan return false; 932bb352b6eSEgor Zhdan } 933bb352b6eSEgor Zhdan llvm::BitstreamEntry Next = MaybeNext.get(); 934bb352b6eSEgor Zhdan 935bb352b6eSEgor Zhdan while (Next.Kind != llvm::BitstreamEntry::EndBlock) { 936bb352b6eSEgor Zhdan if (Next.Kind == llvm::BitstreamEntry::Error) 937bb352b6eSEgor Zhdan return true; 938bb352b6eSEgor Zhdan 939bb352b6eSEgor Zhdan if (Next.Kind == llvm::BitstreamEntry::SubBlock) { 940bb352b6eSEgor Zhdan // Unknown sub-block, possibly for use by a future version of the 941bb352b6eSEgor Zhdan // API notes format. 942bb352b6eSEgor Zhdan if (Cursor.SkipBlock()) 943bb352b6eSEgor Zhdan return true; 944bb352b6eSEgor Zhdan 945bb352b6eSEgor Zhdan MaybeNext = Cursor.advance(); 946bb352b6eSEgor Zhdan if (!MaybeNext) { 947bb352b6eSEgor Zhdan // FIXME this drops the error on the floor. 948bb352b6eSEgor Zhdan consumeError(MaybeNext.takeError()); 949bb352b6eSEgor Zhdan return false; 950bb352b6eSEgor Zhdan } 951bb352b6eSEgor Zhdan Next = MaybeNext.get(); 952bb352b6eSEgor Zhdan continue; 953bb352b6eSEgor Zhdan } 954bb352b6eSEgor Zhdan 955bb352b6eSEgor Zhdan Scratch.clear(); 956bb352b6eSEgor Zhdan llvm::StringRef BlobData; 957bb352b6eSEgor Zhdan llvm::Expected<unsigned> MaybeKind = 958bb352b6eSEgor Zhdan Cursor.readRecord(Next.ID, Scratch, &BlobData); 959bb352b6eSEgor Zhdan if (!MaybeKind) { 960bb352b6eSEgor Zhdan // FIXME this drops the error on the floor. 961bb352b6eSEgor Zhdan consumeError(MaybeKind.takeError()); 962bb352b6eSEgor Zhdan return false; 963bb352b6eSEgor Zhdan } 964bb352b6eSEgor Zhdan unsigned Kind = MaybeKind.get(); 965bb352b6eSEgor Zhdan switch (Kind) { 966bb352b6eSEgor Zhdan case identifier_block::IDENTIFIER_DATA: { 967bb352b6eSEgor Zhdan // Already saw identifier table. 968bb352b6eSEgor Zhdan if (IdentifierTable) 969bb352b6eSEgor Zhdan return true; 970bb352b6eSEgor Zhdan 971bb352b6eSEgor Zhdan uint32_t tableOffset; 972bb352b6eSEgor Zhdan identifier_block::IdentifierDataLayout::readRecord(Scratch, tableOffset); 973bb352b6eSEgor Zhdan auto base = reinterpret_cast<const uint8_t *>(BlobData.data()); 974bb352b6eSEgor Zhdan 975bb352b6eSEgor Zhdan IdentifierTable.reset(SerializedIdentifierTable::Create( 976bb352b6eSEgor Zhdan base + tableOffset, base + sizeof(uint32_t), base)); 977bb352b6eSEgor Zhdan break; 978bb352b6eSEgor Zhdan } 979bb352b6eSEgor Zhdan 980bb352b6eSEgor Zhdan default: 981bb352b6eSEgor Zhdan // Unknown record, possibly for use by a future version of the 982bb352b6eSEgor Zhdan // module format. 983bb352b6eSEgor Zhdan break; 984bb352b6eSEgor Zhdan } 985bb352b6eSEgor Zhdan 986bb352b6eSEgor Zhdan MaybeNext = Cursor.advance(); 987bb352b6eSEgor Zhdan if (!MaybeNext) { 988bb352b6eSEgor Zhdan // FIXME this drops the error on the floor. 989bb352b6eSEgor Zhdan consumeError(MaybeNext.takeError()); 990bb352b6eSEgor Zhdan return false; 991bb352b6eSEgor Zhdan } 992bb352b6eSEgor Zhdan Next = MaybeNext.get(); 993bb352b6eSEgor Zhdan } 994bb352b6eSEgor Zhdan 995bb352b6eSEgor Zhdan return false; 996bb352b6eSEgor Zhdan } 997bb352b6eSEgor Zhdan 99882ee7ae3SEgor Zhdan bool APINotesReader::Implementation::readContextBlock( 999bb352b6eSEgor Zhdan llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl<uint64_t> &Scratch) { 1000bb352b6eSEgor Zhdan if (Cursor.EnterSubBlock(OBJC_CONTEXT_BLOCK_ID)) 1001bb352b6eSEgor Zhdan return true; 1002bb352b6eSEgor Zhdan 1003bb352b6eSEgor Zhdan llvm::Expected<llvm::BitstreamEntry> MaybeNext = Cursor.advance(); 1004bb352b6eSEgor Zhdan if (!MaybeNext) { 1005bb352b6eSEgor Zhdan // FIXME this drops the error on the floor. 1006bb352b6eSEgor Zhdan consumeError(MaybeNext.takeError()); 1007bb352b6eSEgor Zhdan return false; 1008bb352b6eSEgor Zhdan } 1009bb352b6eSEgor Zhdan llvm::BitstreamEntry Next = MaybeNext.get(); 1010bb352b6eSEgor Zhdan 1011bb352b6eSEgor Zhdan while (Next.Kind != llvm::BitstreamEntry::EndBlock) { 1012bb352b6eSEgor Zhdan if (Next.Kind == llvm::BitstreamEntry::Error) 1013bb352b6eSEgor Zhdan return true; 1014bb352b6eSEgor Zhdan 1015bb352b6eSEgor Zhdan if (Next.Kind == llvm::BitstreamEntry::SubBlock) { 1016bb352b6eSEgor Zhdan // Unknown sub-block, possibly for use by a future version of the 1017bb352b6eSEgor Zhdan // API notes format. 1018bb352b6eSEgor Zhdan if (Cursor.SkipBlock()) 1019bb352b6eSEgor Zhdan return true; 1020bb352b6eSEgor Zhdan 1021bb352b6eSEgor Zhdan MaybeNext = Cursor.advance(); 1022bb352b6eSEgor Zhdan if (!MaybeNext) { 1023bb352b6eSEgor Zhdan // FIXME this drops the error on the floor. 1024bb352b6eSEgor Zhdan consumeError(MaybeNext.takeError()); 1025bb352b6eSEgor Zhdan return false; 1026bb352b6eSEgor Zhdan } 1027bb352b6eSEgor Zhdan Next = MaybeNext.get(); 1028bb352b6eSEgor Zhdan continue; 1029bb352b6eSEgor Zhdan } 1030bb352b6eSEgor Zhdan 1031bb352b6eSEgor Zhdan Scratch.clear(); 1032bb352b6eSEgor Zhdan llvm::StringRef BlobData; 1033bb352b6eSEgor Zhdan llvm::Expected<unsigned> MaybeKind = 1034bb352b6eSEgor Zhdan Cursor.readRecord(Next.ID, Scratch, &BlobData); 1035bb352b6eSEgor Zhdan if (!MaybeKind) { 1036bb352b6eSEgor Zhdan // FIXME this drops the error on the floor. 1037bb352b6eSEgor Zhdan consumeError(MaybeKind.takeError()); 1038bb352b6eSEgor Zhdan return false; 1039bb352b6eSEgor Zhdan } 1040bb352b6eSEgor Zhdan unsigned Kind = MaybeKind.get(); 1041bb352b6eSEgor Zhdan switch (Kind) { 104282ee7ae3SEgor Zhdan case context_block::CONTEXT_ID_DATA: { 104382ee7ae3SEgor Zhdan // Already saw Objective-C / C++ context ID table. 104482ee7ae3SEgor Zhdan if (ContextIDTable) 1045bb352b6eSEgor Zhdan return true; 1046bb352b6eSEgor Zhdan 1047bb352b6eSEgor Zhdan uint32_t tableOffset; 104882ee7ae3SEgor Zhdan context_block::ContextIDLayout::readRecord(Scratch, tableOffset); 1049bb352b6eSEgor Zhdan auto base = reinterpret_cast<const uint8_t *>(BlobData.data()); 1050bb352b6eSEgor Zhdan 105182ee7ae3SEgor Zhdan ContextIDTable.reset(SerializedContextIDTable::Create( 1052bb352b6eSEgor Zhdan base + tableOffset, base + sizeof(uint32_t), base)); 1053bb352b6eSEgor Zhdan break; 1054bb352b6eSEgor Zhdan } 1055bb352b6eSEgor Zhdan 105682ee7ae3SEgor Zhdan case context_block::CONTEXT_INFO_DATA: { 105782ee7ae3SEgor Zhdan // Already saw Objective-C / C++ context info table. 105882ee7ae3SEgor Zhdan if (ContextInfoTable) 1059bb352b6eSEgor Zhdan return true; 1060bb352b6eSEgor Zhdan 1061bb352b6eSEgor Zhdan uint32_t tableOffset; 106282ee7ae3SEgor Zhdan context_block::ContextInfoLayout::readRecord(Scratch, tableOffset); 1063bb352b6eSEgor Zhdan auto base = reinterpret_cast<const uint8_t *>(BlobData.data()); 1064bb352b6eSEgor Zhdan 106582ee7ae3SEgor Zhdan ContextInfoTable.reset(SerializedContextInfoTable::Create( 1066bb352b6eSEgor Zhdan base + tableOffset, base + sizeof(uint32_t), base)); 1067bb352b6eSEgor Zhdan break; 1068bb352b6eSEgor Zhdan } 1069bb352b6eSEgor Zhdan 1070bb352b6eSEgor Zhdan default: 1071bb352b6eSEgor Zhdan // Unknown record, possibly for use by a future version of the 1072bb352b6eSEgor Zhdan // module format. 1073bb352b6eSEgor Zhdan break; 1074bb352b6eSEgor Zhdan } 1075bb352b6eSEgor Zhdan 1076bb352b6eSEgor Zhdan MaybeNext = Cursor.advance(); 1077bb352b6eSEgor Zhdan if (!MaybeNext) { 1078bb352b6eSEgor Zhdan // FIXME this drops the error on the floor. 1079bb352b6eSEgor Zhdan consumeError(MaybeNext.takeError()); 1080bb352b6eSEgor Zhdan return false; 1081bb352b6eSEgor Zhdan } 1082bb352b6eSEgor Zhdan Next = MaybeNext.get(); 1083bb352b6eSEgor Zhdan } 1084bb352b6eSEgor Zhdan 1085bb352b6eSEgor Zhdan return false; 1086bb352b6eSEgor Zhdan } 1087bb352b6eSEgor Zhdan 1088bb352b6eSEgor Zhdan bool APINotesReader::Implementation::readObjCPropertyBlock( 1089bb352b6eSEgor Zhdan llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl<uint64_t> &Scratch) { 1090bb352b6eSEgor Zhdan if (Cursor.EnterSubBlock(OBJC_PROPERTY_BLOCK_ID)) 1091bb352b6eSEgor Zhdan return true; 1092bb352b6eSEgor Zhdan 1093bb352b6eSEgor Zhdan llvm::Expected<llvm::BitstreamEntry> MaybeNext = Cursor.advance(); 1094bb352b6eSEgor Zhdan if (!MaybeNext) { 1095bb352b6eSEgor Zhdan // FIXME this drops the error on the floor. 1096bb352b6eSEgor Zhdan consumeError(MaybeNext.takeError()); 1097bb352b6eSEgor Zhdan return false; 1098bb352b6eSEgor Zhdan } 1099bb352b6eSEgor Zhdan llvm::BitstreamEntry Next = MaybeNext.get(); 1100bb352b6eSEgor Zhdan 1101bb352b6eSEgor Zhdan while (Next.Kind != llvm::BitstreamEntry::EndBlock) { 1102bb352b6eSEgor Zhdan if (Next.Kind == llvm::BitstreamEntry::Error) 1103bb352b6eSEgor Zhdan return true; 1104bb352b6eSEgor Zhdan 1105bb352b6eSEgor Zhdan if (Next.Kind == llvm::BitstreamEntry::SubBlock) { 1106bb352b6eSEgor Zhdan // Unknown sub-block, possibly for use by a future version of the 1107bb352b6eSEgor Zhdan // API notes format. 1108bb352b6eSEgor Zhdan if (Cursor.SkipBlock()) 1109bb352b6eSEgor Zhdan return true; 1110bb352b6eSEgor Zhdan 1111bb352b6eSEgor Zhdan MaybeNext = Cursor.advance(); 1112bb352b6eSEgor Zhdan if (!MaybeNext) { 1113bb352b6eSEgor Zhdan // FIXME this drops the error on the floor. 1114bb352b6eSEgor Zhdan consumeError(MaybeNext.takeError()); 1115bb352b6eSEgor Zhdan return false; 1116bb352b6eSEgor Zhdan } 1117bb352b6eSEgor Zhdan Next = MaybeNext.get(); 1118bb352b6eSEgor Zhdan continue; 1119bb352b6eSEgor Zhdan } 1120bb352b6eSEgor Zhdan 1121bb352b6eSEgor Zhdan Scratch.clear(); 1122bb352b6eSEgor Zhdan llvm::StringRef BlobData; 1123bb352b6eSEgor Zhdan llvm::Expected<unsigned> MaybeKind = 1124bb352b6eSEgor Zhdan Cursor.readRecord(Next.ID, Scratch, &BlobData); 1125bb352b6eSEgor Zhdan if (!MaybeKind) { 1126bb352b6eSEgor Zhdan // FIXME this drops the error on the floor. 1127bb352b6eSEgor Zhdan consumeError(MaybeKind.takeError()); 1128bb352b6eSEgor Zhdan return false; 1129bb352b6eSEgor Zhdan } 1130bb352b6eSEgor Zhdan unsigned Kind = MaybeKind.get(); 1131bb352b6eSEgor Zhdan switch (Kind) { 1132bb352b6eSEgor Zhdan case objc_property_block::OBJC_PROPERTY_DATA: { 1133bb352b6eSEgor Zhdan // Already saw Objective-C property table. 1134bb352b6eSEgor Zhdan if (ObjCPropertyTable) 1135bb352b6eSEgor Zhdan return true; 1136bb352b6eSEgor Zhdan 1137bb352b6eSEgor Zhdan uint32_t tableOffset; 1138bb352b6eSEgor Zhdan objc_property_block::ObjCPropertyDataLayout::readRecord(Scratch, 1139bb352b6eSEgor Zhdan tableOffset); 1140bb352b6eSEgor Zhdan auto base = reinterpret_cast<const uint8_t *>(BlobData.data()); 1141bb352b6eSEgor Zhdan 1142bb352b6eSEgor Zhdan ObjCPropertyTable.reset(SerializedObjCPropertyTable::Create( 1143bb352b6eSEgor Zhdan base + tableOffset, base + sizeof(uint32_t), base)); 1144bb352b6eSEgor Zhdan break; 1145bb352b6eSEgor Zhdan } 1146bb352b6eSEgor Zhdan 1147bb352b6eSEgor Zhdan default: 1148bb352b6eSEgor Zhdan // Unknown record, possibly for use by a future version of the 1149bb352b6eSEgor Zhdan // module format. 1150bb352b6eSEgor Zhdan break; 1151bb352b6eSEgor Zhdan } 1152bb352b6eSEgor Zhdan 1153bb352b6eSEgor Zhdan MaybeNext = Cursor.advance(); 1154bb352b6eSEgor Zhdan if (!MaybeNext) { 1155bb352b6eSEgor Zhdan // FIXME this drops the error on the floor. 1156bb352b6eSEgor Zhdan consumeError(MaybeNext.takeError()); 1157bb352b6eSEgor Zhdan return false; 1158bb352b6eSEgor Zhdan } 1159bb352b6eSEgor Zhdan Next = MaybeNext.get(); 1160bb352b6eSEgor Zhdan } 1161bb352b6eSEgor Zhdan 1162bb352b6eSEgor Zhdan return false; 1163bb352b6eSEgor Zhdan } 1164bb352b6eSEgor Zhdan 1165bb352b6eSEgor Zhdan bool APINotesReader::Implementation::readObjCMethodBlock( 1166bb352b6eSEgor Zhdan llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl<uint64_t> &Scratch) { 1167bb352b6eSEgor Zhdan if (Cursor.EnterSubBlock(OBJC_METHOD_BLOCK_ID)) 1168bb352b6eSEgor Zhdan return true; 1169bb352b6eSEgor Zhdan 1170bb352b6eSEgor Zhdan llvm::Expected<llvm::BitstreamEntry> MaybeNext = Cursor.advance(); 1171bb352b6eSEgor Zhdan if (!MaybeNext) { 1172bb352b6eSEgor Zhdan // FIXME this drops the error on the floor. 1173bb352b6eSEgor Zhdan consumeError(MaybeNext.takeError()); 1174bb352b6eSEgor Zhdan return false; 1175bb352b6eSEgor Zhdan } 1176bb352b6eSEgor Zhdan llvm::BitstreamEntry Next = MaybeNext.get(); 1177bb352b6eSEgor Zhdan while (Next.Kind != llvm::BitstreamEntry::EndBlock) { 1178bb352b6eSEgor Zhdan if (Next.Kind == llvm::BitstreamEntry::Error) 1179bb352b6eSEgor Zhdan return true; 1180bb352b6eSEgor Zhdan 1181bb352b6eSEgor Zhdan if (Next.Kind == llvm::BitstreamEntry::SubBlock) { 1182bb352b6eSEgor Zhdan // Unknown sub-block, possibly for use by a future version of the 1183bb352b6eSEgor Zhdan // API notes format. 1184bb352b6eSEgor Zhdan if (Cursor.SkipBlock()) 1185bb352b6eSEgor Zhdan return true; 1186bb352b6eSEgor Zhdan 1187bb352b6eSEgor Zhdan MaybeNext = Cursor.advance(); 1188bb352b6eSEgor Zhdan if (!MaybeNext) { 1189bb352b6eSEgor Zhdan // FIXME this drops the error on the floor. 1190bb352b6eSEgor Zhdan consumeError(MaybeNext.takeError()); 1191bb352b6eSEgor Zhdan return false; 1192bb352b6eSEgor Zhdan } 1193bb352b6eSEgor Zhdan Next = MaybeNext.get(); 1194bb352b6eSEgor Zhdan continue; 1195bb352b6eSEgor Zhdan } 1196bb352b6eSEgor Zhdan 1197bb352b6eSEgor Zhdan Scratch.clear(); 1198bb352b6eSEgor Zhdan llvm::StringRef BlobData; 1199bb352b6eSEgor Zhdan llvm::Expected<unsigned> MaybeKind = 1200bb352b6eSEgor Zhdan Cursor.readRecord(Next.ID, Scratch, &BlobData); 1201bb352b6eSEgor Zhdan if (!MaybeKind) { 1202bb352b6eSEgor Zhdan // FIXME this drops the error on the floor. 1203bb352b6eSEgor Zhdan consumeError(MaybeKind.takeError()); 1204bb352b6eSEgor Zhdan return false; 1205bb352b6eSEgor Zhdan } 1206bb352b6eSEgor Zhdan unsigned Kind = MaybeKind.get(); 1207bb352b6eSEgor Zhdan switch (Kind) { 1208bb352b6eSEgor Zhdan case objc_method_block::OBJC_METHOD_DATA: { 1209bb352b6eSEgor Zhdan // Already saw Objective-C method table. 1210bb352b6eSEgor Zhdan if (ObjCMethodTable) 1211bb352b6eSEgor Zhdan return true; 1212bb352b6eSEgor Zhdan 1213bb352b6eSEgor Zhdan uint32_t tableOffset; 1214bb352b6eSEgor Zhdan objc_method_block::ObjCMethodDataLayout::readRecord(Scratch, tableOffset); 1215bb352b6eSEgor Zhdan auto base = reinterpret_cast<const uint8_t *>(BlobData.data()); 1216bb352b6eSEgor Zhdan 1217bb352b6eSEgor Zhdan ObjCMethodTable.reset(SerializedObjCMethodTable::Create( 1218bb352b6eSEgor Zhdan base + tableOffset, base + sizeof(uint32_t), base)); 1219bb352b6eSEgor Zhdan break; 1220bb352b6eSEgor Zhdan } 1221bb352b6eSEgor Zhdan 1222bb352b6eSEgor Zhdan default: 1223bb352b6eSEgor Zhdan // Unknown record, possibly for use by a future version of the 1224bb352b6eSEgor Zhdan // module format. 1225bb352b6eSEgor Zhdan break; 1226bb352b6eSEgor Zhdan } 1227bb352b6eSEgor Zhdan 1228bb352b6eSEgor Zhdan MaybeNext = Cursor.advance(); 1229bb352b6eSEgor Zhdan if (!MaybeNext) { 1230bb352b6eSEgor Zhdan // FIXME this drops the error on the floor. 1231bb352b6eSEgor Zhdan consumeError(MaybeNext.takeError()); 1232bb352b6eSEgor Zhdan return false; 1233bb352b6eSEgor Zhdan } 1234bb352b6eSEgor Zhdan Next = MaybeNext.get(); 1235bb352b6eSEgor Zhdan } 1236bb352b6eSEgor Zhdan 1237bb352b6eSEgor Zhdan return false; 1238bb352b6eSEgor Zhdan } 1239bb352b6eSEgor Zhdan 12408a79dc7eSEgor Zhdan bool APINotesReader::Implementation::readCXXMethodBlock( 12418a79dc7eSEgor Zhdan llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl<uint64_t> &Scratch) { 12428a79dc7eSEgor Zhdan if (Cursor.EnterSubBlock(CXX_METHOD_BLOCK_ID)) 12438a79dc7eSEgor Zhdan return true; 12448a79dc7eSEgor Zhdan 12458a79dc7eSEgor Zhdan llvm::Expected<llvm::BitstreamEntry> MaybeNext = Cursor.advance(); 12468a79dc7eSEgor Zhdan if (!MaybeNext) { 12478a79dc7eSEgor Zhdan // FIXME this drops the error on the floor. 12488a79dc7eSEgor Zhdan consumeError(MaybeNext.takeError()); 12498a79dc7eSEgor Zhdan return false; 12508a79dc7eSEgor Zhdan } 12518a79dc7eSEgor Zhdan llvm::BitstreamEntry Next = MaybeNext.get(); 12528a79dc7eSEgor Zhdan while (Next.Kind != llvm::BitstreamEntry::EndBlock) { 12538a79dc7eSEgor Zhdan if (Next.Kind == llvm::BitstreamEntry::Error) 12548a79dc7eSEgor Zhdan return true; 12558a79dc7eSEgor Zhdan 12568a79dc7eSEgor Zhdan if (Next.Kind == llvm::BitstreamEntry::SubBlock) { 12578a79dc7eSEgor Zhdan // Unknown sub-block, possibly for use by a future version of the 12588a79dc7eSEgor Zhdan // API notes format. 12598a79dc7eSEgor Zhdan if (Cursor.SkipBlock()) 12608a79dc7eSEgor Zhdan return true; 12618a79dc7eSEgor Zhdan 12628a79dc7eSEgor Zhdan MaybeNext = Cursor.advance(); 12638a79dc7eSEgor Zhdan if (!MaybeNext) { 12648a79dc7eSEgor Zhdan // FIXME this drops the error on the floor. 12658a79dc7eSEgor Zhdan consumeError(MaybeNext.takeError()); 12668a79dc7eSEgor Zhdan return false; 12678a79dc7eSEgor Zhdan } 12688a79dc7eSEgor Zhdan Next = MaybeNext.get(); 12698a79dc7eSEgor Zhdan continue; 12708a79dc7eSEgor Zhdan } 12718a79dc7eSEgor Zhdan 12728a79dc7eSEgor Zhdan Scratch.clear(); 12738a79dc7eSEgor Zhdan llvm::StringRef BlobData; 12748a79dc7eSEgor Zhdan llvm::Expected<unsigned> MaybeKind = 12758a79dc7eSEgor Zhdan Cursor.readRecord(Next.ID, Scratch, &BlobData); 12768a79dc7eSEgor Zhdan if (!MaybeKind) { 12778a79dc7eSEgor Zhdan // FIXME this drops the error on the floor. 12788a79dc7eSEgor Zhdan consumeError(MaybeKind.takeError()); 12798a79dc7eSEgor Zhdan return false; 12808a79dc7eSEgor Zhdan } 12818a79dc7eSEgor Zhdan unsigned Kind = MaybeKind.get(); 12828a79dc7eSEgor Zhdan switch (Kind) { 12838a79dc7eSEgor Zhdan case cxx_method_block::CXX_METHOD_DATA: { 12848a79dc7eSEgor Zhdan // Already saw C++ method table. 12858a79dc7eSEgor Zhdan if (CXXMethodTable) 12868a79dc7eSEgor Zhdan return true; 12878a79dc7eSEgor Zhdan 12888a79dc7eSEgor Zhdan uint32_t tableOffset; 12898a79dc7eSEgor Zhdan cxx_method_block::CXXMethodDataLayout::readRecord(Scratch, tableOffset); 12908a79dc7eSEgor Zhdan auto base = reinterpret_cast<const uint8_t *>(BlobData.data()); 12918a79dc7eSEgor Zhdan 12928a79dc7eSEgor Zhdan CXXMethodTable.reset(SerializedCXXMethodTable::Create( 12938a79dc7eSEgor Zhdan base + tableOffset, base + sizeof(uint32_t), base)); 12948a79dc7eSEgor Zhdan break; 12958a79dc7eSEgor Zhdan } 12968a79dc7eSEgor Zhdan 12978a79dc7eSEgor Zhdan default: 12988a79dc7eSEgor Zhdan // Unknown record, possibly for use by a future version of the 12998a79dc7eSEgor Zhdan // module format. 13008a79dc7eSEgor Zhdan break; 13018a79dc7eSEgor Zhdan } 13028a79dc7eSEgor Zhdan 13038a79dc7eSEgor Zhdan MaybeNext = Cursor.advance(); 13048a79dc7eSEgor Zhdan if (!MaybeNext) { 13058a79dc7eSEgor Zhdan // FIXME this drops the error on the floor. 13068a79dc7eSEgor Zhdan consumeError(MaybeNext.takeError()); 13078a79dc7eSEgor Zhdan return false; 13088a79dc7eSEgor Zhdan } 13098a79dc7eSEgor Zhdan Next = MaybeNext.get(); 13108a79dc7eSEgor Zhdan } 13118a79dc7eSEgor Zhdan 13128a79dc7eSEgor Zhdan return false; 13138a79dc7eSEgor Zhdan } 13148a79dc7eSEgor Zhdan 1315b8169771SEgor Zhdan bool APINotesReader::Implementation::readFieldBlock( 1316b8169771SEgor Zhdan llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl<uint64_t> &Scratch) { 1317b8169771SEgor Zhdan if (Cursor.EnterSubBlock(FIELD_BLOCK_ID)) 1318b8169771SEgor Zhdan return true; 1319b8169771SEgor Zhdan 1320b8169771SEgor Zhdan llvm::Expected<llvm::BitstreamEntry> MaybeNext = Cursor.advance(); 1321b8169771SEgor Zhdan if (!MaybeNext) { 1322b8169771SEgor Zhdan // FIXME this drops the error on the floor. 1323b8169771SEgor Zhdan consumeError(MaybeNext.takeError()); 1324b8169771SEgor Zhdan return false; 1325b8169771SEgor Zhdan } 1326b8169771SEgor Zhdan llvm::BitstreamEntry Next = MaybeNext.get(); 1327b8169771SEgor Zhdan while (Next.Kind != llvm::BitstreamEntry::EndBlock) { 1328b8169771SEgor Zhdan if (Next.Kind == llvm::BitstreamEntry::Error) 1329b8169771SEgor Zhdan return true; 1330b8169771SEgor Zhdan 1331b8169771SEgor Zhdan if (Next.Kind == llvm::BitstreamEntry::SubBlock) { 1332b8169771SEgor Zhdan // Unknown sub-block, possibly for use by a future version of the 1333b8169771SEgor Zhdan // API notes format. 1334b8169771SEgor Zhdan if (Cursor.SkipBlock()) 1335b8169771SEgor Zhdan return true; 1336b8169771SEgor Zhdan 1337b8169771SEgor Zhdan MaybeNext = Cursor.advance(); 1338b8169771SEgor Zhdan if (!MaybeNext) { 1339b8169771SEgor Zhdan // FIXME this drops the error on the floor. 1340b8169771SEgor Zhdan consumeError(MaybeNext.takeError()); 1341b8169771SEgor Zhdan return false; 1342b8169771SEgor Zhdan } 1343b8169771SEgor Zhdan Next = MaybeNext.get(); 1344b8169771SEgor Zhdan continue; 1345b8169771SEgor Zhdan } 1346b8169771SEgor Zhdan 1347b8169771SEgor Zhdan Scratch.clear(); 1348b8169771SEgor Zhdan llvm::StringRef BlobData; 1349b8169771SEgor Zhdan llvm::Expected<unsigned> MaybeKind = 1350b8169771SEgor Zhdan Cursor.readRecord(Next.ID, Scratch, &BlobData); 1351b8169771SEgor Zhdan if (!MaybeKind) { 1352b8169771SEgor Zhdan // FIXME this drops the error on the floor. 1353b8169771SEgor Zhdan consumeError(MaybeKind.takeError()); 1354b8169771SEgor Zhdan return false; 1355b8169771SEgor Zhdan } 1356b8169771SEgor Zhdan unsigned Kind = MaybeKind.get(); 1357b8169771SEgor Zhdan switch (Kind) { 1358b8169771SEgor Zhdan case field_block::FIELD_DATA: { 1359b8169771SEgor Zhdan // Already saw field table. 1360b8169771SEgor Zhdan if (FieldTable) 1361b8169771SEgor Zhdan return true; 1362b8169771SEgor Zhdan 1363b8169771SEgor Zhdan uint32_t tableOffset; 1364b8169771SEgor Zhdan field_block::FieldDataLayout::readRecord(Scratch, tableOffset); 1365b8169771SEgor Zhdan auto base = reinterpret_cast<const uint8_t *>(BlobData.data()); 1366b8169771SEgor Zhdan 1367b8169771SEgor Zhdan FieldTable.reset(SerializedFieldTable::Create( 1368b8169771SEgor Zhdan base + tableOffset, base + sizeof(uint32_t), base)); 1369b8169771SEgor Zhdan break; 1370b8169771SEgor Zhdan } 1371b8169771SEgor Zhdan 1372b8169771SEgor Zhdan default: 1373b8169771SEgor Zhdan // Unknown record, possibly for use by a future version of the 1374b8169771SEgor Zhdan // module format. 1375b8169771SEgor Zhdan break; 1376b8169771SEgor Zhdan } 1377b8169771SEgor Zhdan 1378b8169771SEgor Zhdan MaybeNext = Cursor.advance(); 1379b8169771SEgor Zhdan if (!MaybeNext) { 1380b8169771SEgor Zhdan // FIXME this drops the error on the floor. 1381b8169771SEgor Zhdan consumeError(MaybeNext.takeError()); 1382b8169771SEgor Zhdan return false; 1383b8169771SEgor Zhdan } 1384b8169771SEgor Zhdan Next = MaybeNext.get(); 1385b8169771SEgor Zhdan } 1386b8169771SEgor Zhdan 1387b8169771SEgor Zhdan return false; 1388b8169771SEgor Zhdan } 1389b8169771SEgor Zhdan 1390bb352b6eSEgor Zhdan bool APINotesReader::Implementation::readObjCSelectorBlock( 1391bb352b6eSEgor Zhdan llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl<uint64_t> &Scratch) { 1392bb352b6eSEgor Zhdan if (Cursor.EnterSubBlock(OBJC_SELECTOR_BLOCK_ID)) 1393bb352b6eSEgor Zhdan return true; 1394bb352b6eSEgor Zhdan 1395bb352b6eSEgor Zhdan llvm::Expected<llvm::BitstreamEntry> MaybeNext = Cursor.advance(); 1396bb352b6eSEgor Zhdan if (!MaybeNext) { 1397bb352b6eSEgor Zhdan // FIXME this drops the error on the floor. 1398bb352b6eSEgor Zhdan consumeError(MaybeNext.takeError()); 1399bb352b6eSEgor Zhdan return false; 1400bb352b6eSEgor Zhdan } 1401bb352b6eSEgor Zhdan llvm::BitstreamEntry Next = MaybeNext.get(); 1402bb352b6eSEgor Zhdan while (Next.Kind != llvm::BitstreamEntry::EndBlock) { 1403bb352b6eSEgor Zhdan if (Next.Kind == llvm::BitstreamEntry::Error) 1404bb352b6eSEgor Zhdan return true; 1405bb352b6eSEgor Zhdan 1406bb352b6eSEgor Zhdan if (Next.Kind == llvm::BitstreamEntry::SubBlock) { 1407bb352b6eSEgor Zhdan // Unknown sub-block, possibly for use by a future version of the 1408bb352b6eSEgor Zhdan // API notes format. 1409bb352b6eSEgor Zhdan if (Cursor.SkipBlock()) 1410bb352b6eSEgor Zhdan return true; 1411bb352b6eSEgor Zhdan 1412bb352b6eSEgor Zhdan MaybeNext = Cursor.advance(); 1413bb352b6eSEgor Zhdan if (!MaybeNext) { 1414bb352b6eSEgor Zhdan // FIXME this drops the error on the floor. 1415bb352b6eSEgor Zhdan consumeError(MaybeNext.takeError()); 1416bb352b6eSEgor Zhdan return false; 1417bb352b6eSEgor Zhdan } 1418bb352b6eSEgor Zhdan Next = MaybeNext.get(); 1419bb352b6eSEgor Zhdan continue; 1420bb352b6eSEgor Zhdan } 1421bb352b6eSEgor Zhdan 1422bb352b6eSEgor Zhdan Scratch.clear(); 1423bb352b6eSEgor Zhdan llvm::StringRef BlobData; 1424bb352b6eSEgor Zhdan llvm::Expected<unsigned> MaybeKind = 1425bb352b6eSEgor Zhdan Cursor.readRecord(Next.ID, Scratch, &BlobData); 1426bb352b6eSEgor Zhdan if (!MaybeKind) { 1427bb352b6eSEgor Zhdan // FIXME this drops the error on the floor. 1428bb352b6eSEgor Zhdan consumeError(MaybeKind.takeError()); 1429bb352b6eSEgor Zhdan return false; 1430bb352b6eSEgor Zhdan } 1431bb352b6eSEgor Zhdan unsigned Kind = MaybeKind.get(); 1432bb352b6eSEgor Zhdan switch (Kind) { 1433bb352b6eSEgor Zhdan case objc_selector_block::OBJC_SELECTOR_DATA: { 1434bb352b6eSEgor Zhdan // Already saw Objective-C selector table. 1435bb352b6eSEgor Zhdan if (ObjCSelectorTable) 1436bb352b6eSEgor Zhdan return true; 1437bb352b6eSEgor Zhdan 1438bb352b6eSEgor Zhdan uint32_t tableOffset; 1439bb352b6eSEgor Zhdan objc_selector_block::ObjCSelectorDataLayout::readRecord(Scratch, 1440bb352b6eSEgor Zhdan tableOffset); 1441bb352b6eSEgor Zhdan auto base = reinterpret_cast<const uint8_t *>(BlobData.data()); 1442bb352b6eSEgor Zhdan 1443bb352b6eSEgor Zhdan ObjCSelectorTable.reset(SerializedObjCSelectorTable::Create( 1444bb352b6eSEgor Zhdan base + tableOffset, base + sizeof(uint32_t), base)); 1445bb352b6eSEgor Zhdan break; 1446bb352b6eSEgor Zhdan } 1447bb352b6eSEgor Zhdan 1448bb352b6eSEgor Zhdan default: 1449bb352b6eSEgor Zhdan // Unknown record, possibly for use by a future version of the 1450bb352b6eSEgor Zhdan // module format. 1451bb352b6eSEgor Zhdan break; 1452bb352b6eSEgor Zhdan } 1453bb352b6eSEgor Zhdan 1454bb352b6eSEgor Zhdan MaybeNext = Cursor.advance(); 1455bb352b6eSEgor Zhdan if (!MaybeNext) { 1456bb352b6eSEgor Zhdan // FIXME this drops the error on the floor. 1457bb352b6eSEgor Zhdan consumeError(MaybeNext.takeError()); 1458bb352b6eSEgor Zhdan return false; 1459bb352b6eSEgor Zhdan } 1460bb352b6eSEgor Zhdan Next = MaybeNext.get(); 1461bb352b6eSEgor Zhdan } 1462bb352b6eSEgor Zhdan 1463bb352b6eSEgor Zhdan return false; 1464bb352b6eSEgor Zhdan } 1465bb352b6eSEgor Zhdan 1466bb352b6eSEgor Zhdan bool APINotesReader::Implementation::readGlobalVariableBlock( 1467bb352b6eSEgor Zhdan llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl<uint64_t> &Scratch) { 1468bb352b6eSEgor Zhdan if (Cursor.EnterSubBlock(GLOBAL_VARIABLE_BLOCK_ID)) 1469bb352b6eSEgor Zhdan return true; 1470bb352b6eSEgor Zhdan 1471bb352b6eSEgor Zhdan llvm::Expected<llvm::BitstreamEntry> MaybeNext = Cursor.advance(); 1472bb352b6eSEgor Zhdan if (!MaybeNext) { 1473bb352b6eSEgor Zhdan // FIXME this drops the error on the floor. 1474bb352b6eSEgor Zhdan consumeError(MaybeNext.takeError()); 1475bb352b6eSEgor Zhdan return false; 1476bb352b6eSEgor Zhdan } 1477bb352b6eSEgor Zhdan llvm::BitstreamEntry Next = MaybeNext.get(); 1478bb352b6eSEgor Zhdan while (Next.Kind != llvm::BitstreamEntry::EndBlock) { 1479bb352b6eSEgor Zhdan if (Next.Kind == llvm::BitstreamEntry::Error) 1480bb352b6eSEgor Zhdan return true; 1481bb352b6eSEgor Zhdan 1482bb352b6eSEgor Zhdan if (Next.Kind == llvm::BitstreamEntry::SubBlock) { 1483bb352b6eSEgor Zhdan // Unknown sub-block, possibly for use by a future version of the 1484bb352b6eSEgor Zhdan // API notes format. 1485bb352b6eSEgor Zhdan if (Cursor.SkipBlock()) 1486bb352b6eSEgor Zhdan return true; 1487bb352b6eSEgor Zhdan 1488bb352b6eSEgor Zhdan MaybeNext = Cursor.advance(); 1489bb352b6eSEgor Zhdan if (!MaybeNext) { 1490bb352b6eSEgor Zhdan // FIXME this drops the error on the floor. 1491bb352b6eSEgor Zhdan consumeError(MaybeNext.takeError()); 1492bb352b6eSEgor Zhdan return false; 1493bb352b6eSEgor Zhdan } 1494bb352b6eSEgor Zhdan Next = MaybeNext.get(); 1495bb352b6eSEgor Zhdan continue; 1496bb352b6eSEgor Zhdan } 1497bb352b6eSEgor Zhdan 1498bb352b6eSEgor Zhdan Scratch.clear(); 1499bb352b6eSEgor Zhdan llvm::StringRef BlobData; 1500bb352b6eSEgor Zhdan llvm::Expected<unsigned> MaybeKind = 1501bb352b6eSEgor Zhdan Cursor.readRecord(Next.ID, Scratch, &BlobData); 1502bb352b6eSEgor Zhdan if (!MaybeKind) { 1503bb352b6eSEgor Zhdan // FIXME this drops the error on the floor. 1504bb352b6eSEgor Zhdan consumeError(MaybeKind.takeError()); 1505bb352b6eSEgor Zhdan return false; 1506bb352b6eSEgor Zhdan } 1507bb352b6eSEgor Zhdan unsigned Kind = MaybeKind.get(); 1508bb352b6eSEgor Zhdan switch (Kind) { 1509bb352b6eSEgor Zhdan case global_variable_block::GLOBAL_VARIABLE_DATA: { 1510bb352b6eSEgor Zhdan // Already saw global variable table. 1511bb352b6eSEgor Zhdan if (GlobalVariableTable) 1512bb352b6eSEgor Zhdan return true; 1513bb352b6eSEgor Zhdan 1514bb352b6eSEgor Zhdan uint32_t tableOffset; 1515bb352b6eSEgor Zhdan global_variable_block::GlobalVariableDataLayout::readRecord(Scratch, 1516bb352b6eSEgor Zhdan tableOffset); 1517bb352b6eSEgor Zhdan auto base = reinterpret_cast<const uint8_t *>(BlobData.data()); 1518bb352b6eSEgor Zhdan 1519bb352b6eSEgor Zhdan GlobalVariableTable.reset(SerializedGlobalVariableTable::Create( 1520bb352b6eSEgor Zhdan base + tableOffset, base + sizeof(uint32_t), base)); 1521bb352b6eSEgor Zhdan break; 1522bb352b6eSEgor Zhdan } 1523bb352b6eSEgor Zhdan 1524bb352b6eSEgor Zhdan default: 1525bb352b6eSEgor Zhdan // Unknown record, possibly for use by a future version of the 1526bb352b6eSEgor Zhdan // module format. 1527bb352b6eSEgor Zhdan break; 1528bb352b6eSEgor Zhdan } 1529bb352b6eSEgor Zhdan 1530bb352b6eSEgor Zhdan MaybeNext = Cursor.advance(); 1531bb352b6eSEgor Zhdan if (!MaybeNext) { 1532bb352b6eSEgor Zhdan // FIXME this drops the error on the floor. 1533bb352b6eSEgor Zhdan consumeError(MaybeNext.takeError()); 1534bb352b6eSEgor Zhdan return false; 1535bb352b6eSEgor Zhdan } 1536bb352b6eSEgor Zhdan Next = MaybeNext.get(); 1537bb352b6eSEgor Zhdan } 1538bb352b6eSEgor Zhdan 1539bb352b6eSEgor Zhdan return false; 1540bb352b6eSEgor Zhdan } 1541bb352b6eSEgor Zhdan 1542bb352b6eSEgor Zhdan bool APINotesReader::Implementation::readGlobalFunctionBlock( 1543bb352b6eSEgor Zhdan llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl<uint64_t> &Scratch) { 1544bb352b6eSEgor Zhdan if (Cursor.EnterSubBlock(GLOBAL_FUNCTION_BLOCK_ID)) 1545bb352b6eSEgor Zhdan return true; 1546bb352b6eSEgor Zhdan 1547bb352b6eSEgor Zhdan llvm::Expected<llvm::BitstreamEntry> MaybeNext = Cursor.advance(); 1548bb352b6eSEgor Zhdan if (!MaybeNext) { 1549bb352b6eSEgor Zhdan // FIXME this drops the error on the floor. 1550bb352b6eSEgor Zhdan consumeError(MaybeNext.takeError()); 1551bb352b6eSEgor Zhdan return false; 1552bb352b6eSEgor Zhdan } 1553bb352b6eSEgor Zhdan llvm::BitstreamEntry Next = MaybeNext.get(); 1554bb352b6eSEgor Zhdan while (Next.Kind != llvm::BitstreamEntry::EndBlock) { 1555bb352b6eSEgor Zhdan if (Next.Kind == llvm::BitstreamEntry::Error) 1556bb352b6eSEgor Zhdan return true; 1557bb352b6eSEgor Zhdan 1558bb352b6eSEgor Zhdan if (Next.Kind == llvm::BitstreamEntry::SubBlock) { 1559bb352b6eSEgor Zhdan // Unknown sub-block, possibly for use by a future version of the 1560bb352b6eSEgor Zhdan // API notes format. 1561bb352b6eSEgor Zhdan if (Cursor.SkipBlock()) 1562bb352b6eSEgor Zhdan return true; 1563bb352b6eSEgor Zhdan 1564bb352b6eSEgor Zhdan MaybeNext = Cursor.advance(); 1565bb352b6eSEgor Zhdan if (!MaybeNext) { 1566bb352b6eSEgor Zhdan // FIXME this drops the error on the floor. 1567bb352b6eSEgor Zhdan consumeError(MaybeNext.takeError()); 1568bb352b6eSEgor Zhdan return false; 1569bb352b6eSEgor Zhdan } 1570bb352b6eSEgor Zhdan Next = MaybeNext.get(); 1571bb352b6eSEgor Zhdan continue; 1572bb352b6eSEgor Zhdan } 1573bb352b6eSEgor Zhdan 1574bb352b6eSEgor Zhdan Scratch.clear(); 1575bb352b6eSEgor Zhdan llvm::StringRef BlobData; 1576bb352b6eSEgor Zhdan llvm::Expected<unsigned> MaybeKind = 1577bb352b6eSEgor Zhdan Cursor.readRecord(Next.ID, Scratch, &BlobData); 1578bb352b6eSEgor Zhdan if (!MaybeKind) { 1579bb352b6eSEgor Zhdan // FIXME this drops the error on the floor. 1580bb352b6eSEgor Zhdan consumeError(MaybeKind.takeError()); 1581bb352b6eSEgor Zhdan return false; 1582bb352b6eSEgor Zhdan } 1583bb352b6eSEgor Zhdan unsigned Kind = MaybeKind.get(); 1584bb352b6eSEgor Zhdan switch (Kind) { 1585bb352b6eSEgor Zhdan case global_function_block::GLOBAL_FUNCTION_DATA: { 1586bb352b6eSEgor Zhdan // Already saw global function table. 1587bb352b6eSEgor Zhdan if (GlobalFunctionTable) 1588bb352b6eSEgor Zhdan return true; 1589bb352b6eSEgor Zhdan 1590bb352b6eSEgor Zhdan uint32_t tableOffset; 1591bb352b6eSEgor Zhdan global_function_block::GlobalFunctionDataLayout::readRecord(Scratch, 1592bb352b6eSEgor Zhdan tableOffset); 1593bb352b6eSEgor Zhdan auto base = reinterpret_cast<const uint8_t *>(BlobData.data()); 1594bb352b6eSEgor Zhdan 1595bb352b6eSEgor Zhdan GlobalFunctionTable.reset(SerializedGlobalFunctionTable::Create( 1596bb352b6eSEgor Zhdan base + tableOffset, base + sizeof(uint32_t), base)); 1597bb352b6eSEgor Zhdan break; 1598bb352b6eSEgor Zhdan } 1599bb352b6eSEgor Zhdan 1600bb352b6eSEgor Zhdan default: 1601bb352b6eSEgor Zhdan // Unknown record, possibly for use by a future version of the 1602bb352b6eSEgor Zhdan // module format. 1603bb352b6eSEgor Zhdan break; 1604bb352b6eSEgor Zhdan } 1605bb352b6eSEgor Zhdan 1606bb352b6eSEgor Zhdan MaybeNext = Cursor.advance(); 1607bb352b6eSEgor Zhdan if (!MaybeNext) { 1608bb352b6eSEgor Zhdan // FIXME this drops the error on the floor. 1609bb352b6eSEgor Zhdan consumeError(MaybeNext.takeError()); 1610bb352b6eSEgor Zhdan return false; 1611bb352b6eSEgor Zhdan } 1612bb352b6eSEgor Zhdan Next = MaybeNext.get(); 1613bb352b6eSEgor Zhdan } 1614bb352b6eSEgor Zhdan 1615bb352b6eSEgor Zhdan return false; 1616bb352b6eSEgor Zhdan } 1617bb352b6eSEgor Zhdan 1618bb352b6eSEgor Zhdan bool APINotesReader::Implementation::readEnumConstantBlock( 1619bb352b6eSEgor Zhdan llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl<uint64_t> &Scratch) { 1620bb352b6eSEgor Zhdan if (Cursor.EnterSubBlock(ENUM_CONSTANT_BLOCK_ID)) 1621bb352b6eSEgor Zhdan return true; 1622bb352b6eSEgor Zhdan 1623bb352b6eSEgor Zhdan llvm::Expected<llvm::BitstreamEntry> MaybeNext = Cursor.advance(); 1624bb352b6eSEgor Zhdan if (!MaybeNext) { 1625bb352b6eSEgor Zhdan // FIXME this drops the error on the floor. 1626bb352b6eSEgor Zhdan consumeError(MaybeNext.takeError()); 1627bb352b6eSEgor Zhdan return false; 1628bb352b6eSEgor Zhdan } 1629bb352b6eSEgor Zhdan llvm::BitstreamEntry Next = MaybeNext.get(); 1630bb352b6eSEgor Zhdan while (Next.Kind != llvm::BitstreamEntry::EndBlock) { 1631bb352b6eSEgor Zhdan if (Next.Kind == llvm::BitstreamEntry::Error) 1632bb352b6eSEgor Zhdan return true; 1633bb352b6eSEgor Zhdan 1634bb352b6eSEgor Zhdan if (Next.Kind == llvm::BitstreamEntry::SubBlock) { 1635bb352b6eSEgor Zhdan // Unknown sub-block, possibly for use by a future version of the 1636bb352b6eSEgor Zhdan // API notes format. 1637bb352b6eSEgor Zhdan if (Cursor.SkipBlock()) 1638bb352b6eSEgor Zhdan return true; 1639bb352b6eSEgor Zhdan 1640bb352b6eSEgor Zhdan MaybeNext = Cursor.advance(); 1641bb352b6eSEgor Zhdan if (!MaybeNext) { 1642bb352b6eSEgor Zhdan // FIXME this drops the error on the floor. 1643bb352b6eSEgor Zhdan consumeError(MaybeNext.takeError()); 1644bb352b6eSEgor Zhdan return false; 1645bb352b6eSEgor Zhdan } 1646bb352b6eSEgor Zhdan Next = MaybeNext.get(); 1647bb352b6eSEgor Zhdan continue; 1648bb352b6eSEgor Zhdan } 1649bb352b6eSEgor Zhdan 1650bb352b6eSEgor Zhdan Scratch.clear(); 1651bb352b6eSEgor Zhdan llvm::StringRef BlobData; 1652bb352b6eSEgor Zhdan llvm::Expected<unsigned> MaybeKind = 1653bb352b6eSEgor Zhdan Cursor.readRecord(Next.ID, Scratch, &BlobData); 1654bb352b6eSEgor Zhdan if (!MaybeKind) { 1655bb352b6eSEgor Zhdan // FIXME this drops the error on the floor. 1656bb352b6eSEgor Zhdan consumeError(MaybeKind.takeError()); 1657bb352b6eSEgor Zhdan return false; 1658bb352b6eSEgor Zhdan } 1659bb352b6eSEgor Zhdan unsigned Kind = MaybeKind.get(); 1660bb352b6eSEgor Zhdan switch (Kind) { 1661bb352b6eSEgor Zhdan case enum_constant_block::ENUM_CONSTANT_DATA: { 1662bb352b6eSEgor Zhdan // Already saw enumerator table. 1663bb352b6eSEgor Zhdan if (EnumConstantTable) 1664bb352b6eSEgor Zhdan return true; 1665bb352b6eSEgor Zhdan 1666bb352b6eSEgor Zhdan uint32_t tableOffset; 1667bb352b6eSEgor Zhdan enum_constant_block::EnumConstantDataLayout::readRecord(Scratch, 1668bb352b6eSEgor Zhdan tableOffset); 1669bb352b6eSEgor Zhdan auto base = reinterpret_cast<const uint8_t *>(BlobData.data()); 1670bb352b6eSEgor Zhdan 1671bb352b6eSEgor Zhdan EnumConstantTable.reset(SerializedEnumConstantTable::Create( 1672bb352b6eSEgor Zhdan base + tableOffset, base + sizeof(uint32_t), base)); 1673bb352b6eSEgor Zhdan break; 1674bb352b6eSEgor Zhdan } 1675bb352b6eSEgor Zhdan 1676bb352b6eSEgor Zhdan default: 1677bb352b6eSEgor Zhdan // Unknown record, possibly for use by a future version of the 1678bb352b6eSEgor Zhdan // module format. 1679bb352b6eSEgor Zhdan break; 1680bb352b6eSEgor Zhdan } 1681bb352b6eSEgor Zhdan 1682bb352b6eSEgor Zhdan MaybeNext = Cursor.advance(); 1683bb352b6eSEgor Zhdan if (!MaybeNext) { 1684bb352b6eSEgor Zhdan // FIXME this drops the error on the floor. 1685bb352b6eSEgor Zhdan consumeError(MaybeNext.takeError()); 1686bb352b6eSEgor Zhdan return false; 1687bb352b6eSEgor Zhdan } 1688bb352b6eSEgor Zhdan Next = MaybeNext.get(); 1689bb352b6eSEgor Zhdan } 1690bb352b6eSEgor Zhdan 1691bb352b6eSEgor Zhdan return false; 1692bb352b6eSEgor Zhdan } 1693bb352b6eSEgor Zhdan 1694bb352b6eSEgor Zhdan bool APINotesReader::Implementation::readTagBlock( 1695bb352b6eSEgor Zhdan llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl<uint64_t> &Scratch) { 1696bb352b6eSEgor Zhdan if (Cursor.EnterSubBlock(TAG_BLOCK_ID)) 1697bb352b6eSEgor Zhdan return true; 1698bb352b6eSEgor Zhdan 1699bb352b6eSEgor Zhdan llvm::Expected<llvm::BitstreamEntry> MaybeNext = Cursor.advance(); 1700bb352b6eSEgor Zhdan if (!MaybeNext) { 1701bb352b6eSEgor Zhdan // FIXME this drops the error on the floor. 1702bb352b6eSEgor Zhdan consumeError(MaybeNext.takeError()); 1703bb352b6eSEgor Zhdan return false; 1704bb352b6eSEgor Zhdan } 1705bb352b6eSEgor Zhdan llvm::BitstreamEntry Next = MaybeNext.get(); 1706bb352b6eSEgor Zhdan while (Next.Kind != llvm::BitstreamEntry::EndBlock) { 1707bb352b6eSEgor Zhdan if (Next.Kind == llvm::BitstreamEntry::Error) 1708bb352b6eSEgor Zhdan return true; 1709bb352b6eSEgor Zhdan 1710bb352b6eSEgor Zhdan if (Next.Kind == llvm::BitstreamEntry::SubBlock) { 1711bb352b6eSEgor Zhdan // Unknown sub-block, possibly for use by a future version of the 1712bb352b6eSEgor Zhdan // API notes format. 1713bb352b6eSEgor Zhdan if (Cursor.SkipBlock()) 1714bb352b6eSEgor Zhdan return true; 1715bb352b6eSEgor Zhdan 1716bb352b6eSEgor Zhdan MaybeNext = Cursor.advance(); 1717bb352b6eSEgor Zhdan if (!MaybeNext) { 1718bb352b6eSEgor Zhdan // FIXME this drops the error on the floor. 1719bb352b6eSEgor Zhdan consumeError(MaybeNext.takeError()); 1720bb352b6eSEgor Zhdan return false; 1721bb352b6eSEgor Zhdan } 1722bb352b6eSEgor Zhdan Next = MaybeNext.get(); 1723bb352b6eSEgor Zhdan continue; 1724bb352b6eSEgor Zhdan } 1725bb352b6eSEgor Zhdan 1726bb352b6eSEgor Zhdan Scratch.clear(); 1727bb352b6eSEgor Zhdan llvm::StringRef BlobData; 1728bb352b6eSEgor Zhdan llvm::Expected<unsigned> MaybeKind = 1729bb352b6eSEgor Zhdan Cursor.readRecord(Next.ID, Scratch, &BlobData); 1730bb352b6eSEgor Zhdan if (!MaybeKind) { 1731bb352b6eSEgor Zhdan // FIXME this drops the error on the floor. 1732bb352b6eSEgor Zhdan consumeError(MaybeKind.takeError()); 1733bb352b6eSEgor Zhdan return false; 1734bb352b6eSEgor Zhdan } 1735bb352b6eSEgor Zhdan unsigned Kind = MaybeKind.get(); 1736bb352b6eSEgor Zhdan switch (Kind) { 1737bb352b6eSEgor Zhdan case tag_block::TAG_DATA: { 1738bb352b6eSEgor Zhdan // Already saw tag table. 1739bb352b6eSEgor Zhdan if (TagTable) 1740bb352b6eSEgor Zhdan return true; 1741bb352b6eSEgor Zhdan 1742bb352b6eSEgor Zhdan uint32_t tableOffset; 1743bb352b6eSEgor Zhdan tag_block::TagDataLayout::readRecord(Scratch, tableOffset); 1744bb352b6eSEgor Zhdan auto base = reinterpret_cast<const uint8_t *>(BlobData.data()); 1745bb352b6eSEgor Zhdan 1746bb352b6eSEgor Zhdan TagTable.reset(SerializedTagTable::Create(base + tableOffset, 1747bb352b6eSEgor Zhdan base + sizeof(uint32_t), base)); 1748bb352b6eSEgor Zhdan break; 1749bb352b6eSEgor Zhdan } 1750bb352b6eSEgor Zhdan 1751bb352b6eSEgor Zhdan default: 1752bb352b6eSEgor Zhdan // Unknown record, possibly for use by a future version of the 1753bb352b6eSEgor Zhdan // module format. 1754bb352b6eSEgor Zhdan break; 1755bb352b6eSEgor Zhdan } 1756bb352b6eSEgor Zhdan 1757bb352b6eSEgor Zhdan MaybeNext = Cursor.advance(); 1758bb352b6eSEgor Zhdan if (!MaybeNext) { 1759bb352b6eSEgor Zhdan // FIXME this drops the error on the floor. 1760bb352b6eSEgor Zhdan consumeError(MaybeNext.takeError()); 1761bb352b6eSEgor Zhdan return false; 1762bb352b6eSEgor Zhdan } 1763bb352b6eSEgor Zhdan Next = MaybeNext.get(); 1764bb352b6eSEgor Zhdan } 1765bb352b6eSEgor Zhdan 1766bb352b6eSEgor Zhdan return false; 1767bb352b6eSEgor Zhdan } 1768bb352b6eSEgor Zhdan 1769bb352b6eSEgor Zhdan bool APINotesReader::Implementation::readTypedefBlock( 1770bb352b6eSEgor Zhdan llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl<uint64_t> &Scratch) { 1771bb352b6eSEgor Zhdan if (Cursor.EnterSubBlock(TYPEDEF_BLOCK_ID)) 1772bb352b6eSEgor Zhdan return true; 1773bb352b6eSEgor Zhdan 1774bb352b6eSEgor Zhdan llvm::Expected<llvm::BitstreamEntry> MaybeNext = Cursor.advance(); 1775bb352b6eSEgor Zhdan if (!MaybeNext) { 1776bb352b6eSEgor Zhdan // FIXME this drops the error on the floor. 1777bb352b6eSEgor Zhdan consumeError(MaybeNext.takeError()); 1778bb352b6eSEgor Zhdan return false; 1779bb352b6eSEgor Zhdan } 1780bb352b6eSEgor Zhdan llvm::BitstreamEntry Next = MaybeNext.get(); 1781bb352b6eSEgor Zhdan while (Next.Kind != llvm::BitstreamEntry::EndBlock) { 1782bb352b6eSEgor Zhdan if (Next.Kind == llvm::BitstreamEntry::Error) 1783bb352b6eSEgor Zhdan return true; 1784bb352b6eSEgor Zhdan 1785bb352b6eSEgor Zhdan if (Next.Kind == llvm::BitstreamEntry::SubBlock) { 1786bb352b6eSEgor Zhdan // Unknown sub-block, possibly for use by a future version of the 1787bb352b6eSEgor Zhdan // API notes format. 1788bb352b6eSEgor Zhdan if (Cursor.SkipBlock()) 1789bb352b6eSEgor Zhdan return true; 1790bb352b6eSEgor Zhdan 1791bb352b6eSEgor Zhdan MaybeNext = Cursor.advance(); 1792bb352b6eSEgor Zhdan if (!MaybeNext) { 1793bb352b6eSEgor Zhdan // FIXME this drops the error on the floor. 1794bb352b6eSEgor Zhdan consumeError(MaybeNext.takeError()); 1795bb352b6eSEgor Zhdan return false; 1796bb352b6eSEgor Zhdan } 1797bb352b6eSEgor Zhdan Next = MaybeNext.get(); 1798bb352b6eSEgor Zhdan continue; 1799bb352b6eSEgor Zhdan } 1800bb352b6eSEgor Zhdan 1801bb352b6eSEgor Zhdan Scratch.clear(); 1802bb352b6eSEgor Zhdan llvm::StringRef BlobData; 1803bb352b6eSEgor Zhdan llvm::Expected<unsigned> MaybeKind = 1804bb352b6eSEgor Zhdan Cursor.readRecord(Next.ID, Scratch, &BlobData); 1805bb352b6eSEgor Zhdan if (!MaybeKind) { 1806bb352b6eSEgor Zhdan // FIXME this drops the error on the floor. 1807bb352b6eSEgor Zhdan consumeError(MaybeKind.takeError()); 1808bb352b6eSEgor Zhdan return false; 1809bb352b6eSEgor Zhdan } 1810bb352b6eSEgor Zhdan unsigned Kind = MaybeKind.get(); 1811bb352b6eSEgor Zhdan switch (Kind) { 1812bb352b6eSEgor Zhdan case typedef_block::TYPEDEF_DATA: { 1813bb352b6eSEgor Zhdan // Already saw typedef table. 1814bb352b6eSEgor Zhdan if (TypedefTable) 1815bb352b6eSEgor Zhdan return true; 1816bb352b6eSEgor Zhdan 1817bb352b6eSEgor Zhdan uint32_t tableOffset; 1818bb352b6eSEgor Zhdan typedef_block::TypedefDataLayout::readRecord(Scratch, tableOffset); 1819bb352b6eSEgor Zhdan auto base = reinterpret_cast<const uint8_t *>(BlobData.data()); 1820bb352b6eSEgor Zhdan 1821bb352b6eSEgor Zhdan TypedefTable.reset(SerializedTypedefTable::Create( 1822bb352b6eSEgor Zhdan base + tableOffset, base + sizeof(uint32_t), base)); 1823bb352b6eSEgor Zhdan break; 1824bb352b6eSEgor Zhdan } 1825bb352b6eSEgor Zhdan 1826bb352b6eSEgor Zhdan default: 1827bb352b6eSEgor Zhdan // Unknown record, possibly for use by a future version of the 1828bb352b6eSEgor Zhdan // module format. 1829bb352b6eSEgor Zhdan break; 1830bb352b6eSEgor Zhdan } 1831bb352b6eSEgor Zhdan 1832bb352b6eSEgor Zhdan MaybeNext = Cursor.advance(); 1833bb352b6eSEgor Zhdan if (!MaybeNext) { 1834bb352b6eSEgor Zhdan // FIXME this drops the error on the floor. 1835bb352b6eSEgor Zhdan consumeError(MaybeNext.takeError()); 1836bb352b6eSEgor Zhdan return false; 1837bb352b6eSEgor Zhdan } 1838bb352b6eSEgor Zhdan Next = MaybeNext.get(); 1839bb352b6eSEgor Zhdan } 1840bb352b6eSEgor Zhdan 1841bb352b6eSEgor Zhdan return false; 1842bb352b6eSEgor Zhdan } 1843bb352b6eSEgor Zhdan 1844bb352b6eSEgor Zhdan APINotesReader::APINotesReader(llvm::MemoryBuffer *InputBuffer, 1845bb352b6eSEgor Zhdan llvm::VersionTuple SwiftVersion, bool &Failed) 1846bb352b6eSEgor Zhdan : Implementation(new class Implementation) { 1847bb352b6eSEgor Zhdan Failed = false; 1848bb352b6eSEgor Zhdan 1849bb352b6eSEgor Zhdan // Initialize the input buffer. 1850bb352b6eSEgor Zhdan Implementation->InputBuffer = InputBuffer; 1851bb352b6eSEgor Zhdan Implementation->SwiftVersion = SwiftVersion; 1852bb352b6eSEgor Zhdan llvm::BitstreamCursor Cursor(*Implementation->InputBuffer); 1853bb352b6eSEgor Zhdan 1854bb352b6eSEgor Zhdan // Validate signature. 1855bb352b6eSEgor Zhdan for (auto byte : API_NOTES_SIGNATURE) { 1856bb352b6eSEgor Zhdan if (Cursor.AtEndOfStream()) { 1857bb352b6eSEgor Zhdan Failed = true; 1858bb352b6eSEgor Zhdan return; 1859bb352b6eSEgor Zhdan } 1860bb352b6eSEgor Zhdan if (llvm::Expected<llvm::SimpleBitstreamCursor::word_t> maybeRead = 1861bb352b6eSEgor Zhdan Cursor.Read(8)) { 1862bb352b6eSEgor Zhdan if (maybeRead.get() != byte) { 1863bb352b6eSEgor Zhdan Failed = true; 1864bb352b6eSEgor Zhdan return; 1865bb352b6eSEgor Zhdan } 1866bb352b6eSEgor Zhdan } else { 1867bb352b6eSEgor Zhdan // FIXME this drops the error on the floor. 1868bb352b6eSEgor Zhdan consumeError(maybeRead.takeError()); 1869bb352b6eSEgor Zhdan Failed = true; 1870bb352b6eSEgor Zhdan return; 1871bb352b6eSEgor Zhdan } 1872bb352b6eSEgor Zhdan } 1873bb352b6eSEgor Zhdan 1874bb352b6eSEgor Zhdan // Look at all of the blocks. 1875bb352b6eSEgor Zhdan bool HasValidControlBlock = false; 1876bb352b6eSEgor Zhdan llvm::SmallVector<uint64_t, 64> Scratch; 1877bb352b6eSEgor Zhdan while (!Cursor.AtEndOfStream()) { 1878bb352b6eSEgor Zhdan llvm::Expected<llvm::BitstreamEntry> MaybeTopLevelEntry = Cursor.advance(); 1879bb352b6eSEgor Zhdan if (!MaybeTopLevelEntry) { 1880bb352b6eSEgor Zhdan // FIXME this drops the error on the floor. 1881bb352b6eSEgor Zhdan consumeError(MaybeTopLevelEntry.takeError()); 1882bb352b6eSEgor Zhdan Failed = true; 1883bb352b6eSEgor Zhdan return; 1884bb352b6eSEgor Zhdan } 1885bb352b6eSEgor Zhdan llvm::BitstreamEntry TopLevelEntry = MaybeTopLevelEntry.get(); 1886bb352b6eSEgor Zhdan 1887bb352b6eSEgor Zhdan if (TopLevelEntry.Kind != llvm::BitstreamEntry::SubBlock) 1888bb352b6eSEgor Zhdan break; 1889bb352b6eSEgor Zhdan 1890bb352b6eSEgor Zhdan switch (TopLevelEntry.ID) { 1891bb352b6eSEgor Zhdan case llvm::bitc::BLOCKINFO_BLOCK_ID: 1892bb352b6eSEgor Zhdan if (!Cursor.ReadBlockInfoBlock()) { 1893bb352b6eSEgor Zhdan Failed = true; 1894bb352b6eSEgor Zhdan break; 1895bb352b6eSEgor Zhdan } 1896bb352b6eSEgor Zhdan break; 1897bb352b6eSEgor Zhdan 1898bb352b6eSEgor Zhdan case CONTROL_BLOCK_ID: 1899bb352b6eSEgor Zhdan // Only allow a single control block. 1900bb352b6eSEgor Zhdan if (HasValidControlBlock || 1901bb352b6eSEgor Zhdan Implementation->readControlBlock(Cursor, Scratch)) { 1902bb352b6eSEgor Zhdan Failed = true; 1903bb352b6eSEgor Zhdan return; 1904bb352b6eSEgor Zhdan } 1905bb352b6eSEgor Zhdan 1906bb352b6eSEgor Zhdan HasValidControlBlock = true; 1907bb352b6eSEgor Zhdan break; 1908bb352b6eSEgor Zhdan 1909bb352b6eSEgor Zhdan case IDENTIFIER_BLOCK_ID: 1910bb352b6eSEgor Zhdan if (!HasValidControlBlock || 1911bb352b6eSEgor Zhdan Implementation->readIdentifierBlock(Cursor, Scratch)) { 1912bb352b6eSEgor Zhdan Failed = true; 1913bb352b6eSEgor Zhdan return; 1914bb352b6eSEgor Zhdan } 1915bb352b6eSEgor Zhdan break; 1916bb352b6eSEgor Zhdan 1917bb352b6eSEgor Zhdan case OBJC_CONTEXT_BLOCK_ID: 1918bb352b6eSEgor Zhdan if (!HasValidControlBlock || 191982ee7ae3SEgor Zhdan Implementation->readContextBlock(Cursor, Scratch)) { 1920bb352b6eSEgor Zhdan Failed = true; 1921bb352b6eSEgor Zhdan return; 1922bb352b6eSEgor Zhdan } 1923bb352b6eSEgor Zhdan 1924bb352b6eSEgor Zhdan break; 1925bb352b6eSEgor Zhdan 1926bb352b6eSEgor Zhdan case OBJC_PROPERTY_BLOCK_ID: 1927bb352b6eSEgor Zhdan if (!HasValidControlBlock || 1928bb352b6eSEgor Zhdan Implementation->readObjCPropertyBlock(Cursor, Scratch)) { 1929bb352b6eSEgor Zhdan Failed = true; 1930bb352b6eSEgor Zhdan return; 1931bb352b6eSEgor Zhdan } 1932bb352b6eSEgor Zhdan break; 1933bb352b6eSEgor Zhdan 1934bb352b6eSEgor Zhdan case OBJC_METHOD_BLOCK_ID: 1935bb352b6eSEgor Zhdan if (!HasValidControlBlock || 1936bb352b6eSEgor Zhdan Implementation->readObjCMethodBlock(Cursor, Scratch)) { 1937bb352b6eSEgor Zhdan Failed = true; 1938bb352b6eSEgor Zhdan return; 1939bb352b6eSEgor Zhdan } 1940bb352b6eSEgor Zhdan break; 1941bb352b6eSEgor Zhdan 19428a79dc7eSEgor Zhdan case CXX_METHOD_BLOCK_ID: 19438a79dc7eSEgor Zhdan if (!HasValidControlBlock || 19448a79dc7eSEgor Zhdan Implementation->readCXXMethodBlock(Cursor, Scratch)) { 19458a79dc7eSEgor Zhdan Failed = true; 19468a79dc7eSEgor Zhdan return; 19478a79dc7eSEgor Zhdan } 19488a79dc7eSEgor Zhdan break; 19498a79dc7eSEgor Zhdan 1950b8169771SEgor Zhdan case FIELD_BLOCK_ID: 1951b8169771SEgor Zhdan if (!HasValidControlBlock || 1952b8169771SEgor Zhdan Implementation->readFieldBlock(Cursor, Scratch)) { 1953b8169771SEgor Zhdan Failed = true; 1954b8169771SEgor Zhdan return; 1955b8169771SEgor Zhdan } 1956b8169771SEgor Zhdan break; 1957b8169771SEgor Zhdan 1958bb352b6eSEgor Zhdan case OBJC_SELECTOR_BLOCK_ID: 1959bb352b6eSEgor Zhdan if (!HasValidControlBlock || 1960bb352b6eSEgor Zhdan Implementation->readObjCSelectorBlock(Cursor, Scratch)) { 1961bb352b6eSEgor Zhdan Failed = true; 1962bb352b6eSEgor Zhdan return; 1963bb352b6eSEgor Zhdan } 1964bb352b6eSEgor Zhdan break; 1965bb352b6eSEgor Zhdan 1966bb352b6eSEgor Zhdan case GLOBAL_VARIABLE_BLOCK_ID: 1967bb352b6eSEgor Zhdan if (!HasValidControlBlock || 1968bb352b6eSEgor Zhdan Implementation->readGlobalVariableBlock(Cursor, Scratch)) { 1969bb352b6eSEgor Zhdan Failed = true; 1970bb352b6eSEgor Zhdan return; 1971bb352b6eSEgor Zhdan } 1972bb352b6eSEgor Zhdan break; 1973bb352b6eSEgor Zhdan 1974bb352b6eSEgor Zhdan case GLOBAL_FUNCTION_BLOCK_ID: 1975bb352b6eSEgor Zhdan if (!HasValidControlBlock || 1976bb352b6eSEgor Zhdan Implementation->readGlobalFunctionBlock(Cursor, Scratch)) { 1977bb352b6eSEgor Zhdan Failed = true; 1978bb352b6eSEgor Zhdan return; 1979bb352b6eSEgor Zhdan } 1980bb352b6eSEgor Zhdan break; 1981bb352b6eSEgor Zhdan 1982bb352b6eSEgor Zhdan case ENUM_CONSTANT_BLOCK_ID: 1983bb352b6eSEgor Zhdan if (!HasValidControlBlock || 1984bb352b6eSEgor Zhdan Implementation->readEnumConstantBlock(Cursor, Scratch)) { 1985bb352b6eSEgor Zhdan Failed = true; 1986bb352b6eSEgor Zhdan return; 1987bb352b6eSEgor Zhdan } 1988bb352b6eSEgor Zhdan break; 1989bb352b6eSEgor Zhdan 1990bb352b6eSEgor Zhdan case TAG_BLOCK_ID: 1991bb352b6eSEgor Zhdan if (!HasValidControlBlock || 1992bb352b6eSEgor Zhdan Implementation->readTagBlock(Cursor, Scratch)) { 1993bb352b6eSEgor Zhdan Failed = true; 1994bb352b6eSEgor Zhdan return; 1995bb352b6eSEgor Zhdan } 1996bb352b6eSEgor Zhdan break; 1997bb352b6eSEgor Zhdan 1998bb352b6eSEgor Zhdan case TYPEDEF_BLOCK_ID: 1999bb352b6eSEgor Zhdan if (!HasValidControlBlock || 2000bb352b6eSEgor Zhdan Implementation->readTypedefBlock(Cursor, Scratch)) { 2001bb352b6eSEgor Zhdan Failed = true; 2002bb352b6eSEgor Zhdan return; 2003bb352b6eSEgor Zhdan } 2004bb352b6eSEgor Zhdan break; 2005bb352b6eSEgor Zhdan 2006bb352b6eSEgor Zhdan default: 2007bb352b6eSEgor Zhdan // Unknown top-level block, possibly for use by a future version of the 2008bb352b6eSEgor Zhdan // module format. 2009bb352b6eSEgor Zhdan if (Cursor.SkipBlock()) { 2010bb352b6eSEgor Zhdan Failed = true; 2011bb352b6eSEgor Zhdan return; 2012bb352b6eSEgor Zhdan } 2013bb352b6eSEgor Zhdan break; 2014bb352b6eSEgor Zhdan } 2015bb352b6eSEgor Zhdan } 2016bb352b6eSEgor Zhdan 2017bb352b6eSEgor Zhdan if (!Cursor.AtEndOfStream()) { 2018bb352b6eSEgor Zhdan Failed = true; 2019bb352b6eSEgor Zhdan return; 2020bb352b6eSEgor Zhdan } 2021bb352b6eSEgor Zhdan } 2022bb352b6eSEgor Zhdan 2023bb352b6eSEgor Zhdan APINotesReader::~APINotesReader() { delete Implementation->InputBuffer; } 2024bb352b6eSEgor Zhdan 2025bb352b6eSEgor Zhdan std::unique_ptr<APINotesReader> 2026bb352b6eSEgor Zhdan APINotesReader::Create(std::unique_ptr<llvm::MemoryBuffer> InputBuffer, 2027bb352b6eSEgor Zhdan llvm::VersionTuple SwiftVersion) { 2028bb352b6eSEgor Zhdan bool Failed = false; 2029bb352b6eSEgor Zhdan std::unique_ptr<APINotesReader> Reader( 2030bb352b6eSEgor Zhdan new APINotesReader(InputBuffer.release(), SwiftVersion, Failed)); 2031bb352b6eSEgor Zhdan if (Failed) 2032bb352b6eSEgor Zhdan return nullptr; 2033bb352b6eSEgor Zhdan 2034bb352b6eSEgor Zhdan return Reader; 2035bb352b6eSEgor Zhdan } 2036bb352b6eSEgor Zhdan 2037bb352b6eSEgor Zhdan template <typename T> 2038bb352b6eSEgor Zhdan APINotesReader::VersionedInfo<T>::VersionedInfo( 2039bb352b6eSEgor Zhdan llvm::VersionTuple Version, 20405e4c4365SEgor Zhdan llvm::SmallVector<std::pair<llvm::VersionTuple, T>, 1> R) 20415e4c4365SEgor Zhdan : Results(std::move(R)) { 2042bb352b6eSEgor Zhdan 2043bb352b6eSEgor Zhdan assert(!Results.empty()); 2044bb352b6eSEgor Zhdan assert(std::is_sorted( 2045bb352b6eSEgor Zhdan Results.begin(), Results.end(), 2046bb352b6eSEgor Zhdan [](const std::pair<llvm::VersionTuple, T> &left, 2047bb352b6eSEgor Zhdan const std::pair<llvm::VersionTuple, T> &right) -> bool { 2048*26f5d1eeSBjörn Pettersson // The comparison function should be reflective, and with expensive 2049*26f5d1eeSBjörn Pettersson // checks we can get callbacks basically checking that lambda(a,a) is 2050*26f5d1eeSBjörn Pettersson // false. We could still check that we do not find equal elements when 2051*26f5d1eeSBjörn Pettersson // left!=right. 2052*26f5d1eeSBjörn Pettersson assert((&left == &right || left.first != right.first) && 2053*26f5d1eeSBjörn Pettersson "two entries for the same version"); 2054bb352b6eSEgor Zhdan return left.first < right.first; 2055bb352b6eSEgor Zhdan })); 2056bb352b6eSEgor Zhdan 2057bb352b6eSEgor Zhdan Selected = std::nullopt; 2058bb352b6eSEgor Zhdan for (unsigned i = 0, n = Results.size(); i != n; ++i) { 2059bb352b6eSEgor Zhdan if (!Version.empty() && Results[i].first >= Version) { 2060bb352b6eSEgor Zhdan // If the current version is "4", then entries for 4 are better than 2061bb352b6eSEgor Zhdan // entries for 5, but both are valid. Because entries are sorted, we get 2062bb352b6eSEgor Zhdan // that behavior by picking the first match. 2063bb352b6eSEgor Zhdan Selected = i; 2064bb352b6eSEgor Zhdan break; 2065bb352b6eSEgor Zhdan } 2066bb352b6eSEgor Zhdan } 2067bb352b6eSEgor Zhdan 2068bb352b6eSEgor Zhdan // If we didn't find a match but we have an unversioned result, use the 2069bb352b6eSEgor Zhdan // unversioned result. This will always be the first entry because we encode 2070bb352b6eSEgor Zhdan // it as version 0. 2071bb352b6eSEgor Zhdan if (!Selected && Results[0].first.empty()) 2072bb352b6eSEgor Zhdan Selected = 0; 2073bb352b6eSEgor Zhdan } 2074bb352b6eSEgor Zhdan 2075bb352b6eSEgor Zhdan auto APINotesReader::lookupObjCClassID(llvm::StringRef Name) 2076bb352b6eSEgor Zhdan -> std::optional<ContextID> { 207782ee7ae3SEgor Zhdan if (!Implementation->ContextIDTable) 2078bb352b6eSEgor Zhdan return std::nullopt; 2079bb352b6eSEgor Zhdan 2080bb352b6eSEgor Zhdan std::optional<IdentifierID> ClassID = Implementation->getIdentifier(Name); 2081bb352b6eSEgor Zhdan if (!ClassID) 2082bb352b6eSEgor Zhdan return std::nullopt; 2083bb352b6eSEgor Zhdan 2084bb352b6eSEgor Zhdan // ObjC classes can't be declared in C++ namespaces, so use -1 as the global 2085bb352b6eSEgor Zhdan // context. 208682ee7ae3SEgor Zhdan auto KnownID = Implementation->ContextIDTable->find( 2087bb352b6eSEgor Zhdan ContextTableKey(-1, (uint8_t)ContextKind::ObjCClass, *ClassID)); 208882ee7ae3SEgor Zhdan if (KnownID == Implementation->ContextIDTable->end()) 2089bb352b6eSEgor Zhdan return std::nullopt; 2090bb352b6eSEgor Zhdan 2091bb352b6eSEgor Zhdan return ContextID(*KnownID); 2092bb352b6eSEgor Zhdan } 2093bb352b6eSEgor Zhdan 2094bb352b6eSEgor Zhdan auto APINotesReader::lookupObjCClassInfo(llvm::StringRef Name) 209582ee7ae3SEgor Zhdan -> VersionedInfo<ContextInfo> { 209682ee7ae3SEgor Zhdan if (!Implementation->ContextInfoTable) 2097bb352b6eSEgor Zhdan return std::nullopt; 2098bb352b6eSEgor Zhdan 2099bb352b6eSEgor Zhdan std::optional<ContextID> CtxID = lookupObjCClassID(Name); 2100bb352b6eSEgor Zhdan if (!CtxID) 2101bb352b6eSEgor Zhdan return std::nullopt; 2102bb352b6eSEgor Zhdan 210382ee7ae3SEgor Zhdan auto KnownInfo = Implementation->ContextInfoTable->find(CtxID->Value); 210482ee7ae3SEgor Zhdan if (KnownInfo == Implementation->ContextInfoTable->end()) 2105bb352b6eSEgor Zhdan return std::nullopt; 2106bb352b6eSEgor Zhdan 2107bb352b6eSEgor Zhdan return {Implementation->SwiftVersion, *KnownInfo}; 2108bb352b6eSEgor Zhdan } 2109bb352b6eSEgor Zhdan 2110bb352b6eSEgor Zhdan auto APINotesReader::lookupObjCProtocolID(llvm::StringRef Name) 2111bb352b6eSEgor Zhdan -> std::optional<ContextID> { 211282ee7ae3SEgor Zhdan if (!Implementation->ContextIDTable) 2113bb352b6eSEgor Zhdan return std::nullopt; 2114bb352b6eSEgor Zhdan 2115bb352b6eSEgor Zhdan std::optional<IdentifierID> classID = Implementation->getIdentifier(Name); 2116bb352b6eSEgor Zhdan if (!classID) 2117bb352b6eSEgor Zhdan return std::nullopt; 2118bb352b6eSEgor Zhdan 2119bb352b6eSEgor Zhdan // ObjC classes can't be declared in C++ namespaces, so use -1 as the global 2120bb352b6eSEgor Zhdan // context. 212182ee7ae3SEgor Zhdan auto KnownID = Implementation->ContextIDTable->find( 2122bb352b6eSEgor Zhdan ContextTableKey(-1, (uint8_t)ContextKind::ObjCProtocol, *classID)); 212382ee7ae3SEgor Zhdan if (KnownID == Implementation->ContextIDTable->end()) 2124bb352b6eSEgor Zhdan return std::nullopt; 2125bb352b6eSEgor Zhdan 2126bb352b6eSEgor Zhdan return ContextID(*KnownID); 2127bb352b6eSEgor Zhdan } 2128bb352b6eSEgor Zhdan 2129bb352b6eSEgor Zhdan auto APINotesReader::lookupObjCProtocolInfo(llvm::StringRef Name) 213082ee7ae3SEgor Zhdan -> VersionedInfo<ContextInfo> { 213182ee7ae3SEgor Zhdan if (!Implementation->ContextInfoTable) 2132bb352b6eSEgor Zhdan return std::nullopt; 2133bb352b6eSEgor Zhdan 2134bb352b6eSEgor Zhdan std::optional<ContextID> CtxID = lookupObjCProtocolID(Name); 2135bb352b6eSEgor Zhdan if (!CtxID) 2136bb352b6eSEgor Zhdan return std::nullopt; 2137bb352b6eSEgor Zhdan 213882ee7ae3SEgor Zhdan auto KnownInfo = Implementation->ContextInfoTable->find(CtxID->Value); 213982ee7ae3SEgor Zhdan if (KnownInfo == Implementation->ContextInfoTable->end()) 2140bb352b6eSEgor Zhdan return std::nullopt; 2141bb352b6eSEgor Zhdan 2142bb352b6eSEgor Zhdan return {Implementation->SwiftVersion, *KnownInfo}; 2143bb352b6eSEgor Zhdan } 2144bb352b6eSEgor Zhdan 2145bb352b6eSEgor Zhdan auto APINotesReader::lookupObjCProperty(ContextID CtxID, llvm::StringRef Name, 2146bb352b6eSEgor Zhdan bool IsInstance) 2147bb352b6eSEgor Zhdan -> VersionedInfo<ObjCPropertyInfo> { 2148bb352b6eSEgor Zhdan if (!Implementation->ObjCPropertyTable) 2149bb352b6eSEgor Zhdan return std::nullopt; 2150bb352b6eSEgor Zhdan 2151bb352b6eSEgor Zhdan std::optional<IdentifierID> PropertyID = Implementation->getIdentifier(Name); 2152bb352b6eSEgor Zhdan if (!PropertyID) 2153bb352b6eSEgor Zhdan return std::nullopt; 2154bb352b6eSEgor Zhdan 2155bb352b6eSEgor Zhdan auto Known = Implementation->ObjCPropertyTable->find( 2156bb352b6eSEgor Zhdan std::make_tuple(CtxID.Value, *PropertyID, (char)IsInstance)); 2157bb352b6eSEgor Zhdan if (Known == Implementation->ObjCPropertyTable->end()) 2158bb352b6eSEgor Zhdan return std::nullopt; 2159bb352b6eSEgor Zhdan 2160bb352b6eSEgor Zhdan return {Implementation->SwiftVersion, *Known}; 2161bb352b6eSEgor Zhdan } 2162bb352b6eSEgor Zhdan 2163bb352b6eSEgor Zhdan auto APINotesReader::lookupObjCMethod(ContextID CtxID, ObjCSelectorRef Selector, 2164bb352b6eSEgor Zhdan bool IsInstanceMethod) 2165bb352b6eSEgor Zhdan -> VersionedInfo<ObjCMethodInfo> { 2166bb352b6eSEgor Zhdan if (!Implementation->ObjCMethodTable) 2167bb352b6eSEgor Zhdan return std::nullopt; 2168bb352b6eSEgor Zhdan 2169bb352b6eSEgor Zhdan std::optional<SelectorID> SelID = Implementation->getSelector(Selector); 2170bb352b6eSEgor Zhdan if (!SelID) 2171bb352b6eSEgor Zhdan return std::nullopt; 2172bb352b6eSEgor Zhdan 2173bb352b6eSEgor Zhdan auto Known = Implementation->ObjCMethodTable->find( 2174bb352b6eSEgor Zhdan ObjCMethodTableInfo::internal_key_type{CtxID.Value, *SelID, 2175bb352b6eSEgor Zhdan IsInstanceMethod}); 2176bb352b6eSEgor Zhdan if (Known == Implementation->ObjCMethodTable->end()) 2177bb352b6eSEgor Zhdan return std::nullopt; 2178bb352b6eSEgor Zhdan 2179bb352b6eSEgor Zhdan return {Implementation->SwiftVersion, *Known}; 2180bb352b6eSEgor Zhdan } 2181bb352b6eSEgor Zhdan 2182b8169771SEgor Zhdan auto APINotesReader::lookupField(ContextID CtxID, llvm::StringRef Name) 2183b8169771SEgor Zhdan -> VersionedInfo<FieldInfo> { 2184b8169771SEgor Zhdan if (!Implementation->FieldTable) 2185b8169771SEgor Zhdan return std::nullopt; 2186b8169771SEgor Zhdan 2187b8169771SEgor Zhdan std::optional<IdentifierID> NameID = Implementation->getIdentifier(Name); 2188b8169771SEgor Zhdan if (!NameID) 2189b8169771SEgor Zhdan return std::nullopt; 2190b8169771SEgor Zhdan 2191b8169771SEgor Zhdan auto Known = Implementation->FieldTable->find( 2192b8169771SEgor Zhdan SingleDeclTableKey(CtxID.Value, *NameID)); 2193b8169771SEgor Zhdan if (Known == Implementation->FieldTable->end()) 2194b8169771SEgor Zhdan return std::nullopt; 2195b8169771SEgor Zhdan 2196b8169771SEgor Zhdan return {Implementation->SwiftVersion, *Known}; 2197b8169771SEgor Zhdan } 2198b8169771SEgor Zhdan 21998a79dc7eSEgor Zhdan auto APINotesReader::lookupCXXMethod(ContextID CtxID, llvm::StringRef Name) 22008a79dc7eSEgor Zhdan -> VersionedInfo<CXXMethodInfo> { 22018a79dc7eSEgor Zhdan if (!Implementation->CXXMethodTable) 22028a79dc7eSEgor Zhdan return std::nullopt; 22038a79dc7eSEgor Zhdan 22048a79dc7eSEgor Zhdan std::optional<IdentifierID> NameID = Implementation->getIdentifier(Name); 22058a79dc7eSEgor Zhdan if (!NameID) 22068a79dc7eSEgor Zhdan return std::nullopt; 22078a79dc7eSEgor Zhdan 22088a79dc7eSEgor Zhdan auto Known = Implementation->CXXMethodTable->find( 22098a79dc7eSEgor Zhdan SingleDeclTableKey(CtxID.Value, *NameID)); 22108a79dc7eSEgor Zhdan if (Known == Implementation->CXXMethodTable->end()) 22118a79dc7eSEgor Zhdan return std::nullopt; 22128a79dc7eSEgor Zhdan 22138a79dc7eSEgor Zhdan return {Implementation->SwiftVersion, *Known}; 22148a79dc7eSEgor Zhdan } 22158a79dc7eSEgor Zhdan 2216bb352b6eSEgor Zhdan auto APINotesReader::lookupGlobalVariable(llvm::StringRef Name, 2217bb352b6eSEgor Zhdan std::optional<Context> Ctx) 2218bb352b6eSEgor Zhdan -> VersionedInfo<GlobalVariableInfo> { 2219bb352b6eSEgor Zhdan if (!Implementation->GlobalVariableTable) 2220bb352b6eSEgor Zhdan return std::nullopt; 2221bb352b6eSEgor Zhdan 2222bb352b6eSEgor Zhdan std::optional<IdentifierID> NameID = Implementation->getIdentifier(Name); 2223bb352b6eSEgor Zhdan if (!NameID) 2224bb352b6eSEgor Zhdan return std::nullopt; 2225bb352b6eSEgor Zhdan 2226c5f402f9SEgor Zhdan SingleDeclTableKey Key(Ctx, *NameID); 2227bb352b6eSEgor Zhdan 2228bb352b6eSEgor Zhdan auto Known = Implementation->GlobalVariableTable->find(Key); 2229bb352b6eSEgor Zhdan if (Known == Implementation->GlobalVariableTable->end()) 2230bb352b6eSEgor Zhdan return std::nullopt; 2231bb352b6eSEgor Zhdan 2232bb352b6eSEgor Zhdan return {Implementation->SwiftVersion, *Known}; 2233bb352b6eSEgor Zhdan } 2234bb352b6eSEgor Zhdan 2235bb352b6eSEgor Zhdan auto APINotesReader::lookupGlobalFunction(llvm::StringRef Name, 2236bb352b6eSEgor Zhdan std::optional<Context> Ctx) 2237bb352b6eSEgor Zhdan -> VersionedInfo<GlobalFunctionInfo> { 2238bb352b6eSEgor Zhdan if (!Implementation->GlobalFunctionTable) 2239bb352b6eSEgor Zhdan return std::nullopt; 2240bb352b6eSEgor Zhdan 2241bb352b6eSEgor Zhdan std::optional<IdentifierID> NameID = Implementation->getIdentifier(Name); 2242bb352b6eSEgor Zhdan if (!NameID) 2243bb352b6eSEgor Zhdan return std::nullopt; 2244bb352b6eSEgor Zhdan 2245c5f402f9SEgor Zhdan SingleDeclTableKey Key(Ctx, *NameID); 2246bb352b6eSEgor Zhdan 2247bb352b6eSEgor Zhdan auto Known = Implementation->GlobalFunctionTable->find(Key); 2248bb352b6eSEgor Zhdan if (Known == Implementation->GlobalFunctionTable->end()) 2249bb352b6eSEgor Zhdan return std::nullopt; 2250bb352b6eSEgor Zhdan 2251bb352b6eSEgor Zhdan return {Implementation->SwiftVersion, *Known}; 2252bb352b6eSEgor Zhdan } 2253bb352b6eSEgor Zhdan 2254bb352b6eSEgor Zhdan auto APINotesReader::lookupEnumConstant(llvm::StringRef Name) 2255bb352b6eSEgor Zhdan -> VersionedInfo<EnumConstantInfo> { 2256bb352b6eSEgor Zhdan if (!Implementation->EnumConstantTable) 2257bb352b6eSEgor Zhdan return std::nullopt; 2258bb352b6eSEgor Zhdan 2259bb352b6eSEgor Zhdan std::optional<IdentifierID> NameID = Implementation->getIdentifier(Name); 2260bb352b6eSEgor Zhdan if (!NameID) 2261bb352b6eSEgor Zhdan return std::nullopt; 2262bb352b6eSEgor Zhdan 2263bb352b6eSEgor Zhdan auto Known = Implementation->EnumConstantTable->find(*NameID); 2264bb352b6eSEgor Zhdan if (Known == Implementation->EnumConstantTable->end()) 2265bb352b6eSEgor Zhdan return std::nullopt; 2266bb352b6eSEgor Zhdan 2267bb352b6eSEgor Zhdan return {Implementation->SwiftVersion, *Known}; 2268bb352b6eSEgor Zhdan } 2269bb352b6eSEgor Zhdan 22708a79dc7eSEgor Zhdan auto APINotesReader::lookupTagID(llvm::StringRef Name, 22718a79dc7eSEgor Zhdan std::optional<Context> ParentCtx) 22728a79dc7eSEgor Zhdan -> std::optional<ContextID> { 22738a79dc7eSEgor Zhdan if (!Implementation->ContextIDTable) 22748a79dc7eSEgor Zhdan return std::nullopt; 22758a79dc7eSEgor Zhdan 22768a79dc7eSEgor Zhdan std::optional<IdentifierID> TagID = Implementation->getIdentifier(Name); 22778a79dc7eSEgor Zhdan if (!TagID) 22788a79dc7eSEgor Zhdan return std::nullopt; 22798a79dc7eSEgor Zhdan 22808a79dc7eSEgor Zhdan auto KnownID = Implementation->ContextIDTable->find( 22818a79dc7eSEgor Zhdan ContextTableKey(ParentCtx, ContextKind::Tag, *TagID)); 22828a79dc7eSEgor Zhdan if (KnownID == Implementation->ContextIDTable->end()) 22838a79dc7eSEgor Zhdan return std::nullopt; 22848a79dc7eSEgor Zhdan 22858a79dc7eSEgor Zhdan return ContextID(*KnownID); 22868a79dc7eSEgor Zhdan } 22878a79dc7eSEgor Zhdan 2288bb352b6eSEgor Zhdan auto APINotesReader::lookupTag(llvm::StringRef Name, std::optional<Context> Ctx) 2289bb352b6eSEgor Zhdan -> VersionedInfo<TagInfo> { 2290bb352b6eSEgor Zhdan if (!Implementation->TagTable) 2291bb352b6eSEgor Zhdan return std::nullopt; 2292bb352b6eSEgor Zhdan 2293bb352b6eSEgor Zhdan std::optional<IdentifierID> NameID = Implementation->getIdentifier(Name); 2294bb352b6eSEgor Zhdan if (!NameID) 2295bb352b6eSEgor Zhdan return std::nullopt; 2296bb352b6eSEgor Zhdan 2297c5f402f9SEgor Zhdan SingleDeclTableKey Key(Ctx, *NameID); 2298bb352b6eSEgor Zhdan 2299bb352b6eSEgor Zhdan auto Known = Implementation->TagTable->find(Key); 2300bb352b6eSEgor Zhdan if (Known == Implementation->TagTable->end()) 2301bb352b6eSEgor Zhdan return std::nullopt; 2302bb352b6eSEgor Zhdan 2303bb352b6eSEgor Zhdan return {Implementation->SwiftVersion, *Known}; 2304bb352b6eSEgor Zhdan } 2305bb352b6eSEgor Zhdan 2306bb352b6eSEgor Zhdan auto APINotesReader::lookupTypedef(llvm::StringRef Name, 2307bb352b6eSEgor Zhdan std::optional<Context> Ctx) 2308bb352b6eSEgor Zhdan -> VersionedInfo<TypedefInfo> { 2309bb352b6eSEgor Zhdan if (!Implementation->TypedefTable) 2310bb352b6eSEgor Zhdan return std::nullopt; 2311bb352b6eSEgor Zhdan 2312bb352b6eSEgor Zhdan std::optional<IdentifierID> NameID = Implementation->getIdentifier(Name); 2313bb352b6eSEgor Zhdan if (!NameID) 2314bb352b6eSEgor Zhdan return std::nullopt; 2315bb352b6eSEgor Zhdan 2316c5f402f9SEgor Zhdan SingleDeclTableKey Key(Ctx, *NameID); 2317bb352b6eSEgor Zhdan 2318bb352b6eSEgor Zhdan auto Known = Implementation->TypedefTable->find(Key); 2319bb352b6eSEgor Zhdan if (Known == Implementation->TypedefTable->end()) 2320bb352b6eSEgor Zhdan return std::nullopt; 2321bb352b6eSEgor Zhdan 2322bb352b6eSEgor Zhdan return {Implementation->SwiftVersion, *Known}; 2323bb352b6eSEgor Zhdan } 2324bb352b6eSEgor Zhdan 2325bb352b6eSEgor Zhdan auto APINotesReader::lookupNamespaceID( 2326bb352b6eSEgor Zhdan llvm::StringRef Name, std::optional<ContextID> ParentNamespaceID) 2327bb352b6eSEgor Zhdan -> std::optional<ContextID> { 232882ee7ae3SEgor Zhdan if (!Implementation->ContextIDTable) 2329bb352b6eSEgor Zhdan return std::nullopt; 2330bb352b6eSEgor Zhdan 2331bb352b6eSEgor Zhdan std::optional<IdentifierID> NamespaceID = Implementation->getIdentifier(Name); 2332bb352b6eSEgor Zhdan if (!NamespaceID) 2333bb352b6eSEgor Zhdan return std::nullopt; 2334bb352b6eSEgor Zhdan 2335bb352b6eSEgor Zhdan uint32_t RawParentNamespaceID = 2336bb352b6eSEgor Zhdan ParentNamespaceID ? ParentNamespaceID->Value : -1; 233782ee7ae3SEgor Zhdan auto KnownID = Implementation->ContextIDTable->find( 2338bb352b6eSEgor Zhdan {RawParentNamespaceID, (uint8_t)ContextKind::Namespace, *NamespaceID}); 233982ee7ae3SEgor Zhdan if (KnownID == Implementation->ContextIDTable->end()) 2340bb352b6eSEgor Zhdan return std::nullopt; 2341bb352b6eSEgor Zhdan 2342bb352b6eSEgor Zhdan return ContextID(*KnownID); 2343bb352b6eSEgor Zhdan } 2344bb352b6eSEgor Zhdan 2345bb352b6eSEgor Zhdan } // namespace api_notes 2346bb352b6eSEgor Zhdan } // namespace clang 2347