diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/AST/ExprConstant.cpp | 1 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGBlocks.cpp | 63 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGExprConstant.cpp | 3 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGExprScalar.cpp | 5 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.h | 2 |
5 files changed, 62 insertions, 12 deletions
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index ee698d6c93f..d573236783e 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -260,6 +260,7 @@ public: APValue VisitAddrLabelExpr(AddrLabelExpr *E) { return APValue(E, 0); } APValue VisitCallExpr(CallExpr *E); + APValue VisitBlockExpr(BlockExpr *E) { return APValue(E, 0); } APValue VisitConditionalOperator(ConditionalOperator *E); }; } // end anonymous namespace diff --git a/clang/lib/CodeGen/CGBlocks.cpp b/clang/lib/CodeGen/CGBlocks.cpp index 4a940960730..9a130d7bc0e 100644 --- a/clang/lib/CodeGen/CGBlocks.cpp +++ b/clang/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/clang/lib/CodeGen/CGExprConstant.cpp b/clang/lib/CodeGen/CGExprConstant.cpp index 15dab8faf7b..651a283baa8 100644 --- a/clang/lib/CodeGen/CGExprConstant.cpp +++ b/clang/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/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp index 4b185f61018..eb134573729 100644 --- a/clang/lib/CodeGen/CGExprScalar.cpp +++ b/clang/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/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h index 24453ccadc7..b7d3aa9f38e 100644 --- a/clang/lib/CodeGen/CodeGenModule.h +++ b/clang/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. |