@@ -1932,6 +1932,48 @@ void IRGenerator::emitEagerClassInitialization() {
1932
1932
llvm::appendToGlobalCtors (IGM->Module , RegisterFn, 60000 , nullptr );
1933
1933
}
1934
1934
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
+
1935
1977
// / Emit symbols for eliminated dead methods, which can still be referenced
1936
1978
// / from other modules. This happens e.g. if a public class contains a (dead)
1937
1979
// / private method.
0 commit comments