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) {
30 uint8_t NumVersions = (*
Data++) & 0x03;
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);
50template <
typename Derived,
typename KeyType,
typename UnversionedDataType>
51class VersionedTableInfo {
53 using internal_key_type = KeyType;
54 using external_key_type = KeyType;
56 llvm::SmallVector<std::pair<llvm::VersionTuple, UnversionedDataType>, 1>;
57 using hash_value_type =
size_t;
58 using offset_type = unsigned;
60 internal_key_type GetInternalKey(external_key_type Key) {
return Key; }
62 external_key_type GetExternalKey(internal_key_type Key) {
return Key; }
64 static bool EqualKey(internal_key_type LHS, internal_key_type RHS) {
68 static std::pair<unsigned, unsigned> ReadKeyDataLength(
const uint8_t *&
Data) {
70 endian::readNext<uint16_t, llvm::endianness::little>(
Data);
72 endian::readNext<uint16_t, llvm::endianness::little>(
Data);
73 return {KeyLength, DataLength};
76 static data_type ReadData(internal_key_type Key,
const uint8_t *
Data,
78 unsigned NumElements =
79 endian::readNext<uint16_t, llvm::endianness::little>(
Data);
81 Result.reserve(NumElements);
82 for (
unsigned i = 0; i != NumElements; ++i) {
83 auto version = ReadVersionTuple(
Data);
84 const auto *DataBefore =
Data;
86 auto UnversionedData = Derived::readUnversioned(Key,
Data);
87 assert(
Data != DataBefore &&
88 "Unversioned data reader didn't move pointer");
89 Result.push_back({version, UnversionedData});
97 uint8_t EncodedBits = *
Data++;
98 Info.Unavailable = (EncodedBits >> 1) & 0x01;
99 Info.UnavailableInSwift = EncodedBits & 0x01;
100 if ((EncodedBits >> 2) & 0x01)
101 Info.setSwiftPrivate(
static_cast<bool>((EncodedBits >> 3) & 0x01));
102 if ((EncodedBits >> 4) & 0x01)
107 endian::readNext<uint16_t, llvm::endianness::little>(
Data);
108 Info.UnavailableMsg =
109 std::string(
reinterpret_cast<const char *
>(
Data),
110 reinterpret_cast<const char *
>(
Data) + MsgLength);
113 unsigned SwiftNameLength =
114 endian::readNext<uint16_t, llvm::endianness::little>(
Data);
116 std::string(
reinterpret_cast<const char *
>(
Data),
117 reinterpret_cast<const char *
>(
Data) + SwiftNameLength);
118 Data += SwiftNameLength;
123 ReadCommonEntityInfo(
Data, Info);
125 unsigned SwiftBridgeLength =
126 endian::readNext<uint16_t, llvm::endianness::little>(
Data);
127 if (SwiftBridgeLength > 0) {
128 Info.setSwiftBridge(std::string(
reinterpret_cast<const char *
>(
Data),
129 SwiftBridgeLength - 1));
130 Data += SwiftBridgeLength - 1;
133 unsigned ErrorDomainLength =
134 endian::readNext<uint16_t, llvm::endianness::little>(
Data);
135 if (ErrorDomainLength > 0) {
136 Info.setNSErrorDomain(std::optional<std::string>(std::string(
137 reinterpret_cast<const char *
>(
Data), ErrorDomainLength - 1)));
138 Data += ErrorDomainLength - 1;
141 if (
unsigned ConformanceLength =
142 endian::readNext<uint16_t, llvm::endianness::little>(
Data)) {
143 Info.setSwiftConformance(std::string(
reinterpret_cast<const char *
>(
Data),
144 ConformanceLength - 1));
145 Data += ConformanceLength - 1;
150class IdentifierTableInfo {
152 using internal_key_type = llvm::StringRef;
153 using external_key_type = llvm::StringRef;
156 using offset_type = unsigned;
158 internal_key_type GetInternalKey(external_key_type Key) {
return Key; }
160 external_key_type GetExternalKey(internal_key_type Key) {
return Key; }
162 hash_value_type
ComputeHash(internal_key_type Key) {
163 return llvm::djbHash(Key);
166 static bool EqualKey(internal_key_type LHS, internal_key_type RHS) {
170 static std::pair<unsigned, unsigned> ReadKeyDataLength(
const uint8_t *&
Data) {
172 endian::readNext<uint16_t, llvm::endianness::little>(
Data);
173 unsigned DataLength =
174 endian::readNext<uint16_t, llvm::endianness::little>(
Data);
175 return {KeyLength, DataLength};
178 static internal_key_type ReadKey(
const uint8_t *
Data,
unsigned Length) {
179 return llvm::StringRef(
reinterpret_cast<const char *
>(
Data), Length);
182 static data_type ReadData(internal_key_type key,
const uint8_t *
Data,
184 return endian::readNext<uint32_t, llvm::endianness::little>(
Data);
190class ContextIDTableInfo {
192 using internal_key_type = ContextTableKey;
193 using external_key_type = internal_key_type;
194 using data_type = unsigned;
195 using hash_value_type =
size_t;
196 using offset_type = unsigned;
198 internal_key_type GetInternalKey(external_key_type Key) {
return Key; }
200 external_key_type GetExternalKey(internal_key_type Key) {
return Key; }
202 hash_value_type
ComputeHash(internal_key_type Key) {
203 return static_cast<size_t>(Key.hashValue());
206 static bool EqualKey(internal_key_type LHS, internal_key_type RHS) {
210 static std::pair<unsigned, unsigned> ReadKeyDataLength(
const uint8_t *&
Data) {
212 endian::readNext<uint16_t, llvm::endianness::little>(
Data);
213 unsigned DataLength =
214 endian::readNext<uint16_t, llvm::endianness::little>(
Data);
215 return {KeyLength, DataLength};
218 static internal_key_type ReadKey(
const uint8_t *
Data,
unsigned Length) {
220 endian::readNext<uint32_t, llvm::endianness::little>(
Data);
222 endian::readNext<uint8_t, llvm::endianness::little>(
Data);
223 auto NameID = endian::readNext<uint32_t, llvm::endianness::little>(
Data);
227 static data_type ReadData(internal_key_type Key,
const uint8_t *
Data,
229 return endian::readNext<uint32_t, llvm::endianness::little>(
Data);
234class ContextInfoTableInfo
235 :
public VersionedTableInfo<ContextInfoTableInfo, unsigned, ContextInfo> {
237 static internal_key_type ReadKey(
const uint8_t *
Data,
unsigned Length) {
238 return endian::readNext<uint32_t, llvm::endianness::little>(
Data);
241 hash_value_type
ComputeHash(internal_key_type Key) {
245 static ContextInfo readUnversioned(internal_key_type Key,
246 const uint8_t *&
Data) {
248 ReadCommonTypeInfo(
Data, Info);
249 uint8_t Payload = *
Data++;
252 Info.setHasDesignatedInits(
true);
253 Payload = Payload >> 1;
256 Info.setDefaultNullability(
static_cast<NullabilityKind>(Payload & 0x03));
259 if (Payload & (1 << 1))
260 Info.setSwiftObjCMembers(Payload & 1);
263 if (Payload & (1 << 1))
264 Info.setSwiftImportAsNonGeneric(Payload & 1);
272 ReadCommonEntityInfo(
Data, Info);
278 auto TypeLen = endian::readNext<uint16_t, llvm::endianness::little>(
Data);
279 Info.setType(std::string(
Data,
Data + TypeLen));
284class ObjCPropertyTableInfo
285 :
public VersionedTableInfo<ObjCPropertyTableInfo,
286 std::tuple<uint32_t, uint32_t, uint8_t>,
289 static internal_key_type ReadKey(
const uint8_t *
Data,
unsigned Length) {
290 auto ClassID = endian::readNext<uint32_t, llvm::endianness::little>(
Data);
291 auto NameID = endian::readNext<uint32_t, llvm::endianness::little>(
Data);
292 char IsInstance = endian::readNext<uint8_t, llvm::endianness::little>(
Data);
293 return {ClassID, NameID, IsInstance};
296 hash_value_type
ComputeHash(internal_key_type Key) {
300 static ObjCPropertyInfo readUnversioned(internal_key_type Key,
301 const uint8_t *&
Data) {
302 ObjCPropertyInfo Info;
303 ReadVariableInfo(
Data, Info);
304 uint8_t Flags = *
Data++;
305 if (Flags & (1 << 0))
306 Info.setSwiftImportAsAccessors(Flags & (1 << 1));
313 :
public VersionedTableInfo<FieldTableInfo, SingleDeclTableKey, FieldInfo> {
315 static internal_key_type ReadKey(
const uint8_t *
Data,
unsigned Length) {
316 auto CtxID = endian::readNext<uint32_t, llvm::endianness::little>(
Data);
317 auto NameID = endian::readNext<uint32_t, llvm::endianness::little>(
Data);
318 return {CtxID, NameID};
321 hash_value_type
ComputeHash(internal_key_type Key) {
322 return static_cast<size_t>(Key.hashValue());
325 static FieldInfo readUnversioned(internal_key_type Key,
326 const uint8_t *&
Data) {
328 ReadVariableInfo(
Data, Info);
335 uint8_t Payload = endian::readNext<uint8_t, llvm::endianness::little>(
Data);
337 if (Payload & 0x01) {
338 uint8_t
Level = (Payload >> 1) & 0x7;
339 Info.setLevelAudited(
Level);
343 if (Payload & 0x01) {
344 uint8_t
Kind = (Payload >> 1) & 0x7;
350 uint16_t ExternalBoundsLen =
351 endian::readNext<uint16_t, llvm::endianness::little>(
Data);
352 Info.ExternalBounds = std::string(
Data,
Data + ExternalBoundsLen);
353 Data += ExternalBoundsLen;
358 ReadVariableInfo(
Data, Info);
360 uint8_t Payload = endian::readNext<uint8_t, llvm::endianness::little>(
Data);
361 if (
auto RawConvention = Payload & 0x7) {
363 Info.setRetainCountConvention(Convention);
367 Info.setLifetimebound(Payload & 0x02);
370 Info.setNoEscape(Payload & 0x02);
373 ReadBoundsSafetyInfo(
Data, Info.BoundsSafety.emplace());
378 ReadCommonEntityInfo(
Data, Info);
380 uint8_t Payload = endian::readNext<uint8_t, llvm::endianness::little>(
Data);
382 Info.UnsafeBufferUsage = 1;
384 if (
auto RawConvention = Payload & 0x7) {
386 Info.setRetainCountConvention(Convention);
389 Info.NullabilityAudited = Payload & 0x1;
391 assert(Payload == 0 &&
"Bad API notes");
393 Info.NumAdjustedNullable =
394 endian::readNext<uint8_t, llvm::endianness::little>(
Data);
395 Info.NullabilityPayload =
396 endian::readNext<uint64_t, llvm::endianness::little>(
Data);
399 endian::readNext<uint16_t, llvm::endianness::little>(
Data);
400 while (NumParams > 0) {
402 ReadParamInfo(
Data, pi);
403 Info.Params.push_back(pi);
407 unsigned ResultTypeLen =
408 endian::readNext<uint16_t, llvm::endianness::little>(
Data);
409 Info.ResultType = std::string(
Data,
Data + ResultTypeLen);
410 Data += ResultTypeLen;
412 unsigned SwiftReturnOwnershipLength =
413 endian::readNext<uint16_t, llvm::endianness::little>(
Data);
414 Info.SwiftReturnOwnership = std::string(
reinterpret_cast<const char *
>(
Data),
415 reinterpret_cast<const char *
>(
Data) +
416 SwiftReturnOwnershipLength);
417 Data += SwiftReturnOwnershipLength;
421class ObjCMethodTableInfo
422 :
public VersionedTableInfo<ObjCMethodTableInfo,
423 std::tuple<uint32_t, uint32_t, uint8_t>,
426 static internal_key_type ReadKey(
const uint8_t *
Data,
unsigned Length) {
427 auto ClassID = endian::readNext<uint32_t, llvm::endianness::little>(
Data);
429 endian::readNext<uint32_t, llvm::endianness::little>(
Data);
430 auto IsInstance = endian::readNext<uint8_t, llvm::endianness::little>(
Data);
434 hash_value_type
ComputeHash(internal_key_type Key) {
438 static ObjCMethodInfo readUnversioned(internal_key_type Key,
439 const uint8_t *&
Data) {
441 uint8_t Payload = *
Data++;
442 bool HasSelf = Payload & 0x01;
444 Info.RequiredInit = Payload & 0x01;
446 Info.DesignatedInit = Payload & 0x01;
448 assert(Payload == 0 &&
"Unable to fully decode 'Payload'.");
450 ReadFunctionInfo(
Data, Info);
452 Info.Self = ParamInfo{};
453 ReadParamInfo(
Data, *Info.Self);
460class ObjCSelectorTableInfo {
462 using internal_key_type = StoredObjCSelector;
463 using external_key_type = internal_key_type;
465 using hash_value_type = unsigned;
466 using offset_type = unsigned;
468 internal_key_type GetInternalKey(external_key_type Key) {
return Key; }
470 external_key_type GetExternalKey(internal_key_type Key) {
return Key; }
472 hash_value_type
ComputeHash(internal_key_type Key) {
473 return llvm::DenseMapInfo<StoredObjCSelector>::getHashValue(Key);
476 static bool EqualKey(internal_key_type LHS, internal_key_type RHS) {
477 return llvm::DenseMapInfo<StoredObjCSelector>::isEqual(LHS, RHS);
480 static std::pair<unsigned, unsigned> ReadKeyDataLength(
const uint8_t *&
Data) {
482 endian::readNext<uint16_t, llvm::endianness::little>(
Data);
483 unsigned DataLength =
484 endian::readNext<uint16_t, llvm::endianness::little>(
Data);
485 return {KeyLength, DataLength};
488 static internal_key_type ReadKey(
const uint8_t *
Data,
unsigned Length) {
489 internal_key_type Key;
490 Key.NumArgs = endian::readNext<uint16_t, llvm::endianness::little>(
Data);
491 unsigned NumIdents = (Length -
sizeof(uint16_t)) /
sizeof(uint32_t);
492 for (
unsigned i = 0; i != NumIdents; ++i) {
493 Key.Identifiers.push_back(
494 endian::readNext<uint32_t, llvm::endianness::little>(
Data));
499 static data_type ReadData(internal_key_type Key,
const uint8_t *
Data,
501 return endian::readNext<uint32_t, llvm::endianness::little>(
Data);
506class GlobalVariableTableInfo
507 :
public VersionedTableInfo<GlobalVariableTableInfo, SingleDeclTableKey,
508 GlobalVariableInfo> {
510 static internal_key_type ReadKey(
const uint8_t *
Data,
unsigned Length) {
511 auto CtxID = endian::readNext<uint32_t, llvm::endianness::little>(
Data);
512 auto NameID = endian::readNext<uint32_t, llvm::endianness::little>(
Data);
513 return {CtxID, NameID};
516 hash_value_type
ComputeHash(internal_key_type Key) {
517 return static_cast<size_t>(Key.hashValue());
520 static GlobalVariableInfo readUnversioned(internal_key_type Key,
521 const uint8_t *&
Data) {
522 GlobalVariableInfo Info;
523 ReadVariableInfo(
Data, Info);
529class GlobalFunctionTableInfo
530 :
public VersionedTableInfo<GlobalFunctionTableInfo, SingleDeclTableKey,
531 GlobalFunctionInfo> {
533 static internal_key_type ReadKey(
const uint8_t *
Data,
unsigned Length) {
534 auto CtxID = endian::readNext<uint32_t, llvm::endianness::little>(
Data);
535 auto NameID = endian::readNext<uint32_t, llvm::endianness::little>(
Data);
536 return {CtxID, NameID};
539 hash_value_type
ComputeHash(internal_key_type Key) {
540 return static_cast<size_t>(Key.hashValue());
543 static GlobalFunctionInfo readUnversioned(internal_key_type Key,
544 const uint8_t *&
Data) {
545 GlobalFunctionInfo Info;
546 ReadFunctionInfo(
Data, Info);
552class CXXMethodTableInfo
553 :
public VersionedTableInfo<CXXMethodTableInfo, SingleDeclTableKey,
556 static internal_key_type ReadKey(
const uint8_t *
Data,
unsigned Length) {
557 auto CtxID = endian::readNext<uint32_t, llvm::endianness::little>(
Data);
558 auto NameID = endian::readNext<uint32_t, llvm::endianness::little>(
Data);
559 return {CtxID, NameID};
562 hash_value_type
ComputeHash(internal_key_type Key) {
563 return static_cast<size_t>(Key.hashValue());
566 static CXXMethodInfo readUnversioned(internal_key_type Key,
567 const uint8_t *&
Data) {
570 uint8_t Payload = *
Data++;
571 bool HasThis = Payload & 0x01;
573 assert(Payload == 0 &&
"Unable to fully decode 'Payload'.");
575 ReadFunctionInfo(
Data, Info);
577 Info.This = ParamInfo{};
578 ReadParamInfo(
Data, *Info.This);
585class EnumConstantTableInfo
586 :
public VersionedTableInfo<EnumConstantTableInfo, uint32_t,
589 static internal_key_type ReadKey(
const uint8_t *
Data,
unsigned Length) {
590 auto NameID = endian::readNext<uint32_t, llvm::endianness::little>(
Data);
594 hash_value_type
ComputeHash(internal_key_type Key) {
598 static EnumConstantInfo readUnversioned(internal_key_type Key,
599 const uint8_t *&
Data) {
600 EnumConstantInfo Info;
601 ReadCommonEntityInfo(
Data, Info);
608 :
public VersionedTableInfo<TagTableInfo, SingleDeclTableKey, TagInfo> {
610 static internal_key_type ReadKey(
const uint8_t *
Data,
unsigned Length) {
611 auto CtxID = endian::readNext<uint32_t, llvm::endianness::little>(
Data);
613 endian::readNext<IdentifierID, llvm::endianness::little>(
Data);
614 return {CtxID, NameID};
617 hash_value_type
ComputeHash(internal_key_type Key) {
618 return static_cast<size_t>(Key.hashValue());
621 static TagInfo readUnversioned(internal_key_type Key,
const uint8_t *&
Data) {
624 uint8_t Payload = *
Data++;
626 Info.setFlagEnum(Payload & 2);
629 Info.EnumExtensibility =
633 endian::readNext<uint8_t, llvm::endianness::little>(
Data);
637 endian::readNext<uint8_t, llvm::endianness::little>(
Data);
639 Info.setSwiftEscapable(std::optional(Escapable ==
kSwiftConforms));
641 unsigned ImportAsLength =
642 endian::readNext<uint16_t, llvm::endianness::little>(
Data);
643 if (ImportAsLength > 0) {
645 std::string(
reinterpret_cast<const char *
>(
Data), ImportAsLength - 1);
646 Data += ImportAsLength - 1;
648 unsigned RetainOpLength =
649 endian::readNext<uint16_t, llvm::endianness::little>(
Data);
650 if (RetainOpLength > 0) {
652 std::string(
reinterpret_cast<const char *
>(
Data), RetainOpLength - 1);
653 Data += RetainOpLength - 1;
655 unsigned ReleaseOpLength =
656 endian::readNext<uint16_t, llvm::endianness::little>(
Data);
657 if (ReleaseOpLength > 0) {
658 Info.SwiftReleaseOp = std::string(
reinterpret_cast<const char *
>(
Data),
659 ReleaseOpLength - 1);
660 Data += ReleaseOpLength - 1;
662 unsigned DefaultOwnershipLength =
663 endian::readNext<uint16_t, llvm::endianness::little>(
Data);
664 if (DefaultOwnershipLength > 0) {
665 Info.SwiftDefaultOwnership = std::string(
666 reinterpret_cast<const char *
>(
Data), DefaultOwnershipLength - 1);
667 Data += DefaultOwnershipLength - 1;
669 unsigned DestroyOpLength =
670 endian::readNext<uint16_t, llvm::endianness::little>(
Data);
671 if (DestroyOpLength > 0) {
672 Info.SwiftDestroyOp = std::string(
reinterpret_cast<const char *
>(
Data),
673 DestroyOpLength - 1);
674 Data += DestroyOpLength - 1;
677 ReadCommonTypeInfo(
Data, Info);
683class TypedefTableInfo
684 :
public VersionedTableInfo<TypedefTableInfo, SingleDeclTableKey,
687 static internal_key_type ReadKey(
const uint8_t *
Data,
unsigned Length) {
688 auto CtxID = endian::readNext<uint32_t, llvm::endianness::little>(
Data);
690 endian::readNext<IdentifierID, llvm::endianness::little>(
Data);
691 return {CtxID, nameID};
694 hash_value_type
ComputeHash(internal_key_type Key) {
695 return static_cast<size_t>(Key.hashValue());
698 static TypedefInfo readUnversioned(internal_key_type Key,
699 const uint8_t *&
Data) {
702 uint8_t Payload = *
Data++;
706 ReadCommonTypeInfo(
Data, Info);
728 llvm::OnDiskIterableChainedHashTable<IdentifierTableInfo>;
734 llvm::OnDiskIterableChainedHashTable<ContextIDTableInfo>;
740 llvm::OnDiskIterableChainedHashTable<ContextInfoTableInfo>;
746 llvm::OnDiskIterableChainedHashTable<ObjCPropertyTableInfo>;
752 llvm::OnDiskIterableChainedHashTable<FieldTableInfo>;
758 llvm::OnDiskIterableChainedHashTable<ObjCMethodTableInfo>;
764 llvm::OnDiskIterableChainedHashTable<CXXMethodTableInfo>;
770 llvm::OnDiskIterableChainedHashTable<ObjCSelectorTableInfo>;
776 llvm::OnDiskIterableChainedHashTable<GlobalVariableTableInfo>;
782 llvm::OnDiskIterableChainedHashTable<GlobalFunctionTableInfo>;
788 llvm::OnDiskIterableChainedHashTable<EnumConstantTableInfo>;
799 llvm::OnDiskIterableChainedHashTable<TypedefTableInfo>;
806 std::optional<IdentifierID>
getIdentifier(llvm::StringRef Str);
840std::optional<IdentifierID>
855std::optional<SelectorID>
863 for (
auto Ident :
Selector.Identifiers) {
881 return llvm::createStringError(llvm::inconvertibleErrorCode(),
882 "Failed to enter control block");
884 bool SawMetadata =
false;
888 return MaybeNext.takeError();
890 llvm::BitstreamEntry
Next = MaybeNext.get();
892 while (
Next.Kind != llvm::BitstreamEntry::EndBlock) {
893 if (
Next.Kind == llvm::BitstreamEntry::Error)
894 return llvm::createStringError(llvm::inconvertibleErrorCode(),
895 "Malformed bitstream entry");
897 if (
Next.Kind == llvm::BitstreamEntry::SubBlock) {
900 if (Cursor.SkipBlock())
901 return llvm::createStringError(llvm::inconvertibleErrorCode(),
902 "Failed to skip sub-block");
904 MaybeNext = Cursor.advance();
906 return MaybeNext.takeError();
908 Next = MaybeNext.get();
913 llvm::StringRef BlobData;
915 Cursor.readRecord(
Next.ID, Scratch, &BlobData);
917 return MaybeKind.takeError();
919 unsigned Kind = MaybeKind.get();
925 return llvm::createStringError(llvm::inconvertibleErrorCode(),
926 "Multiple metadata records found");
929 return llvm::createStringError(llvm::inconvertibleErrorCode(),
930 "Version mismatch in API Notes");
952 MaybeNext = Cursor.advance();
954 return MaybeNext.takeError();
956 Next = MaybeNext.get();
960 return llvm::createStringError(llvm::inconvertibleErrorCode(),
961 "Missing metadata record");
963 return llvm::Error::success();
969 return llvm::createStringError(llvm::inconvertibleErrorCode(),
970 "Failed to enter identifier block");
974 return MaybeNext.takeError();
976 llvm::BitstreamEntry
Next = MaybeNext.get();
978 while (
Next.Kind != llvm::BitstreamEntry::EndBlock) {
979 if (
Next.Kind == llvm::BitstreamEntry::Error)
980 return llvm::createStringError(llvm::inconvertibleErrorCode(),
981 "Malformed bitstream entry");
983 if (
Next.Kind == llvm::BitstreamEntry::SubBlock) {
986 if (Cursor.SkipBlock())
987 return llvm::createStringError(llvm::inconvertibleErrorCode(),
988 "Failed to skip sub-block");
990 MaybeNext = Cursor.advance();
992 return MaybeNext.takeError();
994 Next = MaybeNext.get();
999 llvm::StringRef BlobData;
1001 Cursor.readRecord(
Next.ID, Scratch, &BlobData);
1003 return MaybeKind.takeError();
1005 unsigned Kind = MaybeKind.get();
1010 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1011 "Multiple identifier records found");
1013 uint32_t tableOffset;
1014 identifier_block::IdentifierDataLayout::readRecord(Scratch, tableOffset);
1015 auto base =
reinterpret_cast<const uint8_t *
>(BlobData.data());
1018 base + tableOffset, base +
sizeof(uint32_t), base));
1028 MaybeNext = Cursor.advance();
1030 return MaybeNext.takeError();
1032 Next = MaybeNext.get();
1035 return llvm::Error::success();
1041 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1042 "Failed to enter Objective-C context block");
1046 return MaybeNext.takeError();
1048 llvm::BitstreamEntry
Next = MaybeNext.get();
1050 while (
Next.Kind != llvm::BitstreamEntry::EndBlock) {
1051 if (
Next.Kind == llvm::BitstreamEntry::Error)
1052 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1053 "Malformed bitstream entry");
1055 if (
Next.Kind == llvm::BitstreamEntry::SubBlock) {
1058 if (Cursor.SkipBlock())
1059 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1060 "Failed to skip sub-block");
1062 MaybeNext = Cursor.advance();
1064 return MaybeNext.takeError();
1066 Next = MaybeNext.get();
1071 llvm::StringRef BlobData;
1073 Cursor.readRecord(
Next.ID, Scratch, &BlobData);
1075 return MaybeKind.takeError();
1077 unsigned Kind = MaybeKind.get();
1082 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1083 "Multiple context ID records found");
1085 uint32_t tableOffset;
1086 context_block::ContextIDLayout::readRecord(Scratch, tableOffset);
1087 auto base =
reinterpret_cast<const uint8_t *
>(BlobData.data());
1090 base + tableOffset, base +
sizeof(uint32_t), base));
1097 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1098 "Multiple context info records found");
1100 uint32_t tableOffset;
1101 context_block::ContextInfoLayout::readRecord(Scratch, tableOffset);
1102 auto base =
reinterpret_cast<const uint8_t *
>(BlobData.data());
1105 base + tableOffset, base +
sizeof(uint32_t), base));
1115 MaybeNext = Cursor.advance();
1117 return MaybeNext.takeError();
1119 Next = MaybeNext.get();
1122 return llvm::Error::success();
1128 return llvm::createStringError(
1129 llvm::inconvertibleErrorCode(),
1130 "Failed to enter Objective-C property block");
1134 return MaybeNext.takeError();
1136 llvm::BitstreamEntry
Next = MaybeNext.get();
1138 while (
Next.Kind != llvm::BitstreamEntry::EndBlock) {
1139 if (
Next.Kind == llvm::BitstreamEntry::Error)
1140 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1141 "Malformed bitstream entry");
1143 if (
Next.Kind == llvm::BitstreamEntry::SubBlock) {
1146 if (Cursor.SkipBlock())
1147 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1148 "Failed to skip sub-block");
1150 MaybeNext = Cursor.advance();
1152 return MaybeNext.takeError();
1154 Next = MaybeNext.get();
1159 llvm::StringRef BlobData;
1161 Cursor.readRecord(
Next.ID, Scratch, &BlobData);
1163 return MaybeKind.takeError();
1165 unsigned Kind = MaybeKind.get();
1170 return llvm::createStringError(
1171 llvm::inconvertibleErrorCode(),
1172 "Multiple Objective-C property records found");
1174 uint32_t tableOffset;
1175 objc_property_block::ObjCPropertyDataLayout::readRecord(Scratch,
1177 auto base =
reinterpret_cast<const uint8_t *
>(BlobData.data());
1180 base + tableOffset, base +
sizeof(uint32_t), base));
1190 MaybeNext = Cursor.advance();
1192 return MaybeNext.takeError();
1194 Next = MaybeNext.get();
1197 return llvm::Error::success();
1203 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1204 "Failed to enter Objective-C method block");
1208 return MaybeNext.takeError();
1210 llvm::BitstreamEntry
Next = MaybeNext.get();
1211 while (
Next.Kind != llvm::BitstreamEntry::EndBlock) {
1212 if (
Next.Kind == llvm::BitstreamEntry::Error)
1213 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1214 "Malformed bitstream entry");
1216 if (
Next.Kind == llvm::BitstreamEntry::SubBlock) {
1219 if (Cursor.SkipBlock())
1220 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1221 "Failed to skip sub-block");
1223 MaybeNext = Cursor.advance();
1225 return MaybeNext.takeError();
1227 Next = MaybeNext.get();
1232 llvm::StringRef BlobData;
1234 Cursor.readRecord(
Next.ID, Scratch, &BlobData);
1236 return MaybeKind.takeError();
1238 unsigned Kind = MaybeKind.get();
1243 return llvm::createStringError(
1244 llvm::inconvertibleErrorCode(),
1245 "Multiple Objective-C method records found");
1247 uint32_t tableOffset;
1248 objc_method_block::ObjCMethodDataLayout::readRecord(Scratch, tableOffset);
1249 auto base =
reinterpret_cast<const uint8_t *
>(BlobData.data());
1252 base + tableOffset, base +
sizeof(uint32_t), base));
1262 MaybeNext = Cursor.advance();
1264 return MaybeNext.takeError();
1266 Next = MaybeNext.get();
1269 return llvm::Error::success();
1275 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1276 "Failed to enter C++ method block");
1280 return MaybeNext.takeError();
1282 llvm::BitstreamEntry
Next = MaybeNext.get();
1283 while (
Next.Kind != llvm::BitstreamEntry::EndBlock) {
1284 if (
Next.Kind == llvm::BitstreamEntry::Error)
1285 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1286 "Malformed bitstream entry");
1288 if (
Next.Kind == llvm::BitstreamEntry::SubBlock) {
1291 if (Cursor.SkipBlock())
1292 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1293 "Failed to skip sub-block");
1295 MaybeNext = Cursor.advance();
1297 return MaybeNext.takeError();
1299 Next = MaybeNext.get();
1304 llvm::StringRef BlobData;
1306 Cursor.readRecord(
Next.ID, Scratch, &BlobData);
1308 return MaybeKind.takeError();
1310 unsigned Kind = MaybeKind.get();
1315 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1316 "Multiple C++ method records found");
1318 uint32_t tableOffset;
1319 cxx_method_block::CXXMethodDataLayout::readRecord(Scratch, tableOffset);
1320 auto base =
reinterpret_cast<const uint8_t *
>(BlobData.data());
1323 base + tableOffset, base +
sizeof(uint32_t), base));
1333 MaybeNext = Cursor.advance();
1335 return MaybeNext.takeError();
1337 Next = MaybeNext.get();
1340 return llvm::Error::success();
1346 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1347 "Failed to enter field block");
1351 return MaybeNext.takeError();
1353 llvm::BitstreamEntry
Next = MaybeNext.get();
1354 while (
Next.Kind != llvm::BitstreamEntry::EndBlock) {
1355 if (
Next.Kind == llvm::BitstreamEntry::Error)
1356 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1357 "Malformed bitstream entry");
1359 if (
Next.Kind == llvm::BitstreamEntry::SubBlock) {
1362 if (Cursor.SkipBlock())
1363 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1364 "Failed to skip sub-block");
1366 MaybeNext = Cursor.advance();
1368 return MaybeNext.takeError();
1370 Next = MaybeNext.get();
1375 llvm::StringRef BlobData;
1377 Cursor.readRecord(
Next.ID, Scratch, &BlobData);
1379 return MaybeKind.takeError();
1381 unsigned Kind = MaybeKind.get();
1386 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1387 "Multiple field records found");
1389 uint32_t tableOffset;
1390 field_block::FieldDataLayout::readRecord(Scratch, tableOffset);
1391 auto base =
reinterpret_cast<const uint8_t *
>(BlobData.data());
1393 FieldTable.reset(SerializedFieldTable::Create(
1394 base + tableOffset, base +
sizeof(uint32_t), base));
1404 MaybeNext = Cursor.advance();
1406 return MaybeNext.takeError();
1408 Next = MaybeNext.get();
1411 return llvm::Error::success();
1417 return llvm::createStringError(
1418 llvm::inconvertibleErrorCode(),
1419 "Failed to enter Objective-C selector block");
1423 return MaybeNext.takeError();
1425 llvm::BitstreamEntry
Next = MaybeNext.get();
1426 while (
Next.Kind != llvm::BitstreamEntry::EndBlock) {
1427 if (
Next.Kind == llvm::BitstreamEntry::Error)
1428 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1429 "Malformed bitstream entry");
1431 if (
Next.Kind == llvm::BitstreamEntry::SubBlock) {
1434 if (Cursor.SkipBlock())
1435 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1436 "Failed to skip sub-block");
1438 MaybeNext = Cursor.advance();
1440 return MaybeNext.takeError();
1442 Next = MaybeNext.get();
1447 llvm::StringRef BlobData;
1449 Cursor.readRecord(
Next.ID, Scratch, &BlobData);
1451 return MaybeKind.takeError();
1453 unsigned Kind = MaybeKind.get();
1458 return llvm::createStringError(
1459 llvm::inconvertibleErrorCode(),
1460 "Multiple Objective-C selector records found");
1462 uint32_t tableOffset;
1463 objc_selector_block::ObjCSelectorDataLayout::readRecord(Scratch,
1465 auto base =
reinterpret_cast<const uint8_t *
>(BlobData.data());
1468 base + tableOffset, base +
sizeof(uint32_t), base));
1478 MaybeNext = Cursor.advance();
1480 return MaybeNext.takeError();
1482 Next = MaybeNext.get();
1485 return llvm::Error::success();
1491 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1492 "Failed to enter global variable block");
1496 return MaybeNext.takeError();
1498 llvm::BitstreamEntry
Next = MaybeNext.get();
1499 while (
Next.Kind != llvm::BitstreamEntry::EndBlock) {
1500 if (
Next.Kind == llvm::BitstreamEntry::Error)
1501 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1502 "Malformed bitstream entry");
1504 if (
Next.Kind == llvm::BitstreamEntry::SubBlock) {
1507 if (Cursor.SkipBlock())
1508 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1509 "Failed to skip sub-block");
1511 MaybeNext = Cursor.advance();
1513 return MaybeNext.takeError();
1515 Next = MaybeNext.get();
1520 llvm::StringRef BlobData;
1522 Cursor.readRecord(
Next.ID, Scratch, &BlobData);
1524 return MaybeKind.takeError();
1526 unsigned Kind = MaybeKind.get();
1531 return llvm::createStringError(
1532 llvm::inconvertibleErrorCode(),
1533 "Multiple global variable records found");
1535 uint32_t tableOffset;
1536 global_variable_block::GlobalVariableDataLayout::readRecord(Scratch,
1538 auto base =
reinterpret_cast<const uint8_t *
>(BlobData.data());
1541 base + tableOffset, base +
sizeof(uint32_t), base));
1551 MaybeNext = Cursor.advance();
1553 return MaybeNext.takeError();
1555 Next = MaybeNext.get();
1558 return llvm::Error::success();
1564 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1565 "Failed to enter global function block");
1569 return MaybeNext.takeError();
1571 llvm::BitstreamEntry
Next = MaybeNext.get();
1572 while (
Next.Kind != llvm::BitstreamEntry::EndBlock) {
1573 if (
Next.Kind == llvm::BitstreamEntry::Error)
1574 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1575 "Malformed bitstream entry");
1577 if (
Next.Kind == llvm::BitstreamEntry::SubBlock) {
1580 if (Cursor.SkipBlock())
1581 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1582 "Failed to skip sub-block");
1584 MaybeNext = Cursor.advance();
1586 return MaybeNext.takeError();
1588 Next = MaybeNext.get();
1593 llvm::StringRef BlobData;
1595 Cursor.readRecord(
Next.ID, Scratch, &BlobData);
1597 return MaybeKind.takeError();
1599 unsigned Kind = MaybeKind.get();
1604 return llvm::createStringError(
1605 llvm::inconvertibleErrorCode(),
1606 "Multiple global function records found");
1608 uint32_t tableOffset;
1609 global_function_block::GlobalFunctionDataLayout::readRecord(Scratch,
1611 auto base =
reinterpret_cast<const uint8_t *
>(BlobData.data());
1614 base + tableOffset, base +
sizeof(uint32_t), base));
1624 MaybeNext = Cursor.advance();
1626 return MaybeNext.takeError();
1628 Next = MaybeNext.get();
1631 return llvm::Error::success();
1637 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1638 "Failed to enter enum constant block");
1642 return MaybeNext.takeError();
1644 llvm::BitstreamEntry
Next = MaybeNext.get();
1645 while (
Next.Kind != llvm::BitstreamEntry::EndBlock) {
1646 if (
Next.Kind == llvm::BitstreamEntry::Error)
1647 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1648 "Malformed bitstream entry");
1650 if (
Next.Kind == llvm::BitstreamEntry::SubBlock) {
1653 if (Cursor.SkipBlock())
1654 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1655 "Failed to skip sub-block");
1657 MaybeNext = Cursor.advance();
1659 return MaybeNext.takeError();
1661 Next = MaybeNext.get();
1666 llvm::StringRef BlobData;
1668 Cursor.readRecord(
Next.ID, Scratch, &BlobData);
1670 return MaybeKind.takeError();
1672 unsigned Kind = MaybeKind.get();
1677 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1678 "Multiple enum constant records found");
1680 uint32_t tableOffset;
1681 enum_constant_block::EnumConstantDataLayout::readRecord(Scratch,
1683 auto base =
reinterpret_cast<const uint8_t *
>(BlobData.data());
1686 base + tableOffset, base +
sizeof(uint32_t), base));
1696 MaybeNext = Cursor.advance();
1698 return MaybeNext.takeError();
1700 Next = MaybeNext.get();
1703 return llvm::Error::success();
1709 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1710 "Failed to enter tag block");
1714 return MaybeNext.takeError();
1716 llvm::BitstreamEntry
Next = MaybeNext.get();
1717 while (
Next.Kind != llvm::BitstreamEntry::EndBlock) {
1718 if (
Next.Kind == llvm::BitstreamEntry::Error)
1719 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1720 "Malformed bitstream entry");
1722 if (
Next.Kind == llvm::BitstreamEntry::SubBlock) {
1725 if (Cursor.SkipBlock())
1726 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1727 "Failed to skip sub-block");
1729 MaybeNext = Cursor.advance();
1731 return MaybeNext.takeError();
1733 Next = MaybeNext.get();
1738 llvm::StringRef BlobData;
1740 Cursor.readRecord(
Next.ID, Scratch, &BlobData);
1742 return MaybeKind.takeError();
1744 unsigned Kind = MaybeKind.get();
1749 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1750 "Multiple tag records found");
1752 uint32_t tableOffset;
1753 tag_block::TagDataLayout::readRecord(Scratch, tableOffset);
1754 auto base =
reinterpret_cast<const uint8_t *
>(BlobData.data());
1756 TagTable.reset(SerializedTagTable::Create(base + tableOffset,
1757 base +
sizeof(uint32_t), base));
1767 MaybeNext = Cursor.advance();
1769 return MaybeNext.takeError();
1771 Next = MaybeNext.get();
1774 return llvm::Error::success();
1780 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1781 "Failed to enter typedef block");
1785 return MaybeNext.takeError();
1787 llvm::BitstreamEntry
Next = MaybeNext.get();
1788 while (
Next.Kind != llvm::BitstreamEntry::EndBlock) {
1789 if (
Next.Kind == llvm::BitstreamEntry::Error)
1790 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1791 "Malformed bitstream entry");
1793 if (
Next.Kind == llvm::BitstreamEntry::SubBlock) {
1796 if (Cursor.SkipBlock())
1797 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1798 "Failed to skip sub-block");
1800 MaybeNext = Cursor.advance();
1802 return MaybeNext.takeError();
1804 Next = MaybeNext.get();
1809 llvm::StringRef BlobData;
1811 Cursor.readRecord(
Next.ID, Scratch, &BlobData);
1813 return MaybeKind.takeError();
1815 unsigned Kind = MaybeKind.get();
1820 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1821 "Multiple typedef records found");
1823 uint32_t tableOffset;
1824 typedef_block::TypedefDataLayout::readRecord(Scratch, tableOffset);
1825 auto base =
reinterpret_cast<const uint8_t *
>(BlobData.data());
1828 base + tableOffset, base +
sizeof(uint32_t), base));
1838 MaybeNext = Cursor.advance();
1840 return MaybeNext.takeError();
1842 Next = MaybeNext.get();
1845 return llvm::Error::success();
1848APINotesReader::APINotesReader(llvm::MemoryBuffer *InputBuffer,
1849 llvm::VersionTuple SwiftVersion,
1860 if (Cursor.AtEndOfStream()) {
1861 Err = llvm::createStringError(
1862 llvm::inconvertibleErrorCode(),
1863 "Unexpected end of stream while reading signature");
1869 Err = maybeRead.takeError();
1872 if (maybeRead.get() !=
byte) {
1873 Err = llvm::createStringError(llvm::inconvertibleErrorCode(),
1874 "Invalid signature in API notes file");
1880 bool HasValidControlBlock =
false;
1881 llvm::SmallVector<uint64_t, 64> Scratch;
1882 while (!
Cursor.AtEndOfStream()) {
1883 llvm::Expected<llvm::BitstreamEntry> MaybeTopLevelEntry =
Cursor.advance();
1884 if (!MaybeTopLevelEntry) {
1885 Err = MaybeTopLevelEntry.takeError();
1888 llvm::BitstreamEntry TopLevelEntry = MaybeTopLevelEntry.get();
1890 if (TopLevelEntry.Kind != llvm::BitstreamEntry::SubBlock)
1893 switch (TopLevelEntry.ID) {
1894 case llvm::bitc::BLOCKINFO_BLOCK_ID:
1895 if (!
Cursor.ReadBlockInfoBlock()) {
1896 Err = llvm::createStringError(llvm::inconvertibleErrorCode(),
1897 "Failed to read block info");
1904 if (HasValidControlBlock) {
1905 Err = llvm::createStringError(llvm::inconvertibleErrorCode(),
1906 "Multiple control blocks found");
1909 if (llvm::Error BlockErr =
1910 Implementation->readControlBlock(Cursor, Scratch)) {
1911 Err = std::move(BlockErr);
1914 HasValidControlBlock =
true;
1918 if (!HasValidControlBlock) {
1919 Err = llvm::createStringError(llvm::inconvertibleErrorCode(),
1920 "Missing control block");
1923 if (llvm::Error BlockErr =
1924 Implementation->readIdentifierBlock(Cursor, Scratch)) {
1925 Err = std::move(BlockErr);
1931 if (!HasValidControlBlock) {
1932 Err = llvm::createStringError(llvm::inconvertibleErrorCode(),
1933 "Missing control block");
1936 if (llvm::Error BlockErr =
1937 Implementation->readContextBlock(Cursor, Scratch)) {
1938 Err = std::move(BlockErr);
1944 if (!HasValidControlBlock) {
1945 Err = llvm::createStringError(llvm::inconvertibleErrorCode(),
1946 "Missing control block");
1949 if (llvm::Error BlockErr =
1950 Implementation->readObjCPropertyBlock(Cursor, Scratch)) {
1951 Err = std::move(BlockErr);
1957 if (!HasValidControlBlock) {
1958 Err = llvm::createStringError(llvm::inconvertibleErrorCode(),
1959 "Missing control block");
1962 if (llvm::Error BlockErr =
1963 Implementation->readObjCMethodBlock(Cursor, Scratch)) {
1964 Err = std::move(BlockErr);
1970 if (!HasValidControlBlock) {
1971 Err = llvm::createStringError(llvm::inconvertibleErrorCode(),
1972 "Missing control block");
1975 if (llvm::Error BlockErr =
1976 Implementation->readCXXMethodBlock(Cursor, Scratch)) {
1977 Err = std::move(BlockErr);
1983 if (!HasValidControlBlock) {
1984 Err = llvm::createStringError(llvm::inconvertibleErrorCode(),
1985 "Missing control block");
1988 if (llvm::Error BlockErr =
1989 Implementation->readFieldBlock(Cursor, Scratch)) {
1990 Err = std::move(BlockErr);
1996 if (!HasValidControlBlock) {
1997 Err = llvm::createStringError(llvm::inconvertibleErrorCode(),
1998 "Missing control block");
2001 if (llvm::Error BlockErr =
2002 Implementation->readObjCSelectorBlock(Cursor, Scratch)) {
2003 Err = std::move(BlockErr);
2009 if (!HasValidControlBlock) {
2010 Err = llvm::createStringError(llvm::inconvertibleErrorCode(),
2011 "Missing control block");
2014 if (llvm::Error BlockErr =
2015 Implementation->readGlobalVariableBlock(Cursor, Scratch)) {
2016 Err = std::move(BlockErr);
2022 if (!HasValidControlBlock) {
2023 Err = llvm::createStringError(llvm::inconvertibleErrorCode(),
2024 "Missing control block");
2027 if (llvm::Error BlockErr =
2028 Implementation->readGlobalFunctionBlock(Cursor, Scratch)) {
2029 Err = std::move(BlockErr);
2035 if (!HasValidControlBlock) {
2036 Err = llvm::createStringError(llvm::inconvertibleErrorCode(),
2037 "Missing control block");
2040 if (llvm::Error BlockErr =
2041 Implementation->readEnumConstantBlock(Cursor, Scratch)) {
2042 Err = std::move(BlockErr);
2048 if (!HasValidControlBlock) {
2049 Err = llvm::createStringError(llvm::inconvertibleErrorCode(),
2050 "Missing control block");
2053 if (llvm::Error BlockErr =
2054 Implementation->readTagBlock(Cursor, Scratch)) {
2055 Err = std::move(BlockErr);
2061 if (!HasValidControlBlock) {
2062 Err = llvm::createStringError(llvm::inconvertibleErrorCode(),
2063 "Missing control block");
2066 if (llvm::Error BlockErr =
2067 Implementation->readTypedefBlock(Cursor, Scratch)) {
2068 Err = std::move(BlockErr);
2076 if (
Cursor.SkipBlock()) {
2077 Err = llvm::createStringError(llvm::inconvertibleErrorCode(),
2078 "Failed to skip unknown top-level block");
2085 if (!
Cursor.AtEndOfStream()) {
2086 Err = llvm::createStringError(llvm::inconvertibleErrorCode(),
2087 "Bitstream has unread data after all blocks");
2096 llvm::VersionTuple SwiftVersion) {
2097 llvm::Error Err = llvm::Error::success();
2098 std::unique_ptr<APINotesReader> Reader(
2099 new APINotesReader(InputBuffer.release(), SwiftVersion, Err));
2104 return std::move(Reader);
2107template <
typename T>
2109 llvm::VersionTuple Version,
2111 : Results(
std::move(R)) {
2113 assert(!Results.empty());
2114 assert(llvm::is_sorted(
2116 [](
const std::pair<llvm::VersionTuple, T> &left,
2117 const std::pair<llvm::VersionTuple, T> &right) ->
bool {
2122 assert((&left == &right || left.first != right.first) &&
2123 "two entries for the same version");
2124 return left.first < right.first;
2127 Selected = std::nullopt;
2128 for (
unsigned i = 0, n = Results.size(); i != n; ++i) {
2129 if (!Version.empty() && Results[i].first >= Version) {
2141 if (!Selected && Results[0].first.empty())
2146 -> std::optional<ContextID> {
2148 return std::nullopt;
2152 return std::nullopt;
2159 return std::nullopt;
2167 return std::nullopt;
2171 return std::nullopt;
2175 return std::nullopt;
2181 -> std::optional<ContextID> {
2183 return std::nullopt;
2187 return std::nullopt;
2194 return std::nullopt;
2202 return std::nullopt;
2206 return std::nullopt;
2210 return std::nullopt;
2219 return std::nullopt;
2223 return std::nullopt;
2226 std::make_tuple(CtxID.Value, *PropertyID, (
char)IsInstance));
2228 return std::nullopt;
2234 bool IsInstanceMethod)
2237 return std::nullopt;
2241 return std::nullopt;
2244 ObjCMethodTableInfo::internal_key_type{CtxID.Value, *SelID,
2247 return std::nullopt;
2255 return std::nullopt;
2259 return std::nullopt;
2264 return std::nullopt;
2272 return std::nullopt;
2276 return std::nullopt;
2281 return std::nullopt;
2287 std::optional<Context> Ctx)
2290 return std::nullopt;
2294 return std::nullopt;
2300 return std::nullopt;
2306 std::optional<Context> Ctx)
2309 return std::nullopt;
2313 return std::nullopt;
2319 return std::nullopt;
2327 return std::nullopt;
2331 return std::nullopt;
2335 return std::nullopt;
2341 std::optional<Context> ParentCtx)
2342 -> std::optional<ContextID> {
2344 return std::nullopt;
2348 return std::nullopt;
2353 return std::nullopt;
2361 return std::nullopt;
2365 return std::nullopt;
2371 return std::nullopt;
2377 std::optional<Context> Ctx)
2380 return std::nullopt;
2384 return std::nullopt;
2390 return std::nullopt;
2396 llvm::StringRef Name, std::optional<ContextID> ParentNamespaceID)
2397 -> std::optional<ContextID> {
2399 return std::nullopt;
2403 return std::nullopt;
2405 uint32_t RawParentNamespaceID =
2406 ParentNamespaceID ? ParentNamespaceID->Value : -1;
2410 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.
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.
RetainCountConventionKind
llvm::PointerEmbeddedInt< unsigned, 31 > IdentifierID
llvm::PointerEmbeddedInt< unsigned, 31 > SelectorID
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
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)
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