diff options
author | Akira Hatanaka <ahatanaka@apple.com> | 2017-02-14 06:46:55 +0000 |
---|---|---|
committer | Akira Hatanaka <ahatanaka@apple.com> | 2017-02-14 06:46:55 +0000 |
commit | f1b3fc73562d726b3bc23a8e7496d1544a80b47f (patch) | |
tree | 57509e4051a74ac39ff8e9e53ffab519e677cdc6 /clang/lib/CodeGen/CGBlocks.cpp | |
parent | ece84cd10c68f98c18bda52be4e178b2493f7ece (diff) | |
download | bcm5719-llvm-f1b3fc73562d726b3bc23a8e7496d1544a80b47f.tar.gz bcm5719-llvm-f1b3fc73562d726b3bc23a8e7496d1544a80b47f.zip |
[CodeGen][ObjC] Use the type of the captured field of the enclosing
block or lambda.
This is a follow-up to r281682, which fixed a bug in computeBlockInfo
where the captured VarDecl's type, rather than the captured field type
of the enclosing lambda or block, was used to compute the layout of a
block.
This commit makes similar changes to enterBlockScope. This is necessary
to correctly determine whether a block capture requires cleanup.
rdar://problem/30388124
llvm-svn: 295034
Diffstat (limited to 'clang/lib/CodeGen/CGBlocks.cpp')
-rw-r--r-- | clang/lib/CodeGen/CGBlocks.cpp | 29 |
1 files changed, 17 insertions, 12 deletions
diff --git a/clang/lib/CodeGen/CGBlocks.cpp b/clang/lib/CodeGen/CGBlocks.cpp index 53288a69e2d..ff4480c0d6a 100644 --- a/clang/lib/CodeGen/CGBlocks.cpp +++ b/clang/lib/CodeGen/CGBlocks.cpp @@ -318,6 +318,19 @@ static void initializeForBlockHeader(CodeGenModule &CGM, CGBlockInfo &info, elementTypes.push_back(CGM.getBlockDescriptorType()); } +static QualType getCaptureFieldType(const CodeGenFunction &CGF, + const BlockDecl::Capture &CI) { + const VarDecl *VD = CI.getVariable(); + + // If the variable is captured by an enclosing block or lambda expression, + // use the type of the capture field. + if (CGF.BlockInfo && CI.isNested()) + return CGF.BlockInfo->getCapture(VD).fieldType(); + if (auto *FD = CGF.LambdaCaptureFields.lookup(VD)) + return FD->getType(); + return VD->getType(); +} + /// Compute the layout of the given block. Attempts to lay the block /// out with minimal space requirements. static void computeBlockInfo(CodeGenModule &CGM, CodeGenFunction *CGF, @@ -432,15 +445,7 @@ static void computeBlockInfo(CodeGenModule &CGM, CodeGenFunction *CGF, } } - QualType VT = variable->getType(); - - // If the variable is captured by an enclosing block or lambda expression, - // use the type of the capture field. - if (CGF->BlockInfo && CI.isNested()) - VT = CGF->BlockInfo->getCapture(variable).fieldType(); - else if (auto *FD = CGF->LambdaCaptureFields.lookup(variable)) - VT = FD->getType(); - + QualType VT = getCaptureFieldType(*CGF, CI); CharUnits size = C.getTypeSizeInChars(VT); CharUnits align = C.getDeclAlign(variable); @@ -606,8 +611,8 @@ static void enterBlockScope(CodeGenFunction &CGF, BlockDecl *block) { if (capture.isConstant()) continue; // Ignore objects that aren't destructed. - QualType::DestructionKind dtorKind = - variable->getType().isDestructedType(); + QualType VT = getCaptureFieldType(CGF, CI); + QualType::DestructionKind dtorKind = VT.isDestructedType(); if (dtorKind == QualType::DK_none) continue; CodeGenFunction::Destroyer *destroyer; @@ -634,7 +639,7 @@ static void enterBlockScope(CodeGenFunction &CGF, BlockDecl *block) { if (useArrayEHCleanup) cleanupKind = InactiveNormalAndEHCleanup; - CGF.pushDestroy(cleanupKind, addr, variable->getType(), + CGF.pushDestroy(cleanupKind, addr, VT, destroyer, useArrayEHCleanup); // Remember where that cleanup was. |