12437cbfaSAnders Carlsson //===--- CGBlocks.cpp - Emit LLVM Code for declarations -------------------===// 22437cbfaSAnders Carlsson // 32437cbfaSAnders Carlsson // The LLVM Compiler Infrastructure 42437cbfaSAnders Carlsson // 52437cbfaSAnders Carlsson // This file is distributed under the University of Illinois Open Source 62437cbfaSAnders Carlsson // License. See LICENSE.TXT for details. 72437cbfaSAnders Carlsson // 82437cbfaSAnders Carlsson //===----------------------------------------------------------------------===// 92437cbfaSAnders Carlsson // 102437cbfaSAnders Carlsson // This contains code to emit blocks. 112437cbfaSAnders Carlsson // 122437cbfaSAnders Carlsson //===----------------------------------------------------------------------===// 132437cbfaSAnders Carlsson 142e722b91SMike Stump #include "CGDebugInfo.h" 152437cbfaSAnders Carlsson #include "CodeGenFunction.h" 16989908fbSFariborz Jahanian #include "CGObjCRuntime.h" 172437cbfaSAnders Carlsson #include "CodeGenModule.h" 18ad7c5c16SJohn McCall #include "CGBlocks.h" 19692c6e37SMike Stump #include "clang/AST/DeclObjC.h" 202437cbfaSAnders Carlsson #include "llvm/Module.h" 219e2e1c90SBenjamin Kramer #include "llvm/ADT/SmallSet.h" 226a60fa24SAnders Carlsson #include "llvm/Target/TargetData.h" 232437cbfaSAnders Carlsson #include <algorithm> 24db714924STorok Edwin 252437cbfaSAnders Carlsson using namespace clang; 262437cbfaSAnders Carlsson using namespace CodeGen; 272437cbfaSAnders Carlsson 28351762cdSJohn McCall CGBlockInfo::CGBlockInfo(const BlockExpr *blockExpr, const char *N) 29351762cdSJohn McCall : Name(N), CXXThisIndex(0), CanBeGlobal(false), NeedsCopyDispose(false), 3085915250SJohn McCall HasCXXObject(false), UsesStret(false), StructureType(0), Block(blockExpr) { 319d42f0f1SJohn McCall 329d42f0f1SJohn McCall // Skip asm prefix, if any. 339d42f0f1SJohn McCall if (Name && Name[0] == '\01') 349d42f0f1SJohn McCall ++Name; 359d42f0f1SJohn McCall } 369d42f0f1SJohn McCall 37f9b056b0SJohn McCall // Anchor the vtable to this translation unit. 38f9b056b0SJohn McCall CodeGenModule::ByrefHelpers::~ByrefHelpers() {} 39f9b056b0SJohn McCall 40351762cdSJohn McCall /// Build the given block as a global block. 41351762cdSJohn McCall static llvm::Constant *buildGlobalBlock(CodeGenModule &CGM, 42351762cdSJohn McCall const CGBlockInfo &blockInfo, 43351762cdSJohn McCall llvm::Constant *blockFn); 449d42f0f1SJohn McCall 45351762cdSJohn McCall /// Build the helper function to copy a block. 46351762cdSJohn McCall static llvm::Constant *buildCopyHelper(CodeGenModule &CGM, 47351762cdSJohn McCall const CGBlockInfo &blockInfo) { 48351762cdSJohn McCall return CodeGenFunction(CGM).GenerateCopyHelperFunction(blockInfo); 49351762cdSJohn McCall } 50351762cdSJohn McCall 51351762cdSJohn McCall /// Build the helper function to dipose of a block. 52351762cdSJohn McCall static llvm::Constant *buildDisposeHelper(CodeGenModule &CGM, 53351762cdSJohn McCall const CGBlockInfo &blockInfo) { 54351762cdSJohn McCall return CodeGenFunction(CGM).GenerateDestroyHelperFunction(blockInfo); 55351762cdSJohn McCall } 56351762cdSJohn McCall 57351762cdSJohn McCall /// Build the block descriptor constant for a block. 58351762cdSJohn McCall static llvm::Constant *buildBlockDescriptor(CodeGenModule &CGM, 59351762cdSJohn McCall const CGBlockInfo &blockInfo) { 60351762cdSJohn McCall ASTContext &C = CGM.getContext(); 61351762cdSJohn McCall 62351762cdSJohn McCall const llvm::Type *ulong = CGM.getTypes().ConvertType(C.UnsignedLongTy); 63351762cdSJohn McCall const llvm::Type *i8p = CGM.getTypes().ConvertType(C.VoidPtrTy); 64351762cdSJohn McCall 65351762cdSJohn McCall llvm::SmallVector<llvm::Constant*, 6> elements; 6685284bacSMike Stump 6785284bacSMike Stump // reserved 68351762cdSJohn McCall elements.push_back(llvm::ConstantInt::get(ulong, 0)); 6985284bacSMike Stump 7085284bacSMike Stump // Size 712ac40a9fSMike Stump // FIXME: What is the right way to say this doesn't fit? We should give 722ac40a9fSMike Stump // a user diagnostic in that case. Better fix would be to change the 732ac40a9fSMike Stump // API to size_t. 74351762cdSJohn McCall elements.push_back(llvm::ConstantInt::get(ulong, 75351762cdSJohn McCall blockInfo.BlockSize.getQuantity())); 7685284bacSMike Stump 77351762cdSJohn McCall // Optional copy/dispose helpers. 78351762cdSJohn McCall if (blockInfo.NeedsCopyDispose) { 7985284bacSMike Stump // copy_func_helper_decl 80351762cdSJohn McCall elements.push_back(buildCopyHelper(CGM, blockInfo)); 8185284bacSMike Stump 8285284bacSMike Stump // destroy_func_decl 83351762cdSJohn McCall elements.push_back(buildDisposeHelper(CGM, blockInfo)); 8485284bacSMike Stump } 8585284bacSMike Stump 86351762cdSJohn McCall // Signature. Mandatory ObjC-style method descriptor @encode sequence. 87351762cdSJohn McCall std::string typeAtEncoding = 88351762cdSJohn McCall CGM.getContext().getObjCEncodingForBlock(blockInfo.getBlockExpr()); 89351762cdSJohn McCall elements.push_back(llvm::ConstantExpr::getBitCast( 90351762cdSJohn McCall CGM.GetAddrOfConstantCString(typeAtEncoding), i8p)); 91fc83aa04SBlaine Garst 92351762cdSJohn McCall // GC layout. 93351762cdSJohn McCall if (C.getLangOptions().ObjC1) 94351762cdSJohn McCall elements.push_back(CGM.getObjCRuntime().BuildGCBlockLayout(CGM, blockInfo)); 95351762cdSJohn McCall else 96351762cdSJohn McCall elements.push_back(llvm::Constant::getNullValue(i8p)); 97fc83aa04SBlaine Garst 98e64d7ba1SChris Lattner llvm::Constant *init = llvm::ConstantStruct::getAnon(elements); 99c05349e5SFariborz Jahanian 100351762cdSJohn McCall llvm::GlobalVariable *global = 101351762cdSJohn McCall new llvm::GlobalVariable(CGM.getModule(), init->getType(), true, 10285284bacSMike Stump llvm::GlobalValue::InternalLinkage, 103351762cdSJohn McCall init, "__block_descriptor_tmp"); 10485284bacSMike Stump 105351762cdSJohn McCall return llvm::ConstantExpr::getBitCast(global, CGM.getBlockDescriptorType()); 106ed5e69feSAnders Carlsson } 107ed5e69feSAnders Carlsson 108351762cdSJohn McCall /* 109351762cdSJohn McCall Purely notional variadic template describing the layout of a block. 110ed5e69feSAnders Carlsson 111351762cdSJohn McCall template <class _ResultType, class... _ParamTypes, class... _CaptureTypes> 112351762cdSJohn McCall struct Block_literal { 113351762cdSJohn McCall /// Initialized to one of: 114351762cdSJohn McCall /// extern void *_NSConcreteStackBlock[]; 115351762cdSJohn McCall /// extern void *_NSConcreteGlobalBlock[]; 116351762cdSJohn McCall /// 117351762cdSJohn McCall /// In theory, we could start one off malloc'ed by setting 118351762cdSJohn McCall /// BLOCK_NEEDS_FREE, giving it a refcount of 1, and using 119351762cdSJohn McCall /// this isa: 120351762cdSJohn McCall /// extern void *_NSConcreteMallocBlock[]; 121351762cdSJohn McCall struct objc_class *isa; 12285284bacSMike Stump 123351762cdSJohn McCall /// These are the flags (with corresponding bit number) that the 124351762cdSJohn McCall /// compiler is actually supposed to know about. 125351762cdSJohn McCall /// 25. BLOCK_HAS_COPY_DISPOSE - indicates that the block 126351762cdSJohn McCall /// descriptor provides copy and dispose helper functions 127351762cdSJohn McCall /// 26. BLOCK_HAS_CXX_OBJ - indicates that there's a captured 128351762cdSJohn McCall /// object with a nontrivial destructor or copy constructor 129351762cdSJohn McCall /// 28. BLOCK_IS_GLOBAL - indicates that the block is allocated 130351762cdSJohn McCall /// as global memory 131351762cdSJohn McCall /// 29. BLOCK_USE_STRET - indicates that the block function 132351762cdSJohn McCall /// uses stret, which objc_msgSend needs to know about 133351762cdSJohn McCall /// 30. BLOCK_HAS_SIGNATURE - indicates that the block has an 134351762cdSJohn McCall /// @encoded signature string 135351762cdSJohn McCall /// And we're not supposed to manipulate these: 136351762cdSJohn McCall /// 24. BLOCK_NEEDS_FREE - indicates that the block has been moved 137351762cdSJohn McCall /// to malloc'ed memory 138351762cdSJohn McCall /// 27. BLOCK_IS_GC - indicates that the block has been moved to 139351762cdSJohn McCall /// to GC-allocated memory 140351762cdSJohn McCall /// Additionally, the bottom 16 bits are a reference count which 141351762cdSJohn McCall /// should be zero on the stack. 142351762cdSJohn McCall int flags; 143950a9518SDavid Chisnall 144351762cdSJohn McCall /// Reserved; should be zero-initialized. 145351762cdSJohn McCall int reserved; 146950a9518SDavid Chisnall 147351762cdSJohn McCall /// Function pointer generated from block literal. 148351762cdSJohn McCall _ResultType (*invoke)(Block_literal *, _ParamTypes...); 14985284bacSMike Stump 150351762cdSJohn McCall /// Block description metadata generated from block literal. 151351762cdSJohn McCall struct Block_descriptor *block_descriptor; 1523882ace2SJohn McCall 153351762cdSJohn McCall /// Captured values follow. 154351762cdSJohn McCall _CapturesTypes captures...; 155351762cdSJohn McCall }; 156351762cdSJohn McCall */ 157950a9518SDavid Chisnall 158351762cdSJohn McCall /// The number of fields in a block header. 159351762cdSJohn McCall const unsigned BlockHeaderSize = 5; 1604446dcf0SMike Stump 161351762cdSJohn McCall namespace { 162351762cdSJohn McCall /// A chunk of data that we actually have to capture in the block. 163351762cdSJohn McCall struct BlockLayoutChunk { 164351762cdSJohn McCall CharUnits Alignment; 165351762cdSJohn McCall CharUnits Size; 166351762cdSJohn McCall const BlockDecl::Capture *Capture; // null for 'this' 1677c57be3eSJay Foad llvm::Type *Type; 16885284bacSMike Stump 169351762cdSJohn McCall BlockLayoutChunk(CharUnits align, CharUnits size, 170351762cdSJohn McCall const BlockDecl::Capture *capture, 1717c57be3eSJay Foad llvm::Type *type) 172351762cdSJohn McCall : Alignment(align), Size(size), Capture(capture), Type(type) {} 17385284bacSMike Stump 174351762cdSJohn McCall /// Tell the block info that this chunk has the given field index. 175351762cdSJohn McCall void setIndex(CGBlockInfo &info, unsigned index) { 176351762cdSJohn McCall if (!Capture) 177351762cdSJohn McCall info.CXXThisIndex = index; 178b750d928SMike Stump else 179351762cdSJohn McCall info.Captures[Capture->getVariable()] 180351762cdSJohn McCall = CGBlockInfo::Capture::makeIndex(index); 181b750d928SMike Stump } 182351762cdSJohn McCall }; 183d6ef62f0SMike Stump 184351762cdSJohn McCall /// Order by descending alignment. 185351762cdSJohn McCall bool operator<(const BlockLayoutChunk &left, const BlockLayoutChunk &right) { 186351762cdSJohn McCall return left.Alignment > right.Alignment; 187351762cdSJohn McCall } 188b750d928SMike Stump } 189b750d928SMike Stump 190b0a3ecb4SJohn McCall /// Determines if the given type is safe for constant capture in C++. 191b0a3ecb4SJohn McCall static bool isSafeForCXXConstantCapture(QualType type) { 192b0a3ecb4SJohn McCall const RecordType *recordType = 193b0a3ecb4SJohn McCall type->getBaseElementTypeUnsafe()->getAs<RecordType>(); 194b0a3ecb4SJohn McCall 195b0a3ecb4SJohn McCall // Only records can be unsafe. 196b0a3ecb4SJohn McCall if (!recordType) return true; 197b0a3ecb4SJohn McCall 198b0a3ecb4SJohn McCall const CXXRecordDecl *record = cast<CXXRecordDecl>(recordType->getDecl()); 199b0a3ecb4SJohn McCall 200b0a3ecb4SJohn McCall // Maintain semantics for classes with non-trivial dtors or copy ctors. 201b0a3ecb4SJohn McCall if (!record->hasTrivialDestructor()) return false; 202b0a3ecb4SJohn McCall if (!record->hasTrivialCopyConstructor()) return false; 203b0a3ecb4SJohn McCall 204b0a3ecb4SJohn McCall // Otherwise, we just have to make sure there aren't any mutable 205b0a3ecb4SJohn McCall // fields that might have changed since initialization. 20661226d3fSDouglas Gregor return !record->hasMutableFields(); 207b0a3ecb4SJohn McCall } 208b0a3ecb4SJohn McCall 209351762cdSJohn McCall /// It is illegal to modify a const object after initialization. 210351762cdSJohn McCall /// Therefore, if a const object has a constant initializer, we don't 211351762cdSJohn McCall /// actually need to keep storage for it in the block; we'll just 212351762cdSJohn McCall /// rematerialize it at the start of the block function. This is 213351762cdSJohn McCall /// acceptable because we make no promises about address stability of 214351762cdSJohn McCall /// captured variables. 215351762cdSJohn McCall static llvm::Constant *tryCaptureAsConstant(CodeGenModule &CGM, 216351762cdSJohn McCall const VarDecl *var) { 217351762cdSJohn McCall QualType type = var->getType(); 218351762cdSJohn McCall 219351762cdSJohn McCall // We can only do this if the variable is const. 220351762cdSJohn McCall if (!type.isConstQualified()) return 0; 221351762cdSJohn McCall 222b0a3ecb4SJohn McCall // Furthermore, in C++ we have to worry about mutable fields: 223b0a3ecb4SJohn McCall // C++ [dcl.type.cv]p4: 224b0a3ecb4SJohn McCall // Except that any class member declared mutable can be 225b0a3ecb4SJohn McCall // modified, any attempt to modify a const object during its 226b0a3ecb4SJohn McCall // lifetime results in undefined behavior. 227b0a3ecb4SJohn McCall if (CGM.getLangOptions().CPlusPlus && !isSafeForCXXConstantCapture(type)) 228351762cdSJohn McCall return 0; 229351762cdSJohn McCall 230351762cdSJohn McCall // If the variable doesn't have any initializer (shouldn't this be 231351762cdSJohn McCall // invalid?), it's not clear what we should do. Maybe capture as 232351762cdSJohn McCall // zero? 233351762cdSJohn McCall const Expr *init = var->getInit(); 234351762cdSJohn McCall if (!init) return 0; 235351762cdSJohn McCall 236351762cdSJohn McCall return CGM.EmitConstantExpr(init, var->getType()); 237351762cdSJohn McCall } 238351762cdSJohn McCall 239351762cdSJohn McCall /// Get the low bit of a nonzero character count. This is the 240351762cdSJohn McCall /// alignment of the nth byte if the 0th byte is universally aligned. 241351762cdSJohn McCall static CharUnits getLowBit(CharUnits v) { 242351762cdSJohn McCall return CharUnits::fromQuantity(v.getQuantity() & (~v.getQuantity() + 1)); 243351762cdSJohn McCall } 244351762cdSJohn McCall 245351762cdSJohn McCall static void initializeForBlockHeader(CodeGenModule &CGM, CGBlockInfo &info, 2467c57be3eSJay Foad llvm::SmallVectorImpl<llvm::Type*> &elementTypes) { 247351762cdSJohn McCall ASTContext &C = CGM.getContext(); 248351762cdSJohn McCall 249351762cdSJohn McCall // The header is basically a 'struct { void *; int; int; void *; void *; }'. 250351762cdSJohn McCall CharUnits ptrSize, ptrAlign, intSize, intAlign; 251351762cdSJohn McCall llvm::tie(ptrSize, ptrAlign) = C.getTypeInfoInChars(C.VoidPtrTy); 252351762cdSJohn McCall llvm::tie(intSize, intAlign) = C.getTypeInfoInChars(C.IntTy); 253351762cdSJohn McCall 254351762cdSJohn McCall // Are there crazy embedded platforms where this isn't true? 255351762cdSJohn McCall assert(intSize <= ptrSize && "layout assumptions horribly violated"); 256351762cdSJohn McCall 257351762cdSJohn McCall CharUnits headerSize = ptrSize; 258351762cdSJohn McCall if (2 * intSize < ptrAlign) headerSize += ptrSize; 259351762cdSJohn McCall else headerSize += 2 * intSize; 260351762cdSJohn McCall headerSize += 2 * ptrSize; 261351762cdSJohn McCall 262351762cdSJohn McCall info.BlockAlign = ptrAlign; 263351762cdSJohn McCall info.BlockSize = headerSize; 264351762cdSJohn McCall 265351762cdSJohn McCall assert(elementTypes.empty()); 2667c57be3eSJay Foad llvm::Type *i8p = CGM.getTypes().ConvertType(C.VoidPtrTy); 2677c57be3eSJay Foad llvm::Type *intTy = CGM.getTypes().ConvertType(C.IntTy); 268351762cdSJohn McCall elementTypes.push_back(i8p); 269351762cdSJohn McCall elementTypes.push_back(intTy); 270351762cdSJohn McCall elementTypes.push_back(intTy); 271351762cdSJohn McCall elementTypes.push_back(i8p); 272351762cdSJohn McCall elementTypes.push_back(CGM.getBlockDescriptorType()); 273351762cdSJohn McCall 274351762cdSJohn McCall assert(elementTypes.size() == BlockHeaderSize); 275351762cdSJohn McCall } 276351762cdSJohn McCall 277351762cdSJohn McCall /// Compute the layout of the given block. Attempts to lay the block 278351762cdSJohn McCall /// out with minimal space requirements. 279351762cdSJohn McCall static void computeBlockInfo(CodeGenModule &CGM, CGBlockInfo &info) { 280351762cdSJohn McCall ASTContext &C = CGM.getContext(); 281351762cdSJohn McCall const BlockDecl *block = info.getBlockDecl(); 282351762cdSJohn McCall 2837c57be3eSJay Foad llvm::SmallVector<llvm::Type*, 8> elementTypes; 284351762cdSJohn McCall initializeForBlockHeader(CGM, info, elementTypes); 285351762cdSJohn McCall 286351762cdSJohn McCall if (!block->hasCaptures()) { 287351762cdSJohn McCall info.StructureType = 288351762cdSJohn McCall llvm::StructType::get(CGM.getLLVMContext(), elementTypes, true); 289351762cdSJohn McCall info.CanBeGlobal = true; 290351762cdSJohn McCall return; 291351762cdSJohn McCall } 292351762cdSJohn McCall 293351762cdSJohn McCall // Collect the layout chunks. 294351762cdSJohn McCall llvm::SmallVector<BlockLayoutChunk, 16> layout; 295351762cdSJohn McCall layout.reserve(block->capturesCXXThis() + 296351762cdSJohn McCall (block->capture_end() - block->capture_begin())); 297351762cdSJohn McCall 298351762cdSJohn McCall CharUnits maxFieldAlign; 299351762cdSJohn McCall 300351762cdSJohn McCall // First, 'this'. 301351762cdSJohn McCall if (block->capturesCXXThis()) { 302351762cdSJohn McCall const DeclContext *DC = block->getDeclContext(); 303351762cdSJohn McCall for (; isa<BlockDecl>(DC); DC = cast<BlockDecl>(DC)->getDeclContext()) 304351762cdSJohn McCall ; 305938f40b5SRichard Smith QualType thisType; 306938f40b5SRichard Smith if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(DC)) 307938f40b5SRichard Smith thisType = C.getPointerType(C.getRecordType(RD)); 308938f40b5SRichard Smith else 309938f40b5SRichard Smith thisType = cast<CXXMethodDecl>(DC)->getThisType(C); 310351762cdSJohn McCall 3117c57be3eSJay Foad llvm::Type *llvmType = CGM.getTypes().ConvertType(thisType); 312351762cdSJohn McCall std::pair<CharUnits,CharUnits> tinfo 313351762cdSJohn McCall = CGM.getContext().getTypeInfoInChars(thisType); 314351762cdSJohn McCall maxFieldAlign = std::max(maxFieldAlign, tinfo.second); 315351762cdSJohn McCall 316351762cdSJohn McCall layout.push_back(BlockLayoutChunk(tinfo.second, tinfo.first, 0, llvmType)); 317351762cdSJohn McCall } 318351762cdSJohn McCall 319351762cdSJohn McCall // Next, all the block captures. 320351762cdSJohn McCall for (BlockDecl::capture_const_iterator ci = block->capture_begin(), 321351762cdSJohn McCall ce = block->capture_end(); ci != ce; ++ci) { 322351762cdSJohn McCall const VarDecl *variable = ci->getVariable(); 323351762cdSJohn McCall 324351762cdSJohn McCall if (ci->isByRef()) { 325351762cdSJohn McCall // We have to copy/dispose of the __block reference. 326351762cdSJohn McCall info.NeedsCopyDispose = true; 327351762cdSJohn McCall 328351762cdSJohn McCall // Just use void* instead of a pointer to the byref type. 329351762cdSJohn McCall QualType byRefPtrTy = C.VoidPtrTy; 330351762cdSJohn McCall 3317c57be3eSJay Foad llvm::Type *llvmType = CGM.getTypes().ConvertType(byRefPtrTy); 332351762cdSJohn McCall std::pair<CharUnits,CharUnits> tinfo 333351762cdSJohn McCall = CGM.getContext().getTypeInfoInChars(byRefPtrTy); 334351762cdSJohn McCall maxFieldAlign = std::max(maxFieldAlign, tinfo.second); 335351762cdSJohn McCall 336351762cdSJohn McCall layout.push_back(BlockLayoutChunk(tinfo.second, tinfo.first, 337351762cdSJohn McCall &*ci, llvmType)); 338351762cdSJohn McCall continue; 339351762cdSJohn McCall } 340351762cdSJohn McCall 341351762cdSJohn McCall // Otherwise, build a layout chunk with the size and alignment of 342351762cdSJohn McCall // the declaration. 343351762cdSJohn McCall if (llvm::Constant *constant = tryCaptureAsConstant(CGM, variable)) { 344351762cdSJohn McCall info.Captures[variable] = CGBlockInfo::Capture::makeConstant(constant); 345351762cdSJohn McCall continue; 346351762cdSJohn McCall } 347351762cdSJohn McCall 34831168b07SJohn McCall // If we have a lifetime qualifier, honor it for capture purposes. 34931168b07SJohn McCall // That includes *not* copying it if it's __unsafe_unretained. 35031168b07SJohn McCall if (Qualifiers::ObjCLifetime lifetime 35131168b07SJohn McCall = variable->getType().getObjCLifetime()) { 35231168b07SJohn McCall switch (lifetime) { 35331168b07SJohn McCall case Qualifiers::OCL_None: llvm_unreachable("impossible"); 35431168b07SJohn McCall case Qualifiers::OCL_ExplicitNone: 35531168b07SJohn McCall case Qualifiers::OCL_Autoreleasing: 35631168b07SJohn McCall break; 357351762cdSJohn McCall 35831168b07SJohn McCall case Qualifiers::OCL_Strong: 35931168b07SJohn McCall case Qualifiers::OCL_Weak: 36031168b07SJohn McCall info.NeedsCopyDispose = true; 36131168b07SJohn McCall } 36231168b07SJohn McCall 36331168b07SJohn McCall // Block pointers require copy/dispose. So do Objective-C pointers. 36431168b07SJohn McCall } else if (variable->getType()->isObjCRetainableType()) { 365351762cdSJohn McCall info.NeedsCopyDispose = true; 366351762cdSJohn McCall 367351762cdSJohn McCall // So do types that require non-trivial copy construction. 368351762cdSJohn McCall } else if (ci->hasCopyExpr()) { 369351762cdSJohn McCall info.NeedsCopyDispose = true; 370351762cdSJohn McCall info.HasCXXObject = true; 371351762cdSJohn McCall 372351762cdSJohn McCall // And so do types with destructors. 373351762cdSJohn McCall } else if (CGM.getLangOptions().CPlusPlus) { 374351762cdSJohn McCall if (const CXXRecordDecl *record = 375351762cdSJohn McCall variable->getType()->getAsCXXRecordDecl()) { 376351762cdSJohn McCall if (!record->hasTrivialDestructor()) { 377351762cdSJohn McCall info.HasCXXObject = true; 378351762cdSJohn McCall info.NeedsCopyDispose = true; 379351762cdSJohn McCall } 380351762cdSJohn McCall } 381351762cdSJohn McCall } 382351762cdSJohn McCall 383351762cdSJohn McCall CharUnits size = C.getTypeSizeInChars(variable->getType()); 384351762cdSJohn McCall CharUnits align = C.getDeclAlign(variable); 385351762cdSJohn McCall maxFieldAlign = std::max(maxFieldAlign, align); 386351762cdSJohn McCall 3877c57be3eSJay Foad llvm::Type *llvmType = 388351762cdSJohn McCall CGM.getTypes().ConvertTypeForMem(variable->getType()); 389351762cdSJohn McCall 390351762cdSJohn McCall layout.push_back(BlockLayoutChunk(align, size, &*ci, llvmType)); 391351762cdSJohn McCall } 392351762cdSJohn McCall 393351762cdSJohn McCall // If that was everything, we're done here. 394351762cdSJohn McCall if (layout.empty()) { 395351762cdSJohn McCall info.StructureType = 396351762cdSJohn McCall llvm::StructType::get(CGM.getLLVMContext(), elementTypes, true); 397351762cdSJohn McCall info.CanBeGlobal = true; 398351762cdSJohn McCall return; 399351762cdSJohn McCall } 400351762cdSJohn McCall 401351762cdSJohn McCall // Sort the layout by alignment. We have to use a stable sort here 402351762cdSJohn McCall // to get reproducible results. There should probably be an 403351762cdSJohn McCall // llvm::array_pod_stable_sort. 404351762cdSJohn McCall std::stable_sort(layout.begin(), layout.end()); 405351762cdSJohn McCall 406351762cdSJohn McCall CharUnits &blockSize = info.BlockSize; 407351762cdSJohn McCall info.BlockAlign = std::max(maxFieldAlign, info.BlockAlign); 408351762cdSJohn McCall 409351762cdSJohn McCall // Assuming that the first byte in the header is maximally aligned, 410351762cdSJohn McCall // get the alignment of the first byte following the header. 411351762cdSJohn McCall CharUnits endAlign = getLowBit(blockSize); 412351762cdSJohn McCall 413351762cdSJohn McCall // If the end of the header isn't satisfactorily aligned for the 414351762cdSJohn McCall // maximum thing, look for things that are okay with the header-end 415351762cdSJohn McCall // alignment, and keep appending them until we get something that's 416351762cdSJohn McCall // aligned right. This algorithm is only guaranteed optimal if 417351762cdSJohn McCall // that condition is satisfied at some point; otherwise we can get 418351762cdSJohn McCall // things like: 419351762cdSJohn McCall // header // next byte has alignment 4 420351762cdSJohn McCall // something_with_size_5; // next byte has alignment 1 421351762cdSJohn McCall // something_with_alignment_8; 422351762cdSJohn McCall // which has 7 bytes of padding, as opposed to the naive solution 423351762cdSJohn McCall // which might have less (?). 424351762cdSJohn McCall if (endAlign < maxFieldAlign) { 425351762cdSJohn McCall llvm::SmallVectorImpl<BlockLayoutChunk>::iterator 426351762cdSJohn McCall li = layout.begin() + 1, le = layout.end(); 427351762cdSJohn McCall 428351762cdSJohn McCall // Look for something that the header end is already 429351762cdSJohn McCall // satisfactorily aligned for. 430351762cdSJohn McCall for (; li != le && endAlign < li->Alignment; ++li) 431351762cdSJohn McCall ; 432351762cdSJohn McCall 433351762cdSJohn McCall // If we found something that's naturally aligned for the end of 434351762cdSJohn McCall // the header, keep adding things... 435351762cdSJohn McCall if (li != le) { 436351762cdSJohn McCall llvm::SmallVectorImpl<BlockLayoutChunk>::iterator first = li; 437351762cdSJohn McCall for (; li != le; ++li) { 438351762cdSJohn McCall assert(endAlign >= li->Alignment); 439351762cdSJohn McCall 440351762cdSJohn McCall li->setIndex(info, elementTypes.size()); 441351762cdSJohn McCall elementTypes.push_back(li->Type); 442351762cdSJohn McCall blockSize += li->Size; 443351762cdSJohn McCall endAlign = getLowBit(blockSize); 444351762cdSJohn McCall 445351762cdSJohn McCall // ...until we get to the alignment of the maximum field. 446351762cdSJohn McCall if (endAlign >= maxFieldAlign) 447351762cdSJohn McCall break; 448351762cdSJohn McCall } 449351762cdSJohn McCall 450351762cdSJohn McCall // Don't re-append everything we just appended. 451351762cdSJohn McCall layout.erase(first, li); 452351762cdSJohn McCall } 453351762cdSJohn McCall } 454351762cdSJohn McCall 455351762cdSJohn McCall // At this point, we just have to add padding if the end align still 456351762cdSJohn McCall // isn't aligned right. 457351762cdSJohn McCall if (endAlign < maxFieldAlign) { 458351762cdSJohn McCall CharUnits padding = maxFieldAlign - endAlign; 459351762cdSJohn McCall 460e3dc1707SJohn McCall elementTypes.push_back(llvm::ArrayType::get(CGM.Int8Ty, 461e3dc1707SJohn McCall padding.getQuantity())); 462351762cdSJohn McCall blockSize += padding; 463351762cdSJohn McCall 464351762cdSJohn McCall endAlign = getLowBit(blockSize); 465351762cdSJohn McCall assert(endAlign >= maxFieldAlign); 466351762cdSJohn McCall } 467351762cdSJohn McCall 468351762cdSJohn McCall // Slam everything else on now. This works because they have 469351762cdSJohn McCall // strictly decreasing alignment and we expect that size is always a 470351762cdSJohn McCall // multiple of alignment. 471351762cdSJohn McCall for (llvm::SmallVectorImpl<BlockLayoutChunk>::iterator 472351762cdSJohn McCall li = layout.begin(), le = layout.end(); li != le; ++li) { 473351762cdSJohn McCall assert(endAlign >= li->Alignment); 474351762cdSJohn McCall li->setIndex(info, elementTypes.size()); 475351762cdSJohn McCall elementTypes.push_back(li->Type); 476351762cdSJohn McCall blockSize += li->Size; 477351762cdSJohn McCall endAlign = getLowBit(blockSize); 478351762cdSJohn McCall } 479351762cdSJohn McCall 480351762cdSJohn McCall info.StructureType = 481351762cdSJohn McCall llvm::StructType::get(CGM.getLLVMContext(), elementTypes, true); 482351762cdSJohn McCall } 483351762cdSJohn McCall 484351762cdSJohn McCall /// Emit a block literal expression in the current function. 485351762cdSJohn McCall llvm::Value *CodeGenFunction::EmitBlockLiteral(const BlockExpr *blockExpr) { 486351762cdSJohn McCall std::string Name = CurFn->getName(); 487351762cdSJohn McCall CGBlockInfo blockInfo(blockExpr, Name.c_str()); 488351762cdSJohn McCall 489351762cdSJohn McCall // Compute information about the layout, etc., of this block. 490351762cdSJohn McCall computeBlockInfo(CGM, blockInfo); 491351762cdSJohn McCall 492351762cdSJohn McCall // Using that metadata, generate the actual block function. 493351762cdSJohn McCall llvm::Constant *blockFn 494351762cdSJohn McCall = CodeGenFunction(CGM).GenerateBlockFunction(CurGD, blockInfo, 495351762cdSJohn McCall CurFuncDecl, LocalDeclMap); 496e3dc1707SJohn McCall blockFn = llvm::ConstantExpr::getBitCast(blockFn, VoidPtrTy); 497351762cdSJohn McCall 498351762cdSJohn McCall // If there is nothing to capture, we can emit this as a global block. 499351762cdSJohn McCall if (blockInfo.CanBeGlobal) 500351762cdSJohn McCall return buildGlobalBlock(CGM, blockInfo, blockFn); 501351762cdSJohn McCall 502351762cdSJohn McCall // Otherwise, we have to emit this as a local block. 503351762cdSJohn McCall 504351762cdSJohn McCall llvm::Constant *isa = CGM.getNSConcreteStackBlock(); 505e3dc1707SJohn McCall isa = llvm::ConstantExpr::getBitCast(isa, VoidPtrTy); 506351762cdSJohn McCall 507351762cdSJohn McCall // Build the block descriptor. 508351762cdSJohn McCall llvm::Constant *descriptor = buildBlockDescriptor(CGM, blockInfo); 509351762cdSJohn McCall 510351762cdSJohn McCall const llvm::Type *intTy = ConvertType(getContext().IntTy); 511351762cdSJohn McCall 512351762cdSJohn McCall llvm::AllocaInst *blockAddr = 513351762cdSJohn McCall CreateTempAlloca(blockInfo.StructureType, "block"); 514351762cdSJohn McCall blockAddr->setAlignment(blockInfo.BlockAlign.getQuantity()); 515351762cdSJohn McCall 516351762cdSJohn McCall // Compute the initial on-stack block flags. 517ad7c5c16SJohn McCall BlockFlags flags = BLOCK_HAS_SIGNATURE; 518351762cdSJohn McCall if (blockInfo.NeedsCopyDispose) flags |= BLOCK_HAS_COPY_DISPOSE; 519351762cdSJohn McCall if (blockInfo.HasCXXObject) flags |= BLOCK_HAS_CXX_OBJ; 52085915250SJohn McCall if (blockInfo.UsesStret) flags |= BLOCK_USE_STRET; 521351762cdSJohn McCall 522351762cdSJohn McCall // Initialize the block literal. 523351762cdSJohn McCall Builder.CreateStore(isa, Builder.CreateStructGEP(blockAddr, 0, "block.isa")); 524ad7c5c16SJohn McCall Builder.CreateStore(llvm::ConstantInt::get(intTy, flags.getBitMask()), 525351762cdSJohn McCall Builder.CreateStructGEP(blockAddr, 1, "block.flags")); 526351762cdSJohn McCall Builder.CreateStore(llvm::ConstantInt::get(intTy, 0), 527351762cdSJohn McCall Builder.CreateStructGEP(blockAddr, 2, "block.reserved")); 528351762cdSJohn McCall Builder.CreateStore(blockFn, Builder.CreateStructGEP(blockAddr, 3, 529351762cdSJohn McCall "block.invoke")); 530351762cdSJohn McCall Builder.CreateStore(descriptor, Builder.CreateStructGEP(blockAddr, 4, 531351762cdSJohn McCall "block.descriptor")); 532351762cdSJohn McCall 533351762cdSJohn McCall // Finally, capture all the values into the block. 534351762cdSJohn McCall const BlockDecl *blockDecl = blockInfo.getBlockDecl(); 535351762cdSJohn McCall 536351762cdSJohn McCall // First, 'this'. 537351762cdSJohn McCall if (blockDecl->capturesCXXThis()) { 538351762cdSJohn McCall llvm::Value *addr = Builder.CreateStructGEP(blockAddr, 539351762cdSJohn McCall blockInfo.CXXThisIndex, 540351762cdSJohn McCall "block.captured-this.addr"); 541351762cdSJohn McCall Builder.CreateStore(LoadCXXThis(), addr); 542351762cdSJohn McCall } 543351762cdSJohn McCall 544351762cdSJohn McCall // Next, captured variables. 545351762cdSJohn McCall for (BlockDecl::capture_const_iterator ci = blockDecl->capture_begin(), 546351762cdSJohn McCall ce = blockDecl->capture_end(); ci != ce; ++ci) { 547351762cdSJohn McCall const VarDecl *variable = ci->getVariable(); 548351762cdSJohn McCall const CGBlockInfo::Capture &capture = blockInfo.getCapture(variable); 549351762cdSJohn McCall 550351762cdSJohn McCall // Ignore constant captures. 551351762cdSJohn McCall if (capture.isConstant()) continue; 552351762cdSJohn McCall 553351762cdSJohn McCall QualType type = variable->getType(); 554351762cdSJohn McCall 555351762cdSJohn McCall // This will be a [[type]]*, except that a byref entry will just be 556351762cdSJohn McCall // an i8**. 557351762cdSJohn McCall llvm::Value *blockField = 558351762cdSJohn McCall Builder.CreateStructGEP(blockAddr, capture.getIndex(), 559351762cdSJohn McCall "block.captured"); 560351762cdSJohn McCall 561351762cdSJohn McCall // Compute the address of the thing we're going to move into the 562351762cdSJohn McCall // block literal. 563351762cdSJohn McCall llvm::Value *src; 564351762cdSJohn McCall if (ci->isNested()) { 565351762cdSJohn McCall // We need to use the capture from the enclosing block. 566351762cdSJohn McCall const CGBlockInfo::Capture &enclosingCapture = 567351762cdSJohn McCall BlockInfo->getCapture(variable); 568351762cdSJohn McCall 569351762cdSJohn McCall // This is a [[type]]*, except that a byref entry wil just be an i8**. 570351762cdSJohn McCall src = Builder.CreateStructGEP(LoadBlockStruct(), 571351762cdSJohn McCall enclosingCapture.getIndex(), 572351762cdSJohn McCall "block.capture.addr"); 573351762cdSJohn McCall } else { 574351762cdSJohn McCall // This is a [[type]]*. 575351762cdSJohn McCall src = LocalDeclMap[variable]; 576351762cdSJohn McCall } 577351762cdSJohn McCall 578351762cdSJohn McCall // For byrefs, we just write the pointer to the byref struct into 579351762cdSJohn McCall // the block field. There's no need to chase the forwarding 580351762cdSJohn McCall // pointer at this point, since we're building something that will 581351762cdSJohn McCall // live a shorter life than the stack byref anyway. 582351762cdSJohn McCall if (ci->isByRef()) { 583e3dc1707SJohn McCall // Get a void* that points to the byref struct. 584351762cdSJohn McCall if (ci->isNested()) 585351762cdSJohn McCall src = Builder.CreateLoad(src, "byref.capture"); 586351762cdSJohn McCall else 587e3dc1707SJohn McCall src = Builder.CreateBitCast(src, VoidPtrTy); 588351762cdSJohn McCall 589e3dc1707SJohn McCall // Write that void* into the capture field. 590351762cdSJohn McCall Builder.CreateStore(src, blockField); 591351762cdSJohn McCall 592351762cdSJohn McCall // If we have a copy constructor, evaluate that into the block field. 593351762cdSJohn McCall } else if (const Expr *copyExpr = ci->getCopyExpr()) { 594351762cdSJohn McCall EmitSynthesizedCXXCopyCtor(blockField, src, copyExpr); 595351762cdSJohn McCall 596351762cdSJohn McCall // If it's a reference variable, copy the reference into the block field. 597351762cdSJohn McCall } else if (type->isReferenceType()) { 598351762cdSJohn McCall Builder.CreateStore(Builder.CreateLoad(src, "ref.val"), blockField); 599351762cdSJohn McCall 600351762cdSJohn McCall // Otherwise, fake up a POD copy into the block field. 601351762cdSJohn McCall } else { 60231168b07SJohn McCall // Fake up a new variable so that EmitScalarInit doesn't think 60331168b07SJohn McCall // we're referring to the variable in its own initializer. 60431168b07SJohn McCall ImplicitParamDecl blockFieldPseudoVar(/*DC*/ 0, SourceLocation(), 60531168b07SJohn McCall /*name*/ 0, type); 60631168b07SJohn McCall 60793be3f75SJohn McCall // We use one of these or the other depending on whether the 60893be3f75SJohn McCall // reference is nested. 60993be3f75SJohn McCall DeclRefExpr notNested(const_cast<VarDecl*>(variable), type, VK_LValue, 610351762cdSJohn McCall SourceLocation()); 61193be3f75SJohn McCall BlockDeclRefExpr nested(const_cast<VarDecl*>(variable), type, 61293be3f75SJohn McCall VK_LValue, SourceLocation(), /*byref*/ false); 61393be3f75SJohn McCall 61493be3f75SJohn McCall Expr *declRef = 61593be3f75SJohn McCall (ci->isNested() ? static_cast<Expr*>(&nested) : ¬Nested); 61693be3f75SJohn McCall 617351762cdSJohn McCall ImplicitCastExpr l2r(ImplicitCastExpr::OnStack, type, CK_LValueToRValue, 61893be3f75SJohn McCall declRef, VK_RValue); 6191553b190SJohn McCall EmitExprAsInit(&l2r, &blockFieldPseudoVar, 6201553b190SJohn McCall LValue::MakeAddr(blockField, type, 6211553b190SJohn McCall getContext().getDeclAlign(variable) 6221553b190SJohn McCall .getQuantity(), 6231553b190SJohn McCall getContext()), 6245c8f6c47SJohn McCall /*captured by init*/ false); 625351762cdSJohn McCall } 626351762cdSJohn McCall 627351762cdSJohn McCall // Push a destructor if necessary. The semantics for when this 628351762cdSJohn McCall // actually gets run are really obscure. 62931168b07SJohn McCall if (!ci->isByRef()) { 6304bd0fb1fSJohn McCall switch (QualType::DestructionKind dtorKind = type.isDestructedType()) { 63131168b07SJohn McCall case QualType::DK_none: 63231168b07SJohn McCall break; 6334bd0fb1fSJohn McCall 6344bd0fb1fSJohn McCall // Block captures count as local values and have imprecise semantics. 6354bd0fb1fSJohn McCall // They also can't be arrays, so need to worry about that. 636*5fa8e208SJohn McCall case QualType::DK_objc_strong_lifetime: { 637*5fa8e208SJohn McCall // This local is a GCC and MSVC compiler workaround. 638*5fa8e208SJohn McCall Destroyer *destroyer = &destroyARCStrongImprecise; 6394bd0fb1fSJohn McCall pushDestroy(getCleanupKind(dtorKind), blockField, type, 640*5fa8e208SJohn McCall *destroyer, /*useEHCleanupForArray*/ false); 64131168b07SJohn McCall break; 642*5fa8e208SJohn McCall } 6434bd0fb1fSJohn McCall 64431168b07SJohn McCall case QualType::DK_objc_weak_lifetime: 6454bd0fb1fSJohn McCall case QualType::DK_cxx_destructor: 6464bd0fb1fSJohn McCall pushDestroy(dtorKind, blockField, type); 64731168b07SJohn McCall break; 64831168b07SJohn McCall } 64931168b07SJohn McCall } 650351762cdSJohn McCall } 651351762cdSJohn McCall 652351762cdSJohn McCall // Cast to the converted block-pointer type, which happens (somewhat 653351762cdSJohn McCall // unfortunately) to be a pointer to function type. 654351762cdSJohn McCall llvm::Value *result = 655351762cdSJohn McCall Builder.CreateBitCast(blockAddr, 656351762cdSJohn McCall ConvertType(blockInfo.getBlockExpr()->getType())); 6573882ace2SJohn McCall 658351762cdSJohn McCall return result; 659b750d928SMike Stump } 66085284bacSMike Stump 66185284bacSMike Stump 662a5f58b05SChris Lattner llvm::Type *CodeGenModule::getBlockDescriptorType() { 663650c932dSMike Stump if (BlockDescriptorType) 664650c932dSMike Stump return BlockDescriptorType; 6652437cbfaSAnders Carlsson 666a5f58b05SChris Lattner llvm::Type *UnsignedLongTy = 667650c932dSMike Stump getTypes().ConvertType(getContext().UnsignedLongTy); 6682437cbfaSAnders Carlsson 6692437cbfaSAnders Carlsson // struct __block_descriptor { 6702437cbfaSAnders Carlsson // unsigned long reserved; 6712437cbfaSAnders Carlsson // unsigned long block_size; 672fc83aa04SBlaine Garst // 673fc83aa04SBlaine Garst // // later, the following will be added 674fc83aa04SBlaine Garst // 675fc83aa04SBlaine Garst // struct { 676fc83aa04SBlaine Garst // void (*copyHelper)(); 677fc83aa04SBlaine Garst // void (*copyHelper)(); 678fc83aa04SBlaine Garst // } helpers; // !!! optional 679fc83aa04SBlaine Garst // 680fc83aa04SBlaine Garst // const char *signature; // the block signature 681fc83aa04SBlaine Garst // const char *layout; // reserved 6822437cbfaSAnders Carlsson // }; 683845511feSChris Lattner BlockDescriptorType = 684a5f58b05SChris Lattner llvm::StructType::createNamed("struct.__block_descriptor", 685a5f58b05SChris Lattner UnsignedLongTy, UnsignedLongTy, NULL); 6862437cbfaSAnders Carlsson 687351762cdSJohn McCall // Now form a pointer to that. 688351762cdSJohn McCall BlockDescriptorType = llvm::PointerType::getUnqual(BlockDescriptorType); 689650c932dSMike Stump return BlockDescriptorType; 6902437cbfaSAnders Carlsson } 6912437cbfaSAnders Carlsson 692a5f58b05SChris Lattner llvm::Type *CodeGenModule::getGenericBlockLiteralType() { 693005c9a62SMike Stump if (GenericBlockLiteralType) 694005c9a62SMike Stump return GenericBlockLiteralType; 6952437cbfaSAnders Carlsson 696a5f58b05SChris Lattner llvm::Type *BlockDescPtrTy = getBlockDescriptorType(); 6972437cbfaSAnders Carlsson 6982437cbfaSAnders Carlsson // struct __block_literal_generic { 6995d2534adSMike Stump // void *__isa; 7005d2534adSMike Stump // int __flags; 7015d2534adSMike Stump // int __reserved; 7025d2534adSMike Stump // void (*__invoke)(void *); 7035d2534adSMike Stump // struct __block_descriptor *__descriptor; 7042437cbfaSAnders Carlsson // }; 705a5f58b05SChris Lattner GenericBlockLiteralType = 706a5f58b05SChris Lattner llvm::StructType::createNamed("struct.__block_literal_generic", 707a5f58b05SChris Lattner VoidPtrTy, 70892bbd6d4SMike Stump IntTy, 70992bbd6d4SMike Stump IntTy, 710e3dc1707SJohn McCall VoidPtrTy, 7112437cbfaSAnders Carlsson BlockDescPtrTy, 7122437cbfaSAnders Carlsson NULL); 7132437cbfaSAnders Carlsson 714005c9a62SMike Stump return GenericBlockLiteralType; 7152437cbfaSAnders Carlsson } 7162437cbfaSAnders Carlsson 7175d2534adSMike Stump 718bfb3671bSAnders Carlsson RValue CodeGenFunction::EmitBlockCallExpr(const CallExpr* E, 719bfb3671bSAnders Carlsson ReturnValueSlot ReturnValue) { 7202437cbfaSAnders Carlsson const BlockPointerType *BPT = 721c23c7e6aSTed Kremenek E->getCallee()->getType()->getAs<BlockPointerType>(); 7222437cbfaSAnders Carlsson 7232437cbfaSAnders Carlsson llvm::Value *Callee = EmitScalarExpr(E->getCallee()); 7242437cbfaSAnders Carlsson 7252437cbfaSAnders Carlsson // Get a pointer to the generic block literal. 7262437cbfaSAnders Carlsson const llvm::Type *BlockLiteralTy = 7279793f0e4SOwen Anderson llvm::PointerType::getUnqual(CGM.getGenericBlockLiteralType()); 7282437cbfaSAnders Carlsson 7292437cbfaSAnders Carlsson // Bitcast the callee to a block literal. 7302437cbfaSAnders Carlsson llvm::Value *BlockLiteral = 7312437cbfaSAnders Carlsson Builder.CreateBitCast(Callee, BlockLiteralTy, "block.literal"); 7322437cbfaSAnders Carlsson 7332437cbfaSAnders Carlsson // Get the function pointer from the literal. 7342437cbfaSAnders Carlsson llvm::Value *FuncPtr = Builder.CreateStructGEP(BlockLiteral, 3, "tmp"); 7352437cbfaSAnders Carlsson 736e3dc1707SJohn McCall BlockLiteral = Builder.CreateBitCast(BlockLiteral, VoidPtrTy, "tmp"); 7372437cbfaSAnders Carlsson 7382437cbfaSAnders Carlsson // Add the block literal. 7392437cbfaSAnders Carlsson CallArgList Args; 7409dc0db21SJohn McCall Args.add(RValue::get(BlockLiteral), getContext().VoidPtrTy); 7412437cbfaSAnders Carlsson 742479e6fc7SAnders Carlsson QualType FnType = BPT->getPointeeType(); 743479e6fc7SAnders Carlsson 7442437cbfaSAnders Carlsson // And the rest of the arguments. 7459dd450bbSJohn McCall EmitCallArgs(Args, FnType->getAs<FunctionProtoType>(), 746479e6fc7SAnders Carlsson E->arg_begin(), E->arg_end()); 7472437cbfaSAnders Carlsson 7485f50c651SAnders Carlsson // Load the function. 749c76493a6SDaniel Dunbar llvm::Value *Func = Builder.CreateLoad(FuncPtr, "tmp"); 7505f50c651SAnders Carlsson 75185915250SJohn McCall const FunctionType *FuncTy = FnType->castAs<FunctionType>(); 752ab26cfa5SJohn McCall QualType ResultType = FuncTy->getResultType(); 753a60cbcdfSAnders Carlsson 754a60cbcdfSAnders Carlsson const CGFunctionInfo &FnInfo = 755c50c27ccSRafael Espindola CGM.getTypes().getFunctionInfo(ResultType, Args, 756c50c27ccSRafael Espindola FuncTy->getExtInfo()); 7575f50c651SAnders Carlsson 7585f50c651SAnders Carlsson // Cast the function pointer to the right type. 7595f50c651SAnders Carlsson const llvm::Type *BlockFTy = 760a60cbcdfSAnders Carlsson CGM.getTypes().GetFunctionType(FnInfo, false); 7615f50c651SAnders Carlsson 7629793f0e4SOwen Anderson const llvm::Type *BlockFTyPtr = llvm::PointerType::getUnqual(BlockFTy); 7635f50c651SAnders Carlsson Func = Builder.CreateBitCast(Func, BlockFTyPtr); 7645f50c651SAnders Carlsson 7652437cbfaSAnders Carlsson // And call the block. 766bfb3671bSAnders Carlsson return EmitCall(FnInfo, Func, ReturnValue, Args); 7672437cbfaSAnders Carlsson } 7686a60fa24SAnders Carlsson 769351762cdSJohn McCall llvm::Value *CodeGenFunction::GetAddrOfBlockDecl(const VarDecl *variable, 770351762cdSJohn McCall bool isByRef) { 771351762cdSJohn McCall assert(BlockInfo && "evaluating block ref without block information?"); 772351762cdSJohn McCall const CGBlockInfo::Capture &capture = BlockInfo->getCapture(variable); 77387fe5d56SJohn McCall 774351762cdSJohn McCall // Handle constant captures. 775351762cdSJohn McCall if (capture.isConstant()) return LocalDeclMap[variable]; 77687fe5d56SJohn McCall 777351762cdSJohn McCall llvm::Value *addr = 778351762cdSJohn McCall Builder.CreateStructGEP(LoadBlockStruct(), capture.getIndex(), 779351762cdSJohn McCall "block.capture.addr"); 780351762cdSJohn McCall 781351762cdSJohn McCall if (isByRef) { 782351762cdSJohn McCall // addr should be a void** right now. Load, then cast the result 783351762cdSJohn McCall // to byref*. 784351762cdSJohn McCall 785351762cdSJohn McCall addr = Builder.CreateLoad(addr); 786351762cdSJohn McCall const llvm::PointerType *byrefPointerType 787351762cdSJohn McCall = llvm::PointerType::get(BuildByRefType(variable), 0); 788351762cdSJohn McCall addr = Builder.CreateBitCast(addr, byrefPointerType, 789351762cdSJohn McCall "byref.addr"); 790351762cdSJohn McCall 791351762cdSJohn McCall // Follow the forwarding pointer. 792351762cdSJohn McCall addr = Builder.CreateStructGEP(addr, 1, "byref.forwarding"); 793351762cdSJohn McCall addr = Builder.CreateLoad(addr, "byref.addr.forwarded"); 794351762cdSJohn McCall 795351762cdSJohn McCall // Cast back to byref* and GEP over to the actual object. 796351762cdSJohn McCall addr = Builder.CreateBitCast(addr, byrefPointerType); 797351762cdSJohn McCall addr = Builder.CreateStructGEP(addr, getByRefValueLLVMField(variable), 798351762cdSJohn McCall variable->getNameAsString()); 79987fe5d56SJohn McCall } 80087fe5d56SJohn McCall 801351762cdSJohn McCall if (variable->getType()->isReferenceType()) 802351762cdSJohn McCall addr = Builder.CreateLoad(addr, "ref.tmp"); 8030168f4b2SAnders Carlsson 804351762cdSJohn McCall return addr; 80597d01d50SMike Stump } 80697d01d50SMike Stump 8072d5a2878SMike Stump llvm::Constant * 808ad7c5c16SJohn McCall CodeGenModule::GetAddrOfGlobalBlock(const BlockExpr *blockExpr, 809351762cdSJohn McCall const char *name) { 810351762cdSJohn McCall CGBlockInfo blockInfo(blockExpr, name); 8116a60fa24SAnders Carlsson 812351762cdSJohn McCall // Compute information about the layout, etc., of this block. 813ad7c5c16SJohn McCall computeBlockInfo(*this, blockInfo); 8146a60fa24SAnders Carlsson 815351762cdSJohn McCall // Using that metadata, generate the actual block function. 816351762cdSJohn McCall llvm::Constant *blockFn; 817351762cdSJohn McCall { 8185469f29aSMike Stump llvm::DenseMap<const Decl*, llvm::Value*> LocalDeclMap; 819ad7c5c16SJohn McCall blockFn = CodeGenFunction(*this).GenerateBlockFunction(GlobalDecl(), 820351762cdSJohn McCall blockInfo, 821351762cdSJohn McCall 0, LocalDeclMap); 822351762cdSJohn McCall } 823e3dc1707SJohn McCall blockFn = llvm::ConstantExpr::getBitCast(blockFn, VoidPtrTy); 8246a60fa24SAnders Carlsson 825ad7c5c16SJohn McCall return buildGlobalBlock(*this, blockInfo, blockFn); 8266a60fa24SAnders Carlsson } 8276a60fa24SAnders Carlsson 828351762cdSJohn McCall static llvm::Constant *buildGlobalBlock(CodeGenModule &CGM, 829351762cdSJohn McCall const CGBlockInfo &blockInfo, 830351762cdSJohn McCall llvm::Constant *blockFn) { 831351762cdSJohn McCall assert(blockInfo.CanBeGlobal); 832351762cdSJohn McCall 833351762cdSJohn McCall // Generate the constants for the block literal initializer. 834351762cdSJohn McCall llvm::Constant *fields[BlockHeaderSize]; 835351762cdSJohn McCall 836351762cdSJohn McCall // isa 837351762cdSJohn McCall fields[0] = CGM.getNSConcreteGlobalBlock(); 838351762cdSJohn McCall 839351762cdSJohn McCall // __flags 84085915250SJohn McCall BlockFlags flags = BLOCK_IS_GLOBAL | BLOCK_HAS_SIGNATURE; 84185915250SJohn McCall if (blockInfo.UsesStret) flags |= BLOCK_USE_STRET; 84285915250SJohn McCall 843e3dc1707SJohn McCall fields[1] = llvm::ConstantInt::get(CGM.IntTy, flags.getBitMask()); 844351762cdSJohn McCall 845351762cdSJohn McCall // Reserved 846e3dc1707SJohn McCall fields[2] = llvm::Constant::getNullValue(CGM.IntTy); 847351762cdSJohn McCall 848351762cdSJohn McCall // Function 849351762cdSJohn McCall fields[3] = blockFn; 850351762cdSJohn McCall 851351762cdSJohn McCall // Descriptor 852351762cdSJohn McCall fields[4] = buildBlockDescriptor(CGM, blockInfo); 853351762cdSJohn McCall 854e64d7ba1SChris Lattner llvm::Constant *init = llvm::ConstantStruct::getAnon(fields); 855351762cdSJohn McCall 856351762cdSJohn McCall llvm::GlobalVariable *literal = 857351762cdSJohn McCall new llvm::GlobalVariable(CGM.getModule(), 858351762cdSJohn McCall init->getType(), 859351762cdSJohn McCall /*constant*/ true, 860351762cdSJohn McCall llvm::GlobalVariable::InternalLinkage, 861351762cdSJohn McCall init, 862351762cdSJohn McCall "__block_literal_global"); 863351762cdSJohn McCall literal->setAlignment(blockInfo.BlockAlign.getQuantity()); 864351762cdSJohn McCall 865351762cdSJohn McCall // Return a constant of the appropriately-casted type. 866351762cdSJohn McCall const llvm::Type *requiredType = 867351762cdSJohn McCall CGM.getTypes().ConvertType(blockInfo.getBlockExpr()->getType()); 868351762cdSJohn McCall return llvm::ConstantExpr::getBitCast(literal, requiredType); 869cb2fbcb0SMike Stump } 870cb2fbcb0SMike Stump 8714446dcf0SMike Stump llvm::Function * 872351762cdSJohn McCall CodeGenFunction::GenerateBlockFunction(GlobalDecl GD, 873351762cdSJohn McCall const CGBlockInfo &blockInfo, 874351762cdSJohn McCall const Decl *outerFnDecl, 875351762cdSJohn McCall const DeclMapTy &ldm) { 876351762cdSJohn McCall const BlockDecl *blockDecl = blockInfo.getBlockDecl(); 8779074ed8cSDevang Patel 8786e40c615SDevang Patel // Check if we should generate debug info for this block function. 8796e40c615SDevang Patel if (CGM.getModuleDebugInfo()) 8806e40c615SDevang Patel DebugInfo = CGM.getModuleDebugInfo(); 8816e40c615SDevang Patel 882351762cdSJohn McCall BlockInfo = &blockInfo; 8839074ed8cSDevang Patel 8845469f29aSMike Stump // Arrange for local static and local extern declarations to appear 885351762cdSJohn McCall // to be local to this function as well, in case they're directly 886351762cdSJohn McCall // referenced in a block. 887351762cdSJohn McCall for (DeclMapTy::const_iterator i = ldm.begin(), e = ldm.end(); i != e; ++i) { 888351762cdSJohn McCall const VarDecl *var = dyn_cast<VarDecl>(i->first); 889351762cdSJohn McCall if (var && !var->hasLocalStorage()) 890351762cdSJohn McCall LocalDeclMap[var] = i->second; 8915469f29aSMike Stump } 8925469f29aSMike Stump 893351762cdSJohn McCall // Begin building the function declaration. 89409a9b6e3SEli Friedman 895351762cdSJohn McCall // Build the argument list. 896351762cdSJohn McCall FunctionArgList args; 8976a60fa24SAnders Carlsson 898351762cdSJohn McCall // The first argument is the block pointer. Just take it as a void* 899351762cdSJohn McCall // and cast it later. 900351762cdSJohn McCall QualType selfTy = getContext().VoidPtrTy; 9017fe9cc1dSMike Stump IdentifierInfo *II = &CGM.getContext().Idents.get(".block_descriptor"); 902d015328fSMike Stump 903147d021bSJohn McCall ImplicitParamDecl selfDecl(const_cast<BlockDecl*>(blockDecl), 904351762cdSJohn McCall SourceLocation(), II, selfTy); 905a738c25fSJohn McCall args.push_back(&selfDecl); 9067fe9cc1dSMike Stump 907351762cdSJohn McCall // Now add the rest of the parameters. 908351762cdSJohn McCall for (BlockDecl::param_const_iterator i = blockDecl->param_begin(), 909351762cdSJohn McCall e = blockDecl->param_end(); i != e; ++i) 910a738c25fSJohn McCall args.push_back(*i); 911afa3c0a8SFariborz Jahanian 912351762cdSJohn McCall // Create the function declaration. 913351762cdSJohn McCall const FunctionProtoType *fnType = 914351762cdSJohn McCall cast<FunctionProtoType>(blockInfo.getBlockExpr()->getFunctionType()); 915351762cdSJohn McCall const CGFunctionInfo &fnInfo = 916351762cdSJohn McCall CGM.getTypes().getFunctionInfo(fnType->getResultType(), args, 917351762cdSJohn McCall fnType->getExtInfo()); 91885915250SJohn McCall if (CGM.ReturnTypeUsesSRet(fnInfo)) 91985915250SJohn McCall blockInfo.UsesStret = true; 92085915250SJohn McCall 921351762cdSJohn McCall const llvm::FunctionType *fnLLVMType = 922351762cdSJohn McCall CGM.getTypes().GetFunctionType(fnInfo, fnType->isVariadic()); 92387fe5d56SJohn McCall 924351762cdSJohn McCall MangleBuffer name; 925351762cdSJohn McCall CGM.getBlockMangledName(GD, name, blockDecl); 926351762cdSJohn McCall llvm::Function *fn = 927351762cdSJohn McCall llvm::Function::Create(fnLLVMType, llvm::GlobalValue::InternalLinkage, 928351762cdSJohn McCall name.getString(), &CGM.getModule()); 929351762cdSJohn McCall CGM.SetInternalFunctionAttributes(blockDecl, fn, fnInfo); 9306a60fa24SAnders Carlsson 931351762cdSJohn McCall // Begin generating the function. 932a738c25fSJohn McCall StartFunction(blockDecl, fnType->getResultType(), fn, fnInfo, args, 9335f070a51SDevang Patel blockInfo.getBlockExpr()->getBody()->getLocStart()); 934351762cdSJohn McCall CurFuncDecl = outerFnDecl; // StartFunction sets this to blockDecl 9356a60fa24SAnders Carlsson 936147d021bSJohn McCall // Okay. Undo some of what StartFunction did. 937147d021bSJohn McCall 938147d021bSJohn McCall // Pull the 'self' reference out of the local decl map. 939147d021bSJohn McCall llvm::Value *blockAddr = LocalDeclMap[&selfDecl]; 940147d021bSJohn McCall LocalDeclMap.erase(&selfDecl); 941351762cdSJohn McCall BlockPointer = Builder.CreateBitCast(blockAddr, 942351762cdSJohn McCall blockInfo.StructureType->getPointerTo(), 943351762cdSJohn McCall "block"); 944017460abSMike Stump 94587fe5d56SJohn McCall // If we have a C++ 'this' reference, go ahead and force it into 94687fe5d56SJohn McCall // existence now. 947351762cdSJohn McCall if (blockDecl->capturesCXXThis()) { 948351762cdSJohn McCall llvm::Value *addr = Builder.CreateStructGEP(BlockPointer, 949351762cdSJohn McCall blockInfo.CXXThisIndex, 950351762cdSJohn McCall "block.captured-this"); 951351762cdSJohn McCall CXXThisValue = Builder.CreateLoad(addr, "this"); 95287fe5d56SJohn McCall } 95387fe5d56SJohn McCall 954351762cdSJohn McCall // LoadObjCSelf() expects there to be an entry for 'self' in LocalDeclMap; 955351762cdSJohn McCall // appease it. 956351762cdSJohn McCall if (const ObjCMethodDecl *method 957351762cdSJohn McCall = dyn_cast_or_null<ObjCMethodDecl>(CurFuncDecl)) { 958351762cdSJohn McCall const VarDecl *self = method->getSelfDecl(); 959351762cdSJohn McCall 960351762cdSJohn McCall // There might not be a capture for 'self', but if there is... 961351762cdSJohn McCall if (blockInfo.Captures.count(self)) { 962351762cdSJohn McCall const CGBlockInfo::Capture &capture = blockInfo.getCapture(self); 963351762cdSJohn McCall llvm::Value *selfAddr = Builder.CreateStructGEP(BlockPointer, 964351762cdSJohn McCall capture.getIndex(), 965351762cdSJohn McCall "block.captured-self"); 966351762cdSJohn McCall LocalDeclMap[self] = selfAddr; 967351762cdSJohn McCall } 968351762cdSJohn McCall } 969351762cdSJohn McCall 970351762cdSJohn McCall // Also force all the constant captures. 971351762cdSJohn McCall for (BlockDecl::capture_const_iterator ci = blockDecl->capture_begin(), 972351762cdSJohn McCall ce = blockDecl->capture_end(); ci != ce; ++ci) { 973351762cdSJohn McCall const VarDecl *variable = ci->getVariable(); 974351762cdSJohn McCall const CGBlockInfo::Capture &capture = blockInfo.getCapture(variable); 975351762cdSJohn McCall if (!capture.isConstant()) continue; 976351762cdSJohn McCall 977351762cdSJohn McCall unsigned align = getContext().getDeclAlign(variable).getQuantity(); 978351762cdSJohn McCall 979351762cdSJohn McCall llvm::AllocaInst *alloca = 980351762cdSJohn McCall CreateMemTemp(variable->getType(), "block.captured-const"); 981351762cdSJohn McCall alloca->setAlignment(align); 982351762cdSJohn McCall 983351762cdSJohn McCall Builder.CreateStore(capture.getConstant(), alloca, align); 984351762cdSJohn McCall 985351762cdSJohn McCall LocalDeclMap[variable] = alloca; 9869d42f0f1SJohn McCall } 9879d42f0f1SJohn McCall 988017460abSMike Stump // Save a spot to insert the debug information for all the BlockDeclRefDecls. 989017460abSMike Stump llvm::BasicBlock *entry = Builder.GetInsertBlock(); 990017460abSMike Stump llvm::BasicBlock::iterator entry_ptr = Builder.GetInsertPoint(); 991017460abSMike Stump --entry_ptr; 992017460abSMike Stump 993351762cdSJohn McCall EmitStmt(blockDecl->getBody()); 994017460abSMike Stump 9957d69911aSMike Stump // Remember where we were... 9967d69911aSMike Stump llvm::BasicBlock *resume = Builder.GetInsertBlock(); 997017460abSMike Stump 9987d69911aSMike Stump // Go back to the entry. 999017460abSMike Stump ++entry_ptr; 1000017460abSMike Stump Builder.SetInsertPoint(entry, entry_ptr); 1001017460abSMike Stump 10022e722b91SMike Stump // Emit debug information for all the BlockDeclRefDecls. 100387fe5d56SJohn McCall // FIXME: also for 'this' 1004351762cdSJohn McCall if (CGDebugInfo *DI = getDebugInfo()) { 1005351762cdSJohn McCall for (BlockDecl::capture_const_iterator ci = blockDecl->capture_begin(), 1006351762cdSJohn McCall ce = blockDecl->capture_end(); ci != ce; ++ci) { 1007351762cdSJohn McCall const VarDecl *variable = ci->getVariable(); 1008351762cdSJohn McCall DI->setLocation(variable->getLocation()); 1009351762cdSJohn McCall 1010351762cdSJohn McCall const CGBlockInfo::Capture &capture = blockInfo.getCapture(variable); 1011351762cdSJohn McCall if (capture.isConstant()) { 1012351762cdSJohn McCall DI->EmitDeclareOfAutoVariable(variable, LocalDeclMap[variable], 1013351762cdSJohn McCall Builder); 1014351762cdSJohn McCall continue; 1015351762cdSJohn McCall } 1016351762cdSJohn McCall 1017147d021bSJohn McCall DI->EmitDeclareOfBlockDeclRefVariable(variable, BlockPointer, 1018351762cdSJohn McCall Builder, blockInfo); 10192e722b91SMike Stump } 10202e722b91SMike Stump } 1021351762cdSJohn McCall 10227d69911aSMike Stump // And resume where we left off. 10237d69911aSMike Stump if (resume == 0) 10247d69911aSMike Stump Builder.ClearInsertionPoint(); 10257d69911aSMike Stump else 10267d69911aSMike Stump Builder.SetInsertPoint(resume); 10272e722b91SMike Stump 1028351762cdSJohn McCall FinishFunction(cast<CompoundStmt>(blockDecl->getBody())->getRBracLoc()); 10296a60fa24SAnders Carlsson 1030351762cdSJohn McCall return fn; 10316a60fa24SAnders Carlsson } 10321db7d04bSMike Stump 1033351762cdSJohn McCall /* 1034351762cdSJohn McCall notes.push_back(HelperInfo()); 1035351762cdSJohn McCall HelperInfo ¬e = notes.back(); 1036351762cdSJohn McCall note.index = capture.getIndex(); 1037351762cdSJohn McCall note.RequiresCopying = (ci->hasCopyExpr() || BlockRequiresCopying(type)); 1038351762cdSJohn McCall note.cxxbar_import = ci->getCopyExpr(); 10391db7d04bSMike Stump 1040351762cdSJohn McCall if (ci->isByRef()) { 1041351762cdSJohn McCall note.flag = BLOCK_FIELD_IS_BYREF; 1042351762cdSJohn McCall if (type.isObjCGCWeak()) 1043351762cdSJohn McCall note.flag |= BLOCK_FIELD_IS_WEAK; 1044351762cdSJohn McCall } else if (type->isBlockPointerType()) { 1045351762cdSJohn McCall note.flag = BLOCK_FIELD_IS_BLOCK; 1046351762cdSJohn McCall } else { 1047351762cdSJohn McCall note.flag = BLOCK_FIELD_IS_OBJECT; 10481db7d04bSMike Stump } 1049351762cdSJohn McCall */ 10501db7d04bSMike Stump 105197d01d50SMike Stump 10520c743277SMike Stump 1053351762cdSJohn McCall llvm::Constant * 1054ad7c5c16SJohn McCall CodeGenFunction::GenerateCopyHelperFunction(const CGBlockInfo &blockInfo) { 1055351762cdSJohn McCall ASTContext &C = getContext(); 1056351762cdSJohn McCall 1057351762cdSJohn McCall FunctionArgList args; 1058a738c25fSJohn McCall ImplicitParamDecl dstDecl(0, SourceLocation(), 0, C.VoidPtrTy); 1059a738c25fSJohn McCall args.push_back(&dstDecl); 1060a738c25fSJohn McCall ImplicitParamDecl srcDecl(0, SourceLocation(), 0, C.VoidPtrTy); 1061a738c25fSJohn McCall args.push_back(&srcDecl); 10620c743277SMike Stump 10630c743277SMike Stump const CGFunctionInfo &FI = 1064351762cdSJohn McCall CGM.getTypes().getFunctionInfo(C.VoidTy, args, FunctionType::ExtInfo()); 10650c743277SMike Stump 1066351762cdSJohn McCall // FIXME: it would be nice if these were mergeable with things with 1067351762cdSJohn McCall // identical semantics. 1068351762cdSJohn McCall const llvm::FunctionType *LTy = CGM.getTypes().GetFunctionType(FI, false); 10690c743277SMike Stump 10700c743277SMike Stump llvm::Function *Fn = 10710c743277SMike Stump llvm::Function::Create(LTy, llvm::GlobalValue::InternalLinkage, 1072d6b28fc6SBenjamin Kramer "__copy_helper_block_", &CGM.getModule()); 10730c743277SMike Stump 10740c743277SMike Stump IdentifierInfo *II 10750c743277SMike Stump = &CGM.getContext().Idents.get("__copy_helper_block_"); 10760c743277SMike Stump 10772a7c2194SDevang Patel // Check if we should generate debug info for this block helper function. 10782a7c2194SDevang Patel if (CGM.getModuleDebugInfo()) 10792a7c2194SDevang Patel DebugInfo = CGM.getModuleDebugInfo(); 10802a7c2194SDevang Patel 1081351762cdSJohn McCall FunctionDecl *FD = FunctionDecl::Create(C, 1082351762cdSJohn McCall C.getTranslationUnitDecl(), 1083dff1930bSAbramo Bagnara SourceLocation(), 1084351762cdSJohn McCall SourceLocation(), II, C.VoidTy, 0, 10858e7d656aSJohn McCall SC_Static, 10868e7d656aSJohn McCall SC_None, 1087c4df4076SDouglas Gregor false, 10880c743277SMike Stump true); 1089a738c25fSJohn McCall StartFunction(FD, C.VoidTy, Fn, FI, args, SourceLocation()); 1090aeb0ffd5SMike Stump 1091351762cdSJohn McCall const llvm::Type *structPtrTy = blockInfo.StructureType->getPointerTo(); 109267645930SMike Stump 1093a738c25fSJohn McCall llvm::Value *src = GetAddrOfLocalVar(&srcDecl); 1094ad7c5c16SJohn McCall src = Builder.CreateLoad(src); 1095ad7c5c16SJohn McCall src = Builder.CreateBitCast(src, structPtrTy, "block.source"); 109667645930SMike Stump 1097a738c25fSJohn McCall llvm::Value *dst = GetAddrOfLocalVar(&dstDecl); 1098ad7c5c16SJohn McCall dst = Builder.CreateLoad(dst); 1099ad7c5c16SJohn McCall dst = Builder.CreateBitCast(dst, structPtrTy, "block.dest"); 1100aeb0ffd5SMike Stump 1101351762cdSJohn McCall const BlockDecl *blockDecl = blockInfo.getBlockDecl(); 1102aeb0ffd5SMike Stump 1103351762cdSJohn McCall for (BlockDecl::capture_const_iterator ci = blockDecl->capture_begin(), 1104351762cdSJohn McCall ce = blockDecl->capture_end(); ci != ce; ++ci) { 1105351762cdSJohn McCall const VarDecl *variable = ci->getVariable(); 1106351762cdSJohn McCall QualType type = variable->getType(); 1107aeb0ffd5SMike Stump 1108351762cdSJohn McCall const CGBlockInfo::Capture &capture = blockInfo.getCapture(variable); 1109351762cdSJohn McCall if (capture.isConstant()) continue; 1110351762cdSJohn McCall 1111351762cdSJohn McCall const Expr *copyExpr = ci->getCopyExpr(); 111231168b07SJohn McCall BlockFieldFlags flags; 111331168b07SJohn McCall 111431168b07SJohn McCall bool isARCWeakCapture = false; 1115351762cdSJohn McCall 1116351762cdSJohn McCall if (copyExpr) { 1117351762cdSJohn McCall assert(!ci->isByRef()); 1118351762cdSJohn McCall // don't bother computing flags 111931168b07SJohn McCall 1120351762cdSJohn McCall } else if (ci->isByRef()) { 1121351762cdSJohn McCall flags = BLOCK_FIELD_IS_BYREF; 112231168b07SJohn McCall if (type.isObjCGCWeak()) 112331168b07SJohn McCall flags |= BLOCK_FIELD_IS_WEAK; 1124351762cdSJohn McCall 112531168b07SJohn McCall } else if (type->isObjCRetainableType()) { 112631168b07SJohn McCall flags = BLOCK_FIELD_IS_OBJECT; 112731168b07SJohn McCall if (type->isBlockPointerType()) 112831168b07SJohn McCall flags = BLOCK_FIELD_IS_BLOCK; 112931168b07SJohn McCall 113031168b07SJohn McCall // Special rules for ARC captures: 113131168b07SJohn McCall if (getLangOptions().ObjCAutoRefCount) { 113231168b07SJohn McCall Qualifiers qs = type.getQualifiers(); 113331168b07SJohn McCall 113431168b07SJohn McCall // Don't generate special copy logic for a captured object 113531168b07SJohn McCall // unless it's __strong or __weak. 113631168b07SJohn McCall if (!qs.hasStrongOrWeakObjCLifetime()) 113731168b07SJohn McCall continue; 113831168b07SJohn McCall 113931168b07SJohn McCall // Support __weak direct captures. 114031168b07SJohn McCall if (qs.getObjCLifetime() == Qualifiers::OCL_Weak) 114131168b07SJohn McCall isARCWeakCapture = true; 114231168b07SJohn McCall } 114331168b07SJohn McCall } else { 114431168b07SJohn McCall continue; 114531168b07SJohn McCall } 1146351762cdSJohn McCall 1147351762cdSJohn McCall unsigned index = capture.getIndex(); 1148ad7c5c16SJohn McCall llvm::Value *srcField = Builder.CreateStructGEP(src, index); 1149ad7c5c16SJohn McCall llvm::Value *dstField = Builder.CreateStructGEP(dst, index); 1150351762cdSJohn McCall 1151351762cdSJohn McCall // If there's an explicit copy expression, we do that. 1152351762cdSJohn McCall if (copyExpr) { 1153ad7c5c16SJohn McCall EmitSynthesizedCXXCopyCtor(dstField, srcField, copyExpr); 115431168b07SJohn McCall } else if (isARCWeakCapture) { 115531168b07SJohn McCall EmitARCCopyWeak(dstField, srcField); 1156351762cdSJohn McCall } else { 1157351762cdSJohn McCall llvm::Value *srcValue = Builder.CreateLoad(srcField, "blockcopy.src"); 1158e3dc1707SJohn McCall srcValue = Builder.CreateBitCast(srcValue, VoidPtrTy); 1159e3dc1707SJohn McCall llvm::Value *dstAddr = Builder.CreateBitCast(dstField, VoidPtrTy); 1160351762cdSJohn McCall Builder.CreateCall3(CGM.getBlockObjectAssign(), dstAddr, srcValue, 116131168b07SJohn McCall llvm::ConstantInt::get(Int32Ty, flags.getBitMask())); 116267645930SMike Stump } 1163e988bdacSFariborz Jahanian } 1164aeb0ffd5SMike Stump 1165ad7c5c16SJohn McCall FinishFunction(); 11660c743277SMike Stump 1167e3dc1707SJohn McCall return llvm::ConstantExpr::getBitCast(Fn, VoidPtrTy); 116897d01d50SMike Stump } 116997d01d50SMike Stump 1170351762cdSJohn McCall llvm::Constant * 1171ad7c5c16SJohn McCall CodeGenFunction::GenerateDestroyHelperFunction(const CGBlockInfo &blockInfo) { 1172351762cdSJohn McCall ASTContext &C = getContext(); 11730c743277SMike Stump 1174351762cdSJohn McCall FunctionArgList args; 1175a738c25fSJohn McCall ImplicitParamDecl srcDecl(0, SourceLocation(), 0, C.VoidPtrTy); 1176a738c25fSJohn McCall args.push_back(&srcDecl); 11770c743277SMike Stump 11780c743277SMike Stump const CGFunctionInfo &FI = 1179351762cdSJohn McCall CGM.getTypes().getFunctionInfo(C.VoidTy, args, FunctionType::ExtInfo()); 11800c743277SMike Stump 1181cbc2bcafSMike Stump // FIXME: We'd like to put these into a mergable by content, with 1182cbc2bcafSMike Stump // internal linkage. 1183351762cdSJohn McCall const llvm::FunctionType *LTy = CGM.getTypes().GetFunctionType(FI, false); 11840c743277SMike Stump 11850c743277SMike Stump llvm::Function *Fn = 11860c743277SMike Stump llvm::Function::Create(LTy, llvm::GlobalValue::InternalLinkage, 1187d6b28fc6SBenjamin Kramer "__destroy_helper_block_", &CGM.getModule()); 11880c743277SMike Stump 11892a7c2194SDevang Patel // Check if we should generate debug info for this block destroy function. 11902a7c2194SDevang Patel if (CGM.getModuleDebugInfo()) 11912a7c2194SDevang Patel DebugInfo = CGM.getModuleDebugInfo(); 11922a7c2194SDevang Patel 11930c743277SMike Stump IdentifierInfo *II 11940c743277SMike Stump = &CGM.getContext().Idents.get("__destroy_helper_block_"); 11950c743277SMike Stump 1196351762cdSJohn McCall FunctionDecl *FD = FunctionDecl::Create(C, C.getTranslationUnitDecl(), 1197dff1930bSAbramo Bagnara SourceLocation(), 1198351762cdSJohn McCall SourceLocation(), II, C.VoidTy, 0, 11998e7d656aSJohn McCall SC_Static, 12008e7d656aSJohn McCall SC_None, 1201c4df4076SDouglas Gregor false, true); 1202a738c25fSJohn McCall StartFunction(FD, C.VoidTy, Fn, FI, args, SourceLocation()); 12036f7d9f87SMike Stump 1204351762cdSJohn McCall const llvm::Type *structPtrTy = blockInfo.StructureType->getPointerTo(); 120567645930SMike Stump 1206a738c25fSJohn McCall llvm::Value *src = GetAddrOfLocalVar(&srcDecl); 1207ad7c5c16SJohn McCall src = Builder.CreateLoad(src); 1208ad7c5c16SJohn McCall src = Builder.CreateBitCast(src, structPtrTy, "block"); 12096f7d9f87SMike Stump 1210351762cdSJohn McCall const BlockDecl *blockDecl = blockInfo.getBlockDecl(); 1211351762cdSJohn McCall 1212ad7c5c16SJohn McCall CodeGenFunction::RunCleanupsScope cleanups(*this); 1213351762cdSJohn McCall 1214351762cdSJohn McCall for (BlockDecl::capture_const_iterator ci = blockDecl->capture_begin(), 1215351762cdSJohn McCall ce = blockDecl->capture_end(); ci != ce; ++ci) { 1216351762cdSJohn McCall const VarDecl *variable = ci->getVariable(); 1217351762cdSJohn McCall QualType type = variable->getType(); 1218351762cdSJohn McCall 1219351762cdSJohn McCall const CGBlockInfo::Capture &capture = blockInfo.getCapture(variable); 1220351762cdSJohn McCall if (capture.isConstant()) continue; 1221351762cdSJohn McCall 1222ad7c5c16SJohn McCall BlockFieldFlags flags; 1223351762cdSJohn McCall const CXXDestructorDecl *dtor = 0; 1224351762cdSJohn McCall 122531168b07SJohn McCall bool isARCWeakCapture = false; 122631168b07SJohn McCall 1227351762cdSJohn McCall if (ci->isByRef()) { 1228351762cdSJohn McCall flags = BLOCK_FIELD_IS_BYREF; 122931168b07SJohn McCall if (type.isObjCGCWeak()) 123031168b07SJohn McCall flags |= BLOCK_FIELD_IS_WEAK; 123131168b07SJohn McCall } else if (const CXXRecordDecl *record = type->getAsCXXRecordDecl()) { 123231168b07SJohn McCall if (record->hasTrivialDestructor()) 123331168b07SJohn McCall continue; 1234351762cdSJohn McCall dtor = record->getDestructor(); 123531168b07SJohn McCall } else if (type->isObjCRetainableType()) { 123631168b07SJohn McCall flags = BLOCK_FIELD_IS_OBJECT; 123731168b07SJohn McCall if (type->isBlockPointerType()) 123831168b07SJohn McCall flags = BLOCK_FIELD_IS_BLOCK; 1239351762cdSJohn McCall 124031168b07SJohn McCall // Special rules for ARC captures. 124131168b07SJohn McCall if (getLangOptions().ObjCAutoRefCount) { 124231168b07SJohn McCall Qualifiers qs = type.getQualifiers(); 124331168b07SJohn McCall 124431168b07SJohn McCall // Don't generate special dispose logic for a captured object 124531168b07SJohn McCall // unless it's __strong or __weak. 124631168b07SJohn McCall if (!qs.hasStrongOrWeakObjCLifetime()) 124731168b07SJohn McCall continue; 124831168b07SJohn McCall 124931168b07SJohn McCall // Support __weak direct captures. 125031168b07SJohn McCall if (qs.getObjCLifetime() == Qualifiers::OCL_Weak) 125131168b07SJohn McCall isARCWeakCapture = true; 125231168b07SJohn McCall } 125331168b07SJohn McCall } else { 125431168b07SJohn McCall continue; 125531168b07SJohn McCall } 1256351762cdSJohn McCall 1257351762cdSJohn McCall unsigned index = capture.getIndex(); 1258ad7c5c16SJohn McCall llvm::Value *srcField = Builder.CreateStructGEP(src, index); 1259351762cdSJohn McCall 1260351762cdSJohn McCall // If there's an explicit copy expression, we do that. 1261351762cdSJohn McCall if (dtor) { 1262ad7c5c16SJohn McCall PushDestructorCleanup(dtor, srcField); 1263351762cdSJohn McCall 126431168b07SJohn McCall // If this is a __weak capture, emit the release directly. 126531168b07SJohn McCall } else if (isARCWeakCapture) { 126631168b07SJohn McCall EmitARCDestroyWeak(srcField); 126731168b07SJohn McCall 1268351762cdSJohn McCall // Otherwise we call _Block_object_dispose. It wouldn't be too 1269351762cdSJohn McCall // hard to just emit this as a cleanup if we wanted to make sure 1270351762cdSJohn McCall // that things were done in reverse. 1271351762cdSJohn McCall } else { 1272351762cdSJohn McCall llvm::Value *value = Builder.CreateLoad(srcField); 1273e3dc1707SJohn McCall value = Builder.CreateBitCast(value, VoidPtrTy); 1274351762cdSJohn McCall BuildBlockRelease(value, flags); 12756f7d9f87SMike Stump } 12766f7d9f87SMike Stump } 1277351762cdSJohn McCall 1278351762cdSJohn McCall cleanups.ForceCleanup(); 12796f7d9f87SMike Stump 1280ad7c5c16SJohn McCall FinishFunction(); 12810c743277SMike Stump 1282e3dc1707SJohn McCall return llvm::ConstantExpr::getBitCast(Fn, VoidPtrTy); 12830c743277SMike Stump } 12840c743277SMike Stump 1285f9b056b0SJohn McCall namespace { 1286f9b056b0SJohn McCall 1287f9b056b0SJohn McCall /// Emits the copy/dispose helper functions for a __block object of id type. 1288f9b056b0SJohn McCall class ObjectByrefHelpers : public CodeGenModule::ByrefHelpers { 1289f9b056b0SJohn McCall BlockFieldFlags Flags; 1290f9b056b0SJohn McCall 1291f9b056b0SJohn McCall public: 1292f9b056b0SJohn McCall ObjectByrefHelpers(CharUnits alignment, BlockFieldFlags flags) 1293f9b056b0SJohn McCall : ByrefHelpers(alignment), Flags(flags) {} 1294f9b056b0SJohn McCall 12957c623641SJohn McCall void emitCopy(CodeGenFunction &CGF, llvm::Value *destField, 12967c623641SJohn McCall llvm::Value *srcField) { 1297f9b056b0SJohn McCall destField = CGF.Builder.CreateBitCast(destField, CGF.VoidPtrTy); 1298f9b056b0SJohn McCall 1299f9b056b0SJohn McCall srcField = CGF.Builder.CreateBitCast(srcField, CGF.VoidPtrPtrTy); 1300f9b056b0SJohn McCall llvm::Value *srcValue = CGF.Builder.CreateLoad(srcField); 1301f9b056b0SJohn McCall 1302f9b056b0SJohn McCall unsigned flags = (Flags | BLOCK_BYREF_CALLER).getBitMask(); 1303f9b056b0SJohn McCall 1304f9b056b0SJohn McCall llvm::Value *flagsVal = llvm::ConstantInt::get(CGF.Int32Ty, flags); 1305f9b056b0SJohn McCall llvm::Value *fn = CGF.CGM.getBlockObjectAssign(); 1306f9b056b0SJohn McCall CGF.Builder.CreateCall3(fn, destField, srcValue, flagsVal); 1307f9b056b0SJohn McCall } 1308f9b056b0SJohn McCall 1309f9b056b0SJohn McCall void emitDispose(CodeGenFunction &CGF, llvm::Value *field) { 1310f9b056b0SJohn McCall field = CGF.Builder.CreateBitCast(field, CGF.Int8PtrTy->getPointerTo(0)); 1311f9b056b0SJohn McCall llvm::Value *value = CGF.Builder.CreateLoad(field); 1312f9b056b0SJohn McCall 1313f9b056b0SJohn McCall CGF.BuildBlockRelease(value, Flags | BLOCK_BYREF_CALLER); 1314f9b056b0SJohn McCall } 1315f9b056b0SJohn McCall 1316f9b056b0SJohn McCall void profileImpl(llvm::FoldingSetNodeID &id) const { 1317f9b056b0SJohn McCall id.AddInteger(Flags.getBitMask()); 1318f9b056b0SJohn McCall } 1319f9b056b0SJohn McCall }; 1320f9b056b0SJohn McCall 132131168b07SJohn McCall /// Emits the copy/dispose helpers for an ARC __block __weak variable. 132231168b07SJohn McCall class ARCWeakByrefHelpers : public CodeGenModule::ByrefHelpers { 132331168b07SJohn McCall public: 132431168b07SJohn McCall ARCWeakByrefHelpers(CharUnits alignment) : ByrefHelpers(alignment) {} 132531168b07SJohn McCall 132631168b07SJohn McCall void emitCopy(CodeGenFunction &CGF, llvm::Value *destField, 132731168b07SJohn McCall llvm::Value *srcField) { 132831168b07SJohn McCall CGF.EmitARCMoveWeak(destField, srcField); 132931168b07SJohn McCall } 133031168b07SJohn McCall 133131168b07SJohn McCall void emitDispose(CodeGenFunction &CGF, llvm::Value *field) { 133231168b07SJohn McCall CGF.EmitARCDestroyWeak(field); 133331168b07SJohn McCall } 133431168b07SJohn McCall 133531168b07SJohn McCall void profileImpl(llvm::FoldingSetNodeID &id) const { 133631168b07SJohn McCall // 0 is distinguishable from all pointers and byref flags 133731168b07SJohn McCall id.AddInteger(0); 133831168b07SJohn McCall } 133931168b07SJohn McCall }; 134031168b07SJohn McCall 134131168b07SJohn McCall /// Emits the copy/dispose helpers for an ARC __block __strong variable 134231168b07SJohn McCall /// that's not of block-pointer type. 134331168b07SJohn McCall class ARCStrongByrefHelpers : public CodeGenModule::ByrefHelpers { 134431168b07SJohn McCall public: 134531168b07SJohn McCall ARCStrongByrefHelpers(CharUnits alignment) : ByrefHelpers(alignment) {} 134631168b07SJohn McCall 134731168b07SJohn McCall void emitCopy(CodeGenFunction &CGF, llvm::Value *destField, 134831168b07SJohn McCall llvm::Value *srcField) { 134931168b07SJohn McCall // Do a "move" by copying the value and then zeroing out the old 135031168b07SJohn McCall // variable. 135131168b07SJohn McCall 135231168b07SJohn McCall llvm::Value *value = CGF.Builder.CreateLoad(srcField); 135331168b07SJohn McCall llvm::Value *null = 135431168b07SJohn McCall llvm::ConstantPointerNull::get(cast<llvm::PointerType>(value->getType())); 135531168b07SJohn McCall CGF.Builder.CreateStore(value, destField); 135631168b07SJohn McCall CGF.Builder.CreateStore(null, srcField); 135731168b07SJohn McCall } 135831168b07SJohn McCall 135931168b07SJohn McCall void emitDispose(CodeGenFunction &CGF, llvm::Value *field) { 136031168b07SJohn McCall llvm::Value *value = CGF.Builder.CreateLoad(field); 136131168b07SJohn McCall CGF.EmitARCRelease(value, /*precise*/ false); 136231168b07SJohn McCall } 136331168b07SJohn McCall 136431168b07SJohn McCall void profileImpl(llvm::FoldingSetNodeID &id) const { 136531168b07SJohn McCall // 1 is distinguishable from all pointers and byref flags 136631168b07SJohn McCall id.AddInteger(1); 136731168b07SJohn McCall } 136831168b07SJohn McCall }; 136931168b07SJohn McCall 1370f9b056b0SJohn McCall /// Emits the copy/dispose helpers for a __block variable with a 1371f9b056b0SJohn McCall /// nontrivial copy constructor or destructor. 1372f9b056b0SJohn McCall class CXXByrefHelpers : public CodeGenModule::ByrefHelpers { 1373f9b056b0SJohn McCall QualType VarType; 1374f9b056b0SJohn McCall const Expr *CopyExpr; 1375f9b056b0SJohn McCall 1376f9b056b0SJohn McCall public: 1377f9b056b0SJohn McCall CXXByrefHelpers(CharUnits alignment, QualType type, 1378f9b056b0SJohn McCall const Expr *copyExpr) 1379f9b056b0SJohn McCall : ByrefHelpers(alignment), VarType(type), CopyExpr(copyExpr) {} 1380f9b056b0SJohn McCall 1381f9b056b0SJohn McCall bool needsCopy() const { return CopyExpr != 0; } 1382f9b056b0SJohn McCall void emitCopy(CodeGenFunction &CGF, llvm::Value *destField, 1383f9b056b0SJohn McCall llvm::Value *srcField) { 1384f9b056b0SJohn McCall if (!CopyExpr) return; 1385f9b056b0SJohn McCall CGF.EmitSynthesizedCXXCopyCtor(destField, srcField, CopyExpr); 1386f9b056b0SJohn McCall } 1387f9b056b0SJohn McCall 1388f9b056b0SJohn McCall void emitDispose(CodeGenFunction &CGF, llvm::Value *field) { 1389f9b056b0SJohn McCall EHScopeStack::stable_iterator cleanupDepth = CGF.EHStack.stable_begin(); 1390f9b056b0SJohn McCall CGF.PushDestructorCleanup(VarType, field); 1391f9b056b0SJohn McCall CGF.PopCleanupBlocks(cleanupDepth); 1392f9b056b0SJohn McCall } 1393f9b056b0SJohn McCall 1394f9b056b0SJohn McCall void profileImpl(llvm::FoldingSetNodeID &id) const { 1395f9b056b0SJohn McCall id.AddPointer(VarType.getCanonicalType().getAsOpaquePtr()); 1396f9b056b0SJohn McCall } 1397f9b056b0SJohn McCall }; 1398f9b056b0SJohn McCall } // end anonymous namespace 1399f9b056b0SJohn McCall 1400f9b056b0SJohn McCall static llvm::Constant * 1401f9b056b0SJohn McCall generateByrefCopyHelper(CodeGenFunction &CGF, 1402f9b056b0SJohn McCall const llvm::StructType &byrefType, 1403f9b056b0SJohn McCall CodeGenModule::ByrefHelpers &byrefInfo) { 1404f9b056b0SJohn McCall ASTContext &Context = CGF.getContext(); 1405f9b056b0SJohn McCall 1406f9b056b0SJohn McCall QualType R = Context.VoidTy; 1407ee2a5ee5SMike Stump 1408a738c25fSJohn McCall FunctionArgList args; 1409f9b056b0SJohn McCall ImplicitParamDecl dst(0, SourceLocation(), 0, Context.VoidPtrTy); 1410a738c25fSJohn McCall args.push_back(&dst); 1411f89230d9SMike Stump 1412f9b056b0SJohn McCall ImplicitParamDecl src(0, SourceLocation(), 0, Context.VoidPtrTy); 1413a738c25fSJohn McCall args.push_back(&src); 1414ee2a5ee5SMike Stump 1415ee2a5ee5SMike Stump const CGFunctionInfo &FI = 1416f9b056b0SJohn McCall CGF.CGM.getTypes().getFunctionInfo(R, args, FunctionType::ExtInfo()); 1417ee2a5ee5SMike Stump 1418f9b056b0SJohn McCall CodeGenTypes &Types = CGF.CGM.getTypes(); 1419ee2a5ee5SMike Stump const llvm::FunctionType *LTy = Types.GetFunctionType(FI, false); 1420ee2a5ee5SMike Stump 1421cbc2bcafSMike Stump // FIXME: We'd like to put these into a mergable by content, with 1422cbc2bcafSMike Stump // internal linkage. 1423ee2a5ee5SMike Stump llvm::Function *Fn = 1424ee2a5ee5SMike Stump llvm::Function::Create(LTy, llvm::GlobalValue::InternalLinkage, 1425f9b056b0SJohn McCall "__Block_byref_object_copy_", &CGF.CGM.getModule()); 1426ee2a5ee5SMike Stump 1427ee2a5ee5SMike Stump IdentifierInfo *II 1428f9b056b0SJohn McCall = &Context.Idents.get("__Block_byref_object_copy_"); 1429ee2a5ee5SMike Stump 1430f9b056b0SJohn McCall FunctionDecl *FD = FunctionDecl::Create(Context, 1431f9b056b0SJohn McCall Context.getTranslationUnitDecl(), 1432dff1930bSAbramo Bagnara SourceLocation(), 143360ed5604SArgyrios Kyrtzidis SourceLocation(), II, R, 0, 14348e7d656aSJohn McCall SC_Static, 14358e7d656aSJohn McCall SC_None, 1436c4df4076SDouglas Gregor false, true); 143731168b07SJohn McCall 1438f9b056b0SJohn McCall CGF.StartFunction(FD, R, Fn, FI, args, SourceLocation()); 1439f9b056b0SJohn McCall 1440f9b056b0SJohn McCall if (byrefInfo.needsCopy()) { 1441f9b056b0SJohn McCall const llvm::Type *byrefPtrType = byrefType.getPointerTo(0); 1442f89230d9SMike Stump 1443f89230d9SMike Stump // dst->x 1444f9b056b0SJohn McCall llvm::Value *destField = CGF.GetAddrOfLocalVar(&dst); 1445f9b056b0SJohn McCall destField = CGF.Builder.CreateLoad(destField); 1446f9b056b0SJohn McCall destField = CGF.Builder.CreateBitCast(destField, byrefPtrType); 1447f9b056b0SJohn McCall destField = CGF.Builder.CreateStructGEP(destField, 6, "x"); 1448f89230d9SMike Stump 1449f89230d9SMike Stump // src->x 1450f9b056b0SJohn McCall llvm::Value *srcField = CGF.GetAddrOfLocalVar(&src); 1451f9b056b0SJohn McCall srcField = CGF.Builder.CreateLoad(srcField); 1452f9b056b0SJohn McCall srcField = CGF.Builder.CreateBitCast(srcField, byrefPtrType); 1453f9b056b0SJohn McCall srcField = CGF.Builder.CreateStructGEP(srcField, 6, "x"); 145450198098SFariborz Jahanian 1455f9b056b0SJohn McCall byrefInfo.emitCopy(CGF, destField, srcField); 145650198098SFariborz Jahanian } 1457f89230d9SMike Stump 1458f9b056b0SJohn McCall CGF.FinishFunction(); 1459ee2a5ee5SMike Stump 1460f9b056b0SJohn McCall return llvm::ConstantExpr::getBitCast(Fn, CGF.Int8PtrTy); 1461ee2a5ee5SMike Stump } 1462ee2a5ee5SMike Stump 1463f9b056b0SJohn McCall /// Build the copy helper for a __block variable. 1464f9b056b0SJohn McCall static llvm::Constant *buildByrefCopyHelper(CodeGenModule &CGM, 1465f9b056b0SJohn McCall const llvm::StructType &byrefType, 1466f9b056b0SJohn McCall CodeGenModule::ByrefHelpers &info) { 1467f9b056b0SJohn McCall CodeGenFunction CGF(CGM); 1468f9b056b0SJohn McCall return generateByrefCopyHelper(CGF, byrefType, info); 1469f9b056b0SJohn McCall } 1470f9b056b0SJohn McCall 1471f9b056b0SJohn McCall /// Generate code for a __block variable's dispose helper. 1472f9b056b0SJohn McCall static llvm::Constant * 1473f9b056b0SJohn McCall generateByrefDisposeHelper(CodeGenFunction &CGF, 1474f9b056b0SJohn McCall const llvm::StructType &byrefType, 1475f9b056b0SJohn McCall CodeGenModule::ByrefHelpers &byrefInfo) { 1476f9b056b0SJohn McCall ASTContext &Context = CGF.getContext(); 1477f9b056b0SJohn McCall QualType R = Context.VoidTy; 1478ee2a5ee5SMike Stump 1479a738c25fSJohn McCall FunctionArgList args; 1480f9b056b0SJohn McCall ImplicitParamDecl src(0, SourceLocation(), 0, Context.VoidPtrTy); 1481a738c25fSJohn McCall args.push_back(&src); 1482ee2a5ee5SMike Stump 1483ee2a5ee5SMike Stump const CGFunctionInfo &FI = 1484f9b056b0SJohn McCall CGF.CGM.getTypes().getFunctionInfo(R, args, FunctionType::ExtInfo()); 1485ee2a5ee5SMike Stump 1486f9b056b0SJohn McCall CodeGenTypes &Types = CGF.CGM.getTypes(); 1487ee2a5ee5SMike Stump const llvm::FunctionType *LTy = Types.GetFunctionType(FI, false); 1488ee2a5ee5SMike Stump 1489cbc2bcafSMike Stump // FIXME: We'd like to put these into a mergable by content, with 1490cbc2bcafSMike Stump // internal linkage. 1491ee2a5ee5SMike Stump llvm::Function *Fn = 1492ee2a5ee5SMike Stump llvm::Function::Create(LTy, llvm::GlobalValue::InternalLinkage, 149350198098SFariborz Jahanian "__Block_byref_object_dispose_", 1494f9b056b0SJohn McCall &CGF.CGM.getModule()); 1495ee2a5ee5SMike Stump 1496ee2a5ee5SMike Stump IdentifierInfo *II 1497f9b056b0SJohn McCall = &Context.Idents.get("__Block_byref_object_dispose_"); 1498ee2a5ee5SMike Stump 1499f9b056b0SJohn McCall FunctionDecl *FD = FunctionDecl::Create(Context, 1500f9b056b0SJohn McCall Context.getTranslationUnitDecl(), 1501dff1930bSAbramo Bagnara SourceLocation(), 150260ed5604SArgyrios Kyrtzidis SourceLocation(), II, R, 0, 15038e7d656aSJohn McCall SC_Static, 15048e7d656aSJohn McCall SC_None, 1505c4df4076SDouglas Gregor false, true); 1506f9b056b0SJohn McCall CGF.StartFunction(FD, R, Fn, FI, args, SourceLocation()); 1507fbe25dd1SMike Stump 1508f9b056b0SJohn McCall if (byrefInfo.needsDispose()) { 1509f9b056b0SJohn McCall llvm::Value *V = CGF.GetAddrOfLocalVar(&src); 1510f9b056b0SJohn McCall V = CGF.Builder.CreateLoad(V); 1511f9b056b0SJohn McCall V = CGF.Builder.CreateBitCast(V, byrefType.getPointerTo(0)); 1512f9b056b0SJohn McCall V = CGF.Builder.CreateStructGEP(V, 6, "x"); 1513ad7c5c16SJohn McCall 1514f9b056b0SJohn McCall byrefInfo.emitDispose(CGF, V); 1515f9b056b0SJohn McCall } 1516ad7c5c16SJohn McCall 1517f9b056b0SJohn McCall CGF.FinishFunction(); 1518f9b056b0SJohn McCall 1519f9b056b0SJohn McCall return llvm::ConstantExpr::getBitCast(Fn, CGF.Int8PtrTy); 1520f9b056b0SJohn McCall } 1521f9b056b0SJohn McCall 1522f9b056b0SJohn McCall /// Build the dispose helper for a __block variable. 1523f9b056b0SJohn McCall static llvm::Constant *buildByrefDisposeHelper(CodeGenModule &CGM, 1524f9b056b0SJohn McCall const llvm::StructType &byrefType, 1525f9b056b0SJohn McCall CodeGenModule::ByrefHelpers &info) { 1526f9b056b0SJohn McCall CodeGenFunction CGF(CGM); 1527f9b056b0SJohn McCall return generateByrefDisposeHelper(CGF, byrefType, info); 1528f9b056b0SJohn McCall } 1529f9b056b0SJohn McCall 1530f9b056b0SJohn McCall /// 1531f9b056b0SJohn McCall template <class T> static T *buildByrefHelpers(CodeGenModule &CGM, 1532f9b056b0SJohn McCall const llvm::StructType &byrefTy, 1533f9b056b0SJohn McCall T &byrefInfo) { 1534f9b056b0SJohn McCall // Increase the field's alignment to be at least pointer alignment, 1535f9b056b0SJohn McCall // since the layout of the byref struct will guarantee at least that. 1536f9b056b0SJohn McCall byrefInfo.Alignment = std::max(byrefInfo.Alignment, 1537f9b056b0SJohn McCall CharUnits::fromQuantity(CGM.PointerAlignInBytes)); 1538f9b056b0SJohn McCall 1539f9b056b0SJohn McCall llvm::FoldingSetNodeID id; 1540f9b056b0SJohn McCall byrefInfo.Profile(id); 1541f9b056b0SJohn McCall 1542f9b056b0SJohn McCall void *insertPos; 1543f9b056b0SJohn McCall CodeGenModule::ByrefHelpers *node 1544f9b056b0SJohn McCall = CGM.ByrefHelpersCache.FindNodeOrInsertPos(id, insertPos); 1545f9b056b0SJohn McCall if (node) return static_cast<T*>(node); 1546f9b056b0SJohn McCall 1547f9b056b0SJohn McCall byrefInfo.CopyHelper = buildByrefCopyHelper(CGM, byrefTy, byrefInfo); 1548f9b056b0SJohn McCall byrefInfo.DisposeHelper = buildByrefDisposeHelper(CGM, byrefTy, byrefInfo); 1549f9b056b0SJohn McCall 1550f9b056b0SJohn McCall T *copy = new (CGM.getContext()) T(byrefInfo); 1551f9b056b0SJohn McCall CGM.ByrefHelpersCache.InsertNode(copy, insertPos); 1552f9b056b0SJohn McCall return copy; 1553f9b056b0SJohn McCall } 1554f9b056b0SJohn McCall 1555f9b056b0SJohn McCall CodeGenModule::ByrefHelpers * 1556f9b056b0SJohn McCall CodeGenFunction::buildByrefHelpers(const llvm::StructType &byrefType, 1557f9b056b0SJohn McCall const AutoVarEmission &emission) { 1558f9b056b0SJohn McCall const VarDecl &var = *emission.Variable; 1559f9b056b0SJohn McCall QualType type = var.getType(); 1560f9b056b0SJohn McCall 1561f9b056b0SJohn McCall if (const CXXRecordDecl *record = type->getAsCXXRecordDecl()) { 1562f9b056b0SJohn McCall const Expr *copyExpr = CGM.getContext().getBlockVarCopyInits(&var); 1563f9b056b0SJohn McCall if (!copyExpr && record->hasTrivialDestructor()) return 0; 1564f9b056b0SJohn McCall 1565f9b056b0SJohn McCall CXXByrefHelpers byrefInfo(emission.Alignment, type, copyExpr); 1566f9b056b0SJohn McCall return ::buildByrefHelpers(CGM, byrefType, byrefInfo); 1567f9b056b0SJohn McCall } 1568f9b056b0SJohn McCall 156931168b07SJohn McCall // Otherwise, if we don't have a retainable type, there's nothing to do. 157031168b07SJohn McCall // that the runtime does extra copies. 157131168b07SJohn McCall if (!type->isObjCRetainableType()) return 0; 157231168b07SJohn McCall 157331168b07SJohn McCall Qualifiers qs = type.getQualifiers(); 157431168b07SJohn McCall 157531168b07SJohn McCall // If we have lifetime, that dominates. 157631168b07SJohn McCall if (Qualifiers::ObjCLifetime lifetime = qs.getObjCLifetime()) { 157731168b07SJohn McCall assert(getLangOptions().ObjCAutoRefCount); 157831168b07SJohn McCall 157931168b07SJohn McCall switch (lifetime) { 158031168b07SJohn McCall case Qualifiers::OCL_None: llvm_unreachable("impossible"); 158131168b07SJohn McCall 158231168b07SJohn McCall // These are just bits as far as the runtime is concerned. 158331168b07SJohn McCall case Qualifiers::OCL_ExplicitNone: 158431168b07SJohn McCall case Qualifiers::OCL_Autoreleasing: 158531168b07SJohn McCall return 0; 158631168b07SJohn McCall 158731168b07SJohn McCall // Tell the runtime that this is ARC __weak, called by the 158831168b07SJohn McCall // byref routines. 158931168b07SJohn McCall case Qualifiers::OCL_Weak: { 159031168b07SJohn McCall ARCWeakByrefHelpers byrefInfo(emission.Alignment); 159131168b07SJohn McCall return ::buildByrefHelpers(CGM, byrefType, byrefInfo); 159231168b07SJohn McCall } 159331168b07SJohn McCall 159431168b07SJohn McCall // ARC __strong __block variables need to be retained. 159531168b07SJohn McCall case Qualifiers::OCL_Strong: 159631168b07SJohn McCall // Block-pointers need to be _Block_copy'ed, so we let the 159731168b07SJohn McCall // runtime be in charge. But we can't use the code below 159831168b07SJohn McCall // because we don't want to set BYREF_CALLER, which will 159931168b07SJohn McCall // just make the runtime ignore us. 160031168b07SJohn McCall if (type->isBlockPointerType()) { 160131168b07SJohn McCall BlockFieldFlags flags = BLOCK_FIELD_IS_BLOCK; 160231168b07SJohn McCall ObjectByrefHelpers byrefInfo(emission.Alignment, flags); 160331168b07SJohn McCall return ::buildByrefHelpers(CGM, byrefType, byrefInfo); 160431168b07SJohn McCall 160531168b07SJohn McCall // Otherwise, we transfer ownership of the retain from the stack 160631168b07SJohn McCall // to the heap. 160731168b07SJohn McCall } else { 160831168b07SJohn McCall ARCStrongByrefHelpers byrefInfo(emission.Alignment); 160931168b07SJohn McCall return ::buildByrefHelpers(CGM, byrefType, byrefInfo); 161031168b07SJohn McCall } 161131168b07SJohn McCall } 161231168b07SJohn McCall llvm_unreachable("fell out of lifetime switch!"); 161331168b07SJohn McCall } 161431168b07SJohn McCall 1615f9b056b0SJohn McCall BlockFieldFlags flags; 1616f9b056b0SJohn McCall if (type->isBlockPointerType()) { 1617f9b056b0SJohn McCall flags |= BLOCK_FIELD_IS_BLOCK; 1618f9b056b0SJohn McCall } else if (CGM.getContext().isObjCNSObjectType(type) || 1619f9b056b0SJohn McCall type->isObjCObjectPointerType()) { 1620f9b056b0SJohn McCall flags |= BLOCK_FIELD_IS_OBJECT; 1621ad7c5c16SJohn McCall } else { 1622f9b056b0SJohn McCall return 0; 1623ee2a5ee5SMike Stump } 1624ee2a5ee5SMike Stump 1625f9b056b0SJohn McCall if (type.isObjCGCWeak()) 1626f9b056b0SJohn McCall flags |= BLOCK_FIELD_IS_WEAK; 1627ad7c5c16SJohn McCall 1628f9b056b0SJohn McCall ObjectByrefHelpers byrefInfo(emission.Alignment, flags); 1629f9b056b0SJohn McCall return ::buildByrefHelpers(CGM, byrefType, byrefInfo); 1630ee2a5ee5SMike Stump } 1631ee2a5ee5SMike Stump 163273064870SJohn McCall unsigned CodeGenFunction::getByRefValueLLVMField(const ValueDecl *VD) const { 163373064870SJohn McCall assert(ByRefValueInfo.count(VD) && "Did not find value!"); 163473064870SJohn McCall 163573064870SJohn McCall return ByRefValueInfo.find(VD)->second.second; 163673064870SJohn McCall } 163773064870SJohn McCall 163873064870SJohn McCall llvm::Value *CodeGenFunction::BuildBlockByrefAddress(llvm::Value *BaseAddr, 163973064870SJohn McCall const VarDecl *V) { 164073064870SJohn McCall llvm::Value *Loc = Builder.CreateStructGEP(BaseAddr, 1, "forwarding"); 164173064870SJohn McCall Loc = Builder.CreateLoad(Loc); 164273064870SJohn McCall Loc = Builder.CreateStructGEP(Loc, getByRefValueLLVMField(V), 164373064870SJohn McCall V->getNameAsString()); 164473064870SJohn McCall return Loc; 164573064870SJohn McCall } 164673064870SJohn McCall 164773064870SJohn McCall /// BuildByRefType - This routine changes a __block variable declared as T x 164873064870SJohn McCall /// into: 164973064870SJohn McCall /// 165073064870SJohn McCall /// struct { 165173064870SJohn McCall /// void *__isa; 165273064870SJohn McCall /// void *__forwarding; 165373064870SJohn McCall /// int32_t __flags; 165473064870SJohn McCall /// int32_t __size; 165573064870SJohn McCall /// void *__copy_helper; // only if needed 165673064870SJohn McCall /// void *__destroy_helper; // only if needed 165773064870SJohn McCall /// char padding[X]; // only if needed 165873064870SJohn McCall /// T x; 165973064870SJohn McCall /// } x 166073064870SJohn McCall /// 166173064870SJohn McCall const llvm::Type *CodeGenFunction::BuildByRefType(const VarDecl *D) { 166273064870SJohn McCall std::pair<const llvm::Type *, unsigned> &Info = ByRefValueInfo[D]; 166373064870SJohn McCall if (Info.first) 166473064870SJohn McCall return Info.first; 166573064870SJohn McCall 166673064870SJohn McCall QualType Ty = D->getType(); 166773064870SJohn McCall 1668a5f58b05SChris Lattner llvm::SmallVector<llvm::Type *, 8> types; 166973064870SJohn McCall 1670a5f58b05SChris Lattner llvm::StructType *ByRefType = 1671a5f58b05SChris Lattner llvm::StructType::createNamed(getLLVMContext(), 1672a5f58b05SChris Lattner "struct.__block_byref_" + D->getNameAsString()); 167373064870SJohn McCall 167473064870SJohn McCall // void *__isa; 16759dc0db21SJohn McCall types.push_back(Int8PtrTy); 167673064870SJohn McCall 167773064870SJohn McCall // void *__forwarding; 1678a5f58b05SChris Lattner types.push_back(llvm::PointerType::getUnqual(ByRefType)); 167973064870SJohn McCall 168073064870SJohn McCall // int32_t __flags; 16819dc0db21SJohn McCall types.push_back(Int32Ty); 168273064870SJohn McCall 168373064870SJohn McCall // int32_t __size; 16849dc0db21SJohn McCall types.push_back(Int32Ty); 168573064870SJohn McCall 168673064870SJohn McCall bool HasCopyAndDispose = getContext().BlockRequiresCopying(Ty); 168773064870SJohn McCall if (HasCopyAndDispose) { 168873064870SJohn McCall /// void *__copy_helper; 16899dc0db21SJohn McCall types.push_back(Int8PtrTy); 169073064870SJohn McCall 169173064870SJohn McCall /// void *__destroy_helper; 16929dc0db21SJohn McCall types.push_back(Int8PtrTy); 169373064870SJohn McCall } 169473064870SJohn McCall 169573064870SJohn McCall bool Packed = false; 169673064870SJohn McCall CharUnits Align = getContext().getDeclAlign(D); 169773064870SJohn McCall if (Align > getContext().toCharUnitsFromBits(Target.getPointerAlign(0))) { 169873064870SJohn McCall // We have to insert padding. 169973064870SJohn McCall 170073064870SJohn McCall // The struct above has 2 32-bit integers. 170173064870SJohn McCall unsigned CurrentOffsetInBytes = 4 * 2; 170273064870SJohn McCall 170373064870SJohn McCall // And either 2 or 4 pointers. 170473064870SJohn McCall CurrentOffsetInBytes += (HasCopyAndDispose ? 4 : 2) * 170573064870SJohn McCall CGM.getTargetData().getTypeAllocSize(Int8PtrTy); 170673064870SJohn McCall 170773064870SJohn McCall // Align the offset. 170873064870SJohn McCall unsigned AlignedOffsetInBytes = 170973064870SJohn McCall llvm::RoundUpToAlignment(CurrentOffsetInBytes, Align.getQuantity()); 171073064870SJohn McCall 171173064870SJohn McCall unsigned NumPaddingBytes = AlignedOffsetInBytes - CurrentOffsetInBytes; 171273064870SJohn McCall if (NumPaddingBytes > 0) { 1713a5f58b05SChris Lattner llvm::Type *Ty = llvm::Type::getInt8Ty(getLLVMContext()); 171473064870SJohn McCall // FIXME: We need a sema error for alignment larger than the minimum of 17159dc0db21SJohn McCall // the maximal stack alignment and the alignment of malloc on the system. 171673064870SJohn McCall if (NumPaddingBytes > 1) 171773064870SJohn McCall Ty = llvm::ArrayType::get(Ty, NumPaddingBytes); 171873064870SJohn McCall 17199dc0db21SJohn McCall types.push_back(Ty); 172073064870SJohn McCall 172173064870SJohn McCall // We want a packed struct. 172273064870SJohn McCall Packed = true; 172373064870SJohn McCall } 172473064870SJohn McCall } 172573064870SJohn McCall 172673064870SJohn McCall // T x; 17279dc0db21SJohn McCall types.push_back(ConvertTypeForMem(Ty)); 172873064870SJohn McCall 1729a5f58b05SChris Lattner ByRefType->setBody(types, Packed); 173073064870SJohn McCall 1731a5f58b05SChris Lattner Info.first = ByRefType; 173273064870SJohn McCall 17339dc0db21SJohn McCall Info.second = types.size() - 1; 173473064870SJohn McCall 173573064870SJohn McCall return Info.first; 173673064870SJohn McCall } 173773064870SJohn McCall 173873064870SJohn McCall /// Initialize the structural components of a __block variable, i.e. 173973064870SJohn McCall /// everything but the actual object. 174073064870SJohn McCall void CodeGenFunction::emitByrefStructureInit(const AutoVarEmission &emission) { 1741f9b056b0SJohn McCall // Find the address of the local. 1742f9b056b0SJohn McCall llvm::Value *addr = emission.Address; 174373064870SJohn McCall 1744f9b056b0SJohn McCall // That's an alloca of the byref structure type. 1745f9b056b0SJohn McCall const llvm::StructType *byrefType = cast<llvm::StructType>( 1746f9b056b0SJohn McCall cast<llvm::PointerType>(addr->getType())->getElementType()); 1747f9b056b0SJohn McCall 1748f9b056b0SJohn McCall // Build the byref helpers if necessary. This is null if we don't need any. 1749f9b056b0SJohn McCall CodeGenModule::ByrefHelpers *helpers = 1750f9b056b0SJohn McCall buildByrefHelpers(*byrefType, emission); 175173064870SJohn McCall 175273064870SJohn McCall const VarDecl &D = *emission.Variable; 175373064870SJohn McCall QualType type = D.getType(); 175473064870SJohn McCall 1755f9b056b0SJohn McCall llvm::Value *V; 175673064870SJohn McCall 175773064870SJohn McCall // Initialize the 'isa', which is just 0 or 1. 175873064870SJohn McCall int isa = 0; 1759f9b056b0SJohn McCall if (type.isObjCGCWeak()) 176073064870SJohn McCall isa = 1; 176173064870SJohn McCall V = Builder.CreateIntToPtr(Builder.getInt32(isa), Int8PtrTy, "isa"); 176273064870SJohn McCall Builder.CreateStore(V, Builder.CreateStructGEP(addr, 0, "byref.isa")); 176373064870SJohn McCall 176473064870SJohn McCall // Store the address of the variable into its own forwarding pointer. 176573064870SJohn McCall Builder.CreateStore(addr, 176673064870SJohn McCall Builder.CreateStructGEP(addr, 1, "byref.forwarding")); 176773064870SJohn McCall 176873064870SJohn McCall // Blocks ABI: 176973064870SJohn McCall // c) the flags field is set to either 0 if no helper functions are 177073064870SJohn McCall // needed or BLOCK_HAS_COPY_DISPOSE if they are, 177173064870SJohn McCall BlockFlags flags; 1772f9b056b0SJohn McCall if (helpers) flags |= BLOCK_HAS_COPY_DISPOSE; 177373064870SJohn McCall Builder.CreateStore(llvm::ConstantInt::get(IntTy, flags.getBitMask()), 177473064870SJohn McCall Builder.CreateStructGEP(addr, 2, "byref.flags")); 177573064870SJohn McCall 1776f9b056b0SJohn McCall CharUnits byrefSize = CGM.GetTargetTypeStoreSize(byrefType); 1777f9b056b0SJohn McCall V = llvm::ConstantInt::get(IntTy, byrefSize.getQuantity()); 177873064870SJohn McCall Builder.CreateStore(V, Builder.CreateStructGEP(addr, 3, "byref.size")); 177973064870SJohn McCall 1780f9b056b0SJohn McCall if (helpers) { 178173064870SJohn McCall llvm::Value *copy_helper = Builder.CreateStructGEP(addr, 4); 1782f9b056b0SJohn McCall Builder.CreateStore(helpers->CopyHelper, copy_helper); 178373064870SJohn McCall 178473064870SJohn McCall llvm::Value *destroy_helper = Builder.CreateStructGEP(addr, 5); 1785f9b056b0SJohn McCall Builder.CreateStore(helpers->DisposeHelper, destroy_helper); 178673064870SJohn McCall } 178773064870SJohn McCall } 178873064870SJohn McCall 1789ad7c5c16SJohn McCall void CodeGenFunction::BuildBlockRelease(llvm::Value *V, BlockFieldFlags flags) { 1790900546d2SDaniel Dunbar llvm::Value *F = CGM.getBlockObjectDispose(); 1791fbe25dd1SMike Stump llvm::Value *N; 1792ad7c5c16SJohn McCall V = Builder.CreateBitCast(V, Int8PtrTy); 1793ad7c5c16SJohn McCall N = llvm::ConstantInt::get(Int32Ty, flags.getBitMask()); 1794626aecc4SMike Stump Builder.CreateCall2(F, V, N); 1795626aecc4SMike Stump } 179673064870SJohn McCall 179773064870SJohn McCall namespace { 179873064870SJohn McCall struct CallBlockRelease : EHScopeStack::Cleanup { 179973064870SJohn McCall llvm::Value *Addr; 180073064870SJohn McCall CallBlockRelease(llvm::Value *Addr) : Addr(Addr) {} 180173064870SJohn McCall 180273064870SJohn McCall void Emit(CodeGenFunction &CGF, bool IsForEH) { 180331168b07SJohn McCall // Should we be passing FIELD_IS_WEAK here? 180473064870SJohn McCall CGF.BuildBlockRelease(Addr, BLOCK_FIELD_IS_BYREF); 180573064870SJohn McCall } 180673064870SJohn McCall }; 180773064870SJohn McCall } 180873064870SJohn McCall 180973064870SJohn McCall /// Enter a cleanup to destroy a __block variable. Note that this 181073064870SJohn McCall /// cleanup should be a no-op if the variable hasn't left the stack 181173064870SJohn McCall /// yet; if a cleanup is required for the variable itself, that needs 181273064870SJohn McCall /// to be done externally. 181373064870SJohn McCall void CodeGenFunction::enterByrefCleanup(const AutoVarEmission &emission) { 181473064870SJohn McCall // We don't enter this cleanup if we're in pure-GC mode. 181573064870SJohn McCall if (CGM.getLangOptions().getGCMode() == LangOptions::GCOnly) 181673064870SJohn McCall return; 181773064870SJohn McCall 181873064870SJohn McCall EHStack.pushCleanup<CallBlockRelease>(NormalAndEHCleanup, emission.Address); 181973064870SJohn McCall } 1820