CGBlocks.cpp revision bd65cac8de63d108a681035782a71d42954b03ab
1//===--- CGBlocks.cpp - Emit LLVM Code for declarations -------------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This contains code to emit blocks. 11// 12//===----------------------------------------------------------------------===// 13 14#include "CodeGenFunction.h" 15#include "CodeGenModule.h" 16#include "llvm/Module.h" 17#include "llvm/Target/TargetData.h" 18 19#include <algorithm> 20 21using namespace clang; 22using namespace CodeGen; 23 24enum { 25 BLOCK_NEEDS_FREE = (1 << 24), 26 BLOCK_HAS_COPY_DISPOSE = (1 << 25), 27 BLOCK_HAS_CXX_OBJ = (1 << 26), 28 BLOCK_IS_GC = (1 << 27), 29 BLOCK_IS_GLOBAL = (1 << 28), 30 BLOCK_HAS_DESCRIPTOR = (1 << 29) 31}; 32 33llvm::Constant *CodeGenFunction::BuildDescriptorBlockDecl() { 34 // FIXME: Push up. 35 bool BlockHasCopyDispose = false; 36 37 const llvm::PointerType *PtrToInt8Ty 38 = llvm::PointerType::getUnqual(llvm::Type::Int8Ty); 39 const llvm::Type *UnsignedLongTy 40 = CGM.getTypes().ConvertType(getContext().UnsignedLongTy); 41 llvm::Constant *C; 42 std::vector<llvm::Constant*> Elts; 43 44 // reserved 45 C = llvm::ConstantInt::get(UnsignedLongTy, 0); 46 Elts.push_back(C); 47 48 // Size 49 int sz; 50 if (!BlockHasCopyDispose) 51 sz = CGM.getTargetData() 52 .getTypeStoreSizeInBits(CGM.getGenericBlockLiteralType()) / 8; 53 else 54 sz = CGM.getTargetData() 55 .getTypeStoreSizeInBits(CGM.getGenericExtendedBlockLiteralType()) / 8; 56 C = llvm::ConstantInt::get(UnsignedLongTy, sz); 57 Elts.push_back(C); 58 59 if (BlockHasCopyDispose) { 60 // copy_func_helper_decl 61 C = llvm::ConstantInt::get(UnsignedLongTy, 0); 62 C = llvm::ConstantExpr::getBitCast(C, PtrToInt8Ty); 63 Elts.push_back(C); 64 65 // destroy_func_decl 66 C = llvm::ConstantInt::get(UnsignedLongTy, 0); 67 C = llvm::ConstantExpr::getBitCast(C, PtrToInt8Ty); 68 Elts.push_back(C); 69 } 70 71 C = llvm::ConstantStruct::get(Elts); 72 73 C = new llvm::GlobalVariable(C->getType(), true, 74 llvm::GlobalValue::InternalLinkage, 75 C, "__block_descriptor_tmp", &CGM.getModule()); 76 return C; 77} 78 79llvm::Constant *CodeGenModule::getNSConcreteGlobalBlock() { 80 if (NSConcreteGlobalBlock) 81 return NSConcreteGlobalBlock; 82 83 const llvm::PointerType *PtrToInt8Ty 84 = llvm::PointerType::getUnqual(llvm::Type::Int8Ty); 85 // FIXME: We should have a CodeGenModule::AddRuntimeVariable that does the 86 // same thing as CreateRuntimeFunction if there's already a variable with 87 // the same name. 88 NSConcreteGlobalBlock 89 = new llvm::GlobalVariable(PtrToInt8Ty, false, 90 llvm::GlobalValue::ExternalLinkage, 91 0, "_NSConcreteGlobalBlock", 92 &getModule()); 93 94 return NSConcreteGlobalBlock; 95} 96 97llvm::Constant *CodeGenModule::getNSConcreteStackBlock() { 98 if (NSConcreteStackBlock) 99 return NSConcreteStackBlock; 100 101 const llvm::PointerType *PtrToInt8Ty 102 = llvm::PointerType::getUnqual(llvm::Type::Int8Ty); 103 // FIXME: We should have a CodeGenModule::AddRuntimeVariable that does the 104 // same thing as CreateRuntimeFunction if there's already a variable with 105 // the same name. 106 NSConcreteStackBlock 107 = new llvm::GlobalVariable(PtrToInt8Ty, false, 108 llvm::GlobalValue::ExternalLinkage, 109 0, "_NSConcreteStackBlock", 110 &getModule()); 111 112 return NSConcreteStackBlock; 113} 114 115// FIXME: Push most into CGM, passing down a few bits, like current 116// function name. 117llvm::Constant *CodeGenFunction::BuildBlockLiteralTmp(const BlockExpr *BE) { 118 // FIXME: Push up 119 bool BlockHasCopyDispose = false; 120 bool insideFunction = false; 121 bool BlockRefDeclList = false; 122 bool BlockByrefDeclList = false; 123 124 std::vector<llvm::Constant*> Elts; 125 llvm::Constant *C; 126 127 { 128 // C = BuildBlockStructInitlist(); 129 unsigned int flags = BLOCK_HAS_DESCRIPTOR; 130 131 if (BlockHasCopyDispose) 132 flags |= BLOCK_HAS_COPY_DISPOSE; 133 134 // __isa 135 C = CGM.getNSConcreteStackBlock(); 136 if (!insideFunction || 137 (!BlockRefDeclList && !BlockByrefDeclList)) { 138 C = CGM.getNSConcreteGlobalBlock(); 139 flags |= BLOCK_IS_GLOBAL; 140 } 141 const llvm::PointerType *PtrToInt8Ty 142 = llvm::PointerType::getUnqual(llvm::Type::Int8Ty); 143 C = llvm::ConstantExpr::getBitCast(C, PtrToInt8Ty); 144 Elts.push_back(C); 145 146 // __flags 147 const llvm::IntegerType *IntTy = cast<llvm::IntegerType>( 148 CGM.getTypes().ConvertType(CGM.getContext().IntTy)); 149 C = llvm::ConstantInt::get(IntTy, flags); 150 Elts.push_back(C); 151 152 // __reserved 153 C = llvm::ConstantInt::get(IntTy, 0); 154 Elts.push_back(C); 155 156 // __invoke 157 const char *Name = ""; 158 if (const NamedDecl *ND = dyn_cast<NamedDecl>(CurFuncDecl)) 159 if (ND->getIdentifier()) 160 Name = ND->getNameAsCString(); 161 BlockInfo Info(0, Name); 162 llvm::Function *Fn = CodeGenFunction(*this).GenerateBlockFunction(BE, Info); 163 Elts.push_back(Fn); 164 165 // __descriptor 166 Elts.push_back(BuildDescriptorBlockDecl()); 167 168 // FIXME: Add block_original_ref_decl_list and block_byref_decl_list. 169 } 170 171 C = llvm::ConstantStruct::get(Elts); 172 173 char Name[32]; 174 sprintf(Name, "__block_holder_tmp_%d", CGM.getGlobalUniqueCount()); 175 C = new llvm::GlobalVariable(C->getType(), true, 176 llvm::GlobalValue::InternalLinkage, 177 C, Name, &CGM.getModule()); 178 QualType BPT = BE->getType(); 179 C = llvm::ConstantExpr::getBitCast(C, ConvertType(BPT)); 180 return C; 181} 182 183 184 185 186const llvm::Type *CodeGenModule::getBlockDescriptorType() { 187 if (BlockDescriptorType) 188 return BlockDescriptorType; 189 190 const llvm::Type *UnsignedLongTy = 191 getTypes().ConvertType(getContext().UnsignedLongTy); 192 193 // struct __block_descriptor { 194 // unsigned long reserved; 195 // unsigned long block_size; 196 // }; 197 BlockDescriptorType = llvm::StructType::get(UnsignedLongTy, 198 UnsignedLongTy, 199 NULL); 200 201 getModule().addTypeName("struct.__block_descriptor", 202 BlockDescriptorType); 203 204 return BlockDescriptorType; 205} 206 207const llvm::Type * 208CodeGenModule::getGenericBlockLiteralType() { 209 if (GenericBlockLiteralType) 210 return GenericBlockLiteralType; 211 212 const llvm::Type *Int8PtrTy = 213 llvm::PointerType::getUnqual(llvm::Type::Int8Ty); 214 215 const llvm::Type *BlockDescPtrTy = 216 llvm::PointerType::getUnqual(getBlockDescriptorType()); 217 218 const llvm::IntegerType *IntTy = cast<llvm::IntegerType>( 219 getTypes().ConvertType(getContext().IntTy)); 220 221 // struct __block_literal_generic { 222 // void *__isa; 223 // int __flags; 224 // int __reserved; 225 // void (*__invoke)(void *); 226 // struct __block_descriptor *__descriptor; 227 // }; 228 GenericBlockLiteralType = llvm::StructType::get(Int8PtrTy, 229 IntTy, 230 IntTy, 231 Int8PtrTy, 232 BlockDescPtrTy, 233 NULL); 234 235 getModule().addTypeName("struct.__block_literal_generic", 236 GenericBlockLiteralType); 237 238 return GenericBlockLiteralType; 239} 240 241const llvm::Type * 242CodeGenModule::getGenericExtendedBlockLiteralType() { 243 if (GenericExtendedBlockLiteralType) 244 return GenericExtendedBlockLiteralType; 245 246 const llvm::Type *Int8PtrTy = 247 llvm::PointerType::getUnqual(llvm::Type::Int8Ty); 248 249 const llvm::Type *BlockDescPtrTy = 250 llvm::PointerType::getUnqual(getBlockDescriptorType()); 251 252 const llvm::IntegerType *IntTy = cast<llvm::IntegerType>( 253 getTypes().ConvertType(getContext().IntTy)); 254 255 // struct __block_literal_generic { 256 // void *__isa; 257 // int __flags; 258 // int __reserved; 259 // void (*__invoke)(void *); 260 // struct __block_descriptor *__descriptor; 261 // void *__copy_func_helper_decl; 262 // void *__destroy_func_decl; 263 // }; 264 GenericExtendedBlockLiteralType = llvm::StructType::get(Int8PtrTy, 265 IntTy, 266 IntTy, 267 Int8PtrTy, 268 BlockDescPtrTy, 269 Int8PtrTy, 270 Int8PtrTy, 271 NULL); 272 273 getModule().addTypeName("struct.__block_literal_extended_generic", 274 GenericExtendedBlockLiteralType); 275 276 return GenericExtendedBlockLiteralType; 277} 278 279/// getBlockFunctionType - Given a BlockPointerType, will return the 280/// function type for the block, including the first block literal argument. 281static QualType getBlockFunctionType(ASTContext &Ctx, 282 const BlockPointerType *BPT) { 283 const FunctionTypeProto *FTy = cast<FunctionTypeProto>(BPT->getPointeeType()); 284 285 llvm::SmallVector<QualType, 8> Types; 286 Types.push_back(Ctx.getPointerType(Ctx.VoidTy)); 287 288 for (FunctionTypeProto::arg_type_iterator i = FTy->arg_type_begin(), 289 e = FTy->arg_type_end(); i != e; ++i) 290 Types.push_back(*i); 291 292 return Ctx.getFunctionType(FTy->getResultType(), 293 &Types[0], Types.size(), 294 FTy->isVariadic(), 0); 295} 296 297RValue CodeGenFunction::EmitBlockCallExpr(const CallExpr* E) { 298 const BlockPointerType *BPT = 299 E->getCallee()->getType()->getAsBlockPointerType(); 300 301 llvm::Value *Callee = EmitScalarExpr(E->getCallee()); 302 303 // Get a pointer to the generic block literal. 304 const llvm::Type *BlockLiteralTy = 305 llvm::PointerType::getUnqual(CGM.getGenericBlockLiteralType()); 306 307 // Bitcast the callee to a block literal. 308 llvm::Value *BlockLiteral = 309 Builder.CreateBitCast(Callee, BlockLiteralTy, "block.literal"); 310 311 // Get the function pointer from the literal. 312 llvm::Value *FuncPtr = Builder.CreateStructGEP(BlockLiteral, 3, "tmp"); 313 llvm::Value *Func = Builder.CreateLoad(FuncPtr, FuncPtr, "tmp"); 314 315 // Cast the function pointer to the right type. 316 const llvm::Type *BlockFTy = 317 ConvertType(getBlockFunctionType(getContext(), BPT)); 318 const llvm::Type *BlockFTyPtr = llvm::PointerType::getUnqual(BlockFTy); 319 Func = Builder.CreateBitCast(Func, BlockFTyPtr); 320 321 BlockLiteral = 322 Builder.CreateBitCast(BlockLiteral, 323 llvm::PointerType::getUnqual(llvm::Type::Int8Ty), 324 "tmp"); 325 326 // Add the block literal. 327 QualType VoidPtrTy = getContext().getPointerType(getContext().VoidTy); 328 CallArgList Args; 329 Args.push_back(std::make_pair(RValue::get(BlockLiteral), VoidPtrTy)); 330 331 // And the rest of the arguments. 332 for (CallExpr::const_arg_iterator i = E->arg_begin(), e = E->arg_end(); 333 i != e; ++i) 334 Args.push_back(std::make_pair(EmitAnyExprToTemp(*i), 335 i->getType())); 336 337 // And call the block. 338 return EmitCall(CGM.getTypes().getFunctionInfo(E->getType(), Args), 339 Func, Args); 340} 341 342llvm::Constant * 343CodeGenModule::GetAddrOfGlobalBlock(const BlockExpr *BE, const char * n) { 344 // Generate the block descriptor. 345 const llvm::Type *UnsignedLongTy = Types.ConvertType(Context.UnsignedLongTy); 346 const llvm::IntegerType *IntTy = cast<llvm::IntegerType>( 347 getTypes().ConvertType(getContext().IntTy)); 348 349 llvm::Constant *DescriptorFields[2]; 350 351 // Reserved 352 DescriptorFields[0] = llvm::Constant::getNullValue(UnsignedLongTy); 353 354 // Block literal size. For global blocks we just use the size of the generic 355 // block literal struct. 356 uint64_t BlockLiteralSize = 357 TheTargetData.getTypeStoreSizeInBits(getGenericBlockLiteralType()) / 8; 358 DescriptorFields[1] = llvm::ConstantInt::get(UnsignedLongTy,BlockLiteralSize); 359 360 llvm::Constant *DescriptorStruct = 361 llvm::ConstantStruct::get(&DescriptorFields[0], 2); 362 363 llvm::GlobalVariable *Descriptor = 364 new llvm::GlobalVariable(DescriptorStruct->getType(), true, 365 llvm::GlobalVariable::InternalLinkage, 366 DescriptorStruct, "__block_descriptor_global", 367 &getModule()); 368 369 // Generate the constants for the block literal. 370 llvm::Constant *LiteralFields[5]; 371 372 CodeGenFunction::BlockInfo Info(0, n); 373 llvm::Function *Fn = CodeGenFunction(*this).GenerateBlockFunction(BE, Info); 374 375 // isa 376 LiteralFields[0] = getNSConcreteGlobalBlock(); 377 378 // Flags 379 LiteralFields[1] = llvm::ConstantInt::get(IntTy, BLOCK_IS_GLOBAL); 380 381 // Reserved 382 LiteralFields[2] = llvm::Constant::getNullValue(IntTy); 383 384 // Function 385 LiteralFields[3] = Fn; 386 387 // Descriptor 388 LiteralFields[4] = Descriptor; 389 390 llvm::Constant *BlockLiteralStruct = 391 llvm::ConstantStruct::get(&LiteralFields[0], 5); 392 393 llvm::GlobalVariable *BlockLiteral = 394 new llvm::GlobalVariable(BlockLiteralStruct->getType(), true, 395 llvm::GlobalVariable::InternalLinkage, 396 BlockLiteralStruct, "__block_literal_global", 397 &getModule()); 398 399 return BlockLiteral; 400} 401 402llvm::Function *CodeGenFunction::GenerateBlockFunction(const BlockExpr *Expr, 403 const BlockInfo& Info) 404{ 405 const FunctionTypeProto *FTy = 406 cast<FunctionTypeProto>(Expr->getFunctionType()); 407 408 FunctionArgList Args; 409 410 const BlockDecl *BD = Expr->getBlockDecl(); 411 412 // FIXME: This leaks 413 ImplicitParamDecl *SelfDecl = 414 ImplicitParamDecl::Create(getContext(), 0, 415 SourceLocation(), 0, 416 getContext().getPointerType(getContext().VoidTy)); 417 418 Args.push_back(std::make_pair(SelfDecl, SelfDecl->getType())); 419 420 for (BlockDecl::param_iterator i = BD->param_begin(), 421 e = BD->param_end(); i != e; ++i) 422 Args.push_back(std::make_pair(*i, (*i)->getType())); 423 424 const CGFunctionInfo &FI = 425 CGM.getTypes().getFunctionInfo(FTy->getResultType(), Args); 426 427 std::string Name = std::string("__") + Info.Name + "_block_invoke_"; 428 CodeGenTypes &Types = CGM.getTypes(); 429 const llvm::FunctionType *LTy = Types.GetFunctionType(FI, FTy->isVariadic()); 430 431 llvm::Function *Fn = 432 llvm::Function::Create(LTy, llvm::GlobalValue::InternalLinkage, 433 Name, 434 &CGM.getModule()); 435 436 StartFunction(BD, FTy->getResultType(), Fn, Args, 437 Expr->getBody()->getLocEnd()); 438 EmitStmt(Expr->getBody()); 439 FinishFunction(cast<CompoundStmt>(Expr->getBody())->getRBracLoc()); 440 441 return Fn; 442} 443