@@ -2029,8 +2029,10 @@ void Serializer::writePatternBindingInitializer(PatternBindingDecl *binding,
2029
2029
StringRef initStr;
2030
2030
SmallString<128 > scratch;
2031
2031
auto varDecl = binding->getAnchoringVarDecl (bindingIndex);
2032
+ assert ((varDecl || allowCompilerErrors ()) &&
2033
+ " Serializing PDB without anchoring VarDecl" );
2032
2034
if (binding->hasInitStringRepresentation (bindingIndex) &&
2033
- varDecl->isInitExposedToClients ()) {
2035
+ varDecl && varDecl ->isInitExposedToClients ()) {
2034
2036
initStr = binding->getInitStringRepresentation (bindingIndex, scratch);
2035
2037
}
2036
2038
@@ -3929,9 +3931,6 @@ class Serializer::DeclSerializer : public DeclVisitor<DeclSerializer> {
3929
3931
using namespace decls_block ;
3930
3932
verifyAttrSerializable (dtor);
3931
3933
3932
- if (S.allowCompilerErrors () && dtor->isInvalid ())
3933
- return ;
3934
-
3935
3934
auto contextID = S.addDeclContextRef (dtor->getDeclContext ());
3936
3935
3937
3936
unsigned abbrCode = S.DeclTypeAbbrCodes [DestructorLayout::Code];
@@ -3973,12 +3972,34 @@ class Serializer::DeclSerializer : public DeclVisitor<DeclSerializer> {
3973
3972
}
3974
3973
};
3975
3974
3975
+ // / When allowing modules with errors there may be cases where there's little
3976
+ // / point in serializing a declaration and doing so would create a maintenance
3977
+ // / burden on the deserialization side. Returns \c true if the given declaration
3978
+ // / should be skipped and \c false otherwise.
3979
+ static bool canSkipWhenInvalid (const Decl *D) {
3980
+ // There's no point writing out the deinit when its context is not a class
3981
+ // as nothing would be able to reference it
3982
+ if (auto *deinit = dyn_cast<DestructorDecl>(D)) {
3983
+ if (!isa<ClassDecl>(D->getDeclContext ()))
3984
+ return true ;
3985
+ }
3986
+ return false ;
3987
+ }
3988
+
3976
3989
void Serializer::writeASTBlockEntity (const Decl *D) {
3977
3990
using namespace decls_block ;
3978
3991
3979
3992
PrettyStackTraceDecl trace (" serializing" , D);
3980
3993
assert (DeclsToSerialize.hasRef (D));
3981
3994
3995
+ if (D->isInvalid ()) {
3996
+ assert (allowCompilerErrors () &&
3997
+ " cannot create a module with an invalid decl" );
3998
+
3999
+ if (canSkipWhenInvalid (D))
4000
+ return ;
4001
+ }
4002
+
3982
4003
BitOffset initialOffset = Out.GetCurrentBitNo ();
3983
4004
SWIFT_DEFER {
3984
4005
// This is important enough to leave on in Release builds.
@@ -3988,8 +4009,6 @@ void Serializer::writeASTBlockEntity(const Decl *D) {
3988
4009
}
3989
4010
};
3990
4011
3991
- assert ((allowCompilerErrors () || !D->isInvalid ()) &&
3992
- " cannot create a module with an invalid decl" );
3993
4012
if (isDeclXRef (D)) {
3994
4013
writeCrossReference (D);
3995
4014
return ;
0 commit comments