diff options
Diffstat (limited to 'lib/CodeGen/CGBlocks.cpp')
-rw-r--r-- | lib/CodeGen/CGBlocks.cpp | 97 |
1 files changed, 44 insertions, 53 deletions
diff --git a/lib/CodeGen/CGBlocks.cpp b/lib/CodeGen/CGBlocks.cpp index c6c5d5a230..7076067e43 100644 --- a/lib/CodeGen/CGBlocks.cpp +++ b/lib/CodeGen/CGBlocks.cpp @@ -24,7 +24,7 @@ using namespace clang; using namespace CodeGen; llvm::Constant *CodeGenFunction:: -BuildDescriptorBlockDecl(bool BlockHasCopyDispose, CharUnits Size, +BuildDescriptorBlockDecl(const BlockExpr *BE, bool BlockHasCopyDispose, CharUnits Size, const llvm::StructType* Ty, std::vector<HelperInfo> *NoteForHelper) { const llvm::Type *UnsignedLongTy @@ -43,6 +43,7 @@ BuildDescriptorBlockDecl(bool BlockHasCopyDispose, CharUnits Size, C = llvm::ConstantInt::get(UnsignedLongTy, Size.getQuantity()); Elts.push_back(C); + // optional copy/dispose helpers if (BlockHasCopyDispose) { // copy_func_helper_decl Elts.push_back(BuildCopyHelper(Ty, NoteForHelper)); @@ -51,6 +52,17 @@ BuildDescriptorBlockDecl(bool BlockHasCopyDispose, CharUnits Size, Elts.push_back(BuildDestroyHelper(Ty, NoteForHelper)); } + // Signature. non-optional ObjC-style method descriptor @encode sequence + std::string BlockTypeEncoding; + CGM.getContext().getObjCEncodingForBlock(BE, BlockTypeEncoding); + + Elts.push_back(llvm::ConstantExpr::getBitCast( + CGM.GetAddrOfConstantCString(BlockTypeEncoding), PtrToInt8Ty)); + + // Layout. + C = llvm::ConstantInt::get(UnsignedLongTy, 0); + Elts.push_back(C); + C = llvm::ConstantStruct::get(VMContext, Elts, false); C = new llvm::GlobalVariable(CGM.getModule(), C->getType(), true, @@ -135,30 +147,14 @@ llvm::Value *CodeGenFunction::BuildBlockLiteralTmp(const BlockExpr *BE) { size_t BlockFields = 5; - bool hasIntrospection = CGM.getContext().getLangOptions().BlockIntrospection; - - if (hasIntrospection) { - BlockFields++; - } std::vector<llvm::Constant*> Elts(BlockFields); - if (hasIntrospection) { - std::string BlockTypeEncoding; - CGM.getContext().getObjCEncodingForBlock(BE, BlockTypeEncoding); - - Elts[5] = llvm::ConstantExpr::getBitCast( - CGM.GetAddrOfConstantCString(BlockTypeEncoding), PtrToInt8Ty); - } - llvm::Constant *C; llvm::Value *V; { // C = BuildBlockStructInitlist(); - unsigned int flags = BLOCK_HAS_DESCRIPTOR; - - if (hasIntrospection) - flags |= BLOCK_HAS_OBJC_TYPE; + unsigned int flags = BLOCK_HAS_OBJC_TYPE; // We run this first so that we set BlockHasCopyDispose from the entire // block literal. @@ -199,7 +195,7 @@ llvm::Value *CodeGenFunction::BuildBlockLiteralTmp(const BlockExpr *BE) { if (subBlockDeclRefDecls.size() == 0) { // __descriptor - Elts[4] = BuildDescriptorBlockDecl(subBlockHasCopyDispose, subBlockSize, + Elts[4] = BuildDescriptorBlockDecl(BE, subBlockHasCopyDispose, subBlockSize, 0, 0); // Optimize to being a global block. @@ -221,8 +217,6 @@ llvm::Value *CodeGenFunction::BuildBlockLiteralTmp(const BlockExpr *BE) { for (int i=0; i<4; ++i) Types[i] = Elts[i]->getType(); Types[4] = PtrToInt8Ty; - if (hasIntrospection) - Types[5] = PtrToInt8Ty; for (unsigned i=0; i < subBlockDeclRefDecls.size(); ++i) { const Expr *E = subBlockDeclRefDecls[i]; @@ -245,8 +239,6 @@ llvm::Value *CodeGenFunction::BuildBlockLiteralTmp(const BlockExpr *BE) { for (unsigned i=0; i<4; ++i) Builder.CreateStore(Elts[i], Builder.CreateStructGEP(V, i, "block.tmp")); - if (hasIntrospection) - Builder.CreateStore(Elts[5], Builder.CreateStructGEP(V, 5, "block.tmp")); for (unsigned i=0; i < subBlockDeclRefDecls.size(); ++i) { @@ -335,7 +327,8 @@ llvm::Value *CodeGenFunction::BuildBlockLiteralTmp(const BlockExpr *BE) { NoteForHelper.resize(helpersize); // __descriptor - llvm::Value *Descriptor = BuildDescriptorBlockDecl(subBlockHasCopyDispose, + llvm::Value *Descriptor = BuildDescriptorBlockDecl(BE, + subBlockHasCopyDispose, subBlockSize, Ty, &NoteForHelper); Descriptor = Builder.CreateBitCast(Descriptor, PtrToInt8Ty); @@ -371,6 +364,16 @@ const llvm::Type *BlockModule::getBlockDescriptorType() { // struct __block_descriptor { // unsigned long reserved; // unsigned long block_size; + // + // // later, the following will be added + // + // struct { + // void (*copyHelper)(); + // void (*copyHelper)(); + // } helpers; // !!! optional + // + // const char *signature; // the block signature + // const char *layout; // reserved // }; BlockDescriptorType = llvm::StructType::get(UnsignedLongTy->getContext(), UnsignedLongTy, @@ -399,20 +402,8 @@ const llvm::Type *BlockModule::getGenericBlockLiteralType() { // int __reserved; // void (*__invoke)(void *); // struct __block_descriptor *__descriptor; - // // GNU runtime only: - // const char *types; // }; - if (CGM.getContext().getLangOptions().BlockIntrospection) - GenericBlockLiteralType = llvm::StructType::get(IntTy->getContext(), - PtrToInt8Ty, - IntTy, - IntTy, - PtrToInt8Ty, - BlockDescPtrTy, - PtrToInt8Ty, - NULL); - else - GenericBlockLiteralType = llvm::StructType::get(IntTy->getContext(), + GenericBlockLiteralType = llvm::StructType::get(IntTy->getContext(), PtrToInt8Ty, IntTy, IntTy, @@ -556,7 +547,7 @@ BlockModule::GetAddrOfGlobalBlock(const BlockExpr *BE, const char * n) { const llvm::IntegerType *IntTy = cast<llvm::IntegerType>( getTypes().ConvertType(getContext().IntTy)); - llvm::Constant *DescriptorFields[2]; + llvm::Constant *DescriptorFields[4]; // Reserved DescriptorFields[0] = llvm::Constant::getNullValue(UnsignedLongTy); @@ -567,9 +558,21 @@ BlockModule::GetAddrOfGlobalBlock(const BlockExpr *BE, const char * n) { CGM.GetTargetTypeStoreSize(getGenericBlockLiteralType()); DescriptorFields[1] = llvm::ConstantInt::get(UnsignedLongTy,BlockLiteralSize.getQuantity()); + + // signature. non-optional ObjC-style method descriptor @encode sequence + std::string BlockTypeEncoding; + CGM.getContext().getObjCEncodingForBlock(BE, BlockTypeEncoding); + + DescriptorFields[2] = llvm::ConstantExpr::getBitCast( + CGM.GetAddrOfConstantCString(BlockTypeEncoding), PtrToInt8Ty); + + // layout + DescriptorFields[3] = + llvm::ConstantInt::get(UnsignedLongTy,0); + // build the structure from the 4 elements llvm::Constant *DescriptorStruct = - llvm::ConstantStruct::get(VMContext, &DescriptorFields[0], 2, false); + llvm::ConstantStruct::get(VMContext, &DescriptorFields[0], 4, false); llvm::GlobalVariable *Descriptor = new llvm::GlobalVariable(getModule(), DescriptorStruct->getType(), true, @@ -578,8 +581,6 @@ BlockModule::GetAddrOfGlobalBlock(const BlockExpr *BE, const char * n) { int FieldCount = 5; // Generate the constants for the block literal. - if (CGM.getContext().getLangOptions().BlockIntrospection) - FieldCount = 6; std::vector<llvm::Constant*> LiteralFields(FieldCount); @@ -602,10 +603,8 @@ BlockModule::GetAddrOfGlobalBlock(const BlockExpr *BE, const char * n) { LiteralFields[0] = getNSConcreteGlobalBlock(); // Flags - LiteralFields[1] = CGM.getContext().getLangOptions().BlockIntrospection ? - llvm::ConstantInt::get(IntTy, BLOCK_IS_GLOBAL | BLOCK_HAS_DESCRIPTOR | - BLOCK_HAS_OBJC_TYPE) : - llvm::ConstantInt::get(IntTy, BLOCK_IS_GLOBAL | BLOCK_HAS_DESCRIPTOR); + LiteralFields[1] = + llvm::ConstantInt::get(IntTy, BLOCK_IS_GLOBAL | BLOCK_HAS_OBJC_TYPE); // Reserved LiteralFields[2] = llvm::Constant::getNullValue(IntTy); @@ -616,14 +615,6 @@ BlockModule::GetAddrOfGlobalBlock(const BlockExpr *BE, const char * n) { // Descriptor LiteralFields[4] = Descriptor; - // Type encoding - if (CGM.getContext().getLangOptions().BlockIntrospection) { - std::string BlockTypeEncoding; - CGM.getContext().getObjCEncodingForBlock(BE, BlockTypeEncoding); - - LiteralFields[5] = CGM.GetAddrOfConstantCString(BlockTypeEncoding); - } - llvm::Constant *BlockLiteralStruct = llvm::ConstantStruct::get(VMContext, LiteralFields, false); |