aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGExpr.cpp
diff options
context:
space:
mode:
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)