@@ -1861,6 +1861,48 @@ void IRGenerator::emitEagerClassInitialization() {
1861
1861
llvm::appendToGlobalCtors (IGM->Module , RegisterFn, 60000 , nullptr );
1862
1862
}
1863
1863
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
+
1864
1906
// / Emit symbols for eliminated dead methods, which can still be referenced
1865
1907
// / from other modules. This happens e.g. if a public class contains a (dead)
1866
1908
// / private method.
0 commit comments