@@ -2084,8 +2084,10 @@ void Serializer::writePatternBindingInitializer(PatternBindingDecl *binding,
2084
2084
StringRef initStr;
2085
2085
SmallString<128 > scratch;
2086
2086
auto varDecl = binding->getAnchoringVarDecl (bindingIndex);
2087
+ assert ((varDecl || allowCompilerErrors ()) &&
2088
+ " Serializing PDB without anchoring VarDecl" );
2087
2089
if (binding->hasInitStringRepresentation (bindingIndex) &&
2088
- varDecl->isInitExposedToClients ()) {
2090
+ varDecl && varDecl ->isInitExposedToClients ()) {
2089
2091
initStr = binding->getInitStringRepresentation (bindingIndex, scratch);
2090
2092
}
2091
2093
@@ -3957,9 +3959,6 @@ class Serializer::DeclSerializer : public DeclVisitor<DeclSerializer> {
3957
3959
using namespace decls_block ;
3958
3960
verifyAttrSerializable (dtor);
3959
3961
3960
- if (S.allowCompilerErrors () && dtor->isInvalid ())
3961
- return ;
3962
-
3963
3962
auto contextID = S.addDeclContextRef (dtor->getDeclContext ());
3964
3963
3965
3964
unsigned abbrCode = S.DeclTypeAbbrCodes [DestructorLayout::Code];
@@ -4001,12 +4000,34 @@ class Serializer::DeclSerializer : public DeclVisitor<DeclSerializer> {
4001
4000
}
4002
4001
};
4003
4002
4003
+ // / When allowing modules with errors there may be cases where there's little
4004
+ // / point in serializing a declaration and doing so would create a maintenance
4005
+ // / burden on the deserialization side. Returns \c true if the given declaration
4006
+ // / should be skipped and \c false otherwise.
4007
+ static bool canSkipWhenInvalid (const Decl *D) {
4008
+ // There's no point writing out the deinit when its context is not a class
4009
+ // as nothing would be able to reference it
4010
+ if (auto *deinit = dyn_cast<DestructorDecl>(D)) {
4011
+ if (!isa<ClassDecl>(D->getDeclContext ()))
4012
+ return true ;
4013
+ }
4014
+ return false ;
4015
+ }
4016
+
4004
4017
void Serializer::writeASTBlockEntity (const Decl *D) {
4005
4018
using namespace decls_block ;
4006
4019
4007
4020
PrettyStackTraceDecl trace (" serializing" , D);
4008
4021
assert (DeclsToSerialize.hasRef (D));
4009
4022
4023
+ if (D->isInvalid ()) {
4024
+ assert (allowCompilerErrors () &&
4025
+ " cannot create a module with an invalid decl" );
4026
+
4027
+ if (canSkipWhenInvalid (D))
4028
+ return ;
4029
+ }
4030
+
4010
4031
BitOffset initialOffset = Out.GetCurrentBitNo ();
4011
4032
SWIFT_DEFER {
4012
4033
// This is important enough to leave on in Release builds.
@@ -4016,8 +4037,6 @@ void Serializer::writeASTBlockEntity(const Decl *D) {
4016
4037
}
4017
4038
};
4018
4039
4019
- assert ((allowCompilerErrors () || !D->isInvalid ()) &&
4020
- " cannot create a module with an invalid decl" );
4021
4040
if (isDeclXRef (D)) {
4022
4041
writeCrossReference (D);
4023
4042
return ;
0 commit comments