From: Mike Stump Date: Fri, 6 Mar 2009 02:29:21 +0000 (+0000) Subject: More codegen support for the copy/dispose helpers for block literals. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=45031c08c608e548ac12caf0547f89574e994b96;p=clang More codegen support for the copy/dispose helpers for block literals. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@66241 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGBlocks.cpp b/lib/CodeGen/CGBlocks.cpp index a792537ea9..20398d463c 100644 --- a/lib/CodeGen/CGBlocks.cpp +++ b/lib/CodeGen/CGBlocks.cpp @@ -52,16 +52,10 @@ llvm::Constant *CodeGenFunction::BuildDescriptorBlockDecl(uint64_t Size) { if (BlockHasCopyDispose) { // copy_func_helper_decl - // FIXME: implement - C = llvm::Constant::getNullValue(PtrToInt8Ty); - C = llvm::ConstantExpr::getBitCast(C, PtrToInt8Ty); - Elts.push_back(C); + Elts.push_back(BuildCopyHelper()); // destroy_func_decl - // FIXME: implement - C = llvm::Constant::getNullValue(PtrToInt8Ty); - C = llvm::ConstantExpr::getBitCast(C, PtrToInt8Ty); - Elts.push_back(C); + Elts.push_back(BuildDestroyHelper()); } C = llvm::ConstantStruct::get(Elts); @@ -753,14 +747,98 @@ llvm::Constant *BlockFunction::GenerateDestroyHelperFunction() { return llvm::ConstantExpr::getBitCast(Fn, PtrToInt8Ty); } -llvm::Constant *BlockFunction::BuildCopyHelper(int flag) { +llvm::Constant *BlockFunction::BuildCopyHelper() { return CodeGenFunction(CGM).GenerateCopyHelperFunction(); } -llvm::Constant *BlockFunction::BuildDestroyHelper(int flag) { +llvm::Constant *BlockFunction::BuildDestroyHelper() { return CodeGenFunction(CGM).GenerateDestroyHelperFunction(); } +llvm::Constant *BlockFunction::GeneratebyrefCopyHelperFunction() { + QualType R = getContext().VoidTy; + + FunctionArgList Args; + // FIXME: This leaks + ImplicitParamDecl *Src = + ImplicitParamDecl::Create(getContext(), 0, SourceLocation(), 0, + getContext().getPointerType(getContext().VoidTy)); + + Args.push_back(std::make_pair(Src, Src->getType())); + + const CGFunctionInfo &FI = + CGM.getTypes().getFunctionInfo(R, Args); + + std::string Name = std::string("__Block_byref_id_object_copy_"); + CodeGenTypes &Types = CGM.getTypes(); + const llvm::FunctionType *LTy = Types.GetFunctionType(FI, false); + + llvm::Function *Fn = + llvm::Function::Create(LTy, llvm::GlobalValue::InternalLinkage, + Name, + &CGM.getModule()); + + IdentifierInfo *II + = &CGM.getContext().Idents.get("__Block_byref_id_object_copy_"); + + FunctionDecl *FD = FunctionDecl::Create(getContext(), + getContext().getTranslationUnitDecl(), + SourceLocation(), II, R, + FunctionDecl::Static, false, + true); + CGF.StartFunction(FD, R, Fn, Args, SourceLocation()); + // EmitStmt(BExpr->getBody()); + CGF.FinishFunction(); + + return llvm::ConstantExpr::getBitCast(Fn, PtrToInt8Ty); +} + +llvm::Constant *BlockFunction::GeneratebyrefDestroyHelperFunction() { + QualType R = getContext().VoidTy; + + FunctionArgList Args; + // FIXME: This leaks + ImplicitParamDecl *Src = + ImplicitParamDecl::Create(getContext(), 0, SourceLocation(), 0, + getContext().getPointerType(getContext().VoidTy)); + + Args.push_back(std::make_pair(Src, Src->getType())); + + const CGFunctionInfo &FI = + CGM.getTypes().getFunctionInfo(R, Args); + + std::string Name = std::string("__Block_byref_id_object_dispose_"); + CodeGenTypes &Types = CGM.getTypes(); + const llvm::FunctionType *LTy = Types.GetFunctionType(FI, false); + + llvm::Function *Fn = + llvm::Function::Create(LTy, llvm::GlobalValue::InternalLinkage, + Name, + &CGM.getModule()); + + IdentifierInfo *II + = &CGM.getContext().Idents.get("__Block_byref_id_object_dispose_"); + + FunctionDecl *FD = FunctionDecl::Create(getContext(), + getContext().getTranslationUnitDecl(), + SourceLocation(), II, R, + FunctionDecl::Static, false, + true); + CGF.StartFunction(FD, R, Fn, Args, SourceLocation()); + // EmitStmt(BExpr->getBody()); + CGF.FinishFunction(); + + return llvm::ConstantExpr::getBitCast(Fn, PtrToInt8Ty); +} + +llvm::Constant *BlockFunction::BuildbyrefCopyHelper(int flag) { + return CodeGenFunction(CGM).GeneratebyrefCopyHelperFunction(); +} + +llvm::Constant *BlockFunction::BuildbyrefDestroyHelper(int flag) { + return CodeGenFunction(CGM).GeneratebyrefDestroyHelperFunction(); +} + llvm::Value *BlockFunction::getBlockObjectDispose() { if (CGM.BlockObjectDispose == 0) { const llvm::FunctionType *FTy; diff --git a/lib/CodeGen/CGBlocks.h b/lib/CodeGen/CGBlocks.h index 84ad190d6f..adcb4af0d1 100644 --- a/lib/CodeGen/CGBlocks.h +++ b/lib/CodeGen/CGBlocks.h @@ -160,8 +160,14 @@ public: llvm::Constant *GenerateCopyHelperFunction(); llvm::Constant *GenerateDestroyHelperFunction(); - llvm::Constant *BuildCopyHelper(int flag); - llvm::Constant *BuildDestroyHelper(int flag); + llvm::Constant *BuildCopyHelper(); + llvm::Constant *BuildDestroyHelper(); + + llvm::Constant *GeneratebyrefCopyHelperFunction(); + llvm::Constant *GeneratebyrefDestroyHelperFunction(); + + llvm::Constant *BuildbyrefCopyHelper(int flag); + llvm::Constant *BuildbyrefDestroyHelper(int flag); llvm::Value *getBlockObjectDispose(); void BuildBlockRelease(const VarDecl &D, llvm::Value *DeclPtr); diff --git a/lib/CodeGen/CGDecl.cpp b/lib/CodeGen/CGDecl.cpp index 2b995d150c..a24802b285 100644 --- a/lib/CodeGen/CGDecl.cpp +++ b/lib/CodeGen/CGDecl.cpp @@ -375,9 +375,9 @@ void CodeGenFunction::EmitLocalBlockVarDecl(const VarDecl &D) { llvm::Value *copy_helper = Builder.CreateStructGEP(DeclPtr, 4); llvm::Value *destroy_helper = Builder.CreateStructGEP(DeclPtr, 5); - Builder.CreateStore(BuildCopyHelper(flag), copy_helper); + Builder.CreateStore(BuildbyrefCopyHelper(flag), copy_helper); - Builder.CreateStore(BuildDestroyHelper(flag), destroy_helper); + Builder.CreateStore(BuildbyrefDestroyHelper(flag), destroy_helper); } needsDispose = true; } diff --git a/test/CodeGen/blocks-1.c b/test/CodeGen/blocks-1.c index 4a602e27d3..804b688afb 100644 --- a/test/CodeGen/blocks-1.c +++ b/test/CodeGen/blocks-1.c @@ -1,7 +1,9 @@ // RUN: clang %s -emit-llvm -o %t -fblocks -f__block && -// RUN: grep "_Block_object_dispose" %t | count 4 -// RUN: grep "__copy_helper_block_" %t | count 2 -// RUN: grep "__destroy_helper_block_" %t | count 2 +// RUN: grep "_Block_object_dispose" %t | count 5 +// RUN: grep "__copy_helper_block_" %t | count 6 +// RUN: grep "__destroy_helper_block_" %t | count 6 +// RUN: grep "__Block_byref_id_object_copy_" %t | count 2 +// RUN: grep "__Block_byref_id_object_dispose_" %t | count 2 #include void test1() { @@ -31,8 +33,9 @@ void test2() { } void test3() { + __block int k; __block int (^j)(int); - ^{j=0;}(); + ^{j=0; k=0;}(); } int main() {