diff options
Diffstat (limited to 'lib/CodeGen')
-rw-r--r-- | lib/CodeGen/CGBlocks.cpp | 24 | ||||
-rw-r--r-- | lib/CodeGen/CGClass.cpp | 2 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenFunction.cpp | 3 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenFunction.h | 1 |
4 files changed, 19 insertions, 11 deletions
diff --git a/lib/CodeGen/CGBlocks.cpp b/lib/CodeGen/CGBlocks.cpp index f6aa9b4b48..1b35fa0ee4 100644 --- a/lib/CodeGen/CGBlocks.cpp +++ b/lib/CodeGen/CGBlocks.cpp @@ -622,10 +622,11 @@ llvm::Value *CodeGenFunction::EmitBlockLiteral(const BlockExpr *blockExpr) { llvm::Value *CodeGenFunction::EmitBlockLiteral(const CGBlockInfo &blockInfo) { // Using the computed layout, generate the actual block function. + bool isLambdaConv = blockInfo.getBlockDecl()->isConversionFromLambda(); llvm::Constant *blockFn = CodeGenFunction(CGM).GenerateBlockFunction(CurGD, blockInfo, CurFuncDecl, LocalDeclMap, - InLambdaConversionToBlock); + isLambdaConv); blockFn = llvm::ConstantExpr::getBitCast(blockFn, VoidPtrTy); // If there is nothing to capture, we can emit this as a global block. @@ -700,11 +701,10 @@ llvm::Value *CodeGenFunction::EmitBlockLiteral(const CGBlockInfo &blockInfo) { src = Builder.CreateStructGEP(LoadBlockStruct(), enclosingCapture.getIndex(), "block.capture.addr"); - } else if (InLambdaConversionToBlock) { + } else if (blockDecl->isConversionFromLambda()) { // 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(); + // special; we'll simply emit it directly. + src = 0; } else { // This is a [[type]]*. src = LocalDeclMap[variable]; @@ -726,7 +726,19 @@ llvm::Value *CodeGenFunction::EmitBlockLiteral(const CGBlockInfo &blockInfo) { // If we have a copy constructor, evaluate that into the block field. } else if (const Expr *copyExpr = ci->getCopyExpr()) { - EmitSynthesizedCXXCopyCtor(blockField, src, copyExpr); + if (blockDecl->isConversionFromLambda()) { + // If we have a lambda conversion, emit the expression + // directly into the block instead. + CharUnits Align = getContext().getTypeAlignInChars(type); + AggValueSlot Slot = + AggValueSlot::forAddr(blockField, Align, Qualifiers(), + AggValueSlot::IsDestructed, + AggValueSlot::DoesNotNeedGCBarriers, + AggValueSlot::IsNotAliased); + EmitAggExpr(copyExpr, Slot); + } else { + EmitSynthesizedCXXCopyCtor(blockField, src, copyExpr); + } // If it's a reference variable, copy the reference into the block field. } else if (type->isReferenceType()) { diff --git a/lib/CodeGen/CGClass.cpp b/lib/CodeGen/CGClass.cpp index e3b5777387..6b5a149710 100644 --- a/lib/CodeGen/CGClass.cpp +++ b/lib/CodeGen/CGClass.cpp @@ -1795,9 +1795,7 @@ void CodeGenFunction::EmitLambdaToBlockPointerBody(FunctionArgList &Args) { return; } - InLambdaConversionToBlock = true; EmitFunctionBody(Args); - InLambdaConversionToBlock = false; } void CodeGenFunction::EmitLambdaDelegatingInvokeBody(const CXXMethodDecl *MD) { diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp index 5d18169695..47176bd8ec 100644 --- a/lib/CodeGen/CodeGenFunction.cpp +++ b/lib/CodeGen/CodeGenFunction.cpp @@ -32,8 +32,7 @@ CodeGenFunction::CodeGenFunction(CodeGenModule &cgm) Target(CGM.getContext().getTargetInfo()), Builder(cgm.getModule().getContext()), AutoreleaseResult(false), BlockInfo(0), BlockPointer(0), - LambdaThisCaptureField(0), InLambdaConversionToBlock(false), - NormalCleanupDest(0), NextCleanupDestIndex(1), + LambdaThisCaptureField(0), NormalCleanupDest(0), NextCleanupDestIndex(1), FirstBlockInfo(0), EHResumeBlock(0), ExceptionSlot(0), EHSelectorSlot(0), DebugInfo(0), DisableDebugInfo(false), DidCallStackSave(false), IndirectBranch(0), SwitchInsn(0), CaseRangeBlock(0), UnreachableBlock(0), diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index 42c9b7dc9b..7f39868dd9 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/lib/CodeGen/CodeGenFunction.h @@ -601,7 +601,6 @@ public: llvm::DenseMap<const VarDecl *, FieldDecl *> LambdaCaptureFields; FieldDecl *LambdaThisCaptureField; - bool InLambdaConversionToBlock; /// \brief A mapping from NRVO variables to the flags used to indicate /// when the NRVO has been applied to this variable. |