diff options
author | Mike Stump <mrs@apple.com> | 2009-03-06 01:33:24 +0000 |
---|---|---|
committer | Mike Stump <mrs@apple.com> | 2009-03-06 01:33:24 +0000 |
commit | a4f668f3b7e03629066a01b04e415cb2b4655daf (patch) | |
tree | e22535785d1ecd2de960f56386df0fae16c12543 | |
parent | b67db99d58c0a09a5a0ec336be5854451df6df8c (diff) |
Framework for codegen for copy/dispose helpers.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@66231 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/CodeGen/CGBlocks.cpp | 96 | ||||
-rw-r--r-- | lib/CodeGen/CGBlocks.h | 12 | ||||
-rw-r--r-- | lib/CodeGen/CGDecl.cpp | 4 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenFunction.cpp | 3 | ||||
-rw-r--r-- | test/CodeGen/blocks-1.c | 10 |
5 files changed, 103 insertions, 22 deletions
diff --git a/lib/CodeGen/CGBlocks.cpp b/lib/CodeGen/CGBlocks.cpp index 82ac86aaa3..a792537ea9 100644 --- a/lib/CodeGen/CGBlocks.cpp +++ b/lib/CodeGen/CGBlocks.cpp @@ -465,13 +465,13 @@ llvm::Value *CodeGenFunction::GetAddrOfBlockDecl(const BlockDeclRefExpr *E) { // FIXME: add support for copy/dispose helpers. if (!Enable__block && E->isByRef()) ErrorUnsupported(E, "__block variable in block literal"); - else if (E->getType()->isBlockPointerType()) + else if (!Enable__block && E->getType()->isBlockPointerType()) ErrorUnsupported(E, "block pointer in block literal"); else if (E->getDecl()->getAttr<ObjCNSObjectAttr>() || getContext().isObjCNSObjectType(E->getType())) ErrorUnsupported(E, "__attribute__((NSObject)) variable in block " "literal"); - else if (getContext().isObjCObjectPointerType(E->getType())) + else if (!Enable__block && getContext().isObjCObjectPointerType(E->getType())) ErrorUnsupported(E, "Objective-C variable in block literal"); // See if we have already allocated an offset for this variable. @@ -677,20 +677,88 @@ uint64_t CodeGenFunction::getBlockOffset(const BlockDeclRefExpr *BDRE) { return BlockOffset-Size; } -llvm::Value *BlockFunction::BuildCopyHelper(int flag) { - // FIXME: implement - llvm::Value *V = llvm::ConstantInt::get(llvm::Type::Int32Ty, 43); - V = Builder.CreateIntToPtr(V, PtrToInt8Ty, "tmp"); - V = Builder.CreateBitCast(V, PtrToInt8Ty, "tmp"); - return V; +llvm::Constant *BlockFunction::GenerateCopyHelperFunction() { + 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("__copy_helper_block_"); + 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("__copy_helper_block_"); + + 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::Value *BlockFunction::BuildDestroyHelper(int flag) { - // FIXME: implement - llvm::Value *V = llvm::ConstantInt::get(llvm::Type::Int32Ty, 44); - V = Builder.CreateIntToPtr(V, PtrToInt8Ty, "tmp"); - V = Builder.CreateBitCast(V, PtrToInt8Ty, "tmp"); - return V; +llvm::Constant *BlockFunction::GenerateDestroyHelperFunction() { + 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("__destroy_helper_block_"); + 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("__destroy_helper_block_"); + + 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::BuildCopyHelper(int flag) { + return CodeGenFunction(CGM).GenerateCopyHelperFunction(); +} + +llvm::Constant *BlockFunction::BuildDestroyHelper(int flag) { + return CodeGenFunction(CGM).GenerateDestroyHelperFunction(); } llvm::Value *BlockFunction::getBlockObjectDispose() { diff --git a/lib/CodeGen/CGBlocks.h b/lib/CodeGen/CGBlocks.h index 24b0cc9e5b..84ad190d6f 100644 --- a/lib/CodeGen/CGBlocks.h +++ b/lib/CodeGen/CGBlocks.h @@ -110,6 +110,7 @@ public: class BlockFunction : public BlockBase { CodeGenModule &CGM; + CodeGenFunction &CGF; ASTContext &getContext() const; public: @@ -148,16 +149,19 @@ public: CGBuilderTy &Builder; - BlockFunction(CodeGenModule &cgm, CGBuilderTy &B) - : CGM(cgm), Builder(B) { + BlockFunction(CodeGenModule &cgm, CodeGenFunction &cgf, CGBuilderTy &B) + : CGM(cgm), CGF(cgf), Builder(B) { PtrToInt8Ty = llvm::PointerType::getUnqual(llvm::Type::Int8Ty); } ImplicitParamDecl *BlockStructDecl; ImplicitParamDecl *getBlockStructDecl() { return BlockStructDecl; } - llvm::Value *BuildCopyHelper(int flag); - llvm::Value *BuildDestroyHelper(int flag); + llvm::Constant *GenerateCopyHelperFunction(); + llvm::Constant *GenerateDestroyHelperFunction(); + + llvm::Constant *BuildCopyHelper(int flag); + llvm::Constant *BuildDestroyHelper(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 e750d8a8d5..2b995d150c 100644 --- a/lib/CodeGen/CGDecl.cpp +++ b/lib/CodeGen/CGDecl.cpp @@ -354,10 +354,10 @@ void CodeGenFunction::EmitLocalBlockVarDecl(const VarDecl &D) { if (flag&BLOCK_FIELD_IS_WEAK) isa = 1; V = llvm::ConstantInt::get(llvm::Type::Int32Ty, isa); - V = Builder.CreateIntToPtr(V, PtrToInt8Ty, "tmp"); + V = Builder.CreateIntToPtr(V, PtrToInt8Ty, "isa"); Builder.CreateStore(V, isa_field); - V = Builder.CreateBitCast(DeclPtr, PtrToInt8Ty, "tmp"); + V = Builder.CreateBitCast(DeclPtr, PtrToInt8Ty, "forwarding"); Builder.CreateStore(V, forwarding_field); V = llvm::ConstantInt::get(llvm::Type::Int32Ty, flags); diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp index b8e01029f7..adeb4ebfd4 100644 --- a/lib/CodeGen/CodeGenFunction.cpp +++ b/lib/CodeGen/CodeGenFunction.cpp @@ -24,7 +24,8 @@ using namespace clang; using namespace CodeGen; CodeGenFunction::CodeGenFunction(CodeGenModule &cgm) - : BlockFunction(cgm, Builder), CGM(cgm), Target(CGM.getContext().Target), + : BlockFunction(cgm, *this, Builder), CGM(cgm), + Target(CGM.getContext().Target), DebugInfo(0), SwitchInsn(0), CaseRangeBlock(0), InvokeDest(0) { LLVMIntTy = ConvertType(getContext().IntTy); LLVMPointerWidth = Target.getPointerWidth(0); diff --git a/test/CodeGen/blocks-1.c b/test/CodeGen/blocks-1.c index c397185e88..4a602e27d3 100644 --- a/test/CodeGen/blocks-1.c +++ b/test/CodeGen/blocks-1.c @@ -1,5 +1,7 @@ // RUN: clang %s -emit-llvm -o %t -fblocks -f__block && -// RUN: grep "_Block_object_dispose" %t | count 3 +// RUN: grep "_Block_object_dispose" %t | count 4 +// RUN: grep "__copy_helper_block_" %t | count 2 +// RUN: grep "__destroy_helper_block_" %t | count 2 #include <stdio.h> void test1() { @@ -28,8 +30,14 @@ void test2() { printf("a is %d\n", a); } +void test3() { + __block int (^j)(int); + ^{j=0;}(); +} + int main() { test1(); test2(); + test3(); return 0; } |