aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGBlocks.cpp
diff options
context:
space:
mode:
authorMike Stump <mrs@apple.com>2009-02-13 16:19:19 +0000
committerMike Stump <mrs@apple.com>2009-02-13 16:19:19 +0000
commite5fee25e71266712522cff554f25c59b3078a429 (patch)
treedd20d9442f0320de0d38d35b4fabb437a88188f4 /lib/CodeGen/CGBlocks.cpp
parent7cbb3608a7c28a7fb285fdc7f44060c5c175c8a0 (diff)
Condense all the blocks code into CGBlocks.cpp.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@64457 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGBlocks.cpp')
-rw-r--r--lib/CodeGen/CGBlocks.cpp133
1 files changed, 130 insertions, 3 deletions
diff --git a/lib/CodeGen/CGBlocks.cpp b/lib/CodeGen/CGBlocks.cpp
index 7708df5b0e..25c5ab6b71 100644
--- a/lib/CodeGen/CGBlocks.cpp
+++ b/lib/CodeGen/CGBlocks.cpp
@@ -21,11 +21,138 @@
using namespace clang;
using namespace CodeGen;
-// Block flags
enum {
- IsGlobal = 1 << 28
+ BLOCK_NEEDS_FREE = (1 << 24),
+ BLOCK_HAS_COPY_DISPOSE = (1 << 25),
+ BLOCK_HAS_CXX_OBJ = (1 << 26),
+ BLOCK_IS_GC = (1 << 27),
+ BLOCK_IS_GLOBAL = (1 << 28),
+ BLOCK_HAS_DESCRIPTOR = (1 << 29)
};
+llvm::Constant *CodeGenFunction::BuildDescriptorBlockDecl() {
+ // FIXME: Push up.
+ bool BlockHasCopyDispose = false;
+
+ const llvm::PointerType *PtrToInt8Ty
+ = llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
+ llvm::Constant *C;
+ std::vector<llvm::Constant*> Elts;
+
+ // reserved
+ const llvm::IntegerType *LongTy
+ = cast<llvm::IntegerType>(
+ CGM.getTypes().ConvertType(CGM.getContext().LongTy));
+ C = llvm::ConstantInt::get(LongTy, 0);
+ Elts.push_back(C);
+
+ // Size
+ // FIXME: This should be the size of BlockStructType
+ C = llvm::ConstantInt::get(LongTy, 20);
+ Elts.push_back(C);
+
+ if (BlockHasCopyDispose) {
+ // copy_func_helper_decl
+ C = llvm::ConstantInt::get(LongTy, 0);
+ C = llvm::ConstantExpr::getBitCast(C, PtrToInt8Ty);
+ Elts.push_back(C);
+
+ // destroy_func_decl
+ C = llvm::ConstantInt::get(LongTy, 0);
+ C = llvm::ConstantExpr::getBitCast(C, PtrToInt8Ty);
+ Elts.push_back(C);
+ }
+
+ C = llvm::ConstantStruct::get(Elts);
+
+ // FIXME: Should be in module?
+ static int desc_unique_count;
+ char Name[32];
+ sprintf(Name, "__block_descriptor_tmp_%d", ++desc_unique_count);
+ C = new llvm::GlobalVariable(C->getType(), true,
+ llvm::GlobalValue::InternalLinkage,
+ C, Name, &CGM.getModule());
+ return C;
+}
+
+llvm::Constant *CodeGenFunction::BuildBlockLiteralTmp() {
+ // FIXME: Push up
+ bool BlockHasCopyDispose = false;
+ bool insideFunction = false;
+ bool BlockRefDeclList = false;
+ bool BlockByrefDeclList = false;
+
+ std::vector<llvm::Constant*> Elts;
+ llvm::Constant *C;
+
+ bool staticBlockTmp = (BlockRefDeclList == 0
+ && BlockByrefDeclList == 0);
+
+ {
+ // C = BuildBlockStructInitlist();
+ unsigned int flags = BLOCK_HAS_DESCRIPTOR;
+
+ if (BlockHasCopyDispose)
+ flags |= BLOCK_HAS_COPY_DISPOSE;
+
+ const llvm::PointerType *PtrToInt8Ty
+ = llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
+ // FIXME: static? What if we start up a new, unrelated module?
+ // logically we want 1 per module.
+ static llvm::Constant *NSConcreteGlobalBlock_decl
+ = new llvm::GlobalVariable(PtrToInt8Ty, false,
+ llvm::GlobalValue::ExternalLinkage,
+ 0, "_NSConcreteGlobalBlock",
+ &CGM.getModule());
+ static llvm::Constant *NSConcreteStackBlock_decl
+ = new llvm::GlobalVariable(PtrToInt8Ty, false,
+ llvm::GlobalValue::ExternalLinkage,
+ 0, "_NSConcreteStackBlock",
+ &CGM.getModule());
+ C = NSConcreteStackBlock_decl;
+ if (!insideFunction ||
+ (!BlockRefDeclList && !BlockByrefDeclList)) {
+ C = NSConcreteGlobalBlock_decl;
+ flags |= BLOCK_IS_GLOBAL;
+ }
+ C = llvm::ConstantExpr::getBitCast(C, PtrToInt8Ty);
+ Elts.push_back(C);
+
+ // __flags
+ const llvm::IntegerType *IntTy = cast<llvm::IntegerType>(
+ CGM.getTypes().ConvertType(CGM.getContext().IntTy));
+ C = llvm::ConstantInt::get(IntTy, flags);
+ Elts.push_back(C);
+
+ // __reserved
+ C = llvm::ConstantInt::get(IntTy, 0);
+ Elts.push_back(C);
+
+ // __FuncPtr
+ // FIXME: Build this up.
+ Elts.push_back(C);
+
+ // __descriptor
+ Elts.push_back(BuildDescriptorBlockDecl());
+
+ // FIXME: Add block_original_ref_decl_list and block_byref_decl_list.
+ }
+
+ C = llvm::ConstantStruct::get(Elts);
+
+ char Name[32];
+ // FIXME: Boost in CGM?
+ static int global_unique_count;
+ sprintf(Name, "__block_holder_tmp_%d", ++global_unique_count);
+ C = new llvm::GlobalVariable(C->getType(), true,
+ llvm::GlobalValue::InternalLinkage,
+ C, Name, &CGM.getModule());
+ return C;
+}
+
+
+
+
const llvm::Type *CodeGenModule::getBlockDescriptorType() {
if (BlockDescriptorType)
return BlockDescriptorType;
@@ -192,7 +319,7 @@ llvm::Constant *CodeGenModule::GetAddrOfGlobalBlock(const BlockExpr *BE) {
LiteralFields[0] = NSConcreteGlobalBlock;
// Flags
- LiteralFields[1] = llvm::ConstantInt::get(IntTy, IsGlobal);
+ LiteralFields[1] = llvm::ConstantInt::get(IntTy, BLOCK_IS_GLOBAL);
// Reserved
LiteralFields[2] = llvm::Constant::getNullValue(IntTy);