@@ -3794,23 +3794,44 @@ void irgen::emitClassMetadata(IRGenModule &IGM, ClassDecl *classDecl,
37943794 if (IGM.ObjCInterop ) {
37953795 switch (strategy) {
37963796 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.
38003801 if (IGM.hasObjCResilientClassStub (classDecl)) {
3801- IGM.emitObjCResilientClassStub (classDecl);
3802+ auto *stub = IGM.emitObjCResilientClassStub (
3803+ classDecl, /* isPublic=*/ true );
38023804
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 ())
38073809 emitObjCClassSymbol (IGM, classDecl, stub);
38083810
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))
38093818 IGM.addObjCClassStub (stub);
3810- }
38113819 }
38123820 break ;
3821+
38133822 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+
38143835 break ;
38153836
38163837 case ClassMetadataStrategy::Update:
@@ -3820,7 +3841,7 @@ void irgen::emitClassMetadata(IRGenModule &IGM, ClassDecl *classDecl,
38203841 emitObjCClassSymbol (IGM, classDecl, var);
38213842
38223843 IGM.addObjCClass (var,
3823- classDecl->getAttrs ().hasAttribute <ObjCNonLazyRealizationAttr>());
3844+ classDecl->getAttrs ().hasAttribute <ObjCNonLazyRealizationAttr>());
38243845 break ;
38253846 }
38263847 }
0 commit comments