mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Serialization: Round-trip primary associated type list
This commit is contained in:
@@ -991,70 +991,84 @@ void ModuleFile::readAssociatedTypes(
|
||||
}
|
||||
}
|
||||
|
||||
void ModuleFile::readPrimaryAssociatedTypes(
|
||||
SmallVectorImpl<AssociatedTypeDecl *> &assocTypes,
|
||||
llvm::BitstreamCursor &Cursor) {
|
||||
using namespace decls_block;
|
||||
|
||||
BCOffsetRAII lastRecordOffset(Cursor);
|
||||
SmallVector<uint64_t, 8> scratch;
|
||||
StringRef blobData;
|
||||
|
||||
while (true) {
|
||||
lastRecordOffset.reset();
|
||||
|
||||
llvm::BitstreamEntry entry =
|
||||
fatalIfUnexpected(Cursor.advance(AF_DontPopBlockAtEnd));
|
||||
if (entry.Kind != llvm::BitstreamEntry::Record)
|
||||
break;
|
||||
|
||||
scratch.clear();
|
||||
unsigned recordID = fatalIfUnexpected(
|
||||
Cursor.readRecord(entry.ID, scratch, &blobData));
|
||||
if (recordID != PRIMARY_ASSOCIATED_TYPE)
|
||||
break;
|
||||
|
||||
DeclID declID;
|
||||
PrimaryAssociatedTypeLayout::readRecord(scratch, declID);
|
||||
|
||||
assocTypes.push_back(cast<AssociatedTypeDecl>(getDecl(declID)));
|
||||
}
|
||||
}
|
||||
|
||||
static llvm::Error skipRecords(llvm::BitstreamCursor &Cursor, unsigned kind) {
|
||||
using namespace decls_block;
|
||||
|
||||
BCOffsetRAII lastRecordOffset(Cursor);
|
||||
|
||||
while (true) {
|
||||
Expected<llvm::BitstreamEntry> maybeEntry =
|
||||
Cursor.advance(AF_DontPopBlockAtEnd);
|
||||
if (!maybeEntry)
|
||||
return maybeEntry.takeError();
|
||||
llvm::BitstreamEntry entry = maybeEntry.get();
|
||||
if (entry.Kind != llvm::BitstreamEntry::Record)
|
||||
break;
|
||||
|
||||
Expected<unsigned> maybeRecordID = Cursor.skipRecord(entry.ID);
|
||||
if (!maybeRecordID)
|
||||
return maybeRecordID.takeError();
|
||||
if (maybeRecordID.get() != kind)
|
||||
return llvm::Error::success();
|
||||
|
||||
lastRecordOffset.reset();
|
||||
}
|
||||
|
||||
return llvm::Error::success();
|
||||
}
|
||||
|
||||
/// Advances past any records that might be part of a protocol requirement
|
||||
/// signature, which consists of generic requirements together with protocol
|
||||
/// typealias records.
|
||||
static llvm::Error skipRequirementSignature(llvm::BitstreamCursor &Cursor) {
|
||||
using namespace decls_block;
|
||||
|
||||
BCOffsetRAII lastRecordOffset(Cursor);
|
||||
|
||||
while (true) {
|
||||
Expected<llvm::BitstreamEntry> maybeEntry =
|
||||
Cursor.advance(AF_DontPopBlockAtEnd);
|
||||
if (!maybeEntry)
|
||||
return maybeEntry.takeError();
|
||||
llvm::BitstreamEntry entry = maybeEntry.get();
|
||||
if (entry.Kind != llvm::BitstreamEntry::Record)
|
||||
break;
|
||||
|
||||
Expected<unsigned> maybeRecordID = Cursor.skipRecord(entry.ID);
|
||||
if (!maybeRecordID)
|
||||
return maybeRecordID.takeError();
|
||||
switch (maybeRecordID.get()) {
|
||||
case REQUIREMENT_SIGNATURE:
|
||||
break;
|
||||
|
||||
default:
|
||||
// This record is not a generic requirement.
|
||||
return llvm::Error::success();
|
||||
}
|
||||
|
||||
lastRecordOffset.reset();
|
||||
}
|
||||
return llvm::Error::success();
|
||||
return skipRecords(Cursor, REQUIREMENT_SIGNATURE);
|
||||
}
|
||||
|
||||
/// Advances past any lazy associated type member records.
|
||||
static llvm::Error skipAssociatedTypeMembers(llvm::BitstreamCursor &Cursor) {
|
||||
using namespace decls_block;
|
||||
|
||||
BCOffsetRAII lastRecordOffset(Cursor);
|
||||
return skipRecords(Cursor, ASSOCIATED_TYPE);
|
||||
}
|
||||
|
||||
while (true) {
|
||||
Expected<llvm::BitstreamEntry> maybeEntry =
|
||||
Cursor.advance(AF_DontPopBlockAtEnd);
|
||||
if (!maybeEntry)
|
||||
return maybeEntry.takeError();
|
||||
llvm::BitstreamEntry entry = maybeEntry.get();
|
||||
if (entry.Kind != llvm::BitstreamEntry::Record)
|
||||
break;
|
||||
/// Advances past any lazy primary associated type member records.
|
||||
static llvm::Error skipPrimaryAssociatedTypeMembers(
|
||||
llvm::BitstreamCursor &Cursor) {
|
||||
using namespace decls_block;
|
||||
|
||||
Expected<unsigned> maybeRecordID = Cursor.skipRecord(entry.ID);
|
||||
if (!maybeRecordID)
|
||||
return maybeRecordID.takeError();
|
||||
switch (maybeRecordID.get()) {
|
||||
case ASSOCIATED_TYPE:
|
||||
break;
|
||||
|
||||
default:
|
||||
// This record is not an associated type.
|
||||
return llvm::Error::success();
|
||||
}
|
||||
|
||||
lastRecordOffset.reset();
|
||||
}
|
||||
return llvm::Error::success();
|
||||
return skipRecords(Cursor, PRIMARY_ASSOCIATED_TYPE);
|
||||
}
|
||||
|
||||
GenericSignature ModuleFile::getGenericSignature(
|
||||
@@ -3749,16 +3763,21 @@ public:
|
||||
proto->setImplicit();
|
||||
proto->setIsObjC(isObjC);
|
||||
|
||||
proto->setLazyRequirementSignature(&MF,
|
||||
MF.DeclTypeCursor.GetCurrentBitNo());
|
||||
proto->setLazyRequirementSignature(
|
||||
&MF, MF.DeclTypeCursor.GetCurrentBitNo());
|
||||
if (llvm::Error Err = skipRequirementSignature(MF.DeclTypeCursor))
|
||||
MF.fatal(std::move(Err));
|
||||
|
||||
proto->setLazyAssociatedTypeMembers(&MF,
|
||||
MF.DeclTypeCursor.GetCurrentBitNo());
|
||||
proto->setLazyAssociatedTypeMembers(
|
||||
&MF, MF.DeclTypeCursor.GetCurrentBitNo());
|
||||
if (llvm::Error Err = skipAssociatedTypeMembers(MF.DeclTypeCursor))
|
||||
MF.fatal(std::move(Err));
|
||||
|
||||
proto->setLazyPrimaryAssociatedTypeMembers(
|
||||
&MF, MF.DeclTypeCursor.GetCurrentBitNo());
|
||||
if (llvm::Error Err = skipPrimaryAssociatedTypeMembers(MF.DeclTypeCursor))
|
||||
MF.fatal(std::move(Err));
|
||||
|
||||
proto->setMemberLoader(&MF, MF.DeclTypeCursor.GetCurrentBitNo());
|
||||
|
||||
return proto;
|
||||
@@ -6987,6 +7006,14 @@ void ModuleFile::loadAssociatedTypes(const ProtocolDecl *decl,
|
||||
readAssociatedTypes(assocTypes, DeclTypeCursor);
|
||||
}
|
||||
|
||||
void ModuleFile::loadPrimaryAssociatedTypes(const ProtocolDecl *decl,
|
||||
uint64_t contextData,
|
||||
SmallVectorImpl<AssociatedTypeDecl *> &assocTypes) {
|
||||
BCOffsetRAII restoreOffset(DeclTypeCursor);
|
||||
fatalIfNotSuccess(DeclTypeCursor.JumpToBit(contextData));
|
||||
readPrimaryAssociatedTypes(assocTypes, DeclTypeCursor);
|
||||
}
|
||||
|
||||
static Optional<ForeignErrorConvention::Kind>
|
||||
decodeRawStableForeignErrorConventionKind(uint8_t kind) {
|
||||
switch (kind) {
|
||||
|
||||
Reference in New Issue
Block a user