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