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