[cfe-commits] r120713 - in /cfe/trunk: include/clang/AST/ASTContext.h lib/AST/ASTContext.cpp lib/CodeGen/CGBlocks.cpp lib/CodeGen/CGBlocks.h lib/CodeGen/CGDecl.cpp lib/CodeGen/CGExprCXX.cpp lib/CodeGen/CodeGenFunction.h test/CodeGen/blocks-1.c test/CodeGenObjC/blocks-1.m

Fariborz Jahanian fjahanian at apple.com
Thu Dec 2 09:02:11 PST 2010


Author: fjahanian
Date: Thu Dec  2 11:02:11 2010
New Revision: 120713

URL: http://llvm.org/viewvc/llvm-project?rev=120713&view=rev
Log:
IR Gen. part of API support for __block cxx
objects imported into blocks. //rdar://8594790.
Will have a test case coming (as well as one
sent to llvm test suite).

Modified:
    cfe/trunk/include/clang/AST/ASTContext.h
    cfe/trunk/lib/AST/ASTContext.cpp
    cfe/trunk/lib/CodeGen/CGBlocks.cpp
    cfe/trunk/lib/CodeGen/CGBlocks.h
    cfe/trunk/lib/CodeGen/CGDecl.cpp
    cfe/trunk/lib/CodeGen/CGExprCXX.cpp
    cfe/trunk/lib/CodeGen/CodeGenFunction.h
    cfe/trunk/test/CodeGen/blocks-1.c
    cfe/trunk/test/CodeGenObjC/blocks-1.m

Modified: cfe/trunk/include/clang/AST/ASTContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=120713&r1=120712&r2=120713&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Thu Dec  2 11:02:11 2010
@@ -130,7 +130,7 @@
   llvm::DenseMap<ObjCContainerDecl*, ObjCImplDecl*> ObjCImpls;
 
   /// \brief Mapping from __block VarDecls to their copy initialization expr.
-  llvm::DenseMap<VarDecl*, Expr*> BlockVarCopyInits;
+  llvm::DenseMap<const VarDecl*, Expr*> BlockVarCopyInits;
     
   /// \brief Representation of a "canonical" template template parameter that
   /// is used in canonical template names.
@@ -1366,7 +1366,7 @@
   void setBlockVarCopyInits(VarDecl*VD, Expr* Init);
   /// \brief Get the copy initialization expression of VarDecl,or NULL if 
   /// none exists.
-  Expr *getBlockVarCopyInits(VarDecl*VD);
+  Expr *getBlockVarCopyInits(const VarDecl*VD);
 
   /// \brief Allocate an uninitialized TypeSourceInfo.
   ///

Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=120713&r1=120712&r2=120713&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Thu Dec  2 11:02:11 2010
@@ -1010,8 +1010,8 @@
 
 /// \brief Get the copy initialization expression of VarDecl,or NULL if 
 /// none exists.
-Expr *ASTContext::getBlockVarCopyInits(VarDecl*VD) {
-  llvm::DenseMap<VarDecl*, Expr*>::iterator
+Expr *ASTContext::getBlockVarCopyInits(const VarDecl*VD) {
+  llvm::DenseMap<const VarDecl*, Expr*>::iterator
   I = BlockVarCopyInits.find(VD);
   return (I != BlockVarCopyInits.end()) ? cast<Expr>(I->second) : 0;
 }

Modified: cfe/trunk/lib/CodeGen/CGBlocks.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBlocks.cpp?rev=120713&r1=120712&r2=120713&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGBlocks.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGBlocks.cpp Thu Dec  2 11:02:11 2010
@@ -1000,29 +1000,16 @@
         llvm::Value *Srcv = SrcObj;
         Srcv = Builder.CreateStructGEP(Srcv, index);
         llvm::Value *Dstv;
-        if (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.CreateBitCast(DstObj, 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);
-          }
+        if (NoteForHelper[i].cxxvar_import &&
+            (NoteForHelper[i].flag & BLOCK_FIELD_IS_BYREF) == 0) {
+          // Note that cxx objects declared as __block require a
+          // different API. They are copy constructed in their own copy
+          // helper functions (see GeneratebyrefCopyHelperFunction).
+          Srcv = Builder.CreateBitCast(Srcv,
+                                       llvm::PointerType::get(PtrToInt8Ty, 0));
+          Dstv = Builder.CreateStructGEP(DstObj, index);
+          CGF.EmitSynthesizedCXXCopyCtor(Dstv, Srcv, 
+                                         NoteForHelper[i].cxxvar_import->getCopyConstructorExpr());
         }
         else {
           Srcv = Builder.CreateBitCast(Srcv,
@@ -1099,23 +1086,13 @@
         Srcv = Builder.CreateStructGEP(Srcv, index);
         Srcv = Builder.CreateBitCast(Srcv,
                                      llvm::PointerType::get(PtrToInt8Ty, 0));
-        if (NoteForHelper[i].cxxvar_import) {
+        if (NoteForHelper[i].cxxvar_import &&
+            (NoteForHelper[i].flag & BLOCK_FIELD_IS_BYREF) == 0) {
           const BlockDeclRefExpr *BDRE = NoteForHelper[i].cxxvar_import;
           const Expr *E = BDRE->getCopyConstructorExpr();
           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);
         }
@@ -1144,7 +1121,8 @@
 }
 
 llvm::Constant *BlockFunction::
-GeneratebyrefCopyHelperFunction(const llvm::Type *T, int flag) {
+GeneratebyrefCopyHelperFunction(const llvm::Type *T, int flag, 
+                                const VarDecl *BD) {
   QualType R = getContext().VoidTy;
 
   FunctionArgList Args;
@@ -1172,10 +1150,10 @@
   // internal linkage.
   llvm::Function *Fn =
     llvm::Function::Create(LTy, llvm::GlobalValue::InternalLinkage,
-                           "__Block_byref_id_object_copy_", &CGM.getModule());
+                           "__Block_byref_object_copy_", &CGM.getModule());
 
   IdentifierInfo *II
-    = &CGM.getContext().Idents.get("__Block_byref_id_object_copy_");
+    = &CGM.getContext().Idents.get("__Block_byref_object_copy_");
 
   FunctionDecl *FD = FunctionDecl::Create(getContext(),
                                           getContext().getTranslationUnitDecl(),
@@ -1190,22 +1168,30 @@
   V = Builder.CreateBitCast(V, llvm::PointerType::get(T, 0));
   V = Builder.CreateLoad(V);
   V = Builder.CreateStructGEP(V, 6, "x");
-  llvm::Value *DstObj = Builder.CreateBitCast(V, PtrToInt8Ty);
+  llvm::Value *DstObj = V;
 
   // src->x
   V = CGF.GetAddrOfLocalVar(Src);
   V = Builder.CreateLoad(V);
   V = Builder.CreateBitCast(V, T);
   V = Builder.CreateStructGEP(V, 6, "x");
-  V = Builder.CreateBitCast(V, llvm::PointerType::get(PtrToInt8Ty, 0));
-  llvm::Value *SrcObj = Builder.CreateLoad(V);
-
-  flag |= BLOCK_BYREF_CALLER;
-
-  llvm::Value *N = llvm::ConstantInt::get(CGF.Int32Ty, flag);
-  llvm::Value *F = CGM.getBlockObjectAssign();
-  Builder.CreateCall3(F, DstObj, SrcObj, N);
-
+  
+  if (flag & BLOCK_HAS_CXX_OBJ) {
+    assert (BD && "VarDecl is null - GeneratebyrefCopyHelperFunction");
+    llvm::Value *SrcObj = V;
+    CGF.EmitSynthesizedCXXCopyCtor(DstObj, SrcObj, 
+                                   getContext().getBlockVarCopyInits(BD));
+  }
+  else {
+    DstObj = Builder.CreateBitCast(DstObj, PtrToInt8Ty);
+    V = Builder.CreateBitCast(V, llvm::PointerType::get(PtrToInt8Ty, 0));
+    llvm::Value *SrcObj = Builder.CreateLoad(V);
+    flag |= BLOCK_BYREF_CALLER;
+    llvm::Value *N = llvm::ConstantInt::get(CGF.Int32Ty, flag);
+    llvm::Value *F = CGM.getBlockObjectAssign();
+    Builder.CreateCall3(F, DstObj, SrcObj, N);
+  }
+  
   CGF.FinishFunction();
 
   return llvm::ConstantExpr::getBitCast(Fn, PtrToInt8Ty);
@@ -1213,7 +1199,8 @@
 
 llvm::Constant *
 BlockFunction::GeneratebyrefDestroyHelperFunction(const llvm::Type *T,
-                                                  int flag) {
+                                                  int flag,
+                                                  const VarDecl *BD) {
   QualType R = getContext().VoidTy;
 
   FunctionArgList Args;
@@ -1235,11 +1222,11 @@
   // internal linkage.
   llvm::Function *Fn =
     llvm::Function::Create(LTy, llvm::GlobalValue::InternalLinkage,
-                           "__Block_byref_id_object_dispose_",
+                           "__Block_byref_object_dispose_",
                            &CGM.getModule());
 
   IdentifierInfo *II
-    = &CGM.getContext().Idents.get("__Block_byref_id_object_dispose_");
+    = &CGM.getContext().Idents.get("__Block_byref_object_dispose_");
 
   FunctionDecl *FD = FunctionDecl::Create(getContext(),
                                           getContext().getTranslationUnitDecl(),
@@ -1253,18 +1240,28 @@
   V = Builder.CreateBitCast(V, llvm::PointerType::get(T, 0));
   V = Builder.CreateLoad(V);
   V = Builder.CreateStructGEP(V, 6, "x");
-  V = Builder.CreateBitCast(V, llvm::PointerType::get(PtrToInt8Ty, 0));
-  V = Builder.CreateLoad(V);
+  if (flag & BLOCK_HAS_CXX_OBJ) {
+    EHScopeStack::stable_iterator CleanupDepth = CGF.EHStack.stable_begin();
+    assert (BD && "VarDecl is null - GeneratebyrefDestroyHelperFunction");
+    QualType ClassTy = BD->getType();
+    CGF.PushDestructorCleanup(ClassTy, V);
+    CGF.PopCleanupBlocks(CleanupDepth);
+  }
+  else {
+    V = Builder.CreateBitCast(V, llvm::PointerType::get(PtrToInt8Ty, 0));
+    V = Builder.CreateLoad(V);
 
-  flag |= BLOCK_BYREF_CALLER;
-  BuildBlockRelease(V, flag);
+    flag |= BLOCK_BYREF_CALLER;
+    BuildBlockRelease(V, flag);
+  }
   CGF.FinishFunction();
 
   return llvm::ConstantExpr::getBitCast(Fn, PtrToInt8Ty);
 }
 
 llvm::Constant *BlockFunction::BuildbyrefCopyHelper(const llvm::Type *T,
-                                                    int Flag, unsigned Align) {
+                                                    int Flag, unsigned Align,
+                                                    const VarDecl *BD) {
   // All alignments below that of pointer alignment collapse down to just
   // pointer alignment, as we always have at least that much alignment to begin
   // with.
@@ -1277,12 +1274,14 @@
   llvm::Constant *&Entry = CGM.AssignCache[Kind];
   if (Entry)
     return Entry;
-  return Entry = CodeGenFunction(CGM).GeneratebyrefCopyHelperFunction(T, Flag);
+  return Entry = 
+           CodeGenFunction(CGM).GeneratebyrefCopyHelperFunction(T, Flag, BD);
 }
 
 llvm::Constant *BlockFunction::BuildbyrefDestroyHelper(const llvm::Type *T,
                                                        int Flag,
-                                                       unsigned Align) {
+                                                       unsigned Align,
+                                                       const VarDecl *BD) {
   // All alignments below that of pointer alignment collpase down to just
   // pointer alignment, as we always have at least that much alignment to begin
   // with.
@@ -1295,7 +1294,8 @@
   llvm::Constant *&Entry = CGM.DestroyCache[Kind];
   if (Entry)
     return Entry;
-  return Entry=CodeGenFunction(CGM).GeneratebyrefDestroyHelperFunction(T, Flag);
+  return Entry = 
+           CodeGenFunction(CGM).GeneratebyrefDestroyHelperFunction(T, Flag, BD);
 }
 
 void BlockFunction::BuildBlockRelease(llvm::Value *V, int flag) {

Modified: cfe/trunk/lib/CodeGen/CGBlocks.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBlocks.h?rev=120713&r1=120712&r2=120713&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGBlocks.h (original)
+++ cfe/trunk/lib/CodeGen/CGBlocks.h Thu Dec  2 11:02:11 2010
@@ -189,13 +189,16 @@
   llvm::Constant *BuildDestroyHelper(const llvm::StructType *,
                                      std::vector<HelperInfo> *);
 
-  llvm::Constant *GeneratebyrefCopyHelperFunction(const llvm::Type *, int flag);
-  llvm::Constant *GeneratebyrefDestroyHelperFunction(const llvm::Type *T, int);
+  llvm::Constant *GeneratebyrefCopyHelperFunction(const llvm::Type *, int flag,
+                                                  const VarDecl *BD);
+  llvm::Constant *GeneratebyrefDestroyHelperFunction(const llvm::Type *T, 
+                                                     int flag, 
+                                                     const VarDecl *BD);
 
   llvm::Constant *BuildbyrefCopyHelper(const llvm::Type *T, int flag,
-                                       unsigned Align);
+                                       unsigned Align, const VarDecl *BD);
   llvm::Constant *BuildbyrefDestroyHelper(const llvm::Type *T, int flag,
-                                          unsigned Align);
+                                          unsigned Align, const VarDecl *BD);
 
   void BuildBlockRelease(llvm::Value *DeclPtr, int flag = BLOCK_FIELD_IS_BYREF);
 

Modified: cfe/trunk/lib/CodeGen/CGDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDecl.cpp?rev=120713&r1=120712&r2=120713&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGDecl.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGDecl.cpp Thu Dec  2 11:02:11 2010
@@ -756,6 +756,9 @@
                Ty->isObjCObjectPointerType()) {
       flag |= BLOCK_FIELD_IS_OBJECT;
       flags |= BLOCK_HAS_COPY_DISPOSE;
+    } else if (getContext().getBlockVarCopyInits(&D)) {
+        flag |= BLOCK_HAS_CXX_OBJ;
+        flags |= BLOCK_HAS_COPY_DISPOSE;
     }
 
     // FIXME: Someone double check this.
@@ -781,12 +784,12 @@
       SynthesizeCopyDisposeHelpers = true;
       llvm::Value *copy_helper = Builder.CreateStructGEP(DeclPtr, 4);
       Builder.CreateStore(BuildbyrefCopyHelper(DeclPtr->getType(), flag, 
-                                               Align.getQuantity()),
+                                               Align.getQuantity(), &D),
                           copy_helper);
 
       llvm::Value *destroy_helper = Builder.CreateStructGEP(DeclPtr, 5);
       Builder.CreateStore(BuildbyrefDestroyHelper(DeclPtr->getType(), flag,
-                                                  Align.getQuantity()),
+                                                  Align.getQuantity(), &D),
                           destroy_helper);
     }
   }

Modified: cfe/trunk/lib/CodeGen/CGExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprCXX.cpp?rev=120713&r1=120712&r2=120713&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprCXX.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprCXX.cpp Thu Dec  2 11:02:11 2010
@@ -344,8 +344,7 @@
 void
 CodeGenFunction::EmitSynthesizedCXXCopyCtor(llvm::Value *Dest, 
                                             llvm::Value *Src,
-                                            const BlockDeclRefExpr *BDRE) {
-  const Expr *Exp = BDRE->getCopyConstructorExpr();
+                                            const Expr *Exp) {
   if (const CXXExprWithTemporaries *E = dyn_cast<CXXExprWithTemporaries>(Exp))
     Exp = E->getSubExpr();
   assert(isa<CXXConstructExpr>(Exp) && 

Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=120713&r1=120712&r2=120713&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Thu Dec  2 11:02:11 2010
@@ -1659,7 +1659,7 @@
   void EmitCXXConstructExpr(const CXXConstructExpr *E, AggValueSlot Dest);
   
   void EmitSynthesizedCXXCopyCtor(llvm::Value *Dest, llvm::Value *Src,
-                                  const BlockDeclRefExpr *BDRE);
+                                  const Expr *Exp);
 
   RValue EmitCXXExprWithTemporaries(const CXXExprWithTemporaries *E,
                                     AggValueSlot Slot =AggValueSlot::ignored());

Modified: cfe/trunk/test/CodeGen/blocks-1.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/blocks-1.c?rev=120713&r1=120712&r2=120713&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/blocks-1.c (original)
+++ cfe/trunk/test/CodeGen/blocks-1.c Thu Dec  2 11:02:11 2010
@@ -2,8 +2,8 @@
 // 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 "__Block_byref_object_copy_" %t | count 2
+// RUN: grep "__Block_byref_object_dispose_" %t | count 2
 // RUN: grep "i32 135)" %t | count 2
 // RUN: grep "_Block_object_assign" %t | count 10
 

Modified: cfe/trunk/test/CodeGenObjC/blocks-1.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/blocks-1.m?rev=120713&r1=120712&r2=120713&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenObjC/blocks-1.m (original)
+++ cfe/trunk/test/CodeGenObjC/blocks-1.m Thu Dec  2 11:02:11 2010
@@ -2,8 +2,8 @@
 // RUN: grep "_Block_object_dispose" %t | count 6
 // RUN: grep "__copy_helper_block_" %t | count 4
 // RUN: grep "__destroy_helper_block_" %t | count 4
-// RUN: grep "__Block_byref_id_object_copy_" %t | count 2
-// RUN: grep "__Block_byref_id_object_dispose_" %t | count 2
+// RUN: grep "__Block_byref_object_copy_" %t | count 2
+// RUN: grep "__Block_byref_object_dispose_" %t | count 2
 // RUN: grep "i32 135)" %t | count 0
 // RUN: grep "_Block_object_assign" %t | count 4
 // RUN: grep "objc_read_weak" %t | count 2
@@ -12,8 +12,8 @@
 // RUN: grep "_Block_object_dispose" %t | count 6
 // RUN: grep "__copy_helper_block_" %t | count 4
 // RUN: grep "__destroy_helper_block_" %t | count 4
-// RUN: grep "__Block_byref_id_object_copy_" %t | count 2
-// RUN: grep "__Block_byref_id_object_dispose_" %t | count 2
+// RUN: grep "__Block_byref_object_copy_" %t | count 2
+// RUN: grep "__Block_byref_object_dispose_" %t | count 2
 // RUN: grep "i32 135)" %t | count 0
 // RUN: grep "_Block_object_assign" %t | count 4
 // RUN: grep "objc_read_weak" %t | count 2





More information about the cfe-commits mailing list