aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGBlocks.cpp
diff options
context:
space:
mode:
authorEli Friedman <eli.friedman@gmail.com>2012-02-25 02:48:22 +0000
committerEli Friedman <eli.friedman@gmail.com>2012-02-25 02:48:22 +0000
commit64bee65a3436e3f0c352fcfe2130676f3502cffe (patch)
tree9154d934a177c762072a49a0fa5d0813c37c780a /lib/CodeGen/CGBlocks.cpp
parente1d4330adaaa7faf093e725c9c993207eb2d778a (diff)
Work-in-progress for lambda conversion-to-block operator. Still need to implement the retain+autorelease outside of ARC, and there's a bug that causes the generated code to crash in ARC (which I think is unrelated to my code, although I'm not completely sure).
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@151428 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGBlocks.cpp')
-rw-r--r--lib/CodeGen/CGBlocks.cpp19
1 files changed, 15 insertions, 4 deletions
diff --git a/lib/CodeGen/CGBlocks.cpp b/lib/CodeGen/CGBlocks.cpp
index a91a34153f..f6aa9b4b48 100644
--- a/lib/CodeGen/CGBlocks.cpp
+++ b/lib/CodeGen/CGBlocks.cpp
@@ -624,7 +624,8 @@ llvm::Value *CodeGenFunction::EmitBlockLiteral(const CGBlockInfo &blockInfo) {
// Using the computed layout, generate the actual block function.
llvm::Constant *blockFn
= CodeGenFunction(CGM).GenerateBlockFunction(CurGD, blockInfo,
- CurFuncDecl, LocalDeclMap);
+ CurFuncDecl, LocalDeclMap,
+ InLambdaConversionToBlock);
blockFn = llvm::ConstantExpr::getBitCast(blockFn, VoidPtrTy);
// If there is nothing to capture, we can emit this as a global block.
@@ -699,6 +700,11 @@ llvm::Value *CodeGenFunction::EmitBlockLiteral(const CGBlockInfo &blockInfo) {
src = Builder.CreateStructGEP(LoadBlockStruct(),
enclosingCapture.getIndex(),
"block.capture.addr");
+ } else if (InLambdaConversionToBlock) {
+ // The lambda capture in a lambda's conversion-to-block-pointer is
+ // special; we know its argument is an lvalue we can simply emit.
+ CXXConstructExpr *CE = cast<CXXConstructExpr>(ci->getCopyExpr());
+ src = EmitLValue(CE->getArg(0)).getAddress();
} else {
// This is a [[type]]*.
src = LocalDeclMap[variable];
@@ -921,7 +927,8 @@ CodeGenModule::GetAddrOfGlobalBlock(const BlockExpr *blockExpr,
llvm::DenseMap<const Decl*, llvm::Value*> LocalDeclMap;
blockFn = CodeGenFunction(*this).GenerateBlockFunction(GlobalDecl(),
blockInfo,
- 0, LocalDeclMap);
+ 0, LocalDeclMap,
+ false);
}
blockFn = llvm::ConstantExpr::getBitCast(blockFn, VoidPtrTy);
@@ -975,7 +982,8 @@ llvm::Function *
CodeGenFunction::GenerateBlockFunction(GlobalDecl GD,
const CGBlockInfo &blockInfo,
const Decl *outerFnDecl,
- const DeclMapTy &ldm) {
+ const DeclMapTy &ldm,
+ bool IsLambdaConversionToBlock) {
const BlockDecl *blockDecl = blockInfo.getBlockDecl();
// Check if we should generate debug info for this block function.
@@ -1092,7 +1100,10 @@ CodeGenFunction::GenerateBlockFunction(GlobalDecl GD,
llvm::BasicBlock::iterator entry_ptr = Builder.GetInsertPoint();
--entry_ptr;
- EmitStmt(blockDecl->getBody());
+ if (IsLambdaConversionToBlock)
+ EmitLambdaBlockInvokeBody();
+ else
+ EmitStmt(blockDecl->getBody());
// Remember where we were...
llvm::BasicBlock *resume = Builder.GetInsertBlock();