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