aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGDecl.cpp
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2011-02-18 02:58:31 +0000
committerJohn McCall <rjmccall@apple.com>2011-02-18 02:58:31 +0000
commit0d3c985ad5b07121149957e5993cf1e3df26a413 (patch)
tree4f69ecb9ac890652811517653db350a93dcc24c2 /lib/CodeGen/CGDecl.cpp
parentf58483268995daef120529687813a6c5340ff09d (diff)
The flags we're supposed to write into a byref struct are *not* the
_Block_object_* flags; it's just BLOCK_HAS_COPY_DISPOSE or not. Also, we don't need to chase forwarding pointers prior to calling _Block_object_dispose; _Block_object_dispose in fact already does this. rdar://problem/9006315 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@125823 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGDecl.cpp')
-rw-r--r--lib/CodeGen/CGDecl.cpp25
1 files changed, 13 insertions, 12 deletions
diff --git a/lib/CodeGen/CGDecl.cpp b/lib/CodeGen/CGDecl.cpp
index 22f28197c6..a87dfaed9d 100644
--- a/lib/CodeGen/CGDecl.cpp
+++ b/lib/CodeGen/CGDecl.cpp
@@ -504,9 +504,7 @@ namespace {
CallBlockRelease(llvm::Value *Addr) : Addr(Addr) {}
void Emit(CodeGenFunction &CGF, bool IsForEH) {
- llvm::Value *V = CGF.Builder.CreateStructGEP(Addr, 1, "forwarding");
- V = CGF.Builder.CreateLoad(V);
- CGF.BuildBlockRelease(V, BLOCK_FIELD_IS_BYREF);
+ CGF.BuildBlockRelease(Addr, BLOCK_FIELD_IS_BYREF);
}
};
}
@@ -743,10 +741,6 @@ void CodeGenFunction::EmitAutoVarDecl(const VarDecl &D,
if (isByRef) {
EnsureInsertPoint();
- llvm::Value *isa_field = Builder.CreateStructGEP(DeclPtr, 0);
- llvm::Value *forwarding_field = Builder.CreateStructGEP(DeclPtr, 1);
- llvm::Value *flags_field = Builder.CreateStructGEP(DeclPtr, 2);
- llvm::Value *size_field = Builder.CreateStructGEP(DeclPtr, 3);
llvm::Value *V;
BlockFieldFlags fieldFlags;
@@ -776,16 +770,23 @@ void CodeGenFunction::EmitAutoVarDecl(const VarDecl &D,
if (fieldFlags & BLOCK_FIELD_IS_WEAK)
isa = 1;
V = Builder.CreateIntToPtr(Builder.getInt32(isa), Int8PtrTy, "isa");
- Builder.CreateStore(V, isa_field);
+ Builder.CreateStore(V, Builder.CreateStructGEP(DeclPtr, 0, "byref.isa"));
- Builder.CreateStore(DeclPtr, forwarding_field);
+ Builder.CreateStore(DeclPtr, Builder.CreateStructGEP(DeclPtr, 1,
+ "byref.forwarding"));
- Builder.CreateStore(Builder.getInt32(fieldFlags.getBitMask()), flags_field);
+ // Blocks ABI:
+ // c) the flags field is set to either 0 if no helper functions are
+ // needed or BLOCK_HAS_COPY_DISPOSE if they are,
+ BlockFlags flags;
+ if (fieldNeedsCopyDispose) flags |= BLOCK_HAS_COPY_DISPOSE;
+ Builder.CreateStore(llvm::ConstantInt::get(IntTy, flags.getBitMask()),
+ Builder.CreateStructGEP(DeclPtr, 2, "byref.flags"));
const llvm::Type *V1;
V1 = cast<llvm::PointerType>(DeclPtr->getType())->getElementType();
- V = Builder.getInt32(CGM.GetTargetTypeStoreSize(V1).getQuantity());
- Builder.CreateStore(V, size_field);
+ V = llvm::ConstantInt::get(IntTy, CGM.GetTargetTypeStoreSize(V1).getQuantity());
+ Builder.CreateStore(V, Builder.CreateStructGEP(DeclPtr, 3, "byref.size"));
if (fieldNeedsCopyDispose) {
llvm::Value *copy_helper = Builder.CreateStructGEP(DeclPtr, 4);