@@ -2029,8 +2029,10 @@ void Serializer::writePatternBindingInitializer(PatternBindingDecl *binding,
20292029 StringRef initStr;
20302030 SmallString<128 > scratch;
20312031 auto varDecl = binding->getAnchoringVarDecl (bindingIndex);
2032+ assert ((varDecl || allowCompilerErrors ()) &&
2033+ " Serializing PDB without anchoring VarDecl" );
20322034 if (binding->hasInitStringRepresentation (bindingIndex) &&
2033- varDecl->isInitExposedToClients ()) {
2035+ varDecl && varDecl ->isInitExposedToClients ()) {
20342036 initStr = binding->getInitStringRepresentation (bindingIndex, scratch);
20352037 }
20362038
@@ -3929,9 +3931,6 @@ class Serializer::DeclSerializer : public DeclVisitor<DeclSerializer> {
39293931 using namespace decls_block ;
39303932 verifyAttrSerializable (dtor);
39313933
3932- if (S.allowCompilerErrors () && dtor->isInvalid ())
3933- return ;
3934-
39353934 auto contextID = S.addDeclContextRef (dtor->getDeclContext ());
39363935
39373936 unsigned abbrCode = S.DeclTypeAbbrCodes [DestructorLayout::Code];
@@ -3973,12 +3972,34 @@ class Serializer::DeclSerializer : public DeclVisitor<DeclSerializer> {
39733972 }
39743973};
39753974
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+
39763989void Serializer::writeASTBlockEntity (const Decl *D) {
39773990 using namespace decls_block ;
39783991
39793992 PrettyStackTraceDecl trace (" serializing" , D);
39803993 assert (DeclsToSerialize.hasRef (D));
39813994
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+
39824003 BitOffset initialOffset = Out.GetCurrentBitNo ();
39834004 SWIFT_DEFER {
39844005 // This is important enough to leave on in Release builds.
@@ -3988,8 +4009,6 @@ void Serializer::writeASTBlockEntity(const Decl *D) {
39884009 }
39894010 };
39904011
3991- assert ((allowCompilerErrors () || !D->isInvalid ()) &&
3992- " cannot create a module with an invalid decl" );
39934012 if (isDeclXRef (D)) {
39944013 writeCrossReference (D);
39954014 return ;
0 commit comments