]> granicus.if.org Git - clang/commitdiff
Finish off __Block_byref_id_object_dispose codegen for block literals.
authorMike Stump <mrs@apple.com>
Fri, 6 Mar 2009 04:53:30 +0000 (04:53 +0000)
committerMike Stump <mrs@apple.com>
Fri, 6 Mar 2009 04:53:30 +0000 (04:53 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@66247 91177308-0d34-0410-b5e6-96231b3b80d8

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

index efb4e98e2d877eba2b9b6909c7e4e7102021bac2..1c13f90fbff6e133b3ebc275e7b0f776eec6dac9 100644 (file)
@@ -793,7 +793,9 @@ llvm::Constant *BlockFunction::GeneratebyrefCopyHelperFunction() {
   return llvm::ConstantExpr::getBitCast(Fn, PtrToInt8Ty);
 }
 
-llvm::Constant *BlockFunction::GeneratebyrefDestroyHelperFunction() {
+llvm::Constant *
+BlockFunction::GeneratebyrefDestroyHelperFunction(const llvm::Type *T,
+                                                  int flag) {
   QualType R = getContext().VoidTy;
 
   FunctionArgList Args;
@@ -825,7 +827,19 @@ llvm::Constant *BlockFunction::GeneratebyrefDestroyHelperFunction() {
                                           FunctionDecl::Static, false,
                                           true);
   CGF.StartFunction(FD, R, Fn, Args, SourceLocation());
-  // BuildBlockRelease(Src, flag);
+
+  llvm::Value *V = CGF.GetAddrOfLocalVar(Src);
+  V = Builder.CreateBitCast(V, T);
+  V = Builder.CreateStructGEP(V, 6, "x");
+  V = Builder.CreateBitCast(V, PtrToInt8Ty);
+
+  // FIXME: Move to other one.
+  // int flag = BLOCK_FIELD_IS_BYREF;
+  // FIXME: Add weak support
+  if (0)
+    flag |= BLOCK_FIELD_IS_WEAK;
+  flag |= BLOCK_BYREF_CALLER;
+  BuildBlockRelease(V, flag);
   CGF.FinishFunction();
 
   return llvm::ConstantExpr::getBitCast(Fn, PtrToInt8Ty);
@@ -835,8 +849,9 @@ llvm::Constant *BlockFunction::BuildbyrefCopyHelper(int flag) {
   return CodeGenFunction(CGM).GeneratebyrefCopyHelperFunction();
 }
 
-llvm::Constant *BlockFunction::BuildbyrefDestroyHelper(int flag) {
-  return CodeGenFunction(CGM).GeneratebyrefDestroyHelperFunction();
+llvm::Constant *BlockFunction::BuildbyrefDestroyHelper(const llvm::Type *T,
+                                                       int flag) {
+  return CodeGenFunction(CGM).GeneratebyrefDestroyHelperFunction(T, flag);
 }
 
 llvm::Value *BlockFunction::getBlockObjectDispose() {
@@ -853,13 +868,11 @@ llvm::Value *BlockFunction::getBlockObjectDispose() {
   return CGM.BlockObjectDispose;
 }
 
-void BlockFunction::BuildBlockRelease(llvm::Value *DeclPtr) {
+void BlockFunction::BuildBlockRelease(llvm::Value *V, int flag) {
   llvm::Value *F = getBlockObjectDispose();
-  llvm::Value *N, *V;
-  V = Builder.CreateStructGEP(DeclPtr, 1, "forwarding");
-  V = Builder.CreateLoad(V, false);
+  llvm::Value *N;
   V = Builder.CreateBitCast(V, PtrToInt8Ty);
-  N = llvm::ConstantInt::get(llvm::Type::Int32Ty, BLOCK_FIELD_IS_BYREF);
+  N = llvm::ConstantInt::get(llvm::Type::Int32Ty, flag);
   Builder.CreateCall2(F, V, N);
 }
 
index a34e10221698c79c0a26f4a6b73d80af60e5c6b4..9763a1f32af91982a5bc56c120a50edbaa102311 100644 (file)
@@ -164,13 +164,13 @@ public:
   llvm::Constant *BuildDestroyHelper();
 
   llvm::Constant *GeneratebyrefCopyHelperFunction();
-  llvm::Constant *GeneratebyrefDestroyHelperFunction();
+  llvm::Constant *GeneratebyrefDestroyHelperFunction(const llvm::Type *T, int);
 
   llvm::Constant *BuildbyrefCopyHelper(int flag);
-  llvm::Constant *BuildbyrefDestroyHelper(int flag);
+  llvm::Constant *BuildbyrefDestroyHelper(const llvm::Type*, int flag);
 
   llvm::Value *getBlockObjectDispose();
-  void BuildBlockRelease(llvm::Value *DeclPtr);
+  void BuildBlockRelease(llvm::Value *DeclPtr, int flag = BLOCK_FIELD_IS_BYREF);
 
   bool BlockRequiresCopying(QualType Ty) {
     if (Ty->isBlockPointerType())
index e783c6018f8b4494b694992f3f3cd4f434ba0ba8..cf9b741168174ad20b49a1b4449ed0dc4b0c1223 100644 (file)
@@ -345,8 +345,8 @@ void CodeGenFunction::EmitLocalBlockVarDecl(const VarDecl &D) {
       flag |= BLOCK_FIELD_IS_BLOCK;
       flags |= BLOCK_HAS_COPY_DISPOSE;
     } else if (BlockRequiresCopying(Ty)) {
-      flags |= BLOCK_HAS_COPY_DISPOSE;
       flag |= BLOCK_FIELD_IS_OBJECT;
+      flags |= BLOCK_HAS_COPY_DISPOSE;
     }
     // FIXME: Need to set BLOCK_FIELD_IS_WEAK as appropriate.
 
@@ -373,11 +373,11 @@ void CodeGenFunction::EmitLocalBlockVarDecl(const VarDecl &D) {
     if (flags & BLOCK_HAS_COPY_DISPOSE) {
       BlockHasCopyDispose = true;
       llvm::Value *copy_helper = Builder.CreateStructGEP(DeclPtr, 4);
-      llvm::Value *destroy_helper = Builder.CreateStructGEP(DeclPtr, 5);
-
       Builder.CreateStore(BuildbyrefCopyHelper(flag), copy_helper);
 
-      Builder.CreateStore(BuildbyrefDestroyHelper(flag), destroy_helper);
+      llvm::Value *destroy_helper = Builder.CreateStructGEP(DeclPtr, 5);
+      Builder.CreateStore(BuildbyrefDestroyHelper(DeclPtr->getType(), flag),
+                          destroy_helper);
     }
     needsDispose = true;
   }
@@ -400,7 +400,9 @@ void CodeGenFunction::EmitLocalBlockVarDecl(const VarDecl &D) {
 
   if (needsDispose && CGM.getLangOptions().getGCMode() != LangOptions::GCOnly) {
     CleanupScope scope(*this);
-    BuildBlockRelease(DeclPtr);
+    llvm::Value *V = Builder.CreateStructGEP(DeclPtr, 1, "forwarding");
+    V = Builder.CreateLoad(V, false);
+    BuildBlockRelease(V);
   }
 }
 
index 804b688afb36872828ee0e1d545c2af406bf7881..fbc45236aa47273286501a39913f2ee7422b6954 100644 (file)
@@ -1,9 +1,10 @@
 // RUN: clang %s -emit-llvm -o %t -fblocks -f__block &&
-// RUN: grep "_Block_object_dispose" %t | count 5
-// RUN: grep "__copy_helper_block_" %t | count 6
-// RUN: grep "__destroy_helper_block_" %t | count 6
-// RUN: grep "__Block_byref_id_object_copy_" %t | count 2
-// RUN: grep "__Block_byref_id_object_dispose_" %t | count 2
+// RUN: grep "_Block_object_dispose" %t | count 5 &&
+// RUN: grep "__copy_helper_block_" %t | count 6 &&
+// RUN: grep "__destroy_helper_block_" %t | count 6 &&
+// 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 1
 #include <stdio.h>
 
 void test1() {