CGBlocks.cpp revision 206084
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/ADT/SmallSet.h" 21#include "llvm/Target/TargetData.h" 22#include <algorithm> 23 24using namespace clang; 25using namespace CodeGen; 26 27llvm::Constant *CodeGenFunction:: 28BuildDescriptorBlockDecl(const BlockExpr *BE, bool BlockHasCopyDispose, CharUnits Size, 29 const llvm::StructType* Ty, 30 std::vector<HelperInfo> *NoteForHelper) { 31 const llvm::Type *UnsignedLongTy 32 = CGM.getTypes().ConvertType(getContext().UnsignedLongTy); 33 llvm::Constant *C; 34 std::vector<llvm::Constant*> Elts; 35 36 // reserved 37 C = llvm::ConstantInt::get(UnsignedLongTy, 0); 38 Elts.push_back(C); 39 40 // Size 41 // FIXME: What is the right way to say this doesn't fit? We should give 42 // a user diagnostic in that case. Better fix would be to change the 43 // API to size_t. 44 C = llvm::ConstantInt::get(UnsignedLongTy, Size.getQuantity()); 45 Elts.push_back(C); 46 47 // optional copy/dispose helpers 48 if (BlockHasCopyDispose) { 49 // copy_func_helper_decl 50 Elts.push_back(BuildCopyHelper(Ty, NoteForHelper)); 51 52 // destroy_func_decl 53 Elts.push_back(BuildDestroyHelper(Ty, NoteForHelper)); 54 } 55 56 // Signature. non-optional ObjC-style method descriptor @encode sequence 57 std::string BlockTypeEncoding; 58 CGM.getContext().getObjCEncodingForBlock(BE, BlockTypeEncoding); 59 60 Elts.push_back(llvm::ConstantExpr::getBitCast( 61 CGM.GetAddrOfConstantCString(BlockTypeEncoding), PtrToInt8Ty)); 62 63 // Layout. 64 C = llvm::ConstantInt::get(UnsignedLongTy, 0); 65 Elts.push_back(C); 66 67 C = llvm::ConstantStruct::get(VMContext, Elts, false); 68 69 C = new llvm::GlobalVariable(CGM.getModule(), C->getType(), true, 70 llvm::GlobalValue::InternalLinkage, 71 C, "__block_descriptor_tmp"); 72 return C; 73} 74 75llvm::Constant *BlockModule::getNSConcreteGlobalBlock() { 76 if (NSConcreteGlobalBlock == 0) 77 NSConcreteGlobalBlock = CGM.CreateRuntimeVariable(PtrToInt8Ty, 78 "_NSConcreteGlobalBlock"); 79 return NSConcreteGlobalBlock; 80} 81 82llvm::Constant *BlockModule::getNSConcreteStackBlock() { 83 if (NSConcreteStackBlock == 0) 84 NSConcreteStackBlock = CGM.CreateRuntimeVariable(PtrToInt8Ty, 85 "_NSConcreteStackBlock"); 86 return NSConcreteStackBlock; 87} 88 89static void CollectBlockDeclRefInfo( 90 const Stmt *S, CodeGenFunction::BlockInfo &Info, 91 llvm::SmallSet<const DeclContext *, 16> &InnerContexts) { 92 for (Stmt::const_child_iterator I = S->child_begin(), E = S->child_end(); 93 I != E; ++I) 94 if (*I) 95 CollectBlockDeclRefInfo(*I, Info, InnerContexts); 96 97 // We want to ensure we walk down into block literals so we can find 98 // all nested BlockDeclRefExprs. 99 if (const BlockExpr *BE = dyn_cast<BlockExpr>(S)) { 100 InnerContexts.insert(cast<DeclContext>(BE->getBlockDecl())); 101 CollectBlockDeclRefInfo(BE->getBody(), Info, InnerContexts); 102 } 103 104 if (const BlockDeclRefExpr *BDRE = dyn_cast<BlockDeclRefExpr>(S)) { 105 // FIXME: Handle enums. 106 if (isa<FunctionDecl>(BDRE->getDecl())) 107 return; 108 109 // Only Decls that escape are added. 110 if (!InnerContexts.count(BDRE->getDecl()->getDeclContext())) 111 Info.DeclRefs.push_back(BDRE); 112 } 113} 114 115/// CanBlockBeGlobal - Given a BlockInfo struct, determines if a block can be 116/// declared as a global variable instead of on the stack. 117static bool CanBlockBeGlobal(const CodeGenFunction::BlockInfo &Info) { 118 return Info.DeclRefs.empty(); 119} 120 121/// AllocateAllBlockDeclRefs - Preallocate all nested BlockDeclRefExprs to 122/// ensure we can generate the debug information for the parameter for the block 123/// invoke function. 124static void AllocateAllBlockDeclRefs(const CodeGenFunction::BlockInfo &Info, 125 CodeGenFunction *CGF) { 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 std::vector<llvm::Constant*> Elts(BlockFields); 152 153 llvm::Constant *C; 154 llvm::Value *V; 155 156 { 157 // C = BuildBlockStructInitlist(); 158 unsigned int flags = BLOCK_HAS_SIGNATURE; 159 160 // We run this first so that we set BlockHasCopyDispose from the entire 161 // block literal. 162 // __invoke 163 CharUnits subBlockSize; 164 CharUnits subBlockAlign; 165 llvm::SmallVector<const Expr *, 8> subBlockDeclRefDecls; 166 bool subBlockHasCopyDispose = false; 167 llvm::Function *Fn 168 = CodeGenFunction(CGM).GenerateBlockFunction(BE, Info, CurFuncDecl, 169 LocalDeclMap, 170 subBlockSize, 171 subBlockAlign, 172 subBlockDeclRefDecls, 173 subBlockHasCopyDispose); 174 BlockHasCopyDispose |= subBlockHasCopyDispose; 175 Elts[3] = Fn; 176 177 // FIXME: Don't use BlockHasCopyDispose, it is set more often then 178 // necessary, for example: { ^{ __block int i; ^{ i = 1; }(); }(); } 179 if (subBlockHasCopyDispose) 180 flags |= BLOCK_HAS_COPY_DISPOSE; 181 182 // __isa 183 C = CGM.getNSConcreteStackBlock(); 184 C = llvm::ConstantExpr::getBitCast(C, PtrToInt8Ty); 185 Elts[0] = C; 186 187 // __flags 188 { 189 QualType BPT = BE->getType(); 190 const FunctionType *ftype = BPT->getPointeeType()->getAs<FunctionType>(); 191 QualType ResultType = ftype->getResultType(); 192 193 CallArgList Args; 194 CodeGenTypes &Types = CGM.getTypes(); 195 const CGFunctionInfo &FnInfo = Types.getFunctionInfo(ResultType, Args, 196 FunctionType::ExtInfo()); 197 if (CGM.ReturnTypeUsesSret(FnInfo)) 198 flags |= BLOCK_USE_STRET; 199 } 200 const llvm::IntegerType *IntTy = cast<llvm::IntegerType>( 201 CGM.getTypes().ConvertType(CGM.getContext().IntTy)); 202 C = llvm::ConstantInt::get(IntTy, flags); 203 Elts[1] = C; 204 205 // __reserved 206 C = llvm::ConstantInt::get(IntTy, 0); 207 Elts[2] = C; 208 209 if (subBlockDeclRefDecls.size() == 0) { 210 // __descriptor 211 Elts[4] = BuildDescriptorBlockDecl(BE, subBlockHasCopyDispose, subBlockSize, 212 0, 0); 213 214 // Optimize to being a global block. 215 Elts[0] = CGM.getNSConcreteGlobalBlock(); 216 217 Elts[1] = llvm::ConstantInt::get(IntTy, flags|BLOCK_IS_GLOBAL); 218 219 C = llvm::ConstantStruct::get(VMContext, Elts, false); 220 221 C = new llvm::GlobalVariable(CGM.getModule(), C->getType(), true, 222 llvm::GlobalValue::InternalLinkage, C, 223 "__block_holder_tmp_" + 224 llvm::Twine(CGM.getGlobalUniqueCount())); 225 QualType BPT = BE->getType(); 226 C = llvm::ConstantExpr::getBitCast(C, ConvertType(BPT)); 227 return C; 228 } 229 230 std::vector<const llvm::Type *> Types(BlockFields+subBlockDeclRefDecls.size()); 231 for (int i=0; i<4; ++i) 232 Types[i] = Elts[i]->getType(); 233 Types[4] = PtrToInt8Ty; 234 235 for (unsigned i=0; i < subBlockDeclRefDecls.size(); ++i) { 236 const Expr *E = subBlockDeclRefDecls[i]; 237 const BlockDeclRefExpr *BDRE = dyn_cast<BlockDeclRefExpr>(E); 238 QualType Ty = E->getType(); 239 if (BDRE && BDRE->isByRef()) { 240 Types[i+BlockFields] = llvm::PointerType::get(BuildByRefType(BDRE->getDecl()), 0); 241 } else 242 Types[i+BlockFields] = ConvertType(Ty); 243 } 244 245 llvm::StructType *Ty = llvm::StructType::get(VMContext, Types, true); 246 247 llvm::AllocaInst *A = CreateTempAlloca(Ty); 248 A->setAlignment(subBlockAlign.getQuantity()); 249 V = A; 250 251 std::vector<HelperInfo> NoteForHelper(subBlockDeclRefDecls.size()); 252 int helpersize = 0; 253 254 for (unsigned i=0; i<4; ++i) 255 Builder.CreateStore(Elts[i], Builder.CreateStructGEP(V, i, "block.tmp")); 256 257 for (unsigned i=0; i < subBlockDeclRefDecls.size(); ++i) 258 { 259 // FIXME: Push const down. 260 Expr *E = const_cast<Expr*>(subBlockDeclRefDecls[i]); 261 DeclRefExpr *DR; 262 ValueDecl *VD; 263 264 DR = dyn_cast<DeclRefExpr>(E); 265 // Skip padding. 266 if (DR) continue; 267 268 BlockDeclRefExpr *BDRE = dyn_cast<BlockDeclRefExpr>(E); 269 VD = BDRE->getDecl(); 270 271 llvm::Value* Addr = Builder.CreateStructGEP(V, i+BlockFields, "tmp"); 272 NoteForHelper[helpersize].index = i+5; 273 NoteForHelper[helpersize].RequiresCopying 274 = BlockRequiresCopying(VD->getType()); 275 NoteForHelper[helpersize].flag 276 = (VD->getType()->isBlockPointerType() 277 ? BLOCK_FIELD_IS_BLOCK 278 : BLOCK_FIELD_IS_OBJECT); 279 280 if (LocalDeclMap[VD]) { 281 if (BDRE->isByRef()) { 282 NoteForHelper[helpersize].flag = BLOCK_FIELD_IS_BYREF | 283 // FIXME: Someone double check this. 284 (VD->getType().isObjCGCWeak() ? BLOCK_FIELD_IS_WEAK : 0); 285 llvm::Value *Loc = LocalDeclMap[VD]; 286 Loc = Builder.CreateStructGEP(Loc, 1, "forwarding"); 287 Loc = Builder.CreateLoad(Loc); 288 Builder.CreateStore(Loc, Addr); 289 ++helpersize; 290 continue; 291 } else 292 E = new (getContext()) DeclRefExpr (VD, 293 VD->getType(), 294 SourceLocation()); 295 } 296 if (BDRE->isByRef()) { 297 NoteForHelper[helpersize].flag = BLOCK_FIELD_IS_BYREF | 298 // FIXME: Someone double check this. 299 (VD->getType().isObjCGCWeak() ? BLOCK_FIELD_IS_WEAK : 0); 300 E = new (getContext()) 301 UnaryOperator(E, UnaryOperator::AddrOf, 302 getContext().getPointerType(E->getType()), 303 SourceLocation()); 304 } 305 ++helpersize; 306 307 RValue r = EmitAnyExpr(E, Addr, false); 308 if (r.isScalar()) { 309 llvm::Value *Loc = r.getScalarVal(); 310 const llvm::Type *Ty = Types[i+BlockFields]; 311 if (BDRE->isByRef()) { 312 // E is now the address of the value field, instead, we want the 313 // address of the actual ByRef struct. We optimize this slightly 314 // compared to gcc by not grabbing the forwarding slot as this must 315 // be done during Block_copy for us, and we can postpone the work 316 // until then. 317 CharUnits offset = BlockDecls[BDRE->getDecl()]; 318 319 llvm::Value *BlockLiteral = LoadBlockStruct(); 320 321 Loc = Builder.CreateGEP(BlockLiteral, 322 llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), 323 offset.getQuantity()), 324 "block.literal"); 325 Ty = llvm::PointerType::get(Ty, 0); 326 Loc = Builder.CreateBitCast(Loc, Ty); 327 Loc = Builder.CreateLoad(Loc); 328 // Loc = Builder.CreateBitCast(Loc, Ty); 329 } 330 Builder.CreateStore(Loc, Addr); 331 } else if (r.isComplex()) 332 // FIXME: implement 333 ErrorUnsupported(BE, "complex in block literal"); 334 else if (r.isAggregate()) 335 ; // Already created into the destination 336 else 337 assert (0 && "bad block variable"); 338 // FIXME: Ensure that the offset created by the backend for 339 // the struct matches the previously computed offset in BlockDecls. 340 } 341 NoteForHelper.resize(helpersize); 342 343 // __descriptor 344 llvm::Value *Descriptor = BuildDescriptorBlockDecl(BE, 345 subBlockHasCopyDispose, 346 subBlockSize, Ty, 347 &NoteForHelper); 348 Descriptor = Builder.CreateBitCast(Descriptor, PtrToInt8Ty); 349 Builder.CreateStore(Descriptor, Builder.CreateStructGEP(V, 4, "block.tmp")); 350 } 351 352 QualType BPT = BE->getType(); 353 V = Builder.CreateBitCast(V, ConvertType(BPT)); 354 // See if this is a __weak block variable and the must call objc_read_weak 355 // on it. 356 const FunctionType *ftype = BPT->getPointeeType()->getAs<FunctionType>(); 357 QualType RES = ftype->getResultType(); 358 if (RES.isObjCGCWeak()) { 359 // Must cast argument to id* 360 const llvm::Type *ObjectPtrTy = 361 ConvertType(CGM.getContext().getObjCIdType()); 362 const llvm::Type *PtrObjectPtrTy = 363 llvm::PointerType::getUnqual(ObjectPtrTy); 364 V = Builder.CreateBitCast(V, PtrObjectPtrTy); 365 V = CGM.getObjCRuntime().EmitObjCWeakRead(*this, V); 366 } 367 return V; 368} 369 370 371const llvm::Type *BlockModule::getBlockDescriptorType() { 372 if (BlockDescriptorType) 373 return BlockDescriptorType; 374 375 const llvm::Type *UnsignedLongTy = 376 getTypes().ConvertType(getContext().UnsignedLongTy); 377 378 // struct __block_descriptor { 379 // unsigned long reserved; 380 // unsigned long block_size; 381 // 382 // // later, the following will be added 383 // 384 // struct { 385 // void (*copyHelper)(); 386 // void (*copyHelper)(); 387 // } helpers; // !!! optional 388 // 389 // const char *signature; // the block signature 390 // const char *layout; // reserved 391 // }; 392 BlockDescriptorType = llvm::StructType::get(UnsignedLongTy->getContext(), 393 UnsignedLongTy, 394 UnsignedLongTy, 395 NULL); 396 397 getModule().addTypeName("struct.__block_descriptor", 398 BlockDescriptorType); 399 400 return BlockDescriptorType; 401} 402 403const llvm::Type *BlockModule::getGenericBlockLiteralType() { 404 if (GenericBlockLiteralType) 405 return GenericBlockLiteralType; 406 407 const llvm::Type *BlockDescPtrTy = 408 llvm::PointerType::getUnqual(getBlockDescriptorType()); 409 410 const llvm::IntegerType *IntTy = cast<llvm::IntegerType>( 411 getTypes().ConvertType(getContext().IntTy)); 412 413 // struct __block_literal_generic { 414 // void *__isa; 415 // int __flags; 416 // int __reserved; 417 // void (*__invoke)(void *); 418 // struct __block_descriptor *__descriptor; 419 // }; 420 GenericBlockLiteralType = llvm::StructType::get(IntTy->getContext(), 421 PtrToInt8Ty, 422 IntTy, 423 IntTy, 424 PtrToInt8Ty, 425 BlockDescPtrTy, 426 NULL); 427 428 getModule().addTypeName("struct.__block_literal_generic", 429 GenericBlockLiteralType); 430 431 return GenericBlockLiteralType; 432} 433 434 435RValue CodeGenFunction::EmitBlockCallExpr(const CallExpr* E, 436 ReturnValueSlot ReturnValue) { 437 const BlockPointerType *BPT = 438 E->getCallee()->getType()->getAs<BlockPointerType>(); 439 440 llvm::Value *Callee = EmitScalarExpr(E->getCallee()); 441 442 // Get a pointer to the generic block literal. 443 const llvm::Type *BlockLiteralTy = 444 llvm::PointerType::getUnqual(CGM.getGenericBlockLiteralType()); 445 446 // Bitcast the callee to a block literal. 447 llvm::Value *BlockLiteral = 448 Builder.CreateBitCast(Callee, BlockLiteralTy, "block.literal"); 449 450 // Get the function pointer from the literal. 451 llvm::Value *FuncPtr = Builder.CreateStructGEP(BlockLiteral, 3, "tmp"); 452 453 BlockLiteral = 454 Builder.CreateBitCast(BlockLiteral, 455 llvm::Type::getInt8PtrTy(VMContext), 456 "tmp"); 457 458 // Add the block literal. 459 QualType VoidPtrTy = getContext().getPointerType(getContext().VoidTy); 460 CallArgList Args; 461 Args.push_back(std::make_pair(RValue::get(BlockLiteral), VoidPtrTy)); 462 463 QualType FnType = BPT->getPointeeType(); 464 465 // And the rest of the arguments. 466 EmitCallArgs(Args, FnType->getAs<FunctionProtoType>(), 467 E->arg_begin(), E->arg_end()); 468 469 // Load the function. 470 llvm::Value *Func = Builder.CreateLoad(FuncPtr, "tmp"); 471 472 const FunctionType *FuncTy = FnType->getAs<FunctionType>(); 473 QualType ResultType = FuncTy->getResultType(); 474 475 const CGFunctionInfo &FnInfo = 476 CGM.getTypes().getFunctionInfo(ResultType, Args, 477 FuncTy->getExtInfo()); 478 479 // Cast the function pointer to the right type. 480 const llvm::Type *BlockFTy = 481 CGM.getTypes().GetFunctionType(FnInfo, false); 482 483 const llvm::Type *BlockFTyPtr = llvm::PointerType::getUnqual(BlockFTy); 484 Func = Builder.CreateBitCast(Func, BlockFTyPtr); 485 486 // And call the block. 487 return EmitCall(FnInfo, Func, ReturnValue, Args); 488} 489 490CharUnits CodeGenFunction::AllocateBlockDecl(const BlockDeclRefExpr *E) { 491 const ValueDecl *VD = E->getDecl(); 492 CharUnits &offset = BlockDecls[VD]; 493 494 // See if we have already allocated an offset for this variable. 495 if (offset.isPositive()) 496 return offset; 497 498 // Don't run the expensive check, unless we have to. 499 if (!BlockHasCopyDispose) 500 if (E->isByRef() 501 || BlockRequiresCopying(E->getType())) 502 BlockHasCopyDispose = true; 503 504 // if not, allocate one now. 505 offset = getBlockOffset(E); 506 507 return offset; 508} 509 510llvm::Value *CodeGenFunction::GetAddrOfBlockDecl(const BlockDeclRefExpr *E) { 511 const ValueDecl *VD = E->getDecl(); 512 CharUnits offset = AllocateBlockDecl(E); 513 514 515 llvm::Value *BlockLiteral = LoadBlockStruct(); 516 llvm::Value *V = Builder.CreateGEP(BlockLiteral, 517 llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), 518 offset.getQuantity()), 519 "block.literal"); 520 if (E->isByRef()) { 521 const llvm::Type *PtrStructTy 522 = llvm::PointerType::get(BuildByRefType(VD), 0); 523 // The block literal will need a copy/destroy helper. 524 BlockHasCopyDispose = true; 525 526 const llvm::Type *Ty = PtrStructTy; 527 Ty = llvm::PointerType::get(Ty, 0); 528 V = Builder.CreateBitCast(V, Ty); 529 V = Builder.CreateLoad(V); 530 V = Builder.CreateStructGEP(V, 1, "forwarding"); 531 V = Builder.CreateLoad(V); 532 V = Builder.CreateBitCast(V, PtrStructTy); 533 V = Builder.CreateStructGEP(V, getByRefValueLLVMField(VD), 534 VD->getNameAsString()); 535 } else { 536 const llvm::Type *Ty = CGM.getTypes().ConvertType(VD->getType()); 537 538 Ty = llvm::PointerType::get(Ty, 0); 539 V = Builder.CreateBitCast(V, Ty); 540 } 541 return V; 542} 543 544void CodeGenFunction::BlockForwardSelf() { 545 const ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(CurFuncDecl); 546 ImplicitParamDecl *SelfDecl = OMD->getSelfDecl(); 547 llvm::Value *&DMEntry = LocalDeclMap[SelfDecl]; 548 if (DMEntry) 549 return; 550 // FIXME - Eliminate BlockDeclRefExprs, clients don't need/want to care 551 BlockDeclRefExpr *BDRE = new (getContext()) 552 BlockDeclRefExpr(SelfDecl, 553 SelfDecl->getType(), SourceLocation(), false); 554 DMEntry = GetAddrOfBlockDecl(BDRE); 555} 556 557llvm::Constant * 558BlockModule::GetAddrOfGlobalBlock(const BlockExpr *BE, const char * n) { 559 // Generate the block descriptor. 560 const llvm::Type *UnsignedLongTy = Types.ConvertType(Context.UnsignedLongTy); 561 const llvm::IntegerType *IntTy = cast<llvm::IntegerType>( 562 getTypes().ConvertType(getContext().IntTy)); 563 564 llvm::Constant *DescriptorFields[4]; 565 566 // Reserved 567 DescriptorFields[0] = llvm::Constant::getNullValue(UnsignedLongTy); 568 569 // Block literal size. For global blocks we just use the size of the generic 570 // block literal struct. 571 CharUnits BlockLiteralSize = 572 CGM.GetTargetTypeStoreSize(getGenericBlockLiteralType()); 573 DescriptorFields[1] = 574 llvm::ConstantInt::get(UnsignedLongTy,BlockLiteralSize.getQuantity()); 575 576 // signature. non-optional ObjC-style method descriptor @encode sequence 577 std::string BlockTypeEncoding; 578 CGM.getContext().getObjCEncodingForBlock(BE, BlockTypeEncoding); 579 580 DescriptorFields[2] = llvm::ConstantExpr::getBitCast( 581 CGM.GetAddrOfConstantCString(BlockTypeEncoding), PtrToInt8Ty); 582 583 // layout 584 DescriptorFields[3] = 585 llvm::ConstantInt::get(UnsignedLongTy,0); 586 587 // build the structure from the 4 elements 588 llvm::Constant *DescriptorStruct = 589 llvm::ConstantStruct::get(VMContext, &DescriptorFields[0], 4, false); 590 591 llvm::GlobalVariable *Descriptor = 592 new llvm::GlobalVariable(getModule(), DescriptorStruct->getType(), true, 593 llvm::GlobalVariable::InternalLinkage, 594 DescriptorStruct, "__block_descriptor_global"); 595 596 int FieldCount = 5; 597 // Generate the constants for the block literal. 598 599 std::vector<llvm::Constant*> LiteralFields(FieldCount); 600 601 CodeGenFunction::BlockInfo Info(0, n); 602 CharUnits subBlockSize; 603 CharUnits subBlockAlign; 604 llvm::SmallVector<const Expr *, 8> subBlockDeclRefDecls; 605 bool subBlockHasCopyDispose = false; 606 llvm::DenseMap<const Decl*, llvm::Value*> LocalDeclMap; 607 llvm::Function *Fn 608 = CodeGenFunction(CGM).GenerateBlockFunction(BE, Info, 0, LocalDeclMap, 609 subBlockSize, 610 subBlockAlign, 611 subBlockDeclRefDecls, 612 subBlockHasCopyDispose); 613 assert(subBlockSize == BlockLiteralSize 614 && "no imports allowed for global block"); 615 616 // isa 617 LiteralFields[0] = getNSConcreteGlobalBlock(); 618 619 // Flags 620 LiteralFields[1] = 621 llvm::ConstantInt::get(IntTy, BLOCK_IS_GLOBAL | BLOCK_HAS_SIGNATURE); 622 623 // Reserved 624 LiteralFields[2] = llvm::Constant::getNullValue(IntTy); 625 626 // Function 627 LiteralFields[3] = Fn; 628 629 // Descriptor 630 LiteralFields[4] = Descriptor; 631 632 llvm::Constant *BlockLiteralStruct = 633 llvm::ConstantStruct::get(VMContext, LiteralFields, false); 634 635 llvm::GlobalVariable *BlockLiteral = 636 new llvm::GlobalVariable(getModule(), BlockLiteralStruct->getType(), true, 637 llvm::GlobalVariable::InternalLinkage, 638 BlockLiteralStruct, "__block_literal_global"); 639 640 return BlockLiteral; 641} 642 643llvm::Value *CodeGenFunction::LoadBlockStruct() { 644 llvm::Value *V = Builder.CreateLoad(LocalDeclMap[getBlockStructDecl()], 645 "self"); 646 // For now, we codegen based upon byte offsets. 647 return Builder.CreateBitCast(V, PtrToInt8Ty); 648} 649 650llvm::Function * 651CodeGenFunction::GenerateBlockFunction(const BlockExpr *BExpr, 652 const BlockInfo& Info, 653 const Decl *OuterFuncDecl, 654 llvm::DenseMap<const Decl*, llvm::Value*> ldm, 655 CharUnits &Size, 656 CharUnits &Align, 657 llvm::SmallVector<const Expr *, 8> &subBlockDeclRefDecls, 658 bool &subBlockHasCopyDispose) { 659 660 // Check if we should generate debug info for this block. 661 if (CGM.getDebugInfo()) 662 DebugInfo = CGM.getDebugInfo(); 663 664 // Arrange for local static and local extern declarations to appear 665 // to be local to this function as well, as they are directly referenced 666 // in a block. 667 for (llvm::DenseMap<const Decl *, llvm::Value*>::iterator i = ldm.begin(); 668 i != ldm.end(); 669 ++i) { 670 const VarDecl *VD = dyn_cast<VarDecl>(i->first); 671 672 if (VD->getStorageClass() == VarDecl::Static || VD->hasExternalStorage()) 673 LocalDeclMap[VD] = i->second; 674 } 675 676 BlockOffset = 677 CGM.GetTargetTypeStoreSize(CGM.getGenericBlockLiteralType()); 678 BlockAlign = getContext().getTypeAlignInChars(getContext().VoidPtrTy); 679 680 const FunctionType *BlockFunctionType = BExpr->getFunctionType(); 681 QualType ResultType; 682 FunctionType::ExtInfo EInfo = getFunctionExtInfo(*BlockFunctionType); 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, EInfo); 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, FunctionType::ExtInfo()); 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, FunctionType::ExtInfo()); 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, FunctionType::ExtInfo()); 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, FunctionType::ExtInfo()); 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