18#include "llvm/ADT/DenseMap.h"
19#include "llvm/ADT/Hashing.h"
20#include "llvm/Bitstream/BitstreamReader.h"
21#include "llvm/Support/DJB.h"
22#include "llvm/Support/OnDiskHashTable.h"
29using namespace llvm::support;
33llvm::VersionTuple ReadVersionTuple(
const uint8_t *&
Data) {
36 unsigned Major = endian::readNext<uint32_t, llvm::endianness::little>(
Data);
38 return llvm::VersionTuple(Major);
40 unsigned Minor = endian::readNext<uint32_t, llvm::endianness::little>(
Data);
42 return llvm::VersionTuple(Major, Minor);
45 endian::readNext<uint32_t, llvm::endianness::little>(
Data);
47 return llvm::VersionTuple(Major, Minor, Subminor);
49 unsigned Build = endian::readNext<uint32_t, llvm::endianness::little>(
Data);
50 return llvm::VersionTuple(Major, Minor, Subminor, Build);
56 "Unexpected function table key length");
58 auto CtxID = endian::readNext<uint32_t, llvm::endianness::little>(
Data);
59 auto NameID = endian::readNext<uint32_t, llvm::endianness::little>(
Data);
61 endian::readNext<uint8_t, llvm::endianness::little>(
Data);
63 endian::readNext<uint16_t, llvm::endianness::little>(
Data);
67 "Unexpected function table key length");
69 llvm::SmallVector<IdentifierID, 2> ParameterTypeIDs;
72 ParameterTypeIDs.push_back(
73 endian::readNext<uint32_t, llvm::endianness::little>(
Data));
76 "Unexpected function table key flags");
78 return {CtxID, NameID, ParameterTypeIDs};
80 assert(ParameterTypeIDs.empty() &&
81 "Broad function table key should not store parameters");
82 return {CtxID, NameID};
86template <
typename Derived,
typename KeyType,
typename UnversionedDataType>
87class VersionedTableInfo {
89 using internal_key_type = KeyType;
90 using external_key_type = KeyType;
92 llvm::SmallVector<std::pair<llvm::VersionTuple, UnversionedDataType>, 1>;
93 using hash_value_type =
size_t;
94 using offset_type = unsigned;
96 internal_key_type GetInternalKey(external_key_type Key) {
return Key; }
98 external_key_type GetExternalKey(internal_key_type Key) {
return Key; }
100 static bool EqualKey(internal_key_type LHS, internal_key_type RHS) {
104 static std::pair<unsigned, unsigned> ReadKeyDataLength(
const uint8_t *&
Data) {
106 endian::readNext<uint16_t, llvm::endianness::little>(
Data);
107 unsigned DataLength =
108 endian::readNext<uint16_t, llvm::endianness::little>(
Data);
109 return {KeyLength, DataLength};
112 static data_type ReadData(internal_key_type Key,
const uint8_t *
Data,
114 unsigned NumElements =
115 endian::readNext<uint16_t, llvm::endianness::little>(
Data);
117 Result.reserve(NumElements);
118 for (
unsigned i = 0; i != NumElements; ++i) {
119 auto version = ReadVersionTuple(
Data);
120 const auto *DataBefore =
Data;
122 auto UnversionedData = Derived::readUnversioned(Key,
Data);
123 assert(
Data != DataBefore &&
124 "Unversioned data reader didn't move pointer");
125 Result.push_back({version, UnversionedData});
134 Info.Unavailable = (EncodedBits >> 1) & 0x01;
135 Info.UnavailableInSwift = EncodedBits & 0x01;
136 if ((EncodedBits >> 2) & 0x01)
137 Info.setSwiftPrivate(
static_cast<bool>((EncodedBits >> 3) & 0x01));
138 if ((EncodedBits >> 4) & 0x01)
143 endian::readNext<uint16_t, llvm::endianness::little>(
Data);
144 Info.UnavailableMsg =
145 std::string(
reinterpret_cast<const char *
>(
Data),
146 reinterpret_cast<const char *
>(
Data) + MsgLength);
149 unsigned SwiftNameLength =
150 endian::readNext<uint16_t, llvm::endianness::little>(
Data);
152 std::string(
reinterpret_cast<const char *
>(
Data),
153 reinterpret_cast<const char *
>(
Data) + SwiftNameLength);
154 Data += SwiftNameLength;
159 ReadCommonEntityInfo(
Data, Info);
161 unsigned SwiftBridgeLength =
162 endian::readNext<uint16_t, llvm::endianness::little>(
Data);
163 if (SwiftBridgeLength > 0) {
164 Info.setSwiftBridge(std::string(
reinterpret_cast<const char *
>(
Data),
165 SwiftBridgeLength - 1));
166 Data += SwiftBridgeLength - 1;
169 unsigned ErrorDomainLength =
170 endian::readNext<uint16_t, llvm::endianness::little>(
Data);
171 if (ErrorDomainLength > 0) {
172 Info.setNSErrorDomain(std::optional<std::string>(std::string(
173 reinterpret_cast<const char *
>(
Data), ErrorDomainLength - 1)));
174 Data += ErrorDomainLength - 1;
177 if (
unsigned ConformanceLength =
178 endian::readNext<uint16_t, llvm::endianness::little>(
Data)) {
179 Info.setSwiftConformance(std::string(
reinterpret_cast<const char *
>(
Data),
180 ConformanceLength - 1));
181 Data += ConformanceLength - 1;
186class IdentifierTableInfo {
188 using internal_key_type = llvm::StringRef;
189 using external_key_type = llvm::StringRef;
192 using offset_type = unsigned;
194 internal_key_type GetInternalKey(external_key_type Key) {
return Key; }
196 external_key_type GetExternalKey(internal_key_type Key) {
return Key; }
198 hash_value_type
ComputeHash(internal_key_type Key) {
199 return llvm::djbHash(Key);
202 static bool EqualKey(internal_key_type LHS, internal_key_type RHS) {
206 static std::pair<unsigned, unsigned> ReadKeyDataLength(
const uint8_t *&
Data) {
208 endian::readNext<uint16_t, llvm::endianness::little>(
Data);
209 unsigned DataLength =
210 endian::readNext<uint16_t, llvm::endianness::little>(
Data);
211 return {KeyLength, DataLength};
214 static internal_key_type ReadKey(
const uint8_t *
Data,
unsigned Length) {
215 return llvm::StringRef(
reinterpret_cast<const char *
>(
Data), Length);
218 static data_type ReadData(internal_key_type key,
const uint8_t *
Data,
220 return endian::readNext<uint32_t, llvm::endianness::little>(
Data);
226class ContextIDTableInfo {
228 using internal_key_type = ContextTableKey;
229 using external_key_type = internal_key_type;
230 using data_type = unsigned;
231 using hash_value_type =
size_t;
232 using offset_type = unsigned;
234 internal_key_type GetInternalKey(external_key_type Key) {
return Key; }
236 external_key_type GetExternalKey(internal_key_type Key) {
return Key; }
238 hash_value_type
ComputeHash(internal_key_type Key) {
239 return static_cast<size_t>(Key.hashValue());
242 static bool EqualKey(internal_key_type LHS, internal_key_type RHS) {
246 static std::pair<unsigned, unsigned> ReadKeyDataLength(
const uint8_t *&
Data) {
248 endian::readNext<uint16_t, llvm::endianness::little>(
Data);
249 unsigned DataLength =
250 endian::readNext<uint16_t, llvm::endianness::little>(
Data);
251 return {KeyLength, DataLength};
254 static internal_key_type ReadKey(
const uint8_t *
Data,
unsigned Length) {
256 endian::readNext<uint32_t, llvm::endianness::little>(
Data);
258 endian::readNext<uint8_t, llvm::endianness::little>(
Data);
259 auto NameID = endian::readNext<uint32_t, llvm::endianness::little>(
Data);
263 static data_type ReadData(internal_key_type Key,
const uint8_t *
Data,
265 return endian::readNext<uint32_t, llvm::endianness::little>(
Data);
270class ContextInfoTableInfo
271 :
public VersionedTableInfo<ContextInfoTableInfo, unsigned, ContextInfo> {
273 static internal_key_type ReadKey(
const uint8_t *
Data,
unsigned Length) {
274 return endian::readNext<uint32_t, llvm::endianness::little>(
Data);
277 hash_value_type
ComputeHash(internal_key_type Key) {
281 static ContextInfo readUnversioned(internal_key_type Key,
284 ReadCommonTypeInfo(
Data, Info);
288 Info.setHasDesignatedInits(
true);
289 Payload = Payload >> 1;
292 Info.setDefaultNullability(
static_cast<NullabilityKind>(Payload & 0x03));
295 if (Payload & (1 << 1))
296 Info.setSwiftObjCMembers(Payload & 1);
299 if (Payload & (1 << 1))
300 Info.setSwiftImportAsNonGeneric(Payload & 1);
308 ReadCommonEntityInfo(
Data, Info);
314 auto TypeLen = endian::readNext<uint16_t, llvm::endianness::little>(
Data);
315 Info.setType(std::string(
Data,
Data + TypeLen));
320class ObjCPropertyTableInfo
321 :
public VersionedTableInfo<ObjCPropertyTableInfo,
322 std::tuple<uint32_t, uint32_t, uint8_t>,
325 static internal_key_type ReadKey(
const uint8_t *
Data,
unsigned Length) {
326 auto ClassID = endian::readNext<uint32_t, llvm::endianness::little>(
Data);
327 auto NameID = endian::readNext<uint32_t, llvm::endianness::little>(
Data);
328 char IsInstance = endian::readNext<uint8_t, llvm::endianness::little>(
Data);
329 return {ClassID, NameID, IsInstance};
332 hash_value_type
ComputeHash(internal_key_type Key) {
336 static ObjCPropertyInfo readUnversioned(internal_key_type Key,
338 ObjCPropertyInfo Info;
339 ReadVariableInfo(
Data, Info);
341 if (Flags & (1 << 0))
342 Info.setSwiftImportAsAccessors(Flags & (1 << 1));
349 :
public VersionedTableInfo<FieldTableInfo, SingleDeclTableKey, FieldInfo> {
351 static internal_key_type ReadKey(
const uint8_t *
Data,
unsigned Length) {
352 auto CtxID = endian::readNext<uint32_t, llvm::endianness::little>(
Data);
353 auto NameID = endian::readNext<uint32_t, llvm::endianness::little>(
Data);
354 return {CtxID, NameID};
357 hash_value_type
ComputeHash(internal_key_type Key) {
358 return static_cast<size_t>(Key.hashValue());
361 static FieldInfo readUnversioned(internal_key_type Key,
364 ReadVariableInfo(
Data, Info);
371 uint8_t Payload = endian::readNext<uint8_t, llvm::endianness::little>(
Data);
373 if (Payload & 0x01) {
375 Info.setLevelAudited(
Level);
379 if (Payload & 0x01) {
387 endian::readNext<uint16_t, llvm::endianness::little>(
Data);
388 Info.ExternalBounds = std::string(
Data,
Data + ExternalBoundsLen);
389 Data += ExternalBoundsLen;
394 ReadVariableInfo(
Data, Info);
396 uint8_t Payload = endian::readNext<uint8_t, llvm::endianness::little>(
Data);
397 if (
auto RawConvention = Payload & 0x7) {
399 Info.setRetainCountConvention(Convention);
403 Info.setLifetimebound(Payload & 0x02);
406 Info.setNoEscape(Payload & 0x02);
409 ReadBoundsSafetyInfo(
Data, Info.BoundsSafety.emplace());
414 ReadCommonEntityInfo(
Data, Info);
416 uint8_t Payload = endian::readNext<uint8_t, llvm::endianness::little>(
Data);
418 Info.UnsafeBufferUsage = 1;
420 if (
auto RawConvention = Payload & 0x7) {
422 Info.setRetainCountConvention(Convention);
425 Info.NullabilityAudited = Payload & 0x1;
427 assert(Payload == 0 &&
"Bad API notes");
429 Info.NumAdjustedNullable =
430 endian::readNext<uint8_t, llvm::endianness::little>(
Data);
431 Info.NullabilityPayload =
432 endian::readNext<uint64_t, llvm::endianness::little>(
Data);
435 endian::readNext<uint16_t, llvm::endianness::little>(
Data);
436 while (NumParams > 0) {
438 ReadParamInfo(
Data, pi);
439 Info.Params.push_back(pi);
443 unsigned ResultTypeLen =
444 endian::readNext<uint16_t, llvm::endianness::little>(
Data);
445 Info.ResultType = std::string(
Data,
Data + ResultTypeLen);
446 Data += ResultTypeLen;
448 unsigned SwiftReturnOwnershipLength =
449 endian::readNext<uint16_t, llvm::endianness::little>(
Data);
450 Info.SwiftReturnOwnership = std::string(
reinterpret_cast<const char *
>(
Data),
451 reinterpret_cast<const char *
>(
Data) +
452 SwiftReturnOwnershipLength);
453 Data += SwiftReturnOwnershipLength;
457class ObjCMethodTableInfo
458 :
public VersionedTableInfo<ObjCMethodTableInfo,
459 std::tuple<uint32_t, uint32_t, uint8_t>,
462 static internal_key_type ReadKey(
const uint8_t *
Data,
unsigned Length) {
463 auto ClassID = endian::readNext<uint32_t, llvm::endianness::little>(
Data);
465 endian::readNext<uint32_t, llvm::endianness::little>(
Data);
466 auto IsInstance = endian::readNext<uint8_t, llvm::endianness::little>(
Data);
470 hash_value_type
ComputeHash(internal_key_type Key) {
474 static ObjCMethodInfo readUnversioned(internal_key_type Key,
478 bool HasSelf = Payload & 0x01;
480 Info.RequiredInit = Payload & 0x01;
482 Info.DesignatedInit = Payload & 0x01;
484 assert(Payload == 0 &&
"Unable to fully decode 'Payload'.");
486 ReadFunctionInfo(
Data, Info);
488 Info.Self = ParamInfo{};
489 ReadParamInfo(
Data, *Info.Self);
496class ObjCSelectorTableInfo {
498 using internal_key_type = StoredObjCSelector;
499 using external_key_type = internal_key_type;
501 using hash_value_type = unsigned;
502 using offset_type = unsigned;
504 internal_key_type GetInternalKey(external_key_type Key) {
return Key; }
506 external_key_type GetExternalKey(internal_key_type Key) {
return Key; }
508 hash_value_type
ComputeHash(internal_key_type Key) {
509 return llvm::DenseMapInfo<StoredObjCSelector>::getHashValue(Key);
512 static bool EqualKey(internal_key_type LHS, internal_key_type RHS) {
513 return llvm::DenseMapInfo<StoredObjCSelector>::isEqual(LHS, RHS);
516 static std::pair<unsigned, unsigned> ReadKeyDataLength(
const uint8_t *&
Data) {
518 endian::readNext<uint16_t, llvm::endianness::little>(
Data);
519 unsigned DataLength =
520 endian::readNext<uint16_t, llvm::endianness::little>(
Data);
521 return {KeyLength, DataLength};
524 static internal_key_type ReadKey(
const uint8_t *
Data,
unsigned Length) {
525 internal_key_type Key;
526 Key.NumArgs = endian::readNext<uint16_t, llvm::endianness::little>(
Data);
528 for (
unsigned i = 0; i != NumIdents; ++i) {
529 Key.Identifiers.push_back(
530 endian::readNext<uint32_t, llvm::endianness::little>(
Data));
535 static data_type ReadData(internal_key_type Key,
const uint8_t *
Data,
537 return endian::readNext<uint32_t, llvm::endianness::little>(
Data);
542class GlobalVariableTableInfo
543 :
public VersionedTableInfo<GlobalVariableTableInfo, SingleDeclTableKey,
544 GlobalVariableInfo> {
546 static internal_key_type ReadKey(
const uint8_t *
Data,
unsigned Length) {
547 auto CtxID = endian::readNext<uint32_t, llvm::endianness::little>(
Data);
548 auto NameID = endian::readNext<uint32_t, llvm::endianness::little>(
Data);
549 return {CtxID, NameID};
552 hash_value_type
ComputeHash(internal_key_type Key) {
553 return static_cast<size_t>(Key.hashValue());
556 static GlobalVariableInfo readUnversioned(internal_key_type Key,
558 GlobalVariableInfo Info;
559 ReadVariableInfo(
Data, Info);
565class GlobalFunctionTableInfo
566 :
public VersionedTableInfo<GlobalFunctionTableInfo, FunctionTableKey,
567 GlobalFunctionInfo> {
569 static internal_key_type ReadKey(
const uint8_t *
Data,
unsigned Length) {
570 return readFunctionTableKey(
Data, Length);
573 hash_value_type
ComputeHash(internal_key_type Key) {
574 return static_cast<size_t>(Key.hashValue());
577 static GlobalFunctionInfo readUnversioned(internal_key_type Key,
579 GlobalFunctionInfo Info;
580 ReadFunctionInfo(
Data, Info);
586class CXXMethodTableInfo
587 :
public VersionedTableInfo<CXXMethodTableInfo, FunctionTableKey,
590 static internal_key_type ReadKey(
const uint8_t *
Data,
unsigned Length) {
591 return readFunctionTableKey(
Data, Length);
594 hash_value_type
ComputeHash(internal_key_type Key) {
595 return static_cast<size_t>(Key.hashValue());
598 static CXXMethodInfo readUnversioned(internal_key_type Key,
603 bool HasThis = Payload & 0x01;
605 assert(Payload == 0 &&
"Unable to fully decode 'Payload'.");
607 ReadFunctionInfo(
Data, Info);
609 Info.This = ParamInfo{};
610 ReadParamInfo(
Data, *Info.This);
617class EnumConstantTableInfo
618 :
public VersionedTableInfo<EnumConstantTableInfo, uint32_t,
621 static internal_key_type ReadKey(
const uint8_t *
Data,
unsigned Length) {
622 auto NameID = endian::readNext<uint32_t, llvm::endianness::little>(
Data);
626 hash_value_type
ComputeHash(internal_key_type Key) {
630 static EnumConstantInfo readUnversioned(internal_key_type Key,
632 EnumConstantInfo Info;
633 ReadCommonEntityInfo(
Data, Info);
640 :
public VersionedTableInfo<TagTableInfo, SingleDeclTableKey, TagInfo> {
642 static internal_key_type ReadKey(
const uint8_t *
Data,
unsigned Length) {
643 auto CtxID = endian::readNext<uint32_t, llvm::endianness::little>(
Data);
645 endian::readNext<IdentifierID, llvm::endianness::little>(
Data);
646 return {CtxID, NameID};
649 hash_value_type
ComputeHash(internal_key_type Key) {
650 return static_cast<size_t>(Key.hashValue());
653 static TagInfo readUnversioned(internal_key_type Key,
const uint8_t *&
Data) {
658 Info.setFlagEnum(Payload & 2);
661 Info.EnumExtensibility =
665 endian::readNext<uint8_t, llvm::endianness::little>(
Data);
669 endian::readNext<uint8_t, llvm::endianness::little>(
Data);
671 Info.setSwiftEscapable(std::optional(Escapable ==
kSwiftConforms));
673 unsigned ImportAsLength =
674 endian::readNext<uint16_t, llvm::endianness::little>(
Data);
675 if (ImportAsLength > 0) {
677 std::string(
reinterpret_cast<const char *
>(
Data), ImportAsLength - 1);
678 Data += ImportAsLength - 1;
680 unsigned RetainOpLength =
681 endian::readNext<uint16_t, llvm::endianness::little>(
Data);
682 if (RetainOpLength > 0) {
684 std::string(
reinterpret_cast<const char *
>(
Data), RetainOpLength - 1);
685 Data += RetainOpLength - 1;
687 unsigned ReleaseOpLength =
688 endian::readNext<uint16_t, llvm::endianness::little>(
Data);
689 if (ReleaseOpLength > 0) {
690 Info.SwiftReleaseOp = std::string(
reinterpret_cast<const char *
>(
Data),
691 ReleaseOpLength - 1);
692 Data += ReleaseOpLength - 1;
694 unsigned DefaultOwnershipLength =
695 endian::readNext<uint16_t, llvm::endianness::little>(
Data);
696 if (DefaultOwnershipLength > 0) {
697 Info.SwiftDefaultOwnership = std::string(
698 reinterpret_cast<const char *
>(
Data), DefaultOwnershipLength - 1);
699 Data += DefaultOwnershipLength - 1;
701 unsigned DestroyOpLength =
702 endian::readNext<uint16_t, llvm::endianness::little>(
Data);
703 if (DestroyOpLength > 0) {
704 Info.SwiftDestroyOp = std::string(
reinterpret_cast<const char *
>(
Data),
705 DestroyOpLength - 1);
706 Data += DestroyOpLength - 1;
709 ReadCommonTypeInfo(
Data, Info);
715class TypedefTableInfo
716 :
public VersionedTableInfo<TypedefTableInfo, SingleDeclTableKey,
719 static internal_key_type ReadKey(
const uint8_t *
Data,
unsigned Length) {
720 auto CtxID = endian::readNext<uint32_t, llvm::endianness::little>(
Data);
722 endian::readNext<IdentifierID, llvm::endianness::little>(
Data);
723 return {CtxID, nameID};
726 hash_value_type
ComputeHash(internal_key_type Key) {
727 return static_cast<size_t>(Key.hashValue());
730 static TypedefInfo readUnversioned(internal_key_type Key,
738 ReadCommonTypeInfo(
Data, Info);
760 llvm::OnDiskIterableChainedHashTable<IdentifierTableInfo>;
769 llvm::OnDiskIterableChainedHashTable<ContextIDTableInfo>;
775 llvm::OnDiskIterableChainedHashTable<ContextInfoTableInfo>;
781 llvm::OnDiskIterableChainedHashTable<ObjCPropertyTableInfo>;
787 llvm::OnDiskIterableChainedHashTable<FieldTableInfo>;
793 llvm::OnDiskIterableChainedHashTable<ObjCMethodTableInfo>;
799 llvm::OnDiskIterableChainedHashTable<CXXMethodTableInfo>;
805 llvm::OnDiskIterableChainedHashTable<ObjCSelectorTableInfo>;
811 llvm::OnDiskIterableChainedHashTable<GlobalVariableTableInfo>;
817 llvm::OnDiskIterableChainedHashTable<GlobalFunctionTableInfo>;
823 llvm::OnDiskIterableChainedHashTable<EnumConstantTableInfo>;
834 llvm::OnDiskIterableChainedHashTable<TypedefTableInfo>;
841 std::optional<IdentifierID>
getIdentifier(llvm::StringRef Str);
849 template <
typename TableT>
876 std::optional<FunctionTableKey>
getFunctionKey(uint32_t ParentContextID,
877 llvm::StringRef Name);
878 template <
typename ParameterT>
879 std::optional<FunctionTableKey>
882 std::optional<FunctionTableKey>
883 getFunctionKey(std::optional<Context> ParentContext, llvm::StringRef Name);
884 template <
typename ParameterT>
885 std::optional<FunctionTableKey>
886 getFunctionKey(std::optional<Context> ParentContext, llvm::StringRef Name,
899std::optional<IdentifierID>
914std::optional<llvm::StringRef>
920 return llvm::StringRef();
930 auto Identifier = Identifiers.begin();
931 auto KnownID = IDs.begin();
932 auto IdentifierEnd = Identifiers.end();
933 auto KnownIDEnd = IDs.end();
934 for (; Identifier != IdentifierEnd && KnownID != KnownIDEnd;
935 ++Identifier, ++KnownID)
943 return Known->second;
946template <
typename TableT>
950 static_assert(std::is_same_v<TableT, SerializedGlobalFunctionTable> ||
951 std::is_same_v<TableT, SerializedCXXMethodTable>);
952 constexpr bool IsCXXMethod = std::is_same_v<TableT, SerializedCXXMethodTable>;
955 if (!Key.parameterTypeIDs)
962std::optional<FunctionTableKey>
964 llvm::StringRef Name) {
970template <
typename ParameterT>
972 uint32_t ParentContextID, llvm::StringRef Name,
975 ParentContextID, Name, Parameters,
980 std::optional<Context> ParentContext, llvm::StringRef Name) {
981 uint32_t ParentContextID =
982 ParentContext ? ParentContext->id.Value :
static_cast<uint32_t
>(-1);
986template <
typename ParameterT>
988 std::optional<Context> ParentContext, llvm::StringRef Name,
990 uint32_t ParentContextID =
991 ParentContext ? ParentContext->id.Value :
static_cast<uint32_t
>(-1);
995std::optional<SelectorID>
1003 for (
auto Ident :
Selector.Identifiers) {
1007 return std::nullopt;
1013 return std::nullopt;
1021 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1022 "Failed to enter control block");
1024 bool SawMetadata =
false;
1028 return MaybeNext.takeError();
1030 llvm::BitstreamEntry
Next = MaybeNext.get();
1032 while (
Next.Kind != llvm::BitstreamEntry::EndBlock) {
1033 if (
Next.Kind == llvm::BitstreamEntry::Error)
1034 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1035 "Malformed bitstream entry");
1037 if (
Next.Kind == llvm::BitstreamEntry::SubBlock) {
1040 if (Cursor.SkipBlock())
1041 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1042 "Failed to skip sub-block");
1044 MaybeNext = Cursor.advance();
1046 return MaybeNext.takeError();
1048 Next = MaybeNext.get();
1053 llvm::StringRef BlobData;
1055 Cursor.readRecord(
Next.ID, Scratch, &BlobData);
1057 return MaybeKind.takeError();
1059 unsigned Kind = MaybeKind.get();
1065 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1066 "Multiple metadata records found");
1069 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1070 "Version mismatch in API Notes");
1092 MaybeNext = Cursor.advance();
1094 return MaybeNext.takeError();
1096 Next = MaybeNext.get();
1100 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1101 "Missing metadata record");
1103 return llvm::Error::success();
1109 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1110 "Failed to enter identifier block");
1114 return MaybeNext.takeError();
1116 llvm::BitstreamEntry
Next = MaybeNext.get();
1118 while (
Next.Kind != llvm::BitstreamEntry::EndBlock) {
1119 if (
Next.Kind == llvm::BitstreamEntry::Error)
1120 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1121 "Malformed bitstream entry");
1123 if (
Next.Kind == llvm::BitstreamEntry::SubBlock) {
1126 if (Cursor.SkipBlock())
1127 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1128 "Failed to skip sub-block");
1130 MaybeNext = Cursor.advance();
1132 return MaybeNext.takeError();
1134 Next = MaybeNext.get();
1139 llvm::StringRef BlobData;
1141 Cursor.readRecord(
Next.ID, Scratch, &BlobData);
1143 return MaybeKind.takeError();
1145 unsigned Kind = MaybeKind.get();
1150 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1151 "Multiple identifier records found");
1153 uint32_t tableOffset;
1154 identifier_block::IdentifierDataLayout::readRecord(Scratch, tableOffset);
1155 auto base =
reinterpret_cast<const uint8_t *
>(BlobData.data());
1158 base + tableOffset, base +
sizeof(uint32_t), base));
1168 MaybeNext = Cursor.advance();
1170 return MaybeNext.takeError();
1172 Next = MaybeNext.get();
1175 return llvm::Error::success();
1181 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1182 "Failed to enter Objective-C context block");
1186 return MaybeNext.takeError();
1188 llvm::BitstreamEntry
Next = MaybeNext.get();
1190 while (
Next.Kind != llvm::BitstreamEntry::EndBlock) {
1191 if (
Next.Kind == llvm::BitstreamEntry::Error)
1192 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1193 "Malformed bitstream entry");
1195 if (
Next.Kind == llvm::BitstreamEntry::SubBlock) {
1198 if (Cursor.SkipBlock())
1199 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1200 "Failed to skip sub-block");
1202 MaybeNext = Cursor.advance();
1204 return MaybeNext.takeError();
1206 Next = MaybeNext.get();
1211 llvm::StringRef BlobData;
1213 Cursor.readRecord(
Next.ID, Scratch, &BlobData);
1215 return MaybeKind.takeError();
1217 unsigned Kind = MaybeKind.get();
1222 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1223 "Multiple context ID records found");
1225 uint32_t tableOffset;
1226 context_block::ContextIDLayout::readRecord(Scratch, tableOffset);
1227 auto base =
reinterpret_cast<const uint8_t *
>(BlobData.data());
1230 base + tableOffset, base +
sizeof(uint32_t), base));
1237 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1238 "Multiple context info records found");
1240 uint32_t tableOffset;
1241 context_block::ContextInfoLayout::readRecord(Scratch, tableOffset);
1242 auto base =
reinterpret_cast<const uint8_t *
>(BlobData.data());
1245 base + tableOffset, base +
sizeof(uint32_t), base));
1255 MaybeNext = Cursor.advance();
1257 return MaybeNext.takeError();
1259 Next = MaybeNext.get();
1262 return llvm::Error::success();
1268 return llvm::createStringError(
1269 llvm::inconvertibleErrorCode(),
1270 "Failed to enter Objective-C property block");
1274 return MaybeNext.takeError();
1276 llvm::BitstreamEntry
Next = MaybeNext.get();
1278 while (
Next.Kind != llvm::BitstreamEntry::EndBlock) {
1279 if (
Next.Kind == llvm::BitstreamEntry::Error)
1280 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1281 "Malformed bitstream entry");
1283 if (
Next.Kind == llvm::BitstreamEntry::SubBlock) {
1286 if (Cursor.SkipBlock())
1287 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1288 "Failed to skip sub-block");
1290 MaybeNext = Cursor.advance();
1292 return MaybeNext.takeError();
1294 Next = MaybeNext.get();
1299 llvm::StringRef BlobData;
1301 Cursor.readRecord(
Next.ID, Scratch, &BlobData);
1303 return MaybeKind.takeError();
1305 unsigned Kind = MaybeKind.get();
1310 return llvm::createStringError(
1311 llvm::inconvertibleErrorCode(),
1312 "Multiple Objective-C property records found");
1314 uint32_t tableOffset;
1315 objc_property_block::ObjCPropertyDataLayout::readRecord(Scratch,
1317 auto base =
reinterpret_cast<const uint8_t *
>(BlobData.data());
1320 base + tableOffset, base +
sizeof(uint32_t), base));
1330 MaybeNext = Cursor.advance();
1332 return MaybeNext.takeError();
1334 Next = MaybeNext.get();
1337 return llvm::Error::success();
1343 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1344 "Failed to enter Objective-C method block");
1348 return MaybeNext.takeError();
1350 llvm::BitstreamEntry
Next = MaybeNext.get();
1351 while (
Next.Kind != llvm::BitstreamEntry::EndBlock) {
1352 if (
Next.Kind == llvm::BitstreamEntry::Error)
1353 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1354 "Malformed bitstream entry");
1356 if (
Next.Kind == llvm::BitstreamEntry::SubBlock) {
1359 if (Cursor.SkipBlock())
1360 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1361 "Failed to skip sub-block");
1363 MaybeNext = Cursor.advance();
1365 return MaybeNext.takeError();
1367 Next = MaybeNext.get();
1372 llvm::StringRef BlobData;
1374 Cursor.readRecord(
Next.ID, Scratch, &BlobData);
1376 return MaybeKind.takeError();
1378 unsigned Kind = MaybeKind.get();
1383 return llvm::createStringError(
1384 llvm::inconvertibleErrorCode(),
1385 "Multiple Objective-C method records found");
1387 uint32_t tableOffset;
1388 objc_method_block::ObjCMethodDataLayout::readRecord(Scratch, tableOffset);
1389 auto base =
reinterpret_cast<const uint8_t *
>(BlobData.data());
1392 base + tableOffset, base +
sizeof(uint32_t), base));
1402 MaybeNext = Cursor.advance();
1404 return MaybeNext.takeError();
1406 Next = MaybeNext.get();
1409 return llvm::Error::success();
1415 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1416 "Failed to enter C++ method block");
1420 return MaybeNext.takeError();
1422 llvm::BitstreamEntry
Next = MaybeNext.get();
1423 while (
Next.Kind != llvm::BitstreamEntry::EndBlock) {
1424 if (
Next.Kind == llvm::BitstreamEntry::Error)
1425 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1426 "Malformed bitstream entry");
1428 if (
Next.Kind == llvm::BitstreamEntry::SubBlock) {
1431 if (Cursor.SkipBlock())
1432 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1433 "Failed to skip sub-block");
1435 MaybeNext = Cursor.advance();
1437 return MaybeNext.takeError();
1439 Next = MaybeNext.get();
1444 llvm::StringRef BlobData;
1446 Cursor.readRecord(
Next.ID, Scratch, &BlobData);
1448 return MaybeKind.takeError();
1450 unsigned Kind = MaybeKind.get();
1455 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1456 "Multiple C++ method records found");
1458 uint32_t tableOffset;
1459 cxx_method_block::CXXMethodDataLayout::readRecord(Scratch, tableOffset);
1460 auto base =
reinterpret_cast<const uint8_t *
>(BlobData.data());
1463 base + tableOffset, base +
sizeof(uint32_t), base));
1473 MaybeNext = Cursor.advance();
1475 return MaybeNext.takeError();
1477 Next = MaybeNext.get();
1480 return llvm::Error::success();
1486 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1487 "Failed to enter field block");
1491 return MaybeNext.takeError();
1493 llvm::BitstreamEntry
Next = MaybeNext.get();
1494 while (
Next.Kind != llvm::BitstreamEntry::EndBlock) {
1495 if (
Next.Kind == llvm::BitstreamEntry::Error)
1496 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1497 "Malformed bitstream entry");
1499 if (
Next.Kind == llvm::BitstreamEntry::SubBlock) {
1502 if (Cursor.SkipBlock())
1503 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1504 "Failed to skip sub-block");
1506 MaybeNext = Cursor.advance();
1508 return MaybeNext.takeError();
1510 Next = MaybeNext.get();
1515 llvm::StringRef BlobData;
1517 Cursor.readRecord(
Next.ID, Scratch, &BlobData);
1519 return MaybeKind.takeError();
1521 unsigned Kind = MaybeKind.get();
1526 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1527 "Multiple field records found");
1529 uint32_t tableOffset;
1530 field_block::FieldDataLayout::readRecord(Scratch, tableOffset);
1531 auto base =
reinterpret_cast<const uint8_t *
>(BlobData.data());
1533 FieldTable.reset(SerializedFieldTable::Create(
1534 base + tableOffset, base +
sizeof(uint32_t), base));
1544 MaybeNext = Cursor.advance();
1546 return MaybeNext.takeError();
1548 Next = MaybeNext.get();
1551 return llvm::Error::success();
1557 return llvm::createStringError(
1558 llvm::inconvertibleErrorCode(),
1559 "Failed to enter Objective-C selector block");
1563 return MaybeNext.takeError();
1565 llvm::BitstreamEntry
Next = MaybeNext.get();
1566 while (
Next.Kind != llvm::BitstreamEntry::EndBlock) {
1567 if (
Next.Kind == llvm::BitstreamEntry::Error)
1568 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1569 "Malformed bitstream entry");
1571 if (
Next.Kind == llvm::BitstreamEntry::SubBlock) {
1574 if (Cursor.SkipBlock())
1575 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1576 "Failed to skip sub-block");
1578 MaybeNext = Cursor.advance();
1580 return MaybeNext.takeError();
1582 Next = MaybeNext.get();
1587 llvm::StringRef BlobData;
1589 Cursor.readRecord(
Next.ID, Scratch, &BlobData);
1591 return MaybeKind.takeError();
1593 unsigned Kind = MaybeKind.get();
1598 return llvm::createStringError(
1599 llvm::inconvertibleErrorCode(),
1600 "Multiple Objective-C selector records found");
1602 uint32_t tableOffset;
1603 objc_selector_block::ObjCSelectorDataLayout::readRecord(Scratch,
1605 auto base =
reinterpret_cast<const uint8_t *
>(BlobData.data());
1608 base + tableOffset, base +
sizeof(uint32_t), base));
1618 MaybeNext = Cursor.advance();
1620 return MaybeNext.takeError();
1622 Next = MaybeNext.get();
1625 return llvm::Error::success();
1631 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1632 "Failed to enter global variable block");
1636 return MaybeNext.takeError();
1638 llvm::BitstreamEntry
Next = MaybeNext.get();
1639 while (
Next.Kind != llvm::BitstreamEntry::EndBlock) {
1640 if (
Next.Kind == llvm::BitstreamEntry::Error)
1641 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1642 "Malformed bitstream entry");
1644 if (
Next.Kind == llvm::BitstreamEntry::SubBlock) {
1647 if (Cursor.SkipBlock())
1648 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1649 "Failed to skip sub-block");
1651 MaybeNext = Cursor.advance();
1653 return MaybeNext.takeError();
1655 Next = MaybeNext.get();
1660 llvm::StringRef BlobData;
1662 Cursor.readRecord(
Next.ID, Scratch, &BlobData);
1664 return MaybeKind.takeError();
1666 unsigned Kind = MaybeKind.get();
1671 return llvm::createStringError(
1672 llvm::inconvertibleErrorCode(),
1673 "Multiple global variable records found");
1675 uint32_t tableOffset;
1676 global_variable_block::GlobalVariableDataLayout::readRecord(Scratch,
1678 auto base =
reinterpret_cast<const uint8_t *
>(BlobData.data());
1681 base + tableOffset, base +
sizeof(uint32_t), base));
1691 MaybeNext = Cursor.advance();
1693 return MaybeNext.takeError();
1695 Next = MaybeNext.get();
1698 return llvm::Error::success();
1704 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1705 "Failed to enter global function block");
1709 return MaybeNext.takeError();
1711 llvm::BitstreamEntry
Next = MaybeNext.get();
1712 while (
Next.Kind != llvm::BitstreamEntry::EndBlock) {
1713 if (
Next.Kind == llvm::BitstreamEntry::Error)
1714 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1715 "Malformed bitstream entry");
1717 if (
Next.Kind == llvm::BitstreamEntry::SubBlock) {
1720 if (Cursor.SkipBlock())
1721 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1722 "Failed to skip sub-block");
1724 MaybeNext = Cursor.advance();
1726 return MaybeNext.takeError();
1728 Next = MaybeNext.get();
1733 llvm::StringRef BlobData;
1735 Cursor.readRecord(
Next.ID, Scratch, &BlobData);
1737 return MaybeKind.takeError();
1739 unsigned Kind = MaybeKind.get();
1744 return llvm::createStringError(
1745 llvm::inconvertibleErrorCode(),
1746 "Multiple global function records found");
1748 uint32_t tableOffset;
1749 global_function_block::GlobalFunctionDataLayout::readRecord(Scratch,
1751 auto base =
reinterpret_cast<const uint8_t *
>(BlobData.data());
1754 base + tableOffset, base +
sizeof(uint32_t), base));
1764 MaybeNext = Cursor.advance();
1766 return MaybeNext.takeError();
1768 Next = MaybeNext.get();
1771 return llvm::Error::success();
1777 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1778 "Failed to enter enum constant block");
1782 return MaybeNext.takeError();
1784 llvm::BitstreamEntry
Next = MaybeNext.get();
1785 while (
Next.Kind != llvm::BitstreamEntry::EndBlock) {
1786 if (
Next.Kind == llvm::BitstreamEntry::Error)
1787 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1788 "Malformed bitstream entry");
1790 if (
Next.Kind == llvm::BitstreamEntry::SubBlock) {
1793 if (Cursor.SkipBlock())
1794 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1795 "Failed to skip sub-block");
1797 MaybeNext = Cursor.advance();
1799 return MaybeNext.takeError();
1801 Next = MaybeNext.get();
1806 llvm::StringRef BlobData;
1808 Cursor.readRecord(
Next.ID, Scratch, &BlobData);
1810 return MaybeKind.takeError();
1812 unsigned Kind = MaybeKind.get();
1817 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1818 "Multiple enum constant records found");
1820 uint32_t tableOffset;
1821 enum_constant_block::EnumConstantDataLayout::readRecord(Scratch,
1823 auto base =
reinterpret_cast<const uint8_t *
>(BlobData.data());
1826 base + tableOffset, base +
sizeof(uint32_t), base));
1836 MaybeNext = Cursor.advance();
1838 return MaybeNext.takeError();
1840 Next = MaybeNext.get();
1843 return llvm::Error::success();
1849 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1850 "Failed to enter tag block");
1854 return MaybeNext.takeError();
1856 llvm::BitstreamEntry
Next = MaybeNext.get();
1857 while (
Next.Kind != llvm::BitstreamEntry::EndBlock) {
1858 if (
Next.Kind == llvm::BitstreamEntry::Error)
1859 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1860 "Malformed bitstream entry");
1862 if (
Next.Kind == llvm::BitstreamEntry::SubBlock) {
1865 if (Cursor.SkipBlock())
1866 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1867 "Failed to skip sub-block");
1869 MaybeNext = Cursor.advance();
1871 return MaybeNext.takeError();
1873 Next = MaybeNext.get();
1878 llvm::StringRef BlobData;
1880 Cursor.readRecord(
Next.ID, Scratch, &BlobData);
1882 return MaybeKind.takeError();
1884 unsigned Kind = MaybeKind.get();
1889 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1890 "Multiple tag records found");
1892 uint32_t tableOffset;
1893 tag_block::TagDataLayout::readRecord(Scratch, tableOffset);
1894 auto base =
reinterpret_cast<const uint8_t *
>(BlobData.data());
1896 TagTable.reset(SerializedTagTable::Create(base + tableOffset,
1897 base +
sizeof(uint32_t), base));
1907 MaybeNext = Cursor.advance();
1909 return MaybeNext.takeError();
1911 Next = MaybeNext.get();
1914 return llvm::Error::success();
1920 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1921 "Failed to enter typedef block");
1925 return MaybeNext.takeError();
1927 llvm::BitstreamEntry
Next = MaybeNext.get();
1928 while (
Next.Kind != llvm::BitstreamEntry::EndBlock) {
1929 if (
Next.Kind == llvm::BitstreamEntry::Error)
1930 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1931 "Malformed bitstream entry");
1933 if (
Next.Kind == llvm::BitstreamEntry::SubBlock) {
1936 if (Cursor.SkipBlock())
1937 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1938 "Failed to skip sub-block");
1940 MaybeNext = Cursor.advance();
1942 return MaybeNext.takeError();
1944 Next = MaybeNext.get();
1949 llvm::StringRef BlobData;
1951 Cursor.readRecord(
Next.ID, Scratch, &BlobData);
1953 return MaybeKind.takeError();
1955 unsigned Kind = MaybeKind.get();
1960 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1961 "Multiple typedef records found");
1963 uint32_t tableOffset;
1964 typedef_block::TypedefDataLayout::readRecord(Scratch, tableOffset);
1965 auto base =
reinterpret_cast<const uint8_t *
>(BlobData.data());
1968 base + tableOffset, base +
sizeof(uint32_t), base));
1978 MaybeNext = Cursor.advance();
1980 return MaybeNext.takeError();
1982 Next = MaybeNext.get();
1985 return llvm::Error::success();
1988APINotesReader::APINotesReader(llvm::MemoryBuffer *InputBuffer,
1989 llvm::VersionTuple SwiftVersion,
2000 if (Cursor.AtEndOfStream()) {
2001 Err = llvm::createStringError(
2002 llvm::inconvertibleErrorCode(),
2003 "Unexpected end of stream while reading signature");
2009 Err = maybeRead.takeError();
2012 if (maybeRead.get() !=
byte) {
2013 Err = llvm::createStringError(llvm::inconvertibleErrorCode(),
2014 "Invalid signature in API notes file");
2020 bool HasValidControlBlock =
false;
2021 llvm::SmallVector<uint64_t, 64> Scratch;
2022 while (!
Cursor.AtEndOfStream()) {
2023 llvm::Expected<llvm::BitstreamEntry> MaybeTopLevelEntry =
Cursor.advance();
2024 if (!MaybeTopLevelEntry) {
2025 Err = MaybeTopLevelEntry.takeError();
2028 llvm::BitstreamEntry TopLevelEntry = MaybeTopLevelEntry.get();
2030 if (TopLevelEntry.Kind != llvm::BitstreamEntry::SubBlock)
2033 switch (TopLevelEntry.ID) {
2034 case llvm::bitc::BLOCKINFO_BLOCK_ID:
2035 if (!
Cursor.ReadBlockInfoBlock()) {
2036 Err = llvm::createStringError(llvm::inconvertibleErrorCode(),
2037 "Failed to read block info");
2044 if (HasValidControlBlock) {
2045 Err = llvm::createStringError(llvm::inconvertibleErrorCode(),
2046 "Multiple control blocks found");
2049 if (llvm::Error BlockErr =
2050 Implementation->readControlBlock(Cursor, Scratch)) {
2051 Err = std::move(BlockErr);
2054 HasValidControlBlock =
true;
2058 if (!HasValidControlBlock) {
2059 Err = llvm::createStringError(llvm::inconvertibleErrorCode(),
2060 "Missing control block");
2063 if (llvm::Error BlockErr =
2064 Implementation->readIdentifierBlock(Cursor, Scratch)) {
2065 Err = std::move(BlockErr);
2071 if (!HasValidControlBlock) {
2072 Err = llvm::createStringError(llvm::inconvertibleErrorCode(),
2073 "Missing control block");
2076 if (llvm::Error BlockErr =
2077 Implementation->readContextBlock(Cursor, Scratch)) {
2078 Err = std::move(BlockErr);
2084 if (!HasValidControlBlock) {
2085 Err = llvm::createStringError(llvm::inconvertibleErrorCode(),
2086 "Missing control block");
2089 if (llvm::Error BlockErr =
2090 Implementation->readObjCPropertyBlock(Cursor, Scratch)) {
2091 Err = std::move(BlockErr);
2097 if (!HasValidControlBlock) {
2098 Err = llvm::createStringError(llvm::inconvertibleErrorCode(),
2099 "Missing control block");
2102 if (llvm::Error BlockErr =
2103 Implementation->readObjCMethodBlock(Cursor, Scratch)) {
2104 Err = std::move(BlockErr);
2110 if (!HasValidControlBlock) {
2111 Err = llvm::createStringError(llvm::inconvertibleErrorCode(),
2112 "Missing control block");
2115 if (llvm::Error BlockErr =
2116 Implementation->readCXXMethodBlock(Cursor, Scratch)) {
2117 Err = std::move(BlockErr);
2123 if (!HasValidControlBlock) {
2124 Err = llvm::createStringError(llvm::inconvertibleErrorCode(),
2125 "Missing control block");
2128 if (llvm::Error BlockErr =
2129 Implementation->readFieldBlock(Cursor, Scratch)) {
2130 Err = std::move(BlockErr);
2136 if (!HasValidControlBlock) {
2137 Err = llvm::createStringError(llvm::inconvertibleErrorCode(),
2138 "Missing control block");
2141 if (llvm::Error BlockErr =
2142 Implementation->readObjCSelectorBlock(Cursor, Scratch)) {
2143 Err = std::move(BlockErr);
2149 if (!HasValidControlBlock) {
2150 Err = llvm::createStringError(llvm::inconvertibleErrorCode(),
2151 "Missing control block");
2154 if (llvm::Error BlockErr =
2155 Implementation->readGlobalVariableBlock(Cursor, Scratch)) {
2156 Err = std::move(BlockErr);
2162 if (!HasValidControlBlock) {
2163 Err = llvm::createStringError(llvm::inconvertibleErrorCode(),
2164 "Missing control block");
2167 if (llvm::Error BlockErr =
2168 Implementation->readGlobalFunctionBlock(Cursor, Scratch)) {
2169 Err = std::move(BlockErr);
2175 if (!HasValidControlBlock) {
2176 Err = llvm::createStringError(llvm::inconvertibleErrorCode(),
2177 "Missing control block");
2180 if (llvm::Error BlockErr =
2181 Implementation->readEnumConstantBlock(Cursor, Scratch)) {
2182 Err = std::move(BlockErr);
2188 if (!HasValidControlBlock) {
2189 Err = llvm::createStringError(llvm::inconvertibleErrorCode(),
2190 "Missing control block");
2193 if (llvm::Error BlockErr =
2194 Implementation->readTagBlock(Cursor, Scratch)) {
2195 Err = std::move(BlockErr);
2201 if (!HasValidControlBlock) {
2202 Err = llvm::createStringError(llvm::inconvertibleErrorCode(),
2203 "Missing control block");
2206 if (llvm::Error BlockErr =
2207 Implementation->readTypedefBlock(Cursor, Scratch)) {
2208 Err = std::move(BlockErr);
2216 if (
Cursor.SkipBlock()) {
2217 Err = llvm::createStringError(llvm::inconvertibleErrorCode(),
2218 "Failed to skip unknown top-level block");
2225 if (!
Cursor.AtEndOfStream()) {
2226 Err = llvm::createStringError(llvm::inconvertibleErrorCode(),
2227 "Bitstream has unread data after all blocks");
2236 llvm::VersionTuple SwiftVersion) {
2237 llvm::Error Err = llvm::Error::success();
2238 std::unique_ptr<APINotesReader> Reader(
2239 new APINotesReader(InputBuffer.release(), SwiftVersion, Err));
2244 return std::move(Reader);
2247template <
typename T>
2249 llvm::VersionTuple Version,
2251 : Results(
std::move(R)) {
2253 assert(!Results.empty());
2254 assert(llvm::is_sorted(
2256 [](
const std::pair<llvm::VersionTuple, T> &left,
2257 const std::pair<llvm::VersionTuple, T> &right) ->
bool {
2262 assert((&left == &right || left.first != right.first) &&
2263 "two entries for the same version");
2264 return left.first < right.first;
2267 Selected = std::nullopt;
2268 for (
unsigned i = 0, n = Results.size(); i != n; ++i) {
2269 if (!Version.empty() && Results[i].first >= Version) {
2281 if (!Selected && Results[0].first.empty())
2286 -> std::optional<ContextID> {
2288 return std::nullopt;
2292 return std::nullopt;
2299 return std::nullopt;
2307 return std::nullopt;
2311 return std::nullopt;
2315 return std::nullopt;
2321 -> std::optional<ContextID> {
2323 return std::nullopt;
2327 return std::nullopt;
2334 return std::nullopt;
2342 return std::nullopt;
2346 return std::nullopt;
2350 return std::nullopt;
2359 return std::nullopt;
2363 return std::nullopt;
2366 std::make_tuple(CtxID.Value, *PropertyID, (
char)IsInstance));
2368 return std::nullopt;
2374 bool IsInstanceMethod)
2377 return std::nullopt;
2381 return std::nullopt;
2384 ObjCMethodTableInfo::internal_key_type{CtxID.Value, *SelID,
2387 return std::nullopt;
2395 return std::nullopt;
2399 return std::nullopt;
2404 return std::nullopt;
2411 return lookupCXXMethodImpl(CtxID, Name);
2417 return lookupCXXMethodImpl(CtxID, Name, Parameters);
2420std::optional<APINotesFunctionSelectorKey>
2422 std::optional<FunctionTableKey> Key =
2425 return std::nullopt;
2429std::optional<APINotesFunctionSelectorKey>
2433 std::optional<FunctionTableKey> Key =
2436 return std::nullopt;
2440auto APINotesReader::lookupCXXMethodImpl(
ContextID CtxID, llvm::StringRef Name)
2441 -> VersionedInfo<CXXMethodInfo> {
2442 if (!Implementation->CXXMethodTable)
2443 return std::nullopt;
2445 std::optional<FunctionTableKey> Key =
2446 Implementation->getFunctionKey(CtxID.Value, Name);
2448 return std::nullopt;
2450 auto Known = Implementation->CXXMethodTable->find(*Key);
2451 if (Known == Implementation->CXXMethodTable->end())
2452 return std::nullopt;
2454 return {Implementation->SwiftVersion, *Known};
2457template <
typename ParameterT>
2458auto APINotesReader::lookupCXXMethodImpl(
ContextID CtxID, llvm::StringRef Name,
2462 return std::nullopt;
2464 std::optional<FunctionTableKey> Key =
2467 return std::nullopt;
2471 return std::nullopt;
2477 std::optional<Context> Ctx)
2480 return std::nullopt;
2484 return std::nullopt;
2490 return std::nullopt;
2496 std::optional<Context> Ctx)
2498 return lookupGlobalFunctionImpl(Name, Ctx);
2504 return lookupGlobalFunctionImpl(Name, Parameters, Ctx);
2507std::optional<APINotesFunctionSelectorKey>
2509 std::optional<Context> Ctx) {
2510 std::optional<FunctionTableKey> Key =
2513 return std::nullopt;
2517std::optional<APINotesFunctionSelectorKey>
2520 std::optional<Context> Ctx) {
2521 std::optional<FunctionTableKey> Key =
2524 return std::nullopt;
2538std::optional<llvm::SmallVector<std::string, 4>>
2542 return std::nullopt;
2547 std::optional<llvm::StringRef>
TypeName =
2550 return std::nullopt;
2551 ParameterSpellings.push_back(
TypeName->str());
2553 return ParameterSpellings;
2556auto APINotesReader::lookupGlobalFunctionImpl(llvm::StringRef Name,
2557 std::optional<Context> Ctx)
2558 -> VersionedInfo<GlobalFunctionInfo> {
2559 if (!Implementation->GlobalFunctionTable)
2560 return std::nullopt;
2562 std::optional<FunctionTableKey> Key =
2563 Implementation->getFunctionKey(Ctx, Name);
2565 return std::nullopt;
2567 auto Known = Implementation->GlobalFunctionTable->find(*Key);
2568 if (Known == Implementation->GlobalFunctionTable->end())
2569 return std::nullopt;
2571 return {Implementation->SwiftVersion, *Known};
2574template <
typename ParameterT>
2575auto APINotesReader::lookupGlobalFunctionImpl(
2579 return std::nullopt;
2581 std::optional<FunctionTableKey> Key =
2584 return std::nullopt;
2588 return std::nullopt;
2596 return std::nullopt;
2600 return std::nullopt;
2604 return std::nullopt;
2610 std::optional<Context> ParentCtx)
2611 -> std::optional<ContextID> {
2613 return std::nullopt;
2617 return std::nullopt;
2622 return std::nullopt;
2630 return std::nullopt;
2634 return std::nullopt;
2640 return std::nullopt;
2646 std::optional<Context> Ctx)
2649 return std::nullopt;
2653 return std::nullopt;
2659 return std::nullopt;
2665 llvm::StringRef Name, std::optional<ContextID> ParentNamespaceID)
2666 -> std::optional<ContextID> {
2668 return std::nullopt;
2672 return std::nullopt;
2674 uint32_t RawParentNamespaceID =
2675 ParentNamespaceID ? ParentNamespaceID->Value : -1;
2679 return std::nullopt;
static StringRef getIdentifier(const Token &Tok)
__SIZE_TYPE__ size_t
The unsigned integer type of the result of the sizeof operator.
Smart pointer class that efficiently represents Objective-C method names.
llvm::OnDiskIterableChainedHashTable< FieldTableInfo > SerializedFieldTable
std::unique_ptr< SerializedContextIDTable > ContextIDTable
The Objective-C / C++ context ID table.
std::string ModuleName
The name of the module that we read from the control block.
std::optional< std::pair< off_t, time_t > > SourceFileSizeAndModTime
llvm::Error readTypedefBlock(llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl< uint64_t > &Scratch)
std::unique_ptr< SerializedIdentifierTable > IdentifierTable
The identifier table.
llvm::Error readControlBlock(llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl< uint64_t > &Scratch)
llvm::Error readContextBlock(llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl< uint64_t > &Scratch)
llvm::OnDiskIterableChainedHashTable< TagTableInfo > SerializedTagTable
llvm::OnDiskIterableChainedHashTable< GlobalFunctionTableInfo > SerializedGlobalFunctionTable
std::unique_ptr< SerializedGlobalFunctionTable > GlobalFunctionTable
The global function table.
std::unique_ptr< SerializedObjCPropertyTable > ObjCPropertyTable
The Objective-C property table.
llvm::OnDiskIterableChainedHashTable< EnumConstantTableInfo > SerializedEnumConstantTable
llvm::Error readObjCPropertyBlock(llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl< uint64_t > &Scratch)
std::unique_ptr< SerializedGlobalVariableTable > GlobalVariableTable
The global variable table.
llvm::Error readObjCMethodBlock(llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl< uint64_t > &Scratch)
std::unique_ptr< SerializedTypedefTable > TypedefTable
The typedef table.
std::optional< FunctionTableKey > getFunctionKey(uint32_t ParentContextID, llvm::StringRef Name)
llvm::Error readIdentifierBlock(llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl< uint64_t > &Scratch)
llvm::MemoryBuffer * InputBuffer
The input buffer for the API notes data.
std::unique_ptr< SerializedObjCSelectorTable > ObjCSelectorTable
The Objective-C selector table.
llvm::OnDiskIterableChainedHashTable< ObjCMethodTableInfo > SerializedObjCMethodTable
std::optional< llvm::DenseMap< uint32_t, llvm::StringRef > > IdentifierStrings
Lazy reverse lookup cache from identifier ID to string.
llvm::Error readTagBlock(llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl< uint64_t > &Scratch)
llvm::OnDiskIterableChainedHashTable< CXXMethodTableInfo > SerializedCXXMethodTable
llvm::Error readEnumConstantBlock(llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl< uint64_t > &Scratch)
llvm::OnDiskIterableChainedHashTable< ContextInfoTableInfo > SerializedContextInfoTable
std::unique_ptr< SerializedCXXMethodTable > CXXMethodTable
The C++ method table.
llvm::OnDiskIterableChainedHashTable< ObjCSelectorTableInfo > SerializedObjCSelectorTable
llvm::OnDiskIterableChainedHashTable< IdentifierTableInfo > SerializedIdentifierTable
llvm::Error readObjCSelectorBlock(llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl< uint64_t > &Scratch)
llvm::Error readGlobalVariableBlock(llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl< uint64_t > &Scratch)
std::unique_ptr< SerializedEnumConstantTable > EnumConstantTable
The enumerator table.
std::optional< IdentifierID > getIdentifier(llvm::StringRef Str)
Retrieve the identifier ID for the given string, or an empty optional if the string is unknown.
llvm::Error readFieldBlock(llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl< uint64_t > &Scratch)
std::unique_ptr< SerializedTagTable > TagTable
The tag table.
std::optional< llvm::StringRef > getIdentifierString(IdentifierID ID)
Retrieve the identifier string for the given ID, or an empty optional if the ID is unknown.
std::unique_ptr< SerializedFieldTable > FieldTable
The C record field table.
std::optional< SelectorID > getSelector(ObjCSelectorRef Selector)
Retrieve the selector ID for the given selector, or an empty optional if the string is unknown.
llvm::OnDiskIterableChainedHashTable< TypedefTableInfo > SerializedTypedefTable
llvm::OnDiskIterableChainedHashTable< GlobalVariableTableInfo > SerializedGlobalVariableTable
void collectExactFunctionParameterSelectors(TableT &Table, llvm::SmallVectorImpl< APINotesFunctionSelectorKey > &Selectors)
Collect exact parameter selector keys stored in the given function-like table.
llvm::VersionTuple SwiftVersion
The Swift version to use for filtering.
llvm::OnDiskIterableChainedHashTable< ContextIDTableInfo > SerializedContextIDTable
std::unique_ptr< SerializedObjCMethodTable > ObjCMethodTable
The Objective-C method table.
std::unique_ptr< SerializedContextInfoTable > ContextInfoTable
The Objective-C context info table.
llvm::Error readGlobalFunctionBlock(llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl< uint64_t > &Scratch)
llvm::OnDiskIterableChainedHashTable< ObjCPropertyTableInfo > SerializedObjCPropertyTable
llvm::Error readCXXMethodBlock(llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl< uint64_t > &Scratch)
Captures the completed versioned information for a particular part of API notes, including both unver...
VersionedInfo(std::nullopt_t)
Form an empty set of versioned information.
VersionedInfo< ContextInfo > lookupObjCClassInfo(llvm::StringRef Name)
Look for information regarding the given Objective-C class.
VersionedInfo< FieldInfo > lookupField(ContextID CtxID, llvm::StringRef Name)
Look for information regarding the given field of a C struct.
VersionedInfo< CXXMethodInfo > lookupCXXMethod(ContextID CtxID, llvm::StringRef Name)
Look for information regarding the given C++ method in the given C++ tag context.
VersionedInfo< TagInfo > lookupTag(llvm::StringRef Name, std::optional< Context > Ctx=std::nullopt)
Look for information regarding the given tag (struct/union/enum/C++ class).
VersionedInfo< GlobalFunctionInfo > lookupGlobalFunction(llvm::StringRef Name, std::optional< Context > Ctx=std::nullopt)
Look for information regarding the given global function.
VersionedInfo< ObjCPropertyInfo > lookupObjCProperty(ContextID CtxID, llvm::StringRef Name, bool IsInstance)
Look for information regarding the given Objective-C property in the given context.
VersionedInfo< ObjCMethodInfo > lookupObjCMethod(ContextID CtxID, ObjCSelectorRef Selector, bool IsInstanceMethod)
Look for information regarding the given Objective-C method in the given context.
std::optional< APINotesFunctionSelectorKey > getGlobalFunctionSelectorKey(llvm::StringRef Name, std::optional< Context > Ctx=std::nullopt)
Build the selector key for the given global function.
VersionedInfo< GlobalVariableInfo > lookupGlobalVariable(llvm::StringRef Name, std::optional< Context > Ctx=std::nullopt)
Look for information regarding the given global variable.
std::optional< APINotesFunctionSelectorKey > getCXXMethodSelectorKey(ContextID CtxID, llvm::StringRef Name)
Build the selector key for the given C++ method.
std::optional< ContextID > lookupNamespaceID(llvm::StringRef Name, std::optional< ContextID > ParentNamespaceID=std::nullopt)
Look for the context ID of the given C++ namespace.
std::optional< ContextID > lookupTagID(llvm::StringRef Name, std::optional< Context > ParentCtx=std::nullopt)
Look for the context ID of the given C++ tag.
VersionedInfo< TypedefInfo > lookupTypedef(llvm::StringRef Name, std::optional< Context > Ctx=std::nullopt)
Look for information regarding the given typedef.
std::optional< ContextID > lookupObjCClassID(llvm::StringRef Name)
Look for the context ID of the given Objective-C class.
std::optional< llvm::SmallVector< std::string, 4 > > getParameterSelectorSpellingsForDiagnostics(const APINotesFunctionSelectorKey &Key)
Reconstruct parameter selector strings for a stored exact selector key.
static llvm::Expected< std::unique_ptr< APINotesReader > > Create(std::unique_ptr< llvm::MemoryBuffer > InputBuffer, llvm::VersionTuple SwiftVersion)
Create a new API notes reader from the given memory buffer, which contains the contents of a binary A...
VersionedInfo< ContextInfo > lookupObjCProtocolInfo(llvm::StringRef Name)
Look for information regarding the given Objective-C protocol.
void collectExactFunctionParameterSelectors(llvm::SmallVectorImpl< APINotesFunctionSelectorKey > &Selectors)
Collect exact parameter selector keys stored by this reader.
std::optional< ContextID > lookupObjCProtocolID(llvm::StringRef Name)
Look for the context ID of the given Objective-C protocol.
VersionedInfo< EnumConstantInfo > lookupEnumConstant(llvm::StringRef Name)
Look for information regarding the given enumerator.
Describes API notes data for any entity.
Describes API notes for types.
Opaque context ID used to refer to an Objective-C class or protocol or a C++ namespace.
API notes for a function or method.
Describes a function or method parameter.
API notes for a variable/property.
constexpr unsigned FunctionTableKeyBaseLength
RetainCountConventionKind
llvm::PointerEmbeddedInt< unsigned, 31 > IdentifierID
llvm::PointerEmbeddedInt< unsigned, 31 > SelectorID
std::optional< FunctionTableKey > getFunctionKeyImpl(uint32_t ParentContextID, llvm::StringRef Name, GetIdentifierFn GetIdentifier)
const uint8_t kSwiftConforms
SwiftNewTypeKind
The kind of a swift_wrapper/swift_newtype.
EnumExtensibilityKind
The payload for an enum_extensibility attribute.
const uint8_t kSwiftDoesNotConform
constexpr uint8_t FunctionKeyHasParameterSelector
A stored C or C++ function declaration, represented by the ID of its parent context,...
const uint16_t VERSION_MAJOR
API notes file major version number.
const unsigned char API_NOTES_SIGNATURE[]
Magic number for API notes files.
const uint16_t VERSION_MINOR
API notes file minor version number.
@ OBJC_CONTEXT_BLOCK_ID
The Objective-C context data block, which contains information about Objective-C classes and protocol...
@ TYPEDEF_BLOCK_ID
The typedef data block, which maps typedef names to information about the typedefs.
@ OBJC_PROPERTY_BLOCK_ID
The Objective-C property data block, which maps Objective-C (class name, property name) pairs to info...
@ ENUM_CONSTANT_BLOCK_ID
The enum constant data block, which maps enumerator names to information about the enumerators.
@ TAG_BLOCK_ID
The tag data block, which maps tag names to information about the tags.
@ OBJC_METHOD_BLOCK_ID
The Objective-C property data block, which maps Objective-C (class name, selector,...
@ FIELD_BLOCK_ID
The fields data block, which maps names fields of C records to information about the field.
@ OBJC_SELECTOR_BLOCK_ID
The Objective-C selector data block, which maps Objective-C selector names (# of pieces,...
@ CXX_METHOD_BLOCK_ID
The C++ method data block, which maps C++ (context id, method name) pairs to information about the me...
@ GLOBAL_FUNCTION_BLOCK_ID
The (global) functions data block, which maps global function names to information about the global f...
@ CONTROL_BLOCK_ID
The control block, which contains all of the information that needs to be validated prior to committi...
@ IDENTIFIER_BLOCK_ID
The identifier data block, which maps identifier strings to IDs.
@ GLOBAL_VARIABLE_BLOCK_ID
The global variables data block, which maps global variable names to information about the global var...
unsigned ComputeHash(Selector Sel)
The JSON file list parser is used to communicate input to InstallAPI.
NullabilityKind
Describes the nullability of a particular type.
@ Result
The result type of a method or function.
hash_code hash_value(const clang::dependencies::ModuleID &ID)
__packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 __packed_splat2 uint8_t
__packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 __packed_splat2 __packed_splat4 uint16_t
__packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 __packed_splat2 __packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 uint32_t
Stable reader-facing identity for an API notes function selector entry.
A stored Objective-C or C++ context, represented by the ID of its parent context, the kind of this co...
A key for a stored global-function or C++-method API notes entry.
std::optional< llvm::SmallVector< IdentifierID, 2 > > parameterTypeIDs
A temporary reference to an Objective-C selector, suitable for referencing selector data on the stack...
A stored Objective-C or C++ declaration, represented by the ID of its parent context,...
A stored Objective-C selector.
llvm::SmallVector< IdentifierID, 2 > Identifiers