mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[Serialization] Properly skip invalid destructors when allowing errors
7856f2d83d only partially skipped writing
out destructors when they were invalid, ie. it skipped writing the decl
itself but not the records common to all decls. This would cause any
records on the destructor to be applied on the next serialized decl.
Make sure to skip serializing anything to do with the destructor when
it's invalid and does not have a class context.
This commit is contained in:
@@ -3957,9 +3957,6 @@ public:
|
||||
using namespace decls_block;
|
||||
verifyAttrSerializable(dtor);
|
||||
|
||||
if (S.allowCompilerErrors() && dtor->isInvalid())
|
||||
return;
|
||||
|
||||
auto contextID = S.addDeclContextRef(dtor->getDeclContext());
|
||||
|
||||
unsigned abbrCode = S.DeclTypeAbbrCodes[DestructorLayout::Code];
|
||||
@@ -4001,12 +3998,34 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
/// When allowing modules with errors there may be cases where there's little
|
||||
/// point in serializing a declaration and doing so would create a maintenance
|
||||
/// burden on the deserialization side. Returns \c true if the given declaration
|
||||
/// should be skipped and \c false otherwise.
|
||||
static bool canSkipWhenInvalid(const Decl *D) {
|
||||
// There's no point writing out the deinit when its context is not a class
|
||||
// as nothing would be able to reference it
|
||||
if (auto *deinit = dyn_cast<DestructorDecl>(D)) {
|
||||
if (!isa<ClassDecl>(D->getDeclContext()))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Serializer::writeASTBlockEntity(const Decl *D) {
|
||||
using namespace decls_block;
|
||||
|
||||
PrettyStackTraceDecl trace("serializing", D);
|
||||
assert(DeclsToSerialize.hasRef(D));
|
||||
|
||||
if (D->isInvalid()) {
|
||||
assert(allowCompilerErrors() &&
|
||||
"cannot create a module with an invalid decl");
|
||||
|
||||
if (canSkipWhenInvalid(D))
|
||||
return;
|
||||
}
|
||||
|
||||
BitOffset initialOffset = Out.GetCurrentBitNo();
|
||||
SWIFT_DEFER {
|
||||
// This is important enough to leave on in Release builds.
|
||||
@@ -4016,8 +4035,6 @@ void Serializer::writeASTBlockEntity(const Decl *D) {
|
||||
}
|
||||
};
|
||||
|
||||
assert((allowCompilerErrors() || !D->isInvalid()) &&
|
||||
"cannot create a module with an invalid decl");
|
||||
if (isDeclXRef(D)) {
|
||||
writeCrossReference(D);
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user