diff options
| author | Mike Stump <mrs@apple.com> | 2009-02-28 09:07:16 +0000 |
|---|---|---|
| committer | Mike Stump <mrs@apple.com> | 2009-02-28 09:07:16 +0000 |
| commit | a99038c0757a836c6faeeddaa5dfd249b32f6e9e (patch) | |
| tree | 86ec44cc788dc21f42c1edebf26e0311bad1602b /lib/CodeGen/CGExpr.cpp | |
| parent | 709fa15defbc0208b33707b3da3a628df5a9b7b9 (diff) | |
First cut CodeGen support for __block variables.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@65688 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGExpr.cpp')
| -rw-r--r-- | lib/CodeGen/CGExpr.cpp | 37 |
1 files changed, 36 insertions, 1 deletions
diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index e353ab49c3..7e8eff3847 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -151,6 +151,9 @@ LValue CodeGenFunction::EmitLValue(const Expr *E) { case Expr::ObjCEncodeExprClass: return EmitObjCEncodeExprLValue(cast<ObjCEncodeExpr>(E)); + case Expr::BlockDeclRefExprClass: + return EmitBlockDeclRefLValue(cast<BlockDeclRefExpr>(E)); + case Expr::CXXConditionDeclExprClass: return EmitCXXConditionDeclLValue(cast<CXXConditionDeclExpr>(E)); @@ -627,7 +630,7 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) { } else { llvm::Value *V = LocalDeclMap[VD]; - assert(V && "BlockVarDecl not entered in LocalDeclMap?"); + assert(V && "DeclRefExpr not entered in LocalDeclMap?"); // local variables do not get their gc attribute set. QualType::GCAttrTypes attr = QualType::GCNone; // local static? @@ -660,6 +663,38 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) { return LValue(); } +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()); + + // 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) |
