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