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).

llvm-svn: 119368
This commit is contained in:
Fariborz Jahanian 2010-11-16 19:29:39 +00:00
parent 2880185194
commit a3e54bd33e
3 changed files with 57 additions and 20 deletions

View File

@ -1006,14 +1006,36 @@ GenerateCopyHelperFunction(const llvm::StructType *T,
|| 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 @@ GenerateDestroyHelperFunction(const llvm::StructType* T,
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);
}

View File

@ -683,7 +683,11 @@ public:
/// isInConditionalBranch - Return true if we're currently emitting
/// one branch or the other of a conditional expression.
bool isInConditionalBranch() const { return ConditionalBranchLevel != 0; }
/// getByrefValueFieldNumber - Given a declaration, returns the LLVM field
/// number that holds the value.
unsigned getByRefValueLLVMField(const ValueDecl *VD) const;
private:
CGDebugInfo *DebugInfo;
@ -757,10 +761,6 @@ private:
llvm::DenseMap<const ValueDecl *, std::pair<const llvm::Type *,
unsigned> > ByRefValueInfo;
/// getByrefValueFieldNumber - Given a declaration, returns the LLVM field
/// number that holds the value.
unsigned getByRefValueLLVMField(const ValueDecl *VD) const;
llvm::BasicBlock *TerminateLandingPad;
llvm::BasicBlock *TerminateHandler;
llvm::BasicBlock *TrapBB;

View File

@ -2145,17 +2145,21 @@ Sema::BuildDeclarationNameExpr(const CXXScopeSpec &SS,
MarkDeclarationReferenced(Loc, VD);
QualType ExprTy = VD->getType().getNonReferenceType();
// The BlocksAttr indicates the variable is bound by-reference.
if (VD->getAttr<BlocksAttr>())
return Owned(new (Context) BlockDeclRefExpr(VD, ExprTy, Loc, true));
// This is to record that a 'const' was actually synthesize and added.
bool constAdded = !ExprTy.isConstQualified();
// Variable will be bound by-copy, make it const within the closure.
ExprTy.addConst();
bool byrefVar = (VD->getAttr<BlocksAttr>() != 0);
QualType T = VD->getType();
BlockDeclRefExpr *BDRE = new (Context) BlockDeclRefExpr(VD,
ExprTy, Loc, false,
constAdded);
BlockDeclRefExpr *BDRE;
if (!byrefVar) {
// This is to record that a 'const' was actually synthesize and added.
bool constAdded = !ExprTy.isConstQualified();
// Variable will be bound by-copy, make it const within the closure.
ExprTy.addConst();
BDRE = new (Context) BlockDeclRefExpr(VD, ExprTy, Loc, false,
constAdded);
}
else
BDRE = new (Context) BlockDeclRefExpr(VD, ExprTy, Loc, true);
if (getLangOptions().CPlusPlus) {
if (!T->isDependentType() && !T->isReferenceType()) {
Expr *E = new (Context)