diff options
author | John McCall <rjmccall@apple.com> | 2011-09-09 20:41:01 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2011-09-09 20:41:01 +0000 |
commit | 13db5cfc4e5f03eb70efe0d227b53b8280f16161 (patch) | |
tree | 94795d436a9e5021d700babc08f1fcb34e0465bf /lib/CodeGen/CGBlocks.cpp | |
parent | 88914801a4d73e321c6f74f97df7d7b11c298bc6 (diff) |
Treat the weak export of block runtime symbols as a deployment-target
feature akin to the ARC runtime checks. Removes a terrible hack where
IR gen needed to find the declarations of those symbols in the translation
unit.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@139404 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGBlocks.cpp')
-rw-r--r-- | lib/CodeGen/CGBlocks.cpp | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/lib/CodeGen/CGBlocks.cpp b/lib/CodeGen/CGBlocks.cpp index b795ef1bef..fd93255e5c 100644 --- a/lib/CodeGen/CGBlocks.cpp +++ b/lib/CodeGen/CGBlocks.cpp @@ -1809,3 +1809,58 @@ void CodeGenFunction::enterByrefCleanup(const AutoVarEmission &emission) { EHStack.pushCleanup<CallBlockRelease>(NormalAndEHCleanup, emission.Address); } + +/// Adjust the declaration of something from the blocks API. +static void configureBlocksRuntimeObject(CodeGenModule &CGM, + llvm::Constant *C) { + if (!CGM.getLangOptions().BlocksRuntimeOptional) return; + + llvm::GlobalValue *GV = cast<llvm::GlobalValue>(C->stripPointerCasts()); + if (GV->isDeclaration() && + GV->getLinkage() == llvm::GlobalValue::ExternalLinkage) + GV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage); +} + +llvm::Constant *CodeGenModule::getBlockObjectDispose() { + if (BlockObjectDispose) + return BlockObjectDispose; + + llvm::Type *args[] = { Int8PtrTy, Int32Ty }; + llvm::FunctionType *fty + = llvm::FunctionType::get(VoidTy, args, false); + BlockObjectDispose = CreateRuntimeFunction(fty, "_Block_object_dispose"); + configureBlocksRuntimeObject(*this, BlockObjectDispose); + return BlockObjectDispose; +} + +llvm::Constant *CodeGenModule::getBlockObjectAssign() { + if (BlockObjectAssign) + return BlockObjectAssign; + + llvm::Type *args[] = { Int8PtrTy, Int8PtrTy, Int32Ty }; + llvm::FunctionType *fty + = llvm::FunctionType::get(VoidTy, args, false); + BlockObjectAssign = CreateRuntimeFunction(fty, "_Block_object_assign"); + configureBlocksRuntimeObject(*this, BlockObjectAssign); + return BlockObjectAssign; +} + +llvm::Constant *CodeGenModule::getNSConcreteGlobalBlock() { + if (NSConcreteGlobalBlock) + return NSConcreteGlobalBlock; + + NSConcreteGlobalBlock = GetOrCreateLLVMGlobal("_NSConcreteGlobalBlock", + Int8PtrTy->getPointerTo(), 0); + configureBlocksRuntimeObject(*this, NSConcreteGlobalBlock); + return NSConcreteGlobalBlock; +} + +llvm::Constant *CodeGenModule::getNSConcreteStackBlock() { + if (NSConcreteStackBlock) + return NSConcreteStackBlock; + + NSConcreteStackBlock = GetOrCreateLLVMGlobal("_NSConcreteStackBlock", + Int8PtrTy->getPointerTo(), 0); + configureBlocksRuntimeObject(*this, NSConcreteStackBlock); + return NSConcreteStackBlock; +} |