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 "clang/AST/DeclObjC.h" 17 #include "llvm/Module.h" 18 #include "llvm/Target/TargetData.h" 19 #include <algorithm> 20 using namespace clang; 21 using namespace CodeGen; 22 23 llvm::Constant *CodeGenFunction:: 24 BuildDescriptorBlockDecl(bool BlockHasCopyDispose, uint64_t Size, 25 const llvm::StructType* Ty, 26 std::vector<HelperInfo> *NoteForHelper) { 27 const llvm::Type *UnsignedLongTy 28 = CGM.getTypes().ConvertType(getContext().UnsignedLongTy); 29 llvm::Constant *C; 30 std::vector<llvm::Constant*> Elts; 31 32 llvm::LLVMContext &VMContext = CGM.getLLVMContext(); 33 34 // reserved 35 C = llvm::ConstantInt::get(UnsignedLongTy, 0); 36 Elts.push_back(C); 37 38 // Size 39 // FIXME: What is the right way to say this doesn't fit? We should give 40 // a user diagnostic in that case. Better fix would be to change the 41 // API to size_t. 42 C = llvm::ConstantInt::get(UnsignedLongTy, Size); 43 Elts.push_back(C); 44 45 if (BlockHasCopyDispose) { 46 // copy_func_helper_decl 47 Elts.push_back(BuildCopyHelper(Ty, NoteForHelper)); 48 49 // destroy_func_decl 50 Elts.push_back(BuildDestroyHelper(Ty, NoteForHelper)); 51 } 52 53 C = VMContext.getConstantStruct(Elts); 54 55 C = new llvm::GlobalVariable(CGM.getModule(), C->getType(), true, 56 llvm::GlobalValue::InternalLinkage, 57 C, "__block_descriptor_tmp"); 58 return C; 59 } 60 61 llvm::Constant *BlockModule::getNSConcreteGlobalBlock() { 62 if (NSConcreteGlobalBlock == 0) 63 NSConcreteGlobalBlock = CGM.CreateRuntimeVariable(PtrToInt8Ty, 64 "_NSConcreteGlobalBlock"); 65 return NSConcreteGlobalBlock; 66 } 67 68 llvm::Constant *BlockModule::getNSConcreteStackBlock() { 69 if (NSConcreteStackBlock == 0) 70 NSConcreteStackBlock = CGM.CreateRuntimeVariable(PtrToInt8Ty, 71 "_NSConcreteStackBlock"); 72 return NSConcreteStackBlock; 73 } 74 75 static void CollectBlockDeclRefInfo(const Stmt *S, 76 CodeGenFunction::BlockInfo &Info) { 77 for (Stmt::const_child_iterator I = S->child_begin(), E = S->child_end(); 78 I != E; ++I) 79 if (*I) 80 CollectBlockDeclRefInfo(*I, Info); 81 82 if (const BlockDeclRefExpr *DE = dyn_cast<BlockDeclRefExpr>(S)) { 83 // FIXME: Handle enums. 84 if (isa<FunctionDecl>(DE->getDecl())) 85 return; 86 87 if (DE->isByRef()) 88 Info.ByRefDeclRefs.push_back(DE); 89 else 90 Info.ByCopyDeclRefs.push_back(DE); 91 } 92 } 93 94 /// CanBlockBeGlobal - Given a BlockInfo struct, determines if a block can be 95 /// declared as a global variable instead of on the stack. 96 static bool CanBlockBeGlobal(const CodeGenFunction::BlockInfo &Info) { 97 return Info.ByRefDeclRefs.empty() && Info.ByCopyDeclRefs.empty(); 98 } 99 100 // FIXME: Push most into CGM, passing down a few bits, like current function 101 // name. 102 llvm::Value *CodeGenFunction::BuildBlockLiteralTmp(const BlockExpr *BE) { 103 104 std::string Name = CurFn->getName(); 105 CodeGenFunction::BlockInfo Info(0, Name.c_str()); 106 CollectBlockDeclRefInfo(BE->getBody(), Info); 107 108 // Check if the block can be global. 109 // FIXME: This test doesn't work for nested blocks yet. Longer term, I'd like 110 // to just have one code path. We should move this function into CGM and pass 111 // CGF, then we can just check to see if CGF is 0. 112 if (0 && CanBlockBeGlobal(Info)) 113 return CGM.GetAddrOfGlobalBlock(BE, Name.c_str()); 114 115 std::vector<llvm::Constant*> Elts(5); 116 llvm::Constant *C; 117 llvm::Value *V; 118 119 { 120 // C = BuildBlockStructInitlist(); 121 unsigned int flags = BLOCK_HAS_DESCRIPTOR; 122 123 // We run this first so that we set BlockHasCopyDispose from the entire 124 // block literal. 125 // __invoke 126 uint64_t subBlockSize, subBlockAlign; 127 llvm::SmallVector<const Expr *, 8> subBlockDeclRefDecls; 128 bool subBlockHasCopyDispose = false; 129 llvm::Function *Fn 130 = CodeGenFunction(CGM).GenerateBlockFunction(BE, Info, CurFuncDecl, LocalDeclMap, 131 subBlockSize, 132 subBlockAlign, 133 subBlockDeclRefDecls, 134 subBlockHasCopyDispose); 135 BlockHasCopyDispose |= subBlockHasCopyDispose; 136 Elts[3] = Fn; 137 138 // FIXME: Don't use BlockHasCopyDispose, it is set more often then 139 // necessary, for example: { ^{ __block int i; ^{ i = 1; }(); }(); } 140 if (subBlockHasCopyDispose) 141 flags |= BLOCK_HAS_COPY_DISPOSE; 142 143 // __isa 144 C = CGM.getNSConcreteStackBlock(); 145 C = VMContext.getConstantExprBitCast(C, PtrToInt8Ty); 146 Elts[0] = C; 147 148 // __flags 149 const llvm::IntegerType *IntTy = cast<llvm::IntegerType>( 150 CGM.getTypes().ConvertType(CGM.getContext().IntTy)); 151 C = llvm::ConstantInt::get(IntTy, flags); 152 Elts[1] = C; 153 154 // __reserved 155 C = llvm::ConstantInt::get(IntTy, 0); 156 Elts[2] = C; 157 158 if (subBlockDeclRefDecls.size() == 0) { 159 // __descriptor 160 Elts[4] = BuildDescriptorBlockDecl(subBlockHasCopyDispose, subBlockSize, 0, 0); 161 162 // Optimize to being a global block. 163 Elts[0] = CGM.getNSConcreteGlobalBlock(); 164 Elts[1] = llvm::ConstantInt::get(IntTy, flags|BLOCK_IS_GLOBAL); 165 166 C = VMContext.getConstantStruct(Elts); 167 168 char Name[32]; 169 sprintf(Name, "__block_holder_tmp_%d", CGM.getGlobalUniqueCount()); 170 C = new llvm::GlobalVariable(CGM.getModule(), C->getType(), true, 171 llvm::GlobalValue::InternalLinkage, 172 C, Name); 173 QualType BPT = BE->getType(); 174 C = VMContext.getConstantExprBitCast(C, ConvertType(BPT)); 175 return C; 176 } 177 178 std::vector<const llvm::Type *> Types(5+subBlockDeclRefDecls.size()); 179 for (int i=0; i<4; ++i) 180 Types[i] = Elts[i]->getType(); 181 Types[4] = PtrToInt8Ty; 182 183 for (unsigned i=0; i < subBlockDeclRefDecls.size(); ++i) { 184 const Expr *E = subBlockDeclRefDecls[i]; 185 const BlockDeclRefExpr *BDRE = dyn_cast<BlockDeclRefExpr>(E); 186 QualType Ty = E->getType(); 187 if (BDRE && BDRE->isByRef()) { 188 uint64_t Align = getContext().getDeclAlignInBytes(BDRE->getDecl()); 189 Types[i+5] = VMContext.getPointerType(BuildByRefType(Ty, Align), 0); 190 } else 191 Types[i+5] = ConvertType(Ty); 192 } 193 194 llvm::StructType *Ty = VMContext.getStructType(Types, true); 195 196 llvm::AllocaInst *A = CreateTempAlloca(Ty); 197 A->setAlignment(subBlockAlign); 198 V = A; 199 200 std::vector<HelperInfo> NoteForHelper(subBlockDeclRefDecls.size()); 201 int helpersize = 0; 202 203 for (unsigned i=0; i<4; ++i) 204 Builder.CreateStore(Elts[i], Builder.CreateStructGEP(V, i, "block.tmp")); 205 206 for (unsigned i=0; i < subBlockDeclRefDecls.size(); ++i) 207 { 208 // FIXME: Push const down. 209 Expr *E = const_cast<Expr*>(subBlockDeclRefDecls[i]); 210 DeclRefExpr *DR; 211 ValueDecl *VD; 212 213 DR = dyn_cast<DeclRefExpr>(E); 214 // Skip padding. 215 if (DR) continue; 216 217 BlockDeclRefExpr *BDRE = dyn_cast<BlockDeclRefExpr>(E); 218 VD = BDRE->getDecl(); 219 220 llvm::Value* Addr = Builder.CreateStructGEP(V, i+5, "tmp"); 221 NoteForHelper[helpersize].index = i+5; 222 NoteForHelper[helpersize].RequiresCopying = BlockRequiresCopying(VD->getType()); 223 NoteForHelper[helpersize].flag 224 = VD->getType()->isBlockPointerType() ? BLOCK_FIELD_IS_BLOCK : BLOCK_FIELD_IS_OBJECT; 225 226 if (LocalDeclMap[VD]) { 227 if (BDRE->isByRef()) { 228 NoteForHelper[helpersize].flag = BLOCK_FIELD_IS_BYREF | 229 // FIXME: Someone double check this. 230 (VD->getType().isObjCGCWeak() ? BLOCK_FIELD_IS_WEAK : 0); 231 const llvm::Type *Ty = Types[i+5]; 232 llvm::Value *Loc = LocalDeclMap[VD]; 233 Loc = Builder.CreateStructGEP(Loc, 1, "forwarding"); 234 Loc = Builder.CreateLoad(Loc, false); 235 Loc = Builder.CreateBitCast(Loc, Ty); 236 Builder.CreateStore(Loc, Addr); 237 ++helpersize; 238 continue; 239 } else 240 E = new (getContext()) DeclRefExpr (cast<NamedDecl>(VD), 241 VD->getType(), SourceLocation(), 242 false, false); 243 } 244 if (BDRE->isByRef()) { 245 NoteForHelper[helpersize].flag = BLOCK_FIELD_IS_BYREF | 246 // FIXME: Someone double check this. 247 (VD->getType().isObjCGCWeak() ? BLOCK_FIELD_IS_WEAK : 0); 248 E = new (getContext()) 249 UnaryOperator(E, UnaryOperator::AddrOf, 250 getContext().getPointerType(E->getType()), 251 SourceLocation()); 252 } 253 ++helpersize; 254 255 RValue r = EmitAnyExpr(E, Addr, false); 256 if (r.isScalar()) { 257 llvm::Value *Loc = r.getScalarVal(); 258 const llvm::Type *Ty = Types[i+5]; 259 if (BDRE->isByRef()) { 260 // E is now the address of the value field, instead, we want the 261 // address of the actual ByRef struct. We optimize this slightly 262 // compared to gcc by not grabbing the forwarding slot as this must 263 // be done during Block_copy for us, and we can postpone the work 264 // until then. 265 uint64_t offset = BlockDecls[BDRE->getDecl()]; 266 267 llvm::Value *BlockLiteral = LoadBlockStruct(); 268 269 Loc = Builder.CreateGEP(BlockLiteral, 270 llvm::ConstantInt::get(llvm::Type::Int64Ty, 271 offset), 272 "block.literal"); 273 Ty = VMContext.getPointerType(Ty, 0); 274 Loc = Builder.CreateBitCast(Loc, Ty); 275 Loc = Builder.CreateLoad(Loc, false); 276 // Loc = Builder.CreateBitCast(Loc, Ty); 277 } 278 Builder.CreateStore(Loc, Addr); 279 } else if (r.isComplex()) 280 // FIXME: implement 281 ErrorUnsupported(BE, "complex in block literal"); 282 else if (r.isAggregate()) 283 ; // Already created into the destination 284 else 285 assert (0 && "bad block variable"); 286 // FIXME: Ensure that the offset created by the backend for 287 // the struct matches the previously computed offset in BlockDecls. 288 } 289 NoteForHelper.resize(helpersize); 290 291 // __descriptor 292 llvm::Value *Descriptor = BuildDescriptorBlockDecl(subBlockHasCopyDispose, 293 subBlockSize, Ty, 294 &NoteForHelper); 295 Descriptor = Builder.CreateBitCast(Descriptor, PtrToInt8Ty); 296 Builder.CreateStore(Descriptor, Builder.CreateStructGEP(V, 4, "block.tmp")); 297 } 298 299 QualType BPT = BE->getType(); 300 return Builder.CreateBitCast(V, ConvertType(BPT)); 301 } 302 303 304 const llvm::Type *BlockModule::getBlockDescriptorType() { 305 if (BlockDescriptorType) 306 return BlockDescriptorType; 307 308 const llvm::Type *UnsignedLongTy = 309 getTypes().ConvertType(getContext().UnsignedLongTy); 310 311 // struct __block_descriptor { 312 // unsigned long reserved; 313 // unsigned long block_size; 314 // }; 315 BlockDescriptorType = VMContext.getStructType(UnsignedLongTy, 316 UnsignedLongTy, 317 NULL); 318 319 getModule().addTypeName("struct.__block_descriptor", 320 BlockDescriptorType); 321 322 return BlockDescriptorType; 323 } 324 325 const llvm::Type *BlockModule::getGenericBlockLiteralType() { 326 if (GenericBlockLiteralType) 327 return GenericBlockLiteralType; 328 329 const llvm::Type *BlockDescPtrTy = 330 VMContext.getPointerTypeUnqual(getBlockDescriptorType()); 331 332 const llvm::IntegerType *IntTy = cast<llvm::IntegerType>( 333 getTypes().ConvertType(getContext().IntTy)); 334 335 // struct __block_literal_generic { 336 // void *__isa; 337 // int __flags; 338 // int __reserved; 339 // void (*__invoke)(void *); 340 // struct __block_descriptor *__descriptor; 341 // }; 342 GenericBlockLiteralType = VMContext.getStructType(PtrToInt8Ty, 343 IntTy, 344 IntTy, 345 PtrToInt8Ty, 346 BlockDescPtrTy, 347 NULL); 348 349 getModule().addTypeName("struct.__block_literal_generic", 350 GenericBlockLiteralType); 351 352 return GenericBlockLiteralType; 353 } 354 355 const llvm::Type *BlockModule::getGenericExtendedBlockLiteralType() { 356 if (GenericExtendedBlockLiteralType) 357 return GenericExtendedBlockLiteralType; 358 359 const llvm::Type *BlockDescPtrTy = 360 VMContext.getPointerTypeUnqual(getBlockDescriptorType()); 361 362 const llvm::IntegerType *IntTy = cast<llvm::IntegerType>( 363 getTypes().ConvertType(getContext().IntTy)); 364 365 // struct __block_literal_generic { 366 // void *__isa; 367 // int __flags; 368 // int __reserved; 369 // void (*__invoke)(void *); 370 // struct __block_descriptor *__descriptor; 371 // void *__copy_func_helper_decl; 372 // void *__destroy_func_decl; 373 // }; 374 GenericExtendedBlockLiteralType = VMContext.getStructType(PtrToInt8Ty, 375 IntTy, 376 IntTy, 377 PtrToInt8Ty, 378 BlockDescPtrTy, 379 PtrToInt8Ty, 380 PtrToInt8Ty, 381 NULL); 382 383 getModule().addTypeName("struct.__block_literal_extended_generic", 384 GenericExtendedBlockLiteralType); 385 386 return GenericExtendedBlockLiteralType; 387 } 388 389 RValue CodeGenFunction::EmitBlockCallExpr(const CallExpr* E) { 390 const BlockPointerType *BPT = 391 E->getCallee()->getType()->getAsBlockPointerType(); 392 393 llvm::Value *Callee = EmitScalarExpr(E->getCallee()); 394 395 // Get a pointer to the generic block literal. 396 const llvm::Type *BlockLiteralTy = 397 VMContext.getPointerTypeUnqual(CGM.getGenericBlockLiteralType()); 398 399 // Bitcast the callee to a block literal. 400 llvm::Value *BlockLiteral = 401 Builder.CreateBitCast(Callee, BlockLiteralTy, "block.literal"); 402 403 // Get the function pointer from the literal. 404 llvm::Value *FuncPtr = Builder.CreateStructGEP(BlockLiteral, 3, "tmp"); 405 406 BlockLiteral = 407 Builder.CreateBitCast(BlockLiteral, 408 VMContext.getPointerTypeUnqual(llvm::Type::Int8Ty), 409 "tmp"); 410 411 // Add the block literal. 412 QualType VoidPtrTy = getContext().getPointerType(getContext().VoidTy); 413 CallArgList Args; 414 Args.push_back(std::make_pair(RValue::get(BlockLiteral), VoidPtrTy)); 415 416 QualType FnType = BPT->getPointeeType(); 417 418 // And the rest of the arguments. 419 EmitCallArgs(Args, FnType->getAsFunctionProtoType(), 420 E->arg_begin(), E->arg_end()); 421 422 // Load the function. 423 llvm::Value *Func = Builder.CreateLoad(FuncPtr, false, "tmp"); 424 425 QualType ResultType = FnType->getAsFunctionType()->getResultType(); 426 427 const CGFunctionInfo &FnInfo = 428 CGM.getTypes().getFunctionInfo(ResultType, Args); 429 430 // Cast the function pointer to the right type. 431 const llvm::Type *BlockFTy = 432 CGM.getTypes().GetFunctionType(FnInfo, false); 433 434 const llvm::Type *BlockFTyPtr = VMContext.getPointerTypeUnqual(BlockFTy); 435 Func = Builder.CreateBitCast(Func, BlockFTyPtr); 436 437 // And call the block. 438 return EmitCall(FnInfo, Func, Args); 439 } 440 441 llvm::Value *CodeGenFunction::GetAddrOfBlockDecl(const BlockDeclRefExpr *E) { 442 uint64_t &offset = BlockDecls[E->getDecl()]; 443 444 const llvm::Type *Ty; 445 Ty = CGM.getTypes().ConvertType(E->getDecl()->getType()); 446 447 // See if we have already allocated an offset for this variable. 448 if (offset == 0) { 449 // Don't run the expensive check, unless we have to. 450 if (!BlockHasCopyDispose && BlockRequiresCopying(E->getType())) 451 BlockHasCopyDispose = true; 452 // if not, allocate one now. 453 offset = getBlockOffset(E); 454 } 455 456 llvm::Value *BlockLiteral = LoadBlockStruct(); 457 llvm::Value *V = Builder.CreateGEP(BlockLiteral, 458 llvm::ConstantInt::get(llvm::Type::Int64Ty, 459 offset), 460 "block.literal"); 461 if (E->isByRef()) { 462 bool needsCopyDispose = BlockRequiresCopying(E->getType()); 463 uint64_t Align = getContext().getDeclAlignInBytes(E->getDecl()); 464 const llvm::Type *PtrStructTy 465 = VMContext.getPointerType(BuildByRefType(E->getType(), Align), 0); 466 // The block literal will need a copy/destroy helper. 467 BlockHasCopyDispose = true; 468 Ty = PtrStructTy; 469 Ty = VMContext.getPointerType(Ty, 0); 470 V = Builder.CreateBitCast(V, Ty); 471 V = Builder.CreateLoad(V, false); 472 V = Builder.CreateStructGEP(V, 1, "forwarding"); 473 V = Builder.CreateLoad(V, false); 474 V = Builder.CreateBitCast(V, PtrStructTy); 475 V = Builder.CreateStructGEP(V, needsCopyDispose*2 + 4, "x"); 476 } else { 477 Ty = VMContext.getPointerType(Ty, 0); 478 V = Builder.CreateBitCast(V, Ty); 479 } 480 return V; 481 } 482 483 void CodeGenFunction::BlockForwardSelf() { 484 const ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(CurFuncDecl); 485 ImplicitParamDecl *SelfDecl = OMD->getSelfDecl(); 486 llvm::Value *&DMEntry = LocalDeclMap[SelfDecl]; 487 if (DMEntry) 488 return; 489 // FIXME - Eliminate BlockDeclRefExprs, clients don't need/want to care 490 BlockDeclRefExpr *BDRE = new (getContext()) 491 BlockDeclRefExpr(SelfDecl, 492 SelfDecl->getType(), SourceLocation(), false); 493 DMEntry = GetAddrOfBlockDecl(BDRE); 494 } 495 496 llvm::Constant * 497 BlockModule::GetAddrOfGlobalBlock(const BlockExpr *BE, const char * n) { 498 // Generate the block descriptor. 499 const llvm::Type *UnsignedLongTy = Types.ConvertType(Context.UnsignedLongTy); 500 const llvm::IntegerType *IntTy = cast<llvm::IntegerType>( 501 getTypes().ConvertType(getContext().IntTy)); 502 503 llvm::Constant *DescriptorFields[2]; 504 505 // Reserved 506 DescriptorFields[0] = getModule().getContext().getNullValue(UnsignedLongTy); 507 508 // Block literal size. For global blocks we just use the size of the generic 509 // block literal struct. 510 uint64_t BlockLiteralSize = 511 TheTargetData.getTypeStoreSizeInBits(getGenericBlockLiteralType()) / 8; 512 DescriptorFields[1] = 513 llvm::ConstantInt::get(UnsignedLongTy,BlockLiteralSize); 514 515 llvm::Constant *DescriptorStruct = 516 VMContext.getConstantStruct(&DescriptorFields[0], 2); 517 518 llvm::GlobalVariable *Descriptor = 519 new llvm::GlobalVariable(getModule(), DescriptorStruct->getType(), true, 520 llvm::GlobalVariable::InternalLinkage, 521 DescriptorStruct, "__block_descriptor_global"); 522 523 // Generate the constants for the block literal. 524 llvm::Constant *LiteralFields[5]; 525 526 CodeGenFunction::BlockInfo Info(0, n); 527 uint64_t subBlockSize, subBlockAlign; 528 llvm::SmallVector<const Expr *, 8> subBlockDeclRefDecls; 529 bool subBlockHasCopyDispose = false; 530 llvm::DenseMap<const Decl*, llvm::Value*> LocalDeclMap; 531 llvm::Function *Fn 532 = CodeGenFunction(CGM).GenerateBlockFunction(BE, Info, 0, LocalDeclMap, 533 subBlockSize, 534 subBlockAlign, 535 subBlockDeclRefDecls, 536 subBlockHasCopyDispose); 537 assert(subBlockSize == BlockLiteralSize 538 && "no imports allowed for global block"); 539 540 // isa 541 LiteralFields[0] = getNSConcreteGlobalBlock(); 542 543 // Flags 544 LiteralFields[1] = 545 llvm::ConstantInt::get(IntTy, BLOCK_IS_GLOBAL | BLOCK_HAS_DESCRIPTOR); 546 547 // Reserved 548 LiteralFields[2] = getModule().getContext().getNullValue(IntTy); 549 550 // Function 551 LiteralFields[3] = Fn; 552 553 // Descriptor 554 LiteralFields[4] = Descriptor; 555 556 llvm::Constant *BlockLiteralStruct = 557 VMContext.getConstantStruct(&LiteralFields[0], 5); 558 559 llvm::GlobalVariable *BlockLiteral = 560 new llvm::GlobalVariable(getModule(), BlockLiteralStruct->getType(), true, 561 llvm::GlobalVariable::InternalLinkage, 562 BlockLiteralStruct, "__block_literal_global"); 563 564 return BlockLiteral; 565 } 566 567 llvm::Value *CodeGenFunction::LoadBlockStruct() { 568 return Builder.CreateLoad(LocalDeclMap[getBlockStructDecl()], "self"); 569 } 570 571 llvm::Function * 572 CodeGenFunction::GenerateBlockFunction(const BlockExpr *BExpr, 573 const BlockInfo& Info, 574 const Decl *OuterFuncDecl, 575 llvm::DenseMap<const Decl*, llvm::Value*> ldm, 576 uint64_t &Size, 577 uint64_t &Align, 578 llvm::SmallVector<const Expr *, 8> &subBlockDeclRefDecls, 579 bool &subBlockHasCopyDispose) { 580 581 // Check if we should generate debug info for this block. 582 if (CGM.getDebugInfo()) 583 DebugInfo = CGM.getDebugInfo(); 584 585 // Arrange for local static and local extern declarations to appear 586 // to be local to this function as well, as they are directly referenced 587 // in a block. 588 for (llvm::DenseMap<const Decl *, llvm::Value*>::iterator i = ldm.begin(); 589 i != ldm.end(); 590 ++i) { 591 const VarDecl *VD = dyn_cast<VarDecl>(i->first); 592 593 if (VD->getStorageClass() == VarDecl::Static || VD->hasExternalStorage()) 594 LocalDeclMap[VD] = i->second; 595 } 596 597 // FIXME: We need to rearrange the code for copy/dispose so we have this 598 // sooner, so we can calculate offsets correctly. 599 if (!BlockHasCopyDispose) 600 BlockOffset = CGM.getTargetData() 601 .getTypeStoreSizeInBits(CGM.getGenericBlockLiteralType()) / 8; 602 else 603 BlockOffset = CGM.getTargetData() 604 .getTypeStoreSizeInBits(CGM.getGenericExtendedBlockLiteralType()) / 8; 605 BlockAlign = getContext().getTypeAlign(getContext().VoidPtrTy) / 8; 606 607 const FunctionType *BlockFunctionType = BExpr->getFunctionType(); 608 QualType ResultType; 609 bool IsVariadic; 610 if (const FunctionProtoType *FTy = 611 dyn_cast<FunctionProtoType>(BlockFunctionType)) { 612 ResultType = FTy->getResultType(); 613 IsVariadic = FTy->isVariadic(); 614 } 615 else { 616 // K&R style block. 617 ResultType = BlockFunctionType->getResultType(); 618 IsVariadic = false; 619 } 620 621 FunctionArgList Args; 622 623 const BlockDecl *BD = BExpr->getBlockDecl(); 624 625 // FIXME: This leaks 626 ImplicitParamDecl *SelfDecl = 627 ImplicitParamDecl::Create(getContext(), 0, 628 SourceLocation(), 0, 629 getContext().getPointerType(getContext().VoidTy)); 630 631 Args.push_back(std::make_pair(SelfDecl, SelfDecl->getType())); 632 BlockStructDecl = SelfDecl; 633 634 for (BlockDecl::param_const_iterator i = BD->param_begin(), 635 e = BD->param_end(); i != e; ++i) 636 Args.push_back(std::make_pair(*i, (*i)->getType())); 637 638 const CGFunctionInfo &FI = 639 CGM.getTypes().getFunctionInfo(ResultType, Args); 640 641 std::string Name = std::string("__") + Info.Name + "_block_invoke_"; 642 CodeGenTypes &Types = CGM.getTypes(); 643 const llvm::FunctionType *LTy = Types.GetFunctionType(FI, IsVariadic); 644 645 llvm::Function *Fn = 646 llvm::Function::Create(LTy, llvm::GlobalValue::InternalLinkage, 647 Name, 648 &CGM.getModule()); 649 650 CGM.SetInternalFunctionAttributes(BD, Fn, FI); 651 652 StartFunction(BD, ResultType, Fn, Args, 653 BExpr->getBody()->getLocEnd()); 654 CurFuncDecl = OuterFuncDecl; 655 CurCodeDecl = BD; 656 EmitStmt(BExpr->getBody()); 657 FinishFunction(cast<CompoundStmt>(BExpr->getBody())->getRBracLoc()); 658 659 // The runtime needs a minimum alignment of a void *. 660 uint64_t MinAlign = getContext().getTypeAlign(getContext().VoidPtrTy) / 8; 661 BlockOffset = llvm::RoundUpToAlignment(BlockOffset, MinAlign); 662 663 Size = BlockOffset; 664 Align = BlockAlign; 665 subBlockDeclRefDecls = BlockDeclRefDecls; 666 subBlockHasCopyDispose |= BlockHasCopyDispose; 667 return Fn; 668 } 669 670 uint64_t BlockFunction::getBlockOffset(const BlockDeclRefExpr *BDRE) { 671 const ValueDecl *D = dyn_cast<ValueDecl>(BDRE->getDecl()); 672 673 uint64_t Size = getContext().getTypeSize(D->getType()) / 8; 674 uint64_t Align = getContext().getDeclAlignInBytes(D); 675 676 if (BDRE->isByRef()) { 677 Size = getContext().getTypeSize(getContext().VoidPtrTy) / 8; 678 Align = getContext().getTypeAlign(getContext().VoidPtrTy) / 8; 679 } 680 681 assert ((Align > 0) && "alignment must be 1 byte or more"); 682 683 uint64_t OldOffset = BlockOffset; 684 685 // Ensure proper alignment, even if it means we have to have a gap 686 BlockOffset = llvm::RoundUpToAlignment(BlockOffset, Align); 687 BlockAlign = std::max(Align, BlockAlign); 688 689 uint64_t Pad = BlockOffset - OldOffset; 690 if (Pad) { 691 VMContext.getArrayType(llvm::Type::Int8Ty, Pad); 692 QualType PadTy = getContext().getConstantArrayType(getContext().CharTy, 693 llvm::APInt(32, Pad), 694 ArrayType::Normal, 0); 695 ValueDecl *PadDecl = VarDecl::Create(getContext(), 0, SourceLocation(), 696 0, QualType(PadTy), VarDecl::None, 697 SourceLocation()); 698 Expr *E; 699 E = new (getContext()) DeclRefExpr(PadDecl, PadDecl->getType(), 700 SourceLocation(), false, false); 701 BlockDeclRefDecls.push_back(E); 702 } 703 BlockDeclRefDecls.push_back(BDRE); 704 705 BlockOffset += Size; 706 return BlockOffset-Size; 707 } 708 709 llvm::Constant *BlockFunction:: 710 GenerateCopyHelperFunction(bool BlockHasCopyDispose, const llvm::StructType *T, 711 std::vector<HelperInfo> *NoteForHelperp) { 712 QualType R = getContext().VoidTy; 713 714 FunctionArgList Args; 715 // FIXME: This leaks 716 ImplicitParamDecl *Dst = 717 ImplicitParamDecl::Create(getContext(), 0, SourceLocation(), 0, 718 getContext().getPointerType(getContext().VoidTy)); 719 Args.push_back(std::make_pair(Dst, Dst->getType())); 720 ImplicitParamDecl *Src = 721 ImplicitParamDecl::Create(getContext(), 0, SourceLocation(), 0, 722 getContext().getPointerType(getContext().VoidTy)); 723 Args.push_back(std::make_pair(Src, Src->getType())); 724 725 const CGFunctionInfo &FI = 726 CGM.getTypes().getFunctionInfo(R, Args); 727 728 // FIXME: We'd like to put these into a mergable by content, with 729 // internal linkage. 730 std::string Name = std::string("__copy_helper_block_"); 731 CodeGenTypes &Types = CGM.getTypes(); 732 const llvm::FunctionType *LTy = Types.GetFunctionType(FI, false); 733 734 llvm::Function *Fn = 735 llvm::Function::Create(LTy, llvm::GlobalValue::InternalLinkage, 736 Name, 737 &CGM.getModule()); 738 739 IdentifierInfo *II 740 = &CGM.getContext().Idents.get("__copy_helper_block_"); 741 742 FunctionDecl *FD = FunctionDecl::Create(getContext(), 743 getContext().getTranslationUnitDecl(), 744 SourceLocation(), II, R, 745 FunctionDecl::Static, false, 746 true); 747 CGF.StartFunction(FD, R, Fn, Args, SourceLocation()); 748 749 llvm::Value *SrcObj = CGF.GetAddrOfLocalVar(Src); 750 llvm::Type *PtrPtrT; 751 752 if (NoteForHelperp) { 753 std::vector<HelperInfo> &NoteForHelper = *NoteForHelperp; 754 755 PtrPtrT = VMContext.getPointerType(VMContext.getPointerType(T, 0), 0); 756 SrcObj = Builder.CreateBitCast(SrcObj, PtrPtrT); 757 SrcObj = Builder.CreateLoad(SrcObj); 758 759 llvm::Value *DstObj = CGF.GetAddrOfLocalVar(Dst); 760 llvm::Type *PtrPtrT; 761 PtrPtrT = VMContext.getPointerType(VMContext.getPointerType(T, 0), 0); 762 DstObj = Builder.CreateBitCast(DstObj, PtrPtrT); 763 DstObj = Builder.CreateLoad(DstObj); 764 765 for (unsigned i=0; i < NoteForHelper.size(); ++i) { 766 int flag = NoteForHelper[i].flag; 767 int index = NoteForHelper[i].index; 768 769 if ((NoteForHelper[i].flag & BLOCK_FIELD_IS_BYREF) 770 || NoteForHelper[i].RequiresCopying) { 771 llvm::Value *Srcv = SrcObj; 772 Srcv = Builder.CreateStructGEP(Srcv, index); 773 Srcv = Builder.CreateBitCast(Srcv, 774 VMContext.getPointerType(PtrToInt8Ty, 0)); 775 Srcv = Builder.CreateLoad(Srcv); 776 777 llvm::Value *Dstv = Builder.CreateStructGEP(DstObj, index); 778 Dstv = Builder.CreateBitCast(Dstv, PtrToInt8Ty); 779 780 llvm::Value *N = llvm::ConstantInt::get(llvm::Type::Int32Ty, flag); 781 llvm::Value *F = getBlockObjectAssign(); 782 Builder.CreateCall3(F, Dstv, Srcv, N); 783 } 784 } 785 } 786 787 CGF.FinishFunction(); 788 789 return VMContext.getConstantExprBitCast(Fn, PtrToInt8Ty); 790 } 791 792 llvm::Constant *BlockFunction:: 793 GenerateDestroyHelperFunction(bool BlockHasCopyDispose, 794 const llvm::StructType* T, 795 std::vector<HelperInfo> *NoteForHelperp) { 796 QualType R = getContext().VoidTy; 797 798 FunctionArgList Args; 799 // FIXME: This leaks 800 ImplicitParamDecl *Src = 801 ImplicitParamDecl::Create(getContext(), 0, SourceLocation(), 0, 802 getContext().getPointerType(getContext().VoidTy)); 803 804 Args.push_back(std::make_pair(Src, Src->getType())); 805 806 const CGFunctionInfo &FI = 807 CGM.getTypes().getFunctionInfo(R, Args); 808 809 // FIXME: We'd like to put these into a mergable by content, with 810 // internal linkage. 811 std::string Name = std::string("__destroy_helper_block_"); 812 CodeGenTypes &Types = CGM.getTypes(); 813 const llvm::FunctionType *LTy = Types.GetFunctionType(FI, false); 814 815 llvm::Function *Fn = 816 llvm::Function::Create(LTy, llvm::GlobalValue::InternalLinkage, 817 Name, 818 &CGM.getModule()); 819 820 IdentifierInfo *II 821 = &CGM.getContext().Idents.get("__destroy_helper_block_"); 822 823 FunctionDecl *FD = FunctionDecl::Create(getContext(), 824 getContext().getTranslationUnitDecl(), 825 SourceLocation(), II, R, 826 FunctionDecl::Static, false, 827 true); 828 CGF.StartFunction(FD, R, Fn, Args, SourceLocation()); 829 830 if (NoteForHelperp) { 831 std::vector<HelperInfo> &NoteForHelper = *NoteForHelperp; 832 833 llvm::Value *SrcObj = CGF.GetAddrOfLocalVar(Src); 834 llvm::Type *PtrPtrT; 835 PtrPtrT = VMContext.getPointerType(VMContext.getPointerType(T, 0), 0); 836 SrcObj = Builder.CreateBitCast(SrcObj, PtrPtrT); 837 SrcObj = Builder.CreateLoad(SrcObj); 838 839 for (unsigned i=0; i < NoteForHelper.size(); ++i) { 840 int flag = NoteForHelper[i].flag; 841 int index = NoteForHelper[i].index; 842 843 if ((NoteForHelper[i].flag & BLOCK_FIELD_IS_BYREF) 844 || NoteForHelper[i].RequiresCopying) { 845 llvm::Value *Srcv = SrcObj; 846 Srcv = Builder.CreateStructGEP(Srcv, index); 847 Srcv = Builder.CreateBitCast(Srcv, 848 VMContext.getPointerType(PtrToInt8Ty, 0)); 849 Srcv = Builder.CreateLoad(Srcv); 850 851 BuildBlockRelease(Srcv, flag); 852 } 853 } 854 } 855 856 CGF.FinishFunction(); 857 858 return VMContext.getConstantExprBitCast(Fn, PtrToInt8Ty); 859 } 860 861 llvm::Constant *BlockFunction::BuildCopyHelper(const llvm::StructType *T, 862 std::vector<HelperInfo> *NoteForHelper) { 863 return CodeGenFunction(CGM).GenerateCopyHelperFunction(BlockHasCopyDispose, 864 T, NoteForHelper); 865 } 866 867 llvm::Constant *BlockFunction::BuildDestroyHelper(const llvm::StructType *T, 868 std::vector<HelperInfo> *NoteForHelperp) { 869 return CodeGenFunction(CGM).GenerateDestroyHelperFunction(BlockHasCopyDispose, 870 T, NoteForHelperp); 871 } 872 873 llvm::Constant *BlockFunction:: 874 GeneratebyrefCopyHelperFunction(const llvm::Type *T, int flag) { 875 QualType R = getContext().VoidTy; 876 877 FunctionArgList Args; 878 // FIXME: This leaks 879 ImplicitParamDecl *Dst = 880 ImplicitParamDecl::Create(getContext(), 0, SourceLocation(), 0, 881 getContext().getPointerType(getContext().VoidTy)); 882 Args.push_back(std::make_pair(Dst, Dst->getType())); 883 884 // FIXME: This leaks 885 ImplicitParamDecl *Src = 886 ImplicitParamDecl::Create(getContext(), 0, SourceLocation(), 0, 887 getContext().getPointerType(getContext().VoidTy)); 888 Args.push_back(std::make_pair(Src, Src->getType())); 889 890 const CGFunctionInfo &FI = 891 CGM.getTypes().getFunctionInfo(R, Args); 892 893 std::string Name = std::string("__Block_byref_id_object_copy_"); 894 CodeGenTypes &Types = CGM.getTypes(); 895 const llvm::FunctionType *LTy = Types.GetFunctionType(FI, false); 896 897 // FIXME: We'd like to put these into a mergable by content, with 898 // internal linkage. 899 llvm::Function *Fn = 900 llvm::Function::Create(LTy, llvm::GlobalValue::InternalLinkage, 901 Name, 902 &CGM.getModule()); 903 904 IdentifierInfo *II 905 = &CGM.getContext().Idents.get("__Block_byref_id_object_copy_"); 906 907 FunctionDecl *FD = FunctionDecl::Create(getContext(), 908 getContext().getTranslationUnitDecl(), 909 SourceLocation(), II, R, 910 FunctionDecl::Static, false, 911 true); 912 CGF.StartFunction(FD, R, Fn, Args, SourceLocation()); 913 914 // dst->x 915 llvm::Value *V = CGF.GetAddrOfLocalVar(Dst); 916 V = Builder.CreateBitCast(V, VMContext.getPointerType(T, 0)); 917 V = Builder.CreateLoad(V); 918 V = Builder.CreateStructGEP(V, 6, "x"); 919 llvm::Value *DstObj = Builder.CreateBitCast(V, PtrToInt8Ty); 920 921 // src->x 922 V = CGF.GetAddrOfLocalVar(Src); 923 V = Builder.CreateLoad(V); 924 V = Builder.CreateBitCast(V, T); 925 V = Builder.CreateStructGEP(V, 6, "x"); 926 V = Builder.CreateBitCast(V, VMContext.getPointerType(PtrToInt8Ty, 0)); 927 llvm::Value *SrcObj = Builder.CreateLoad(V); 928 929 flag |= BLOCK_BYREF_CALLER; 930 931 llvm::Value *N = llvm::ConstantInt::get(llvm::Type::Int32Ty, flag); 932 llvm::Value *F = getBlockObjectAssign(); 933 Builder.CreateCall3(F, DstObj, SrcObj, N); 934 935 CGF.FinishFunction(); 936 937 return VMContext.getConstantExprBitCast(Fn, PtrToInt8Ty); 938 } 939 940 llvm::Constant * 941 BlockFunction::GeneratebyrefDestroyHelperFunction(const llvm::Type *T, 942 int flag) { 943 QualType R = getContext().VoidTy; 944 945 FunctionArgList Args; 946 // FIXME: This leaks 947 ImplicitParamDecl *Src = 948 ImplicitParamDecl::Create(getContext(), 0, SourceLocation(), 0, 949 getContext().getPointerType(getContext().VoidTy)); 950 951 Args.push_back(std::make_pair(Src, Src->getType())); 952 953 const CGFunctionInfo &FI = 954 CGM.getTypes().getFunctionInfo(R, Args); 955 956 std::string Name = std::string("__Block_byref_id_object_dispose_"); 957 CodeGenTypes &Types = CGM.getTypes(); 958 const llvm::FunctionType *LTy = Types.GetFunctionType(FI, false); 959 960 // FIXME: We'd like to put these into a mergable by content, with 961 // internal linkage. 962 llvm::Function *Fn = 963 llvm::Function::Create(LTy, llvm::GlobalValue::InternalLinkage, 964 Name, 965 &CGM.getModule()); 966 967 IdentifierInfo *II 968 = &CGM.getContext().Idents.get("__Block_byref_id_object_dispose_"); 969 970 FunctionDecl *FD = FunctionDecl::Create(getContext(), 971 getContext().getTranslationUnitDecl(), 972 SourceLocation(), II, R, 973 FunctionDecl::Static, false, 974 true); 975 CGF.StartFunction(FD, R, Fn, Args, SourceLocation()); 976 977 llvm::Value *V = CGF.GetAddrOfLocalVar(Src); 978 V = Builder.CreateBitCast(V, VMContext.getPointerType(T, 0)); 979 V = Builder.CreateLoad(V); 980 V = Builder.CreateStructGEP(V, 6, "x"); 981 V = Builder.CreateBitCast(V, VMContext.getPointerType(PtrToInt8Ty, 0)); 982 V = Builder.CreateLoad(V); 983 984 flag |= BLOCK_BYREF_CALLER; 985 BuildBlockRelease(V, flag); 986 CGF.FinishFunction(); 987 988 return VMContext.getConstantExprBitCast(Fn, PtrToInt8Ty); 989 } 990 991 llvm::Constant *BlockFunction::BuildbyrefCopyHelper(const llvm::Type *T, 992 int flag, unsigned Align) { 993 // All alignments below that of pointer alignment collpase down to just 994 // pointer alignment, as we always have at least that much alignment to begin 995 // with. 996 Align /= unsigned(CGF.Target.getPointerAlign(0)/8); 997 // As an optimization, we only generate a single function of each kind we 998 // might need. We need a different one for each alignment and for each 999 // setting of flags. We mix Align and flag to get the kind. 1000 uint64_t kind = (uint64_t)Align*BLOCK_BYREF_CURRENT_MAX + flag; 1001 llvm::Constant *& Entry = CGM.AssignCache[kind]; 1002 if (Entry) 1003 return Entry; 1004 return Entry=CodeGenFunction(CGM).GeneratebyrefCopyHelperFunction(T, flag); 1005 } 1006 1007 llvm::Constant *BlockFunction::BuildbyrefDestroyHelper(const llvm::Type *T, 1008 int flag, 1009 unsigned Align) { 1010 // All alignments below that of pointer alignment collpase down to just 1011 // pointer alignment, as we always have at least that much alignment to begin 1012 // with. 1013 Align /= unsigned(CGF.Target.getPointerAlign(0)/8); 1014 // As an optimization, we only generate a single function of each kind we 1015 // might need. We need a different one for each alignment and for each 1016 // setting of flags. We mix Align and flag to get the kind. 1017 uint64_t kind = (uint64_t)Align*BLOCK_BYREF_CURRENT_MAX + flag; 1018 llvm::Constant *& Entry = CGM.DestroyCache[kind]; 1019 if (Entry) 1020 return Entry; 1021 return Entry=CodeGenFunction(CGM).GeneratebyrefDestroyHelperFunction(T, flag); 1022 } 1023 1024 llvm::Value *BlockFunction::getBlockObjectDispose() { 1025 if (CGM.BlockObjectDispose == 0) { 1026 const llvm::FunctionType *FTy; 1027 std::vector<const llvm::Type*> ArgTys; 1028 const llvm::Type *ResultType = llvm::Type::VoidTy; 1029 ArgTys.push_back(PtrToInt8Ty); 1030 ArgTys.push_back(llvm::Type::Int32Ty); 1031 FTy = VMContext.getFunctionType(ResultType, ArgTys, false); 1032 CGM.BlockObjectDispose 1033 = CGM.CreateRuntimeFunction(FTy, "_Block_object_dispose"); 1034 } 1035 return CGM.BlockObjectDispose; 1036 } 1037 1038 llvm::Value *BlockFunction::getBlockObjectAssign() { 1039 if (CGM.BlockObjectAssign == 0) { 1040 const llvm::FunctionType *FTy; 1041 std::vector<const llvm::Type*> ArgTys; 1042 const llvm::Type *ResultType = llvm::Type::VoidTy; 1043 ArgTys.push_back(PtrToInt8Ty); 1044 ArgTys.push_back(PtrToInt8Ty); 1045 ArgTys.push_back(llvm::Type::Int32Ty); 1046 FTy = VMContext.getFunctionType(ResultType, ArgTys, false); 1047 CGM.BlockObjectAssign 1048 = CGM.CreateRuntimeFunction(FTy, "_Block_object_assign"); 1049 } 1050 return CGM.BlockObjectAssign; 1051 } 1052 1053 void BlockFunction::BuildBlockRelease(llvm::Value *V, int flag) { 1054 llvm::Value *F = getBlockObjectDispose(); 1055 llvm::Value *N; 1056 V = Builder.CreateBitCast(V, PtrToInt8Ty); 1057 N = llvm::ConstantInt::get(llvm::Type::Int32Ty, flag); 1058 Builder.CreateCall2(F, V, N); 1059 } 1060 1061 ASTContext &BlockFunction::getContext() const { return CGM.getContext(); } 1062 1063 BlockFunction::BlockFunction(CodeGenModule &cgm, CodeGenFunction &cgf, 1064 CGBuilderTy &B) 1065 : CGM(cgm), CGF(cgf), VMContext(cgm.getLLVMContext()), Builder(B) { 1066 PtrToInt8Ty = VMContext.getPointerTypeUnqual(llvm::Type::Int8Ty); 1067 1068 BlockHasCopyDispose = false; 1069 } 1070