[Serialization] Fix bad tagging of deserialized decls that can result in failed member lookups

The issue was introduced in ec95e68ab9 which changed the behavior of `ModuleFile::getDeclChecked()` slightly.

rdar://49336277
This commit is contained in:
Argyrios Kyrtzidis
2019-03-28 11:45:30 -07:00
parent 526678cc2b
commit 1b2cb9c723
5 changed files with 54 additions and 20 deletions

View File

@@ -3751,35 +3751,35 @@ public:
Expected<Decl *>
ModuleFile::getDeclChecked(DeclID DID) {
// Tag every deserialized ValueDecl coming out of getDeclChecked with its ID.
if (DID == 0)
return nullptr;
assert(DID <= Decls.size() && "invalid decl ID");
auto &declOrOffset = Decls[DID-1];
if (declOrOffset.isComplete())
return declOrOffset;
if (!declOrOffset.isComplete()) {
++NumDeclsLoaded;
BCOffsetRAII restoreOffset(DeclTypeCursor);
DeclTypeCursor.JumpToBit(declOrOffset);
++NumDeclsLoaded;
BCOffsetRAII restoreOffset(DeclTypeCursor);
DeclTypeCursor.JumpToBit(declOrOffset);
ModuleFile::DeserializingEntityRAII deserializingEntity(*this);
Expected<Decl *> deserialized =
DeclDeserializer(*this, declOrOffset).getDeclCheckedImpl();
if (!deserialized)
return deserialized;
}
SWIFT_DEFER {
if (!declOrOffset.isComplete())
return;
if (auto *IDC = dyn_cast_or_null<IterableDeclContext>(declOrOffset.get())) {
// Only set the DeclID on the returned Decl if it's one that was loaded
// and _wasn't_ one that had its DeclID set elsewhere (a followed XREF).
if (IDC->wasDeserialized() &&
static_cast<uint32_t>(IDC->getDeclID()) == 0) {
IDC->setDeclID(DID);
}
// Tag every deserialized ValueDecl coming out of getDeclChecked with its ID.
assert(declOrOffset.isComplete());
if (auto *IDC = dyn_cast_or_null<IterableDeclContext>(declOrOffset.get())) {
// Only set the DeclID on the returned Decl if it's one that was loaded
// and _wasn't_ one that had its DeclID set elsewhere (a followed XREF).
if (IDC->wasDeserialized() &&
static_cast<uint32_t>(IDC->getDeclID()) == 0) {
IDC->setDeclID(DID);
}
};
ModuleFile::DeserializingEntityRAII deserializingEntity(*this);
return DeclDeserializer(*this, declOrOffset).getDeclCheckedImpl();
}
return declOrOffset;
}
llvm::Error DeclDeserializer::deserializeDeclAttributes() {