@@ -671,7 +671,10 @@ class AssociatedTypeMetadataBuilder : public ReflectionMetadataBuilder {
671
671
};
672
672
673
673
class FieldTypeMetadataBuilder : public ReflectionMetadataBuilder {
674
- const uint32_t fieldRecordSize = 12 ;
674
+ public:
675
+ static const uint32_t FieldRecordSize = 12 ;
676
+
677
+ private:
675
678
const NominalTypeDecl *NTD;
676
679
677
680
void addFieldDecl (const ValueDecl *value, Type type,
@@ -714,7 +717,7 @@ class FieldTypeMetadataBuilder : public ReflectionMetadataBuilder {
714
717
}
715
718
716
719
B.addInt16 (uint16_t (kind));
717
- B.addInt16 (fieldRecordSize );
720
+ B.addInt16 (FieldRecordSize );
718
721
719
722
auto properties = NTD->getStoredProperties ();
720
723
B.addInt32 (properties.size ());
@@ -737,7 +740,7 @@ class FieldTypeMetadataBuilder : public ReflectionMetadataBuilder {
737
740
}
738
741
739
742
B.addInt16 (uint16_t (kind));
740
- B.addInt16 (fieldRecordSize );
743
+ B.addInt16 (FieldRecordSize );
741
744
B.addInt32 (strategy.getElementsWithPayload ().size ()
742
745
+ strategy.getElementsWithNoPayload ().size ());
743
746
@@ -764,7 +767,7 @@ class FieldTypeMetadataBuilder : public ReflectionMetadataBuilder {
764
767
else
765
768
Kind = FieldDescriptorKind::Protocol;
766
769
B.addInt16 (uint16_t (Kind));
767
- B.addInt16 (fieldRecordSize );
770
+ B.addInt16 (FieldRecordSize );
768
771
B.addInt32 (0 );
769
772
}
770
773
@@ -825,6 +828,57 @@ class FieldTypeMetadataBuilder : public ReflectionMetadataBuilder {
825
828
}
826
829
};
827
830
831
+ static bool
832
+ deploymentTargetHasRemoteMirrorZeroSizedTypeDescriptorBug (IRGenModule &IGM) {
833
+ auto target = IGM.Context .LangOpts .Target ;
834
+
835
+ if (target.isMacOSX () && target.isMacOSXVersionLT (10 , 16 , 0 )) {
836
+ return true ;
837
+ }
838
+ if (target.isiOS () && target.isOSVersionLT (14 )) { // includes tvOS
839
+ return true ;
840
+ }
841
+ if (target.isWatchOS () && target.isOSVersionLT (7 )) {
842
+ return true ;
843
+ }
844
+
845
+ return false ;
846
+ }
847
+
848
+ // / Metadata builder that emits a fixed-layout empty type as an empty struct, as
849
+ // / a workaround for a RemoteMirror crash in older OSes.
850
+ class EmptyStructMetadataBuilder : public ReflectionMetadataBuilder {
851
+ const NominalTypeDecl *NTD;
852
+
853
+ void layout () override {
854
+ addNominalRef (NTD);
855
+ B.addInt32 (0 );
856
+ B.addInt16 (uint16_t (FieldDescriptorKind::Struct));
857
+ B.addInt16 (FieldTypeMetadataBuilder::FieldRecordSize);
858
+ B.addInt32 (0 );
859
+ }
860
+
861
+ public:
862
+ EmptyStructMetadataBuilder (IRGenModule &IGM,
863
+ const NominalTypeDecl *NTD)
864
+ : ReflectionMetadataBuilder(IGM), NTD(NTD) {
865
+ assert (IGM.getTypeInfoForUnlowered (
866
+ NTD->getDeclaredTypeInContext ()->getCanonicalType ())
867
+ .isKnownEmpty (ResilienceExpansion::Maximal)
868
+ && " should only be used for known empty types" );
869
+ }
870
+
871
+ llvm::GlobalVariable *emit () {
872
+ auto section = IGM.getFieldTypeMetadataSectionName ();
873
+ return ReflectionMetadataBuilder::emit (
874
+ [&](IRGenModule &IGM, ConstantInit definition) -> llvm::Constant* {
875
+ return IGM.getAddrOfReflectionFieldDescriptor (
876
+ NTD->getDeclaredType ()->getCanonicalType (), definition);
877
+ },
878
+ section);
879
+ }
880
+ };
881
+
828
882
class FixedTypeMetadataBuilder : public ReflectionMetadataBuilder {
829
883
ModuleDecl *module ;
830
884
CanType type;
@@ -1338,6 +1392,19 @@ void IRGenModule::emitFieldDescriptor(const NominalTypeDecl *D) {
1338
1392
}
1339
1393
1340
1394
if (needsOpaqueDescriptor) {
1395
+ // Work around an issue in the RemoteMirror library that ships in
1396
+ // macOS 10.15/iOS 13 and earlier that causes it to crash on a
1397
+ // BuiltinTypeDescriptor with zero size. If the type has zero size, emit it
1398
+ // as an empty struct instead, which will have the same impact on the
1399
+ // encoded type layout.
1400
+ auto &TI = getTypeInfoForUnlowered (T);
1401
+ if (deploymentTargetHasRemoteMirrorZeroSizedTypeDescriptorBug (*this )
1402
+ && TI.isKnownEmpty (ResilienceExpansion::Maximal)) {
1403
+ EmptyStructMetadataBuilder builder (*this , D);
1404
+ builder.emit ();
1405
+ return ;
1406
+ }
1407
+
1341
1408
FixedTypeMetadataBuilder builder (*this , D);
1342
1409
builder.emit ();
1343
1410
}
0 commit comments