More codegen for blocks. The type of block literals should be better.

The size calculation is improved.

llvm-svn: 64994
This commit is contained in:
Mike Stump
2009-02-19 01:01:04 +00:00
parent 0f3dd9a86b
commit 5d2534ada7
5 changed files with 62 additions and 12 deletions

View File

@@ -46,8 +46,13 @@ llvm::Constant *CodeGenFunction::BuildDescriptorBlockDecl() {
Elts.push_back(C);
// Size
int sz = CGM.getTargetData()
.getTypeStoreSizeInBits(CGM.getGenericBlockLiteralType()) / 8;
int sz;
if (!BlockHasCopyDispose)
sz = CGM.getTargetData()
.getTypeStoreSizeInBits(CGM.getGenericBlockLiteralType()) / 8;
else
sz = CGM.getTargetData()
.getTypeStoreSizeInBits(CGM.getGenericExtendedBlockLiteralType()) / 8;
C = llvm::ConstantInt::get(UnsignedLongTy, sz);
Elts.push_back(C);
@@ -107,6 +112,8 @@ llvm::Constant *CodeGenModule::getNSConcreteStackBlock() {
return NSConcreteStackBlock;
}
// FIXME: Push most into CGM, passing down a few bits, like current
// function name.
llvm::Constant *CodeGenFunction::BuildBlockLiteralTmp(const BlockExpr *BE) {
// FIXME: Push up
bool BlockHasCopyDispose = false;
@@ -146,7 +153,7 @@ llvm::Constant *CodeGenFunction::BuildBlockLiteralTmp(const BlockExpr *BE) {
C = llvm::ConstantInt::get(IntTy, 0);
Elts.push_back(C);
// __FuncPtr
// __invoke
const char *Name = "";
if (const NamedDecl *ND = dyn_cast<NamedDecl>(CurFuncDecl))
if (ND->getIdentifier())
@@ -168,6 +175,8 @@ llvm::Constant *CodeGenFunction::BuildBlockLiteralTmp(const BlockExpr *BE) {
C = new llvm::GlobalVariable(C->getType(), true,
llvm::GlobalValue::InternalLinkage,
C, Name, &CGM.getModule());
QualType BPT = BE->getType();
C = llvm::ConstantExpr::getBitCast(C, ConvertType(BPT));
return C;
}
@@ -210,11 +219,11 @@ CodeGenModule::getGenericBlockLiteralType() {
getTypes().ConvertType(getContext().IntTy));
// struct __block_literal_generic {
// void *isa;
// int flags;
// int reserved;
// void (*invoke)(void *);
// struct __block_descriptor *descriptor;
// void *__isa;
// int __flags;
// int __reserved;
// void (*__invoke)(void *);
// struct __block_descriptor *__descriptor;
// };
GenericBlockLiteralType = llvm::StructType::get(Int8PtrTy,
IntTy,
@@ -229,6 +238,44 @@ CodeGenModule::getGenericBlockLiteralType() {
return GenericBlockLiteralType;
}
const llvm::Type *
CodeGenModule::getGenericExtendedBlockLiteralType() {
if (GenericExtendedBlockLiteralType)
return GenericExtendedBlockLiteralType;
const llvm::Type *Int8PtrTy =
llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
const llvm::Type *BlockDescPtrTy =
llvm::PointerType::getUnqual(getBlockDescriptorType());
const llvm::IntegerType *IntTy = cast<llvm::IntegerType>(
getTypes().ConvertType(getContext().IntTy));
// struct __block_literal_generic {
// void *__isa;
// int __flags;
// int __reserved;
// void (*__invoke)(void *);
// struct __block_descriptor *__descriptor;
// void *__copy_func_helper_decl;
// void *__destroy_func_decl;
// };
GenericExtendedBlockLiteralType = llvm::StructType::get(Int8PtrTy,
IntTy,
IntTy,
Int8PtrTy,
BlockDescPtrTy,
Int8PtrTy,
Int8PtrTy,
NULL);
getModule().addTypeName("struct.__block_literal_extended_generic",
GenericExtendedBlockLiteralType);
return GenericExtendedBlockLiteralType;
}
/// getBlockFunctionType - Given a BlockPointerType, will return the
/// function type for the block, including the first block literal argument.
static QualType getBlockFunctionType(ASTContext &Ctx,