@@ -3794,23 +3794,44 @@ void irgen::emitClassMetadata(IRGenModule &IGM, ClassDecl *classDecl,
3794
3794
if (IGM.ObjCInterop ) {
3795
3795
switch (strategy) {
3796
3796
case ClassMetadataStrategy::Resilient:
3797
- // Even non-@objc classes can have Objective-C categories attached, so
3798
- // we always emit a resilient class stub as long as -enable-objc-interop
3799
- // is set.
3797
+ // We always emit a resilient class stub as long as -enable-objc-interop
3798
+ // is set. You can define @objc members in an extension of a resilient
3799
+ // class across a module boundary, and this category is attached to the
3800
+ // class stub.
3800
3801
if (IGM.hasObjCResilientClassStub (classDecl)) {
3801
- IGM.emitObjCResilientClassStub (classDecl);
3802
+ auto *stub = IGM.emitObjCResilientClassStub (
3803
+ classDecl, /* isPublic=*/ true );
3802
3804
3803
- if (classDecl-> isObjC ()) {
3804
- auto *stub = IGM. getAddrOfObjCResilientClassStub (
3805
- classDecl, NotForDefinition,
3806
- TypeMetadataAddress::AddressPoint);
3805
+ // If the class has Objective-C ancestry but does *not* have generic
3806
+ // ancestry, it appears in the generated header. We emit an Objective-C
3807
+ // class symbol aliased to the class stub for Clang to reference.
3808
+ if (classDecl-> isObjC ())
3807
3809
emitObjCClassSymbol (IGM, classDecl, stub);
3808
3810
3811
+ // Note that if the class has generic ancestry, isObjC() is false.
3812
+ // This is because such classes cannot appear in the generated header,
3813
+ // because their generic superclasses cannot appear in the generated
3814
+ // header either. However, we still want to emit the class stub in
3815
+ // the __objc_stublist section of the binary, so that they are visited
3816
+ // by objc_copyClassList().
3817
+ if (classDecl->checkAncestry (AncestryFlags::ObjC))
3809
3818
IGM.addObjCClassStub (stub);
3810
- }
3811
3819
}
3812
3820
break ;
3821
+
3813
3822
case ClassMetadataStrategy::Singleton:
3823
+ // If the class has Objective-C ancestry, we emit the class stub and
3824
+ // add it to the __obj_stublist. Note that the stub is not public in
3825
+ // this case, since there is no reason to reference directly; it only
3826
+ // exists so that objc_copyClassList() can find it.
3827
+ if (IGM.hasObjCResilientClassStub (classDecl)) {
3828
+ if (classDecl->checkAncestry (AncestryFlags::ObjC)) {
3829
+ auto *stub = IGM.emitObjCResilientClassStub (
3830
+ classDecl, /* isPublic=*/ false );
3831
+ IGM.addObjCClassStub (stub);
3832
+ }
3833
+ }
3834
+
3814
3835
break ;
3815
3836
3816
3837
case ClassMetadataStrategy::Update:
@@ -3820,7 +3841,7 @@ void irgen::emitClassMetadata(IRGenModule &IGM, ClassDecl *classDecl,
3820
3841
emitObjCClassSymbol (IGM, classDecl, var);
3821
3842
3822
3843
IGM.addObjCClass (var,
3823
- classDecl->getAttrs ().hasAttribute <ObjCNonLazyRealizationAttr>());
3844
+ classDecl->getAttrs ().hasAttribute <ObjCNonLazyRealizationAttr>());
3824
3845
break ;
3825
3846
}
3826
3847
}
0 commit comments