diff options
author | Mike Stump <mrs@apple.com> | 2009-02-19 01:01:04 +0000 |
---|---|---|
committer | Mike Stump <mrs@apple.com> | 2009-02-19 01:01:04 +0000 |
commit | bd65cac8de63d108a681035782a71d42954b03ab (patch) | |
tree | 24940ea04c00270874f9be9f9dfbf3a377d94346 /lib/CodeGen | |
parent | 611a8c49c6a5848aed17eced8f2f3f7b1b7577a1 (diff) |
More codegen for blocks. The type of block literals should be better.
The size calculation is improved.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@64994 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen')
-rw-r--r-- | lib/CodeGen/CGBlocks.cpp | 63 | ||||
-rw-r--r-- | lib/CodeGen/CGExprConstant.cpp | 3 | ||||
-rw-r--r-- | lib/CodeGen/CGExprScalar.cpp | 5 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenModule.h | 2 |
4 files changed, 61 insertions, 12 deletions
diff --git a/lib/CodeGen/CGBlocks.cpp b/lib/CodeGen/CGBlocks.cpp index 4a94096073..9a130d7bc0 100644 --- a/lib/CodeGen/CGBlocks.cpp +++ b/lib/CodeGen/CGBlocks.cpp @@ -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, diff --git a/lib/CodeGen/CGExprConstant.cpp b/lib/CodeGen/CGExprConstant.cpp index 15dab8faf7..651a283baa 100644 --- a/lib/CodeGen/CGExprConstant.cpp +++ b/lib/CodeGen/CGExprConstant.cpp @@ -614,6 +614,9 @@ public: std::string S(Literal->getStrData(), Literal->getByteLength()); return CGM.GetAddrOfConstantCFString(S); } + case Expr::BlockExprClass: { + return CGF->BuildBlockLiteralTmp(cast<BlockExpr>(E)); + } } return 0; diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp index 4b185f6101..eb13457372 100644 --- a/lib/CodeGen/CGExprScalar.cpp +++ b/lib/CodeGen/CGExprScalar.cpp @@ -1364,10 +1364,7 @@ Value *ScalarExprEmitter::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) { Value *ScalarExprEmitter::VisitBlockExpr(const BlockExpr *BE) { llvm::Constant *C = CGF.BuildBlockLiteralTmp(BE); - - const llvm::PointerType *PtrToInt8Ty - = llvm::PointerType::getUnqual(llvm::Type::Int8Ty); - return llvm::ConstantExpr::getBitCast(C, PtrToInt8Ty); + return C; } //===----------------------------------------------------------------------===// diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h index 24453ccadc..b7d3aa9f38 100644 --- a/lib/CodeGen/CodeGenModule.h +++ b/lib/CodeGen/CodeGenModule.h @@ -145,6 +145,7 @@ class CodeGenModule { const llvm::Type *BlockDescriptorType; const llvm::Type *GenericBlockLiteralType; + const llvm::Type *GenericExtendedBlockLiteralType; struct { int GlobalUniqueCount; } Block; @@ -166,6 +167,7 @@ public: const llvm::Type *getBlockDescriptorType(); const llvm::Type *getGenericBlockLiteralType(); + const llvm::Type *getGenericExtendedBlockLiteralType(); /// getObjCRuntime() - Return a reference to the configured /// Objective-C runtime. |