diff options
Diffstat (limited to 'lib/CodeGen/CGDecl.cpp')
-rw-r--r-- | lib/CodeGen/CGDecl.cpp | 63 |
1 files changed, 32 insertions, 31 deletions
diff --git a/lib/CodeGen/CGDecl.cpp b/lib/CodeGen/CGDecl.cpp index 0f74a3f530..c3708d1efd 100644 --- a/lib/CodeGen/CGDecl.cpp +++ b/lib/CodeGen/CGDecl.cpp @@ -14,6 +14,7 @@ #include "CGDebugInfo.h" #include "CodeGenFunction.h" #include "CodeGenModule.h" +#include "CGBlocks.h" #include "clang/AST/ASTContext.h" #include "clang/AST/CharUnits.h" #include "clang/AST/Decl.h" @@ -337,9 +338,7 @@ const llvm::Type *CodeGenFunction::BuildByRefType(const VarDecl *D) { std::vector<const llvm::Type *> Types; - const llvm::PointerType *Int8PtrTy = llvm::Type::getInt8PtrTy(VMContext); - - llvm::PATypeHolder ByRefTypeHolder = llvm::OpaqueType::get(VMContext); + llvm::PATypeHolder ByRefTypeHolder = llvm::OpaqueType::get(getLLVMContext()); // void *__isa; Types.push_back(Int8PtrTy); @@ -380,7 +379,7 @@ const llvm::Type *CodeGenFunction::BuildByRefType(const VarDecl *D) { unsigned NumPaddingBytes = AlignedOffsetInBytes - CurrentOffsetInBytes; if (NumPaddingBytes > 0) { - const llvm::Type *Ty = llvm::Type::getInt8Ty(VMContext); + const llvm::Type *Ty = llvm::Type::getInt8Ty(getLLVMContext()); // FIXME: We need a sema error for alignment larger than the minimum of // the maximal stack alignmint and the alignment of malloc on the system. if (NumPaddingBytes > 1) @@ -396,7 +395,7 @@ const llvm::Type *CodeGenFunction::BuildByRefType(const VarDecl *D) { // T x; Types.push_back(ConvertTypeForMem(Ty)); - const llvm::Type *T = llvm::StructType::get(VMContext, Types, Packed); + const llvm::Type *T = llvm::StructType::get(getLLVMContext(), Types, Packed); cast<llvm::OpaqueType>(ByRefTypeHolder.get())->refineAbstractTypeTo(T); CGM.getModule().addTypeName("struct.__block_byref_" + D->getNameAsString(), @@ -507,7 +506,7 @@ namespace { void Emit(CodeGenFunction &CGF, bool IsForEH) { llvm::Value *V = CGF.Builder.CreateStructGEP(Addr, 1, "forwarding"); V = CGF.Builder.CreateLoad(V); - CGF.BuildBlockRelease(V, BlockFunction::BLOCK_FIELD_IS_BYREF); + CGF.BuildBlockRelease(V, BLOCK_FIELD_IS_BYREF); } }; } @@ -686,8 +685,7 @@ void CodeGenFunction::EmitAutoVarDecl(const VarDecl &D, if (!DidCallStackSave) { // Save the stack. - const llvm::Type *LTy = llvm::Type::getInt8PtrTy(VMContext); - llvm::Value *Stack = CreateTempAlloca(LTy, "saved_stack"); + llvm::Value *Stack = CreateTempAlloca(Int8PtrTy, "saved_stack"); llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::stacksave); llvm::Value *V = Builder.CreateCall(F); @@ -709,7 +707,7 @@ void CodeGenFunction::EmitAutoVarDecl(const VarDecl &D, // Allocate memory for the array. llvm::AllocaInst *VLA = - Builder.CreateAlloca(llvm::Type::getInt8Ty(VMContext), VLASize, "vla"); + Builder.CreateAlloca(llvm::Type::getInt8Ty(getLLVMContext()), VLASize, "vla"); VLA->setAlignment(getContext().getDeclAlign(&D).getQuantity()); DeclPtr = Builder.CreateBitCast(VLA, LElemPtrTy, "tmp"); @@ -743,59 +741,62 @@ void CodeGenFunction::EmitAutoVarDecl(const VarDecl &D, } if (isByRef) { - const llvm::PointerType *PtrToInt8Ty = llvm::Type::getInt8PtrTy(VMContext); - EnsureInsertPoint(); llvm::Value *isa_field = Builder.CreateStructGEP(DeclPtr, 0); llvm::Value *forwarding_field = Builder.CreateStructGEP(DeclPtr, 1); llvm::Value *flags_field = Builder.CreateStructGEP(DeclPtr, 2); llvm::Value *size_field = Builder.CreateStructGEP(DeclPtr, 3); llvm::Value *V; - int flag = 0; - int flags = 0; + + BlockFieldFlags fieldFlags; + bool fieldNeedsCopyDispose = false; needsDispose = true; if (Ty->isBlockPointerType()) { - flag |= BLOCK_FIELD_IS_BLOCK; - flags |= BLOCK_HAS_COPY_DISPOSE; + fieldFlags |= BLOCK_FIELD_IS_BLOCK; + fieldNeedsCopyDispose = true; } else if (getContext().isObjCNSObjectType(Ty) || 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; + fieldFlags |= BLOCK_FIELD_IS_OBJECT; + fieldNeedsCopyDispose = true; + } else if (getLangOptions().CPlusPlus) { + if (getContext().getBlockVarCopyInits(&D)) + fieldNeedsCopyDispose = true; + else if (const CXXRecordDecl *record = D.getType()->getAsCXXRecordDecl()) + fieldNeedsCopyDispose = !record->hasTrivialDestructor(); } // FIXME: Someone double check this. if (Ty.isObjCGCWeak()) - flag |= BLOCK_FIELD_IS_WEAK; + fieldFlags |= BLOCK_FIELD_IS_WEAK; int isa = 0; - if (flag & BLOCK_FIELD_IS_WEAK) + if (fieldFlags & BLOCK_FIELD_IS_WEAK) isa = 1; - V = Builder.CreateIntToPtr(Builder.getInt32(isa), PtrToInt8Ty, "isa"); + V = Builder.CreateIntToPtr(Builder.getInt32(isa), Int8PtrTy, "isa"); Builder.CreateStore(V, isa_field); Builder.CreateStore(DeclPtr, forwarding_field); - Builder.CreateStore(Builder.getInt32(flags), flags_field); + Builder.CreateStore(Builder.getInt32(fieldFlags.getBitMask()), flags_field); const llvm::Type *V1; V1 = cast<llvm::PointerType>(DeclPtr->getType())->getElementType(); V = Builder.getInt32(CGM.GetTargetTypeStoreSize(V1).getQuantity()); Builder.CreateStore(V, size_field); - if (flags & BLOCK_HAS_COPY_DISPOSE) { + if (fieldNeedsCopyDispose) { llvm::Value *copy_helper = Builder.CreateStructGEP(DeclPtr, 4); - Builder.CreateStore(BuildbyrefCopyHelper(DeclPtr->getType(), flag, - Align.getQuantity(), &D), + Builder.CreateStore(CGM.BuildbyrefCopyHelper(DeclPtr->getType(), + fieldFlags, + Align.getQuantity(), &D), copy_helper); llvm::Value *destroy_helper = Builder.CreateStructGEP(DeclPtr, 5); - Builder.CreateStore(BuildbyrefDestroyHelper(DeclPtr->getType(), flag, - Align.getQuantity(), &D), + Builder.CreateStore(CGM.BuildbyrefDestroyHelper(DeclPtr->getType(), + fieldFlags, + Align.getQuantity(), &D), destroy_helper); } } @@ -814,10 +815,10 @@ void CodeGenFunction::EmitAutoVarDecl(const VarDecl &D, assert(Init != 0 && "Wasn't a simple constant init?"); llvm::Value *SizeVal = - llvm::ConstantInt::get(CGF.IntPtrTy, + llvm::ConstantInt::get(IntPtrTy, getContext().getTypeSizeInChars(Ty).getQuantity()); - const llvm::Type *BP = Builder.getInt8PtrTy(); + const llvm::Type *BP = Int8PtrTy; if (Loc->getType() != BP) Loc = Builder.CreateBitCast(Loc, BP, "tmp"); |