[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