@@ -1861,6 +1861,48 @@ void IRGenerator::emitEagerClassInitialization() {
18611861 llvm::appendToGlobalCtors (IGM->Module , RegisterFn, 60000 , nullptr );
18621862}
18631863
1864+ void IRGenerator::emitObjCActorsNeedingSuperclassSwizzle () {
1865+ if (ObjCActorsNeedingSuperclassSwizzle.empty ())
1866+ return ;
1867+
1868+ // Emit the register function in the primary module.
1869+ IRGenModule *IGM = getPrimaryIGM ();
1870+
1871+ llvm::Function *RegisterFn = llvm::Function::Create (
1872+ llvm::FunctionType::get (IGM->VoidTy , false ),
1873+ llvm::GlobalValue::PrivateLinkage,
1874+ " _swift_objc_actor_initialization" );
1875+ IGM->Module .getFunctionList ().push_back (RegisterFn);
1876+ IRGenFunction RegisterIGF (*IGM, RegisterFn);
1877+ RegisterFn->setAttributes (IGM->constructInitialAttributes ());
1878+ RegisterFn->setCallingConv (IGM->DefaultCC );
1879+
1880+ // Look up the SwiftNativeNSObject class.
1881+ auto swiftNativeNSObjectName =
1882+ IGM->getAddrOfGlobalString (" SwiftNativeNSObject" );
1883+ auto swiftNativeNSObjectClass = RegisterIGF.Builder .CreateCall (
1884+ RegisterIGF.IGM .getObjCGetRequiredClassFn (), swiftNativeNSObjectName);
1885+
1886+ for (ClassDecl *CD : ObjCActorsNeedingSuperclassSwizzle) {
1887+ // The @objc actor class.
1888+ llvm::Value *classRef = RegisterIGF.emitTypeMetadataRef (
1889+ CD->getDeclaredInterfaceType ()->getCanonicalType ());
1890+ classRef = RegisterIGF.Builder .CreateBitCast (classRef, IGM->ObjCClassPtrTy );
1891+
1892+ // Set its superclass to SwiftNativeNSObject.
1893+ RegisterIGF.Builder .CreateCall (
1894+ RegisterIGF.IGM .getSetSuperclassFn (),
1895+ { classRef, swiftNativeNSObjectClass});
1896+ }
1897+ RegisterIGF.Builder .CreateRetVoid ();
1898+
1899+ // Add the registration function as a static initializer. We use a priority
1900+ // slightly lower than used for C++ global constructors, so that the code is
1901+ // executed before C++ global constructors (in case someone manages to access
1902+ // an @objc actor from a global constructor).
1903+ llvm::appendToGlobalCtors (IGM->Module , RegisterFn, 60000 , nullptr );
1904+ }
1905+
18641906// / Emit symbols for eliminated dead methods, which can still be referenced
18651907// / from other modules. This happens e.g. if a public class contains a (dead)
18661908// / private method.
0 commit comments