[Serialization] Handle XREFs to private types (#14352)

We can encounter these when the compiler modifies an inlinable
function to break apart a struct and the struct uses a private
type for one of its fields. It's questionable whether we /should/
handle this, but meanwhile this /is/ a non-intrusive fix that
preserves the performance of non-resilient libraries.

(That is, it appears this worked in Swift 4.0, though perhaps
not all of the same optimizations kicked in.)

https://bugs.swift.org/browse/SR-6874
This commit is contained in:
Jordan Rose
2018-02-07 16:42:16 -08:00
committed by GitHub
parent 573ebc5920
commit af67204b51
7 changed files with 156 additions and 17 deletions

View File

@@ -1868,8 +1868,16 @@ void Serializer::writeCrossReference(const DeclContext *DC, uint32_t pathLen) {
auto generic = cast<GenericTypeDecl>(DC);
abbrCode = DeclTypeAbbrCodes[XRefTypePathPieceLayout::Code];
Identifier discriminator;
if (generic->isOutermostPrivateOrFilePrivateScope()) {
auto *containingFile = cast<FileUnit>(generic->getModuleScopeContext());
discriminator = containingFile->getDiscriminatorForPrivateValue(generic);
}
XRefTypePathPieceLayout::emitRecord(Out, ScratchRecord, abbrCode,
addDeclBaseNameRef(generic->getName()),
addDeclBaseNameRef(discriminator),
false);
break;
}
@@ -2019,8 +2027,17 @@ void Serializer::writeCrossReference(const Decl *D) {
bool isProtocolExt = D->getDeclContext()->getAsProtocolExtensionContext();
if (auto type = dyn_cast<TypeDecl>(D)) {
abbrCode = DeclTypeAbbrCodes[XRefTypePathPieceLayout::Code];
Identifier discriminator;
if (type->isOutermostPrivateOrFilePrivateScope()) {
auto *containingFile =
cast<FileUnit>(type->getDeclContext()->getModuleScopeContext());
discriminator = containingFile->getDiscriminatorForPrivateValue(type);
}
XRefTypePathPieceLayout::emitRecord(Out, ScratchRecord, abbrCode,
addDeclBaseNameRef(type->getName()),
addDeclBaseNameRef(discriminator),
isProtocolExt);
return;
}