]> granicus.if.org Git - clang/commitdiff
Fixup codegen for nested blocks that use copy/dispose in the inner
authorMike Stump <mrs@apple.com>
Fri, 10 Apr 2009 18:52:28 +0000 (18:52 +0000)
committerMike Stump <mrs@apple.com>
Fri, 10 Apr 2009 18:52:28 +0000 (18:52 +0000)
blocks, so that the outer blocks use it as well.  Radar 6762279

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@68811 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGBlocks.cpp
lib/CodeGen/CGBlocks.h
test/CodeGen/blocks-1.c

index a623cf18cf9b430de5a9af543f7f3f22441ae46d..4e9419ed2045222132232fce41f620b68664e1fc 100644 (file)
@@ -48,10 +48,10 @@ BuildDescriptorBlockDecl(bool BlockHasCopyDispose, uint64_t Size,
 
   if (BlockHasCopyDispose) {
     // copy_func_helper_decl
-    Elts.push_back(BuildCopyHelper(Ty, *NoteForHelper));
+    Elts.push_back(BuildCopyHelper(Ty, NoteForHelper));
 
     // destroy_func_decl
-    Elts.push_back(BuildDestroyHelper(Ty, *NoteForHelper));
+    Elts.push_back(BuildDestroyHelper(Ty, NoteForHelper));
   }
 
   C = llvm::ConstantStruct::get(Elts);
@@ -178,7 +178,6 @@ llvm::Value *CodeGenFunction::BuildBlockLiteralTmp(const BlockExpr *BE) {
 
     if (subBlockDeclRefDecls.size() == 0) {
       // __descriptor
-      assert(subBlockHasCopyDispose == false);
       Elts[4] = BuildDescriptorBlockDecl(subBlockHasCopyDispose, subBlockSize, 0, 0);
 
       // Optimize to being a global block.
@@ -714,7 +713,7 @@ uint64_t BlockFunction::getBlockOffset(const BlockDeclRefExpr *BDRE) {
 
 llvm::Constant *BlockFunction::
 GenerateCopyHelperFunction(bool BlockHasCopyDispose, const llvm::StructType *T,
-                           std::vector<HelperInfo> &NoteForHelper) {
+                           std::vector<HelperInfo> *NoteForHelperp) {
   QualType R = getContext().VoidTy;
 
   FunctionArgList Args;
@@ -752,31 +751,36 @@ GenerateCopyHelperFunction(bool BlockHasCopyDispose, const llvm::StructType *T,
 
   llvm::Value *SrcObj = CGF.GetAddrOfLocalVar(Src);
   llvm::Type *PtrPtrT;
-  PtrPtrT = llvm::PointerType::get(llvm::PointerType::get(T, 0), 0);
-  SrcObj = Builder.CreateBitCast(SrcObj, PtrPtrT);
-  SrcObj = Builder.CreateLoad(SrcObj);
-
-  llvm::Value *DstObj = CGF.GetAddrOfLocalVar(Dst);
-  DstObj = Builder.CreateBitCast(DstObj, llvm::PointerType::get(T, 0));
-
-  for (unsigned i=0; i < NoteForHelper.size(); ++i) {
-    int flag = NoteForHelper[i].flag;
-    int index = NoteForHelper[i].index;
-
-    if ((NoteForHelper[i].flag & BLOCK_FIELD_IS_BYREF)
-        || NoteForHelper[i].RequiresCopying) {
-      llvm::Value *Srcv = SrcObj;
-      Srcv = Builder.CreateStructGEP(Srcv, index);
-      Srcv = Builder.CreateBitCast(Srcv,
-                                   llvm::PointerType::get(PtrToInt8Ty, 0));
-      Srcv = Builder.CreateLoad(Srcv);
-
-      llvm::Value *Dstv = Builder.CreateStructGEP(DstObj, index);
-      Dstv = Builder.CreateBitCast(Dstv, PtrToInt8Ty);
-
-      llvm::Value *N = llvm::ConstantInt::get(llvm::Type::Int32Ty, flag);
-      llvm::Value *F = getBlockObjectAssign();
-      Builder.CreateCall3(F, Dstv, Srcv, N);
+
+  if (NoteForHelperp) {
+    std::vector<HelperInfo> &NoteForHelper = *NoteForHelperp;
+
+    PtrPtrT = llvm::PointerType::get(llvm::PointerType::get(T, 0), 0);
+    SrcObj = Builder.CreateBitCast(SrcObj, PtrPtrT);
+    SrcObj = Builder.CreateLoad(SrcObj);
+
+    llvm::Value *DstObj = CGF.GetAddrOfLocalVar(Dst);
+    DstObj = Builder.CreateBitCast(DstObj, llvm::PointerType::get(T, 0));
+
+    for (unsigned i=0; i < NoteForHelper.size(); ++i) {
+      int flag = NoteForHelper[i].flag;
+      int index = NoteForHelper[i].index;
+
+      if ((NoteForHelper[i].flag & BLOCK_FIELD_IS_BYREF)
+          || NoteForHelper[i].RequiresCopying) {
+        llvm::Value *Srcv = SrcObj;
+        Srcv = Builder.CreateStructGEP(Srcv, index);
+        Srcv = Builder.CreateBitCast(Srcv,
+                                     llvm::PointerType::get(PtrToInt8Ty, 0));
+        Srcv = Builder.CreateLoad(Srcv);
+
+        llvm::Value *Dstv = Builder.CreateStructGEP(DstObj, index);
+        Dstv = Builder.CreateBitCast(Dstv, PtrToInt8Ty);
+
+        llvm::Value *N = llvm::ConstantInt::get(llvm::Type::Int32Ty, flag);
+        llvm::Value *F = getBlockObjectAssign();
+        Builder.CreateCall3(F, Dstv, Srcv, N);
+      }
     }
   }
 
@@ -788,7 +792,7 @@ GenerateCopyHelperFunction(bool BlockHasCopyDispose, const llvm::StructType *T,
 llvm::Constant *BlockFunction::
 GenerateDestroyHelperFunction(bool BlockHasCopyDispose,
                               const llvm::StructType* T,
-                              std::vector<HelperInfo> &NoteForHelper) {
+                              std::vector<HelperInfo> *NoteForHelperp) {
   QualType R = getContext().VoidTy;
 
   FunctionArgList Args;
@@ -821,25 +825,29 @@ GenerateDestroyHelperFunction(bool BlockHasCopyDispose,
                                           true);
   CGF.StartFunction(FD, R, Fn, Args, SourceLocation());
 
-  llvm::Value *SrcObj = CGF.GetAddrOfLocalVar(Src);
-  llvm::Type *PtrPtrT;
-  PtrPtrT = llvm::PointerType::get(llvm::PointerType::get(T, 0), 0);
-  SrcObj = Builder.CreateBitCast(SrcObj, PtrPtrT);
-  SrcObj = Builder.CreateLoad(SrcObj);
-
-  for (unsigned i=0; i < NoteForHelper.size(); ++i) {
-    int flag = NoteForHelper[i].flag;
-    int index = NoteForHelper[i].index;
-
-    if ((NoteForHelper[i].flag & BLOCK_FIELD_IS_BYREF)
-        || NoteForHelper[i].RequiresCopying) {
-      llvm::Value *Srcv = SrcObj;
-      Srcv = Builder.CreateStructGEP(Srcv, index);
-      Srcv = Builder.CreateBitCast(Srcv,
-                                   llvm::PointerType::get(PtrToInt8Ty, 0));
-      Srcv = Builder.CreateLoad(Srcv);
-
-      BuildBlockRelease(Srcv, flag);
+  if (NoteForHelperp) {
+    std::vector<HelperInfo> &NoteForHelper = *NoteForHelperp;
+
+    llvm::Value *SrcObj = CGF.GetAddrOfLocalVar(Src);
+    llvm::Type *PtrPtrT;
+    PtrPtrT = llvm::PointerType::get(llvm::PointerType::get(T, 0), 0);
+    SrcObj = Builder.CreateBitCast(SrcObj, PtrPtrT);
+    SrcObj = Builder.CreateLoad(SrcObj);
+
+    for (unsigned i=0; i < NoteForHelper.size(); ++i) {
+      int flag = NoteForHelper[i].flag;
+      int index = NoteForHelper[i].index;
+
+      if ((NoteForHelper[i].flag & BLOCK_FIELD_IS_BYREF)
+          || NoteForHelper[i].RequiresCopying) {
+        llvm::Value *Srcv = SrcObj;
+        Srcv = Builder.CreateStructGEP(Srcv, index);
+        Srcv = Builder.CreateBitCast(Srcv,
+                                     llvm::PointerType::get(PtrToInt8Ty, 0));
+        Srcv = Builder.CreateLoad(Srcv);
+
+        BuildBlockRelease(Srcv, flag);
+      }
     }
   }
 
@@ -849,15 +857,15 @@ GenerateDestroyHelperFunction(bool BlockHasCopyDispose,
 }
 
 llvm::Constant *BlockFunction::BuildCopyHelper(const llvm::StructType *T,
-                                       std::vector<HelperInfo> &NoteForHelper) {
+                                       std::vector<HelperInfo> *NoteForHelper) {
   return CodeGenFunction(CGM).GenerateCopyHelperFunction(BlockHasCopyDispose,
                                                          T, NoteForHelper);
 }
 
 llvm::Constant *BlockFunction::BuildDestroyHelper(const llvm::StructType *T,
-                                       std::vector<HelperInfo> &NoteForHelper) {
+                                      std::vector<HelperInfo> *NoteForHelperp) {
   return CodeGenFunction(CGM).GenerateDestroyHelperFunction(BlockHasCopyDispose,
-                                                            T, NoteForHelper);
+                                                            T, NoteForHelperp);
 }
 
 llvm::Constant *BlockFunction::
index 3eca891289683167520eeb10d42b9ef53840c61c..58276c294d8b0ae7ef89f7fd49e761d26a319dff 100644 (file)
@@ -183,14 +183,14 @@ public:
   ImplicitParamDecl *getBlockStructDecl() { return BlockStructDecl; }
 
   llvm::Constant *GenerateCopyHelperFunction(bool, const llvm::StructType *,
-                                             std::vector<HelperInfo> &);
+                                             std::vector<HelperInfo> *);
   llvm::Constant *GenerateDestroyHelperFunction(bool, const llvm::StructType *,
-                                                std::vector<HelperInfo> &);
+                                                std::vector<HelperInfo> *);
 
   llvm::Constant *BuildCopyHelper(const llvm::StructType *,
-                                  std::vector<HelperInfo> &);
+                                  std::vector<HelperInfo> *);
   llvm::Constant *BuildDestroyHelper(const llvm::StructType *,
-                                     std::vector<HelperInfo> &);
+                                     std::vector<HelperInfo> *);
 
   llvm::Constant *GeneratebyrefCopyHelperFunction(const llvm::Type *, int flag);
   llvm::Constant *GeneratebyrefDestroyHelperFunction(const llvm::Type *T, int);
index f2677f3c27568d88a5410f6df4e75118106f8f73..10498cb00495f5f3f9379433444711e62e8ce5b5 100644 (file)
@@ -1,11 +1,11 @@
 // RUN: clang-cc %s -emit-llvm -o %t -fblocks &&
-// RUN: grep "_Block_object_dispose" %t | count 15 &&
-// RUN: grep "__copy_helper_block_" %t | count 12 &&
-// RUN: grep "__destroy_helper_block_" %t | count 12 &&
+// RUN: grep "_Block_object_dispose" %t | count 17 &&
+// RUN: grep "__copy_helper_block_" %t | count 16 &&
+// RUN: grep "__destroy_helper_block_" %t | count 16 &&
 // RUN: grep "__Block_byref_id_object_copy_" %t | count 2 &&
 // RUN: grep "__Block_byref_id_object_dispose_" %t | count 2 &&
 // RUN: grep "i32 135)" %t | count 2 &&
-// RUN: grep "_Block_object_assign" %t | count 9
+// RUN: grep "_Block_object_assign" %t | count 10
 
 #include <stdio.h>
 
@@ -57,7 +57,14 @@ void test5() {
 void test6() {
   __block int i;
   ^{ i=1; }();
- ^{};
+  ^{}();
+}
+
+void test7() {
+  ^{
+    __block int i;
+    ^{ i = 1; }();
+  }();
 }
 
 int main() {