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