First cut CodeGen support for __block variables.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@65688 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp
index e353ab4..7e8eff3 100644
--- a/lib/CodeGen/CGExpr.cpp
+++ b/lib/CodeGen/CGExpr.cpp
@@ -151,6 +151,9 @@
   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 @@
     }
     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 @@
   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)