From ee09422b014151a6a47c2ce704a81e94467bc786 Mon Sep 17 00:00:00 2001 From: Mike Stump Date: Fri, 6 Mar 2009 06:12:24 +0000 Subject: [PATCH] Complete __Block_byref_id_object_copy cogegen for block literals. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@66257 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGBlocks.cpp | 52 ++++++++++++++++++++++++++++++++++++---- lib/CodeGen/CGBlocks.h | 10 ++++---- lib/CodeGen/CGDecl.cpp | 3 ++- 3 files changed, 55 insertions(+), 10 deletions(-) diff --git a/lib/CodeGen/CGBlocks.cpp b/lib/CodeGen/CGBlocks.cpp index 1c13f90fbf..3326f83c19 100644 --- a/lib/CodeGen/CGBlocks.cpp +++ b/lib/CodeGen/CGBlocks.cpp @@ -755,15 +755,21 @@ llvm::Constant *BlockFunction::BuildDestroyHelper() { return CodeGenFunction(CGM).GenerateDestroyHelperFunction(); } -llvm::Constant *BlockFunction::GeneratebyrefCopyHelperFunction() { +llvm::Constant *BlockFunction:: +GeneratebyrefCopyHelperFunction(const llvm::Type *T, int flag) { QualType R = getContext().VoidTy; FunctionArgList Args; // FIXME: This leaks - ImplicitParamDecl *Src = + ImplicitParamDecl *Dst = ImplicitParamDecl::Create(getContext(), 0, SourceLocation(), 0, getContext().getPointerType(getContext().VoidTy)); + Args.push_back(std::make_pair(Dst, Dst->getType())); + // 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 = @@ -787,7 +793,27 @@ llvm::Constant *BlockFunction::GeneratebyrefCopyHelperFunction() { FunctionDecl::Static, false, true); CGF.StartFunction(FD, R, Fn, Args, SourceLocation()); - // EmitStmt(BExpr->getBody()); + + // dst->x + llvm::Value *V = CGF.GetAddrOfLocalVar(Dst); + V = Builder.CreateBitCast(V, T); + V = Builder.CreateStructGEP(V, 6, "x"); + llvm::Value *DstObj = Builder.CreateBitCast(V, PtrToInt8Ty); + + // src->x + V = CGF.GetAddrOfLocalVar(Src); + V = Builder.CreateLoad(V); + V = Builder.CreateBitCast(V, T); + V = Builder.CreateStructGEP(V, 6, "x"); + V = Builder.CreateBitCast(V, llvm::PointerType::get(PtrToInt8Ty, 0)); + llvm::Value *SrcObj = Builder.CreateLoad(V); + + flag |= BLOCK_BYREF_CALLER; + + llvm::Value *N = llvm::ConstantInt::get(llvm::Type::Int32Ty, flag); + llvm::Value *F = getBlockObjectAssign(); + Builder.CreateCall3(F, DstObj, SrcObj, N); + CGF.FinishFunction(); return llvm::ConstantExpr::getBitCast(Fn, PtrToInt8Ty); @@ -845,8 +871,9 @@ BlockFunction::GeneratebyrefDestroyHelperFunction(const llvm::Type *T, return llvm::ConstantExpr::getBitCast(Fn, PtrToInt8Ty); } -llvm::Constant *BlockFunction::BuildbyrefCopyHelper(int flag) { - return CodeGenFunction(CGM).GeneratebyrefCopyHelperFunction(); +llvm::Constant *BlockFunction::BuildbyrefCopyHelper(const llvm::Type *T, + int flag) { + return CodeGenFunction(CGM).GeneratebyrefCopyHelperFunction(T, flag); } llvm::Constant *BlockFunction::BuildbyrefDestroyHelper(const llvm::Type *T, @@ -868,6 +895,21 @@ llvm::Value *BlockFunction::getBlockObjectDispose() { return CGM.BlockObjectDispose; } +llvm::Value *BlockFunction::getBlockObjectAssign() { + if (CGM.BlockObjectAssign == 0) { + const llvm::FunctionType *FTy; + std::vector ArgTys; + const llvm::Type *ResultType = llvm::Type::VoidTy; + ArgTys.push_back(PtrToInt8Ty); + ArgTys.push_back(PtrToInt8Ty); + ArgTys.push_back(llvm::Type::Int32Ty); + FTy = llvm::FunctionType::get(ResultType, ArgTys, false); + CGM.BlockObjectAssign + = CGM.CreateRuntimeFunction(FTy, "_Block_object_assign"); + } + return CGM.BlockObjectAssign; +} + void BlockFunction::BuildBlockRelease(llvm::Value *V, int flag) { llvm::Value *F = getBlockObjectDispose(); llvm::Value *N; diff --git a/lib/CodeGen/CGBlocks.h b/lib/CodeGen/CGBlocks.h index 9763a1f32a..e915a512b7 100644 --- a/lib/CodeGen/CGBlocks.h +++ b/lib/CodeGen/CGBlocks.h @@ -94,6 +94,7 @@ public: int GlobalUniqueCount; } Block; + llvm::Value *BlockObjectAssign; llvm::Value *BlockObjectDispose; const llvm::Type *PtrToInt8Ty; @@ -102,7 +103,7 @@ public: : Context(C), TheModule(M), TheTargetData(TD), Types(T), CGM(CodeGen), NSConcreteGlobalBlock(0), NSConcreteStackBlock(0), BlockDescriptorType(0), - GenericBlockLiteralType(0), BlockObjectDispose(0) { + GenericBlockLiteralType(0), BlockObjectAssign(0), BlockObjectDispose(0) { Block.GlobalUniqueCount = 0; PtrToInt8Ty = llvm::PointerType::getUnqual(llvm::Type::Int8Ty); } @@ -163,12 +164,13 @@ public: llvm::Constant *BuildCopyHelper(); llvm::Constant *BuildDestroyHelper(); - llvm::Constant *GeneratebyrefCopyHelperFunction(); + llvm::Constant *GeneratebyrefCopyHelperFunction(const llvm::Type *, int flag); llvm::Constant *GeneratebyrefDestroyHelperFunction(const llvm::Type *T, int); - llvm::Constant *BuildbyrefCopyHelper(int flag); - llvm::Constant *BuildbyrefDestroyHelper(const llvm::Type*, int flag); + llvm::Constant *BuildbyrefCopyHelper(const llvm::Type *T, int flag); + llvm::Constant *BuildbyrefDestroyHelper(const llvm::Type *T, int flag); + llvm::Value *getBlockObjectAssign(); llvm::Value *getBlockObjectDispose(); void BuildBlockRelease(llvm::Value *DeclPtr, int flag = BLOCK_FIELD_IS_BYREF); diff --git a/lib/CodeGen/CGDecl.cpp b/lib/CodeGen/CGDecl.cpp index cf9b741168..1322ca223a 100644 --- a/lib/CodeGen/CGDecl.cpp +++ b/lib/CodeGen/CGDecl.cpp @@ -373,7 +373,8 @@ void CodeGenFunction::EmitLocalBlockVarDecl(const VarDecl &D) { if (flags & BLOCK_HAS_COPY_DISPOSE) { BlockHasCopyDispose = true; llvm::Value *copy_helper = Builder.CreateStructGEP(DeclPtr, 4); - Builder.CreateStore(BuildbyrefCopyHelper(flag), copy_helper); + Builder.CreateStore(BuildbyrefCopyHelper(DeclPtr->getType(), flag), + copy_helper); llvm::Value *destroy_helper = Builder.CreateStructGEP(DeclPtr, 5); Builder.CreateStore(BuildbyrefDestroyHelper(DeclPtr->getType(), flag), -- 2.40.0