@@ -1932,6 +1932,48 @@ void IRGenerator::emitEagerClassInitialization() {
19321932 llvm::appendToGlobalCtors (IGM->Module , RegisterFn, 60000 , nullptr );
19331933}
19341934
1935+ void IRGenerator::emitObjCActorsNeedingSuperclassSwizzle () {
1936+ if (ObjCActorsNeedingSuperclassSwizzle.empty ())
1937+ return ;
1938+
1939+ // Emit the register function in the primary module.
1940+ IRGenModule *IGM = getPrimaryIGM ();
1941+
1942+ llvm::Function *RegisterFn = llvm::Function::Create (
1943+ llvm::FunctionType::get (IGM->VoidTy , false ),
1944+ llvm::GlobalValue::PrivateLinkage,
1945+ " _swift_objc_actor_initialization" );
1946+ IGM->Module .getFunctionList ().push_back (RegisterFn);
1947+ IRGenFunction RegisterIGF (*IGM, RegisterFn);
1948+ RegisterFn->setAttributes (IGM->constructInitialAttributes ());
1949+ RegisterFn->setCallingConv (IGM->DefaultCC );
1950+
1951+ // Look up the SwiftNativeNSObject class.
1952+ auto swiftNativeNSObjectName =
1953+ IGM->getAddrOfGlobalString (" SwiftNativeNSObject" );
1954+ auto swiftNativeNSObjectClass = RegisterIGF.Builder .CreateCall (
1955+ RegisterIGF.IGM .getObjCGetRequiredClassFn (), swiftNativeNSObjectName);
1956+
1957+ for (ClassDecl *CD : ObjCActorsNeedingSuperclassSwizzle) {
1958+ // The @objc actor class.
1959+ llvm::Value *classRef = RegisterIGF.emitTypeMetadataRef (
1960+ CD->getDeclaredInterfaceType ()->getCanonicalType ());
1961+ classRef = RegisterIGF.Builder .CreateBitCast (classRef, IGM->ObjCClassPtrTy );
1962+
1963+ // Set its superclass to SwiftNativeNSObject.
1964+ RegisterIGF.Builder .CreateCall (
1965+ RegisterIGF.IGM .getSetSuperclassFn (),
1966+ { classRef, swiftNativeNSObjectClass});
1967+ }
1968+ RegisterIGF.Builder .CreateRetVoid ();
1969+
1970+ // Add the registration function as a static initializer. We use a priority
1971+ // slightly lower than used for C++ global constructors, so that the code is
1972+ // executed before C++ global constructors (in case someone manages to access
1973+ // an @objc actor from a global constructor).
1974+ llvm::appendToGlobalCtors (IGM->Module , RegisterFn, 60000 , nullptr );
1975+ }
1976+
19351977// / Emit symbols for eliminated dead methods, which can still be referenced
19361978// / from other modules. This happens e.g. if a public class contains a (dead)
19371979// / private method.
0 commit comments