aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGExpr.cpp
diff options
context:
space:
mode:
authorMike Stump <mrs@apple.com>2009-02-28 09:07:16 +0000
committerMike Stump <mrs@apple.com>2009-02-28 09:07:16 +0000
commita99038c0757a836c6faeeddaa5dfd249b32f6e9e (patch)
tree86ec44cc788dc21f42c1edebf26e0311bad1602b /lib/CodeGen/CGExpr.cpp
parent709fa15defbc0208b33707b3da3a628df5a9b7b9 (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.cpp37
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)