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