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