diff options
author | Mike Stump <mrs@apple.com> | 2009-04-10 18:52:28 +0000 |
---|---|---|
committer | Mike Stump <mrs@apple.com> | 2009-04-10 18:52:28 +0000 |
commit | b7477cf6cf6cf4f132ba7beff42684e59bed15f4 (patch) | |
tree | ad6b2369f2d92be091cbead7f525fa1e640a2868 | |
parent | 960cd06eab1325071d331b462553c9e4135c926e (diff) |
Fixup codegen for nested blocks that use copy/dispose in the inner
blocks, so that the outer blocks use it as well. Radar 6762279
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@68811 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/CodeGen/CGBlocks.cpp | 112 | ||||
-rw-r--r-- | lib/CodeGen/CGBlocks.h | 8 | ||||
-rw-r--r-- | test/CodeGen/blocks-1.c | 17 |
3 files changed, 76 insertions, 61 deletions
diff --git a/lib/CodeGen/CGBlocks.cpp b/lib/CodeGen/CGBlocks.cpp index a623cf18cf..4e9419ed20 100644 --- a/lib/CodeGen/CGBlocks.cpp +++ b/lib/CodeGen/CGBlocks.cpp @@ -48,10 +48,10 @@ BuildDescriptorBlockDecl(bool BlockHasCopyDispose, uint64_t Size, if (BlockHasCopyDispose) { // copy_func_helper_decl - Elts.push_back(BuildCopyHelper(Ty, *NoteForHelper)); + Elts.push_back(BuildCopyHelper(Ty, NoteForHelper)); // destroy_func_decl - Elts.push_back(BuildDestroyHelper(Ty, *NoteForHelper)); + Elts.push_back(BuildDestroyHelper(Ty, NoteForHelper)); } C = llvm::ConstantStruct::get(Elts); @@ -178,7 +178,6 @@ llvm::Value *CodeGenFunction::BuildBlockLiteralTmp(const BlockExpr *BE) { if (subBlockDeclRefDecls.size() == 0) { // __descriptor - assert(subBlockHasCopyDispose == false); Elts[4] = BuildDescriptorBlockDecl(subBlockHasCopyDispose, subBlockSize, 0, 0); // Optimize to being a global block. @@ -714,7 +713,7 @@ uint64_t BlockFunction::getBlockOffset(const BlockDeclRefExpr *BDRE) { llvm::Constant *BlockFunction:: GenerateCopyHelperFunction(bool BlockHasCopyDispose, const llvm::StructType *T, - std::vector<HelperInfo> &NoteForHelper) { + std::vector<HelperInfo> *NoteForHelperp) { QualType R = getContext().VoidTy; FunctionArgList Args; @@ -752,31 +751,36 @@ GenerateCopyHelperFunction(bool BlockHasCopyDispose, const llvm::StructType *T, llvm::Value *SrcObj = CGF.GetAddrOfLocalVar(Src); llvm::Type *PtrPtrT; - PtrPtrT = llvm::PointerType::get(llvm::PointerType::get(T, 0), 0); - SrcObj = Builder.CreateBitCast(SrcObj, PtrPtrT); - SrcObj = Builder.CreateLoad(SrcObj); - - llvm::Value *DstObj = CGF.GetAddrOfLocalVar(Dst); - DstObj = Builder.CreateBitCast(DstObj, llvm::PointerType::get(T, 0)); - - for (unsigned i=0; i < NoteForHelper.size(); ++i) { - int flag = NoteForHelper[i].flag; - int index = NoteForHelper[i].index; - - if ((NoteForHelper[i].flag & BLOCK_FIELD_IS_BYREF) - || NoteForHelper[i].RequiresCopying) { - llvm::Value *Srcv = SrcObj; - Srcv = Builder.CreateStructGEP(Srcv, index); - Srcv = Builder.CreateBitCast(Srcv, - llvm::PointerType::get(PtrToInt8Ty, 0)); - Srcv = Builder.CreateLoad(Srcv); - - llvm::Value *Dstv = Builder.CreateStructGEP(DstObj, index); - Dstv = Builder.CreateBitCast(Dstv, PtrToInt8Ty); - - llvm::Value *N = llvm::ConstantInt::get(llvm::Type::Int32Ty, flag); - llvm::Value *F = getBlockObjectAssign(); - Builder.CreateCall3(F, Dstv, Srcv, N); + + if (NoteForHelperp) { + std::vector<HelperInfo> &NoteForHelper = *NoteForHelperp; + + PtrPtrT = llvm::PointerType::get(llvm::PointerType::get(T, 0), 0); + SrcObj = Builder.CreateBitCast(SrcObj, PtrPtrT); + SrcObj = Builder.CreateLoad(SrcObj); + + llvm::Value *DstObj = CGF.GetAddrOfLocalVar(Dst); + DstObj = Builder.CreateBitCast(DstObj, llvm::PointerType::get(T, 0)); + + for (unsigned i=0; i < NoteForHelper.size(); ++i) { + int flag = NoteForHelper[i].flag; + int index = NoteForHelper[i].index; + + if ((NoteForHelper[i].flag & BLOCK_FIELD_IS_BYREF) + || NoteForHelper[i].RequiresCopying) { + llvm::Value *Srcv = SrcObj; + Srcv = Builder.CreateStructGEP(Srcv, index); + Srcv = Builder.CreateBitCast(Srcv, + llvm::PointerType::get(PtrToInt8Ty, 0)); + Srcv = Builder.CreateLoad(Srcv); + + llvm::Value *Dstv = Builder.CreateStructGEP(DstObj, index); + Dstv = Builder.CreateBitCast(Dstv, PtrToInt8Ty); + + llvm::Value *N = llvm::ConstantInt::get(llvm::Type::Int32Ty, flag); + llvm::Value *F = getBlockObjectAssign(); + Builder.CreateCall3(F, Dstv, Srcv, N); + } } } @@ -788,7 +792,7 @@ GenerateCopyHelperFunction(bool BlockHasCopyDispose, const llvm::StructType *T, llvm::Constant *BlockFunction:: GenerateDestroyHelperFunction(bool BlockHasCopyDispose, const llvm::StructType* T, - std::vector<HelperInfo> &NoteForHelper) { + std::vector<HelperInfo> *NoteForHelperp) { QualType R = getContext().VoidTy; FunctionArgList Args; @@ -821,25 +825,29 @@ GenerateDestroyHelperFunction(bool BlockHasCopyDispose, true); CGF.StartFunction(FD, R, Fn, Args, SourceLocation()); - llvm::Value *SrcObj = CGF.GetAddrOfLocalVar(Src); - llvm::Type *PtrPtrT; - PtrPtrT = llvm::PointerType::get(llvm::PointerType::get(T, 0), 0); - SrcObj = Builder.CreateBitCast(SrcObj, PtrPtrT); - SrcObj = Builder.CreateLoad(SrcObj); - - for (unsigned i=0; i < NoteForHelper.size(); ++i) { - int flag = NoteForHelper[i].flag; - int index = NoteForHelper[i].index; - - if ((NoteForHelper[i].flag & BLOCK_FIELD_IS_BYREF) - || NoteForHelper[i].RequiresCopying) { - llvm::Value *Srcv = SrcObj; - Srcv = Builder.CreateStructGEP(Srcv, index); - Srcv = Builder.CreateBitCast(Srcv, - llvm::PointerType::get(PtrToInt8Ty, 0)); - Srcv = Builder.CreateLoad(Srcv); - - BuildBlockRelease(Srcv, flag); + if (NoteForHelperp) { + std::vector<HelperInfo> &NoteForHelper = *NoteForHelperp; + + llvm::Value *SrcObj = CGF.GetAddrOfLocalVar(Src); + llvm::Type *PtrPtrT; + PtrPtrT = llvm::PointerType::get(llvm::PointerType::get(T, 0), 0); + SrcObj = Builder.CreateBitCast(SrcObj, PtrPtrT); + SrcObj = Builder.CreateLoad(SrcObj); + + for (unsigned i=0; i < NoteForHelper.size(); ++i) { + int flag = NoteForHelper[i].flag; + int index = NoteForHelper[i].index; + + if ((NoteForHelper[i].flag & BLOCK_FIELD_IS_BYREF) + || NoteForHelper[i].RequiresCopying) { + llvm::Value *Srcv = SrcObj; + Srcv = Builder.CreateStructGEP(Srcv, index); + Srcv = Builder.CreateBitCast(Srcv, + llvm::PointerType::get(PtrToInt8Ty, 0)); + Srcv = Builder.CreateLoad(Srcv); + + BuildBlockRelease(Srcv, flag); + } } } @@ -849,15 +857,15 @@ GenerateDestroyHelperFunction(bool BlockHasCopyDispose, } llvm::Constant *BlockFunction::BuildCopyHelper(const llvm::StructType *T, - std::vector<HelperInfo> &NoteForHelper) { + std::vector<HelperInfo> *NoteForHelper) { return CodeGenFunction(CGM).GenerateCopyHelperFunction(BlockHasCopyDispose, T, NoteForHelper); } llvm::Constant *BlockFunction::BuildDestroyHelper(const llvm::StructType *T, - std::vector<HelperInfo> &NoteForHelper) { + std::vector<HelperInfo> *NoteForHelperp) { return CodeGenFunction(CGM).GenerateDestroyHelperFunction(BlockHasCopyDispose, - T, NoteForHelper); + T, NoteForHelperp); } llvm::Constant *BlockFunction:: diff --git a/lib/CodeGen/CGBlocks.h b/lib/CodeGen/CGBlocks.h index 3eca891289..58276c294d 100644 --- a/lib/CodeGen/CGBlocks.h +++ b/lib/CodeGen/CGBlocks.h @@ -183,14 +183,14 @@ public: ImplicitParamDecl *getBlockStructDecl() { return BlockStructDecl; } llvm::Constant *GenerateCopyHelperFunction(bool, const llvm::StructType *, - std::vector<HelperInfo> &); + std::vector<HelperInfo> *); llvm::Constant *GenerateDestroyHelperFunction(bool, const llvm::StructType *, - std::vector<HelperInfo> &); + std::vector<HelperInfo> *); llvm::Constant *BuildCopyHelper(const llvm::StructType *, - std::vector<HelperInfo> &); + std::vector<HelperInfo> *); llvm::Constant *BuildDestroyHelper(const llvm::StructType *, - std::vector<HelperInfo> &); + std::vector<HelperInfo> *); llvm::Constant *GeneratebyrefCopyHelperFunction(const llvm::Type *, int flag); llvm::Constant *GeneratebyrefDestroyHelperFunction(const llvm::Type *T, int); diff --git a/test/CodeGen/blocks-1.c b/test/CodeGen/blocks-1.c index f2677f3c27..10498cb004 100644 --- a/test/CodeGen/blocks-1.c +++ b/test/CodeGen/blocks-1.c @@ -1,11 +1,11 @@ // RUN: clang-cc %s -emit-llvm -o %t -fblocks && -// RUN: grep "_Block_object_dispose" %t | count 15 && -// RUN: grep "__copy_helper_block_" %t | count 12 && -// RUN: grep "__destroy_helper_block_" %t | count 12 && +// RUN: grep "_Block_object_dispose" %t | count 17 && +// RUN: grep "__copy_helper_block_" %t | count 16 && +// RUN: grep "__destroy_helper_block_" %t | count 16 && // RUN: grep "__Block_byref_id_object_copy_" %t | count 2 && // RUN: grep "__Block_byref_id_object_dispose_" %t | count 2 && // RUN: grep "i32 135)" %t | count 2 && -// RUN: grep "_Block_object_assign" %t | count 9 +// RUN: grep "_Block_object_assign" %t | count 10 #include <stdio.h> @@ -57,7 +57,14 @@ void test5() { void test6() { __block int i; ^{ i=1; }(); - ^{}; + ^{}(); +} + +void test7() { + ^{ + __block int i; + ^{ i = 1; }(); + }(); } int main() { |