aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGExpr.cpp
diff options
context:
space:
mode:
authorMike Stump <mrs@apple.com>2009-03-04 03:23:46 +0000
committerMike Stump <mrs@apple.com>2009-03-04 03:23:46 +0000
commitdab514fc30242c7afd6c03956e46136c400fb0d3 (patch)
tree4e0b95fba8f049e941f13a488596abf18a08d77a /lib/CodeGen/CGExpr.cpp
parent41168eac256fed59ec5406a75fce91c59cd5dd91 (diff)
Improved ABI compliance for __block variables. No testcases yet as we
still give an unsupported error for them due to the fact this is a work in progress. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@66007 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGExpr.cpp')
-rw-r--r--lib/CodeGen/CGExpr.cpp50
1 files changed, 11 insertions, 39 deletions
diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp
index 5485e9eb1f..d54c6954fb 100644
--- a/lib/CodeGen/CGExpr.cpp
+++ b/lib/CodeGen/CGExpr.cpp
@@ -636,6 +636,17 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {
// local static?
if (!VD->hasLocalStorage())
attr = getContext().getObjCGCAttrKind(E->getType());
+ if (VD->getAttr<BlocksAttr>()) {
+ bool needsCopyDispose = BlockRequiresCopying(VD->getType());
+ const llvm::Type *PtrStructTy = V->getType();
+ const llvm::Type *Ty = PtrStructTy;
+ Ty = llvm::PointerType::get(Ty, 0);
+ V = Builder.CreateStructGEP(V, 1, "forwarding");
+ V = Builder.CreateBitCast(V, Ty);
+ V = Builder.CreateLoad(V, false);
+ V = Builder.CreateBitCast(V, PtrStructTy);
+ V = Builder.CreateStructGEP(V, needsCopyDispose*2 + 4, "x");
+ }
LV = LValue::MakeAddr(V, E->getType().getCVRQualifiers(), attr);
}
LValue::SetObjCNonGC(LV, VD->hasLocalStorage());
@@ -667,45 +678,6 @@ LValue CodeGenFunction::EmitBlockDeclRefLValue(const BlockDeclRefExpr *E) {
return LValue::MakeAddr(GetAddrOfBlockDecl(E), 0);
}
-llvm::Value *CodeGenFunction::GetAddrOfBlockDecl(const BlockDeclRefExpr *E) {
- // FIXME: ensure we don't need copy/dispose.
- uint64_t &offset = BlockDecls[E->getDecl()];
-
- const llvm::Type *Ty;
- Ty = CGM.getTypes().ConvertType(E->getDecl()->getType());
-
- if (E->isByRef())
- ErrorUnsupported(E, "__block variable in block literal");
- else if (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()))
- ErrorUnsupported(E, "Objective-C variable in block literal");
-
- // See if we have already allocated an offset for this variable.
- if (offset == 0) {
- // if not, allocate one now.
- offset = getBlockOffset(E);
- }
-
- llvm::Value *BlockLiteral = LoadBlockStruct();
- llvm::Value *V = Builder.CreateGEP(BlockLiteral,
- llvm::ConstantInt::get(llvm::Type::Int64Ty,
- offset),
- "tmp");
- Ty = llvm::PointerType::get(Ty, 0);
- if (E->isByRef())
- Ty = llvm::PointerType::get(Ty, 0);
- V = Builder.CreateBitCast(V, Ty);
- if (E->isByRef())
- V = Builder.CreateLoad(V, false, "tmp");
-
- return V;
-}
-
LValue CodeGenFunction::EmitUnaryOpLValue(const UnaryOperator *E) {
// __extension__ doesn't affect lvalue-ness.
if (E->getOpcode() == UnaryOperator::Extension)