Implements __block API for c++ objects. There is still
issue with runtime which I am discussing it with Blaine.
This is wip (so no test yet).


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@119368 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/CGBlocks.cpp b/lib/CodeGen/CGBlocks.cpp
index 2206e8a..e216646 100644
--- a/lib/CodeGen/CGBlocks.cpp
+++ b/lib/CodeGen/CGBlocks.cpp
@@ -1006,14 +1006,36 @@
           || NoteForHelper[i].RequiresCopying) {
         llvm::Value *Srcv = SrcObj;
         Srcv = Builder.CreateStructGEP(Srcv, index);
-        Srcv = Builder.CreateBitCast(Srcv,
-                                     llvm::PointerType::get(PtrToInt8Ty, 0));
-        llvm::Value *Dstv = Builder.CreateStructGEP(DstObj, index);
+        llvm::Value *Dstv;
         if (NoteForHelper[i].cxxvar_import) {
-          CGF.EmitSynthesizedCXXCopyCtor(Dstv, Srcv, 
-                                         NoteForHelper[i].cxxvar_import);
+          if (NoteForHelper[i].flag & BLOCK_FIELD_IS_BYREF) {
+            const ValueDecl *VD = NoteForHelper[i].cxxvar_import->getDecl();
+            const llvm::Type *PtrStructTy
+              = llvm::PointerType::get(CGF.BuildByRefType(VD), 0);
+            Srcv = Builder.CreateLoad(Srcv);
+            Srcv = Builder.CreateBitCast(Srcv, PtrStructTy);
+            Srcv = Builder.CreateStructGEP(Srcv, CGF.getByRefValueLLVMField(VD),
+                                        VD->getNameAsString());
+            Dstv = Builder.CreateStructGEP(DstObj, index);
+            Dstv = Builder.CreateLoad(Dstv);
+            Dstv = Builder.CreateBitCast(Dstv, PtrStructTy);
+            Dstv = Builder.CreateStructGEP(Dstv, CGF.getByRefValueLLVMField(VD),
+                                           VD->getNameAsString());
+            CGF.EmitSynthesizedCXXCopyCtor(Dstv, Srcv, 
+                                           NoteForHelper[i].cxxvar_import);
+          }
+          else {
+            Srcv = Builder.CreateBitCast(Srcv,
+                                         llvm::PointerType::get(PtrToInt8Ty, 0));
+            Dstv = Builder.CreateStructGEP(DstObj, index);
+            CGF.EmitSynthesizedCXXCopyCtor(Dstv, Srcv, 
+                                           NoteForHelper[i].cxxvar_import);
+          }
         }
         else {
+          Srcv = Builder.CreateBitCast(Srcv,
+                                       llvm::PointerType::get(PtrToInt8Ty, 0));
+          Dstv = Builder.CreateStructGEP(DstObj, index);
           Srcv = Builder.CreateLoad(Srcv);
           Dstv = Builder.CreateBitCast(Dstv, PtrToInt8Ty);
           llvm::Value *N = llvm::ConstantInt::get(CGF.Int32Ty, flag);
@@ -1091,6 +1113,17 @@
           QualType ClassTy = E->getType();
           QualType PtrClassTy = getContext().getPointerType(ClassTy);
           const llvm::Type *t = CGM.getTypes().ConvertType(PtrClassTy);
+          
+          if (NoteForHelper[i].flag & BLOCK_FIELD_IS_BYREF) {
+            const ValueDecl *VD = NoteForHelper[i].cxxvar_import->getDecl();
+            const llvm::Type *PtrStructTy
+              = llvm::PointerType::get(CGF.BuildByRefType(VD), 0);
+            Srcv = Builder.CreateLoad(Srcv);
+            Srcv = Builder.CreateBitCast(Srcv, PtrStructTy);
+            Srcv = Builder.CreateStructGEP(Srcv, CGF.getByRefValueLLVMField(VD),
+                                           VD->getNameAsString());
+            
+          }
           Srcv = Builder.CreateBitCast(Srcv, t);
           CGF.PushDestructorCleanup(ClassTy, Srcv);
         }