Fixup codegen for nested blocks that use copy/dispose in the inner

blocks, so that the outer blocks use it as well.  Radar 6762279

llvm-svn: 68811
This commit is contained in:
Mike Stump 2009-04-10 18:52:28 +00:00
parent f074ca7454
commit 6764593098
3 changed files with 68 additions and 53 deletions

View File

@ -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,6 +751,10 @@ GenerateCopyHelperFunction(bool BlockHasCopyDispose, const llvm::StructType *T,
llvm::Value *SrcObj = CGF.GetAddrOfLocalVar(Src);
llvm::Type *PtrPtrT;
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);
@ -779,6 +782,7 @@ GenerateCopyHelperFunction(bool BlockHasCopyDispose, const llvm::StructType *T,
Builder.CreateCall3(F, Dstv, Srcv, N);
}
}
}
CGF.FinishFunction();
@ -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,6 +825,9 @@ GenerateDestroyHelperFunction(bool BlockHasCopyDispose,
true);
CGF.StartFunction(FD, R, Fn, Args, SourceLocation());
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);
@ -842,6 +849,7 @@ GenerateDestroyHelperFunction(bool BlockHasCopyDispose,
BuildBlockRelease(Srcv, flag);
}
}
}
CGF.FinishFunction();
@ -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::

View File

@ -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);

View File

@ -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() {