diff options
author | Mike Stump <mrs@apple.com> | 2009-03-04 03:23:46 +0000 |
---|---|---|
committer | Mike Stump <mrs@apple.com> | 2009-03-04 03:23:46 +0000 |
commit | dab514fc30242c7afd6c03956e46136c400fb0d3 (patch) | |
tree | 4e0b95fba8f049e941f13a488596abf18a08d77a /lib/CodeGen/CGExpr.cpp | |
parent | 41168eac256fed59ec5406a75fce91c59cd5dd91 (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.cpp | 50 |
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) |