18#include "llvm/ADT/Hashing.h"
19#include "llvm/Bitstream/BitstreamReader.h"
20#include "llvm/Support/DJB.h"
21#include "llvm/Support/OnDiskHashTable.h"
25using namespace llvm::support;
29llvm::VersionTuple ReadVersionTuple(
const uint8_t *&
Data) {
32 unsigned Major = endian::readNext<uint32_t, llvm::endianness::little>(
Data);
34 return llvm::VersionTuple(Major);
36 unsigned Minor = endian::readNext<uint32_t, llvm::endianness::little>(
Data);
38 return llvm::VersionTuple(Major, Minor);
41 endian::readNext<uint32_t, llvm::endianness::little>(
Data);
43 return llvm::VersionTuple(Major, Minor, Subminor);
45 unsigned Build = endian::readNext<uint32_t, llvm::endianness::little>(
Data);
46 return llvm::VersionTuple(Major, Minor, Subminor, Build);
52 "Unexpected function table key length");
54 auto CtxID = endian::readNext<uint32_t, llvm::endianness::little>(
Data);
55 auto NameID = endian::readNext<uint32_t, llvm::endianness::little>(
Data);
57 endian::readNext<uint8_t, llvm::endianness::little>(
Data);
59 endian::readNext<uint16_t, llvm::endianness::little>(
Data);
63 "Unexpected function table key length");
65 llvm::SmallVector<IdentifierID, 2> ParameterTypeIDs;
68 ParameterTypeIDs.push_back(
69 endian::readNext<uint32_t, llvm::endianness::little>(
Data));
72 "Unexpected function table key flags");
74 return {CtxID, NameID, ParameterTypeIDs};
76 assert(ParameterTypeIDs.empty() &&
77 "Broad function table key should not store parameters");
78 return {CtxID, NameID};
82template <
typename Derived,
typename KeyType,
typename UnversionedDataType>
83class VersionedTableInfo {
85 using internal_key_type = KeyType;
86 using external_key_type = KeyType;
88 llvm::SmallVector<std::pair<llvm::VersionTuple, UnversionedDataType>, 1>;
89 using hash_value_type =
size_t;
90 using offset_type = unsigned;
92 internal_key_type GetInternalKey(external_key_type Key) {
return Key; }
94 external_key_type GetExternalKey(internal_key_type Key) {
return Key; }
96 static bool EqualKey(internal_key_type LHS, internal_key_type RHS) {
100 static std::pair<unsigned, unsigned> ReadKeyDataLength(
const uint8_t *&
Data) {
102 endian::readNext<uint16_t, llvm::endianness::little>(
Data);
103 unsigned DataLength =
104 endian::readNext<uint16_t, llvm::endianness::little>(
Data);
105 return {KeyLength, DataLength};
108 static data_type ReadData(internal_key_type Key,
const uint8_t *
Data,
110 unsigned NumElements =
111 endian::readNext<uint16_t, llvm::endianness::little>(
Data);
113 Result.reserve(NumElements);
114 for (
unsigned i = 0; i != NumElements; ++i) {
115 auto version = ReadVersionTuple(
Data);
116 const auto *DataBefore =
Data;
118 auto UnversionedData = Derived::readUnversioned(Key,
Data);
119 assert(
Data != DataBefore &&
120 "Unversioned data reader didn't move pointer");
121 Result.push_back({version, UnversionedData});
130 Info.Unavailable = (EncodedBits >> 1) & 0x01;
131 Info.UnavailableInSwift = EncodedBits & 0x01;
132 if ((EncodedBits >> 2) & 0x01)
133 Info.setSwiftPrivate(
static_cast<bool>((EncodedBits >> 3) & 0x01));
134 if ((EncodedBits >> 4) & 0x01)
139 endian::readNext<uint16_t, llvm::endianness::little>(
Data);
140 Info.UnavailableMsg =
141 std::string(
reinterpret_cast<const char *
>(
Data),
142 reinterpret_cast<const char *
>(
Data) + MsgLength);
145 unsigned SwiftNameLength =
146 endian::readNext<uint16_t, llvm::endianness::little>(
Data);
148 std::string(
reinterpret_cast<const char *
>(
Data),
149 reinterpret_cast<const char *
>(
Data) + SwiftNameLength);
150 Data += SwiftNameLength;
155 ReadCommonEntityInfo(
Data, Info);
157 unsigned SwiftBridgeLength =
158 endian::readNext<uint16_t, llvm::endianness::little>(
Data);
159 if (SwiftBridgeLength > 0) {
160 Info.setSwiftBridge(std::string(
reinterpret_cast<const char *
>(
Data),
161 SwiftBridgeLength - 1));
162 Data += SwiftBridgeLength - 1;
165 unsigned ErrorDomainLength =
166 endian::readNext<uint16_t, llvm::endianness::little>(
Data);
167 if (ErrorDomainLength > 0) {
168 Info.setNSErrorDomain(std::optional<std::string>(std::string(
169 reinterpret_cast<const char *
>(
Data), ErrorDomainLength - 1)));
170 Data += ErrorDomainLength - 1;
173 if (
unsigned ConformanceLength =
174 endian::readNext<uint16_t, llvm::endianness::little>(
Data)) {
175 Info.setSwiftConformance(std::string(
reinterpret_cast<const char *
>(
Data),
176 ConformanceLength - 1));
177 Data += ConformanceLength - 1;
182class IdentifierTableInfo {
184 using internal_key_type = llvm::StringRef;
185 using external_key_type = llvm::StringRef;
188 using offset_type = unsigned;
190 internal_key_type GetInternalKey(external_key_type Key) {
return Key; }
192 external_key_type GetExternalKey(internal_key_type Key) {
return Key; }
194 hash_value_type
ComputeHash(internal_key_type Key) {
195 return llvm::djbHash(Key);
198 static bool EqualKey(internal_key_type LHS, internal_key_type RHS) {
202 static std::pair<unsigned, unsigned> ReadKeyDataLength(
const uint8_t *&
Data) {
204 endian::readNext<uint16_t, llvm::endianness::little>(
Data);
205 unsigned DataLength =
206 endian::readNext<uint16_t, llvm::endianness::little>(
Data);
207 return {KeyLength, DataLength};
210 static internal_key_type ReadKey(
const uint8_t *
Data,
unsigned Length) {
211 return llvm::StringRef(
reinterpret_cast<const char *
>(
Data), Length);
214 static data_type ReadData(internal_key_type key,
const uint8_t *
Data,
216 return endian::readNext<uint32_t, llvm::endianness::little>(
Data);
222class ContextIDTableInfo {
224 using internal_key_type = ContextTableKey;
225 using external_key_type = internal_key_type;
226 using data_type = unsigned;
227 using hash_value_type =
size_t;
228 using offset_type = unsigned;
230 internal_key_type GetInternalKey(external_key_type Key) {
return Key; }
232 external_key_type GetExternalKey(internal_key_type Key) {
return Key; }
234 hash_value_type
ComputeHash(internal_key_type Key) {
235 return static_cast<size_t>(Key.hashValue());
238 static bool EqualKey(internal_key_type LHS, internal_key_type RHS) {
242 static std::pair<unsigned, unsigned> ReadKeyDataLength(
const uint8_t *&
Data) {
244 endian::readNext<uint16_t, llvm::endianness::little>(
Data);
245 unsigned DataLength =
246 endian::readNext<uint16_t, llvm::endianness::little>(
Data);
247 return {KeyLength, DataLength};
250 static internal_key_type ReadKey(
const uint8_t *
Data,
unsigned Length) {
252 endian::readNext<uint32_t, llvm::endianness::little>(
Data);
254 endian::readNext<uint8_t, llvm::endianness::little>(
Data);
255 auto NameID = endian::readNext<uint32_t, llvm::endianness::little>(
Data);
259 static data_type ReadData(internal_key_type Key,
const uint8_t *
Data,
261 return endian::readNext<uint32_t, llvm::endianness::little>(
Data);
266class ContextInfoTableInfo
267 :
public VersionedTableInfo<ContextInfoTableInfo, unsigned, ContextInfo> {
269 static internal_key_type ReadKey(
const uint8_t *
Data,
unsigned Length) {
270 return endian::readNext<uint32_t, llvm::endianness::little>(
Data);
273 hash_value_type
ComputeHash(internal_key_type Key) {
277 static ContextInfo readUnversioned(internal_key_type Key,
280 ReadCommonTypeInfo(
Data, Info);
284 Info.setHasDesignatedInits(
true);
285 Payload = Payload >> 1;
288 Info.setDefaultNullability(
static_cast<NullabilityKind>(Payload & 0x03));
291 if (Payload & (1 << 1))
292 Info.setSwiftObjCMembers(Payload & 1);
295 if (Payload & (1 << 1))
296 Info.setSwiftImportAsNonGeneric(Payload & 1);
304 ReadCommonEntityInfo(
Data, Info);
310 auto TypeLen = endian::readNext<uint16_t, llvm::endianness::little>(
Data);
311 Info.setType(std::string(
Data,
Data + TypeLen));
316class ObjCPropertyTableInfo
317 :
public VersionedTableInfo<ObjCPropertyTableInfo,
318 std::tuple<uint32_t, uint32_t, uint8_t>,
321 static internal_key_type ReadKey(
const uint8_t *
Data,
unsigned Length) {
322 auto ClassID = endian::readNext<uint32_t, llvm::endianness::little>(
Data);
323 auto NameID = endian::readNext<uint32_t, llvm::endianness::little>(
Data);
324 char IsInstance = endian::readNext<uint8_t, llvm::endianness::little>(
Data);
325 return {ClassID, NameID, IsInstance};
328 hash_value_type
ComputeHash(internal_key_type Key) {
332 static ObjCPropertyInfo readUnversioned(internal_key_type Key,
334 ObjCPropertyInfo Info;
335 ReadVariableInfo(
Data, Info);
337 if (Flags & (1 << 0))
338 Info.setSwiftImportAsAccessors(Flags & (1 << 1));
345 :
public VersionedTableInfo<FieldTableInfo, SingleDeclTableKey, FieldInfo> {
347 static internal_key_type ReadKey(
const uint8_t *
Data,
unsigned Length) {
348 auto CtxID = endian::readNext<uint32_t, llvm::endianness::little>(
Data);
349 auto NameID = endian::readNext<uint32_t, llvm::endianness::little>(
Data);
350 return {CtxID, NameID};
353 hash_value_type
ComputeHash(internal_key_type Key) {
354 return static_cast<size_t>(Key.hashValue());
357 static FieldInfo readUnversioned(internal_key_type Key,
360 ReadVariableInfo(
Data, Info);
367 uint8_t Payload = endian::readNext<uint8_t, llvm::endianness::little>(
Data);
369 if (Payload & 0x01) {
371 Info.setLevelAudited(
Level);
375 if (Payload & 0x01) {
383 endian::readNext<uint16_t, llvm::endianness::little>(
Data);
384 Info.ExternalBounds = std::string(
Data,
Data + ExternalBoundsLen);
385 Data += ExternalBoundsLen;
390 ReadVariableInfo(
Data, Info);
392 uint8_t Payload = endian::readNext<uint8_t, llvm::endianness::little>(
Data);
393 if (
auto RawConvention = Payload & 0x7) {
395 Info.setRetainCountConvention(Convention);
399 Info.setLifetimebound(Payload & 0x02);
402 Info.setNoEscape(Payload & 0x02);
405 ReadBoundsSafetyInfo(
Data, Info.BoundsSafety.emplace());
410 ReadCommonEntityInfo(
Data, Info);
412 uint8_t Payload = endian::readNext<uint8_t, llvm::endianness::little>(
Data);
414 Info.UnsafeBufferUsage = 1;
416 if (
auto RawConvention = Payload & 0x7) {
418 Info.setRetainCountConvention(Convention);
421 Info.NullabilityAudited = Payload & 0x1;
423 assert(Payload == 0 &&
"Bad API notes");
425 Info.NumAdjustedNullable =
426 endian::readNext<uint8_t, llvm::endianness::little>(
Data);
427 Info.NullabilityPayload =
428 endian::readNext<uint64_t, llvm::endianness::little>(
Data);
431 endian::readNext<uint16_t, llvm::endianness::little>(
Data);
432 while (NumParams > 0) {
434 ReadParamInfo(
Data, pi);
435 Info.Params.push_back(pi);
439 unsigned ResultTypeLen =
440 endian::readNext<uint16_t, llvm::endianness::little>(
Data);
441 Info.ResultType = std::string(
Data,
Data + ResultTypeLen);
442 Data += ResultTypeLen;
444 unsigned SwiftReturnOwnershipLength =
445 endian::readNext<uint16_t, llvm::endianness::little>(
Data);
446 Info.SwiftReturnOwnership = std::string(
reinterpret_cast<const char *
>(
Data),
447 reinterpret_cast<const char *
>(
Data) +
448 SwiftReturnOwnershipLength);
449 Data += SwiftReturnOwnershipLength;
453class ObjCMethodTableInfo
454 :
public VersionedTableInfo<ObjCMethodTableInfo,
455 std::tuple<uint32_t, uint32_t, uint8_t>,
458 static internal_key_type ReadKey(
const uint8_t *
Data,
unsigned Length) {
459 auto ClassID = endian::readNext<uint32_t, llvm::endianness::little>(
Data);
461 endian::readNext<uint32_t, llvm::endianness::little>(
Data);
462 auto IsInstance = endian::readNext<uint8_t, llvm::endianness::little>(
Data);
466 hash_value_type
ComputeHash(internal_key_type Key) {
470 static ObjCMethodInfo readUnversioned(internal_key_type Key,
474 bool HasSelf = Payload & 0x01;
476 Info.RequiredInit = Payload & 0x01;
478 Info.DesignatedInit = Payload & 0x01;
480 assert(Payload == 0 &&
"Unable to fully decode 'Payload'.");
482 ReadFunctionInfo(
Data, Info);
484 Info.Self = ParamInfo{};
485 ReadParamInfo(
Data, *Info.Self);
492class ObjCSelectorTableInfo {
494 using internal_key_type = StoredObjCSelector;
495 using external_key_type = internal_key_type;
497 using hash_value_type = unsigned;
498 using offset_type = unsigned;
500 internal_key_type GetInternalKey(external_key_type Key) {
return Key; }
502 external_key_type GetExternalKey(internal_key_type Key) {
return Key; }
504 hash_value_type
ComputeHash(internal_key_type Key) {
505 return llvm::DenseMapInfo<StoredObjCSelector>::getHashValue(Key);
508 static bool EqualKey(internal_key_type LHS, internal_key_type RHS) {
509 return llvm::DenseMapInfo<StoredObjCSelector>::isEqual(LHS, RHS);
512 static std::pair<unsigned, unsigned> ReadKeyDataLength(
const uint8_t *&
Data) {
514 endian::readNext<uint16_t, llvm::endianness::little>(
Data);
515 unsigned DataLength =
516 endian::readNext<uint16_t, llvm::endianness::little>(
Data);
517 return {KeyLength, DataLength};
520 static internal_key_type ReadKey(
const uint8_t *
Data,
unsigned Length) {
521 internal_key_type Key;
522 Key.NumArgs = endian::readNext<uint16_t, llvm::endianness::little>(
Data);
524 for (
unsigned i = 0; i != NumIdents; ++i) {
525 Key.Identifiers.push_back(
526 endian::readNext<uint32_t, llvm::endianness::little>(
Data));
531 static data_type ReadData(internal_key_type Key,
const uint8_t *
Data,
533 return endian::readNext<uint32_t, llvm::endianness::little>(
Data);
538class GlobalVariableTableInfo
539 :
public VersionedTableInfo<GlobalVariableTableInfo, SingleDeclTableKey,
540 GlobalVariableInfo> {
542 static internal_key_type ReadKey(
const uint8_t *
Data,
unsigned Length) {
543 auto CtxID = endian::readNext<uint32_t, llvm::endianness::little>(
Data);
544 auto NameID = endian::readNext<uint32_t, llvm::endianness::little>(
Data);
545 return {CtxID, NameID};
548 hash_value_type
ComputeHash(internal_key_type Key) {
549 return static_cast<size_t>(Key.hashValue());
552 static GlobalVariableInfo readUnversioned(internal_key_type Key,
554 GlobalVariableInfo Info;
555 ReadVariableInfo(
Data, Info);
561class GlobalFunctionTableInfo
562 :
public VersionedTableInfo<GlobalFunctionTableInfo, FunctionTableKey,
563 GlobalFunctionInfo> {
565 static internal_key_type ReadKey(
const uint8_t *
Data,
unsigned Length) {
566 return readFunctionTableKey(
Data, Length);
569 hash_value_type
ComputeHash(internal_key_type Key) {
570 return static_cast<size_t>(Key.hashValue());
573 static GlobalFunctionInfo readUnversioned(internal_key_type Key,
575 GlobalFunctionInfo Info;
576 ReadFunctionInfo(
Data, Info);
582class CXXMethodTableInfo
583 :
public VersionedTableInfo<CXXMethodTableInfo, FunctionTableKey,
586 static internal_key_type ReadKey(
const uint8_t *
Data,
unsigned Length) {
587 return readFunctionTableKey(
Data, Length);
590 hash_value_type
ComputeHash(internal_key_type Key) {
591 return static_cast<size_t>(Key.hashValue());
594 static CXXMethodInfo readUnversioned(internal_key_type Key,
599 bool HasThis = Payload & 0x01;
601 assert(Payload == 0 &&
"Unable to fully decode 'Payload'.");
603 ReadFunctionInfo(
Data, Info);
605 Info.This = ParamInfo{};
606 ReadParamInfo(
Data, *Info.This);
613class EnumConstantTableInfo
614 :
public VersionedTableInfo<EnumConstantTableInfo, uint32_t,
617 static internal_key_type ReadKey(
const uint8_t *
Data,
unsigned Length) {
618 auto NameID = endian::readNext<uint32_t, llvm::endianness::little>(
Data);
622 hash_value_type
ComputeHash(internal_key_type Key) {
626 static EnumConstantInfo readUnversioned(internal_key_type Key,
628 EnumConstantInfo Info;
629 ReadCommonEntityInfo(
Data, Info);
636 :
public VersionedTableInfo<TagTableInfo, SingleDeclTableKey, TagInfo> {
638 static internal_key_type ReadKey(
const uint8_t *
Data,
unsigned Length) {
639 auto CtxID = endian::readNext<uint32_t, llvm::endianness::little>(
Data);
641 endian::readNext<IdentifierID, llvm::endianness::little>(
Data);
642 return {CtxID, NameID};
645 hash_value_type
ComputeHash(internal_key_type Key) {
646 return static_cast<size_t>(Key.hashValue());
649 static TagInfo readUnversioned(internal_key_type Key,
const uint8_t *&
Data) {
654 Info.setFlagEnum(Payload & 2);
657 Info.EnumExtensibility =
661 endian::readNext<uint8_t, llvm::endianness::little>(
Data);
665 endian::readNext<uint8_t, llvm::endianness::little>(
Data);
667 Info.setSwiftEscapable(std::optional(Escapable ==
kSwiftConforms));
669 unsigned ImportAsLength =
670 endian::readNext<uint16_t, llvm::endianness::little>(
Data);
671 if (ImportAsLength > 0) {
673 std::string(
reinterpret_cast<const char *
>(
Data), ImportAsLength - 1);
674 Data += ImportAsLength - 1;
676 unsigned RetainOpLength =
677 endian::readNext<uint16_t, llvm::endianness::little>(
Data);
678 if (RetainOpLength > 0) {
680 std::string(
reinterpret_cast<const char *
>(
Data), RetainOpLength - 1);
681 Data += RetainOpLength - 1;
683 unsigned ReleaseOpLength =
684 endian::readNext<uint16_t, llvm::endianness::little>(
Data);
685 if (ReleaseOpLength > 0) {
686 Info.SwiftReleaseOp = std::string(
reinterpret_cast<const char *
>(
Data),
687 ReleaseOpLength - 1);
688 Data += ReleaseOpLength - 1;
690 unsigned DefaultOwnershipLength =
691 endian::readNext<uint16_t, llvm::endianness::little>(
Data);
692 if (DefaultOwnershipLength > 0) {
693 Info.SwiftDefaultOwnership = std::string(
694 reinterpret_cast<const char *
>(
Data), DefaultOwnershipLength - 1);
695 Data += DefaultOwnershipLength - 1;
697 unsigned DestroyOpLength =
698 endian::readNext<uint16_t, llvm::endianness::little>(
Data);
699 if (DestroyOpLength > 0) {
700 Info.SwiftDestroyOp = std::string(
reinterpret_cast<const char *
>(
Data),
701 DestroyOpLength - 1);
702 Data += DestroyOpLength - 1;
705 ReadCommonTypeInfo(
Data, Info);
711class TypedefTableInfo
712 :
public VersionedTableInfo<TypedefTableInfo, SingleDeclTableKey,
715 static internal_key_type ReadKey(
const uint8_t *
Data,
unsigned Length) {
716 auto CtxID = endian::readNext<uint32_t, llvm::endianness::little>(
Data);
718 endian::readNext<IdentifierID, llvm::endianness::little>(
Data);
719 return {CtxID, nameID};
722 hash_value_type
ComputeHash(internal_key_type Key) {
723 return static_cast<size_t>(Key.hashValue());
726 static TypedefInfo readUnversioned(internal_key_type Key,
734 ReadCommonTypeInfo(
Data, Info);
756 llvm::OnDiskIterableChainedHashTable<IdentifierTableInfo>;
762 llvm::OnDiskIterableChainedHashTable<ContextIDTableInfo>;
768 llvm::OnDiskIterableChainedHashTable<ContextInfoTableInfo>;
774 llvm::OnDiskIterableChainedHashTable<ObjCPropertyTableInfo>;
780 llvm::OnDiskIterableChainedHashTable<FieldTableInfo>;
786 llvm::OnDiskIterableChainedHashTable<ObjCMethodTableInfo>;
792 llvm::OnDiskIterableChainedHashTable<CXXMethodTableInfo>;
798 llvm::OnDiskIterableChainedHashTable<ObjCSelectorTableInfo>;
804 llvm::OnDiskIterableChainedHashTable<GlobalVariableTableInfo>;
810 llvm::OnDiskIterableChainedHashTable<GlobalFunctionTableInfo>;
816 llvm::OnDiskIterableChainedHashTable<EnumConstantTableInfo>;
827 llvm::OnDiskIterableChainedHashTable<TypedefTableInfo>;
834 std::optional<IdentifierID>
getIdentifier(llvm::StringRef Str);
858 std::optional<FunctionTableKey>
getFunctionKey(uint32_t ParentContextID,
859 llvm::StringRef Name);
860 std::optional<FunctionTableKey>
863 std::optional<FunctionTableKey>
864 getFunctionKey(std::optional<Context> ParentContext, llvm::StringRef Name);
865 std::optional<FunctionTableKey>
866 getFunctionKey(std::optional<Context> ParentContext, llvm::StringRef Name,
879std::optional<IdentifierID>
894std::optional<FunctionTableKey>
896 llvm::StringRef Name) {
903 uint32_t ParentContextID, llvm::StringRef Name,
906 ParentContextID, Name, Parameters,
911 std::optional<Context> ParentContext, llvm::StringRef Name) {
912 uint32_t ParentContextID =
913 ParentContext ? ParentContext->id.Value :
static_cast<uint32_t
>(-1);
918 std::optional<Context> ParentContext, llvm::StringRef Name,
920 uint32_t ParentContextID =
921 ParentContext ? ParentContext->id.Value :
static_cast<uint32_t
>(-1);
925std::optional<SelectorID>
933 for (
auto Ident :
Selector.Identifiers) {
951 return llvm::createStringError(llvm::inconvertibleErrorCode(),
952 "Failed to enter control block");
954 bool SawMetadata =
false;
958 return MaybeNext.takeError();
960 llvm::BitstreamEntry
Next = MaybeNext.get();
962 while (
Next.Kind != llvm::BitstreamEntry::EndBlock) {
963 if (
Next.Kind == llvm::BitstreamEntry::Error)
964 return llvm::createStringError(llvm::inconvertibleErrorCode(),
965 "Malformed bitstream entry");
967 if (
Next.Kind == llvm::BitstreamEntry::SubBlock) {
970 if (Cursor.SkipBlock())
971 return llvm::createStringError(llvm::inconvertibleErrorCode(),
972 "Failed to skip sub-block");
974 MaybeNext = Cursor.advance();
976 return MaybeNext.takeError();
978 Next = MaybeNext.get();
983 llvm::StringRef BlobData;
985 Cursor.readRecord(
Next.ID, Scratch, &BlobData);
987 return MaybeKind.takeError();
989 unsigned Kind = MaybeKind.get();
995 return llvm::createStringError(llvm::inconvertibleErrorCode(),
996 "Multiple metadata records found");
999 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1000 "Version mismatch in API Notes");
1022 MaybeNext = Cursor.advance();
1024 return MaybeNext.takeError();
1026 Next = MaybeNext.get();
1030 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1031 "Missing metadata record");
1033 return llvm::Error::success();
1039 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1040 "Failed to enter identifier block");
1044 return MaybeNext.takeError();
1046 llvm::BitstreamEntry
Next = MaybeNext.get();
1048 while (
Next.Kind != llvm::BitstreamEntry::EndBlock) {
1049 if (
Next.Kind == llvm::BitstreamEntry::Error)
1050 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1051 "Malformed bitstream entry");
1053 if (
Next.Kind == llvm::BitstreamEntry::SubBlock) {
1056 if (Cursor.SkipBlock())
1057 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1058 "Failed to skip sub-block");
1060 MaybeNext = Cursor.advance();
1062 return MaybeNext.takeError();
1064 Next = MaybeNext.get();
1069 llvm::StringRef BlobData;
1071 Cursor.readRecord(
Next.ID, Scratch, &BlobData);
1073 return MaybeKind.takeError();
1075 unsigned Kind = MaybeKind.get();
1080 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1081 "Multiple identifier records found");
1083 uint32_t tableOffset;
1084 identifier_block::IdentifierDataLayout::readRecord(Scratch, tableOffset);
1085 auto base =
reinterpret_cast<const uint8_t *
>(BlobData.data());
1088 base + tableOffset, base +
sizeof(uint32_t), base));
1098 MaybeNext = Cursor.advance();
1100 return MaybeNext.takeError();
1102 Next = MaybeNext.get();
1105 return llvm::Error::success();
1111 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1112 "Failed to enter Objective-C context block");
1116 return MaybeNext.takeError();
1118 llvm::BitstreamEntry
Next = MaybeNext.get();
1120 while (
Next.Kind != llvm::BitstreamEntry::EndBlock) {
1121 if (
Next.Kind == llvm::BitstreamEntry::Error)
1122 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1123 "Malformed bitstream entry");
1125 if (
Next.Kind == llvm::BitstreamEntry::SubBlock) {
1128 if (Cursor.SkipBlock())
1129 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1130 "Failed to skip sub-block");
1132 MaybeNext = Cursor.advance();
1134 return MaybeNext.takeError();
1136 Next = MaybeNext.get();
1141 llvm::StringRef BlobData;
1143 Cursor.readRecord(
Next.ID, Scratch, &BlobData);
1145 return MaybeKind.takeError();
1147 unsigned Kind = MaybeKind.get();
1152 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1153 "Multiple context ID records found");
1155 uint32_t tableOffset;
1156 context_block::ContextIDLayout::readRecord(Scratch, tableOffset);
1157 auto base =
reinterpret_cast<const uint8_t *
>(BlobData.data());
1160 base + tableOffset, base +
sizeof(uint32_t), base));
1167 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1168 "Multiple context info records found");
1170 uint32_t tableOffset;
1171 context_block::ContextInfoLayout::readRecord(Scratch, tableOffset);
1172 auto base =
reinterpret_cast<const uint8_t *
>(BlobData.data());
1175 base + tableOffset, base +
sizeof(uint32_t), base));
1185 MaybeNext = Cursor.advance();
1187 return MaybeNext.takeError();
1189 Next = MaybeNext.get();
1192 return llvm::Error::success();
1198 return llvm::createStringError(
1199 llvm::inconvertibleErrorCode(),
1200 "Failed to enter Objective-C property block");
1204 return MaybeNext.takeError();
1206 llvm::BitstreamEntry
Next = MaybeNext.get();
1208 while (
Next.Kind != llvm::BitstreamEntry::EndBlock) {
1209 if (
Next.Kind == llvm::BitstreamEntry::Error)
1210 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1211 "Malformed bitstream entry");
1213 if (
Next.Kind == llvm::BitstreamEntry::SubBlock) {
1216 if (Cursor.SkipBlock())
1217 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1218 "Failed to skip sub-block");
1220 MaybeNext = Cursor.advance();
1222 return MaybeNext.takeError();
1224 Next = MaybeNext.get();
1229 llvm::StringRef BlobData;
1231 Cursor.readRecord(
Next.ID, Scratch, &BlobData);
1233 return MaybeKind.takeError();
1235 unsigned Kind = MaybeKind.get();
1240 return llvm::createStringError(
1241 llvm::inconvertibleErrorCode(),
1242 "Multiple Objective-C property records found");
1244 uint32_t tableOffset;
1245 objc_property_block::ObjCPropertyDataLayout::readRecord(Scratch,
1247 auto base =
reinterpret_cast<const uint8_t *
>(BlobData.data());
1250 base + tableOffset, base +
sizeof(uint32_t), base));
1260 MaybeNext = Cursor.advance();
1262 return MaybeNext.takeError();
1264 Next = MaybeNext.get();
1267 return llvm::Error::success();
1273 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1274 "Failed to enter Objective-C method block");
1278 return MaybeNext.takeError();
1280 llvm::BitstreamEntry
Next = MaybeNext.get();
1281 while (
Next.Kind != llvm::BitstreamEntry::EndBlock) {
1282 if (
Next.Kind == llvm::BitstreamEntry::Error)
1283 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1284 "Malformed bitstream entry");
1286 if (
Next.Kind == llvm::BitstreamEntry::SubBlock) {
1289 if (Cursor.SkipBlock())
1290 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1291 "Failed to skip sub-block");
1293 MaybeNext = Cursor.advance();
1295 return MaybeNext.takeError();
1297 Next = MaybeNext.get();
1302 llvm::StringRef BlobData;
1304 Cursor.readRecord(
Next.ID, Scratch, &BlobData);
1306 return MaybeKind.takeError();
1308 unsigned Kind = MaybeKind.get();
1313 return llvm::createStringError(
1314 llvm::inconvertibleErrorCode(),
1315 "Multiple Objective-C method records found");
1317 uint32_t tableOffset;
1318 objc_method_block::ObjCMethodDataLayout::readRecord(Scratch, tableOffset);
1319 auto base =
reinterpret_cast<const uint8_t *
>(BlobData.data());
1322 base + tableOffset, base +
sizeof(uint32_t), base));
1332 MaybeNext = Cursor.advance();
1334 return MaybeNext.takeError();
1336 Next = MaybeNext.get();
1339 return llvm::Error::success();
1345 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1346 "Failed to enter C++ method block");
1350 return MaybeNext.takeError();
1352 llvm::BitstreamEntry
Next = MaybeNext.get();
1353 while (
Next.Kind != llvm::BitstreamEntry::EndBlock) {
1354 if (
Next.Kind == llvm::BitstreamEntry::Error)
1355 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1356 "Malformed bitstream entry");
1358 if (
Next.Kind == llvm::BitstreamEntry::SubBlock) {
1361 if (Cursor.SkipBlock())
1362 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1363 "Failed to skip sub-block");
1365 MaybeNext = Cursor.advance();
1367 return MaybeNext.takeError();
1369 Next = MaybeNext.get();
1374 llvm::StringRef BlobData;
1376 Cursor.readRecord(
Next.ID, Scratch, &BlobData);
1378 return MaybeKind.takeError();
1380 unsigned Kind = MaybeKind.get();
1385 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1386 "Multiple C++ method records found");
1388 uint32_t tableOffset;
1389 cxx_method_block::CXXMethodDataLayout::readRecord(Scratch, tableOffset);
1390 auto base =
reinterpret_cast<const uint8_t *
>(BlobData.data());
1393 base + tableOffset, base +
sizeof(uint32_t), base));
1403 MaybeNext = Cursor.advance();
1405 return MaybeNext.takeError();
1407 Next = MaybeNext.get();
1410 return llvm::Error::success();
1416 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1417 "Failed to enter field block");
1421 return MaybeNext.takeError();
1423 llvm::BitstreamEntry
Next = MaybeNext.get();
1424 while (
Next.Kind != llvm::BitstreamEntry::EndBlock) {
1425 if (
Next.Kind == llvm::BitstreamEntry::Error)
1426 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1427 "Malformed bitstream entry");
1429 if (
Next.Kind == llvm::BitstreamEntry::SubBlock) {
1432 if (Cursor.SkipBlock())
1433 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1434 "Failed to skip sub-block");
1436 MaybeNext = Cursor.advance();
1438 return MaybeNext.takeError();
1440 Next = MaybeNext.get();
1445 llvm::StringRef BlobData;
1447 Cursor.readRecord(
Next.ID, Scratch, &BlobData);
1449 return MaybeKind.takeError();
1451 unsigned Kind = MaybeKind.get();
1456 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1457 "Multiple field records found");
1459 uint32_t tableOffset;
1460 field_block::FieldDataLayout::readRecord(Scratch, tableOffset);
1461 auto base =
reinterpret_cast<const uint8_t *
>(BlobData.data());
1463 FieldTable.reset(SerializedFieldTable::Create(
1464 base + tableOffset, base +
sizeof(uint32_t), base));
1474 MaybeNext = Cursor.advance();
1476 return MaybeNext.takeError();
1478 Next = MaybeNext.get();
1481 return llvm::Error::success();
1487 return llvm::createStringError(
1488 llvm::inconvertibleErrorCode(),
1489 "Failed to enter Objective-C selector block");
1493 return MaybeNext.takeError();
1495 llvm::BitstreamEntry
Next = MaybeNext.get();
1496 while (
Next.Kind != llvm::BitstreamEntry::EndBlock) {
1497 if (
Next.Kind == llvm::BitstreamEntry::Error)
1498 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1499 "Malformed bitstream entry");
1501 if (
Next.Kind == llvm::BitstreamEntry::SubBlock) {
1504 if (Cursor.SkipBlock())
1505 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1506 "Failed to skip sub-block");
1508 MaybeNext = Cursor.advance();
1510 return MaybeNext.takeError();
1512 Next = MaybeNext.get();
1517 llvm::StringRef BlobData;
1519 Cursor.readRecord(
Next.ID, Scratch, &BlobData);
1521 return MaybeKind.takeError();
1523 unsigned Kind = MaybeKind.get();
1528 return llvm::createStringError(
1529 llvm::inconvertibleErrorCode(),
1530 "Multiple Objective-C selector records found");
1532 uint32_t tableOffset;
1533 objc_selector_block::ObjCSelectorDataLayout::readRecord(Scratch,
1535 auto base =
reinterpret_cast<const uint8_t *
>(BlobData.data());
1538 base + tableOffset, base +
sizeof(uint32_t), base));
1548 MaybeNext = Cursor.advance();
1550 return MaybeNext.takeError();
1552 Next = MaybeNext.get();
1555 return llvm::Error::success();
1561 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1562 "Failed to enter global variable block");
1566 return MaybeNext.takeError();
1568 llvm::BitstreamEntry
Next = MaybeNext.get();
1569 while (
Next.Kind != llvm::BitstreamEntry::EndBlock) {
1570 if (
Next.Kind == llvm::BitstreamEntry::Error)
1571 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1572 "Malformed bitstream entry");
1574 if (
Next.Kind == llvm::BitstreamEntry::SubBlock) {
1577 if (Cursor.SkipBlock())
1578 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1579 "Failed to skip sub-block");
1581 MaybeNext = Cursor.advance();
1583 return MaybeNext.takeError();
1585 Next = MaybeNext.get();
1590 llvm::StringRef BlobData;
1592 Cursor.readRecord(
Next.ID, Scratch, &BlobData);
1594 return MaybeKind.takeError();
1596 unsigned Kind = MaybeKind.get();
1601 return llvm::createStringError(
1602 llvm::inconvertibleErrorCode(),
1603 "Multiple global variable records found");
1605 uint32_t tableOffset;
1606 global_variable_block::GlobalVariableDataLayout::readRecord(Scratch,
1608 auto base =
reinterpret_cast<const uint8_t *
>(BlobData.data());
1611 base + tableOffset, base +
sizeof(uint32_t), base));
1621 MaybeNext = Cursor.advance();
1623 return MaybeNext.takeError();
1625 Next = MaybeNext.get();
1628 return llvm::Error::success();
1634 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1635 "Failed to enter global function block");
1639 return MaybeNext.takeError();
1641 llvm::BitstreamEntry
Next = MaybeNext.get();
1642 while (
Next.Kind != llvm::BitstreamEntry::EndBlock) {
1643 if (
Next.Kind == llvm::BitstreamEntry::Error)
1644 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1645 "Malformed bitstream entry");
1647 if (
Next.Kind == llvm::BitstreamEntry::SubBlock) {
1650 if (Cursor.SkipBlock())
1651 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1652 "Failed to skip sub-block");
1654 MaybeNext = Cursor.advance();
1656 return MaybeNext.takeError();
1658 Next = MaybeNext.get();
1663 llvm::StringRef BlobData;
1665 Cursor.readRecord(
Next.ID, Scratch, &BlobData);
1667 return MaybeKind.takeError();
1669 unsigned Kind = MaybeKind.get();
1674 return llvm::createStringError(
1675 llvm::inconvertibleErrorCode(),
1676 "Multiple global function records found");
1678 uint32_t tableOffset;
1679 global_function_block::GlobalFunctionDataLayout::readRecord(Scratch,
1681 auto base =
reinterpret_cast<const uint8_t *
>(BlobData.data());
1684 base + tableOffset, base +
sizeof(uint32_t), base));
1694 MaybeNext = Cursor.advance();
1696 return MaybeNext.takeError();
1698 Next = MaybeNext.get();
1701 return llvm::Error::success();
1707 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1708 "Failed to enter enum constant block");
1712 return MaybeNext.takeError();
1714 llvm::BitstreamEntry
Next = MaybeNext.get();
1715 while (
Next.Kind != llvm::BitstreamEntry::EndBlock) {
1716 if (
Next.Kind == llvm::BitstreamEntry::Error)
1717 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1718 "Malformed bitstream entry");
1720 if (
Next.Kind == llvm::BitstreamEntry::SubBlock) {
1723 if (Cursor.SkipBlock())
1724 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1725 "Failed to skip sub-block");
1727 MaybeNext = Cursor.advance();
1729 return MaybeNext.takeError();
1731 Next = MaybeNext.get();
1736 llvm::StringRef BlobData;
1738 Cursor.readRecord(
Next.ID, Scratch, &BlobData);
1740 return MaybeKind.takeError();
1742 unsigned Kind = MaybeKind.get();
1747 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1748 "Multiple enum constant records found");
1750 uint32_t tableOffset;
1751 enum_constant_block::EnumConstantDataLayout::readRecord(Scratch,
1753 auto base =
reinterpret_cast<const uint8_t *
>(BlobData.data());
1756 base + tableOffset, base +
sizeof(uint32_t), base));
1766 MaybeNext = Cursor.advance();
1768 return MaybeNext.takeError();
1770 Next = MaybeNext.get();
1773 return llvm::Error::success();
1779 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1780 "Failed to enter tag block");
1784 return MaybeNext.takeError();
1786 llvm::BitstreamEntry
Next = MaybeNext.get();
1787 while (
Next.Kind != llvm::BitstreamEntry::EndBlock) {
1788 if (
Next.Kind == llvm::BitstreamEntry::Error)
1789 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1790 "Malformed bitstream entry");
1792 if (
Next.Kind == llvm::BitstreamEntry::SubBlock) {
1795 if (Cursor.SkipBlock())
1796 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1797 "Failed to skip sub-block");
1799 MaybeNext = Cursor.advance();
1801 return MaybeNext.takeError();
1803 Next = MaybeNext.get();
1808 llvm::StringRef BlobData;
1810 Cursor.readRecord(
Next.ID, Scratch, &BlobData);
1812 return MaybeKind.takeError();
1814 unsigned Kind = MaybeKind.get();
1819 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1820 "Multiple tag records found");
1822 uint32_t tableOffset;
1823 tag_block::TagDataLayout::readRecord(Scratch, tableOffset);
1824 auto base =
reinterpret_cast<const uint8_t *
>(BlobData.data());
1826 TagTable.reset(SerializedTagTable::Create(base + tableOffset,
1827 base +
sizeof(uint32_t), base));
1837 MaybeNext = Cursor.advance();
1839 return MaybeNext.takeError();
1841 Next = MaybeNext.get();
1844 return llvm::Error::success();
1850 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1851 "Failed to enter typedef block");
1855 return MaybeNext.takeError();
1857 llvm::BitstreamEntry
Next = MaybeNext.get();
1858 while (
Next.Kind != llvm::BitstreamEntry::EndBlock) {
1859 if (
Next.Kind == llvm::BitstreamEntry::Error)
1860 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1861 "Malformed bitstream entry");
1863 if (
Next.Kind == llvm::BitstreamEntry::SubBlock) {
1866 if (Cursor.SkipBlock())
1867 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1868 "Failed to skip sub-block");
1870 MaybeNext = Cursor.advance();
1872 return MaybeNext.takeError();
1874 Next = MaybeNext.get();
1879 llvm::StringRef BlobData;
1881 Cursor.readRecord(
Next.ID, Scratch, &BlobData);
1883 return MaybeKind.takeError();
1885 unsigned Kind = MaybeKind.get();
1890 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1891 "Multiple typedef records found");
1893 uint32_t tableOffset;
1894 typedef_block::TypedefDataLayout::readRecord(Scratch, tableOffset);
1895 auto base =
reinterpret_cast<const uint8_t *
>(BlobData.data());
1898 base + tableOffset, base +
sizeof(uint32_t), base));
1908 MaybeNext = Cursor.advance();
1910 return MaybeNext.takeError();
1912 Next = MaybeNext.get();
1915 return llvm::Error::success();
1918APINotesReader::APINotesReader(llvm::MemoryBuffer *InputBuffer,
1919 llvm::VersionTuple SwiftVersion,
1930 if (Cursor.AtEndOfStream()) {
1931 Err = llvm::createStringError(
1932 llvm::inconvertibleErrorCode(),
1933 "Unexpected end of stream while reading signature");
1939 Err = maybeRead.takeError();
1942 if (maybeRead.get() !=
byte) {
1943 Err = llvm::createStringError(llvm::inconvertibleErrorCode(),
1944 "Invalid signature in API notes file");
1950 bool HasValidControlBlock =
false;
1951 llvm::SmallVector<uint64_t, 64> Scratch;
1952 while (!
Cursor.AtEndOfStream()) {
1953 llvm::Expected<llvm::BitstreamEntry> MaybeTopLevelEntry =
Cursor.advance();
1954 if (!MaybeTopLevelEntry) {
1955 Err = MaybeTopLevelEntry.takeError();
1958 llvm::BitstreamEntry TopLevelEntry = MaybeTopLevelEntry.get();
1960 if (TopLevelEntry.Kind != llvm::BitstreamEntry::SubBlock)
1963 switch (TopLevelEntry.ID) {
1964 case llvm::bitc::BLOCKINFO_BLOCK_ID:
1965 if (!
Cursor.ReadBlockInfoBlock()) {
1966 Err = llvm::createStringError(llvm::inconvertibleErrorCode(),
1967 "Failed to read block info");
1974 if (HasValidControlBlock) {
1975 Err = llvm::createStringError(llvm::inconvertibleErrorCode(),
1976 "Multiple control blocks found");
1979 if (llvm::Error BlockErr =
1980 Implementation->readControlBlock(Cursor, Scratch)) {
1981 Err = std::move(BlockErr);
1984 HasValidControlBlock =
true;
1988 if (!HasValidControlBlock) {
1989 Err = llvm::createStringError(llvm::inconvertibleErrorCode(),
1990 "Missing control block");
1993 if (llvm::Error BlockErr =
1994 Implementation->readIdentifierBlock(Cursor, Scratch)) {
1995 Err = std::move(BlockErr);
2001 if (!HasValidControlBlock) {
2002 Err = llvm::createStringError(llvm::inconvertibleErrorCode(),
2003 "Missing control block");
2006 if (llvm::Error BlockErr =
2007 Implementation->readContextBlock(Cursor, Scratch)) {
2008 Err = std::move(BlockErr);
2014 if (!HasValidControlBlock) {
2015 Err = llvm::createStringError(llvm::inconvertibleErrorCode(),
2016 "Missing control block");
2019 if (llvm::Error BlockErr =
2020 Implementation->readObjCPropertyBlock(Cursor, Scratch)) {
2021 Err = std::move(BlockErr);
2027 if (!HasValidControlBlock) {
2028 Err = llvm::createStringError(llvm::inconvertibleErrorCode(),
2029 "Missing control block");
2032 if (llvm::Error BlockErr =
2033 Implementation->readObjCMethodBlock(Cursor, Scratch)) {
2034 Err = std::move(BlockErr);
2040 if (!HasValidControlBlock) {
2041 Err = llvm::createStringError(llvm::inconvertibleErrorCode(),
2042 "Missing control block");
2045 if (llvm::Error BlockErr =
2046 Implementation->readCXXMethodBlock(Cursor, Scratch)) {
2047 Err = std::move(BlockErr);
2053 if (!HasValidControlBlock) {
2054 Err = llvm::createStringError(llvm::inconvertibleErrorCode(),
2055 "Missing control block");
2058 if (llvm::Error BlockErr =
2059 Implementation->readFieldBlock(Cursor, Scratch)) {
2060 Err = std::move(BlockErr);
2066 if (!HasValidControlBlock) {
2067 Err = llvm::createStringError(llvm::inconvertibleErrorCode(),
2068 "Missing control block");
2071 if (llvm::Error BlockErr =
2072 Implementation->readObjCSelectorBlock(Cursor, Scratch)) {
2073 Err = std::move(BlockErr);
2079 if (!HasValidControlBlock) {
2080 Err = llvm::createStringError(llvm::inconvertibleErrorCode(),
2081 "Missing control block");
2084 if (llvm::Error BlockErr =
2085 Implementation->readGlobalVariableBlock(Cursor, Scratch)) {
2086 Err = std::move(BlockErr);
2092 if (!HasValidControlBlock) {
2093 Err = llvm::createStringError(llvm::inconvertibleErrorCode(),
2094 "Missing control block");
2097 if (llvm::Error BlockErr =
2098 Implementation->readGlobalFunctionBlock(Cursor, Scratch)) {
2099 Err = std::move(BlockErr);
2105 if (!HasValidControlBlock) {
2106 Err = llvm::createStringError(llvm::inconvertibleErrorCode(),
2107 "Missing control block");
2110 if (llvm::Error BlockErr =
2111 Implementation->readEnumConstantBlock(Cursor, Scratch)) {
2112 Err = std::move(BlockErr);
2118 if (!HasValidControlBlock) {
2119 Err = llvm::createStringError(llvm::inconvertibleErrorCode(),
2120 "Missing control block");
2123 if (llvm::Error BlockErr =
2124 Implementation->readTagBlock(Cursor, Scratch)) {
2125 Err = std::move(BlockErr);
2131 if (!HasValidControlBlock) {
2132 Err = llvm::createStringError(llvm::inconvertibleErrorCode(),
2133 "Missing control block");
2136 if (llvm::Error BlockErr =
2137 Implementation->readTypedefBlock(Cursor, Scratch)) {
2138 Err = std::move(BlockErr);
2146 if (
Cursor.SkipBlock()) {
2147 Err = llvm::createStringError(llvm::inconvertibleErrorCode(),
2148 "Failed to skip unknown top-level block");
2155 if (!
Cursor.AtEndOfStream()) {
2156 Err = llvm::createStringError(llvm::inconvertibleErrorCode(),
2157 "Bitstream has unread data after all blocks");
2166 llvm::VersionTuple SwiftVersion) {
2167 llvm::Error Err = llvm::Error::success();
2168 std::unique_ptr<APINotesReader> Reader(
2169 new APINotesReader(InputBuffer.release(), SwiftVersion, Err));
2174 return std::move(Reader);
2177template <
typename T>
2179 llvm::VersionTuple Version,
2181 : Results(
std::move(R)) {
2183 assert(!Results.empty());
2184 assert(llvm::is_sorted(
2186 [](
const std::pair<llvm::VersionTuple, T> &left,
2187 const std::pair<llvm::VersionTuple, T> &right) ->
bool {
2192 assert((&left == &right || left.first != right.first) &&
2193 "two entries for the same version");
2194 return left.first < right.first;
2197 Selected = std::nullopt;
2198 for (
unsigned i = 0, n = Results.size(); i != n; ++i) {
2199 if (!Version.empty() && Results[i].first >= Version) {
2211 if (!Selected && Results[0].first.empty())
2216 -> std::optional<ContextID> {
2218 return std::nullopt;
2222 return std::nullopt;
2229 return std::nullopt;
2237 return std::nullopt;
2241 return std::nullopt;
2245 return std::nullopt;
2251 -> std::optional<ContextID> {
2253 return std::nullopt;
2257 return std::nullopt;
2264 return std::nullopt;
2272 return std::nullopt;
2276 return std::nullopt;
2280 return std::nullopt;
2289 return std::nullopt;
2293 return std::nullopt;
2296 std::make_tuple(CtxID.Value, *PropertyID, (
char)IsInstance));
2298 return std::nullopt;
2304 bool IsInstanceMethod)
2307 return std::nullopt;
2311 return std::nullopt;
2314 ObjCMethodTableInfo::internal_key_type{CtxID.Value, *SelID,
2317 return std::nullopt;
2325 return std::nullopt;
2329 return std::nullopt;
2334 return std::nullopt;
2341 return lookupCXXMethodImpl(CtxID, Name);
2347 return lookupCXXMethodImpl(CtxID, Name, Parameters);
2350auto APINotesReader::lookupCXXMethodImpl(
ContextID CtxID, llvm::StringRef Name)
2351 -> VersionedInfo<CXXMethodInfo> {
2352 if (!Implementation->CXXMethodTable)
2353 return std::nullopt;
2355 std::optional<FunctionTableKey> Key =
2356 Implementation->getFunctionKey(CtxID.Value, Name);
2358 return std::nullopt;
2360 auto Known = Implementation->CXXMethodTable->find(*Key);
2361 if (Known == Implementation->CXXMethodTable->end())
2362 return std::nullopt;
2364 return {Implementation->SwiftVersion, *Known};
2367auto APINotesReader::lookupCXXMethodImpl(
2368 ContextID CtxID, llvm::StringRef Name,
2370 -> VersionedInfo<CXXMethodInfo> {
2371 if (!Implementation->CXXMethodTable)
2372 return std::nullopt;
2374 std::optional<FunctionTableKey> Key =
2375 Implementation->getFunctionKey(CtxID.Value, Name, Parameters);
2377 return std::nullopt;
2379 auto Known = Implementation->CXXMethodTable->find(*Key);
2380 if (Known == Implementation->CXXMethodTable->end())
2381 return std::nullopt;
2383 return {Implementation->SwiftVersion, *Known};
2387 std::optional<Context> Ctx)
2390 return std::nullopt;
2394 return std::nullopt;
2400 return std::nullopt;
2406 std::optional<Context> Ctx)
2408 return lookupGlobalFunctionImpl(Name, Ctx);
2414 return lookupGlobalFunctionImpl(Name, Parameters, Ctx);
2417auto APINotesReader::lookupGlobalFunctionImpl(llvm::StringRef Name,
2418 std::optional<Context> Ctx)
2419 -> VersionedInfo<GlobalFunctionInfo> {
2420 if (!Implementation->GlobalFunctionTable)
2421 return std::nullopt;
2423 std::optional<FunctionTableKey> Key =
2424 Implementation->getFunctionKey(Ctx, Name);
2426 return std::nullopt;
2428 auto Known = Implementation->GlobalFunctionTable->find(*Key);
2429 if (Known == Implementation->GlobalFunctionTable->end())
2430 return std::nullopt;
2432 return {Implementation->SwiftVersion, *Known};
2435auto APINotesReader::lookupGlobalFunctionImpl(
2437 std::optional<Context> Ctx) -> VersionedInfo<GlobalFunctionInfo> {
2438 if (!Implementation->GlobalFunctionTable)
2439 return std::nullopt;
2441 std::optional<FunctionTableKey> Key =
2442 Implementation->getFunctionKey(Ctx, Name, Parameters);
2444 return std::nullopt;
2446 auto Known = Implementation->GlobalFunctionTable->find(*Key);
2447 if (Known == Implementation->GlobalFunctionTable->end())
2448 return std::nullopt;
2450 return {Implementation->SwiftVersion, *Known};
2456 return std::nullopt;
2460 return std::nullopt;
2464 return std::nullopt;
2470 std::optional<Context> ParentCtx)
2471 -> std::optional<ContextID> {
2473 return std::nullopt;
2477 return std::nullopt;
2482 return std::nullopt;
2490 return std::nullopt;
2494 return std::nullopt;
2500 return std::nullopt;
2506 std::optional<Context> Ctx)
2509 return std::nullopt;
2513 return std::nullopt;
2519 return std::nullopt;
2525 llvm::StringRef Name, std::optional<ContextID> ParentNamespaceID)
2526 -> std::optional<ContextID> {
2528 return std::nullopt;
2532 return std::nullopt;
2534 uint32_t RawParentNamespaceID =
2535 ParentNamespaceID ? ParentNamespaceID->Value : -1;
2539 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
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::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
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.
VersionedInfo< GlobalVariableInfo > lookupGlobalVariable(llvm::StringRef Name, std::optional< Context > Ctx=std::nullopt)
Look for information regarding the given global variable.
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.
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.
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
A stored Objective-C or C++ context, represented by the ID of its parent context, the kind of this co...
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