Unconditionally support block introspection data in a new field at the end

of the block descriptor field.  This field is the ObjC style @encode
signature of the implementation function, and was to this point
conditionally provided in the block literal data structure.  That
provisional support is removed.

Additionally, eliminate unused enumerations for the block literal flags field.
The first shipping ABI unconditionally set (1<<29) but this bit is unused
by the runtime, so the second ABI will unconditionally have (1<<30) set so
that the runtime can in fact distinguish whether the additional data is
present or not.

llvm-svn: 96989
This commit is contained in:
Blaine Garst
2010-02-23 21:51:17 +00:00
parent c26ddccf38
commit fc83aa04db
7 changed files with 140 additions and 59 deletions

View File

@@ -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);