diff options
author | rdivacky <rdivacky@FreeBSD.org> | 2009-11-18 14:59:57 +0000 |
---|---|---|
committer | rdivacky <rdivacky@FreeBSD.org> | 2009-11-18 14:59:57 +0000 |
commit | 741c13ecc20fb35b836ad690aeecd402f002d654 (patch) | |
tree | 60a1694bec5a44d15456acc880cb2f91619f66aa /lib/CodeGen/CGBlocks.cpp | |
parent | b3a51061b1b9c4add078237850649f7c9efb13ab (diff) | |
download | FreeBSD-src-741c13ecc20fb35b836ad690aeecd402f002d654.zip FreeBSD-src-741c13ecc20fb35b836ad690aeecd402f002d654.tar.gz |
Update clang to r89205.
Diffstat (limited to 'lib/CodeGen/CGBlocks.cpp')
-rw-r--r-- | lib/CodeGen/CGBlocks.cpp | 69 |
1 files changed, 59 insertions, 10 deletions
diff --git a/lib/CodeGen/CGBlocks.cpp b/lib/CodeGen/CGBlocks.cpp index 682cf5d..bc9eb67 100644 --- a/lib/CodeGen/CGBlocks.cpp +++ b/lib/CodeGen/CGBlocks.cpp @@ -146,7 +146,23 @@ llvm::Value *CodeGenFunction::BuildBlockLiteralTmp(const BlockExpr *BE) { if (0 && CanBlockBeGlobal(Info)) return CGM.GetAddrOfGlobalBlock(BE, Name.c_str()); - std::vector<llvm::Constant*> Elts(5); + 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; @@ -154,6 +170,9 @@ llvm::Value *CodeGenFunction::BuildBlockLiteralTmp(const BlockExpr *BE) { // C = BuildBlockStructInitlist(); unsigned int flags = BLOCK_HAS_DESCRIPTOR; + if (hasIntrospection) + flags |= BLOCK_HAS_OBJC_TYPE; + // We run this first so that we set BlockHasCopyDispose from the entire // block literal. // __invoke @@ -211,19 +230,21 @@ llvm::Value *CodeGenFunction::BuildBlockLiteralTmp(const BlockExpr *BE) { return C; } - std::vector<const llvm::Type *> Types(5+subBlockDeclRefDecls.size()); + std::vector<const llvm::Type *> Types(BlockFields+subBlockDeclRefDecls.size()); 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]; const BlockDeclRefExpr *BDRE = dyn_cast<BlockDeclRefExpr>(E); QualType Ty = E->getType(); if (BDRE && BDRE->isByRef()) { - Types[i+5] = llvm::PointerType::get(BuildByRefType(BDRE->getDecl()), 0); + Types[i+BlockFields] = llvm::PointerType::get(BuildByRefType(BDRE->getDecl()), 0); } else - Types[i+5] = ConvertType(Ty); + Types[i+BlockFields] = ConvertType(Ty); } llvm::StructType *Ty = llvm::StructType::get(VMContext, Types, true); @@ -237,6 +258,8 @@ 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) { @@ -252,7 +275,7 @@ llvm::Value *CodeGenFunction::BuildBlockLiteralTmp(const BlockExpr *BE) { BlockDeclRefExpr *BDRE = dyn_cast<BlockDeclRefExpr>(E); VD = BDRE->getDecl(); - llvm::Value* Addr = Builder.CreateStructGEP(V, i+5, "tmp"); + llvm::Value* Addr = Builder.CreateStructGEP(V, i+BlockFields, "tmp"); NoteForHelper[helpersize].index = i+5; NoteForHelper[helpersize].RequiresCopying = BlockRequiresCopying(VD->getType()); @@ -291,7 +314,7 @@ llvm::Value *CodeGenFunction::BuildBlockLiteralTmp(const BlockExpr *BE) { RValue r = EmitAnyExpr(E, Addr, false); if (r.isScalar()) { llvm::Value *Loc = r.getScalarVal(); - const llvm::Type *Ty = Types[i+5]; + const llvm::Type *Ty = Types[i+BlockFields]; if (BDRE->isByRef()) { // E is now the address of the value field, instead, we want the // address of the actual ByRef struct. We optimize this slightly @@ -375,8 +398,20 @@ const llvm::Type *BlockModule::getGenericBlockLiteralType() { // int __reserved; // void (*__invoke)(void *); // struct __block_descriptor *__descriptor; + // // GNU runtime only: + // const char *types; // }; - GenericBlockLiteralType = llvm::StructType::get(IntTy->getContext(), + 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(), PtrToInt8Ty, IntTy, IntTy, @@ -571,8 +606,12 @@ BlockModule::GetAddrOfGlobalBlock(const BlockExpr *BE, const char * n) { llvm::GlobalVariable::InternalLinkage, DescriptorStruct, "__block_descriptor_global"); + int FieldCount = 5; // Generate the constants for the block literal. - llvm::Constant *LiteralFields[5]; + if (CGM.getContext().getLangOptions().BlockIntrospection) + FieldCount = 6; + + std::vector<llvm::Constant*> LiteralFields(FieldCount); CodeGenFunction::BlockInfo Info(0, n); uint64_t subBlockSize, subBlockAlign; @@ -592,7 +631,9 @@ BlockModule::GetAddrOfGlobalBlock(const BlockExpr *BE, const char * n) { LiteralFields[0] = getNSConcreteGlobalBlock(); // Flags - LiteralFields[1] = + 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); // Reserved @@ -603,9 +644,17 @@ 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[0], 5, false); + llvm::ConstantStruct::get(VMContext, LiteralFields, false); llvm::GlobalVariable *BlockLiteral = new llvm::GlobalVariable(getModule(), BlockLiteralStruct->getType(), true, |