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