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