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