CGBlocks.cpp revision 6c803f7f46533c69e2f8a9a882af9ae3b7fffb6f
1acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson//===--- CGBlocks.cpp - Emit LLVM Code for declarations -------------------===// 2acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson// 3acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson// The LLVM Compiler Infrastructure 4acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson// 5acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson// This file is distributed under the University of Illinois Open Source 6acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson// License. See LICENSE.TXT for details. 7acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson// 8acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson//===----------------------------------------------------------------------===// 9acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson// 10acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson// This contains code to emit blocks. 11acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson// 12acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson//===----------------------------------------------------------------------===// 13acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson 14b1a6e687967105bf1e18dfba196d0248e6700a4eMike Stump#include "CGDebugInfo.h" 15acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson#include "CodeGenFunction.h" 16263c4dec5f0fda5a77ed99f3ccd456c15cb8720fFariborz Jahanian#include "CGObjCRuntime.h" 17acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson#include "CodeGenModule.h" 18d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall#include "CGBlocks.h" 196cc88f78fd36d3511b89412b193494b3e423cbffMike Stump#include "clang/AST/DeclObjC.h" 20acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson#include "llvm/Module.h" 216876fe615e16b0e76c7711e129e470305b7e9d41Benjamin Kramer#include "llvm/ADT/SmallSet.h" 22d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson#include "llvm/Target/TargetData.h" 23acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson#include <algorithm> 24f42e4a6e089e8413247400fe58ad299193371f9cTorok Edwin 25acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlssonusing namespace clang; 26acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlssonusing namespace CodeGen; 27acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson 281a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCallCGBlockInfo::CGBlockInfo(const BlockDecl *block, StringRef name) 291a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall : Name(name), CXXThisIndex(0), CanBeGlobal(false), NeedsCopyDispose(false), 306f103ba42cb69d50005a977c5ea583984ab63fc4John McCall HasCXXObject(false), UsesStret(false), StructureType(0), Block(block), 316f103ba42cb69d50005a977c5ea583984ab63fc4John McCall DominatingIP(0) { 32ee5042903d53fa7b0fbc1902d0ea07d57c7775b1John McCall 331a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall // Skip asm prefix, if any. 'name' is usually taken directly from 341a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall // the mangled name of the enclosing function. 351a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall if (!name.empty() && name[0] == '\01') 361a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall name = name.substr(1); 37ee5042903d53fa7b0fbc1902d0ea07d57c7775b1John McCall} 38ee5042903d53fa7b0fbc1902d0ea07d57c7775b1John McCall 39f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall// Anchor the vtable to this translation unit. 40f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCallCodeGenModule::ByrefHelpers::~ByrefHelpers() {} 41f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall 426b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall/// Build the given block as a global block. 436b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCallstatic llvm::Constant *buildGlobalBlock(CodeGenModule &CGM, 446b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall const CGBlockInfo &blockInfo, 456b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall llvm::Constant *blockFn); 46ee5042903d53fa7b0fbc1902d0ea07d57c7775b1John McCall 476b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall/// Build the helper function to copy a block. 486b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCallstatic llvm::Constant *buildCopyHelper(CodeGenModule &CGM, 496b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall const CGBlockInfo &blockInfo) { 506b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall return CodeGenFunction(CGM).GenerateCopyHelperFunction(blockInfo); 516b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall} 526b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 536b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall/// Build the helper function to dipose of a block. 546b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCallstatic llvm::Constant *buildDisposeHelper(CodeGenModule &CGM, 556b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall const CGBlockInfo &blockInfo) { 566b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall return CodeGenFunction(CGM).GenerateDestroyHelperFunction(blockInfo); 576b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall} 586b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 596b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall/// Build the block descriptor constant for a block. 606b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCallstatic llvm::Constant *buildBlockDescriptor(CodeGenModule &CGM, 616b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall const CGBlockInfo &blockInfo) { 626b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall ASTContext &C = CGM.getContext(); 636b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 642acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *ulong = CGM.getTypes().ConvertType(C.UnsignedLongTy); 652acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *i8p = CGM.getTypes().ConvertType(C.VoidPtrTy); 666b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 675f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<llvm::Constant*, 6> elements; 68e5fee25e71266712522cff554f25c59b3078a429Mike Stump 69e5fee25e71266712522cff554f25c59b3078a429Mike Stump // reserved 706b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall elements.push_back(llvm::ConstantInt::get(ulong, 0)); 71e5fee25e71266712522cff554f25c59b3078a429Mike Stump 72e5fee25e71266712522cff554f25c59b3078a429Mike Stump // Size 73d6840002c37ba25effe5eb4bb89c4ae2e1d80945Mike Stump // FIXME: What is the right way to say this doesn't fit? We should give 74d6840002c37ba25effe5eb4bb89c4ae2e1d80945Mike Stump // a user diagnostic in that case. Better fix would be to change the 75d6840002c37ba25effe5eb4bb89c4ae2e1d80945Mike Stump // API to size_t. 766b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall elements.push_back(llvm::ConstantInt::get(ulong, 776b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall blockInfo.BlockSize.getQuantity())); 78e5fee25e71266712522cff554f25c59b3078a429Mike Stump 796b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // Optional copy/dispose helpers. 806b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall if (blockInfo.NeedsCopyDispose) { 81e5fee25e71266712522cff554f25c59b3078a429Mike Stump // copy_func_helper_decl 826b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall elements.push_back(buildCopyHelper(CGM, blockInfo)); 83e5fee25e71266712522cff554f25c59b3078a429Mike Stump 84e5fee25e71266712522cff554f25c59b3078a429Mike Stump // destroy_func_decl 856b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall elements.push_back(buildDisposeHelper(CGM, blockInfo)); 86e5fee25e71266712522cff554f25c59b3078a429Mike Stump } 87e5fee25e71266712522cff554f25c59b3078a429Mike Stump 886b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // Signature. Mandatory ObjC-style method descriptor @encode sequence. 896b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall std::string typeAtEncoding = 906b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall CGM.getContext().getObjCEncodingForBlock(blockInfo.getBlockExpr()); 916b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall elements.push_back(llvm::ConstantExpr::getBitCast( 926b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall CGM.GetAddrOfConstantCString(typeAtEncoding), i8p)); 932a7eb28397148079cbc8e54e8a3871ef01c4f4bcBlaine Garst 946b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // GC layout. 954e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (C.getLangOpts().ObjC1) 966b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall elements.push_back(CGM.getObjCRuntime().BuildGCBlockLayout(CGM, blockInfo)); 976b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall else 986b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall elements.push_back(llvm::Constant::getNullValue(i8p)); 99ea1471e0e967548c596a71469702f8846dbaf3c0John McCall 100c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner llvm::Constant *init = llvm::ConstantStruct::getAnon(elements); 1014de9fce48e42cc7ec1345c0fd21b3dbc5b9114c8Anders Carlsson 1026b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall llvm::GlobalVariable *global = 1036b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall new llvm::GlobalVariable(CGM.getModule(), init->getType(), true, 1046b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall llvm::GlobalValue::InternalLinkage, 1056b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall init, "__block_descriptor_tmp"); 106ea26cb522e88fc86b0d1cae61dcefcfe4cc20231Mike Stump 1076b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall return llvm::ConstantExpr::getBitCast(global, CGM.getBlockDescriptorType()); 1084de9fce48e42cc7ec1345c0fd21b3dbc5b9114c8Anders Carlsson} 1094de9fce48e42cc7ec1345c0fd21b3dbc5b9114c8Anders Carlsson 1106b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall/* 1116b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall Purely notional variadic template describing the layout of a block. 1126b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 1136b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall template <class _ResultType, class... _ParamTypes, class... _CaptureTypes> 1146b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall struct Block_literal { 1156b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall /// Initialized to one of: 1166b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall /// extern void *_NSConcreteStackBlock[]; 1176b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall /// extern void *_NSConcreteGlobalBlock[]; 1186b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall /// 1196b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall /// In theory, we could start one off malloc'ed by setting 1206b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall /// BLOCK_NEEDS_FREE, giving it a refcount of 1, and using 1216b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall /// this isa: 1226b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall /// extern void *_NSConcreteMallocBlock[]; 1236b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall struct objc_class *isa; 1246b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 1256b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall /// These are the flags (with corresponding bit number) that the 1266b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall /// compiler is actually supposed to know about. 1276b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall /// 25. BLOCK_HAS_COPY_DISPOSE - indicates that the block 1286b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall /// descriptor provides copy and dispose helper functions 1296b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall /// 26. BLOCK_HAS_CXX_OBJ - indicates that there's a captured 1306b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall /// object with a nontrivial destructor or copy constructor 1316b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall /// 28. BLOCK_IS_GLOBAL - indicates that the block is allocated 1326b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall /// as global memory 1336b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall /// 29. BLOCK_USE_STRET - indicates that the block function 1346b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall /// uses stret, which objc_msgSend needs to know about 1356b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall /// 30. BLOCK_HAS_SIGNATURE - indicates that the block has an 1366b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall /// @encoded signature string 1376b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall /// And we're not supposed to manipulate these: 1386b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall /// 24. BLOCK_NEEDS_FREE - indicates that the block has been moved 1396b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall /// to malloc'ed memory 1406b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall /// 27. BLOCK_IS_GC - indicates that the block has been moved to 1416b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall /// to GC-allocated memory 1426b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall /// Additionally, the bottom 16 bits are a reference count which 1436b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall /// should be zero on the stack. 1446b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall int flags; 1456b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 1466b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall /// Reserved; should be zero-initialized. 1476b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall int reserved; 1486b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 1496b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall /// Function pointer generated from block literal. 1506b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall _ResultType (*invoke)(Block_literal *, _ParamTypes...); 1516b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 1526b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall /// Block description metadata generated from block literal. 1536b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall struct Block_descriptor *block_descriptor; 1546b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 1556b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall /// Captured values follow. 1566b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall _CapturesTypes captures...; 1576b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall }; 1586b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall */ 1596b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 1606b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall/// The number of fields in a block header. 1616b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCallconst unsigned BlockHeaderSize = 5; 1626b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 1636b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCallnamespace { 1646b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall /// A chunk of data that we actually have to capture in the block. 1656b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall struct BlockLayoutChunk { 1666b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall CharUnits Alignment; 1676b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall CharUnits Size; 1686b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall const BlockDecl::Capture *Capture; // null for 'this' 169ef6de3da8572607f786303c07150daa6e140ab19Jay Foad llvm::Type *Type; 1706b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 1716b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall BlockLayoutChunk(CharUnits align, CharUnits size, 1726b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall const BlockDecl::Capture *capture, 173ef6de3da8572607f786303c07150daa6e140ab19Jay Foad llvm::Type *type) 1746b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall : Alignment(align), Size(size), Capture(capture), Type(type) {} 1756b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 1766b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall /// Tell the block info that this chunk has the given field index. 1776b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall void setIndex(CGBlockInfo &info, unsigned index) { 1786b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall if (!Capture) 1796b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall info.CXXThisIndex = index; 1806b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall else 1816b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall info.Captures[Capture->getVariable()] 1826b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall = CGBlockInfo::Capture::makeIndex(index); 1836b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall } 1846b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall }; 1854de9fce48e42cc7ec1345c0fd21b3dbc5b9114c8Anders Carlsson 1866b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall /// Order by descending alignment. 1876b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall bool operator<(const BlockLayoutChunk &left, const BlockLayoutChunk &right) { 1886b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall return left.Alignment > right.Alignment; 1896b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall } 1906b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall} 19100470a1c4c44c5ed26bad9a38b4d3904b02d7a28Mike Stump 192461c9c1bc39ed8cbe8311f396f7ee3839e9fda53John McCall/// Determines if the given type is safe for constant capture in C++. 193461c9c1bc39ed8cbe8311f396f7ee3839e9fda53John McCallstatic bool isSafeForCXXConstantCapture(QualType type) { 194461c9c1bc39ed8cbe8311f396f7ee3839e9fda53John McCall const RecordType *recordType = 195461c9c1bc39ed8cbe8311f396f7ee3839e9fda53John McCall type->getBaseElementTypeUnsafe()->getAs<RecordType>(); 196461c9c1bc39ed8cbe8311f396f7ee3839e9fda53John McCall 197461c9c1bc39ed8cbe8311f396f7ee3839e9fda53John McCall // Only records can be unsafe. 198461c9c1bc39ed8cbe8311f396f7ee3839e9fda53John McCall if (!recordType) return true; 199461c9c1bc39ed8cbe8311f396f7ee3839e9fda53John McCall 200461c9c1bc39ed8cbe8311f396f7ee3839e9fda53John McCall const CXXRecordDecl *record = cast<CXXRecordDecl>(recordType->getDecl()); 201461c9c1bc39ed8cbe8311f396f7ee3839e9fda53John McCall 202461c9c1bc39ed8cbe8311f396f7ee3839e9fda53John McCall // Maintain semantics for classes with non-trivial dtors or copy ctors. 203461c9c1bc39ed8cbe8311f396f7ee3839e9fda53John McCall if (!record->hasTrivialDestructor()) return false; 204461c9c1bc39ed8cbe8311f396f7ee3839e9fda53John McCall if (!record->hasTrivialCopyConstructor()) return false; 205461c9c1bc39ed8cbe8311f396f7ee3839e9fda53John McCall 206461c9c1bc39ed8cbe8311f396f7ee3839e9fda53John McCall // Otherwise, we just have to make sure there aren't any mutable 207461c9c1bc39ed8cbe8311f396f7ee3839e9fda53John McCall // fields that might have changed since initialization. 2082bb110125e0e5adb7c1c65d12adfa34151ca1c47Douglas Gregor return !record->hasMutableFields(); 209461c9c1bc39ed8cbe8311f396f7ee3839e9fda53John McCall} 210461c9c1bc39ed8cbe8311f396f7ee3839e9fda53John McCall 2116b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall/// It is illegal to modify a const object after initialization. 2126b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall/// Therefore, if a const object has a constant initializer, we don't 2136b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall/// actually need to keep storage for it in the block; we'll just 2146b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall/// rematerialize it at the start of the block function. This is 2156b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall/// acceptable because we make no promises about address stability of 2166b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall/// captured variables. 2176b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCallstatic llvm::Constant *tryCaptureAsConstant(CodeGenModule &CGM, 2182d6a5670465cb3f1d811695a9f23e372508240d2Richard Smith CodeGenFunction *CGF, 2196b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall const VarDecl *var) { 2206b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall QualType type = var->getType(); 2216b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 2226b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // We can only do this if the variable is const. 2236b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall if (!type.isConstQualified()) return 0; 2246b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 225461c9c1bc39ed8cbe8311f396f7ee3839e9fda53John McCall // Furthermore, in C++ we have to worry about mutable fields: 226461c9c1bc39ed8cbe8311f396f7ee3839e9fda53John McCall // C++ [dcl.type.cv]p4: 227461c9c1bc39ed8cbe8311f396f7ee3839e9fda53John McCall // Except that any class member declared mutable can be 228461c9c1bc39ed8cbe8311f396f7ee3839e9fda53John McCall // modified, any attempt to modify a const object during its 229461c9c1bc39ed8cbe8311f396f7ee3839e9fda53John McCall // lifetime results in undefined behavior. 2304e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (CGM.getLangOpts().CPlusPlus && !isSafeForCXXConstantCapture(type)) 2316b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall return 0; 2326b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 2336b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // If the variable doesn't have any initializer (shouldn't this be 2346b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // invalid?), it's not clear what we should do. Maybe capture as 2356b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // zero? 2366b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall const Expr *init = var->getInit(); 2376b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall if (!init) return 0; 2386b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 2392d6a5670465cb3f1d811695a9f23e372508240d2Richard Smith return CGM.EmitConstantInit(*var, CGF); 2406b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall} 2415e530af5d51572a0ed5dbe50da54bd333840c63dDavid Chisnall 2426b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall/// Get the low bit of a nonzero character count. This is the 2436b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall/// alignment of the nth byte if the 0th byte is universally aligned. 2446b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCallstatic CharUnits getLowBit(CharUnits v) { 2456b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall return CharUnits::fromQuantity(v.getQuantity() & (~v.getQuantity() + 1)); 2466b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall} 2475e530af5d51572a0ed5dbe50da54bd333840c63dDavid Chisnall 2486b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCallstatic void initializeForBlockHeader(CodeGenModule &CGM, CGBlockInfo &info, 2495f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVectorImpl<llvm::Type*> &elementTypes) { 2506b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall ASTContext &C = CGM.getContext(); 251e5fee25e71266712522cff554f25c59b3078a429Mike Stump 2526b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // The header is basically a 'struct { void *; int; int; void *; void *; }'. 2536b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall CharUnits ptrSize, ptrAlign, intSize, intAlign; 2546b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall llvm::tie(ptrSize, ptrAlign) = C.getTypeInfoInChars(C.VoidPtrTy); 2556b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall llvm::tie(intSize, intAlign) = C.getTypeInfoInChars(C.IntTy); 256711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 2576b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // Are there crazy embedded platforms where this isn't true? 2586b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall assert(intSize <= ptrSize && "layout assumptions horribly violated"); 2595e530af5d51572a0ed5dbe50da54bd333840c63dDavid Chisnall 2606b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall CharUnits headerSize = ptrSize; 2616b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall if (2 * intSize < ptrAlign) headerSize += ptrSize; 2626b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall else headerSize += 2 * intSize; 2636b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall headerSize += 2 * ptrSize; 26400470a1c4c44c5ed26bad9a38b4d3904b02d7a28Mike Stump 2656b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall info.BlockAlign = ptrAlign; 2666b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall info.BlockSize = headerSize; 2678a2b4b1c5b960710db95e9b296d9a600aee37c00Mike Stump 2686b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall assert(elementTypes.empty()); 269ef6de3da8572607f786303c07150daa6e140ab19Jay Foad llvm::Type *i8p = CGM.getTypes().ConvertType(C.VoidPtrTy); 270ef6de3da8572607f786303c07150daa6e140ab19Jay Foad llvm::Type *intTy = CGM.getTypes().ConvertType(C.IntTy); 2716b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall elementTypes.push_back(i8p); 2726b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall elementTypes.push_back(intTy); 2736b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall elementTypes.push_back(intTy); 2746b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall elementTypes.push_back(i8p); 2756b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall elementTypes.push_back(CGM.getBlockDescriptorType()); 2768a2b4b1c5b960710db95e9b296d9a600aee37c00Mike Stump 2776b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall assert(elementTypes.size() == BlockHeaderSize); 2786b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall} 2798a2b4b1c5b960710db95e9b296d9a600aee37c00Mike Stump 2806b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall/// Compute the layout of the given block. Attempts to lay the block 2816b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall/// out with minimal space requirements. 2822d6a5670465cb3f1d811695a9f23e372508240d2Richard Smithstatic void computeBlockInfo(CodeGenModule &CGM, CodeGenFunction *CGF, 2832d6a5670465cb3f1d811695a9f23e372508240d2Richard Smith CGBlockInfo &info) { 2846b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall ASTContext &C = CGM.getContext(); 2856b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall const BlockDecl *block = info.getBlockDecl(); 2860892099dbc640720400a1d9decd2733a09d733e5Mike Stump 2875f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<llvm::Type*, 8> elementTypes; 2886b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall initializeForBlockHeader(CGM, info, elementTypes); 28900470a1c4c44c5ed26bad9a38b4d3904b02d7a28Mike Stump 2906b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall if (!block->hasCaptures()) { 2916b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall info.StructureType = 2926b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall llvm::StructType::get(CGM.getLLVMContext(), elementTypes, true); 2936b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall info.CanBeGlobal = true; 2946b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall return; 2956b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall } 296ea1471e0e967548c596a71469702f8846dbaf3c0John McCall 2976b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // Collect the layout chunks. 2985f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<BlockLayoutChunk, 16> layout; 2996b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall layout.reserve(block->capturesCXXThis() + 3006b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall (block->capture_end() - block->capture_begin())); 301ea1471e0e967548c596a71469702f8846dbaf3c0John McCall 3026b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall CharUnits maxFieldAlign; 303ea1471e0e967548c596a71469702f8846dbaf3c0John McCall 3046b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // First, 'this'. 3056b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall if (block->capturesCXXThis()) { 3066b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall const DeclContext *DC = block->getDeclContext(); 3076b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall for (; isa<BlockDecl>(DC); DC = cast<BlockDecl>(DC)->getDeclContext()) 3086b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall ; 3097a614d8380297fcd2bc23986241905d97222948cRichard Smith QualType thisType; 3107a614d8380297fcd2bc23986241905d97222948cRichard Smith if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(DC)) 3117a614d8380297fcd2bc23986241905d97222948cRichard Smith thisType = C.getPointerType(C.getRecordType(RD)); 3127a614d8380297fcd2bc23986241905d97222948cRichard Smith else 3137a614d8380297fcd2bc23986241905d97222948cRichard Smith thisType = cast<CXXMethodDecl>(DC)->getThisType(C); 314ea1471e0e967548c596a71469702f8846dbaf3c0John McCall 315ef6de3da8572607f786303c07150daa6e140ab19Jay Foad llvm::Type *llvmType = CGM.getTypes().ConvertType(thisType); 3166b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall std::pair<CharUnits,CharUnits> tinfo 3176b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall = CGM.getContext().getTypeInfoInChars(thisType); 3186b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall maxFieldAlign = std::max(maxFieldAlign, tinfo.second); 319ea1471e0e967548c596a71469702f8846dbaf3c0John McCall 3206b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall layout.push_back(BlockLayoutChunk(tinfo.second, tinfo.first, 0, llvmType)); 3216b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall } 322ea1471e0e967548c596a71469702f8846dbaf3c0John McCall 3236b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // Next, all the block captures. 3246b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall for (BlockDecl::capture_const_iterator ci = block->capture_begin(), 3256b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall ce = block->capture_end(); ci != ce; ++ci) { 3266b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall const VarDecl *variable = ci->getVariable(); 327ea1471e0e967548c596a71469702f8846dbaf3c0John McCall 3286b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall if (ci->isByRef()) { 3296b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // We have to copy/dispose of the __block reference. 3306b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall info.NeedsCopyDispose = true; 3316b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 3326b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // Just use void* instead of a pointer to the byref type. 3336b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall QualType byRefPtrTy = C.VoidPtrTy; 3346b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 335ef6de3da8572607f786303c07150daa6e140ab19Jay Foad llvm::Type *llvmType = CGM.getTypes().ConvertType(byRefPtrTy); 3366b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall std::pair<CharUnits,CharUnits> tinfo 3376b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall = CGM.getContext().getTypeInfoInChars(byRefPtrTy); 3386b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall maxFieldAlign = std::max(maxFieldAlign, tinfo.second); 3396b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 3406b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall layout.push_back(BlockLayoutChunk(tinfo.second, tinfo.first, 3416b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall &*ci, llvmType)); 3426b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall continue; 3436b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall } 3446b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 3456b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // Otherwise, build a layout chunk with the size and alignment of 3466b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // the declaration. 3472d6a5670465cb3f1d811695a9f23e372508240d2Richard Smith if (llvm::Constant *constant = tryCaptureAsConstant(CGM, CGF, variable)) { 3486b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall info.Captures[variable] = CGBlockInfo::Capture::makeConstant(constant); 3496b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall continue; 3506b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall } 3516b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 352f85e193739c953358c865005855253af4f68a497John McCall // If we have a lifetime qualifier, honor it for capture purposes. 353f85e193739c953358c865005855253af4f68a497John McCall // That includes *not* copying it if it's __unsafe_unretained. 354f85e193739c953358c865005855253af4f68a497John McCall if (Qualifiers::ObjCLifetime lifetime 355f85e193739c953358c865005855253af4f68a497John McCall = variable->getType().getObjCLifetime()) { 356f85e193739c953358c865005855253af4f68a497John McCall switch (lifetime) { 357f85e193739c953358c865005855253af4f68a497John McCall case Qualifiers::OCL_None: llvm_unreachable("impossible"); 358f85e193739c953358c865005855253af4f68a497John McCall case Qualifiers::OCL_ExplicitNone: 359f85e193739c953358c865005855253af4f68a497John McCall case Qualifiers::OCL_Autoreleasing: 360f85e193739c953358c865005855253af4f68a497John McCall break; 361f85e193739c953358c865005855253af4f68a497John McCall 362f85e193739c953358c865005855253af4f68a497John McCall case Qualifiers::OCL_Strong: 363f85e193739c953358c865005855253af4f68a497John McCall case Qualifiers::OCL_Weak: 364f85e193739c953358c865005855253af4f68a497John McCall info.NeedsCopyDispose = true; 365f85e193739c953358c865005855253af4f68a497John McCall } 3666b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 367f85e193739c953358c865005855253af4f68a497John McCall // Block pointers require copy/dispose. So do Objective-C pointers. 368f85e193739c953358c865005855253af4f68a497John McCall } else if (variable->getType()->isObjCRetainableType()) { 3696b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall info.NeedsCopyDispose = true; 3706b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 3716b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // So do types that require non-trivial copy construction. 3726b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall } else if (ci->hasCopyExpr()) { 3736b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall info.NeedsCopyDispose = true; 3746b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall info.HasCXXObject = true; 3756b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 3766b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // And so do types with destructors. 3774e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie } else if (CGM.getLangOpts().CPlusPlus) { 3786b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall if (const CXXRecordDecl *record = 3796b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall variable->getType()->getAsCXXRecordDecl()) { 3806b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall if (!record->hasTrivialDestructor()) { 3816b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall info.HasCXXObject = true; 3826b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall info.NeedsCopyDispose = true; 383ea1471e0e967548c596a71469702f8846dbaf3c0John McCall } 384f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall } 3856b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall } 3866b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 387c637d738897b1745af3bad7fc551f26b98da838cFariborz Jahanian QualType VT = variable->getType(); 388d8c4551fa22a9c346e6a9e56333915197c97e394Fariborz Jahanian CharUnits size = C.getTypeSizeInChars(VT); 389c637d738897b1745af3bad7fc551f26b98da838cFariborz Jahanian CharUnits align = C.getDeclAlign(variable); 390d8c4551fa22a9c346e6a9e56333915197c97e394Fariborz Jahanian 3916b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall maxFieldAlign = std::max(maxFieldAlign, align); 3926b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 393ef6de3da8572607f786303c07150daa6e140ab19Jay Foad llvm::Type *llvmType = 394d8c4551fa22a9c346e6a9e56333915197c97e394Fariborz Jahanian CGM.getTypes().ConvertTypeForMem(VT); 395d8c4551fa22a9c346e6a9e56333915197c97e394Fariborz Jahanian 3966b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall layout.push_back(BlockLayoutChunk(align, size, &*ci, llvmType)); 3976b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall } 398ea1471e0e967548c596a71469702f8846dbaf3c0John McCall 3996b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // If that was everything, we're done here. 4006b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall if (layout.empty()) { 4016b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall info.StructureType = 4026b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall llvm::StructType::get(CGM.getLLVMContext(), elementTypes, true); 4036b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall info.CanBeGlobal = true; 4046b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall return; 4056b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall } 4066b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 4076b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // Sort the layout by alignment. We have to use a stable sort here 4086b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // to get reproducible results. There should probably be an 4096b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // llvm::array_pod_stable_sort. 4106b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall std::stable_sort(layout.begin(), layout.end()); 4116b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 4126b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall CharUnits &blockSize = info.BlockSize; 4136b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall info.BlockAlign = std::max(maxFieldAlign, info.BlockAlign); 4146b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 4156b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // Assuming that the first byte in the header is maximally aligned, 4166b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // get the alignment of the first byte following the header. 4176b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall CharUnits endAlign = getLowBit(blockSize); 4186b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 4196b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // If the end of the header isn't satisfactorily aligned for the 4206b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // maximum thing, look for things that are okay with the header-end 4216b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // alignment, and keep appending them until we get something that's 4226b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // aligned right. This algorithm is only guaranteed optimal if 4236b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // that condition is satisfied at some point; otherwise we can get 4246b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // things like: 4256b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // header // next byte has alignment 4 4266b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // something_with_size_5; // next byte has alignment 1 4276b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // something_with_alignment_8; 4286b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // which has 7 bytes of padding, as opposed to the naive solution 4296b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // which might have less (?). 4306b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall if (endAlign < maxFieldAlign) { 4315f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVectorImpl<BlockLayoutChunk>::iterator 4326b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall li = layout.begin() + 1, le = layout.end(); 4336b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 4346b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // Look for something that the header end is already 4356b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // satisfactorily aligned for. 4366b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall for (; li != le && endAlign < li->Alignment; ++li) 4376b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall ; 4386b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 4396b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // If we found something that's naturally aligned for the end of 4406b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // the header, keep adding things... 4416b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall if (li != le) { 4425f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVectorImpl<BlockLayoutChunk>::iterator first = li; 4436b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall for (; li != le; ++li) { 4446b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall assert(endAlign >= li->Alignment); 4456b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 4466b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall li->setIndex(info, elementTypes.size()); 4476b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall elementTypes.push_back(li->Type); 4486b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall blockSize += li->Size; 4496b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall endAlign = getLowBit(blockSize); 4506b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 4516b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // ...until we get to the alignment of the maximum field. 4526b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall if (endAlign >= maxFieldAlign) 4536b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall break; 4548a2b4b1c5b960710db95e9b296d9a600aee37c00Mike Stump } 455ea1471e0e967548c596a71469702f8846dbaf3c0John McCall 4566b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // Don't re-append everything we just appended. 4576b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall layout.erase(first, li); 4586b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall } 4596b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall } 4606b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 4616ea4841da1390b4f76d066f25333f11f6d8c5f40John McCall assert(endAlign == getLowBit(blockSize)); 4626ea4841da1390b4f76d066f25333f11f6d8c5f40John McCall 4636b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // At this point, we just have to add padding if the end align still 4646b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // isn't aligned right. 4656b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall if (endAlign < maxFieldAlign) { 4666ea4841da1390b4f76d066f25333f11f6d8c5f40John McCall CharUnits newBlockSize = blockSize.RoundUpToAlignment(maxFieldAlign); 4676ea4841da1390b4f76d066f25333f11f6d8c5f40John McCall CharUnits padding = newBlockSize - blockSize; 4686b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 4695936e33bf74dd6bf126ceee0f6169a2593d03a69John McCall elementTypes.push_back(llvm::ArrayType::get(CGM.Int8Ty, 4705936e33bf74dd6bf126ceee0f6169a2593d03a69John McCall padding.getQuantity())); 4716ea4841da1390b4f76d066f25333f11f6d8c5f40John McCall blockSize = newBlockSize; 4726c803f7f46533c69e2f8a9a882af9ae3b7fffb6fJohn McCall endAlign = getLowBit(blockSize); // might be > maxFieldAlign 4736b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall } 4746b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 4756c803f7f46533c69e2f8a9a882af9ae3b7fffb6fJohn McCall assert(endAlign >= maxFieldAlign); 4766ea4841da1390b4f76d066f25333f11f6d8c5f40John McCall assert(endAlign == getLowBit(blockSize)); 4776ea4841da1390b4f76d066f25333f11f6d8c5f40John McCall 4786b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // Slam everything else on now. This works because they have 4796b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // strictly decreasing alignment and we expect that size is always a 4806b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // multiple of alignment. 4815f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner for (SmallVectorImpl<BlockLayoutChunk>::iterator 4826b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall li = layout.begin(), le = layout.end(); li != le; ++li) { 4836b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall assert(endAlign >= li->Alignment); 4846b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall li->setIndex(info, elementTypes.size()); 4856b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall elementTypes.push_back(li->Type); 4866b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall blockSize += li->Size; 4876b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall endAlign = getLowBit(blockSize); 4886b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall } 4896b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 4906b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall info.StructureType = 4916b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall llvm::StructType::get(CGM.getLLVMContext(), elementTypes, true); 4926b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall} 4936b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 4941a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall/// Enter the scope of a block. This should be run at the entrance to 4951a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall/// a full-expression so that the block's cleanups are pushed at the 4961a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall/// right place in the stack. 4971a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCallstatic void enterBlockScope(CodeGenFunction &CGF, BlockDecl *block) { 49838baeabb253f3e04d5b54bf834dbd9f5ebdc9e5cJohn McCall assert(CGF.HaveInsertPoint()); 49938baeabb253f3e04d5b54bf834dbd9f5ebdc9e5cJohn McCall 5001a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall // Allocate the block info and place it at the head of the list. 5011a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall CGBlockInfo &blockInfo = 5021a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall *new CGBlockInfo(block, CGF.CurFn->getName()); 5031a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall blockInfo.NextBlockInfo = CGF.FirstBlockInfo; 5041a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall CGF.FirstBlockInfo = &blockInfo; 5051a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall 5061a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall // Compute information about the layout, etc., of this block, 5071a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall // pushing cleanups as necessary. 5082d6a5670465cb3f1d811695a9f23e372508240d2Richard Smith computeBlockInfo(CGF.CGM, &CGF, blockInfo); 5091a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall 5101a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall // Nothing else to do if it can be global. 5111a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall if (blockInfo.CanBeGlobal) return; 5121a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall 5131a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall // Make the allocation for the block. 5141a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall blockInfo.Address = 5151a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall CGF.CreateTempAlloca(blockInfo.StructureType, "block"); 5161a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall blockInfo.Address->setAlignment(blockInfo.BlockAlign.getQuantity()); 5171a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall 5181a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall // If there are cleanups to emit, enter them (but inactive). 5191a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall if (!blockInfo.NeedsCopyDispose) return; 5201a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall 5211a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall // Walk through the captures (in order) and find the ones not 5221a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall // captured by constant. 5231a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall for (BlockDecl::capture_const_iterator ci = block->capture_begin(), 5241a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall ce = block->capture_end(); ci != ce; ++ci) { 5251a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall // Ignore __block captures; there's nothing special in the 5261a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall // on-stack block that we need to do for them. 5271a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall if (ci->isByRef()) continue; 5281a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall 5291a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall // Ignore variables that are constant-captured. 5301a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall const VarDecl *variable = ci->getVariable(); 5311a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall CGBlockInfo::Capture &capture = blockInfo.getCapture(variable); 5321a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall if (capture.isConstant()) continue; 5331a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall 5341a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall // Ignore objects that aren't destructed. 5351a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall QualType::DestructionKind dtorKind = 5361a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall variable->getType().isDestructedType(); 5371a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall if (dtorKind == QualType::DK_none) continue; 5381a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall 5391a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall CodeGenFunction::Destroyer *destroyer; 5401a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall 5411a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall // Block captures count as local values and have imprecise semantics. 5421a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall // They also can't be arrays, so need to worry about that. 5431a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall if (dtorKind == QualType::DK_objc_strong_lifetime) { 544516bbd42e62d709013824d6fb8445a0cfda3129aPeter Collingbourne destroyer = CodeGenFunction::destroyARCStrongImprecise; 5451a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall } else { 546516bbd42e62d709013824d6fb8445a0cfda3129aPeter Collingbourne destroyer = CGF.getDestroyer(dtorKind); 5471a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall } 5481a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall 5491a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall // GEP down to the address. 5501a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall llvm::Value *addr = CGF.Builder.CreateStructGEP(blockInfo.Address, 5511a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall capture.getIndex()); 5521a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall 5536f103ba42cb69d50005a977c5ea583984ab63fc4John McCall // We can use that GEP as the dominating IP. 5546f103ba42cb69d50005a977c5ea583984ab63fc4John McCall if (!blockInfo.DominatingIP) 5556f103ba42cb69d50005a977c5ea583984ab63fc4John McCall blockInfo.DominatingIP = cast<llvm::Instruction>(addr); 5566f103ba42cb69d50005a977c5ea583984ab63fc4John McCall 5571a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall CleanupKind cleanupKind = InactiveNormalCleanup; 5581a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall bool useArrayEHCleanup = CGF.needsEHCleanup(dtorKind); 5591a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall if (useArrayEHCleanup) 5601a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall cleanupKind = InactiveNormalAndEHCleanup; 5611a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall 5621a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall CGF.pushDestroy(cleanupKind, addr, variable->getType(), 563516bbd42e62d709013824d6fb8445a0cfda3129aPeter Collingbourne destroyer, useArrayEHCleanup); 5641a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall 5651a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall // Remember where that cleanup was. 5661a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall capture.setCleanup(CGF.EHStack.stable_begin()); 5671a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall } 5681a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall} 5691a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall 5701a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall/// Enter a full-expression with a non-trivial number of objects to 5711a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall/// clean up. This is in this file because, at the moment, the only 5721a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall/// kind of cleanup object is a BlockDecl*. 5731a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCallvoid CodeGenFunction::enterNonTrivialFullExpression(const ExprWithCleanups *E) { 5741a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall assert(E->getNumObjects() != 0); 5751a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall ArrayRef<ExprWithCleanups::CleanupObject> cleanups = E->getObjects(); 5761a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall for (ArrayRef<ExprWithCleanups::CleanupObject>::iterator 5771a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall i = cleanups.begin(), e = cleanups.end(); i != e; ++i) { 5781a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall enterBlockScope(*this, *i); 5791a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall } 5801a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall} 5811a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall 5821a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall/// Find the layout for the given block in a linked list and remove it. 5831a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCallstatic CGBlockInfo *findAndRemoveBlockInfo(CGBlockInfo **head, 5841a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall const BlockDecl *block) { 5851a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall while (true) { 5861a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall assert(head && *head); 5871a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall CGBlockInfo *cur = *head; 5881a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall 5891a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall // If this is the block we're looking for, splice it out of the list. 5901a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall if (cur->getBlockDecl() == block) { 5911a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall *head = cur->NextBlockInfo; 5921a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall return cur; 5931a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall } 5941a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall 5951a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall head = &cur->NextBlockInfo; 5961a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall } 5971a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall} 5981a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall 5991a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall/// Destroy a chain of block layouts. 6001a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCallvoid CodeGenFunction::destroyBlockInfos(CGBlockInfo *head) { 6011a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall assert(head && "destroying an empty chain"); 6021a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall do { 6031a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall CGBlockInfo *cur = head; 6041a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall head = cur->NextBlockInfo; 6051a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall delete cur; 6061a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall } while (head != 0); 6071a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall} 6081a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall 6096b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall/// Emit a block literal expression in the current function. 6106b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCallllvm::Value *CodeGenFunction::EmitBlockLiteral(const BlockExpr *blockExpr) { 6111a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall // If the block has no captures, we won't have a pre-computed 6121a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall // layout for it. 6131a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall if (!blockExpr->getBlockDecl()->hasCaptures()) { 6141a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall CGBlockInfo blockInfo(blockExpr->getBlockDecl(), CurFn->getName()); 6152d6a5670465cb3f1d811695a9f23e372508240d2Richard Smith computeBlockInfo(CGM, this, blockInfo); 6161a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall blockInfo.BlockExpression = blockExpr; 6171a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall return EmitBlockLiteral(blockInfo); 6181a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall } 6196b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 6201a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall // Find the block info for this block and take ownership of it. 6216f42b62b6194f53bcbc349f5d17388e1936535d7Dylan Noblesmith OwningPtr<CGBlockInfo> blockInfo; 6221a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall blockInfo.reset(findAndRemoveBlockInfo(&FirstBlockInfo, 6231a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall blockExpr->getBlockDecl())); 6246b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 6251a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall blockInfo->BlockExpression = blockExpr; 6261a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall return EmitBlockLiteral(*blockInfo); 6271a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall} 6281a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall 6291a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCallllvm::Value *CodeGenFunction::EmitBlockLiteral(const CGBlockInfo &blockInfo) { 6301a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall // Using the computed layout, generate the actual block function. 63123f0267e2d56c0407f12e62df3561ecf75d74e6eEli Friedman bool isLambdaConv = blockInfo.getBlockDecl()->isConversionFromLambda(); 6326b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall llvm::Constant *blockFn 6336b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall = CodeGenFunction(CGM).GenerateBlockFunction(CurGD, blockInfo, 63464bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman CurFuncDecl, LocalDeclMap, 63523f0267e2d56c0407f12e62df3561ecf75d74e6eEli Friedman isLambdaConv); 6365936e33bf74dd6bf126ceee0f6169a2593d03a69John McCall blockFn = llvm::ConstantExpr::getBitCast(blockFn, VoidPtrTy); 6376b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 6386b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // If there is nothing to capture, we can emit this as a global block. 6396b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall if (blockInfo.CanBeGlobal) 6406b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall return buildGlobalBlock(CGM, blockInfo, blockFn); 6416b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 6426b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // Otherwise, we have to emit this as a local block. 6436b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 6446b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall llvm::Constant *isa = CGM.getNSConcreteStackBlock(); 6455936e33bf74dd6bf126ceee0f6169a2593d03a69John McCall isa = llvm::ConstantExpr::getBitCast(isa, VoidPtrTy); 6466b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 6476b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // Build the block descriptor. 6486b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall llvm::Constant *descriptor = buildBlockDescriptor(CGM, blockInfo); 6496b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 6501a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall llvm::AllocaInst *blockAddr = blockInfo.Address; 6511a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall assert(blockAddr && "block has no address!"); 6526b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 6536b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // Compute the initial on-stack block flags. 654d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall BlockFlags flags = BLOCK_HAS_SIGNATURE; 6556b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall if (blockInfo.NeedsCopyDispose) flags |= BLOCK_HAS_COPY_DISPOSE; 6566b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall if (blockInfo.HasCXXObject) flags |= BLOCK_HAS_CXX_OBJ; 65764cd2328ef55735c910d3d51dd40eafc38d7a504John McCall if (blockInfo.UsesStret) flags |= BLOCK_USE_STRET; 6586b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 6596b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // Initialize the block literal. 6606b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall Builder.CreateStore(isa, Builder.CreateStructGEP(blockAddr, 0, "block.isa")); 6611a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall Builder.CreateStore(llvm::ConstantInt::get(IntTy, flags.getBitMask()), 6626b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall Builder.CreateStructGEP(blockAddr, 1, "block.flags")); 6631a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall Builder.CreateStore(llvm::ConstantInt::get(IntTy, 0), 6646b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall Builder.CreateStructGEP(blockAddr, 2, "block.reserved")); 6656b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall Builder.CreateStore(blockFn, Builder.CreateStructGEP(blockAddr, 3, 6666b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall "block.invoke")); 6676b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall Builder.CreateStore(descriptor, Builder.CreateStructGEP(blockAddr, 4, 6686b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall "block.descriptor")); 6696b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 6706b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // Finally, capture all the values into the block. 6716b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall const BlockDecl *blockDecl = blockInfo.getBlockDecl(); 6726b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 6736b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // First, 'this'. 6746b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall if (blockDecl->capturesCXXThis()) { 6756b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall llvm::Value *addr = Builder.CreateStructGEP(blockAddr, 6766b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall blockInfo.CXXThisIndex, 6776b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall "block.captured-this.addr"); 6786b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall Builder.CreateStore(LoadCXXThis(), addr); 6796b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall } 6806b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 6816b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // Next, captured variables. 6826b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall for (BlockDecl::capture_const_iterator ci = blockDecl->capture_begin(), 6836b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall ce = blockDecl->capture_end(); ci != ce; ++ci) { 6846b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall const VarDecl *variable = ci->getVariable(); 6856b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall const CGBlockInfo::Capture &capture = blockInfo.getCapture(variable); 6866b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 6876b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // Ignore constant captures. 6886b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall if (capture.isConstant()) continue; 6896b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 6906b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall QualType type = variable->getType(); 6916b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 6926b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // This will be a [[type]]*, except that a byref entry will just be 6936b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // an i8**. 6946b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall llvm::Value *blockField = 6956b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall Builder.CreateStructGEP(blockAddr, capture.getIndex(), 6966b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall "block.captured"); 6976b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 6986b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // Compute the address of the thing we're going to move into the 6996b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // block literal. 7006b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall llvm::Value *src; 7016b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall if (ci->isNested()) { 7026b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // We need to use the capture from the enclosing block. 7036b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall const CGBlockInfo::Capture &enclosingCapture = 7046b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall BlockInfo->getCapture(variable); 7056b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 7066b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // This is a [[type]]*, except that a byref entry wil just be an i8**. 7076b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall src = Builder.CreateStructGEP(LoadBlockStruct(), 7086b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall enclosingCapture.getIndex(), 7096b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall "block.capture.addr"); 71023f0267e2d56c0407f12e62df3561ecf75d74e6eEli Friedman } else if (blockDecl->isConversionFromLambda()) { 71164bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman // The lambda capture in a lambda's conversion-to-block-pointer is 71223f0267e2d56c0407f12e62df3561ecf75d74e6eEli Friedman // special; we'll simply emit it directly. 71323f0267e2d56c0407f12e62df3561ecf75d74e6eEli Friedman src = 0; 7146b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall } else { 7156b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // This is a [[type]]*. 7166b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall src = LocalDeclMap[variable]; 7176b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall } 7186b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 7196b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // For byrefs, we just write the pointer to the byref struct into 7206b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // the block field. There's no need to chase the forwarding 7216b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // pointer at this point, since we're building something that will 7226b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // live a shorter life than the stack byref anyway. 7236b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall if (ci->isByRef()) { 7245936e33bf74dd6bf126ceee0f6169a2593d03a69John McCall // Get a void* that points to the byref struct. 7256b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall if (ci->isNested()) 7266b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall src = Builder.CreateLoad(src, "byref.capture"); 727ea1471e0e967548c596a71469702f8846dbaf3c0John McCall else 7285936e33bf74dd6bf126ceee0f6169a2593d03a69John McCall src = Builder.CreateBitCast(src, VoidPtrTy); 7296b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 7305936e33bf74dd6bf126ceee0f6169a2593d03a69John McCall // Write that void* into the capture field. 7316b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall Builder.CreateStore(src, blockField); 7326b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 7336b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // If we have a copy constructor, evaluate that into the block field. 7346b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall } else if (const Expr *copyExpr = ci->getCopyExpr()) { 73523f0267e2d56c0407f12e62df3561ecf75d74e6eEli Friedman if (blockDecl->isConversionFromLambda()) { 73623f0267e2d56c0407f12e62df3561ecf75d74e6eEli Friedman // If we have a lambda conversion, emit the expression 73723f0267e2d56c0407f12e62df3561ecf75d74e6eEli Friedman // directly into the block instead. 73823f0267e2d56c0407f12e62df3561ecf75d74e6eEli Friedman CharUnits Align = getContext().getTypeAlignInChars(type); 73923f0267e2d56c0407f12e62df3561ecf75d74e6eEli Friedman AggValueSlot Slot = 74023f0267e2d56c0407f12e62df3561ecf75d74e6eEli Friedman AggValueSlot::forAddr(blockField, Align, Qualifiers(), 74123f0267e2d56c0407f12e62df3561ecf75d74e6eEli Friedman AggValueSlot::IsDestructed, 74223f0267e2d56c0407f12e62df3561ecf75d74e6eEli Friedman AggValueSlot::DoesNotNeedGCBarriers, 743649b4a1a9b5e6f768ca0cb84bd97b00f51083e15Chad Rosier AggValueSlot::IsNotAliased); 74423f0267e2d56c0407f12e62df3561ecf75d74e6eEli Friedman EmitAggExpr(copyExpr, Slot); 74523f0267e2d56c0407f12e62df3561ecf75d74e6eEli Friedman } else { 74623f0267e2d56c0407f12e62df3561ecf75d74e6eEli Friedman EmitSynthesizedCXXCopyCtor(blockField, src, copyExpr); 74723f0267e2d56c0407f12e62df3561ecf75d74e6eEli Friedman } 7486b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 7496b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // If it's a reference variable, copy the reference into the block field. 750c637d738897b1745af3bad7fc551f26b98da838cFariborz Jahanian } else if (type->isReferenceType()) { 7516b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall Builder.CreateStore(Builder.CreateLoad(src, "ref.val"), blockField); 7526b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 7536b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // Otherwise, fake up a POD copy into the block field. 7546b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall } else { 755f85e193739c953358c865005855253af4f68a497John McCall // Fake up a new variable so that EmitScalarInit doesn't think 756f85e193739c953358c865005855253af4f68a497John McCall // we're referring to the variable in its own initializer. 757f85e193739c953358c865005855253af4f68a497John McCall ImplicitParamDecl blockFieldPseudoVar(/*DC*/ 0, SourceLocation(), 758c637d738897b1745af3bad7fc551f26b98da838cFariborz Jahanian /*name*/ 0, type); 759f85e193739c953358c865005855253af4f68a497John McCall 760bb699b07426be017056c2c549ac3ffb488cab6e3John McCall // We use one of these or the other depending on whether the 761bb699b07426be017056c2c549ac3ffb488cab6e3John McCall // reference is nested. 762f4b88a45902af1802a1cb42ba48b1c474474f228John McCall DeclRefExpr declRef(const_cast<VarDecl*>(variable), 763f4b88a45902af1802a1cb42ba48b1c474474f228John McCall /*refersToEnclosing*/ ci->isNested(), type, 764f4b88a45902af1802a1cb42ba48b1c474474f228John McCall VK_LValue, SourceLocation()); 765bb699b07426be017056c2c549ac3ffb488cab6e3John McCall 766c637d738897b1745af3bad7fc551f26b98da838cFariborz Jahanian ImplicitCastExpr l2r(ImplicitCastExpr::OnStack, type, CK_LValueToRValue, 767f4b88a45902af1802a1cb42ba48b1c474474f228John McCall &declRef, VK_RValue); 768a07398ed98ea2b55ad7a505a3aab18aed93b149fJohn McCall EmitExprAsInit(&l2r, &blockFieldPseudoVar, 769c637d738897b1745af3bad7fc551f26b98da838cFariborz Jahanian MakeAddrLValue(blockField, type, 7706da2c716017d5c8530ec99779524491ebc5dadb8Eli Friedman getContext().getDeclAlign(variable)), 771df045200e0220f10bf03de05ca878949e0c40a5aJohn McCall /*captured by init*/ false); 772ea1471e0e967548c596a71469702f8846dbaf3c0John McCall } 7736b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 7741a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall // Activate the cleanup if layout pushed one. 775f85e193739c953358c865005855253af4f68a497John McCall if (!ci->isByRef()) { 7761a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall EHScopeStack::stable_iterator cleanup = capture.getCleanup(); 7771a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall if (cleanup.isValid()) 7786f103ba42cb69d50005a977c5ea583984ab63fc4John McCall ActivateCleanupBlock(cleanup, blockInfo.DominatingIP); 779f85e193739c953358c865005855253af4f68a497John McCall } 780e5fee25e71266712522cff554f25c59b3078a429Mike Stump } 78100470a1c4c44c5ed26bad9a38b4d3904b02d7a28Mike Stump 7826b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // Cast to the converted block-pointer type, which happens (somewhat 7836b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // unfortunately) to be a pointer to function type. 7846b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall llvm::Value *result = 7856b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall Builder.CreateBitCast(blockAddr, 7866b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall ConvertType(blockInfo.getBlockExpr()->getType())); 787711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 7886b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall return result; 789e5fee25e71266712522cff554f25c59b3078a429Mike Stump} 790e5fee25e71266712522cff554f25c59b3078a429Mike Stump 791e5fee25e71266712522cff554f25c59b3078a429Mike Stump 7929cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattnerllvm::Type *CodeGenModule::getBlockDescriptorType() { 793ab695143861b520f5c9f8f982534a71d355396f1Mike Stump if (BlockDescriptorType) 794ab695143861b520f5c9f8f982534a71d355396f1Mike Stump return BlockDescriptorType; 795ab695143861b520f5c9f8f982534a71d355396f1Mike Stump 7969cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *UnsignedLongTy = 797ab695143861b520f5c9f8f982534a71d355396f1Mike Stump getTypes().ConvertType(getContext().UnsignedLongTy); 798a5448544eea6663f8dce30a50343ef5125559794Mike Stump 799ab695143861b520f5c9f8f982534a71d355396f1Mike Stump // struct __block_descriptor { 800ab695143861b520f5c9f8f982534a71d355396f1Mike Stump // unsigned long reserved; 801ab695143861b520f5c9f8f982534a71d355396f1Mike Stump // unsigned long block_size; 8022a7eb28397148079cbc8e54e8a3871ef01c4f4bcBlaine Garst // 8032a7eb28397148079cbc8e54e8a3871ef01c4f4bcBlaine Garst // // later, the following will be added 8042a7eb28397148079cbc8e54e8a3871ef01c4f4bcBlaine Garst // 8052a7eb28397148079cbc8e54e8a3871ef01c4f4bcBlaine Garst // struct { 8062a7eb28397148079cbc8e54e8a3871ef01c4f4bcBlaine Garst // void (*copyHelper)(); 8072a7eb28397148079cbc8e54e8a3871ef01c4f4bcBlaine Garst // void (*copyHelper)(); 8082a7eb28397148079cbc8e54e8a3871ef01c4f4bcBlaine Garst // } helpers; // !!! optional 8092a7eb28397148079cbc8e54e8a3871ef01c4f4bcBlaine Garst // 8102a7eb28397148079cbc8e54e8a3871ef01c4f4bcBlaine Garst // const char *signature; // the block signature 8112a7eb28397148079cbc8e54e8a3871ef01c4f4bcBlaine Garst // const char *layout; // reserved 812ab695143861b520f5c9f8f982534a71d355396f1Mike Stump // }; 8137650d95a1a616ea300f37126a8dfc93dc19a662aChris Lattner BlockDescriptorType = 814c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner llvm::StructType::create("struct.__block_descriptor", 815c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner UnsignedLongTy, UnsignedLongTy, NULL); 816ab695143861b520f5c9f8f982534a71d355396f1Mike Stump 8176b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // Now form a pointer to that. 8186b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall BlockDescriptorType = llvm::PointerType::getUnqual(BlockDescriptorType); 819ab695143861b520f5c9f8f982534a71d355396f1Mike Stump return BlockDescriptorType; 820acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson} 821acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson 8229cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattnerllvm::Type *CodeGenModule::getGenericBlockLiteralType() { 8239b8a7977109604d573b49d517e98badbbb9d5ac7Mike Stump if (GenericBlockLiteralType) 8249b8a7977109604d573b49d517e98badbbb9d5ac7Mike Stump return GenericBlockLiteralType; 8259b8a7977109604d573b49d517e98badbbb9d5ac7Mike Stump 8269cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *BlockDescPtrTy = getBlockDescriptorType(); 827a5448544eea6663f8dce30a50343ef5125559794Mike Stump 8289b8a7977109604d573b49d517e98badbbb9d5ac7Mike Stump // struct __block_literal_generic { 829bd65cac8de63d108a681035782a71d42954b03abMike Stump // void *__isa; 830bd65cac8de63d108a681035782a71d42954b03abMike Stump // int __flags; 831bd65cac8de63d108a681035782a71d42954b03abMike Stump // int __reserved; 832bd65cac8de63d108a681035782a71d42954b03abMike Stump // void (*__invoke)(void *); 833bd65cac8de63d108a681035782a71d42954b03abMike Stump // struct __block_descriptor *__descriptor; 8349b8a7977109604d573b49d517e98badbbb9d5ac7Mike Stump // }; 8359cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner GenericBlockLiteralType = 836c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner llvm::StructType::create("struct.__block_literal_generic", 837c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner VoidPtrTy, IntTy, IntTy, VoidPtrTy, 838c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner BlockDescPtrTy, NULL); 839a5448544eea6663f8dce30a50343ef5125559794Mike Stump 8409b8a7977109604d573b49d517e98badbbb9d5ac7Mike Stump return GenericBlockLiteralType; 841acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson} 842acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson 843bd65cac8de63d108a681035782a71d42954b03abMike Stump 844a1736c0c750d4514a5d8fda36670addf1e4de54aAnders CarlssonRValue CodeGenFunction::EmitBlockCallExpr(const CallExpr* E, 845a1736c0c750d4514a5d8fda36670addf1e4de54aAnders Carlsson ReturnValueSlot ReturnValue) { 846a5448544eea6663f8dce30a50343ef5125559794Mike Stump const BlockPointerType *BPT = 8476217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek E->getCallee()->getType()->getAs<BlockPointerType>(); 848a5448544eea6663f8dce30a50343ef5125559794Mike Stump 849acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson llvm::Value *Callee = EmitScalarExpr(E->getCallee()); 850acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson 851acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson // Get a pointer to the generic block literal. 8522acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *BlockLiteralTy = 85396e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson llvm::PointerType::getUnqual(CGM.getGenericBlockLiteralType()); 854acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson 855acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson // Bitcast the callee to a block literal. 856a5448544eea6663f8dce30a50343ef5125559794Mike Stump llvm::Value *BlockLiteral = 857acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson Builder.CreateBitCast(Callee, BlockLiteralTy, "block.literal"); 858acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson 859acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson // Get the function pointer from the literal. 860578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer llvm::Value *FuncPtr = Builder.CreateStructGEP(BlockLiteral, 3); 861acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson 862578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer BlockLiteral = Builder.CreateBitCast(BlockLiteral, VoidPtrTy); 863a5448544eea6663f8dce30a50343ef5125559794Mike Stump 864acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson // Add the block literal. 865acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson CallArgList Args; 8660774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall Args.add(RValue::get(BlockLiteral), getContext().VoidPtrTy); 867a5448544eea6663f8dce30a50343ef5125559794Mike Stump 868782f397c1459ef7d8b910c0fb6b95c5f1c19c14fAnders Carlsson QualType FnType = BPT->getPointeeType(); 869782f397c1459ef7d8b910c0fb6b95c5f1c19c14fAnders Carlsson 870acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson // And the rest of the arguments. 871183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall EmitCallArgs(Args, FnType->getAs<FunctionProtoType>(), 872782f397c1459ef7d8b910c0fb6b95c5f1c19c14fAnders Carlsson E->arg_begin(), E->arg_end()); 873a5448544eea6663f8dce30a50343ef5125559794Mike Stump 8746e460ff03f984d34d6f3ba7f191380b823b6062fAnders Carlsson // Load the function. 875578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer llvm::Value *Func = Builder.CreateLoad(FuncPtr); 8766e460ff03f984d34d6f3ba7f191380b823b6062fAnders Carlsson 87764cd2328ef55735c910d3d51dd40eafc38d7a504John McCall const FunctionType *FuncTy = FnType->castAs<FunctionType>(); 878de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall const CGFunctionInfo &FnInfo = 879de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall CGM.getTypes().arrangeFunctionCall(Args, FuncTy); 8801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 8816e460ff03f984d34d6f3ba7f191380b823b6062fAnders Carlsson // Cast the function pointer to the right type. 882de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall llvm::Type *BlockFTy = CGM.getTypes().GetFunctionType(FnInfo); 8831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 8842acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *BlockFTyPtr = llvm::PointerType::getUnqual(BlockFTy); 8856e460ff03f984d34d6f3ba7f191380b823b6062fAnders Carlsson Func = Builder.CreateBitCast(Func, BlockFTyPtr); 8861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 887acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson // And call the block. 888a1736c0c750d4514a5d8fda36670addf1e4de54aAnders Carlsson return EmitCall(FnInfo, Func, ReturnValue, Args); 889acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson} 890d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson 8916b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCallllvm::Value *CodeGenFunction::GetAddrOfBlockDecl(const VarDecl *variable, 8926b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall bool isByRef) { 8936b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall assert(BlockInfo && "evaluating block ref without block information?"); 8946b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall const CGBlockInfo::Capture &capture = BlockInfo->getCapture(variable); 895ea1471e0e967548c596a71469702f8846dbaf3c0John McCall 8966b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // Handle constant captures. 8976b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall if (capture.isConstant()) return LocalDeclMap[variable]; 898ea1471e0e967548c596a71469702f8846dbaf3c0John McCall 8996b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall llvm::Value *addr = 9006b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall Builder.CreateStructGEP(LoadBlockStruct(), capture.getIndex(), 9016b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall "block.capture.addr"); 902ea1471e0e967548c596a71469702f8846dbaf3c0John McCall 9036b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall if (isByRef) { 9046b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // addr should be a void** right now. Load, then cast the result 9056b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // to byref*. 906dab514fc30242c7afd6c03956e46136c400fb0d3Mike Stump 9076b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall addr = Builder.CreateLoad(addr); 9082acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::PointerType *byrefPointerType 9096b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall = llvm::PointerType::get(BuildByRefType(variable), 0); 9106b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall addr = Builder.CreateBitCast(addr, byrefPointerType, 9116b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall "byref.addr"); 912ea26cb522e88fc86b0d1cae61dcefcfe4cc20231Mike Stump 9136b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // Follow the forwarding pointer. 9146b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall addr = Builder.CreateStructGEP(addr, 1, "byref.forwarding"); 9156b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall addr = Builder.CreateLoad(addr, "byref.addr.forwarded"); 916ea1471e0e967548c596a71469702f8846dbaf3c0John McCall 9176b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // Cast back to byref* and GEP over to the actual object. 9186b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall addr = Builder.CreateBitCast(addr, byrefPointerType); 9196b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall addr = Builder.CreateStructGEP(addr, getByRefValueLLVMField(variable), 9206b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall variable->getNameAsString()); 921ea1471e0e967548c596a71469702f8846dbaf3c0John McCall } 922ea26cb522e88fc86b0d1cae61dcefcfe4cc20231Mike Stump 923c637d738897b1745af3bad7fc551f26b98da838cFariborz Jahanian if (variable->getType()->isReferenceType()) 9246b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall addr = Builder.CreateLoad(addr, "ref.tmp"); 925ea26cb522e88fc86b0d1cae61dcefcfe4cc20231Mike Stump 9266b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall return addr; 927dab514fc30242c7afd6c03956e46136c400fb0d3Mike Stump} 928dab514fc30242c7afd6c03956e46136c400fb0d3Mike Stump 92967a6448a8d52ae46d1cba4e474f9f6b3968d2ff9Mike Stumpllvm::Constant * 930d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCallCodeGenModule::GetAddrOfGlobalBlock(const BlockExpr *blockExpr, 9315936e33bf74dd6bf126ceee0f6169a2593d03a69John McCall const char *name) { 9321a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall CGBlockInfo blockInfo(blockExpr->getBlockDecl(), name); 9331a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall blockInfo.BlockExpression = blockExpr; 934a5448544eea6663f8dce30a50343ef5125559794Mike Stump 9356b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // Compute information about the layout, etc., of this block. 9362d6a5670465cb3f1d811695a9f23e372508240d2Richard Smith computeBlockInfo(*this, 0, blockInfo); 9372a7eb28397148079cbc8e54e8a3871ef01c4f4bcBlaine Garst 9386b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // Using that metadata, generate the actual block function. 9396b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall llvm::Constant *blockFn; 9406b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall { 9416b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall llvm::DenseMap<const Decl*, llvm::Value*> LocalDeclMap; 942d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall blockFn = CodeGenFunction(*this).GenerateBlockFunction(GlobalDecl(), 943d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall blockInfo, 94464bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman 0, LocalDeclMap, 94564bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman false); 9466b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall } 9475936e33bf74dd6bf126ceee0f6169a2593d03a69John McCall blockFn = llvm::ConstantExpr::getBitCast(blockFn, VoidPtrTy); 948a5448544eea6663f8dce30a50343ef5125559794Mike Stump 949d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall return buildGlobalBlock(*this, blockInfo, blockFn); 9506b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall} 9515e530af5d51572a0ed5dbe50da54bd333840c63dDavid Chisnall 9526b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCallstatic llvm::Constant *buildGlobalBlock(CodeGenModule &CGM, 9536b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall const CGBlockInfo &blockInfo, 9546b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall llvm::Constant *blockFn) { 9556b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall assert(blockInfo.CanBeGlobal); 956a5448544eea6663f8dce30a50343ef5125559794Mike Stump 9576b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // Generate the constants for the block literal initializer. 9586b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall llvm::Constant *fields[BlockHeaderSize]; 959a5448544eea6663f8dce30a50343ef5125559794Mike Stump 960d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson // isa 9616b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall fields[0] = CGM.getNSConcreteGlobalBlock(); 962a5448544eea6663f8dce30a50343ef5125559794Mike Stump 9637edddb896e10d7ab494927842f7402583d9fa02dFariborz Jahanian // __flags 96464cd2328ef55735c910d3d51dd40eafc38d7a504John McCall BlockFlags flags = BLOCK_IS_GLOBAL | BLOCK_HAS_SIGNATURE; 96564cd2328ef55735c910d3d51dd40eafc38d7a504John McCall if (blockInfo.UsesStret) flags |= BLOCK_USE_STRET; 96664cd2328ef55735c910d3d51dd40eafc38d7a504John McCall 9675936e33bf74dd6bf126ceee0f6169a2593d03a69John McCall fields[1] = llvm::ConstantInt::get(CGM.IntTy, flags.getBitMask()); 968a5448544eea6663f8dce30a50343ef5125559794Mike Stump 969d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson // Reserved 9705936e33bf74dd6bf126ceee0f6169a2593d03a69John McCall fields[2] = llvm::Constant::getNullValue(CGM.IntTy); 971a5448544eea6663f8dce30a50343ef5125559794Mike Stump 972d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson // Function 9736b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall fields[3] = blockFn; 974a5448544eea6663f8dce30a50343ef5125559794Mike Stump 975d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson // Descriptor 9766b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall fields[4] = buildBlockDescriptor(CGM, blockInfo); 977a5448544eea6663f8dce30a50343ef5125559794Mike Stump 978c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner llvm::Constant *init = llvm::ConstantStruct::getAnon(fields); 979d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson 9806b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall llvm::GlobalVariable *literal = 9816b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall new llvm::GlobalVariable(CGM.getModule(), 9826b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall init->getType(), 9836b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall /*constant*/ true, 9846b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall llvm::GlobalVariable::InternalLinkage, 9856b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall init, 9866b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall "__block_literal_global"); 9876b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall literal->setAlignment(blockInfo.BlockAlign.getQuantity()); 9886b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 9896b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // Return a constant of the appropriately-casted type. 9902acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *requiredType = 9916b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall CGM.getTypes().ConvertType(blockInfo.getBlockExpr()->getType()); 9926b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall return llvm::ConstantExpr::getBitCast(literal, requiredType); 9934e7a1f7682d94811bd41fca8aefccc38f686db23Mike Stump} 9944e7a1f7682d94811bd41fca8aefccc38f686db23Mike Stump 99500470a1c4c44c5ed26bad9a38b4d3904b02d7a28Mike Stumpllvm::Function * 9966b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCallCodeGenFunction::GenerateBlockFunction(GlobalDecl GD, 9976b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall const CGBlockInfo &blockInfo, 9986b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall const Decl *outerFnDecl, 99964bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman const DeclMapTy &ldm, 100064bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman bool IsLambdaConversionToBlock) { 10016b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall const BlockDecl *blockDecl = blockInfo.getBlockDecl(); 1002963dfbde17a28bc88ee1647bc85fd8407bfc9555Devang Patel 10036d1155be2aca28659a47fbe612222845811ff2a3Devang Patel // Check if we should generate debug info for this block function. 10046d1155be2aca28659a47fbe612222845811ff2a3Devang Patel if (CGM.getModuleDebugInfo()) 10056d1155be2aca28659a47fbe612222845811ff2a3Devang Patel DebugInfo = CGM.getModuleDebugInfo(); 10066d1155be2aca28659a47fbe612222845811ff2a3Devang Patel 10076b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall BlockInfo = &blockInfo; 10081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 10097f28a9c37e67ae16396042ad9c085830969daf29Mike Stump // Arrange for local static and local extern declarations to appear 10106b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // to be local to this function as well, in case they're directly 10116b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // referenced in a block. 10126b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall for (DeclMapTy::const_iterator i = ldm.begin(), e = ldm.end(); i != e; ++i) { 10136b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall const VarDecl *var = dyn_cast<VarDecl>(i->first); 10146b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall if (var && !var->hasLocalStorage()) 10156b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall LocalDeclMap[var] = i->second; 10167f28a9c37e67ae16396042ad9c085830969daf29Mike Stump } 10177f28a9c37e67ae16396042ad9c085830969daf29Mike Stump 10186b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // Begin building the function declaration. 1019a5448544eea6663f8dce30a50343ef5125559794Mike Stump 10206b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // Build the argument list. 10216b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall FunctionArgList args; 1022d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson 10236b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // The first argument is the block pointer. Just take it as a void* 10246b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // and cast it later. 10256b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall QualType selfTy = getContext().VoidPtrTy; 1026ea26cb522e88fc86b0d1cae61dcefcfe4cc20231Mike Stump IdentifierInfo *II = &CGM.getContext().Idents.get(".block_descriptor"); 1027ea26cb522e88fc86b0d1cae61dcefcfe4cc20231Mike Stump 10288178df3b39ab923ff5d24538812628abee33df79John McCall ImplicitParamDecl selfDecl(const_cast<BlockDecl*>(blockDecl), 10298178df3b39ab923ff5d24538812628abee33df79John McCall SourceLocation(), II, selfTy); 1030d26bc76c98006609002d9930f8840490e88ac5b5John McCall args.push_back(&selfDecl); 10316b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 10326b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // Now add the rest of the parameters. 10336b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall for (BlockDecl::param_const_iterator i = blockDecl->param_begin(), 10346b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall e = blockDecl->param_end(); i != e; ++i) 1035d26bc76c98006609002d9930f8840490e88ac5b5John McCall args.push_back(*i); 10366b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 10376b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // Create the function declaration. 1038de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall const FunctionProtoType *fnType = blockInfo.getBlockExpr()->getFunctionType(); 10396b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall const CGFunctionInfo &fnInfo = 1040de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall CGM.getTypes().arrangeFunctionDeclaration(fnType->getResultType(), args, 1041de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall fnType->getExtInfo(), 1042de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall fnType->isVariadic()); 104364cd2328ef55735c910d3d51dd40eafc38d7a504John McCall if (CGM.ReturnTypeUsesSRet(fnInfo)) 104464cd2328ef55735c910d3d51dd40eafc38d7a504John McCall blockInfo.UsesStret = true; 104564cd2328ef55735c910d3d51dd40eafc38d7a504John McCall 1046de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall llvm::FunctionType *fnLLVMType = CGM.getTypes().GetFunctionType(fnInfo); 10476b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 10486b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall MangleBuffer name; 10496b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall CGM.getBlockMangledName(GD, name, blockDecl); 10506b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall llvm::Function *fn = 10516b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall llvm::Function::Create(fnLLVMType, llvm::GlobalValue::InternalLinkage, 10526b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall name.getString(), &CGM.getModule()); 10536b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall CGM.SetInternalFunctionAttributes(blockDecl, fn, fnInfo); 10546b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 10556b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // Begin generating the function. 1056d26bc76c98006609002d9930f8840490e88ac5b5John McCall StartFunction(blockDecl, fnType->getResultType(), fn, fnInfo, args, 10573f4cb252832cf14f72d66ed707316d3759c8a689Devang Patel blockInfo.getBlockExpr()->getBody()->getLocStart()); 10586b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall CurFuncDecl = outerFnDecl; // StartFunction sets this to blockDecl 10596b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 10608178df3b39ab923ff5d24538812628abee33df79John McCall // Okay. Undo some of what StartFunction did. 10618178df3b39ab923ff5d24538812628abee33df79John McCall 10628178df3b39ab923ff5d24538812628abee33df79John McCall // Pull the 'self' reference out of the local decl map. 10638178df3b39ab923ff5d24538812628abee33df79John McCall llvm::Value *blockAddr = LocalDeclMap[&selfDecl]; 10648178df3b39ab923ff5d24538812628abee33df79John McCall LocalDeclMap.erase(&selfDecl); 10656b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall BlockPointer = Builder.CreateBitCast(blockAddr, 10666b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall blockInfo.StructureType->getPointerTo(), 10676b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall "block"); 1068a5448544eea6663f8dce30a50343ef5125559794Mike Stump 10696b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // If we have a C++ 'this' reference, go ahead and force it into 10706b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // existence now. 10716b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall if (blockDecl->capturesCXXThis()) { 10726b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall llvm::Value *addr = Builder.CreateStructGEP(BlockPointer, 10736b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall blockInfo.CXXThisIndex, 10746b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall "block.captured-this"); 10756b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall CXXThisValue = Builder.CreateLoad(addr, "this"); 10766b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall } 1077a5448544eea6663f8dce30a50343ef5125559794Mike Stump 10786b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // LoadObjCSelf() expects there to be an entry for 'self' in LocalDeclMap; 10796b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // appease it. 10806b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall if (const ObjCMethodDecl *method 10816b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall = dyn_cast_or_null<ObjCMethodDecl>(CurFuncDecl)) { 10826b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall const VarDecl *self = method->getSelfDecl(); 10836b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 10846b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // There might not be a capture for 'self', but if there is... 10856b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall if (blockInfo.Captures.count(self)) { 10866b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall const CGBlockInfo::Capture &capture = blockInfo.getCapture(self); 10876b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall llvm::Value *selfAddr = Builder.CreateStructGEP(BlockPointer, 10886b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall capture.getIndex(), 10896b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall "block.captured-self"); 10906b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall LocalDeclMap[self] = selfAddr; 10916b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall } 10926b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall } 1093a5448544eea6663f8dce30a50343ef5125559794Mike Stump 10946b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // Also force all the constant captures. 10956b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall for (BlockDecl::capture_const_iterator ci = blockDecl->capture_begin(), 10966b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall ce = blockDecl->capture_end(); ci != ce; ++ci) { 10976b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall const VarDecl *variable = ci->getVariable(); 10986b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall const CGBlockInfo::Capture &capture = blockInfo.getCapture(variable); 10996b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall if (!capture.isConstant()) continue; 1100d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson 11016b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall unsigned align = getContext().getDeclAlign(variable).getQuantity(); 1102a5448544eea6663f8dce30a50343ef5125559794Mike Stump 11036b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall llvm::AllocaInst *alloca = 11046b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall CreateMemTemp(variable->getType(), "block.captured-const"); 11056b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall alloca->setAlignment(align); 1106a5448544eea6663f8dce30a50343ef5125559794Mike Stump 11076b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall Builder.CreateStore(capture.getConstant(), alloca, align); 1108ea1471e0e967548c596a71469702f8846dbaf3c0John McCall 11096b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall LocalDeclMap[variable] = alloca; 1110ee5042903d53fa7b0fbc1902d0ea07d57c7775b1John McCall } 1111ee5042903d53fa7b0fbc1902d0ea07d57c7775b1John McCall 1112f4b88a45902af1802a1cb42ba48b1c474474f228John McCall // Save a spot to insert the debug information for all the DeclRefExprs. 1113b1a6e687967105bf1e18dfba196d0248e6700a4eMike Stump llvm::BasicBlock *entry = Builder.GetInsertBlock(); 1114b289b3f324eb10d416b87080e39b315f6c17a695Mike Stump llvm::BasicBlock::iterator entry_ptr = Builder.GetInsertPoint(); 1115b289b3f324eb10d416b87080e39b315f6c17a695Mike Stump --entry_ptr; 1116b1a6e687967105bf1e18dfba196d0248e6700a4eMike Stump 111764bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman if (IsLambdaConversionToBlock) 111864bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman EmitLambdaBlockInvokeBody(); 111964bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman else 112064bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman EmitStmt(blockDecl->getBody()); 1121b289b3f324eb10d416b87080e39b315f6c17a695Mike Stump 1122de8c5c77e27b6b0064c45d964ea8bcc2c853114dMike Stump // Remember where we were... 1123de8c5c77e27b6b0064c45d964ea8bcc2c853114dMike Stump llvm::BasicBlock *resume = Builder.GetInsertBlock(); 1124b289b3f324eb10d416b87080e39b315f6c17a695Mike Stump 1125de8c5c77e27b6b0064c45d964ea8bcc2c853114dMike Stump // Go back to the entry. 1126b289b3f324eb10d416b87080e39b315f6c17a695Mike Stump ++entry_ptr; 1127b289b3f324eb10d416b87080e39b315f6c17a695Mike Stump Builder.SetInsertPoint(entry, entry_ptr); 1128b289b3f324eb10d416b87080e39b315f6c17a695Mike Stump 1129f4b88a45902af1802a1cb42ba48b1c474474f228John McCall // Emit debug information for all the DeclRefExprs. 11306b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // FIXME: also for 'this' 1131b1a6e687967105bf1e18dfba196d0248e6700a4eMike Stump if (CGDebugInfo *DI = getDebugInfo()) { 11326b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall for (BlockDecl::capture_const_iterator ci = blockDecl->capture_begin(), 11336b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall ce = blockDecl->capture_end(); ci != ce; ++ci) { 11346b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall const VarDecl *variable = ci->getVariable(); 113573fb35003aad027492e661a3749e921b5d1ecaf9Eric Christopher DI->EmitLocation(Builder, variable->getLocation()); 11366b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 11376b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall const CGBlockInfo::Capture &capture = blockInfo.getCapture(variable); 11386b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall if (capture.isConstant()) { 11396b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall DI->EmitDeclareOfAutoVariable(variable, LocalDeclMap[variable], 11406b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall Builder); 11416b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall continue; 1142b1a6e687967105bf1e18dfba196d0248e6700a4eMike Stump } 11436b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 11448178df3b39ab923ff5d24538812628abee33df79John McCall DI->EmitDeclareOfBlockDeclRefVariable(variable, BlockPointer, 11456b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall Builder, blockInfo); 1146b1a6e687967105bf1e18dfba196d0248e6700a4eMike Stump } 1147b1a6e687967105bf1e18dfba196d0248e6700a4eMike Stump } 11486b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 1149de8c5c77e27b6b0064c45d964ea8bcc2c853114dMike Stump // And resume where we left off. 1150de8c5c77e27b6b0064c45d964ea8bcc2c853114dMike Stump if (resume == 0) 1151de8c5c77e27b6b0064c45d964ea8bcc2c853114dMike Stump Builder.ClearInsertionPoint(); 1152de8c5c77e27b6b0064c45d964ea8bcc2c853114dMike Stump else 1153de8c5c77e27b6b0064c45d964ea8bcc2c853114dMike Stump Builder.SetInsertPoint(resume); 1154b1a6e687967105bf1e18dfba196d0248e6700a4eMike Stump 11556b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall FinishFunction(cast<CompoundStmt>(blockDecl->getBody())->getRBracLoc()); 1156d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson 11576b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall return fn; 1158d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson} 1159a99038c0757a836c6faeeddaa5dfd249b32f6e9eMike Stump 11606b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall/* 11616b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall notes.push_back(HelperInfo()); 11626b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall HelperInfo ¬e = notes.back(); 11636b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall note.index = capture.getIndex(); 11646b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall note.RequiresCopying = (ci->hasCopyExpr() || BlockRequiresCopying(type)); 11656b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall note.cxxbar_import = ci->getCopyExpr(); 11666b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 11676b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall if (ci->isByRef()) { 11686b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall note.flag = BLOCK_FIELD_IS_BYREF; 11696b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall if (type.isObjCGCWeak()) 11706b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall note.flag |= BLOCK_FIELD_IS_WEAK; 11716b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall } else if (type->isBlockPointerType()) { 11726b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall note.flag = BLOCK_FIELD_IS_BLOCK; 11736b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall } else { 11746b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall note.flag = BLOCK_FIELD_IS_OBJECT; 11756b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall } 11766b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall */ 1177a99038c0757a836c6faeeddaa5dfd249b32f6e9eMike Stump 1178dab514fc30242c7afd6c03956e46136c400fb0d3Mike Stump 1179a4f668f3b7e03629066a01b04e415cb2b4655dafMike Stump 11806b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCallllvm::Constant * 1181d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCallCodeGenFunction::GenerateCopyHelperFunction(const CGBlockInfo &blockInfo) { 11826b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall ASTContext &C = getContext(); 11836b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 11846b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall FunctionArgList args; 1185d26bc76c98006609002d9930f8840490e88ac5b5John McCall ImplicitParamDecl dstDecl(0, SourceLocation(), 0, C.VoidPtrTy); 1186d26bc76c98006609002d9930f8840490e88ac5b5John McCall args.push_back(&dstDecl); 1187d26bc76c98006609002d9930f8840490e88ac5b5John McCall ImplicitParamDecl srcDecl(0, SourceLocation(), 0, C.VoidPtrTy); 1188d26bc76c98006609002d9930f8840490e88ac5b5John McCall args.push_back(&srcDecl); 11891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1190a4f668f3b7e03629066a01b04e415cb2b4655dafMike Stump const CGFunctionInfo &FI = 1191de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall CGM.getTypes().arrangeFunctionDeclaration(C.VoidTy, args, 1192de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall FunctionType::ExtInfo(), 1193de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall /*variadic*/ false); 1194a4f668f3b7e03629066a01b04e415cb2b4655dafMike Stump 11956b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // FIXME: it would be nice if these were mergeable with things with 11966b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // identical semantics. 1197de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall llvm::FunctionType *LTy = CGM.getTypes().GetFunctionType(FI); 1198a4f668f3b7e03629066a01b04e415cb2b4655dafMike Stump 1199a4f668f3b7e03629066a01b04e415cb2b4655dafMike Stump llvm::Function *Fn = 1200a4f668f3b7e03629066a01b04e415cb2b4655dafMike Stump llvm::Function::Create(LTy, llvm::GlobalValue::InternalLinkage, 12013cf7c5dc23569ae76bd4bddaed22f696233d8e44Benjamin Kramer "__copy_helper_block_", &CGM.getModule()); 1202a4f668f3b7e03629066a01b04e415cb2b4655dafMike Stump 1203a4f668f3b7e03629066a01b04e415cb2b4655dafMike Stump IdentifierInfo *II 1204a4f668f3b7e03629066a01b04e415cb2b4655dafMike Stump = &CGM.getContext().Idents.get("__copy_helper_block_"); 1205a4f668f3b7e03629066a01b04e415cb2b4655dafMike Stump 120658dc5ca0841900b197de7733197196f435bf0cc3Devang Patel // Check if we should generate debug info for this block helper function. 120758dc5ca0841900b197de7733197196f435bf0cc3Devang Patel if (CGM.getModuleDebugInfo()) 120858dc5ca0841900b197de7733197196f435bf0cc3Devang Patel DebugInfo = CGM.getModuleDebugInfo(); 120958dc5ca0841900b197de7733197196f435bf0cc3Devang Patel 12106b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall FunctionDecl *FD = FunctionDecl::Create(C, 12116b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall C.getTranslationUnitDecl(), 1212ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara SourceLocation(), 12136b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall SourceLocation(), II, C.VoidTy, 0, 1214d931b086984257de68868a64a235c2b4b34003fbJohn McCall SC_Static, 1215d931b086984257de68868a64a235c2b4b34003fbJohn McCall SC_None, 121616573fa9705b546b7597c273b25b85d6321e2b33Douglas Gregor false, 1217e5bbebb4d14347700ff0b1838f14cae3b8a35c69Eric Christopher false); 1218d26bc76c98006609002d9930f8840490e88ac5b5John McCall StartFunction(FD, C.VoidTy, Fn, FI, args, SourceLocation()); 12190892099dbc640720400a1d9decd2733a09d733e5Mike Stump 12202acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *structPtrTy = blockInfo.StructureType->getPointerTo(); 12216b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 1222d26bc76c98006609002d9930f8840490e88ac5b5John McCall llvm::Value *src = GetAddrOfLocalVar(&srcDecl); 1223d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall src = Builder.CreateLoad(src); 1224d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall src = Builder.CreateBitCast(src, structPtrTy, "block.source"); 12256b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 1226d26bc76c98006609002d9930f8840490e88ac5b5John McCall llvm::Value *dst = GetAddrOfLocalVar(&dstDecl); 1227d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall dst = Builder.CreateLoad(dst); 1228d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall dst = Builder.CreateBitCast(dst, structPtrTy, "block.dest"); 12296b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 12306b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall const BlockDecl *blockDecl = blockInfo.getBlockDecl(); 12316b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 12326b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall for (BlockDecl::capture_const_iterator ci = blockDecl->capture_begin(), 12336b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall ce = blockDecl->capture_end(); ci != ce; ++ci) { 12346b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall const VarDecl *variable = ci->getVariable(); 12356b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall QualType type = variable->getType(); 12366b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 12376b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall const CGBlockInfo::Capture &capture = blockInfo.getCapture(variable); 12386b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall if (capture.isConstant()) continue; 12396b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 12406b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall const Expr *copyExpr = ci->getCopyExpr(); 1241f85e193739c953358c865005855253af4f68a497John McCall BlockFieldFlags flags; 1242f85e193739c953358c865005855253af4f68a497John McCall 1243f85e193739c953358c865005855253af4f68a497John McCall bool isARCWeakCapture = false; 12446b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 12456b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall if (copyExpr) { 12466b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall assert(!ci->isByRef()); 12476b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // don't bother computing flags 1248f85e193739c953358c865005855253af4f68a497John McCall 12496b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall } else if (ci->isByRef()) { 12506b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall flags = BLOCK_FIELD_IS_BYREF; 1251f85e193739c953358c865005855253af4f68a497John McCall if (type.isObjCGCWeak()) 1252f85e193739c953358c865005855253af4f68a497John McCall flags |= BLOCK_FIELD_IS_WEAK; 1253f85e193739c953358c865005855253af4f68a497John McCall 1254f85e193739c953358c865005855253af4f68a497John McCall } else if (type->isObjCRetainableType()) { 12556b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall flags = BLOCK_FIELD_IS_OBJECT; 1256f85e193739c953358c865005855253af4f68a497John McCall if (type->isBlockPointerType()) 1257f85e193739c953358c865005855253af4f68a497John McCall flags = BLOCK_FIELD_IS_BLOCK; 12586b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 1259f85e193739c953358c865005855253af4f68a497John McCall // Special rules for ARC captures: 12604e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (getLangOpts().ObjCAutoRefCount) { 1261f85e193739c953358c865005855253af4f68a497John McCall Qualifiers qs = type.getQualifiers(); 1262f85e193739c953358c865005855253af4f68a497John McCall 1263f85e193739c953358c865005855253af4f68a497John McCall // Don't generate special copy logic for a captured object 1264f85e193739c953358c865005855253af4f68a497John McCall // unless it's __strong or __weak. 1265f85e193739c953358c865005855253af4f68a497John McCall if (!qs.hasStrongOrWeakObjCLifetime()) 1266f85e193739c953358c865005855253af4f68a497John McCall continue; 1267f85e193739c953358c865005855253af4f68a497John McCall 1268f85e193739c953358c865005855253af4f68a497John McCall // Support __weak direct captures. 1269f85e193739c953358c865005855253af4f68a497John McCall if (qs.getObjCLifetime() == Qualifiers::OCL_Weak) 1270f85e193739c953358c865005855253af4f68a497John McCall isARCWeakCapture = true; 1271f85e193739c953358c865005855253af4f68a497John McCall } 1272f85e193739c953358c865005855253af4f68a497John McCall } else { 1273f85e193739c953358c865005855253af4f68a497John McCall continue; 1274f85e193739c953358c865005855253af4f68a497John McCall } 12756b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 12766b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall unsigned index = capture.getIndex(); 1277d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall llvm::Value *srcField = Builder.CreateStructGEP(src, index); 1278d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall llvm::Value *dstField = Builder.CreateStructGEP(dst, index); 12796b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 12806b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // If there's an explicit copy expression, we do that. 12816b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall if (copyExpr) { 1282d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall EmitSynthesizedCXXCopyCtor(dstField, srcField, copyExpr); 1283f85e193739c953358c865005855253af4f68a497John McCall } else if (isARCWeakCapture) { 1284f85e193739c953358c865005855253af4f68a497John McCall EmitARCCopyWeak(dstField, srcField); 12856b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall } else { 12866b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall llvm::Value *srcValue = Builder.CreateLoad(srcField, "blockcopy.src"); 12875936e33bf74dd6bf126ceee0f6169a2593d03a69John McCall srcValue = Builder.CreateBitCast(srcValue, VoidPtrTy); 12885936e33bf74dd6bf126ceee0f6169a2593d03a69John McCall llvm::Value *dstAddr = Builder.CreateBitCast(dstField, VoidPtrTy); 12896b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall Builder.CreateCall3(CGM.getBlockObjectAssign(), dstAddr, srcValue, 1290f85e193739c953358c865005855253af4f68a497John McCall llvm::ConstantInt::get(Int32Ty, flags.getBitMask())); 12910892099dbc640720400a1d9decd2733a09d733e5Mike Stump } 12920892099dbc640720400a1d9decd2733a09d733e5Mike Stump } 12930892099dbc640720400a1d9decd2733a09d733e5Mike Stump 1294d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall FinishFunction(); 1295a4f668f3b7e03629066a01b04e415cb2b4655dafMike Stump 12965936e33bf74dd6bf126ceee0f6169a2593d03a69John McCall return llvm::ConstantExpr::getBitCast(Fn, VoidPtrTy); 1297dab514fc30242c7afd6c03956e46136c400fb0d3Mike Stump} 1298dab514fc30242c7afd6c03956e46136c400fb0d3Mike Stump 12996b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCallllvm::Constant * 1300d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCallCodeGenFunction::GenerateDestroyHelperFunction(const CGBlockInfo &blockInfo) { 13016b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall ASTContext &C = getContext(); 1302a4f668f3b7e03629066a01b04e415cb2b4655dafMike Stump 13036b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall FunctionArgList args; 1304d26bc76c98006609002d9930f8840490e88ac5b5John McCall ImplicitParamDecl srcDecl(0, SourceLocation(), 0, C.VoidPtrTy); 1305d26bc76c98006609002d9930f8840490e88ac5b5John McCall args.push_back(&srcDecl); 13061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1307a4f668f3b7e03629066a01b04e415cb2b4655dafMike Stump const CGFunctionInfo &FI = 1308de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall CGM.getTypes().arrangeFunctionDeclaration(C.VoidTy, args, 1309de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall FunctionType::ExtInfo(), 1310de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall /*variadic*/ false); 1311a4f668f3b7e03629066a01b04e415cb2b4655dafMike Stump 13123899a7fb9c7eeed19cc38d082921dd8b3d0d6624Mike Stump // FIXME: We'd like to put these into a mergable by content, with 13133899a7fb9c7eeed19cc38d082921dd8b3d0d6624Mike Stump // internal linkage. 1314de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall llvm::FunctionType *LTy = CGM.getTypes().GetFunctionType(FI); 1315a4f668f3b7e03629066a01b04e415cb2b4655dafMike Stump 1316a4f668f3b7e03629066a01b04e415cb2b4655dafMike Stump llvm::Function *Fn = 1317a4f668f3b7e03629066a01b04e415cb2b4655dafMike Stump llvm::Function::Create(LTy, llvm::GlobalValue::InternalLinkage, 13183cf7c5dc23569ae76bd4bddaed22f696233d8e44Benjamin Kramer "__destroy_helper_block_", &CGM.getModule()); 1319a4f668f3b7e03629066a01b04e415cb2b4655dafMike Stump 132058dc5ca0841900b197de7733197196f435bf0cc3Devang Patel // Check if we should generate debug info for this block destroy function. 132158dc5ca0841900b197de7733197196f435bf0cc3Devang Patel if (CGM.getModuleDebugInfo()) 132258dc5ca0841900b197de7733197196f435bf0cc3Devang Patel DebugInfo = CGM.getModuleDebugInfo(); 132358dc5ca0841900b197de7733197196f435bf0cc3Devang Patel 1324a4f668f3b7e03629066a01b04e415cb2b4655dafMike Stump IdentifierInfo *II 1325a4f668f3b7e03629066a01b04e415cb2b4655dafMike Stump = &CGM.getContext().Idents.get("__destroy_helper_block_"); 1326a4f668f3b7e03629066a01b04e415cb2b4655dafMike Stump 13276b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall FunctionDecl *FD = FunctionDecl::Create(C, C.getTranslationUnitDecl(), 1328ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara SourceLocation(), 13296b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall SourceLocation(), II, C.VoidTy, 0, 1330d931b086984257de68868a64a235c2b4b34003fbJohn McCall SC_Static, 1331d931b086984257de68868a64a235c2b4b34003fbJohn McCall SC_None, 1332e5bbebb4d14347700ff0b1838f14cae3b8a35c69Eric Christopher false, false); 1333d26bc76c98006609002d9930f8840490e88ac5b5John McCall StartFunction(FD, C.VoidTy, Fn, FI, args, SourceLocation()); 13341edf6b646ea161ce1193ba278ae88de82ff7114dMike Stump 13352acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *structPtrTy = blockInfo.StructureType->getPointerTo(); 1336b7477cf6cf6cf4f132ba7beff42684e59bed15f4Mike Stump 1337d26bc76c98006609002d9930f8840490e88ac5b5John McCall llvm::Value *src = GetAddrOfLocalVar(&srcDecl); 1338d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall src = Builder.CreateLoad(src); 1339d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall src = Builder.CreateBitCast(src, structPtrTy, "block"); 13406b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 13416b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall const BlockDecl *blockDecl = blockInfo.getBlockDecl(); 13426b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 1343d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall CodeGenFunction::RunCleanupsScope cleanups(*this); 13446b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 13456b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall for (BlockDecl::capture_const_iterator ci = blockDecl->capture_begin(), 13466b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall ce = blockDecl->capture_end(); ci != ce; ++ci) { 13476b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall const VarDecl *variable = ci->getVariable(); 13486b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall QualType type = variable->getType(); 13496b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 13506b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall const CGBlockInfo::Capture &capture = blockInfo.getCapture(variable); 13516b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall if (capture.isConstant()) continue; 13526b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 1353d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall BlockFieldFlags flags; 13546b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall const CXXDestructorDecl *dtor = 0; 13556b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 1356f85e193739c953358c865005855253af4f68a497John McCall bool isARCWeakCapture = false; 1357f85e193739c953358c865005855253af4f68a497John McCall 13586b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall if (ci->isByRef()) { 13596b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall flags = BLOCK_FIELD_IS_BYREF; 1360f85e193739c953358c865005855253af4f68a497John McCall if (type.isObjCGCWeak()) 1361f85e193739c953358c865005855253af4f68a497John McCall flags |= BLOCK_FIELD_IS_WEAK; 1362f85e193739c953358c865005855253af4f68a497John McCall } else if (const CXXRecordDecl *record = type->getAsCXXRecordDecl()) { 1363f85e193739c953358c865005855253af4f68a497John McCall if (record->hasTrivialDestructor()) 1364f85e193739c953358c865005855253af4f68a497John McCall continue; 1365f85e193739c953358c865005855253af4f68a497John McCall dtor = record->getDestructor(); 1366f85e193739c953358c865005855253af4f68a497John McCall } else if (type->isObjCRetainableType()) { 13676b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall flags = BLOCK_FIELD_IS_OBJECT; 1368f85e193739c953358c865005855253af4f68a497John McCall if (type->isBlockPointerType()) 1369f85e193739c953358c865005855253af4f68a497John McCall flags = BLOCK_FIELD_IS_BLOCK; 1370f85e193739c953358c865005855253af4f68a497John McCall 1371f85e193739c953358c865005855253af4f68a497John McCall // Special rules for ARC captures. 13724e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (getLangOpts().ObjCAutoRefCount) { 1373f85e193739c953358c865005855253af4f68a497John McCall Qualifiers qs = type.getQualifiers(); 1374f85e193739c953358c865005855253af4f68a497John McCall 1375f85e193739c953358c865005855253af4f68a497John McCall // Don't generate special dispose logic for a captured object 1376f85e193739c953358c865005855253af4f68a497John McCall // unless it's __strong or __weak. 1377f85e193739c953358c865005855253af4f68a497John McCall if (!qs.hasStrongOrWeakObjCLifetime()) 1378f85e193739c953358c865005855253af4f68a497John McCall continue; 13796b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 1380f85e193739c953358c865005855253af4f68a497John McCall // Support __weak direct captures. 1381f85e193739c953358c865005855253af4f68a497John McCall if (qs.getObjCLifetime() == Qualifiers::OCL_Weak) 1382f85e193739c953358c865005855253af4f68a497John McCall isARCWeakCapture = true; 1383f85e193739c953358c865005855253af4f68a497John McCall } 1384f85e193739c953358c865005855253af4f68a497John McCall } else { 1385f85e193739c953358c865005855253af4f68a497John McCall continue; 1386f85e193739c953358c865005855253af4f68a497John McCall } 13876b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 13886b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall unsigned index = capture.getIndex(); 1389d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall llvm::Value *srcField = Builder.CreateStructGEP(src, index); 13906b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 13916b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // If there's an explicit copy expression, we do that. 13926b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall if (dtor) { 1393d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall PushDestructorCleanup(dtor, srcField); 13946b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 1395f85e193739c953358c865005855253af4f68a497John McCall // If this is a __weak capture, emit the release directly. 1396f85e193739c953358c865005855253af4f68a497John McCall } else if (isARCWeakCapture) { 1397f85e193739c953358c865005855253af4f68a497John McCall EmitARCDestroyWeak(srcField); 1398f85e193739c953358c865005855253af4f68a497John McCall 13996b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // Otherwise we call _Block_object_dispose. It wouldn't be too 14006b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // hard to just emit this as a cleanup if we wanted to make sure 14016b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // that things were done in reverse. 14026b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall } else { 14036b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall llvm::Value *value = Builder.CreateLoad(srcField); 14045936e33bf74dd6bf126ceee0f6169a2593d03a69John McCall value = Builder.CreateBitCast(value, VoidPtrTy); 14056b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall BuildBlockRelease(value, flags); 14061edf6b646ea161ce1193ba278ae88de82ff7114dMike Stump } 14071edf6b646ea161ce1193ba278ae88de82ff7114dMike Stump } 14081edf6b646ea161ce1193ba278ae88de82ff7114dMike Stump 14096b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall cleanups.ForceCleanup(); 14106b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 1411d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall FinishFunction(); 1412a4f668f3b7e03629066a01b04e415cb2b4655dafMike Stump 14135936e33bf74dd6bf126ceee0f6169a2593d03a69John McCall return llvm::ConstantExpr::getBitCast(Fn, VoidPtrTy); 1414a4f668f3b7e03629066a01b04e415cb2b4655dafMike Stump} 1415a4f668f3b7e03629066a01b04e415cb2b4655dafMike Stump 1416f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCallnamespace { 1417f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall 1418f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall/// Emits the copy/dispose helper functions for a __block object of id type. 1419f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCallclass ObjectByrefHelpers : public CodeGenModule::ByrefHelpers { 1420f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall BlockFieldFlags Flags; 1421f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall 1422f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCallpublic: 1423f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall ObjectByrefHelpers(CharUnits alignment, BlockFieldFlags flags) 1424f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall : ByrefHelpers(alignment), Flags(flags) {} 1425f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall 1426361701965ed119099d180d419ac25a0503fcc0feJohn McCall void emitCopy(CodeGenFunction &CGF, llvm::Value *destField, 1427361701965ed119099d180d419ac25a0503fcc0feJohn McCall llvm::Value *srcField) { 1428f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall destField = CGF.Builder.CreateBitCast(destField, CGF.VoidPtrTy); 1429f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall 1430f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall srcField = CGF.Builder.CreateBitCast(srcField, CGF.VoidPtrPtrTy); 1431f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall llvm::Value *srcValue = CGF.Builder.CreateLoad(srcField); 1432f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall 1433f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall unsigned flags = (Flags | BLOCK_BYREF_CALLER).getBitMask(); 1434f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall 1435f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall llvm::Value *flagsVal = llvm::ConstantInt::get(CGF.Int32Ty, flags); 1436f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall llvm::Value *fn = CGF.CGM.getBlockObjectAssign(); 1437f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall CGF.Builder.CreateCall3(fn, destField, srcValue, flagsVal); 1438f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall } 1439f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall 1440f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall void emitDispose(CodeGenFunction &CGF, llvm::Value *field) { 1441f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall field = CGF.Builder.CreateBitCast(field, CGF.Int8PtrTy->getPointerTo(0)); 1442f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall llvm::Value *value = CGF.Builder.CreateLoad(field); 1443f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall 1444f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall CGF.BuildBlockRelease(value, Flags | BLOCK_BYREF_CALLER); 1445f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall } 1446f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall 1447f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall void profileImpl(llvm::FoldingSetNodeID &id) const { 1448f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall id.AddInteger(Flags.getBitMask()); 1449f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall } 1450f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall}; 1451f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall 1452f85e193739c953358c865005855253af4f68a497John McCall/// Emits the copy/dispose helpers for an ARC __block __weak variable. 1453f85e193739c953358c865005855253af4f68a497John McCallclass ARCWeakByrefHelpers : public CodeGenModule::ByrefHelpers { 1454f85e193739c953358c865005855253af4f68a497John McCallpublic: 1455f85e193739c953358c865005855253af4f68a497John McCall ARCWeakByrefHelpers(CharUnits alignment) : ByrefHelpers(alignment) {} 1456f85e193739c953358c865005855253af4f68a497John McCall 1457f85e193739c953358c865005855253af4f68a497John McCall void emitCopy(CodeGenFunction &CGF, llvm::Value *destField, 1458f85e193739c953358c865005855253af4f68a497John McCall llvm::Value *srcField) { 1459f85e193739c953358c865005855253af4f68a497John McCall CGF.EmitARCMoveWeak(destField, srcField); 1460f85e193739c953358c865005855253af4f68a497John McCall } 1461f85e193739c953358c865005855253af4f68a497John McCall 1462f85e193739c953358c865005855253af4f68a497John McCall void emitDispose(CodeGenFunction &CGF, llvm::Value *field) { 1463f85e193739c953358c865005855253af4f68a497John McCall CGF.EmitARCDestroyWeak(field); 1464f85e193739c953358c865005855253af4f68a497John McCall } 1465f85e193739c953358c865005855253af4f68a497John McCall 1466f85e193739c953358c865005855253af4f68a497John McCall void profileImpl(llvm::FoldingSetNodeID &id) const { 1467f85e193739c953358c865005855253af4f68a497John McCall // 0 is distinguishable from all pointers and byref flags 1468f85e193739c953358c865005855253af4f68a497John McCall id.AddInteger(0); 1469f85e193739c953358c865005855253af4f68a497John McCall } 1470f85e193739c953358c865005855253af4f68a497John McCall}; 1471f85e193739c953358c865005855253af4f68a497John McCall 1472f85e193739c953358c865005855253af4f68a497John McCall/// Emits the copy/dispose helpers for an ARC __block __strong variable 1473f85e193739c953358c865005855253af4f68a497John McCall/// that's not of block-pointer type. 1474f85e193739c953358c865005855253af4f68a497John McCallclass ARCStrongByrefHelpers : public CodeGenModule::ByrefHelpers { 1475f85e193739c953358c865005855253af4f68a497John McCallpublic: 1476f85e193739c953358c865005855253af4f68a497John McCall ARCStrongByrefHelpers(CharUnits alignment) : ByrefHelpers(alignment) {} 1477f85e193739c953358c865005855253af4f68a497John McCall 1478f85e193739c953358c865005855253af4f68a497John McCall void emitCopy(CodeGenFunction &CGF, llvm::Value *destField, 1479f85e193739c953358c865005855253af4f68a497John McCall llvm::Value *srcField) { 1480f85e193739c953358c865005855253af4f68a497John McCall // Do a "move" by copying the value and then zeroing out the old 1481f85e193739c953358c865005855253af4f68a497John McCall // variable. 1482f85e193739c953358c865005855253af4f68a497John McCall 1483a59e4b7fca1d46afd8f315fa87fa8bf1a68df9cdJohn McCall llvm::LoadInst *value = CGF.Builder.CreateLoad(srcField); 1484a59e4b7fca1d46afd8f315fa87fa8bf1a68df9cdJohn McCall value->setAlignment(Alignment.getQuantity()); 1485a59e4b7fca1d46afd8f315fa87fa8bf1a68df9cdJohn McCall 1486f85e193739c953358c865005855253af4f68a497John McCall llvm::Value *null = 1487f85e193739c953358c865005855253af4f68a497John McCall llvm::ConstantPointerNull::get(cast<llvm::PointerType>(value->getType())); 1488a59e4b7fca1d46afd8f315fa87fa8bf1a68df9cdJohn McCall 1489a59e4b7fca1d46afd8f315fa87fa8bf1a68df9cdJohn McCall llvm::StoreInst *store = CGF.Builder.CreateStore(value, destField); 1490a59e4b7fca1d46afd8f315fa87fa8bf1a68df9cdJohn McCall store->setAlignment(Alignment.getQuantity()); 1491a59e4b7fca1d46afd8f315fa87fa8bf1a68df9cdJohn McCall 1492a59e4b7fca1d46afd8f315fa87fa8bf1a68df9cdJohn McCall store = CGF.Builder.CreateStore(null, srcField); 1493a59e4b7fca1d46afd8f315fa87fa8bf1a68df9cdJohn McCall store->setAlignment(Alignment.getQuantity()); 1494f85e193739c953358c865005855253af4f68a497John McCall } 1495f85e193739c953358c865005855253af4f68a497John McCall 1496f85e193739c953358c865005855253af4f68a497John McCall void emitDispose(CodeGenFunction &CGF, llvm::Value *field) { 1497a59e4b7fca1d46afd8f315fa87fa8bf1a68df9cdJohn McCall llvm::LoadInst *value = CGF.Builder.CreateLoad(field); 1498a59e4b7fca1d46afd8f315fa87fa8bf1a68df9cdJohn McCall value->setAlignment(Alignment.getQuantity()); 1499a59e4b7fca1d46afd8f315fa87fa8bf1a68df9cdJohn McCall 1500f85e193739c953358c865005855253af4f68a497John McCall CGF.EmitARCRelease(value, /*precise*/ false); 1501f85e193739c953358c865005855253af4f68a497John McCall } 1502f85e193739c953358c865005855253af4f68a497John McCall 1503f85e193739c953358c865005855253af4f68a497John McCall void profileImpl(llvm::FoldingSetNodeID &id) const { 1504f85e193739c953358c865005855253af4f68a497John McCall // 1 is distinguishable from all pointers and byref flags 1505f85e193739c953358c865005855253af4f68a497John McCall id.AddInteger(1); 1506f85e193739c953358c865005855253af4f68a497John McCall } 1507f85e193739c953358c865005855253af4f68a497John McCall}; 1508f85e193739c953358c865005855253af4f68a497John McCall 1509a59e4b7fca1d46afd8f315fa87fa8bf1a68df9cdJohn McCall/// Emits the copy/dispose helpers for an ARC __block __strong 1510a59e4b7fca1d46afd8f315fa87fa8bf1a68df9cdJohn McCall/// variable that's of block-pointer type. 1511a59e4b7fca1d46afd8f315fa87fa8bf1a68df9cdJohn McCallclass ARCStrongBlockByrefHelpers : public CodeGenModule::ByrefHelpers { 1512a59e4b7fca1d46afd8f315fa87fa8bf1a68df9cdJohn McCallpublic: 1513a59e4b7fca1d46afd8f315fa87fa8bf1a68df9cdJohn McCall ARCStrongBlockByrefHelpers(CharUnits alignment) : ByrefHelpers(alignment) {} 1514a59e4b7fca1d46afd8f315fa87fa8bf1a68df9cdJohn McCall 1515a59e4b7fca1d46afd8f315fa87fa8bf1a68df9cdJohn McCall void emitCopy(CodeGenFunction &CGF, llvm::Value *destField, 1516a59e4b7fca1d46afd8f315fa87fa8bf1a68df9cdJohn McCall llvm::Value *srcField) { 1517a59e4b7fca1d46afd8f315fa87fa8bf1a68df9cdJohn McCall // Do the copy with objc_retainBlock; that's all that 1518a59e4b7fca1d46afd8f315fa87fa8bf1a68df9cdJohn McCall // _Block_object_assign would do anyway, and we'd have to pass the 1519a59e4b7fca1d46afd8f315fa87fa8bf1a68df9cdJohn McCall // right arguments to make sure it doesn't get no-op'ed. 1520a59e4b7fca1d46afd8f315fa87fa8bf1a68df9cdJohn McCall llvm::LoadInst *oldValue = CGF.Builder.CreateLoad(srcField); 1521a59e4b7fca1d46afd8f315fa87fa8bf1a68df9cdJohn McCall oldValue->setAlignment(Alignment.getQuantity()); 1522a59e4b7fca1d46afd8f315fa87fa8bf1a68df9cdJohn McCall 1523a59e4b7fca1d46afd8f315fa87fa8bf1a68df9cdJohn McCall llvm::Value *copy = CGF.EmitARCRetainBlock(oldValue, /*mandatory*/ true); 1524a59e4b7fca1d46afd8f315fa87fa8bf1a68df9cdJohn McCall 1525a59e4b7fca1d46afd8f315fa87fa8bf1a68df9cdJohn McCall llvm::StoreInst *store = CGF.Builder.CreateStore(copy, destField); 1526a59e4b7fca1d46afd8f315fa87fa8bf1a68df9cdJohn McCall store->setAlignment(Alignment.getQuantity()); 1527a59e4b7fca1d46afd8f315fa87fa8bf1a68df9cdJohn McCall } 1528a59e4b7fca1d46afd8f315fa87fa8bf1a68df9cdJohn McCall 1529a59e4b7fca1d46afd8f315fa87fa8bf1a68df9cdJohn McCall void emitDispose(CodeGenFunction &CGF, llvm::Value *field) { 1530a59e4b7fca1d46afd8f315fa87fa8bf1a68df9cdJohn McCall llvm::LoadInst *value = CGF.Builder.CreateLoad(field); 1531a59e4b7fca1d46afd8f315fa87fa8bf1a68df9cdJohn McCall value->setAlignment(Alignment.getQuantity()); 1532a59e4b7fca1d46afd8f315fa87fa8bf1a68df9cdJohn McCall 1533a59e4b7fca1d46afd8f315fa87fa8bf1a68df9cdJohn McCall CGF.EmitARCRelease(value, /*precise*/ false); 1534a59e4b7fca1d46afd8f315fa87fa8bf1a68df9cdJohn McCall } 1535a59e4b7fca1d46afd8f315fa87fa8bf1a68df9cdJohn McCall 1536a59e4b7fca1d46afd8f315fa87fa8bf1a68df9cdJohn McCall void profileImpl(llvm::FoldingSetNodeID &id) const { 1537a59e4b7fca1d46afd8f315fa87fa8bf1a68df9cdJohn McCall // 2 is distinguishable from all pointers and byref flags 1538a59e4b7fca1d46afd8f315fa87fa8bf1a68df9cdJohn McCall id.AddInteger(2); 1539a59e4b7fca1d46afd8f315fa87fa8bf1a68df9cdJohn McCall } 1540a59e4b7fca1d46afd8f315fa87fa8bf1a68df9cdJohn McCall}; 1541a59e4b7fca1d46afd8f315fa87fa8bf1a68df9cdJohn McCall 1542f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall/// Emits the copy/dispose helpers for a __block variable with a 1543f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall/// nontrivial copy constructor or destructor. 1544f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCallclass CXXByrefHelpers : public CodeGenModule::ByrefHelpers { 1545f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall QualType VarType; 1546f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall const Expr *CopyExpr; 1547f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall 1548f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCallpublic: 1549f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall CXXByrefHelpers(CharUnits alignment, QualType type, 1550f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall const Expr *copyExpr) 1551f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall : ByrefHelpers(alignment), VarType(type), CopyExpr(copyExpr) {} 1552f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall 1553f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall bool needsCopy() const { return CopyExpr != 0; } 1554f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall void emitCopy(CodeGenFunction &CGF, llvm::Value *destField, 1555f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall llvm::Value *srcField) { 1556f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall if (!CopyExpr) return; 1557f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall CGF.EmitSynthesizedCXXCopyCtor(destField, srcField, CopyExpr); 1558f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall } 1559f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall 1560f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall void emitDispose(CodeGenFunction &CGF, llvm::Value *field) { 1561f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall EHScopeStack::stable_iterator cleanupDepth = CGF.EHStack.stable_begin(); 1562f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall CGF.PushDestructorCleanup(VarType, field); 1563f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall CGF.PopCleanupBlocks(cleanupDepth); 1564f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall } 1565f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall 1566f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall void profileImpl(llvm::FoldingSetNodeID &id) const { 1567f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall id.AddPointer(VarType.getCanonicalType().getAsOpaquePtr()); 1568f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall } 1569f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall}; 1570f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall} // end anonymous namespace 1571f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall 1572f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCallstatic llvm::Constant * 1573f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCallgenerateByrefCopyHelper(CodeGenFunction &CGF, 15742acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::StructType &byrefType, 1575f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall CodeGenModule::ByrefHelpers &byrefInfo) { 1576f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall ASTContext &Context = CGF.getContext(); 1577f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall 1578f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall QualType R = Context.VoidTy; 157945031c08c608e548ac12caf0547f89574e994b96Mike Stump 1580d26bc76c98006609002d9930f8840490e88ac5b5John McCall FunctionArgList args; 1581f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall ImplicitParamDecl dst(0, SourceLocation(), 0, Context.VoidPtrTy); 1582d26bc76c98006609002d9930f8840490e88ac5b5John McCall args.push_back(&dst); 1583d26bc76c98006609002d9930f8840490e88ac5b5John McCall 1584f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall ImplicitParamDecl src(0, SourceLocation(), 0, Context.VoidPtrTy); 1585d26bc76c98006609002d9930f8840490e88ac5b5John McCall args.push_back(&src); 15861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 158745031c08c608e548ac12caf0547f89574e994b96Mike Stump const CGFunctionInfo &FI = 1588de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall CGF.CGM.getTypes().arrangeFunctionDeclaration(R, args, 1589de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall FunctionType::ExtInfo(), 1590de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall /*variadic*/ false); 159145031c08c608e548ac12caf0547f89574e994b96Mike Stump 1592f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall CodeGenTypes &Types = CGF.CGM.getTypes(); 1593de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall llvm::FunctionType *LTy = Types.GetFunctionType(FI); 159445031c08c608e548ac12caf0547f89574e994b96Mike Stump 15953899a7fb9c7eeed19cc38d082921dd8b3d0d6624Mike Stump // FIXME: We'd like to put these into a mergable by content, with 15963899a7fb9c7eeed19cc38d082921dd8b3d0d6624Mike Stump // internal linkage. 159745031c08c608e548ac12caf0547f89574e994b96Mike Stump llvm::Function *Fn = 159845031c08c608e548ac12caf0547f89574e994b96Mike Stump llvm::Function::Create(LTy, llvm::GlobalValue::InternalLinkage, 1599f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall "__Block_byref_object_copy_", &CGF.CGM.getModule()); 160045031c08c608e548ac12caf0547f89574e994b96Mike Stump 160145031c08c608e548ac12caf0547f89574e994b96Mike Stump IdentifierInfo *II 1602f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall = &Context.Idents.get("__Block_byref_object_copy_"); 160345031c08c608e548ac12caf0547f89574e994b96Mike Stump 1604f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall FunctionDecl *FD = FunctionDecl::Create(Context, 1605f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall Context.getTranslationUnitDecl(), 1606ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara SourceLocation(), 1607a1d5662d96465f0fddf8819d245da4d19b892effArgyrios Kyrtzidis SourceLocation(), II, R, 0, 1608d931b086984257de68868a64a235c2b4b34003fbJohn McCall SC_Static, 1609d931b086984257de68868a64a235c2b4b34003fbJohn McCall SC_None, 1610b92bd4b3271b7892abe9fd8c74fb54a27ad702abEric Christopher false, false); 1611f85e193739c953358c865005855253af4f68a497John McCall 1612f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall CGF.StartFunction(FD, R, Fn, FI, args, SourceLocation()); 161345031c08c608e548ac12caf0547f89574e994b96Mike Stump 1614f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall if (byrefInfo.needsCopy()) { 16152acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *byrefPtrType = byrefType.getPointerTo(0); 1616f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall 1617f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall // dst->x 1618f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall llvm::Value *destField = CGF.GetAddrOfLocalVar(&dst); 1619f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall destField = CGF.Builder.CreateLoad(destField); 1620f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall destField = CGF.Builder.CreateBitCast(destField, byrefPtrType); 1621f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall destField = CGF.Builder.CreateStructGEP(destField, 6, "x"); 1622f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall 1623f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall // src->x 1624f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall llvm::Value *srcField = CGF.GetAddrOfLocalVar(&src); 1625f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall srcField = CGF.Builder.CreateLoad(srcField); 1626f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall srcField = CGF.Builder.CreateBitCast(srcField, byrefPtrType); 1627f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall srcField = CGF.Builder.CreateStructGEP(srcField, 6, "x"); 1628f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall 1629f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall byrefInfo.emitCopy(CGF, destField, srcField); 1630f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall } 1631f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall 1632f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall CGF.FinishFunction(); 1633f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall 1634f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall return llvm::ConstantExpr::getBitCast(Fn, CGF.Int8PtrTy); 163545031c08c608e548ac12caf0547f89574e994b96Mike Stump} 163645031c08c608e548ac12caf0547f89574e994b96Mike Stump 1637f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall/// Build the copy helper for a __block variable. 1638f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCallstatic llvm::Constant *buildByrefCopyHelper(CodeGenModule &CGM, 16392acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::StructType &byrefType, 1640f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall CodeGenModule::ByrefHelpers &info) { 1641f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall CodeGenFunction CGF(CGM); 1642f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall return generateByrefCopyHelper(CGF, byrefType, info); 1643f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall} 1644f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall 1645f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall/// Generate code for a __block variable's dispose helper. 1646f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCallstatic llvm::Constant * 1647f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCallgenerateByrefDisposeHelper(CodeGenFunction &CGF, 16482acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::StructType &byrefType, 1649f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall CodeGenModule::ByrefHelpers &byrefInfo) { 1650f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall ASTContext &Context = CGF.getContext(); 1651f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall QualType R = Context.VoidTy; 165245031c08c608e548ac12caf0547f89574e994b96Mike Stump 1653d26bc76c98006609002d9930f8840490e88ac5b5John McCall FunctionArgList args; 1654f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall ImplicitParamDecl src(0, SourceLocation(), 0, Context.VoidPtrTy); 1655d26bc76c98006609002d9930f8840490e88ac5b5John McCall args.push_back(&src); 16561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 165745031c08c608e548ac12caf0547f89574e994b96Mike Stump const CGFunctionInfo &FI = 1658de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall CGF.CGM.getTypes().arrangeFunctionDeclaration(R, args, 1659de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall FunctionType::ExtInfo(), 1660de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall /*variadic*/ false); 166145031c08c608e548ac12caf0547f89574e994b96Mike Stump 1662f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall CodeGenTypes &Types = CGF.CGM.getTypes(); 1663de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall llvm::FunctionType *LTy = Types.GetFunctionType(FI); 166445031c08c608e548ac12caf0547f89574e994b96Mike Stump 16653899a7fb9c7eeed19cc38d082921dd8b3d0d6624Mike Stump // FIXME: We'd like to put these into a mergable by content, with 16663899a7fb9c7eeed19cc38d082921dd8b3d0d6624Mike Stump // internal linkage. 166745031c08c608e548ac12caf0547f89574e994b96Mike Stump llvm::Function *Fn = 166845031c08c608e548ac12caf0547f89574e994b96Mike Stump llvm::Function::Create(LTy, llvm::GlobalValue::InternalLinkage, 1669830937bc1100fba7682f7c32c40512085870f50cFariborz Jahanian "__Block_byref_object_dispose_", 1670f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall &CGF.CGM.getModule()); 167145031c08c608e548ac12caf0547f89574e994b96Mike Stump 167245031c08c608e548ac12caf0547f89574e994b96Mike Stump IdentifierInfo *II 1673f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall = &Context.Idents.get("__Block_byref_object_dispose_"); 167445031c08c608e548ac12caf0547f89574e994b96Mike Stump 1675f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall FunctionDecl *FD = FunctionDecl::Create(Context, 1676f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall Context.getTranslationUnitDecl(), 1677ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara SourceLocation(), 1678a1d5662d96465f0fddf8819d245da4d19b892effArgyrios Kyrtzidis SourceLocation(), II, R, 0, 1679d931b086984257de68868a64a235c2b4b34003fbJohn McCall SC_Static, 1680d931b086984257de68868a64a235c2b4b34003fbJohn McCall SC_None, 1681b92bd4b3271b7892abe9fd8c74fb54a27ad702abEric Christopher false, false); 1682f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall CGF.StartFunction(FD, R, Fn, FI, args, SourceLocation()); 16831851b68aaa6717783609f366f5d87bbd0030f189Mike Stump 1684f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall if (byrefInfo.needsDispose()) { 1685f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall llvm::Value *V = CGF.GetAddrOfLocalVar(&src); 1686f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall V = CGF.Builder.CreateLoad(V); 1687f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall V = CGF.Builder.CreateBitCast(V, byrefType.getPointerTo(0)); 1688f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall V = CGF.Builder.CreateStructGEP(V, 6, "x"); 1689d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall 1690f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall byrefInfo.emitDispose(CGF, V); 1691830937bc1100fba7682f7c32c40512085870f50cFariborz Jahanian } 169245031c08c608e548ac12caf0547f89574e994b96Mike Stump 1693f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall CGF.FinishFunction(); 1694d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall 1695f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall return llvm::ConstantExpr::getBitCast(Fn, CGF.Int8PtrTy); 169645031c08c608e548ac12caf0547f89574e994b96Mike Stump} 169745031c08c608e548ac12caf0547f89574e994b96Mike Stump 1698f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall/// Build the dispose helper for a __block variable. 1699f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCallstatic llvm::Constant *buildByrefDisposeHelper(CodeGenModule &CGM, 17002acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::StructType &byrefType, 1701f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall CodeGenModule::ByrefHelpers &info) { 1702f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall CodeGenFunction CGF(CGM); 1703f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall return generateByrefDisposeHelper(CGF, byrefType, info); 170445031c08c608e548ac12caf0547f89574e994b96Mike Stump} 170545031c08c608e548ac12caf0547f89574e994b96Mike Stump 1706f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall/// 1707f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCalltemplate <class T> static T *buildByrefHelpers(CodeGenModule &CGM, 17082acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::StructType &byrefTy, 1709f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall T &byrefInfo) { 1710f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall // Increase the field's alignment to be at least pointer alignment, 1711f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall // since the layout of the byref struct will guarantee at least that. 1712f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall byrefInfo.Alignment = std::max(byrefInfo.Alignment, 1713f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall CharUnits::fromQuantity(CGM.PointerAlignInBytes)); 1714f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall 1715f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall llvm::FoldingSetNodeID id; 1716f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall byrefInfo.Profile(id); 1717f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall 1718f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall void *insertPos; 1719f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall CodeGenModule::ByrefHelpers *node 1720f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall = CGM.ByrefHelpersCache.FindNodeOrInsertPos(id, insertPos); 1721f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall if (node) return static_cast<T*>(node); 1722f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall 1723f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall byrefInfo.CopyHelper = buildByrefCopyHelper(CGM, byrefTy, byrefInfo); 1724f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall byrefInfo.DisposeHelper = buildByrefDisposeHelper(CGM, byrefTy, byrefInfo); 1725f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall 1726f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall T *copy = new (CGM.getContext()) T(byrefInfo); 1727f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall CGM.ByrefHelpersCache.InsertNode(copy, insertPos); 1728f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall return copy; 1729f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall} 1730f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall 1731f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCallCodeGenModule::ByrefHelpers * 17322acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris LattnerCodeGenFunction::buildByrefHelpers(llvm::StructType &byrefType, 1733f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall const AutoVarEmission &emission) { 1734f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall const VarDecl &var = *emission.Variable; 1735f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall QualType type = var.getType(); 1736f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall 1737f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall if (const CXXRecordDecl *record = type->getAsCXXRecordDecl()) { 1738f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall const Expr *copyExpr = CGM.getContext().getBlockVarCopyInits(&var); 1739f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall if (!copyExpr && record->hasTrivialDestructor()) return 0; 1740f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall 1741f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall CXXByrefHelpers byrefInfo(emission.Alignment, type, copyExpr); 1742f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall return ::buildByrefHelpers(CGM, byrefType, byrefInfo); 1743f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall } 1744f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall 1745f85e193739c953358c865005855253af4f68a497John McCall // Otherwise, if we don't have a retainable type, there's nothing to do. 1746f85e193739c953358c865005855253af4f68a497John McCall // that the runtime does extra copies. 1747f85e193739c953358c865005855253af4f68a497John McCall if (!type->isObjCRetainableType()) return 0; 1748f85e193739c953358c865005855253af4f68a497John McCall 1749f85e193739c953358c865005855253af4f68a497John McCall Qualifiers qs = type.getQualifiers(); 1750f85e193739c953358c865005855253af4f68a497John McCall 1751f85e193739c953358c865005855253af4f68a497John McCall // If we have lifetime, that dominates. 1752f85e193739c953358c865005855253af4f68a497John McCall if (Qualifiers::ObjCLifetime lifetime = qs.getObjCLifetime()) { 17534e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie assert(getLangOpts().ObjCAutoRefCount); 1754f85e193739c953358c865005855253af4f68a497John McCall 1755f85e193739c953358c865005855253af4f68a497John McCall switch (lifetime) { 1756f85e193739c953358c865005855253af4f68a497John McCall case Qualifiers::OCL_None: llvm_unreachable("impossible"); 1757f85e193739c953358c865005855253af4f68a497John McCall 1758f85e193739c953358c865005855253af4f68a497John McCall // These are just bits as far as the runtime is concerned. 1759f85e193739c953358c865005855253af4f68a497John McCall case Qualifiers::OCL_ExplicitNone: 1760f85e193739c953358c865005855253af4f68a497John McCall case Qualifiers::OCL_Autoreleasing: 1761f85e193739c953358c865005855253af4f68a497John McCall return 0; 1762f85e193739c953358c865005855253af4f68a497John McCall 1763f85e193739c953358c865005855253af4f68a497John McCall // Tell the runtime that this is ARC __weak, called by the 1764f85e193739c953358c865005855253af4f68a497John McCall // byref routines. 1765f85e193739c953358c865005855253af4f68a497John McCall case Qualifiers::OCL_Weak: { 1766f85e193739c953358c865005855253af4f68a497John McCall ARCWeakByrefHelpers byrefInfo(emission.Alignment); 1767f85e193739c953358c865005855253af4f68a497John McCall return ::buildByrefHelpers(CGM, byrefType, byrefInfo); 1768f85e193739c953358c865005855253af4f68a497John McCall } 1769f85e193739c953358c865005855253af4f68a497John McCall 1770f85e193739c953358c865005855253af4f68a497John McCall // ARC __strong __block variables need to be retained. 1771f85e193739c953358c865005855253af4f68a497John McCall case Qualifiers::OCL_Strong: 1772a59e4b7fca1d46afd8f315fa87fa8bf1a68df9cdJohn McCall // Block pointers need to be copied, and there's no direct 1773a59e4b7fca1d46afd8f315fa87fa8bf1a68df9cdJohn McCall // transfer possible. 1774f85e193739c953358c865005855253af4f68a497John McCall if (type->isBlockPointerType()) { 1775a59e4b7fca1d46afd8f315fa87fa8bf1a68df9cdJohn McCall ARCStrongBlockByrefHelpers byrefInfo(emission.Alignment); 1776f85e193739c953358c865005855253af4f68a497John McCall return ::buildByrefHelpers(CGM, byrefType, byrefInfo); 1777f85e193739c953358c865005855253af4f68a497John McCall 1778f85e193739c953358c865005855253af4f68a497John McCall // Otherwise, we transfer ownership of the retain from the stack 1779f85e193739c953358c865005855253af4f68a497John McCall // to the heap. 1780f85e193739c953358c865005855253af4f68a497John McCall } else { 1781f85e193739c953358c865005855253af4f68a497John McCall ARCStrongByrefHelpers byrefInfo(emission.Alignment); 1782f85e193739c953358c865005855253af4f68a497John McCall return ::buildByrefHelpers(CGM, byrefType, byrefInfo); 1783f85e193739c953358c865005855253af4f68a497John McCall } 1784f85e193739c953358c865005855253af4f68a497John McCall } 1785f85e193739c953358c865005855253af4f68a497John McCall llvm_unreachable("fell out of lifetime switch!"); 1786f85e193739c953358c865005855253af4f68a497John McCall } 1787f85e193739c953358c865005855253af4f68a497John McCall 1788f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall BlockFieldFlags flags; 1789f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall if (type->isBlockPointerType()) { 1790f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall flags |= BLOCK_FIELD_IS_BLOCK; 1791f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall } else if (CGM.getContext().isObjCNSObjectType(type) || 1792f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall type->isObjCObjectPointerType()) { 1793f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall flags |= BLOCK_FIELD_IS_OBJECT; 1794f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall } else { 1795f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall return 0; 1796f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall } 1797f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall 1798f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall if (type.isObjCGCWeak()) 1799f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall flags |= BLOCK_FIELD_IS_WEAK; 1800f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall 1801f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall ObjectByrefHelpers byrefInfo(emission.Alignment, flags); 1802f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall return ::buildByrefHelpers(CGM, byrefType, byrefInfo); 180345031c08c608e548ac12caf0547f89574e994b96Mike Stump} 180445031c08c608e548ac12caf0547f89574e994b96Mike Stump 18055af02db5a48476e0748f135369663080eae87c64John McCallunsigned CodeGenFunction::getByRefValueLLVMField(const ValueDecl *VD) const { 18065af02db5a48476e0748f135369663080eae87c64John McCall assert(ByRefValueInfo.count(VD) && "Did not find value!"); 18075af02db5a48476e0748f135369663080eae87c64John McCall 18085af02db5a48476e0748f135369663080eae87c64John McCall return ByRefValueInfo.find(VD)->second.second; 18095af02db5a48476e0748f135369663080eae87c64John McCall} 18105af02db5a48476e0748f135369663080eae87c64John McCall 18115af02db5a48476e0748f135369663080eae87c64John McCallllvm::Value *CodeGenFunction::BuildBlockByrefAddress(llvm::Value *BaseAddr, 18125af02db5a48476e0748f135369663080eae87c64John McCall const VarDecl *V) { 18135af02db5a48476e0748f135369663080eae87c64John McCall llvm::Value *Loc = Builder.CreateStructGEP(BaseAddr, 1, "forwarding"); 18145af02db5a48476e0748f135369663080eae87c64John McCall Loc = Builder.CreateLoad(Loc); 18155af02db5a48476e0748f135369663080eae87c64John McCall Loc = Builder.CreateStructGEP(Loc, getByRefValueLLVMField(V), 18165af02db5a48476e0748f135369663080eae87c64John McCall V->getNameAsString()); 18175af02db5a48476e0748f135369663080eae87c64John McCall return Loc; 18185af02db5a48476e0748f135369663080eae87c64John McCall} 18195af02db5a48476e0748f135369663080eae87c64John McCall 18205af02db5a48476e0748f135369663080eae87c64John McCall/// BuildByRefType - This routine changes a __block variable declared as T x 18215af02db5a48476e0748f135369663080eae87c64John McCall/// into: 18225af02db5a48476e0748f135369663080eae87c64John McCall/// 18235af02db5a48476e0748f135369663080eae87c64John McCall/// struct { 18245af02db5a48476e0748f135369663080eae87c64John McCall/// void *__isa; 18255af02db5a48476e0748f135369663080eae87c64John McCall/// void *__forwarding; 18265af02db5a48476e0748f135369663080eae87c64John McCall/// int32_t __flags; 18275af02db5a48476e0748f135369663080eae87c64John McCall/// int32_t __size; 18285af02db5a48476e0748f135369663080eae87c64John McCall/// void *__copy_helper; // only if needed 18295af02db5a48476e0748f135369663080eae87c64John McCall/// void *__destroy_helper; // only if needed 18305af02db5a48476e0748f135369663080eae87c64John McCall/// char padding[X]; // only if needed 18315af02db5a48476e0748f135369663080eae87c64John McCall/// T x; 18325af02db5a48476e0748f135369663080eae87c64John McCall/// } x 18335af02db5a48476e0748f135369663080eae87c64John McCall/// 18342acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattnerllvm::Type *CodeGenFunction::BuildByRefType(const VarDecl *D) { 18352acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner std::pair<llvm::Type *, unsigned> &Info = ByRefValueInfo[D]; 18365af02db5a48476e0748f135369663080eae87c64John McCall if (Info.first) 18375af02db5a48476e0748f135369663080eae87c64John McCall return Info.first; 18385af02db5a48476e0748f135369663080eae87c64John McCall 18395af02db5a48476e0748f135369663080eae87c64John McCall QualType Ty = D->getType(); 18405af02db5a48476e0748f135369663080eae87c64John McCall 18415f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<llvm::Type *, 8> types; 18425af02db5a48476e0748f135369663080eae87c64John McCall 18439cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::StructType *ByRefType = 1844c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner llvm::StructType::create(getLLVMContext(), 1845c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner "struct.__block_byref_" + D->getNameAsString()); 18465af02db5a48476e0748f135369663080eae87c64John McCall 18475af02db5a48476e0748f135369663080eae87c64John McCall // void *__isa; 18480774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall types.push_back(Int8PtrTy); 18495af02db5a48476e0748f135369663080eae87c64John McCall 18505af02db5a48476e0748f135369663080eae87c64John McCall // void *__forwarding; 18519cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner types.push_back(llvm::PointerType::getUnqual(ByRefType)); 18525af02db5a48476e0748f135369663080eae87c64John McCall 18535af02db5a48476e0748f135369663080eae87c64John McCall // int32_t __flags; 18540774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall types.push_back(Int32Ty); 18555af02db5a48476e0748f135369663080eae87c64John McCall 18565af02db5a48476e0748f135369663080eae87c64John McCall // int32_t __size; 18570774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall types.push_back(Int32Ty); 18585af02db5a48476e0748f135369663080eae87c64John McCall 18599595dae5f78cd1762d8f0076887821be65f7e5a6David Chisnall bool HasCopyAndDispose = 18609595dae5f78cd1762d8f0076887821be65f7e5a6David Chisnall (Ty->isObjCRetainableType()) || getContext().getBlockVarCopyInits(D); 18615af02db5a48476e0748f135369663080eae87c64John McCall if (HasCopyAndDispose) { 18625af02db5a48476e0748f135369663080eae87c64John McCall /// void *__copy_helper; 18630774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall types.push_back(Int8PtrTy); 18645af02db5a48476e0748f135369663080eae87c64John McCall 18655af02db5a48476e0748f135369663080eae87c64John McCall /// void *__destroy_helper; 18660774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall types.push_back(Int8PtrTy); 18675af02db5a48476e0748f135369663080eae87c64John McCall } 18685af02db5a48476e0748f135369663080eae87c64John McCall 18695af02db5a48476e0748f135369663080eae87c64John McCall bool Packed = false; 18705af02db5a48476e0748f135369663080eae87c64John McCall CharUnits Align = getContext().getDeclAlign(D); 18715af02db5a48476e0748f135369663080eae87c64John McCall if (Align > getContext().toCharUnitsFromBits(Target.getPointerAlign(0))) { 18725af02db5a48476e0748f135369663080eae87c64John McCall // We have to insert padding. 18735af02db5a48476e0748f135369663080eae87c64John McCall 18745af02db5a48476e0748f135369663080eae87c64John McCall // The struct above has 2 32-bit integers. 18755af02db5a48476e0748f135369663080eae87c64John McCall unsigned CurrentOffsetInBytes = 4 * 2; 18765af02db5a48476e0748f135369663080eae87c64John McCall 18775af02db5a48476e0748f135369663080eae87c64John McCall // And either 2 or 4 pointers. 18785af02db5a48476e0748f135369663080eae87c64John McCall CurrentOffsetInBytes += (HasCopyAndDispose ? 4 : 2) * 18795af02db5a48476e0748f135369663080eae87c64John McCall CGM.getTargetData().getTypeAllocSize(Int8PtrTy); 18805af02db5a48476e0748f135369663080eae87c64John McCall 18815af02db5a48476e0748f135369663080eae87c64John McCall // Align the offset. 18825af02db5a48476e0748f135369663080eae87c64John McCall unsigned AlignedOffsetInBytes = 18835af02db5a48476e0748f135369663080eae87c64John McCall llvm::RoundUpToAlignment(CurrentOffsetInBytes, Align.getQuantity()); 18845af02db5a48476e0748f135369663080eae87c64John McCall 18855af02db5a48476e0748f135369663080eae87c64John McCall unsigned NumPaddingBytes = AlignedOffsetInBytes - CurrentOffsetInBytes; 18865af02db5a48476e0748f135369663080eae87c64John McCall if (NumPaddingBytes > 0) { 18878b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattner llvm::Type *Ty = Int8Ty; 18885af02db5a48476e0748f135369663080eae87c64John McCall // FIXME: We need a sema error for alignment larger than the minimum of 18890774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall // the maximal stack alignment and the alignment of malloc on the system. 18905af02db5a48476e0748f135369663080eae87c64John McCall if (NumPaddingBytes > 1) 18915af02db5a48476e0748f135369663080eae87c64John McCall Ty = llvm::ArrayType::get(Ty, NumPaddingBytes); 18925af02db5a48476e0748f135369663080eae87c64John McCall 18930774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall types.push_back(Ty); 18945af02db5a48476e0748f135369663080eae87c64John McCall 18955af02db5a48476e0748f135369663080eae87c64John McCall // We want a packed struct. 18965af02db5a48476e0748f135369663080eae87c64John McCall Packed = true; 18975af02db5a48476e0748f135369663080eae87c64John McCall } 18985af02db5a48476e0748f135369663080eae87c64John McCall } 18995af02db5a48476e0748f135369663080eae87c64John McCall 19005af02db5a48476e0748f135369663080eae87c64John McCall // T x; 19010774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall types.push_back(ConvertTypeForMem(Ty)); 19025af02db5a48476e0748f135369663080eae87c64John McCall 19039cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner ByRefType->setBody(types, Packed); 19045af02db5a48476e0748f135369663080eae87c64John McCall 19059cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner Info.first = ByRefType; 19065af02db5a48476e0748f135369663080eae87c64John McCall 19070774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall Info.second = types.size() - 1; 19085af02db5a48476e0748f135369663080eae87c64John McCall 19095af02db5a48476e0748f135369663080eae87c64John McCall return Info.first; 19105af02db5a48476e0748f135369663080eae87c64John McCall} 19115af02db5a48476e0748f135369663080eae87c64John McCall 19125af02db5a48476e0748f135369663080eae87c64John McCall/// Initialize the structural components of a __block variable, i.e. 19135af02db5a48476e0748f135369663080eae87c64John McCall/// everything but the actual object. 19145af02db5a48476e0748f135369663080eae87c64John McCallvoid CodeGenFunction::emitByrefStructureInit(const AutoVarEmission &emission) { 1915f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall // Find the address of the local. 1916f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall llvm::Value *addr = emission.Address; 1917f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall 1918f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall // That's an alloca of the byref structure type. 19192acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::StructType *byrefType = cast<llvm::StructType>( 1920f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall cast<llvm::PointerType>(addr->getType())->getElementType()); 19215af02db5a48476e0748f135369663080eae87c64John McCall 1922f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall // Build the byref helpers if necessary. This is null if we don't need any. 1923f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall CodeGenModule::ByrefHelpers *helpers = 1924f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall buildByrefHelpers(*byrefType, emission); 19255af02db5a48476e0748f135369663080eae87c64John McCall 19265af02db5a48476e0748f135369663080eae87c64John McCall const VarDecl &D = *emission.Variable; 19275af02db5a48476e0748f135369663080eae87c64John McCall QualType type = D.getType(); 19285af02db5a48476e0748f135369663080eae87c64John McCall 1929f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall llvm::Value *V; 19305af02db5a48476e0748f135369663080eae87c64John McCall 19315af02db5a48476e0748f135369663080eae87c64John McCall // Initialize the 'isa', which is just 0 or 1. 19325af02db5a48476e0748f135369663080eae87c64John McCall int isa = 0; 1933f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall if (type.isObjCGCWeak()) 19345af02db5a48476e0748f135369663080eae87c64John McCall isa = 1; 19355af02db5a48476e0748f135369663080eae87c64John McCall V = Builder.CreateIntToPtr(Builder.getInt32(isa), Int8PtrTy, "isa"); 19365af02db5a48476e0748f135369663080eae87c64John McCall Builder.CreateStore(V, Builder.CreateStructGEP(addr, 0, "byref.isa")); 19375af02db5a48476e0748f135369663080eae87c64John McCall 19385af02db5a48476e0748f135369663080eae87c64John McCall // Store the address of the variable into its own forwarding pointer. 19395af02db5a48476e0748f135369663080eae87c64John McCall Builder.CreateStore(addr, 19405af02db5a48476e0748f135369663080eae87c64John McCall Builder.CreateStructGEP(addr, 1, "byref.forwarding")); 19415af02db5a48476e0748f135369663080eae87c64John McCall 19425af02db5a48476e0748f135369663080eae87c64John McCall // Blocks ABI: 19435af02db5a48476e0748f135369663080eae87c64John McCall // c) the flags field is set to either 0 if no helper functions are 19445af02db5a48476e0748f135369663080eae87c64John McCall // needed or BLOCK_HAS_COPY_DISPOSE if they are, 19455af02db5a48476e0748f135369663080eae87c64John McCall BlockFlags flags; 1946f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall if (helpers) flags |= BLOCK_HAS_COPY_DISPOSE; 19475af02db5a48476e0748f135369663080eae87c64John McCall Builder.CreateStore(llvm::ConstantInt::get(IntTy, flags.getBitMask()), 19485af02db5a48476e0748f135369663080eae87c64John McCall Builder.CreateStructGEP(addr, 2, "byref.flags")); 19495af02db5a48476e0748f135369663080eae87c64John McCall 1950f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall CharUnits byrefSize = CGM.GetTargetTypeStoreSize(byrefType); 1951f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall V = llvm::ConstantInt::get(IntTy, byrefSize.getQuantity()); 19525af02db5a48476e0748f135369663080eae87c64John McCall Builder.CreateStore(V, Builder.CreateStructGEP(addr, 3, "byref.size")); 19535af02db5a48476e0748f135369663080eae87c64John McCall 1954f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall if (helpers) { 19555af02db5a48476e0748f135369663080eae87c64John McCall llvm::Value *copy_helper = Builder.CreateStructGEP(addr, 4); 1956f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall Builder.CreateStore(helpers->CopyHelper, copy_helper); 19575af02db5a48476e0748f135369663080eae87c64John McCall 19585af02db5a48476e0748f135369663080eae87c64John McCall llvm::Value *destroy_helper = Builder.CreateStructGEP(addr, 5); 1959f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall Builder.CreateStore(helpers->DisposeHelper, destroy_helper); 19605af02db5a48476e0748f135369663080eae87c64John McCall } 19615af02db5a48476e0748f135369663080eae87c64John McCall} 19625af02db5a48476e0748f135369663080eae87c64John McCall 1963d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCallvoid CodeGenFunction::BuildBlockRelease(llvm::Value *V, BlockFieldFlags flags) { 1964673431a2986f750b4d8fadb57abf3f00db27bbbdDaniel Dunbar llvm::Value *F = CGM.getBlockObjectDispose(); 19651851b68aaa6717783609f366f5d87bbd0030f189Mike Stump llvm::Value *N; 1966d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall V = Builder.CreateBitCast(V, Int8PtrTy); 1967d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall N = llvm::ConstantInt::get(Int32Ty, flags.getBitMask()); 1968797b6327571f9d7b1c45404a56ddcbf9b9298ae8Mike Stump Builder.CreateCall2(F, V, N); 1969797b6327571f9d7b1c45404a56ddcbf9b9298ae8Mike Stump} 19705af02db5a48476e0748f135369663080eae87c64John McCall 19715af02db5a48476e0748f135369663080eae87c64John McCallnamespace { 19725af02db5a48476e0748f135369663080eae87c64John McCall struct CallBlockRelease : EHScopeStack::Cleanup { 19735af02db5a48476e0748f135369663080eae87c64John McCall llvm::Value *Addr; 19745af02db5a48476e0748f135369663080eae87c64John McCall CallBlockRelease(llvm::Value *Addr) : Addr(Addr) {} 19755af02db5a48476e0748f135369663080eae87c64John McCall 1976ad346f4f678ab1c3222425641d851dc63e9dfa1aJohn McCall void Emit(CodeGenFunction &CGF, Flags flags) { 1977f85e193739c953358c865005855253af4f68a497John McCall // Should we be passing FIELD_IS_WEAK here? 19785af02db5a48476e0748f135369663080eae87c64John McCall CGF.BuildBlockRelease(Addr, BLOCK_FIELD_IS_BYREF); 19795af02db5a48476e0748f135369663080eae87c64John McCall } 19805af02db5a48476e0748f135369663080eae87c64John McCall }; 19815af02db5a48476e0748f135369663080eae87c64John McCall} 19825af02db5a48476e0748f135369663080eae87c64John McCall 19835af02db5a48476e0748f135369663080eae87c64John McCall/// Enter a cleanup to destroy a __block variable. Note that this 19845af02db5a48476e0748f135369663080eae87c64John McCall/// cleanup should be a no-op if the variable hasn't left the stack 19855af02db5a48476e0748f135369663080eae87c64John McCall/// yet; if a cleanup is required for the variable itself, that needs 19865af02db5a48476e0748f135369663080eae87c64John McCall/// to be done externally. 19875af02db5a48476e0748f135369663080eae87c64John McCallvoid CodeGenFunction::enterByrefCleanup(const AutoVarEmission &emission) { 19885af02db5a48476e0748f135369663080eae87c64John McCall // We don't enter this cleanup if we're in pure-GC mode. 19894e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (CGM.getLangOpts().getGC() == LangOptions::GCOnly) 19905af02db5a48476e0748f135369663080eae87c64John McCall return; 19915af02db5a48476e0748f135369663080eae87c64John McCall 19925af02db5a48476e0748f135369663080eae87c64John McCall EHStack.pushCleanup<CallBlockRelease>(NormalAndEHCleanup, emission.Address); 19935af02db5a48476e0748f135369663080eae87c64John McCall} 199413db5cfc4e5f03eb70efe0d227b53b8280f16161John McCall 199513db5cfc4e5f03eb70efe0d227b53b8280f16161John McCall/// Adjust the declaration of something from the blocks API. 199613db5cfc4e5f03eb70efe0d227b53b8280f16161John McCallstatic void configureBlocksRuntimeObject(CodeGenModule &CGM, 199713db5cfc4e5f03eb70efe0d227b53b8280f16161John McCall llvm::Constant *C) { 19984e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (!CGM.getLangOpts().BlocksRuntimeOptional) return; 199913db5cfc4e5f03eb70efe0d227b53b8280f16161John McCall 200013db5cfc4e5f03eb70efe0d227b53b8280f16161John McCall llvm::GlobalValue *GV = cast<llvm::GlobalValue>(C->stripPointerCasts()); 200113db5cfc4e5f03eb70efe0d227b53b8280f16161John McCall if (GV->isDeclaration() && 200213db5cfc4e5f03eb70efe0d227b53b8280f16161John McCall GV->getLinkage() == llvm::GlobalValue::ExternalLinkage) 200313db5cfc4e5f03eb70efe0d227b53b8280f16161John McCall GV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage); 200413db5cfc4e5f03eb70efe0d227b53b8280f16161John McCall} 200513db5cfc4e5f03eb70efe0d227b53b8280f16161John McCall 200613db5cfc4e5f03eb70efe0d227b53b8280f16161John McCallllvm::Constant *CodeGenModule::getBlockObjectDispose() { 200713db5cfc4e5f03eb70efe0d227b53b8280f16161John McCall if (BlockObjectDispose) 200813db5cfc4e5f03eb70efe0d227b53b8280f16161John McCall return BlockObjectDispose; 200913db5cfc4e5f03eb70efe0d227b53b8280f16161John McCall 201013db5cfc4e5f03eb70efe0d227b53b8280f16161John McCall llvm::Type *args[] = { Int8PtrTy, Int32Ty }; 201113db5cfc4e5f03eb70efe0d227b53b8280f16161John McCall llvm::FunctionType *fty 201213db5cfc4e5f03eb70efe0d227b53b8280f16161John McCall = llvm::FunctionType::get(VoidTy, args, false); 201313db5cfc4e5f03eb70efe0d227b53b8280f16161John McCall BlockObjectDispose = CreateRuntimeFunction(fty, "_Block_object_dispose"); 201413db5cfc4e5f03eb70efe0d227b53b8280f16161John McCall configureBlocksRuntimeObject(*this, BlockObjectDispose); 201513db5cfc4e5f03eb70efe0d227b53b8280f16161John McCall return BlockObjectDispose; 201613db5cfc4e5f03eb70efe0d227b53b8280f16161John McCall} 201713db5cfc4e5f03eb70efe0d227b53b8280f16161John McCall 201813db5cfc4e5f03eb70efe0d227b53b8280f16161John McCallllvm::Constant *CodeGenModule::getBlockObjectAssign() { 201913db5cfc4e5f03eb70efe0d227b53b8280f16161John McCall if (BlockObjectAssign) 202013db5cfc4e5f03eb70efe0d227b53b8280f16161John McCall return BlockObjectAssign; 202113db5cfc4e5f03eb70efe0d227b53b8280f16161John McCall 202213db5cfc4e5f03eb70efe0d227b53b8280f16161John McCall llvm::Type *args[] = { Int8PtrTy, Int8PtrTy, Int32Ty }; 202313db5cfc4e5f03eb70efe0d227b53b8280f16161John McCall llvm::FunctionType *fty 202413db5cfc4e5f03eb70efe0d227b53b8280f16161John McCall = llvm::FunctionType::get(VoidTy, args, false); 202513db5cfc4e5f03eb70efe0d227b53b8280f16161John McCall BlockObjectAssign = CreateRuntimeFunction(fty, "_Block_object_assign"); 202613db5cfc4e5f03eb70efe0d227b53b8280f16161John McCall configureBlocksRuntimeObject(*this, BlockObjectAssign); 202713db5cfc4e5f03eb70efe0d227b53b8280f16161John McCall return BlockObjectAssign; 202813db5cfc4e5f03eb70efe0d227b53b8280f16161John McCall} 202913db5cfc4e5f03eb70efe0d227b53b8280f16161John McCall 203013db5cfc4e5f03eb70efe0d227b53b8280f16161John McCallllvm::Constant *CodeGenModule::getNSConcreteGlobalBlock() { 203113db5cfc4e5f03eb70efe0d227b53b8280f16161John McCall if (NSConcreteGlobalBlock) 203213db5cfc4e5f03eb70efe0d227b53b8280f16161John McCall return NSConcreteGlobalBlock; 203313db5cfc4e5f03eb70efe0d227b53b8280f16161John McCall 203413db5cfc4e5f03eb70efe0d227b53b8280f16161John McCall NSConcreteGlobalBlock = GetOrCreateLLVMGlobal("_NSConcreteGlobalBlock", 203513db5cfc4e5f03eb70efe0d227b53b8280f16161John McCall Int8PtrTy->getPointerTo(), 0); 203613db5cfc4e5f03eb70efe0d227b53b8280f16161John McCall configureBlocksRuntimeObject(*this, NSConcreteGlobalBlock); 203713db5cfc4e5f03eb70efe0d227b53b8280f16161John McCall return NSConcreteGlobalBlock; 203813db5cfc4e5f03eb70efe0d227b53b8280f16161John McCall} 203913db5cfc4e5f03eb70efe0d227b53b8280f16161John McCall 204013db5cfc4e5f03eb70efe0d227b53b8280f16161John McCallllvm::Constant *CodeGenModule::getNSConcreteStackBlock() { 204113db5cfc4e5f03eb70efe0d227b53b8280f16161John McCall if (NSConcreteStackBlock) 204213db5cfc4e5f03eb70efe0d227b53b8280f16161John McCall return NSConcreteStackBlock; 204313db5cfc4e5f03eb70efe0d227b53b8280f16161John McCall 204413db5cfc4e5f03eb70efe0d227b53b8280f16161John McCall NSConcreteStackBlock = GetOrCreateLLVMGlobal("_NSConcreteStackBlock", 204513db5cfc4e5f03eb70efe0d227b53b8280f16161John McCall Int8PtrTy->getPointerTo(), 0); 204613db5cfc4e5f03eb70efe0d227b53b8280f16161John McCall configureBlocksRuntimeObject(*this, NSConcreteStackBlock); 204713db5cfc4e5f03eb70efe0d227b53b8280f16161John McCall return NSConcreteStackBlock; 204813db5cfc4e5f03eb70efe0d227b53b8280f16161John McCall} 2049