187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar//===--- CGBlocks.cpp - Emit LLVM Code for declarations ---------*- C++ -*-===// 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 1455fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "CGBlocks.h" 15b1a6e687967105bf1e18dfba196d0248e6700a4eMike Stump#include "CGDebugInfo.h" 16263c4dec5f0fda5a77ed99f3ccd456c15cb8720fFariborz Jahanian#include "CGObjCRuntime.h" 1755fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "CodeGenFunction.h" 18acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson#include "CodeGenModule.h" 196cc88f78fd36d3511b89412b193494b3e423cbffMike Stump#include "clang/AST/DeclObjC.h" 206876fe615e16b0e76c7711e129e470305b7e9d41Benjamin Kramer#include "llvm/ADT/SmallSet.h" 21651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#include "llvm/IR/CallSite.h" 223b844ba7d5be205a9b4f5f0b0d1b7978977f4b8cChandler Carruth#include "llvm/IR/DataLayout.h" 233b844ba7d5be205a9b4f5f0b0d1b7978977f4b8cChandler Carruth#include "llvm/IR/Module.h" 24acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson#include <algorithm> 257d4b9fabf3778ca90aa45392a49cb9c082709929Fariborz Jahanian#include <cstdio> 26f42e4a6e089e8413247400fe58ad299193371f9cTorok Edwin 27acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlssonusing namespace clang; 28acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlssonusing namespace CodeGen; 29acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson 301a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCallCGBlockInfo::CGBlockInfo(const BlockDecl *block, StringRef name) 311a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall : Name(name), CXXThisIndex(0), CanBeGlobal(false), NeedsCopyDispose(false), 32f22ae6512dec60d9e526fe55b988f8d42ced5b57Fariborz Jahanian HasCXXObject(false), UsesStret(false), HasCapturedVariableLayout(false), 3387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar LocalAddress(Address::invalid()), StructureType(nullptr), Block(block), 346bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines DominatingIP(nullptr) { 356bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 361a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall // Skip asm prefix, if any. 'name' is usually taken directly from 371a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall // the mangled name of the enclosing function. 381a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall if (!name.empty() && name[0] == '\01') 391a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall name = name.substr(1); 40ee5042903d53fa7b0fbc1902d0ea07d57c7775b1John McCall} 41ee5042903d53fa7b0fbc1902d0ea07d57c7775b1John McCall 42f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall// Anchor the vtable to this translation unit. 4387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga NainarBlockByrefHelpers::~BlockByrefHelpers() {} 44f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall 456b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall/// Build the given block as a global block. 466b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCallstatic llvm::Constant *buildGlobalBlock(CodeGenModule &CGM, 476b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall const CGBlockInfo &blockInfo, 486b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall llvm::Constant *blockFn); 49ee5042903d53fa7b0fbc1902d0ea07d57c7775b1John McCall 506b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall/// Build the helper function to copy a block. 516b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCallstatic llvm::Constant *buildCopyHelper(CodeGenModule &CGM, 526b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall const CGBlockInfo &blockInfo) { 536b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall return CodeGenFunction(CGM).GenerateCopyHelperFunction(blockInfo); 546b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall} 556b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 56651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// Build the helper function to dispose of a block. 576b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCallstatic llvm::Constant *buildDisposeHelper(CodeGenModule &CGM, 586b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall const CGBlockInfo &blockInfo) { 596b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall return CodeGenFunction(CGM).GenerateDestroyHelperFunction(blockInfo); 606b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall} 616b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 62af879c0222791b5e026653a834df1c5c1fb41552Fariborz Jahanian/// buildBlockDescriptor - Build the block descriptor meta-data for a block. 63af879c0222791b5e026653a834df1c5c1fb41552Fariborz Jahanian/// buildBlockDescriptor is accessed from 5th field of the Block_literal 64af879c0222791b5e026653a834df1c5c1fb41552Fariborz Jahanian/// meta-data and contains stationary information about the block literal. 65af879c0222791b5e026653a834df1c5c1fb41552Fariborz Jahanian/// Its definition will have 4 (or optinally 6) words. 6641487f37d3174dcf827761d7c95a7e9d4ffdf56dDmitri Gribenko/// \code 67af879c0222791b5e026653a834df1c5c1fb41552Fariborz Jahanian/// struct Block_descriptor { 68af879c0222791b5e026653a834df1c5c1fb41552Fariborz Jahanian/// unsigned long reserved; 69af879c0222791b5e026653a834df1c5c1fb41552Fariborz Jahanian/// unsigned long size; // size of Block_literal metadata in bytes. 70af879c0222791b5e026653a834df1c5c1fb41552Fariborz Jahanian/// void *copy_func_helper_decl; // optional copy helper. 71af879c0222791b5e026653a834df1c5c1fb41552Fariborz Jahanian/// void *destroy_func_decl; // optioanl destructor helper. 7241487f37d3174dcf827761d7c95a7e9d4ffdf56dDmitri Gribenko/// void *block_method_encoding_address; // @encode for block literal signature. 73af879c0222791b5e026653a834df1c5c1fb41552Fariborz Jahanian/// void *block_layout_info; // encoding of captured block variables. 74af879c0222791b5e026653a834df1c5c1fb41552Fariborz Jahanian/// }; 7541487f37d3174dcf827761d7c95a7e9d4ffdf56dDmitri Gribenko/// \endcode 766b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCallstatic llvm::Constant *buildBlockDescriptor(CodeGenModule &CGM, 776b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall const CGBlockInfo &blockInfo) { 786b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall ASTContext &C = CGM.getContext(); 796b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 802acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *ulong = CGM.getTypes().ConvertType(C.UnsignedLongTy); 8187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar llvm::Type *i8p = nullptr; 82176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (CGM.getLangOpts().OpenCL) 83176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines i8p = 84176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines llvm::Type::getInt8PtrTy( 85176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines CGM.getLLVMContext(), C.getTargetAddressSpace(LangAS::opencl_constant)); 86176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines else 87176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines i8p = CGM.getTypes().ConvertType(C.VoidPtrTy); 886b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 895f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<llvm::Constant*, 6> elements; 90e5fee25e71266712522cff554f25c59b3078a429Mike Stump 91e5fee25e71266712522cff554f25c59b3078a429Mike Stump // reserved 926b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall elements.push_back(llvm::ConstantInt::get(ulong, 0)); 93e5fee25e71266712522cff554f25c59b3078a429Mike Stump 94e5fee25e71266712522cff554f25c59b3078a429Mike Stump // Size 95d6840002c37ba25effe5eb4bb89c4ae2e1d80945Mike Stump // FIXME: What is the right way to say this doesn't fit? We should give 96d6840002c37ba25effe5eb4bb89c4ae2e1d80945Mike Stump // a user diagnostic in that case. Better fix would be to change the 97d6840002c37ba25effe5eb4bb89c4ae2e1d80945Mike Stump // API to size_t. 986b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall elements.push_back(llvm::ConstantInt::get(ulong, 996b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall blockInfo.BlockSize.getQuantity())); 100e5fee25e71266712522cff554f25c59b3078a429Mike Stump 1016b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // Optional copy/dispose helpers. 1026b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall if (blockInfo.NeedsCopyDispose) { 103e5fee25e71266712522cff554f25c59b3078a429Mike Stump // copy_func_helper_decl 1046b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall elements.push_back(buildCopyHelper(CGM, blockInfo)); 105e5fee25e71266712522cff554f25c59b3078a429Mike Stump 106e5fee25e71266712522cff554f25c59b3078a429Mike Stump // destroy_func_decl 1076b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall elements.push_back(buildDisposeHelper(CGM, blockInfo)); 108e5fee25e71266712522cff554f25c59b3078a429Mike Stump } 109e5fee25e71266712522cff554f25c59b3078a429Mike Stump 1106b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // Signature. Mandatory ObjC-style method descriptor @encode sequence. 1116b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall std::string typeAtEncoding = 1126b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall CGM.getContext().getObjCEncodingForBlock(blockInfo.getBlockExpr()); 1136b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall elements.push_back(llvm::ConstantExpr::getBitCast( 11487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar CGM.GetAddrOfConstantCString(typeAtEncoding).getPointer(), i8p)); 1152a7eb28397148079cbc8e54e8a3871ef01c4f4bcBlaine Garst 1166b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // GC layout. 117c46b43517a18c8f41934a38a3580bd477ab54265Fariborz Jahanian if (C.getLangOpts().ObjC1) { 118c46b43517a18c8f41934a38a3580bd477ab54265Fariborz Jahanian if (CGM.getLangOpts().getGC() != LangOptions::NonGC) 119c46b43517a18c8f41934a38a3580bd477ab54265Fariborz Jahanian elements.push_back(CGM.getObjCRuntime().BuildGCBlockLayout(CGM, blockInfo)); 120c46b43517a18c8f41934a38a3580bd477ab54265Fariborz Jahanian else 121c46b43517a18c8f41934a38a3580bd477ab54265Fariborz Jahanian elements.push_back(CGM.getObjCRuntime().BuildRCBlockLayout(CGM, blockInfo)); 122c46b43517a18c8f41934a38a3580bd477ab54265Fariborz Jahanian } 1236b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall else 1246b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall elements.push_back(llvm::Constant::getNullValue(i8p)); 125ea1471e0e967548c596a71469702f8846dbaf3c0John McCall 126c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner llvm::Constant *init = llvm::ConstantStruct::getAnon(elements); 1274de9fce48e42cc7ec1345c0fd21b3dbc5b9114c8Anders Carlsson 1286b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall llvm::GlobalVariable *global = 1296b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall new llvm::GlobalVariable(CGM.getModule(), init->getType(), true, 1306b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall llvm::GlobalValue::InternalLinkage, 1316b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall init, "__block_descriptor_tmp"); 132ea26cb522e88fc86b0d1cae61dcefcfe4cc20231Mike Stump 1336b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall return llvm::ConstantExpr::getBitCast(global, CGM.getBlockDescriptorType()); 1344de9fce48e42cc7ec1345c0fd21b3dbc5b9114c8Anders Carlsson} 1354de9fce48e42cc7ec1345c0fd21b3dbc5b9114c8Anders Carlsson 1366b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall/* 1376b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall Purely notional variadic template describing the layout of a block. 1386b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 1396b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall template <class _ResultType, class... _ParamTypes, class... _CaptureTypes> 1406b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall struct Block_literal { 1416b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall /// Initialized to one of: 1426b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall /// extern void *_NSConcreteStackBlock[]; 1436b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall /// extern void *_NSConcreteGlobalBlock[]; 1446b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall /// 1456b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall /// In theory, we could start one off malloc'ed by setting 1466b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall /// BLOCK_NEEDS_FREE, giving it a refcount of 1, and using 1476b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall /// this isa: 1486b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall /// extern void *_NSConcreteMallocBlock[]; 1496b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall struct objc_class *isa; 1506b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 1516b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall /// These are the flags (with corresponding bit number) that the 1526b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall /// compiler is actually supposed to know about. 1536b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall /// 25. BLOCK_HAS_COPY_DISPOSE - indicates that the block 1546b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall /// descriptor provides copy and dispose helper functions 1556b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall /// 26. BLOCK_HAS_CXX_OBJ - indicates that there's a captured 1566b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall /// object with a nontrivial destructor or copy constructor 1576b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall /// 28. BLOCK_IS_GLOBAL - indicates that the block is allocated 1586b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall /// as global memory 1596b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall /// 29. BLOCK_USE_STRET - indicates that the block function 1606b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall /// uses stret, which objc_msgSend needs to know about 1616b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall /// 30. BLOCK_HAS_SIGNATURE - indicates that the block has an 1626b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall /// @encoded signature string 1636b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall /// And we're not supposed to manipulate these: 1646b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall /// 24. BLOCK_NEEDS_FREE - indicates that the block has been moved 1656b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall /// to malloc'ed memory 1666b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall /// 27. BLOCK_IS_GC - indicates that the block has been moved to 1676b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall /// to GC-allocated memory 1686b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall /// Additionally, the bottom 16 bits are a reference count which 1696b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall /// should be zero on the stack. 1706b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall int flags; 1716b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 1726b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall /// Reserved; should be zero-initialized. 1736b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall int reserved; 1746b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 1756b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall /// Function pointer generated from block literal. 1766b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall _ResultType (*invoke)(Block_literal *, _ParamTypes...); 1776b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 1786b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall /// Block description metadata generated from block literal. 1796b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall struct Block_descriptor *block_descriptor; 1806b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 1816b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall /// Captured values follow. 1826b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall _CapturesTypes captures...; 1836b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall }; 1846b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall */ 1856b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 1866b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall/// The number of fields in a block header. 1876b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCallconst unsigned BlockHeaderSize = 5; 1886b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 1896b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCallnamespace { 1906b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall /// A chunk of data that we actually have to capture in the block. 1916b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall struct BlockLayoutChunk { 1926b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall CharUnits Alignment; 1936b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall CharUnits Size; 19490a2d39d3082518566d5a22409a7bbba0d42f054Fariborz Jahanian Qualifiers::ObjCLifetime Lifetime; 1956b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall const BlockDecl::Capture *Capture; // null for 'this' 196ef6de3da8572607f786303c07150daa6e140ab19Jay Foad llvm::Type *Type; 1976b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 1986b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall BlockLayoutChunk(CharUnits align, CharUnits size, 19990a2d39d3082518566d5a22409a7bbba0d42f054Fariborz Jahanian Qualifiers::ObjCLifetime lifetime, 2006b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall const BlockDecl::Capture *capture, 201ef6de3da8572607f786303c07150daa6e140ab19Jay Foad llvm::Type *type) 20290a2d39d3082518566d5a22409a7bbba0d42f054Fariborz Jahanian : Alignment(align), Size(size), Lifetime(lifetime), 20390a2d39d3082518566d5a22409a7bbba0d42f054Fariborz Jahanian Capture(capture), Type(type) {} 2046b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 2056b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall /// Tell the block info that this chunk has the given field index. 20687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar void setIndex(CGBlockInfo &info, unsigned index, CharUnits offset) { 20787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (!Capture) { 2086b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall info.CXXThisIndex = index; 20987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar info.CXXThisOffset = offset; 21087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } else { 21187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar info.Captures.insert({Capture->getVariable(), 21287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar CGBlockInfo::Capture::makeIndex(index, offset)}); 21387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 2146b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall } 2156b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall }; 2164de9fce48e42cc7ec1345c0fd21b3dbc5b9114c8Anders Carlsson 21790a2d39d3082518566d5a22409a7bbba0d42f054Fariborz Jahanian /// Order by 1) all __strong together 2) next, all byfref together 3) next, 21890a2d39d3082518566d5a22409a7bbba0d42f054Fariborz Jahanian /// all __weak together. Preserve descending alignment in all situations. 2196b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall bool operator<(const BlockLayoutChunk &left, const BlockLayoutChunk &right) { 22087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (left.Alignment != right.Alignment) 22187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar return left.Alignment > right.Alignment; 22287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 22387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar auto getPrefOrder = [](const BlockLayoutChunk &chunk) { 22487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (chunk.Capture && chunk.Capture->isByRef()) 22587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar return 1; 22687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (chunk.Lifetime == Qualifiers::OCL_Strong) 22787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar return 0; 22887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (chunk.Lifetime == Qualifiers::OCL_Weak) 22987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar return 2; 23087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar return 3; 23187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar }; 23287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 23387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar return getPrefOrder(left) < getPrefOrder(right); 2346b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall } 23587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar} // end anonymous namespace 23600470a1c4c44c5ed26bad9a38b4d3904b02d7a28Mike Stump 237461c9c1bc39ed8cbe8311f396f7ee3839e9fda53John McCall/// Determines if the given type is safe for constant capture in C++. 238461c9c1bc39ed8cbe8311f396f7ee3839e9fda53John McCallstatic bool isSafeForCXXConstantCapture(QualType type) { 239461c9c1bc39ed8cbe8311f396f7ee3839e9fda53John McCall const RecordType *recordType = 240461c9c1bc39ed8cbe8311f396f7ee3839e9fda53John McCall type->getBaseElementTypeUnsafe()->getAs<RecordType>(); 241461c9c1bc39ed8cbe8311f396f7ee3839e9fda53John McCall 242461c9c1bc39ed8cbe8311f396f7ee3839e9fda53John McCall // Only records can be unsafe. 243461c9c1bc39ed8cbe8311f396f7ee3839e9fda53John McCall if (!recordType) return true; 244461c9c1bc39ed8cbe8311f396f7ee3839e9fda53John McCall 2456bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const auto *record = cast<CXXRecordDecl>(recordType->getDecl()); 246461c9c1bc39ed8cbe8311f396f7ee3839e9fda53John McCall 247461c9c1bc39ed8cbe8311f396f7ee3839e9fda53John McCall // Maintain semantics for classes with non-trivial dtors or copy ctors. 248461c9c1bc39ed8cbe8311f396f7ee3839e9fda53John McCall if (!record->hasTrivialDestructor()) return false; 249426391cd51af86f9d59eceb0fb1c42153eccbb9aRichard Smith if (record->hasNonTrivialCopyConstructor()) return false; 250461c9c1bc39ed8cbe8311f396f7ee3839e9fda53John McCall 251461c9c1bc39ed8cbe8311f396f7ee3839e9fda53John McCall // Otherwise, we just have to make sure there aren't any mutable 252461c9c1bc39ed8cbe8311f396f7ee3839e9fda53John McCall // fields that might have changed since initialization. 2532bb110125e0e5adb7c1c65d12adfa34151ca1c47Douglas Gregor return !record->hasMutableFields(); 254461c9c1bc39ed8cbe8311f396f7ee3839e9fda53John McCall} 255461c9c1bc39ed8cbe8311f396f7ee3839e9fda53John McCall 2566b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall/// It is illegal to modify a const object after initialization. 2576b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall/// Therefore, if a const object has a constant initializer, we don't 2586b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall/// actually need to keep storage for it in the block; we'll just 2596b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall/// rematerialize it at the start of the block function. This is 2606b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall/// acceptable because we make no promises about address stability of 2616b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall/// captured variables. 2626b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCallstatic llvm::Constant *tryCaptureAsConstant(CodeGenModule &CGM, 2632d6a5670465cb3f1d811695a9f23e372508240d2Richard Smith CodeGenFunction *CGF, 2646b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall const VarDecl *var) { 2654967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // Return if this is a function paramter. We shouldn't try to 2664967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // rematerialize default arguments of function parameters. 2674967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (isa<ParmVarDecl>(var)) 2684967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar return nullptr; 2694967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 2706b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall QualType type = var->getType(); 2716b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 2726b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // We can only do this if the variable is const. 2736bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (!type.isConstQualified()) return nullptr; 2746b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 275461c9c1bc39ed8cbe8311f396f7ee3839e9fda53John McCall // Furthermore, in C++ we have to worry about mutable fields: 276461c9c1bc39ed8cbe8311f396f7ee3839e9fda53John McCall // C++ [dcl.type.cv]p4: 277461c9c1bc39ed8cbe8311f396f7ee3839e9fda53John McCall // Except that any class member declared mutable can be 278461c9c1bc39ed8cbe8311f396f7ee3839e9fda53John McCall // modified, any attempt to modify a const object during its 279461c9c1bc39ed8cbe8311f396f7ee3839e9fda53John McCall // lifetime results in undefined behavior. 2804e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (CGM.getLangOpts().CPlusPlus && !isSafeForCXXConstantCapture(type)) 2816bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 2826b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 2836b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // If the variable doesn't have any initializer (shouldn't this be 2846b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // invalid?), it's not clear what we should do. Maybe capture as 2856b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // zero? 2866b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall const Expr *init = var->getInit(); 2876bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (!init) return nullptr; 2886b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 2892d6a5670465cb3f1d811695a9f23e372508240d2Richard Smith return CGM.EmitConstantInit(*var, CGF); 2906b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall} 2915e530af5d51572a0ed5dbe50da54bd333840c63dDavid Chisnall 2926b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall/// Get the low bit of a nonzero character count. This is the 2936b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall/// alignment of the nth byte if the 0th byte is universally aligned. 2946b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCallstatic CharUnits getLowBit(CharUnits v) { 2956b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall return CharUnits::fromQuantity(v.getQuantity() & (~v.getQuantity() + 1)); 2966b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall} 2975e530af5d51572a0ed5dbe50da54bd333840c63dDavid Chisnall 2986b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCallstatic void initializeForBlockHeader(CodeGenModule &CGM, CGBlockInfo &info, 2995f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVectorImpl<llvm::Type*> &elementTypes) { 30087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // The header is basically 'struct { void *; int; int; void *; void *; }'. 30187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // Assert that that struct is packed. 30287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar assert(CGM.getIntSize() <= CGM.getPointerSize()); 30387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar assert(CGM.getIntAlign() <= CGM.getPointerAlign()); 30487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar assert((2 * CGM.getIntSize()).isMultipleOf(CGM.getPointerAlign())); 3055e530af5d51572a0ed5dbe50da54bd333840c63dDavid Chisnall 30687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar info.BlockAlign = CGM.getPointerAlign(); 30787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar info.BlockSize = 3 * CGM.getPointerSize() + 2 * CGM.getIntSize(); 3088a2b4b1c5b960710db95e9b296d9a600aee37c00Mike Stump 3096b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall assert(elementTypes.empty()); 31087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar elementTypes.push_back(CGM.VoidPtrTy); 31187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar elementTypes.push_back(CGM.IntTy); 31287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar elementTypes.push_back(CGM.IntTy); 31387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar elementTypes.push_back(CGM.VoidPtrTy); 3146b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall elementTypes.push_back(CGM.getBlockDescriptorType()); 3158a2b4b1c5b960710db95e9b296d9a600aee37c00Mike Stump 3166b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall assert(elementTypes.size() == BlockHeaderSize); 3176b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall} 3188a2b4b1c5b960710db95e9b296d9a600aee37c00Mike Stump 3196b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall/// Compute the layout of the given block. Attempts to lay the block 3206b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall/// out with minimal space requirements. 3212d6a5670465cb3f1d811695a9f23e372508240d2Richard Smithstatic void computeBlockInfo(CodeGenModule &CGM, CodeGenFunction *CGF, 3222d6a5670465cb3f1d811695a9f23e372508240d2Richard Smith CGBlockInfo &info) { 3236b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall ASTContext &C = CGM.getContext(); 3246b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall const BlockDecl *block = info.getBlockDecl(); 3250892099dbc640720400a1d9decd2733a09d733e5Mike Stump 3265f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<llvm::Type*, 8> elementTypes; 3276b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall initializeForBlockHeader(CGM, info, elementTypes); 32800470a1c4c44c5ed26bad9a38b4d3904b02d7a28Mike Stump 3296b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall if (!block->hasCaptures()) { 3306b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall info.StructureType = 3316b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall llvm::StructType::get(CGM.getLLVMContext(), elementTypes, true); 3326b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall info.CanBeGlobal = true; 3336b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall return; 3346b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall } 335f22ae6512dec60d9e526fe55b988f8d42ced5b57Fariborz Jahanian else if (C.getLangOpts().ObjC1 && 336f22ae6512dec60d9e526fe55b988f8d42ced5b57Fariborz Jahanian CGM.getLangOpts().getGC() == LangOptions::NonGC) 337f22ae6512dec60d9e526fe55b988f8d42ced5b57Fariborz Jahanian info.HasCapturedVariableLayout = true; 338f22ae6512dec60d9e526fe55b988f8d42ced5b57Fariborz Jahanian 3396b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // Collect the layout chunks. 3405f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<BlockLayoutChunk, 16> layout; 3416b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall layout.reserve(block->capturesCXXThis() + 3426b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall (block->capture_end() - block->capture_begin())); 343ea1471e0e967548c596a71469702f8846dbaf3c0John McCall 3446b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall CharUnits maxFieldAlign; 345ea1471e0e967548c596a71469702f8846dbaf3c0John McCall 3466b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // First, 'this'. 3476b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall if (block->capturesCXXThis()) { 348c1b8d095c18c3f55d662c49e59f7a934ae7e9440Eli Friedman assert(CGF && CGF->CurFuncDecl && isa<CXXMethodDecl>(CGF->CurFuncDecl) && 349c1b8d095c18c3f55d662c49e59f7a934ae7e9440Eli Friedman "Can't capture 'this' outside a method"); 350c1b8d095c18c3f55d662c49e59f7a934ae7e9440Eli Friedman QualType thisType = cast<CXXMethodDecl>(CGF->CurFuncDecl)->getThisType(C); 351ea1471e0e967548c596a71469702f8846dbaf3c0John McCall 35287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // Theoretically, this could be in a different address space, so 35387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // don't assume standard pointer size/align. 354ef6de3da8572607f786303c07150daa6e140ab19Jay Foad llvm::Type *llvmType = CGM.getTypes().ConvertType(thisType); 3556b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall std::pair<CharUnits,CharUnits> tinfo 3566b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall = CGM.getContext().getTypeInfoInChars(thisType); 3576b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall maxFieldAlign = std::max(maxFieldAlign, tinfo.second); 358ea1471e0e967548c596a71469702f8846dbaf3c0John McCall 35990a2d39d3082518566d5a22409a7bbba0d42f054Fariborz Jahanian layout.push_back(BlockLayoutChunk(tinfo.second, tinfo.first, 36090a2d39d3082518566d5a22409a7bbba0d42f054Fariborz Jahanian Qualifiers::OCL_None, 3616bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines nullptr, llvmType)); 3626b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall } 363ea1471e0e967548c596a71469702f8846dbaf3c0John McCall 3646b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // Next, all the block captures. 365651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (const auto &CI : block->captures()) { 366651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const VarDecl *variable = CI.getVariable(); 367ea1471e0e967548c596a71469702f8846dbaf3c0John McCall 368651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (CI.isByRef()) { 3696b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // We have to copy/dispose of the __block reference. 3706b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall info.NeedsCopyDispose = true; 3716b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 3726b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // Just use void* instead of a pointer to the byref type. 37387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar CharUnits align = CGM.getPointerAlign(); 37487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar maxFieldAlign = std::max(maxFieldAlign, align); 3756b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 37687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar layout.push_back(BlockLayoutChunk(align, CGM.getPointerSize(), 37787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar Qualifiers::OCL_None, &CI, 37887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar CGM.VoidPtrTy)); 3796b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall continue; 3806b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall } 3816b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 3826b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // Otherwise, build a layout chunk with the size and alignment of 3836b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // the declaration. 3842d6a5670465cb3f1d811695a9f23e372508240d2Richard Smith if (llvm::Constant *constant = tryCaptureAsConstant(CGM, CGF, variable)) { 3856b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall info.Captures[variable] = CGBlockInfo::Capture::makeConstant(constant); 3866b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall continue; 3876b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall } 3886b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 389f85e193739c953358c865005855253af4f68a497John McCall // If we have a lifetime qualifier, honor it for capture purposes. 390f85e193739c953358c865005855253af4f68a497John McCall // That includes *not* copying it if it's __unsafe_unretained. 39190a2d39d3082518566d5a22409a7bbba0d42f054Fariborz Jahanian Qualifiers::ObjCLifetime lifetime = 39290a2d39d3082518566d5a22409a7bbba0d42f054Fariborz Jahanian variable->getType().getObjCLifetime(); 39390a2d39d3082518566d5a22409a7bbba0d42f054Fariborz Jahanian if (lifetime) { 394f85e193739c953358c865005855253af4f68a497John McCall switch (lifetime) { 395f85e193739c953358c865005855253af4f68a497John McCall case Qualifiers::OCL_None: llvm_unreachable("impossible"); 396f85e193739c953358c865005855253af4f68a497John McCall case Qualifiers::OCL_ExplicitNone: 397f85e193739c953358c865005855253af4f68a497John McCall case Qualifiers::OCL_Autoreleasing: 398f85e193739c953358c865005855253af4f68a497John McCall break; 399f85e193739c953358c865005855253af4f68a497John McCall 400f85e193739c953358c865005855253af4f68a497John McCall case Qualifiers::OCL_Strong: 401f85e193739c953358c865005855253af4f68a497John McCall case Qualifiers::OCL_Weak: 402f85e193739c953358c865005855253af4f68a497John McCall info.NeedsCopyDispose = true; 403f85e193739c953358c865005855253af4f68a497John McCall } 4046b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 405f85e193739c953358c865005855253af4f68a497John McCall // Block pointers require copy/dispose. So do Objective-C pointers. 406f85e193739c953358c865005855253af4f68a497John McCall } else if (variable->getType()->isObjCRetainableType()) { 40787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // But honor the inert __unsafe_unretained qualifier, which doesn't 40887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // actually make it into the type system. 40987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (variable->getType()->isObjCInertUnsafeUnretainedType()) { 41087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar lifetime = Qualifiers::OCL_ExplicitNone; 41187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } else { 41287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar info.NeedsCopyDispose = true; 41387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // used for mrr below. 41487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar lifetime = Qualifiers::OCL_Strong; 41587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 4166b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 4176b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // So do types that require non-trivial copy construction. 418651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } else if (CI.hasCopyExpr()) { 4196b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall info.NeedsCopyDispose = true; 4206b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall info.HasCXXObject = true; 4216b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 4226b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // And so do types with destructors. 4234e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie } else if (CGM.getLangOpts().CPlusPlus) { 4246b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall if (const CXXRecordDecl *record = 4256b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall variable->getType()->getAsCXXRecordDecl()) { 4266b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall if (!record->hasTrivialDestructor()) { 4276b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall info.HasCXXObject = true; 4286b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall info.NeedsCopyDispose = true; 429ea1471e0e967548c596a71469702f8846dbaf3c0John McCall } 430f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall } 4316b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall } 4326b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 433c637d738897b1745af3bad7fc551f26b98da838cFariborz Jahanian QualType VT = variable->getType(); 434d8c4551fa22a9c346e6a9e56333915197c97e394Fariborz Jahanian CharUnits size = C.getTypeSizeInChars(VT); 435c637d738897b1745af3bad7fc551f26b98da838cFariborz Jahanian CharUnits align = C.getDeclAlign(variable); 436d8c4551fa22a9c346e6a9e56333915197c97e394Fariborz Jahanian 4376b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall maxFieldAlign = std::max(maxFieldAlign, align); 4386b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 439ef6de3da8572607f786303c07150daa6e140ab19Jay Foad llvm::Type *llvmType = 440d8c4551fa22a9c346e6a9e56333915197c97e394Fariborz Jahanian CGM.getTypes().ConvertTypeForMem(VT); 441d8c4551fa22a9c346e6a9e56333915197c97e394Fariborz Jahanian 442651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines layout.push_back(BlockLayoutChunk(align, size, lifetime, &CI, llvmType)); 4436b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall } 444ea1471e0e967548c596a71469702f8846dbaf3c0John McCall 4456b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // If that was everything, we're done here. 4466b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall if (layout.empty()) { 4476b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall info.StructureType = 4486b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall llvm::StructType::get(CGM.getLLVMContext(), elementTypes, true); 4496b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall info.CanBeGlobal = true; 4506b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall return; 4516b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall } 4526b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 4536b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // Sort the layout by alignment. We have to use a stable sort here 4546b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // to get reproducible results. There should probably be an 4556b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // llvm::array_pod_stable_sort. 4566b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall std::stable_sort(layout.begin(), layout.end()); 457ff685c562c8fd5dfc6effec17377fde9dad6f271Fariborz Jahanian 458ff685c562c8fd5dfc6effec17377fde9dad6f271Fariborz Jahanian // Needed for blocks layout info. 459ff685c562c8fd5dfc6effec17377fde9dad6f271Fariborz Jahanian info.BlockHeaderForcedGapOffset = info.BlockSize; 460ff685c562c8fd5dfc6effec17377fde9dad6f271Fariborz Jahanian info.BlockHeaderForcedGapSize = CharUnits::Zero(); 461ff685c562c8fd5dfc6effec17377fde9dad6f271Fariborz Jahanian 4626b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall CharUnits &blockSize = info.BlockSize; 4636b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall info.BlockAlign = std::max(maxFieldAlign, info.BlockAlign); 4646b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 4656b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // Assuming that the first byte in the header is maximally aligned, 4666b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // get the alignment of the first byte following the header. 4676b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall CharUnits endAlign = getLowBit(blockSize); 4686b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 4696b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // If the end of the header isn't satisfactorily aligned for the 4706b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // maximum thing, look for things that are okay with the header-end 4716b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // alignment, and keep appending them until we get something that's 4726b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // aligned right. This algorithm is only guaranteed optimal if 4736b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // that condition is satisfied at some point; otherwise we can get 4746b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // things like: 4756b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // header // next byte has alignment 4 4766b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // something_with_size_5; // next byte has alignment 1 4776b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // something_with_alignment_8; 4786b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // which has 7 bytes of padding, as opposed to the naive solution 4796b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // which might have less (?). 4806b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall if (endAlign < maxFieldAlign) { 4815f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVectorImpl<BlockLayoutChunk>::iterator 4826b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall li = layout.begin() + 1, le = layout.end(); 4836b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 4846b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // Look for something that the header end is already 4856b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // satisfactorily aligned for. 4866b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall for (; li != le && endAlign < li->Alignment; ++li) 4876b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall ; 4886b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 4896b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // If we found something that's naturally aligned for the end of 4906b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // the header, keep adding things... 4916b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall if (li != le) { 4925f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVectorImpl<BlockLayoutChunk>::iterator first = li; 4936b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall for (; li != le; ++li) { 4946b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall assert(endAlign >= li->Alignment); 4956b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 49687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar li->setIndex(info, elementTypes.size(), blockSize); 4976b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall elementTypes.push_back(li->Type); 4986b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall blockSize += li->Size; 4996b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall endAlign = getLowBit(blockSize); 5006b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 5016b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // ...until we get to the alignment of the maximum field. 502ff685c562c8fd5dfc6effec17377fde9dad6f271Fariborz Jahanian if (endAlign >= maxFieldAlign) { 5036b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall break; 504ff685c562c8fd5dfc6effec17377fde9dad6f271Fariborz Jahanian } 5058a2b4b1c5b960710db95e9b296d9a600aee37c00Mike Stump } 5066b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // Don't re-append everything we just appended. 5076b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall layout.erase(first, li); 5086b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall } 5096b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall } 5106b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 5116ea4841da1390b4f76d066f25333f11f6d8c5f40John McCall assert(endAlign == getLowBit(blockSize)); 512ff685c562c8fd5dfc6effec17377fde9dad6f271Fariborz Jahanian 5136b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // At this point, we just have to add padding if the end align still 5146b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // isn't aligned right. 5156b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall if (endAlign < maxFieldAlign) { 5164967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar CharUnits newBlockSize = blockSize.alignTo(maxFieldAlign); 5176ea4841da1390b4f76d066f25333f11f6d8c5f40John McCall CharUnits padding = newBlockSize - blockSize; 5186b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 51987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // If we haven't yet added any fields, remember that there was an 52087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // initial gap; this need to go into the block layout bit map. 52187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (blockSize == info.BlockHeaderForcedGapOffset) { 52287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar info.BlockHeaderForcedGapSize = padding; 52387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 52487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 5255936e33bf74dd6bf126ceee0f6169a2593d03a69John McCall elementTypes.push_back(llvm::ArrayType::get(CGM.Int8Ty, 5265936e33bf74dd6bf126ceee0f6169a2593d03a69John McCall padding.getQuantity())); 5276ea4841da1390b4f76d066f25333f11f6d8c5f40John McCall blockSize = newBlockSize; 5286c803f7f46533c69e2f8a9a882af9ae3b7fffb6fJohn McCall endAlign = getLowBit(blockSize); // might be > maxFieldAlign 5296b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall } 5306b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 5316c803f7f46533c69e2f8a9a882af9ae3b7fffb6fJohn McCall assert(endAlign >= maxFieldAlign); 5326ea4841da1390b4f76d066f25333f11f6d8c5f40John McCall assert(endAlign == getLowBit(blockSize)); 5336b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // Slam everything else on now. This works because they have 5346b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // strictly decreasing alignment and we expect that size is always a 5356b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // multiple of alignment. 5365f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner for (SmallVectorImpl<BlockLayoutChunk>::iterator 5376b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall li = layout.begin(), le = layout.end(); li != le; ++li) { 538176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (endAlign < li->Alignment) { 539176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // size may not be multiple of alignment. This can only happen with 540176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // an over-aligned variable. We will be adding a padding field to 541176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // make the size be multiple of alignment. 542176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines CharUnits padding = li->Alignment - endAlign; 543176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines elementTypes.push_back(llvm::ArrayType::get(CGM.Int8Ty, 544176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines padding.getQuantity())); 545176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines blockSize += padding; 546176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines endAlign = getLowBit(blockSize); 547176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 5486b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall assert(endAlign >= li->Alignment); 54987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar li->setIndex(info, elementTypes.size(), blockSize); 5506b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall elementTypes.push_back(li->Type); 5516b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall blockSize += li->Size; 5526b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall endAlign = getLowBit(blockSize); 5536b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall } 5546b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 5556b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall info.StructureType = 5566b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall llvm::StructType::get(CGM.getLLVMContext(), elementTypes, true); 5576b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall} 5586b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 5591a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall/// Enter the scope of a block. This should be run at the entrance to 5601a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall/// a full-expression so that the block's cleanups are pushed at the 5611a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall/// right place in the stack. 5621a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCallstatic void enterBlockScope(CodeGenFunction &CGF, BlockDecl *block) { 56338baeabb253f3e04d5b54bf834dbd9f5ebdc9e5cJohn McCall assert(CGF.HaveInsertPoint()); 56438baeabb253f3e04d5b54bf834dbd9f5ebdc9e5cJohn McCall 5651a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall // Allocate the block info and place it at the head of the list. 5661a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall CGBlockInfo &blockInfo = 5671a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall *new CGBlockInfo(block, CGF.CurFn->getName()); 5681a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall blockInfo.NextBlockInfo = CGF.FirstBlockInfo; 5691a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall CGF.FirstBlockInfo = &blockInfo; 5701a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall 5711a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall // Compute information about the layout, etc., of this block, 5721a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall // pushing cleanups as necessary. 5732d6a5670465cb3f1d811695a9f23e372508240d2Richard Smith computeBlockInfo(CGF.CGM, &CGF, blockInfo); 5741a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall 5751a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall // Nothing else to do if it can be global. 5761a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall if (blockInfo.CanBeGlobal) return; 5771a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall 5781a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall // Make the allocation for the block. 57987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar blockInfo.LocalAddress = CGF.CreateTempAlloca(blockInfo.StructureType, 58087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar blockInfo.BlockAlign, "block"); 5811a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall 5821a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall // If there are cleanups to emit, enter them (but inactive). 5831a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall if (!blockInfo.NeedsCopyDispose) return; 5841a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall 5851a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall // Walk through the captures (in order) and find the ones not 5861a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall // captured by constant. 587651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (const auto &CI : block->captures()) { 5881a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall // Ignore __block captures; there's nothing special in the 5891a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall // on-stack block that we need to do for them. 590651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (CI.isByRef()) continue; 5911a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall 5921a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall // Ignore variables that are constant-captured. 593651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const VarDecl *variable = CI.getVariable(); 5941a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall CGBlockInfo::Capture &capture = blockInfo.getCapture(variable); 5951a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall if (capture.isConstant()) continue; 5961a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall 5971a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall // Ignore objects that aren't destructed. 5981a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall QualType::DestructionKind dtorKind = 5991a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall variable->getType().isDestructedType(); 6001a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall if (dtorKind == QualType::DK_none) continue; 6011a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall 6021a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall CodeGenFunction::Destroyer *destroyer; 6031a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall 6041a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall // Block captures count as local values and have imprecise semantics. 6051a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall // They also can't be arrays, so need to worry about that. 6061a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall if (dtorKind == QualType::DK_objc_strong_lifetime) { 607516bbd42e62d709013824d6fb8445a0cfda3129aPeter Collingbourne destroyer = CodeGenFunction::destroyARCStrongImprecise; 6081a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall } else { 609516bbd42e62d709013824d6fb8445a0cfda3129aPeter Collingbourne destroyer = CGF.getDestroyer(dtorKind); 6101a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall } 6111a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall 6121a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall // GEP down to the address. 61387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar Address addr = CGF.Builder.CreateStructGEP(blockInfo.LocalAddress, 61487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar capture.getIndex(), 61587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar capture.getOffset()); 6161a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall 6176f103ba42cb69d50005a977c5ea583984ab63fc4John McCall // We can use that GEP as the dominating IP. 6186f103ba42cb69d50005a977c5ea583984ab63fc4John McCall if (!blockInfo.DominatingIP) 61987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar blockInfo.DominatingIP = cast<llvm::Instruction>(addr.getPointer()); 6206f103ba42cb69d50005a977c5ea583984ab63fc4John McCall 6211a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall CleanupKind cleanupKind = InactiveNormalCleanup; 6221a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall bool useArrayEHCleanup = CGF.needsEHCleanup(dtorKind); 6231a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall if (useArrayEHCleanup) 6241a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall cleanupKind = InactiveNormalAndEHCleanup; 6251a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall 6261a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall CGF.pushDestroy(cleanupKind, addr, variable->getType(), 627516bbd42e62d709013824d6fb8445a0cfda3129aPeter Collingbourne destroyer, useArrayEHCleanup); 6281a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall 6291a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall // Remember where that cleanup was. 6301a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall capture.setCleanup(CGF.EHStack.stable_begin()); 6311a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall } 6321a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall} 6331a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall 6341a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall/// Enter a full-expression with a non-trivial number of objects to 6351a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall/// clean up. This is in this file because, at the moment, the only 6361a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall/// kind of cleanup object is a BlockDecl*. 6371a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCallvoid CodeGenFunction::enterNonTrivialFullExpression(const ExprWithCleanups *E) { 6381a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall assert(E->getNumObjects() != 0); 6391a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall ArrayRef<ExprWithCleanups::CleanupObject> cleanups = E->getObjects(); 6401a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall for (ArrayRef<ExprWithCleanups::CleanupObject>::iterator 6411a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall i = cleanups.begin(), e = cleanups.end(); i != e; ++i) { 6421a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall enterBlockScope(*this, *i); 6431a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall } 6441a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall} 6451a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall 6461a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall/// Find the layout for the given block in a linked list and remove it. 6471a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCallstatic CGBlockInfo *findAndRemoveBlockInfo(CGBlockInfo **head, 6481a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall const BlockDecl *block) { 6491a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall while (true) { 6501a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall assert(head && *head); 6511a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall CGBlockInfo *cur = *head; 6521a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall 6531a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall // If this is the block we're looking for, splice it out of the list. 6541a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall if (cur->getBlockDecl() == block) { 6551a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall *head = cur->NextBlockInfo; 6561a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall return cur; 6571a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall } 6581a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall 6591a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall head = &cur->NextBlockInfo; 6601a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall } 6611a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall} 6621a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall 6631a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall/// Destroy a chain of block layouts. 6641a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCallvoid CodeGenFunction::destroyBlockInfos(CGBlockInfo *head) { 6651a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall assert(head && "destroying an empty chain"); 6661a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall do { 6671a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall CGBlockInfo *cur = head; 6681a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall head = cur->NextBlockInfo; 6691a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall delete cur; 6706bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } while (head != nullptr); 6711a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall} 6721a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall 6736b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall/// Emit a block literal expression in the current function. 6746b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCallllvm::Value *CodeGenFunction::EmitBlockLiteral(const BlockExpr *blockExpr) { 6751a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall // If the block has no captures, we won't have a pre-computed 6761a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall // layout for it. 6771a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall if (!blockExpr->getBlockDecl()->hasCaptures()) { 6781a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall CGBlockInfo blockInfo(blockExpr->getBlockDecl(), CurFn->getName()); 6792d6a5670465cb3f1d811695a9f23e372508240d2Richard Smith computeBlockInfo(CGM, this, blockInfo); 6801a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall blockInfo.BlockExpression = blockExpr; 6811a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall return EmitBlockLiteral(blockInfo); 6821a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall } 6836b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 6841a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall // Find the block info for this block and take ownership of it. 685651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::unique_ptr<CGBlockInfo> blockInfo; 6861a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall blockInfo.reset(findAndRemoveBlockInfo(&FirstBlockInfo, 6871a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall blockExpr->getBlockDecl())); 6886b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 6891a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall blockInfo->BlockExpression = blockExpr; 6901a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall return EmitBlockLiteral(*blockInfo); 6911a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall} 6921a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall 6931a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCallllvm::Value *CodeGenFunction::EmitBlockLiteral(const CGBlockInfo &blockInfo) { 6941a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall // Using the computed layout, generate the actual block function. 69523f0267e2d56c0407f12e62df3561ecf75d74e6eEli Friedman bool isLambdaConv = blockInfo.getBlockDecl()->isConversionFromLambda(); 6966b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall llvm::Constant *blockFn 6974904bf4e84cfb48080270ebaa9005327f18ab0e5Fariborz Jahanian = CodeGenFunction(CGM, true).GenerateBlockFunction(CurGD, blockInfo, 698f5ebf9bf1df10ac15ba32a4b24dfe171b7848c58John McCall LocalDeclMap, 699f5ebf9bf1df10ac15ba32a4b24dfe171b7848c58John McCall isLambdaConv); 7005936e33bf74dd6bf126ceee0f6169a2593d03a69John McCall blockFn = llvm::ConstantExpr::getBitCast(blockFn, VoidPtrTy); 7016b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 7026b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // If there is nothing to capture, we can emit this as a global block. 7036b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall if (blockInfo.CanBeGlobal) 7046b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall return buildGlobalBlock(CGM, blockInfo, blockFn); 7056b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 7066b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // Otherwise, we have to emit this as a local block. 7076b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 7086b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall llvm::Constant *isa = CGM.getNSConcreteStackBlock(); 7095936e33bf74dd6bf126ceee0f6169a2593d03a69John McCall isa = llvm::ConstantExpr::getBitCast(isa, VoidPtrTy); 7106b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 7116b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // Build the block descriptor. 7126b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall llvm::Constant *descriptor = buildBlockDescriptor(CGM, blockInfo); 7136b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 71487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar Address blockAddr = blockInfo.LocalAddress; 71587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar assert(blockAddr.isValid() && "block has no address!"); 7166b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 7176b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // Compute the initial on-stack block flags. 718d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall BlockFlags flags = BLOCK_HAS_SIGNATURE; 719f22ae6512dec60d9e526fe55b988f8d42ced5b57Fariborz Jahanian if (blockInfo.HasCapturedVariableLayout) flags |= BLOCK_HAS_EXTENDED_LAYOUT; 7206b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall if (blockInfo.NeedsCopyDispose) flags |= BLOCK_HAS_COPY_DISPOSE; 7216b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall if (blockInfo.HasCXXObject) flags |= BLOCK_HAS_CXX_OBJ; 72264cd2328ef55735c910d3d51dd40eafc38d7a504John McCall if (blockInfo.UsesStret) flags |= BLOCK_USE_STRET; 7236b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 72487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar auto projectField = 72587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar [&](unsigned index, CharUnits offset, const Twine &name) -> Address { 72687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar return Builder.CreateStructGEP(blockAddr, index, offset, name); 72787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar }; 72887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar auto storeField = 72987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar [&](llvm::Value *value, unsigned index, CharUnits offset, 73087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar const Twine &name) { 73187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar Builder.CreateStore(value, projectField(index, offset, name)); 73287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar }; 73387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 73487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // Initialize the block header. 73587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar { 73687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // We assume all the header fields are densely packed. 73787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar unsigned index = 0; 73887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar CharUnits offset; 73987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar auto addHeaderField = 74087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar [&](llvm::Value *value, CharUnits size, const Twine &name) { 74187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar storeField(value, index, offset, name); 74287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar offset += size; 74387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar index++; 74487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar }; 74587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 74687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar addHeaderField(isa, getPointerSize(), "block.isa"); 74787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar addHeaderField(llvm::ConstantInt::get(IntTy, flags.getBitMask()), 74887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar getIntSize(), "block.flags"); 74987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar addHeaderField(llvm::ConstantInt::get(IntTy, 0), 75087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar getIntSize(), "block.reserved"); 75187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar addHeaderField(blockFn, getPointerSize(), "block.invoke"); 75287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar addHeaderField(descriptor, getPointerSize(), "block.descriptor"); 75387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 7546b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 7556b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // Finally, capture all the values into the block. 7566b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall const BlockDecl *blockDecl = blockInfo.getBlockDecl(); 7576b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 7586b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // First, 'this'. 7596b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall if (blockDecl->capturesCXXThis()) { 76087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar Address addr = projectField(blockInfo.CXXThisIndex, blockInfo.CXXThisOffset, 76187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar "block.captured-this.addr"); 7626b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall Builder.CreateStore(LoadCXXThis(), addr); 7636b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall } 7646b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 7656b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // Next, captured variables. 766651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (const auto &CI : blockDecl->captures()) { 767651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const VarDecl *variable = CI.getVariable(); 7686b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall const CGBlockInfo::Capture &capture = blockInfo.getCapture(variable); 7696b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 7706b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // Ignore constant captures. 7716b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall if (capture.isConstant()) continue; 7726b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 7736b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall QualType type = variable->getType(); 7746b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 7756b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // This will be a [[type]]*, except that a byref entry will just be 7766b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // an i8**. 77787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar Address blockField = 77887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar projectField(capture.getIndex(), capture.getOffset(), "block.captured"); 7796b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 7806b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // Compute the address of the thing we're going to move into the 7816b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // block literal. 78287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar Address src = Address::invalid(); 7834967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 7844967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (blockDecl->isConversionFromLambda()) { 78564bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman // The lambda capture in a lambda's conversion-to-block-pointer is 78623f0267e2d56c0407f12e62df3561ecf75d74e6eEli Friedman // special; we'll simply emit it directly. 78787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar src = Address::invalid(); 7884967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } else if (CI.isByRef()) { 7894967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (BlockInfo && CI.isNested()) { 7904967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // We need to use the capture from the enclosing block. 7914967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar const CGBlockInfo::Capture &enclosingCapture = 7924967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar BlockInfo->getCapture(variable); 7934967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 7944967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // This is a [[type]]*, except that a byref entry wil just be an i8**. 7954967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar src = Builder.CreateStructGEP(LoadBlockStruct(), 7964967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar enclosingCapture.getIndex(), 7974967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar enclosingCapture.getOffset(), 7984967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar "block.capture.addr"); 79987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } else { 8004967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar auto I = LocalDeclMap.find(variable); 8014967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar assert(I != LocalDeclMap.end()); 8024967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar src = I->second; 8030353a7b2df9dc36784f9ec354c266f9c603053e1John McCall } 8044967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } else { 8054967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar DeclRefExpr declRef(const_cast<VarDecl *>(variable), 8064967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar /*RefersToEnclosingVariableOrCapture*/ CI.isNested(), 8074967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar type.getNonReferenceType(), VK_LValue, 8084967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar SourceLocation()); 8094967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar src = EmitDeclRefLValue(&declRef).getAddress(); 8104967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar }; 8116b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 8126b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // For byrefs, we just write the pointer to the byref struct into 8136b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // the block field. There's no need to chase the forwarding 8146b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // pointer at this point, since we're building something that will 8156b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // live a shorter life than the stack byref anyway. 816651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (CI.isByRef()) { 8175936e33bf74dd6bf126ceee0f6169a2593d03a69John McCall // Get a void* that points to the byref struct. 81887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar llvm::Value *byrefPointer; 819651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (CI.isNested()) 82087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar byrefPointer = Builder.CreateLoad(src, "byref.capture"); 821ea1471e0e967548c596a71469702f8846dbaf3c0John McCall else 82287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar byrefPointer = Builder.CreateBitCast(src.getPointer(), VoidPtrTy); 8236b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 8245936e33bf74dd6bf126ceee0f6169a2593d03a69John McCall // Write that void* into the capture field. 82587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar Builder.CreateStore(byrefPointer, blockField); 8266b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 8276b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // If we have a copy constructor, evaluate that into the block field. 828651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } else if (const Expr *copyExpr = CI.getCopyExpr()) { 82923f0267e2d56c0407f12e62df3561ecf75d74e6eEli Friedman if (blockDecl->isConversionFromLambda()) { 83023f0267e2d56c0407f12e62df3561ecf75d74e6eEli Friedman // If we have a lambda conversion, emit the expression 83123f0267e2d56c0407f12e62df3561ecf75d74e6eEli Friedman // directly into the block instead. 83223f0267e2d56c0407f12e62df3561ecf75d74e6eEli Friedman AggValueSlot Slot = 83387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar AggValueSlot::forAddr(blockField, Qualifiers(), 83423f0267e2d56c0407f12e62df3561ecf75d74e6eEli Friedman AggValueSlot::IsDestructed, 83523f0267e2d56c0407f12e62df3561ecf75d74e6eEli Friedman AggValueSlot::DoesNotNeedGCBarriers, 836649b4a1a9b5e6f768ca0cb84bd97b00f51083e15Chad Rosier AggValueSlot::IsNotAliased); 83723f0267e2d56c0407f12e62df3561ecf75d74e6eEli Friedman EmitAggExpr(copyExpr, Slot); 83823f0267e2d56c0407f12e62df3561ecf75d74e6eEli Friedman } else { 83923f0267e2d56c0407f12e62df3561ecf75d74e6eEli Friedman EmitSynthesizedCXXCopyCtor(blockField, src, copyExpr); 84023f0267e2d56c0407f12e62df3561ecf75d74e6eEli Friedman } 8416b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 8426b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // If it's a reference variable, copy the reference into the block field. 843c637d738897b1745af3bad7fc551f26b98da838cFariborz Jahanian } else if (type->isReferenceType()) { 8444967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar Builder.CreateStore(src.getPointer(), blockField); 8454b9bcd667776932e9b4c84144a9e7e8d581ffa63John McCall 8464b9bcd667776932e9b4c84144a9e7e8d581ffa63John McCall // If this is an ARC __strong block-pointer variable, don't do a 8474b9bcd667776932e9b4c84144a9e7e8d581ffa63John McCall // block copy. 8484b9bcd667776932e9b4c84144a9e7e8d581ffa63John McCall // 8494b9bcd667776932e9b4c84144a9e7e8d581ffa63John McCall // TODO: this can be generalized into the normal initialization logic: 8504b9bcd667776932e9b4c84144a9e7e8d581ffa63John McCall // we should never need to do a block-copy when initializing a local 8514b9bcd667776932e9b4c84144a9e7e8d581ffa63John McCall // variable, because the local variable's lifetime should be strictly 8524b9bcd667776932e9b4c84144a9e7e8d581ffa63John McCall // contained within the stack block's. 8534b9bcd667776932e9b4c84144a9e7e8d581ffa63John McCall } else if (type.getObjCLifetime() == Qualifiers::OCL_Strong && 8544b9bcd667776932e9b4c84144a9e7e8d581ffa63John McCall type->isBlockPointerType()) { 8554b9bcd667776932e9b4c84144a9e7e8d581ffa63John McCall // Load the block and do a simple retain. 85687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar llvm::Value *value = Builder.CreateLoad(src, "block.captured_block"); 8574b9bcd667776932e9b4c84144a9e7e8d581ffa63John McCall value = EmitARCRetainNonBlock(value); 8584b9bcd667776932e9b4c84144a9e7e8d581ffa63John McCall 8594b9bcd667776932e9b4c84144a9e7e8d581ffa63John McCall // Do a primitive store to the block field. 86087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar Builder.CreateStore(value, blockField); 8616b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 8626b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // Otherwise, fake up a POD copy into the block field. 8636b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall } else { 864f85e193739c953358c865005855253af4f68a497John McCall // Fake up a new variable so that EmitScalarInit doesn't think 865f85e193739c953358c865005855253af4f68a497John McCall // we're referring to the variable in its own initializer. 8666bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines ImplicitParamDecl blockFieldPseudoVar(getContext(), /*DC*/ nullptr, 8676bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SourceLocation(), /*name*/ nullptr, 8686bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines type); 869f85e193739c953358c865005855253af4f68a497John McCall 870bb699b07426be017056c2c549ac3ffb488cab6e3John McCall // We use one of these or the other depending on whether the 871bb699b07426be017056c2c549ac3ffb488cab6e3John McCall // reference is nested. 8720e2c34f92f00628d48968dfea096d36381f494cbStephen Hines DeclRefExpr declRef(const_cast<VarDecl *>(variable), 8730e2c34f92f00628d48968dfea096d36381f494cbStephen Hines /*RefersToEnclosingVariableOrCapture*/ CI.isNested(), 8740e2c34f92f00628d48968dfea096d36381f494cbStephen Hines type, VK_LValue, SourceLocation()); 875bb699b07426be017056c2c549ac3ffb488cab6e3John McCall 876c637d738897b1745af3bad7fc551f26b98da838cFariborz Jahanian ImplicitCastExpr l2r(ImplicitCastExpr::OnStack, type, CK_LValueToRValue, 877f4b88a45902af1802a1cb42ba48b1c474474f228John McCall &declRef, VK_RValue); 8780e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // FIXME: Pass a specific location for the expr init so that the store is 8790e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // attributed to a reasonable location - otherwise it may be attributed to 8800e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // locations of subexpressions in the initialization. 881a07398ed98ea2b55ad7a505a3aab18aed93b149fJohn McCall EmitExprAsInit(&l2r, &blockFieldPseudoVar, 88287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar MakeAddrLValue(blockField, type, AlignmentSource::Decl), 883df045200e0220f10bf03de05ca878949e0c40a5aJohn McCall /*captured by init*/ false); 884ea1471e0e967548c596a71469702f8846dbaf3c0John McCall } 8856b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 8861a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall // Activate the cleanup if layout pushed one. 887651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (!CI.isByRef()) { 8881a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall EHScopeStack::stable_iterator cleanup = capture.getCleanup(); 8891a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall if (cleanup.isValid()) 8906f103ba42cb69d50005a977c5ea583984ab63fc4John McCall ActivateCleanupBlock(cleanup, blockInfo.DominatingIP); 891f85e193739c953358c865005855253af4f68a497John McCall } 892e5fee25e71266712522cff554f25c59b3078a429Mike Stump } 89300470a1c4c44c5ed26bad9a38b4d3904b02d7a28Mike Stump 8946b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // Cast to the converted block-pointer type, which happens (somewhat 8956b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // unfortunately) to be a pointer to function type. 8966b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall llvm::Value *result = 89787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar Builder.CreateBitCast(blockAddr.getPointer(), 8986b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall ConvertType(blockInfo.getBlockExpr()->getType())); 899711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 9006b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall return result; 901e5fee25e71266712522cff554f25c59b3078a429Mike Stump} 902e5fee25e71266712522cff554f25c59b3078a429Mike Stump 903e5fee25e71266712522cff554f25c59b3078a429Mike Stump 9049cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattnerllvm::Type *CodeGenModule::getBlockDescriptorType() { 905ab695143861b520f5c9f8f982534a71d355396f1Mike Stump if (BlockDescriptorType) 906ab695143861b520f5c9f8f982534a71d355396f1Mike Stump return BlockDescriptorType; 907ab695143861b520f5c9f8f982534a71d355396f1Mike Stump 9089cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *UnsignedLongTy = 909ab695143861b520f5c9f8f982534a71d355396f1Mike Stump getTypes().ConvertType(getContext().UnsignedLongTy); 910a5448544eea6663f8dce30a50343ef5125559794Mike Stump 911ab695143861b520f5c9f8f982534a71d355396f1Mike Stump // struct __block_descriptor { 912ab695143861b520f5c9f8f982534a71d355396f1Mike Stump // unsigned long reserved; 913ab695143861b520f5c9f8f982534a71d355396f1Mike Stump // unsigned long block_size; 9142a7eb28397148079cbc8e54e8a3871ef01c4f4bcBlaine Garst // 9152a7eb28397148079cbc8e54e8a3871ef01c4f4bcBlaine Garst // // later, the following will be added 9162a7eb28397148079cbc8e54e8a3871ef01c4f4bcBlaine Garst // 9172a7eb28397148079cbc8e54e8a3871ef01c4f4bcBlaine Garst // struct { 9182a7eb28397148079cbc8e54e8a3871ef01c4f4bcBlaine Garst // void (*copyHelper)(); 9192a7eb28397148079cbc8e54e8a3871ef01c4f4bcBlaine Garst // void (*copyHelper)(); 9202a7eb28397148079cbc8e54e8a3871ef01c4f4bcBlaine Garst // } helpers; // !!! optional 9212a7eb28397148079cbc8e54e8a3871ef01c4f4bcBlaine Garst // 9222a7eb28397148079cbc8e54e8a3871ef01c4f4bcBlaine Garst // const char *signature; // the block signature 9232a7eb28397148079cbc8e54e8a3871ef01c4f4bcBlaine Garst // const char *layout; // reserved 924ab695143861b520f5c9f8f982534a71d355396f1Mike Stump // }; 9257650d95a1a616ea300f37126a8dfc93dc19a662aChris Lattner BlockDescriptorType = 926c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner llvm::StructType::create("struct.__block_descriptor", 9270e2c34f92f00628d48968dfea096d36381f494cbStephen Hines UnsignedLongTy, UnsignedLongTy, nullptr); 928ab695143861b520f5c9f8f982534a71d355396f1Mike Stump 9296b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // Now form a pointer to that. 9306b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall BlockDescriptorType = llvm::PointerType::getUnqual(BlockDescriptorType); 931ab695143861b520f5c9f8f982534a71d355396f1Mike Stump return BlockDescriptorType; 932acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson} 933acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson 9349cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattnerllvm::Type *CodeGenModule::getGenericBlockLiteralType() { 9359b8a7977109604d573b49d517e98badbbb9d5ac7Mike Stump if (GenericBlockLiteralType) 9369b8a7977109604d573b49d517e98badbbb9d5ac7Mike Stump return GenericBlockLiteralType; 9379b8a7977109604d573b49d517e98badbbb9d5ac7Mike Stump 9389cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *BlockDescPtrTy = getBlockDescriptorType(); 939a5448544eea6663f8dce30a50343ef5125559794Mike Stump 9409b8a7977109604d573b49d517e98badbbb9d5ac7Mike Stump // struct __block_literal_generic { 941bd65cac8de63d108a681035782a71d42954b03abMike Stump // void *__isa; 942bd65cac8de63d108a681035782a71d42954b03abMike Stump // int __flags; 943bd65cac8de63d108a681035782a71d42954b03abMike Stump // int __reserved; 944bd65cac8de63d108a681035782a71d42954b03abMike Stump // void (*__invoke)(void *); 945bd65cac8de63d108a681035782a71d42954b03abMike Stump // struct __block_descriptor *__descriptor; 9469b8a7977109604d573b49d517e98badbbb9d5ac7Mike Stump // }; 9479cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner GenericBlockLiteralType = 948c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner llvm::StructType::create("struct.__block_literal_generic", 949c1c20114a401e503c07d68c47e0728bb063f35c8Chris Lattner VoidPtrTy, IntTy, IntTy, VoidPtrTy, 9500e2c34f92f00628d48968dfea096d36381f494cbStephen Hines BlockDescPtrTy, nullptr); 951a5448544eea6663f8dce30a50343ef5125559794Mike Stump 9529b8a7977109604d573b49d517e98badbbb9d5ac7Mike Stump return GenericBlockLiteralType; 953acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson} 954acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson 9554ee7dc2369c1f0257a73b2e83a7d38fdebdd9176Nick LewyckyRValue CodeGenFunction::EmitBlockCallExpr(const CallExpr *E, 956a1736c0c750d4514a5d8fda36670addf1e4de54aAnders Carlsson ReturnValueSlot ReturnValue) { 957a5448544eea6663f8dce30a50343ef5125559794Mike Stump const BlockPointerType *BPT = 9586217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek E->getCallee()->getType()->getAs<BlockPointerType>(); 959a5448544eea6663f8dce30a50343ef5125559794Mike Stump 960acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson llvm::Value *Callee = EmitScalarExpr(E->getCallee()); 961acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson 962acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson // Get a pointer to the generic block literal. 9632acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *BlockLiteralTy = 96496e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson llvm::PointerType::getUnqual(CGM.getGenericBlockLiteralType()); 965acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson 966acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson // Bitcast the callee to a block literal. 967a5448544eea6663f8dce30a50343ef5125559794Mike Stump llvm::Value *BlockLiteral = 968acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson Builder.CreateBitCast(Callee, BlockLiteralTy, "block.literal"); 969acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson 970acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson // Get the function pointer from the literal. 97187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar llvm::Value *FuncPtr = 97287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar Builder.CreateStructGEP(CGM.getGenericBlockLiteralType(), BlockLiteral, 3); 973acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson 974578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer BlockLiteral = Builder.CreateBitCast(BlockLiteral, VoidPtrTy); 975a5448544eea6663f8dce30a50343ef5125559794Mike Stump 976acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson // Add the block literal. 977acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson CallArgList Args; 9780774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall Args.add(RValue::get(BlockLiteral), getContext().VoidPtrTy); 979a5448544eea6663f8dce30a50343ef5125559794Mike Stump 980782f397c1459ef7d8b910c0fb6b95c5f1c19c14fAnders Carlsson QualType FnType = BPT->getPointeeType(); 981782f397c1459ef7d8b910c0fb6b95c5f1c19c14fAnders Carlsson 982acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson // And the rest of the arguments. 98387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar EmitCallArgs(Args, FnType->getAs<FunctionProtoType>(), E->arguments()); 984a5448544eea6663f8dce30a50343ef5125559794Mike Stump 9856e460ff03f984d34d6f3ba7f191380b823b6062fAnders Carlsson // Load the function. 98687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar llvm::Value *Func = Builder.CreateAlignedLoad(FuncPtr, getPointerAlign()); 9876e460ff03f984d34d6f3ba7f191380b823b6062fAnders Carlsson 98864cd2328ef55735c910d3d51dd40eafc38d7a504John McCall const FunctionType *FuncTy = FnType->castAs<FunctionType>(); 989de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall const CGFunctionInfo &FnInfo = 990e56bb36e8eea89bae7dfe6eb6ea0455af126bf4aJohn McCall CGM.getTypes().arrangeBlockFunctionCall(Args, FuncTy); 9911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 9926e460ff03f984d34d6f3ba7f191380b823b6062fAnders Carlsson // Cast the function pointer to the right type. 993de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall llvm::Type *BlockFTy = CGM.getTypes().GetFunctionType(FnInfo); 9941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 9952acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *BlockFTyPtr = llvm::PointerType::getUnqual(BlockFTy); 9966e460ff03f984d34d6f3ba7f191380b823b6062fAnders Carlsson Func = Builder.CreateBitCast(Func, BlockFTyPtr); 9971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 998acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson // And call the block. 999a1736c0c750d4514a5d8fda36670addf1e4de54aAnders Carlsson return EmitCall(FnInfo, Func, ReturnValue, Args); 1000acfde805d644bc71dfeac54ddbc9f12cdae0bb02Anders Carlsson} 1001d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson 100287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga NainarAddress CodeGenFunction::GetAddrOfBlockDecl(const VarDecl *variable, 100387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar bool isByRef) { 10046b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall assert(BlockInfo && "evaluating block ref without block information?"); 10056b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall const CGBlockInfo::Capture &capture = BlockInfo->getCapture(variable); 1006ea1471e0e967548c596a71469702f8846dbaf3c0John McCall 10076b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // Handle constant captures. 100887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (capture.isConstant()) return LocalDeclMap.find(variable)->second; 1009ea1471e0e967548c596a71469702f8846dbaf3c0John McCall 101087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar Address addr = 101187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar Builder.CreateStructGEP(LoadBlockStruct(), capture.getIndex(), 101287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar capture.getOffset(), "block.capture.addr"); 1013ea1471e0e967548c596a71469702f8846dbaf3c0John McCall 10146b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall if (isByRef) { 10156b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // addr should be a void** right now. Load, then cast the result 10166b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // to byref*. 1017dab514fc30242c7afd6c03956e46136c400fb0d3Mike Stump 101887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar auto &byrefInfo = getBlockByrefInfo(variable); 101987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar addr = Address(Builder.CreateLoad(addr), byrefInfo.ByrefAlignment); 102087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 102187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar auto byrefPointerType = llvm::PointerType::get(byrefInfo.Type, 0); 102287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar addr = Builder.CreateBitCast(addr, byrefPointerType, "byref.addr"); 102387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 102487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar addr = emitBlockByrefAddress(addr, byrefInfo, /*follow*/ true, 102587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar variable->getName()); 1026ea1471e0e967548c596a71469702f8846dbaf3c0John McCall } 1027ea26cb522e88fc86b0d1cae61dcefcfe4cc20231Mike Stump 102887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (auto refType = variable->getType()->getAs<ReferenceType>()) { 102987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar addr = EmitLoadOfReference(addr, refType); 103087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 1031ea26cb522e88fc86b0d1cae61dcefcfe4cc20231Mike Stump 10326b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall return addr; 1033dab514fc30242c7afd6c03956e46136c400fb0d3Mike Stump} 1034dab514fc30242c7afd6c03956e46136c400fb0d3Mike Stump 103567a6448a8d52ae46d1cba4e474f9f6b3968d2ff9Mike Stumpllvm::Constant * 1036d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCallCodeGenModule::GetAddrOfGlobalBlock(const BlockExpr *blockExpr, 10375936e33bf74dd6bf126ceee0f6169a2593d03a69John McCall const char *name) { 10381a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall CGBlockInfo blockInfo(blockExpr->getBlockDecl(), name); 10391a343ebbf413e8eae6b2737b2b2d79cbf5765571John McCall blockInfo.BlockExpression = blockExpr; 1040a5448544eea6663f8dce30a50343ef5125559794Mike Stump 10416b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // Compute information about the layout, etc., of this block. 10426bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines computeBlockInfo(*this, nullptr, blockInfo); 10432a7eb28397148079cbc8e54e8a3871ef01c4f4bcBlaine Garst 10446b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // Using that metadata, generate the actual block function. 10456b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall llvm::Constant *blockFn; 10466b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall { 104787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar CodeGenFunction::DeclMapTy LocalDeclMap; 1048d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall blockFn = CodeGenFunction(*this).GenerateBlockFunction(GlobalDecl(), 1049d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall blockInfo, 1050f5ebf9bf1df10ac15ba32a4b24dfe171b7848c58John McCall LocalDeclMap, 105164bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman false); 10526b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall } 10535936e33bf74dd6bf126ceee0f6169a2593d03a69John McCall blockFn = llvm::ConstantExpr::getBitCast(blockFn, VoidPtrTy); 1054a5448544eea6663f8dce30a50343ef5125559794Mike Stump 1055d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall return buildGlobalBlock(*this, blockInfo, blockFn); 10566b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall} 10575e530af5d51572a0ed5dbe50da54bd333840c63dDavid Chisnall 10586b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCallstatic llvm::Constant *buildGlobalBlock(CodeGenModule &CGM, 10596b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall const CGBlockInfo &blockInfo, 10606b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall llvm::Constant *blockFn) { 10616b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall assert(blockInfo.CanBeGlobal); 1062a5448544eea6663f8dce30a50343ef5125559794Mike Stump 10636b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // Generate the constants for the block literal initializer. 10646b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall llvm::Constant *fields[BlockHeaderSize]; 1065a5448544eea6663f8dce30a50343ef5125559794Mike Stump 1066d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson // isa 10676b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall fields[0] = CGM.getNSConcreteGlobalBlock(); 1068a5448544eea6663f8dce30a50343ef5125559794Mike Stump 10697edddb896e10d7ab494927842f7402583d9fa02dFariborz Jahanian // __flags 107064cd2328ef55735c910d3d51dd40eafc38d7a504John McCall BlockFlags flags = BLOCK_IS_GLOBAL | BLOCK_HAS_SIGNATURE; 107164cd2328ef55735c910d3d51dd40eafc38d7a504John McCall if (blockInfo.UsesStret) flags |= BLOCK_USE_STRET; 107264cd2328ef55735c910d3d51dd40eafc38d7a504John McCall 10735936e33bf74dd6bf126ceee0f6169a2593d03a69John McCall fields[1] = llvm::ConstantInt::get(CGM.IntTy, flags.getBitMask()); 1074a5448544eea6663f8dce30a50343ef5125559794Mike Stump 1075d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson // Reserved 10765936e33bf74dd6bf126ceee0f6169a2593d03a69John McCall fields[2] = llvm::Constant::getNullValue(CGM.IntTy); 1077a5448544eea6663f8dce30a50343ef5125559794Mike Stump 1078d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson // Function 10796b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall fields[3] = blockFn; 1080a5448544eea6663f8dce30a50343ef5125559794Mike Stump 1081d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson // Descriptor 10826b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall fields[4] = buildBlockDescriptor(CGM, blockInfo); 1083a5448544eea6663f8dce30a50343ef5125559794Mike Stump 1084c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner llvm::Constant *init = llvm::ConstantStruct::getAnon(fields); 1085d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson 10866b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall llvm::GlobalVariable *literal = 10876b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall new llvm::GlobalVariable(CGM.getModule(), 10886b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall init->getType(), 10896b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall /*constant*/ true, 10906b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall llvm::GlobalVariable::InternalLinkage, 10916b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall init, 10926b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall "__block_literal_global"); 10936b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall literal->setAlignment(blockInfo.BlockAlign.getQuantity()); 10946b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 10956b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // Return a constant of the appropriately-casted type. 10962acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *requiredType = 10976b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall CGM.getTypes().ConvertType(blockInfo.getBlockExpr()->getType()); 10986b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall return llvm::ConstantExpr::getBitCast(literal, requiredType); 10994e7a1f7682d94811bd41fca8aefccc38f686db23Mike Stump} 11004e7a1f7682d94811bd41fca8aefccc38f686db23Mike Stump 110187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainarvoid CodeGenFunction::setBlockContextParameter(const ImplicitParamDecl *D, 110287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar unsigned argNum, 110387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar llvm::Value *arg) { 110487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar assert(BlockInfo && "not emitting prologue of block invocation function?!"); 110587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 110687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar llvm::Value *localAddr = nullptr; 110787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (CGM.getCodeGenOpts().OptimizationLevel == 0) { 110887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // Allocate a stack slot to let the debug info survive the RA. 110987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar Address alloc = CreateMemTemp(D->getType(), D->getName() + ".addr"); 111087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar Builder.CreateStore(arg, alloc); 111187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar localAddr = Builder.CreateLoad(alloc); 111287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 111387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 111487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (CGDebugInfo *DI = getDebugInfo()) { 11154967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (CGM.getCodeGenOpts().getDebugInfo() >= 11164967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar codegenoptions::LimitedDebugInfo) { 111787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar DI->setLocation(D->getLocation()); 111887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar DI->EmitDeclareOfBlockLiteralArgVariable(*BlockInfo, arg, argNum, 111987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar localAddr, Builder); 112087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 112187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 112287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 112387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar SourceLocation StartLoc = BlockInfo->getBlockExpr()->getBody()->getLocStart(); 112487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar ApplyDebugLocation Scope(*this, StartLoc); 112587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 112687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // Instead of messing around with LocalDeclMap, just set the value 112787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // directly as BlockPointer. 112887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar BlockPointer = Builder.CreateBitCast(arg, 112987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar BlockInfo->StructureType->getPointerTo(), 113087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar "block"); 113187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar} 113287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 113387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga NainarAddress CodeGenFunction::LoadBlockStruct() { 113487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar assert(BlockInfo && "not in a block invocation function!"); 113587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar assert(BlockPointer && "no block pointer set!"); 113687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar return Address(BlockPointer, BlockInfo->BlockAlign); 113787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar} 113887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 113900470a1c4c44c5ed26bad9a38b4d3904b02d7a28Mike Stumpllvm::Function * 11406b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCallCodeGenFunction::GenerateBlockFunction(GlobalDecl GD, 11416b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall const CGBlockInfo &blockInfo, 114264bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman const DeclMapTy &ldm, 114364bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman bool IsLambdaConversionToBlock) { 11446b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall const BlockDecl *blockDecl = blockInfo.getBlockDecl(); 1145963dfbde17a28bc88ee1647bc85fd8407bfc9555Devang Patel 11464904bf4e84cfb48080270ebaa9005327f18ab0e5Fariborz Jahanian CurGD = GD; 11470e2c34f92f00628d48968dfea096d36381f494cbStephen Hines 11480e2c34f92f00628d48968dfea096d36381f494cbStephen Hines CurEHLocation = blockInfo.getBlockExpr()->getLocEnd(); 11494904bf4e84cfb48080270ebaa9005327f18ab0e5Fariborz Jahanian 11506b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall BlockInfo = &blockInfo; 11511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 11527f28a9c37e67ae16396042ad9c085830969daf29Mike Stump // Arrange for local static and local extern declarations to appear 11536b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // to be local to this function as well, in case they're directly 11546b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // referenced in a block. 11556b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall for (DeclMapTy::const_iterator i = ldm.begin(), e = ldm.end(); i != e; ++i) { 11566bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const auto *var = dyn_cast<VarDecl>(i->first); 11576b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall if (var && !var->hasLocalStorage()) 115887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar setAddrOfLocalVar(var, i->second); 11597f28a9c37e67ae16396042ad9c085830969daf29Mike Stump } 11607f28a9c37e67ae16396042ad9c085830969daf29Mike Stump 11616b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // Begin building the function declaration. 1162a5448544eea6663f8dce30a50343ef5125559794Mike Stump 11636b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // Build the argument list. 11646b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall FunctionArgList args; 1165d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson 11666b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // The first argument is the block pointer. Just take it as a void* 11676b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // and cast it later. 11686b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall QualType selfTy = getContext().VoidPtrTy; 1169ea26cb522e88fc86b0d1cae61dcefcfe4cc20231Mike Stump IdentifierInfo *II = &CGM.getContext().Idents.get(".block_descriptor"); 1170ea26cb522e88fc86b0d1cae61dcefcfe4cc20231Mike Stump 11716bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines ImplicitParamDecl selfDecl(getContext(), const_cast<BlockDecl*>(blockDecl), 11728178df3b39ab923ff5d24538812628abee33df79John McCall SourceLocation(), II, selfTy); 1173d26bc76c98006609002d9930f8840490e88ac5b5John McCall args.push_back(&selfDecl); 11746b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 11756b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // Now add the rest of the parameters. 11760e2c34f92f00628d48968dfea096d36381f494cbStephen Hines args.append(blockDecl->param_begin(), blockDecl->param_end()); 11776b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 11786b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // Create the function declaration. 1179de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall const FunctionProtoType *fnType = blockInfo.getBlockExpr()->getFunctionType(); 11804967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar const CGFunctionInfo &fnInfo = 11814967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar CGM.getTypes().arrangeBlockFunctionDeclaration(fnType, args); 1182651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (CGM.ReturnSlotInterferesWithArgs(fnInfo)) 118364cd2328ef55735c910d3d51dd40eafc38d7a504John McCall blockInfo.UsesStret = true; 118464cd2328ef55735c910d3d51dd40eafc38d7a504John McCall 1185de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall llvm::FunctionType *fnLLVMType = CGM.getTypes().GetFunctionType(fnInfo); 11866b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 1187c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines StringRef name = CGM.getBlockMangledName(GD, blockDecl); 1188c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines llvm::Function *fn = llvm::Function::Create( 1189c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines fnLLVMType, llvm::GlobalValue::InternalLinkage, name, &CGM.getModule()); 11906b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall CGM.SetInternalFunctionAttributes(blockDecl, fn, fnInfo); 11916b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 11926b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // Begin generating the function. 1193651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines StartFunction(blockDecl, fnType->getReturnType(), fn, fnInfo, args, 11946bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines blockDecl->getLocation(), 11953f4cb252832cf14f72d66ed707316d3759c8a689Devang Patel blockInfo.getBlockExpr()->getBody()->getLocStart()); 11966b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 11978178df3b39ab923ff5d24538812628abee33df79John McCall // Okay. Undo some of what StartFunction did. 119887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 11999b97adfb770c3b55c1a45049d53b624bbc6f62e1Adrian Prantl // At -O0 we generate an explicit alloca for the BlockPointer, so the RA 12009b97adfb770c3b55c1a45049d53b624bbc6f62e1Adrian Prantl // won't delete the dbg.declare intrinsics for captured variables. 12019b97adfb770c3b55c1a45049d53b624bbc6f62e1Adrian Prantl llvm::Value *BlockPointerDbgLoc = BlockPointer; 12029b97adfb770c3b55c1a45049d53b624bbc6f62e1Adrian Prantl if (CGM.getCodeGenOpts().OptimizationLevel == 0) { 12039b97adfb770c3b55c1a45049d53b624bbc6f62e1Adrian Prantl // Allocate a stack slot for it, so we can point the debugger to it 120487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar Address Alloca = CreateTempAlloca(BlockPointer->getType(), 120587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar getPointerAlign(), 120687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar "block.addr"); 12077959194fded7b2b1d37ead268d42c8ae6b10fe25Adrian Prantl // Set the DebugLocation to empty, so the store is recognized as a 12087959194fded7b2b1d37ead268d42c8ae6b10fe25Adrian Prantl // frame setup instruction by llvm::DwarfDebug::beginFunction(). 12090e2c34f92f00628d48968dfea096d36381f494cbStephen Hines auto NL = ApplyDebugLocation::CreateEmpty(*this); 121087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar Builder.CreateStore(BlockPointer, Alloca); 121187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar BlockPointerDbgLoc = Alloca.getPointer(); 12129b97adfb770c3b55c1a45049d53b624bbc6f62e1Adrian Prantl } 1213a5448544eea6663f8dce30a50343ef5125559794Mike Stump 12146b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // If we have a C++ 'this' reference, go ahead and force it into 12156b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // existence now. 12166b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall if (blockDecl->capturesCXXThis()) { 121787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar Address addr = 121887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar Builder.CreateStructGEP(LoadBlockStruct(), blockInfo.CXXThisIndex, 121987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar blockInfo.CXXThisOffset, "block.captured-this"); 12206b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall CXXThisValue = Builder.CreateLoad(addr, "this"); 12216b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall } 1222a5448544eea6663f8dce30a50343ef5125559794Mike Stump 12236b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // Also force all the constant captures. 1224651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (const auto &CI : blockDecl->captures()) { 1225651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const VarDecl *variable = CI.getVariable(); 12266b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall const CGBlockInfo::Capture &capture = blockInfo.getCapture(variable); 12276b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall if (!capture.isConstant()) continue; 1228d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson 122987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar CharUnits align = getContext().getDeclAlign(variable); 123087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar Address alloca = 123187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar CreateMemTemp(variable->getType(), align, "block.captured-const"); 1232a5448544eea6663f8dce30a50343ef5125559794Mike Stump 123387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar Builder.CreateStore(capture.getConstant(), alloca); 1234ea1471e0e967548c596a71469702f8846dbaf3c0John McCall 123587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar setAddrOfLocalVar(variable, alloca); 1236ee5042903d53fa7b0fbc1902d0ea07d57c7775b1John McCall } 1237ee5042903d53fa7b0fbc1902d0ea07d57c7775b1John McCall 1238f4b88a45902af1802a1cb42ba48b1c474474f228John McCall // Save a spot to insert the debug information for all the DeclRefExprs. 1239b1a6e687967105bf1e18dfba196d0248e6700a4eMike Stump llvm::BasicBlock *entry = Builder.GetInsertBlock(); 1240b289b3f324eb10d416b87080e39b315f6c17a695Mike Stump llvm::BasicBlock::iterator entry_ptr = Builder.GetInsertPoint(); 1241b289b3f324eb10d416b87080e39b315f6c17a695Mike Stump --entry_ptr; 1242b1a6e687967105bf1e18dfba196d0248e6700a4eMike Stump 124364bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman if (IsLambdaConversionToBlock) 124464bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman EmitLambdaBlockInvokeBody(); 1245651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines else { 124687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar PGO.assignRegionCounters(GlobalDecl(blockDecl), fn); 1247b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar incrementProfileCounter(blockDecl->getBody()); 124864bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman EmitStmt(blockDecl->getBody()); 1249651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 1250b289b3f324eb10d416b87080e39b315f6c17a695Mike Stump 1251de8c5c77e27b6b0064c45d964ea8bcc2c853114dMike Stump // Remember where we were... 1252de8c5c77e27b6b0064c45d964ea8bcc2c853114dMike Stump llvm::BasicBlock *resume = Builder.GetInsertBlock(); 1253b289b3f324eb10d416b87080e39b315f6c17a695Mike Stump 1254de8c5c77e27b6b0064c45d964ea8bcc2c853114dMike Stump // Go back to the entry. 1255b289b3f324eb10d416b87080e39b315f6c17a695Mike Stump ++entry_ptr; 1256b289b3f324eb10d416b87080e39b315f6c17a695Mike Stump Builder.SetInsertPoint(entry, entry_ptr); 1257b289b3f324eb10d416b87080e39b315f6c17a695Mike Stump 1258f4b88a45902af1802a1cb42ba48b1c474474f228John McCall // Emit debug information for all the DeclRefExprs. 12596b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // FIXME: also for 'this' 1260b1a6e687967105bf1e18dfba196d0248e6700a4eMike Stump if (CGDebugInfo *DI = getDebugInfo()) { 1261651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (const auto &CI : blockDecl->captures()) { 1262651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const VarDecl *variable = CI.getVariable(); 126373fb35003aad027492e661a3749e921b5d1ecaf9Eric Christopher DI->EmitLocation(Builder, variable->getLocation()); 12646b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 12654967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (CGM.getCodeGenOpts().getDebugInfo() >= 12664967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar codegenoptions::LimitedDebugInfo) { 1267fd00eecad6fa5400cf37269d84361a0551d0e6d3Alexey Samsonov const CGBlockInfo::Capture &capture = blockInfo.getCapture(variable); 1268fd00eecad6fa5400cf37269d84361a0551d0e6d3Alexey Samsonov if (capture.isConstant()) { 126987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar auto addr = LocalDeclMap.find(variable)->second; 127087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar DI->EmitDeclareOfAutoVariable(variable, addr.getPointer(), 1271fd00eecad6fa5400cf37269d84361a0551d0e6d3Alexey Samsonov Builder); 1272fd00eecad6fa5400cf37269d84361a0551d0e6d3Alexey Samsonov continue; 1273fd00eecad6fa5400cf37269d84361a0551d0e6d3Alexey Samsonov } 12746b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 127587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar DI->EmitDeclareOfBlockDeclRefVariable( 127687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar variable, BlockPointerDbgLoc, Builder, blockInfo, 127787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar entry_ptr == entry->end() ? nullptr : &*entry_ptr); 1278fd00eecad6fa5400cf37269d84361a0551d0e6d3Alexey Samsonov } 1279b1a6e687967105bf1e18dfba196d0248e6700a4eMike Stump } 12803c7a0e1a75ebe13366a646a9eb8c4aa61e4728d3Manman Ren // Recover location if it was changed in the above loop. 12813c7a0e1a75ebe13366a646a9eb8c4aa61e4728d3Manman Ren DI->EmitLocation(Builder, 1282d83cdd61341ec95c0954687ad387f1175cc2d7bdAdrian Prantl cast<CompoundStmt>(blockDecl->getBody())->getRBracLoc()); 1283b1a6e687967105bf1e18dfba196d0248e6700a4eMike Stump } 12846b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 1285de8c5c77e27b6b0064c45d964ea8bcc2c853114dMike Stump // And resume where we left off. 12866bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (resume == nullptr) 1287de8c5c77e27b6b0064c45d964ea8bcc2c853114dMike Stump Builder.ClearInsertionPoint(); 1288de8c5c77e27b6b0064c45d964ea8bcc2c853114dMike Stump else 1289de8c5c77e27b6b0064c45d964ea8bcc2c853114dMike Stump Builder.SetInsertPoint(resume); 1290b1a6e687967105bf1e18dfba196d0248e6700a4eMike Stump 12916b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall FinishFunction(cast<CompoundStmt>(blockDecl->getBody())->getRBracLoc()); 1292d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson 12936b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall return fn; 1294d5cab5435371b8cc74a9e05ebd40b5995ebad149Anders Carlsson} 1295a99038c0757a836c6faeeddaa5dfd249b32f6e9eMike Stump 12966b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall/* 12976b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall notes.push_back(HelperInfo()); 12986b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall HelperInfo ¬e = notes.back(); 12996b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall note.index = capture.getIndex(); 13006b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall note.RequiresCopying = (ci->hasCopyExpr() || BlockRequiresCopying(type)); 13016b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall note.cxxbar_import = ci->getCopyExpr(); 13026b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 13036b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall if (ci->isByRef()) { 13046b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall note.flag = BLOCK_FIELD_IS_BYREF; 13056b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall if (type.isObjCGCWeak()) 13066b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall note.flag |= BLOCK_FIELD_IS_WEAK; 13076b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall } else if (type->isBlockPointerType()) { 13086b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall note.flag = BLOCK_FIELD_IS_BLOCK; 13096b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall } else { 13106b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall note.flag = BLOCK_FIELD_IS_OBJECT; 13116b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall } 13126b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall */ 1313a99038c0757a836c6faeeddaa5dfd249b32f6e9eMike Stump 1314b62faef5ec86c1931785ffa805ece9b491735894John McCall/// Generate the copy-helper function for a block closure object: 1315b62faef5ec86c1931785ffa805ece9b491735894John McCall/// static void block_copy_helper(block_t *dst, block_t *src); 1316b62faef5ec86c1931785ffa805ece9b491735894John McCall/// The runtime will have previously initialized 'dst' by doing a 1317b62faef5ec86c1931785ffa805ece9b491735894John McCall/// bit-copy of 'src'. 1318b62faef5ec86c1931785ffa805ece9b491735894John McCall/// 1319b62faef5ec86c1931785ffa805ece9b491735894John McCall/// Note that this copies an entire block closure object to the heap; 1320b62faef5ec86c1931785ffa805ece9b491735894John McCall/// it should not be confused with a 'byref copy helper', which moves 1321b62faef5ec86c1931785ffa805ece9b491735894John McCall/// the contents of an individual __block variable to the heap. 13226b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCallllvm::Constant * 1323d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCallCodeGenFunction::GenerateCopyHelperFunction(const CGBlockInfo &blockInfo) { 13246b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall ASTContext &C = getContext(); 13256b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 13266b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall FunctionArgList args; 13276bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines ImplicitParamDecl dstDecl(getContext(), nullptr, SourceLocation(), nullptr, 13286bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines C.VoidPtrTy); 1329d26bc76c98006609002d9930f8840490e88ac5b5John McCall args.push_back(&dstDecl); 13306bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines ImplicitParamDecl srcDecl(getContext(), nullptr, SourceLocation(), nullptr, 13316bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines C.VoidPtrTy); 1332d26bc76c98006609002d9930f8840490e88ac5b5John McCall args.push_back(&srcDecl); 13331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 13344967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar const CGFunctionInfo &FI = 13354967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar CGM.getTypes().arrangeBuiltinFunctionDeclaration(C.VoidTy, args); 1336a4f668f3b7e03629066a01b04e415cb2b4655dafMike Stump 13376b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // FIXME: it would be nice if these were mergeable with things with 13386b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // identical semantics. 1339de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall llvm::FunctionType *LTy = CGM.getTypes().GetFunctionType(FI); 1340a4f668f3b7e03629066a01b04e415cb2b4655dafMike Stump 1341a4f668f3b7e03629066a01b04e415cb2b4655dafMike Stump llvm::Function *Fn = 1342a4f668f3b7e03629066a01b04e415cb2b4655dafMike Stump llvm::Function::Create(LTy, llvm::GlobalValue::InternalLinkage, 13433cf7c5dc23569ae76bd4bddaed22f696233d8e44Benjamin Kramer "__copy_helper_block_", &CGM.getModule()); 1344a4f668f3b7e03629066a01b04e415cb2b4655dafMike Stump 1345a4f668f3b7e03629066a01b04e415cb2b4655dafMike Stump IdentifierInfo *II 1346a4f668f3b7e03629066a01b04e415cb2b4655dafMike Stump = &CGM.getContext().Idents.get("__copy_helper_block_"); 1347a4f668f3b7e03629066a01b04e415cb2b4655dafMike Stump 13486b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall FunctionDecl *FD = FunctionDecl::Create(C, 13496b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall C.getTranslationUnitDecl(), 1350ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara SourceLocation(), 13516bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SourceLocation(), II, C.VoidTy, 13526bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines nullptr, SC_Static, 135316573fa9705b546b7597c273b25b85d6321e2b33Douglas Gregor false, 1354e5bbebb4d14347700ff0b1838f14cae3b8a35c69Eric Christopher false); 135587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 135687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar CGM.SetInternalFunctionAttributes(nullptr, Fn, FI); 135787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 13580e2c34f92f00628d48968dfea096d36381f494cbStephen Hines auto NL = ApplyDebugLocation::CreateEmpty(*this); 13596bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines StartFunction(FD, C.VoidTy, Fn, FI, args); 13600e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // Create a scope with an artificial location for the body of this function. 13610e2c34f92f00628d48968dfea096d36381f494cbStephen Hines auto AL = ApplyDebugLocation::CreateArtificial(*this); 13622acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *structPtrTy = blockInfo.StructureType->getPointerTo(); 13636b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 136487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar Address src = GetAddrOfLocalVar(&srcDecl); 136587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar src = Address(Builder.CreateLoad(src), blockInfo.BlockAlign); 1366d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall src = Builder.CreateBitCast(src, structPtrTy, "block.source"); 13676b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 136887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar Address dst = GetAddrOfLocalVar(&dstDecl); 136987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar dst = Address(Builder.CreateLoad(dst), blockInfo.BlockAlign); 1370d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall dst = Builder.CreateBitCast(dst, structPtrTy, "block.dest"); 13716b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 13726b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall const BlockDecl *blockDecl = blockInfo.getBlockDecl(); 13736b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 1374651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (const auto &CI : blockDecl->captures()) { 1375651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const VarDecl *variable = CI.getVariable(); 13766b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall QualType type = variable->getType(); 13776b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 13786b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall const CGBlockInfo::Capture &capture = blockInfo.getCapture(variable); 13796b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall if (capture.isConstant()) continue; 13806b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 1381651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const Expr *copyExpr = CI.getCopyExpr(); 1382f85e193739c953358c865005855253af4f68a497John McCall BlockFieldFlags flags; 1383f85e193739c953358c865005855253af4f68a497John McCall 1384015f33b6741ffceba3a71ee2d71d46418a7dc34cJohn McCall bool useARCWeakCopy = false; 1385015f33b6741ffceba3a71ee2d71d46418a7dc34cJohn McCall bool useARCStrongCopy = false; 13866b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 13876b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall if (copyExpr) { 1388651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines assert(!CI.isByRef()); 13896b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // don't bother computing flags 1390f85e193739c953358c865005855253af4f68a497John McCall 1391651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } else if (CI.isByRef()) { 13926b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall flags = BLOCK_FIELD_IS_BYREF; 1393f85e193739c953358c865005855253af4f68a497John McCall if (type.isObjCGCWeak()) 1394f85e193739c953358c865005855253af4f68a497John McCall flags |= BLOCK_FIELD_IS_WEAK; 1395f85e193739c953358c865005855253af4f68a497John McCall 1396f85e193739c953358c865005855253af4f68a497John McCall } else if (type->isObjCRetainableType()) { 13976b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall flags = BLOCK_FIELD_IS_OBJECT; 1398015f33b6741ffceba3a71ee2d71d46418a7dc34cJohn McCall bool isBlockPointer = type->isBlockPointerType(); 1399015f33b6741ffceba3a71ee2d71d46418a7dc34cJohn McCall if (isBlockPointer) 1400f85e193739c953358c865005855253af4f68a497John McCall flags = BLOCK_FIELD_IS_BLOCK; 14016b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 1402f85e193739c953358c865005855253af4f68a497John McCall // Special rules for ARC captures: 140387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar Qualifiers qs = type.getQualifiers(); 140487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 140587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // We need to register __weak direct captures with the runtime. 140687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (qs.getObjCLifetime() == Qualifiers::OCL_Weak) { 140787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar useARCWeakCopy = true; 140887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 140987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // We need to retain the copied value for __strong direct captures. 141087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } else if (qs.getObjCLifetime() == Qualifiers::OCL_Strong) { 141187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // If it's a block pointer, we have to copy the block and 141287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // assign that to the destination pointer, so we might as 141387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // well use _Block_object_assign. Otherwise we can avoid that. 141487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (!isBlockPointer) 141587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar useARCStrongCopy = true; 1416f85e193739c953358c865005855253af4f68a497John McCall 1417015f33b6741ffceba3a71ee2d71d46418a7dc34cJohn McCall // Non-ARC captures of retainable pointers are strong and 1418015f33b6741ffceba3a71ee2d71d46418a7dc34cJohn McCall // therefore require a call to _Block_object_assign. 141987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } else if (!qs.getObjCLifetime() && !getLangOpts().ObjCAutoRefCount) { 1420015f33b6741ffceba3a71ee2d71d46418a7dc34cJohn McCall // fall through 142187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 142287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // Otherwise the memcpy is fine. 142387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } else { 142487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar continue; 1425f85e193739c953358c865005855253af4f68a497John McCall } 142687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 142787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // For all other types, the memcpy is fine. 1428f85e193739c953358c865005855253af4f68a497John McCall } else { 1429f85e193739c953358c865005855253af4f68a497John McCall continue; 1430f85e193739c953358c865005855253af4f68a497John McCall } 14316b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 14326b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall unsigned index = capture.getIndex(); 143387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar Address srcField = Builder.CreateStructGEP(src, index, capture.getOffset()); 143487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar Address dstField = Builder.CreateStructGEP(dst, index, capture.getOffset()); 14356b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 14366b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // If there's an explicit copy expression, we do that. 14376b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall if (copyExpr) { 1438d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall EmitSynthesizedCXXCopyCtor(dstField, srcField, copyExpr); 1439015f33b6741ffceba3a71ee2d71d46418a7dc34cJohn McCall } else if (useARCWeakCopy) { 1440f85e193739c953358c865005855253af4f68a497John McCall EmitARCCopyWeak(dstField, srcField); 14416b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall } else { 14426b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall llvm::Value *srcValue = Builder.CreateLoad(srcField, "blockcopy.src"); 1443015f33b6741ffceba3a71ee2d71d46418a7dc34cJohn McCall if (useARCStrongCopy) { 1444015f33b6741ffceba3a71ee2d71d46418a7dc34cJohn McCall // At -O0, store null into the destination field (so that the 1445015f33b6741ffceba3a71ee2d71d46418a7dc34cJohn McCall // storeStrong doesn't over-release) and then call storeStrong. 1446015f33b6741ffceba3a71ee2d71d46418a7dc34cJohn McCall // This is a workaround to not having an initStrong call. 1447015f33b6741ffceba3a71ee2d71d46418a7dc34cJohn McCall if (CGM.getCodeGenOpts().OptimizationLevel == 0) { 14486bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines auto *ty = cast<llvm::PointerType>(srcValue->getType()); 1449015f33b6741ffceba3a71ee2d71d46418a7dc34cJohn McCall llvm::Value *null = llvm::ConstantPointerNull::get(ty); 1450015f33b6741ffceba3a71ee2d71d46418a7dc34cJohn McCall Builder.CreateStore(null, dstField); 1451015f33b6741ffceba3a71ee2d71d46418a7dc34cJohn McCall EmitARCStoreStrongCall(dstField, srcValue, true); 1452015f33b6741ffceba3a71ee2d71d46418a7dc34cJohn McCall 1453015f33b6741ffceba3a71ee2d71d46418a7dc34cJohn McCall // With optimization enabled, take advantage of the fact that 1454015f33b6741ffceba3a71ee2d71d46418a7dc34cJohn McCall // the blocks runtime guarantees a memcpy of the block data, and 1455015f33b6741ffceba3a71ee2d71d46418a7dc34cJohn McCall // just emit a retain of the src field. 1456015f33b6741ffceba3a71ee2d71d46418a7dc34cJohn McCall } else { 1457015f33b6741ffceba3a71ee2d71d46418a7dc34cJohn McCall EmitARCRetainNonBlock(srcValue); 1458015f33b6741ffceba3a71ee2d71d46418a7dc34cJohn McCall 1459015f33b6741ffceba3a71ee2d71d46418a7dc34cJohn McCall // We don't need this anymore, so kill it. It's not quite 1460015f33b6741ffceba3a71ee2d71d46418a7dc34cJohn McCall // worth the annoyance to avoid creating it in the first place. 146187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar cast<llvm::Instruction>(dstField.getPointer())->eraseFromParent(); 1462015f33b6741ffceba3a71ee2d71d46418a7dc34cJohn McCall } 1463015f33b6741ffceba3a71ee2d71d46418a7dc34cJohn McCall } else { 1464015f33b6741ffceba3a71ee2d71d46418a7dc34cJohn McCall srcValue = Builder.CreateBitCast(srcValue, VoidPtrTy); 146587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar llvm::Value *dstAddr = 146687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar Builder.CreateBitCast(dstField.getPointer(), VoidPtrTy); 1467bd7370a78604e9a20d698bfe328c1e43f12a0613John McCall llvm::Value *args[] = { 1468bd7370a78604e9a20d698bfe328c1e43f12a0613John McCall dstAddr, srcValue, llvm::ConstantInt::get(Int32Ty, flags.getBitMask()) 1469bd7370a78604e9a20d698bfe328c1e43f12a0613John McCall }; 1470bd7370a78604e9a20d698bfe328c1e43f12a0613John McCall 1471bd7370a78604e9a20d698bfe328c1e43f12a0613John McCall bool copyCanThrow = false; 1472651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (CI.isByRef() && variable->getType()->getAsCXXRecordDecl()) { 1473bd7370a78604e9a20d698bfe328c1e43f12a0613John McCall const Expr *copyExpr = 1474bd7370a78604e9a20d698bfe328c1e43f12a0613John McCall CGM.getContext().getBlockVarCopyInits(variable); 1475bd7370a78604e9a20d698bfe328c1e43f12a0613John McCall if (copyExpr) { 1476bd7370a78604e9a20d698bfe328c1e43f12a0613John McCall copyCanThrow = true; // FIXME: reuse the noexcept logic 1477bd7370a78604e9a20d698bfe328c1e43f12a0613John McCall } 1478bd7370a78604e9a20d698bfe328c1e43f12a0613John McCall } 1479bd7370a78604e9a20d698bfe328c1e43f12a0613John McCall 1480bd7370a78604e9a20d698bfe328c1e43f12a0613John McCall if (copyCanThrow) { 1481bd7370a78604e9a20d698bfe328c1e43f12a0613John McCall EmitRuntimeCallOrInvoke(CGM.getBlockObjectAssign(), args); 1482bd7370a78604e9a20d698bfe328c1e43f12a0613John McCall } else { 1483bd7370a78604e9a20d698bfe328c1e43f12a0613John McCall EmitNounwindRuntimeCall(CGM.getBlockObjectAssign(), args); 1484bd7370a78604e9a20d698bfe328c1e43f12a0613John McCall } 1485015f33b6741ffceba3a71ee2d71d46418a7dc34cJohn McCall } 14860892099dbc640720400a1d9decd2733a09d733e5Mike Stump } 14870892099dbc640720400a1d9decd2733a09d733e5Mike Stump } 14880892099dbc640720400a1d9decd2733a09d733e5Mike Stump 1489d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall FinishFunction(); 1490a4f668f3b7e03629066a01b04e415cb2b4655dafMike Stump 14915936e33bf74dd6bf126ceee0f6169a2593d03a69John McCall return llvm::ConstantExpr::getBitCast(Fn, VoidPtrTy); 1492dab514fc30242c7afd6c03956e46136c400fb0d3Mike Stump} 1493dab514fc30242c7afd6c03956e46136c400fb0d3Mike Stump 1494b62faef5ec86c1931785ffa805ece9b491735894John McCall/// Generate the destroy-helper function for a block closure object: 1495b62faef5ec86c1931785ffa805ece9b491735894John McCall/// static void block_destroy_helper(block_t *theBlock); 1496b62faef5ec86c1931785ffa805ece9b491735894John McCall/// 1497b62faef5ec86c1931785ffa805ece9b491735894John McCall/// Note that this destroys a heap-allocated block closure object; 1498b62faef5ec86c1931785ffa805ece9b491735894John McCall/// it should not be confused with a 'byref destroy helper', which 1499b62faef5ec86c1931785ffa805ece9b491735894John McCall/// destroys the heap-allocated contents of an individual __block 1500b62faef5ec86c1931785ffa805ece9b491735894John McCall/// variable. 15016b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCallllvm::Constant * 1502d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCallCodeGenFunction::GenerateDestroyHelperFunction(const CGBlockInfo &blockInfo) { 15036b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall ASTContext &C = getContext(); 1504a4f668f3b7e03629066a01b04e415cb2b4655dafMike Stump 15056b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall FunctionArgList args; 15066bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines ImplicitParamDecl srcDecl(getContext(), nullptr, SourceLocation(), nullptr, 15076bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines C.VoidPtrTy); 1508d26bc76c98006609002d9930f8840490e88ac5b5John McCall args.push_back(&srcDecl); 15091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 15104967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar const CGFunctionInfo &FI = 15114967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar CGM.getTypes().arrangeBuiltinFunctionDeclaration(C.VoidTy, args); 1512a4f668f3b7e03629066a01b04e415cb2b4655dafMike Stump 15133899a7fb9c7eeed19cc38d082921dd8b3d0d6624Mike Stump // FIXME: We'd like to put these into a mergable by content, with 15143899a7fb9c7eeed19cc38d082921dd8b3d0d6624Mike Stump // internal linkage. 1515de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall llvm::FunctionType *LTy = CGM.getTypes().GetFunctionType(FI); 1516a4f668f3b7e03629066a01b04e415cb2b4655dafMike Stump 1517a4f668f3b7e03629066a01b04e415cb2b4655dafMike Stump llvm::Function *Fn = 1518a4f668f3b7e03629066a01b04e415cb2b4655dafMike Stump llvm::Function::Create(LTy, llvm::GlobalValue::InternalLinkage, 15193cf7c5dc23569ae76bd4bddaed22f696233d8e44Benjamin Kramer "__destroy_helper_block_", &CGM.getModule()); 1520a4f668f3b7e03629066a01b04e415cb2b4655dafMike Stump 1521a4f668f3b7e03629066a01b04e415cb2b4655dafMike Stump IdentifierInfo *II 1522a4f668f3b7e03629066a01b04e415cb2b4655dafMike Stump = &CGM.getContext().Idents.get("__destroy_helper_block_"); 1523a4f668f3b7e03629066a01b04e415cb2b4655dafMike Stump 15246b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall FunctionDecl *FD = FunctionDecl::Create(C, C.getTranslationUnitDecl(), 1525ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara SourceLocation(), 15266bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SourceLocation(), II, C.VoidTy, 15276bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines nullptr, SC_Static, 1528e5bbebb4d14347700ff0b1838f14cae3b8a35c69Eric Christopher false, false); 152987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 153087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar CGM.SetInternalFunctionAttributes(nullptr, Fn, FI); 153187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 1532b6cdc96e7679f0344a36395a87c249930fac8a9fAdrian Prantl // Create a scope with an artificial location for the body of this function. 15330e2c34f92f00628d48968dfea096d36381f494cbStephen Hines auto NL = ApplyDebugLocation::CreateEmpty(*this); 15346bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines StartFunction(FD, C.VoidTy, Fn, FI, args); 15350e2c34f92f00628d48968dfea096d36381f494cbStephen Hines auto AL = ApplyDebugLocation::CreateArtificial(*this); 15361edf6b646ea161ce1193ba278ae88de82ff7114dMike Stump 15372acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *structPtrTy = blockInfo.StructureType->getPointerTo(); 1538b7477cf6cf6cf4f132ba7beff42684e59bed15f4Mike Stump 153987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar Address src = GetAddrOfLocalVar(&srcDecl); 154087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar src = Address(Builder.CreateLoad(src), blockInfo.BlockAlign); 1541d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall src = Builder.CreateBitCast(src, structPtrTy, "block"); 15426b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 15436b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall const BlockDecl *blockDecl = blockInfo.getBlockDecl(); 15446b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 1545d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall CodeGenFunction::RunCleanupsScope cleanups(*this); 15466b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 1547651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (const auto &CI : blockDecl->captures()) { 1548651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const VarDecl *variable = CI.getVariable(); 15496b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall QualType type = variable->getType(); 15506b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 15516b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall const CGBlockInfo::Capture &capture = blockInfo.getCapture(variable); 15526b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall if (capture.isConstant()) continue; 15536b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 1554d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall BlockFieldFlags flags; 15556bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const CXXDestructorDecl *dtor = nullptr; 15566b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 1557015f33b6741ffceba3a71ee2d71d46418a7dc34cJohn McCall bool useARCWeakDestroy = false; 1558015f33b6741ffceba3a71ee2d71d46418a7dc34cJohn McCall bool useARCStrongDestroy = false; 1559f85e193739c953358c865005855253af4f68a497John McCall 1560651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (CI.isByRef()) { 15616b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall flags = BLOCK_FIELD_IS_BYREF; 1562f85e193739c953358c865005855253af4f68a497John McCall if (type.isObjCGCWeak()) 1563f85e193739c953358c865005855253af4f68a497John McCall flags |= BLOCK_FIELD_IS_WEAK; 1564f85e193739c953358c865005855253af4f68a497John McCall } else if (const CXXRecordDecl *record = type->getAsCXXRecordDecl()) { 1565f85e193739c953358c865005855253af4f68a497John McCall if (record->hasTrivialDestructor()) 1566f85e193739c953358c865005855253af4f68a497John McCall continue; 1567f85e193739c953358c865005855253af4f68a497John McCall dtor = record->getDestructor(); 1568f85e193739c953358c865005855253af4f68a497John McCall } else if (type->isObjCRetainableType()) { 15696b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall flags = BLOCK_FIELD_IS_OBJECT; 1570f85e193739c953358c865005855253af4f68a497John McCall if (type->isBlockPointerType()) 1571f85e193739c953358c865005855253af4f68a497John McCall flags = BLOCK_FIELD_IS_BLOCK; 1572f85e193739c953358c865005855253af4f68a497John McCall 1573f85e193739c953358c865005855253af4f68a497John McCall // Special rules for ARC captures. 157487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar Qualifiers qs = type.getQualifiers(); 1575f85e193739c953358c865005855253af4f68a497John McCall 157687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // Use objc_storeStrong for __strong direct captures; the 157787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // dynamic tools really like it when we do this. 157887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (qs.getObjCLifetime() == Qualifiers::OCL_Strong) { 157987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar useARCStrongDestroy = true; 158087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 158187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // Support __weak direct captures. 158287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } else if (qs.getObjCLifetime() == Qualifiers::OCL_Weak) { 158387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar useARCWeakDestroy = true; 15846b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 158587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // Non-ARC captures are strong, and we need to use _Block_object_dispose. 158687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } else if (!qs.hasObjCLifetime() && !getLangOpts().ObjCAutoRefCount) { 158787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // fall through 1588015f33b6741ffceba3a71ee2d71d46418a7dc34cJohn McCall 158987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // Otherwise, we have nothing to do. 159087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } else { 159187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar continue; 1592f85e193739c953358c865005855253af4f68a497John McCall } 1593f85e193739c953358c865005855253af4f68a497John McCall } else { 1594f85e193739c953358c865005855253af4f68a497John McCall continue; 1595f85e193739c953358c865005855253af4f68a497John McCall } 15966b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 159787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar Address srcField = 159887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar Builder.CreateStructGEP(src, capture.getIndex(), capture.getOffset()); 15996b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 16006b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // If there's an explicit copy expression, we do that. 16016b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall if (dtor) { 1602d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall PushDestructorCleanup(dtor, srcField); 16036b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 1604f85e193739c953358c865005855253af4f68a497John McCall // If this is a __weak capture, emit the release directly. 1605015f33b6741ffceba3a71ee2d71d46418a7dc34cJohn McCall } else if (useARCWeakDestroy) { 1606f85e193739c953358c865005855253af4f68a497John McCall EmitARCDestroyWeak(srcField); 1607f85e193739c953358c865005855253af4f68a497John McCall 1608015f33b6741ffceba3a71ee2d71d46418a7dc34cJohn McCall // Destroy strong objects with a call if requested. 1609015f33b6741ffceba3a71ee2d71d46418a7dc34cJohn McCall } else if (useARCStrongDestroy) { 16105b07e8077a20b80fee90bd76c43c6150c676e4a8John McCall EmitARCDestroyStrong(srcField, ARCImpreciseLifetime); 1611015f33b6741ffceba3a71ee2d71d46418a7dc34cJohn McCall 16126b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // Otherwise we call _Block_object_dispose. It wouldn't be too 16136b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // hard to just emit this as a cleanup if we wanted to make sure 16146b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // that things were done in reverse. 16156b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall } else { 16166b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall llvm::Value *value = Builder.CreateLoad(srcField); 16175936e33bf74dd6bf126ceee0f6169a2593d03a69John McCall value = Builder.CreateBitCast(value, VoidPtrTy); 16186b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall BuildBlockRelease(value, flags); 16191edf6b646ea161ce1193ba278ae88de82ff7114dMike Stump } 16201edf6b646ea161ce1193ba278ae88de82ff7114dMike Stump } 16211edf6b646ea161ce1193ba278ae88de82ff7114dMike Stump 16226b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall cleanups.ForceCleanup(); 16236b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall 1624d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall FinishFunction(); 1625a4f668f3b7e03629066a01b04e415cb2b4655dafMike Stump 16265936e33bf74dd6bf126ceee0f6169a2593d03a69John McCall return llvm::ConstantExpr::getBitCast(Fn, VoidPtrTy); 1627a4f668f3b7e03629066a01b04e415cb2b4655dafMike Stump} 1628a4f668f3b7e03629066a01b04e415cb2b4655dafMike Stump 1629f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCallnamespace { 1630f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall 1631f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall/// Emits the copy/dispose helper functions for a __block object of id type. 163287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainarclass ObjectByrefHelpers final : public BlockByrefHelpers { 1633f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall BlockFieldFlags Flags; 1634f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall 1635f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCallpublic: 1636f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall ObjectByrefHelpers(CharUnits alignment, BlockFieldFlags flags) 163787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar : BlockByrefHelpers(alignment), Flags(flags) {} 1638f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall 163987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar void emitCopy(CodeGenFunction &CGF, Address destField, 164087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar Address srcField) override { 1641f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall destField = CGF.Builder.CreateBitCast(destField, CGF.VoidPtrTy); 1642f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall 1643f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall srcField = CGF.Builder.CreateBitCast(srcField, CGF.VoidPtrPtrTy); 1644f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall llvm::Value *srcValue = CGF.Builder.CreateLoad(srcField); 1645f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall 1646f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall unsigned flags = (Flags | BLOCK_BYREF_CALLER).getBitMask(); 1647f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall 1648f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall llvm::Value *flagsVal = llvm::ConstantInt::get(CGF.Int32Ty, flags); 1649f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall llvm::Value *fn = CGF.CGM.getBlockObjectAssign(); 1650bd7370a78604e9a20d698bfe328c1e43f12a0613John McCall 165187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar llvm::Value *args[] = { destField.getPointer(), srcValue, flagsVal }; 1652bd7370a78604e9a20d698bfe328c1e43f12a0613John McCall CGF.EmitNounwindRuntimeCall(fn, args); 1653f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall } 1654f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall 165587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar void emitDispose(CodeGenFunction &CGF, Address field) override { 1656f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall field = CGF.Builder.CreateBitCast(field, CGF.Int8PtrTy->getPointerTo(0)); 1657f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall llvm::Value *value = CGF.Builder.CreateLoad(field); 1658f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall 1659f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall CGF.BuildBlockRelease(value, Flags | BLOCK_BYREF_CALLER); 1660f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall } 1661f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall 1662651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void profileImpl(llvm::FoldingSetNodeID &id) const override { 1663f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall id.AddInteger(Flags.getBitMask()); 1664f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall } 1665f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall}; 1666f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall 1667f85e193739c953358c865005855253af4f68a497John McCall/// Emits the copy/dispose helpers for an ARC __block __weak variable. 166887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainarclass ARCWeakByrefHelpers final : public BlockByrefHelpers { 1669f85e193739c953358c865005855253af4f68a497John McCallpublic: 167087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar ARCWeakByrefHelpers(CharUnits alignment) : BlockByrefHelpers(alignment) {} 1671f85e193739c953358c865005855253af4f68a497John McCall 167287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar void emitCopy(CodeGenFunction &CGF, Address destField, 167387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar Address srcField) override { 1674f85e193739c953358c865005855253af4f68a497John McCall CGF.EmitARCMoveWeak(destField, srcField); 1675f85e193739c953358c865005855253af4f68a497John McCall } 1676f85e193739c953358c865005855253af4f68a497John McCall 167787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar void emitDispose(CodeGenFunction &CGF, Address field) override { 1678f85e193739c953358c865005855253af4f68a497John McCall CGF.EmitARCDestroyWeak(field); 1679f85e193739c953358c865005855253af4f68a497John McCall } 1680f85e193739c953358c865005855253af4f68a497John McCall 1681651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void profileImpl(llvm::FoldingSetNodeID &id) const override { 1682f85e193739c953358c865005855253af4f68a497John McCall // 0 is distinguishable from all pointers and byref flags 1683f85e193739c953358c865005855253af4f68a497John McCall id.AddInteger(0); 1684f85e193739c953358c865005855253af4f68a497John McCall } 1685f85e193739c953358c865005855253af4f68a497John McCall}; 1686f85e193739c953358c865005855253af4f68a497John McCall 1687f85e193739c953358c865005855253af4f68a497John McCall/// Emits the copy/dispose helpers for an ARC __block __strong variable 1688f85e193739c953358c865005855253af4f68a497John McCall/// that's not of block-pointer type. 168987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainarclass ARCStrongByrefHelpers final : public BlockByrefHelpers { 1690f85e193739c953358c865005855253af4f68a497John McCallpublic: 169187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar ARCStrongByrefHelpers(CharUnits alignment) : BlockByrefHelpers(alignment) {} 1692f85e193739c953358c865005855253af4f68a497John McCall 169387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar void emitCopy(CodeGenFunction &CGF, Address destField, 169487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar Address srcField) override { 1695f85e193739c953358c865005855253af4f68a497John McCall // Do a "move" by copying the value and then zeroing out the old 1696f85e193739c953358c865005855253af4f68a497John McCall // variable. 1697f85e193739c953358c865005855253af4f68a497John McCall 169887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar llvm::Value *value = CGF.Builder.CreateLoad(srcField); 1699a59e4b7fca1d46afd8f315fa87fa8bf1a68df9cdJohn McCall 1700f85e193739c953358c865005855253af4f68a497John McCall llvm::Value *null = 1701f85e193739c953358c865005855253af4f68a497John McCall llvm::ConstantPointerNull::get(cast<llvm::PointerType>(value->getType())); 1702a59e4b7fca1d46afd8f315fa87fa8bf1a68df9cdJohn McCall 17037a77f1994bdbe67db361b851a0907cf49fddfd91Fariborz Jahanian if (CGF.CGM.getCodeGenOpts().OptimizationLevel == 0) { 170487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar CGF.Builder.CreateStore(null, destField); 17057a77f1994bdbe67db361b851a0907cf49fddfd91Fariborz Jahanian CGF.EmitARCStoreStrongCall(destField, value, /*ignored*/ true); 17067a77f1994bdbe67db361b851a0907cf49fddfd91Fariborz Jahanian CGF.EmitARCStoreStrongCall(srcField, null, /*ignored*/ true); 17077a77f1994bdbe67db361b851a0907cf49fddfd91Fariborz Jahanian return; 17087a77f1994bdbe67db361b851a0907cf49fddfd91Fariborz Jahanian } 170987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar CGF.Builder.CreateStore(value, destField); 171087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar CGF.Builder.CreateStore(null, srcField); 1711f85e193739c953358c865005855253af4f68a497John McCall } 1712f85e193739c953358c865005855253af4f68a497John McCall 171387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar void emitDispose(CodeGenFunction &CGF, Address field) override { 17145b07e8077a20b80fee90bd76c43c6150c676e4a8John McCall CGF.EmitARCDestroyStrong(field, ARCImpreciseLifetime); 1715f85e193739c953358c865005855253af4f68a497John McCall } 1716f85e193739c953358c865005855253af4f68a497John McCall 1717651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void profileImpl(llvm::FoldingSetNodeID &id) const override { 1718f85e193739c953358c865005855253af4f68a497John McCall // 1 is distinguishable from all pointers and byref flags 1719f85e193739c953358c865005855253af4f68a497John McCall id.AddInteger(1); 1720f85e193739c953358c865005855253af4f68a497John McCall } 1721f85e193739c953358c865005855253af4f68a497John McCall}; 1722f85e193739c953358c865005855253af4f68a497John McCall 1723a59e4b7fca1d46afd8f315fa87fa8bf1a68df9cdJohn McCall/// Emits the copy/dispose helpers for an ARC __block __strong 1724a59e4b7fca1d46afd8f315fa87fa8bf1a68df9cdJohn McCall/// variable that's of block-pointer type. 172587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainarclass ARCStrongBlockByrefHelpers final : public BlockByrefHelpers { 1726a59e4b7fca1d46afd8f315fa87fa8bf1a68df9cdJohn McCallpublic: 172787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar ARCStrongBlockByrefHelpers(CharUnits alignment) 172887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar : BlockByrefHelpers(alignment) {} 1729a59e4b7fca1d46afd8f315fa87fa8bf1a68df9cdJohn McCall 173087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar void emitCopy(CodeGenFunction &CGF, Address destField, 173187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar Address srcField) override { 1732a59e4b7fca1d46afd8f315fa87fa8bf1a68df9cdJohn McCall // Do the copy with objc_retainBlock; that's all that 1733a59e4b7fca1d46afd8f315fa87fa8bf1a68df9cdJohn McCall // _Block_object_assign would do anyway, and we'd have to pass the 1734a59e4b7fca1d46afd8f315fa87fa8bf1a68df9cdJohn McCall // right arguments to make sure it doesn't get no-op'ed. 173587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar llvm::Value *oldValue = CGF.Builder.CreateLoad(srcField); 1736a59e4b7fca1d46afd8f315fa87fa8bf1a68df9cdJohn McCall llvm::Value *copy = CGF.EmitARCRetainBlock(oldValue, /*mandatory*/ true); 173787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar CGF.Builder.CreateStore(copy, destField); 1738a59e4b7fca1d46afd8f315fa87fa8bf1a68df9cdJohn McCall } 1739a59e4b7fca1d46afd8f315fa87fa8bf1a68df9cdJohn McCall 174087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar void emitDispose(CodeGenFunction &CGF, Address field) override { 17415b07e8077a20b80fee90bd76c43c6150c676e4a8John McCall CGF.EmitARCDestroyStrong(field, ARCImpreciseLifetime); 1742a59e4b7fca1d46afd8f315fa87fa8bf1a68df9cdJohn McCall } 1743a59e4b7fca1d46afd8f315fa87fa8bf1a68df9cdJohn McCall 1744651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void profileImpl(llvm::FoldingSetNodeID &id) const override { 1745a59e4b7fca1d46afd8f315fa87fa8bf1a68df9cdJohn McCall // 2 is distinguishable from all pointers and byref flags 1746a59e4b7fca1d46afd8f315fa87fa8bf1a68df9cdJohn McCall id.AddInteger(2); 1747a59e4b7fca1d46afd8f315fa87fa8bf1a68df9cdJohn McCall } 1748a59e4b7fca1d46afd8f315fa87fa8bf1a68df9cdJohn McCall}; 1749a59e4b7fca1d46afd8f315fa87fa8bf1a68df9cdJohn McCall 1750f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall/// Emits the copy/dispose helpers for a __block variable with a 1751f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall/// nontrivial copy constructor or destructor. 175287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainarclass CXXByrefHelpers final : public BlockByrefHelpers { 1753f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall QualType VarType; 1754f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall const Expr *CopyExpr; 1755f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall 1756f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCallpublic: 1757f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall CXXByrefHelpers(CharUnits alignment, QualType type, 1758f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall const Expr *copyExpr) 175987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar : BlockByrefHelpers(alignment), VarType(type), CopyExpr(copyExpr) {} 1760f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall 17616bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines bool needsCopy() const override { return CopyExpr != nullptr; } 176287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar void emitCopy(CodeGenFunction &CGF, Address destField, 176387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar Address srcField) override { 1764f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall if (!CopyExpr) return; 1765f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall CGF.EmitSynthesizedCXXCopyCtor(destField, srcField, CopyExpr); 1766f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall } 1767f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall 176887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar void emitDispose(CodeGenFunction &CGF, Address field) override { 1769f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall EHScopeStack::stable_iterator cleanupDepth = CGF.EHStack.stable_begin(); 1770f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall CGF.PushDestructorCleanup(VarType, field); 1771f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall CGF.PopCleanupBlocks(cleanupDepth); 1772f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall } 1773f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall 1774651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void profileImpl(llvm::FoldingSetNodeID &id) const override { 1775f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall id.AddPointer(VarType.getCanonicalType().getAsOpaquePtr()); 1776f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall } 1777f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall}; 1778f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall} // end anonymous namespace 1779f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall 1780f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCallstatic llvm::Constant * 178187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga NainargenerateByrefCopyHelper(CodeGenFunction &CGF, const BlockByrefInfo &byrefInfo, 178287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar BlockByrefHelpers &generator) { 1783f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall ASTContext &Context = CGF.getContext(); 1784f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall 1785f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall QualType R = Context.VoidTy; 178645031c08c608e548ac12caf0547f89574e994b96Mike Stump 1787d26bc76c98006609002d9930f8840490e88ac5b5John McCall FunctionArgList args; 17886bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines ImplicitParamDecl dst(CGF.getContext(), nullptr, SourceLocation(), nullptr, 17896bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Context.VoidPtrTy); 1790d26bc76c98006609002d9930f8840490e88ac5b5John McCall args.push_back(&dst); 1791d26bc76c98006609002d9930f8840490e88ac5b5John McCall 17926bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines ImplicitParamDecl src(CGF.getContext(), nullptr, SourceLocation(), nullptr, 17936bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Context.VoidPtrTy); 1794d26bc76c98006609002d9930f8840490e88ac5b5John McCall args.push_back(&src); 17951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 17964967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar const CGFunctionInfo &FI = 17974967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar CGF.CGM.getTypes().arrangeBuiltinFunctionDeclaration(R, args); 179845031c08c608e548ac12caf0547f89574e994b96Mike Stump 179987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar llvm::FunctionType *LTy = CGF.CGM.getTypes().GetFunctionType(FI); 180045031c08c608e548ac12caf0547f89574e994b96Mike Stump 18013899a7fb9c7eeed19cc38d082921dd8b3d0d6624Mike Stump // FIXME: We'd like to put these into a mergable by content, with 18023899a7fb9c7eeed19cc38d082921dd8b3d0d6624Mike Stump // internal linkage. 180345031c08c608e548ac12caf0547f89574e994b96Mike Stump llvm::Function *Fn = 180445031c08c608e548ac12caf0547f89574e994b96Mike Stump llvm::Function::Create(LTy, llvm::GlobalValue::InternalLinkage, 1805f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall "__Block_byref_object_copy_", &CGF.CGM.getModule()); 180645031c08c608e548ac12caf0547f89574e994b96Mike Stump 180745031c08c608e548ac12caf0547f89574e994b96Mike Stump IdentifierInfo *II 1808f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall = &Context.Idents.get("__Block_byref_object_copy_"); 180945031c08c608e548ac12caf0547f89574e994b96Mike Stump 1810f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall FunctionDecl *FD = FunctionDecl::Create(Context, 1811f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall Context.getTranslationUnitDecl(), 1812ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara SourceLocation(), 18136bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SourceLocation(), II, R, nullptr, 1814d931b086984257de68868a64a235c2b4b34003fbJohn McCall SC_Static, 1815b92bd4b3271b7892abe9fd8c74fb54a27ad702abEric Christopher false, false); 1816f85e193739c953358c865005855253af4f68a497John McCall 181787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar CGF.CGM.SetInternalFunctionAttributes(nullptr, Fn, FI); 181887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 18196bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines CGF.StartFunction(FD, R, Fn, FI, args); 182045031c08c608e548ac12caf0547f89574e994b96Mike Stump 182187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (generator.needsCopy()) { 182287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar llvm::Type *byrefPtrType = byrefInfo.Type->getPointerTo(0); 1823f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall 1824f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall // dst->x 182587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar Address destField = CGF.GetAddrOfLocalVar(&dst); 182687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar destField = Address(CGF.Builder.CreateLoad(destField), 182787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar byrefInfo.ByrefAlignment); 1828f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall destField = CGF.Builder.CreateBitCast(destField, byrefPtrType); 182987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar destField = CGF.emitBlockByrefAddress(destField, byrefInfo, false, 183087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar "dest-object"); 1831f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall 1832f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall // src->x 183387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar Address srcField = CGF.GetAddrOfLocalVar(&src); 183487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar srcField = Address(CGF.Builder.CreateLoad(srcField), 183587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar byrefInfo.ByrefAlignment); 1836f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall srcField = CGF.Builder.CreateBitCast(srcField, byrefPtrType); 183787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar srcField = CGF.emitBlockByrefAddress(srcField, byrefInfo, false, 183887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar "src-object"); 1839f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall 184087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar generator.emitCopy(CGF, destField, srcField); 1841f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall } 1842f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall 1843f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall CGF.FinishFunction(); 1844f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall 1845f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall return llvm::ConstantExpr::getBitCast(Fn, CGF.Int8PtrTy); 184645031c08c608e548ac12caf0547f89574e994b96Mike Stump} 184745031c08c608e548ac12caf0547f89574e994b96Mike Stump 1848f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall/// Build the copy helper for a __block variable. 1849f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCallstatic llvm::Constant *buildByrefCopyHelper(CodeGenModule &CGM, 185087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar const BlockByrefInfo &byrefInfo, 185187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar BlockByrefHelpers &generator) { 1852f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall CodeGenFunction CGF(CGM); 185387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar return generateByrefCopyHelper(CGF, byrefInfo, generator); 1854f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall} 1855f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall 1856f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall/// Generate code for a __block variable's dispose helper. 1857f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCallstatic llvm::Constant * 1858f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCallgenerateByrefDisposeHelper(CodeGenFunction &CGF, 185987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar const BlockByrefInfo &byrefInfo, 186087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar BlockByrefHelpers &generator) { 1861f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall ASTContext &Context = CGF.getContext(); 1862f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall QualType R = Context.VoidTy; 186345031c08c608e548ac12caf0547f89574e994b96Mike Stump 1864d26bc76c98006609002d9930f8840490e88ac5b5John McCall FunctionArgList args; 18656bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines ImplicitParamDecl src(CGF.getContext(), nullptr, SourceLocation(), nullptr, 18666bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Context.VoidPtrTy); 1867d26bc76c98006609002d9930f8840490e88ac5b5John McCall args.push_back(&src); 18681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 18694967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar const CGFunctionInfo &FI = 18704967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar CGF.CGM.getTypes().arrangeBuiltinFunctionDeclaration(R, args); 187145031c08c608e548ac12caf0547f89574e994b96Mike Stump 187287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar llvm::FunctionType *LTy = CGF.CGM.getTypes().GetFunctionType(FI); 187345031c08c608e548ac12caf0547f89574e994b96Mike Stump 18743899a7fb9c7eeed19cc38d082921dd8b3d0d6624Mike Stump // FIXME: We'd like to put these into a mergable by content, with 18753899a7fb9c7eeed19cc38d082921dd8b3d0d6624Mike Stump // internal linkage. 187645031c08c608e548ac12caf0547f89574e994b96Mike Stump llvm::Function *Fn = 187745031c08c608e548ac12caf0547f89574e994b96Mike Stump llvm::Function::Create(LTy, llvm::GlobalValue::InternalLinkage, 1878830937bc1100fba7682f7c32c40512085870f50cFariborz Jahanian "__Block_byref_object_dispose_", 1879f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall &CGF.CGM.getModule()); 188045031c08c608e548ac12caf0547f89574e994b96Mike Stump 188145031c08c608e548ac12caf0547f89574e994b96Mike Stump IdentifierInfo *II 1882f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall = &Context.Idents.get("__Block_byref_object_dispose_"); 188345031c08c608e548ac12caf0547f89574e994b96Mike Stump 1884f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall FunctionDecl *FD = FunctionDecl::Create(Context, 1885f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall Context.getTranslationUnitDecl(), 1886ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara SourceLocation(), 18876bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SourceLocation(), II, R, nullptr, 1888d931b086984257de68868a64a235c2b4b34003fbJohn McCall SC_Static, 1889b92bd4b3271b7892abe9fd8c74fb54a27ad702abEric Christopher false, false); 189087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 189187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar CGF.CGM.SetInternalFunctionAttributes(nullptr, Fn, FI); 189287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 18936bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines CGF.StartFunction(FD, R, Fn, FI, args); 18941851b68aaa6717783609f366f5d87bbd0030f189Mike Stump 189587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (generator.needsDispose()) { 189687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar Address addr = CGF.GetAddrOfLocalVar(&src); 189787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar addr = Address(CGF.Builder.CreateLoad(addr), byrefInfo.ByrefAlignment); 189887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar auto byrefPtrType = byrefInfo.Type->getPointerTo(0); 189987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar addr = CGF.Builder.CreateBitCast(addr, byrefPtrType); 190087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar addr = CGF.emitBlockByrefAddress(addr, byrefInfo, false, "object"); 1901d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall 190287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar generator.emitDispose(CGF, addr); 1903830937bc1100fba7682f7c32c40512085870f50cFariborz Jahanian } 190445031c08c608e548ac12caf0547f89574e994b96Mike Stump 1905f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall CGF.FinishFunction(); 1906d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall 1907f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall return llvm::ConstantExpr::getBitCast(Fn, CGF.Int8PtrTy); 190845031c08c608e548ac12caf0547f89574e994b96Mike Stump} 190945031c08c608e548ac12caf0547f89574e994b96Mike Stump 1910f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall/// Build the dispose helper for a __block variable. 1911f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCallstatic llvm::Constant *buildByrefDisposeHelper(CodeGenModule &CGM, 191287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar const BlockByrefInfo &byrefInfo, 191387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar BlockByrefHelpers &generator) { 1914f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall CodeGenFunction CGF(CGM); 191587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar return generateByrefDisposeHelper(CGF, byrefInfo, generator); 191645031c08c608e548ac12caf0547f89574e994b96Mike Stump} 191745031c08c608e548ac12caf0547f89574e994b96Mike Stump 1918b62faef5ec86c1931785ffa805ece9b491735894John McCall/// Lazily build the copy and dispose helpers for a __block variable 1919b62faef5ec86c1931785ffa805ece9b491735894John McCall/// with the given information. 192087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainartemplate <class T> 192187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainarstatic T *buildByrefHelpers(CodeGenModule &CGM, const BlockByrefInfo &byrefInfo, 192287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar T &&generator) { 1923f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall llvm::FoldingSetNodeID id; 192487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar generator.Profile(id); 1925f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall 1926f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall void *insertPos; 192787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar BlockByrefHelpers *node 1928f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall = CGM.ByrefHelpersCache.FindNodeOrInsertPos(id, insertPos); 1929f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall if (node) return static_cast<T*>(node); 1930f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall 193187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar generator.CopyHelper = buildByrefCopyHelper(CGM, byrefInfo, generator); 193287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar generator.DisposeHelper = buildByrefDisposeHelper(CGM, byrefInfo, generator); 1933f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall 193487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar T *copy = new (CGM.getContext()) T(std::move(generator)); 1935f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall CGM.ByrefHelpersCache.InsertNode(copy, insertPos); 1936f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall return copy; 1937f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall} 1938f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall 1939b62faef5ec86c1931785ffa805ece9b491735894John McCall/// Build the copy and dispose helpers for the given __block variable 1940b62faef5ec86c1931785ffa805ece9b491735894John McCall/// emission. Places the helpers in the global cache. Returns null 1941b62faef5ec86c1931785ffa805ece9b491735894John McCall/// if no helpers are required. 194287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga NainarBlockByrefHelpers * 19432acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris LattnerCodeGenFunction::buildByrefHelpers(llvm::StructType &byrefType, 1944f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall const AutoVarEmission &emission) { 1945f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall const VarDecl &var = *emission.Variable; 1946f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall QualType type = var.getType(); 1947f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall 194887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar auto &byrefInfo = getBlockByrefInfo(&var); 194987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 195087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // The alignment we care about for the purposes of uniquing byref 195187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // helpers is the alignment of the actual byref value field. 195287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar CharUnits valueAlignment = 195387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar byrefInfo.ByrefAlignment.alignmentAtOffset(byrefInfo.FieldOffset); 1954b62faef5ec86c1931785ffa805ece9b491735894John McCall 1955f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall if (const CXXRecordDecl *record = type->getAsCXXRecordDecl()) { 1956f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall const Expr *copyExpr = CGM.getContext().getBlockVarCopyInits(&var); 19576bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (!copyExpr && record->hasTrivialDestructor()) return nullptr; 1958f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall 195987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar return ::buildByrefHelpers( 196087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar CGM, byrefInfo, CXXByrefHelpers(valueAlignment, type, copyExpr)); 1961f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall } 1962f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall 1963f85e193739c953358c865005855253af4f68a497John McCall // Otherwise, if we don't have a retainable type, there's nothing to do. 1964f85e193739c953358c865005855253af4f68a497John McCall // that the runtime does extra copies. 19656bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (!type->isObjCRetainableType()) return nullptr; 1966f85e193739c953358c865005855253af4f68a497John McCall 1967f85e193739c953358c865005855253af4f68a497John McCall Qualifiers qs = type.getQualifiers(); 1968f85e193739c953358c865005855253af4f68a497John McCall 1969f85e193739c953358c865005855253af4f68a497John McCall // If we have lifetime, that dominates. 1970f85e193739c953358c865005855253af4f68a497John McCall if (Qualifiers::ObjCLifetime lifetime = qs.getObjCLifetime()) { 1971f85e193739c953358c865005855253af4f68a497John McCall switch (lifetime) { 1972f85e193739c953358c865005855253af4f68a497John McCall case Qualifiers::OCL_None: llvm_unreachable("impossible"); 1973f85e193739c953358c865005855253af4f68a497John McCall 1974f85e193739c953358c865005855253af4f68a497John McCall // These are just bits as far as the runtime is concerned. 1975f85e193739c953358c865005855253af4f68a497John McCall case Qualifiers::OCL_ExplicitNone: 1976f85e193739c953358c865005855253af4f68a497John McCall case Qualifiers::OCL_Autoreleasing: 19776bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 1978f85e193739c953358c865005855253af4f68a497John McCall 1979f85e193739c953358c865005855253af4f68a497John McCall // Tell the runtime that this is ARC __weak, called by the 1980f85e193739c953358c865005855253af4f68a497John McCall // byref routines. 198187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar case Qualifiers::OCL_Weak: 198287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar return ::buildByrefHelpers(CGM, byrefInfo, 198387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar ARCWeakByrefHelpers(valueAlignment)); 1984f85e193739c953358c865005855253af4f68a497John McCall 1985f85e193739c953358c865005855253af4f68a497John McCall // ARC __strong __block variables need to be retained. 1986f85e193739c953358c865005855253af4f68a497John McCall case Qualifiers::OCL_Strong: 1987a59e4b7fca1d46afd8f315fa87fa8bf1a68df9cdJohn McCall // Block pointers need to be copied, and there's no direct 1988a59e4b7fca1d46afd8f315fa87fa8bf1a68df9cdJohn McCall // transfer possible. 1989f85e193739c953358c865005855253af4f68a497John McCall if (type->isBlockPointerType()) { 199087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar return ::buildByrefHelpers(CGM, byrefInfo, 199187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar ARCStrongBlockByrefHelpers(valueAlignment)); 1992f85e193739c953358c865005855253af4f68a497John McCall 1993f85e193739c953358c865005855253af4f68a497John McCall // Otherwise, we transfer ownership of the retain from the stack 1994f85e193739c953358c865005855253af4f68a497John McCall // to the heap. 1995f85e193739c953358c865005855253af4f68a497John McCall } else { 199687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar return ::buildByrefHelpers(CGM, byrefInfo, 199787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar ARCStrongByrefHelpers(valueAlignment)); 1998f85e193739c953358c865005855253af4f68a497John McCall } 1999f85e193739c953358c865005855253af4f68a497John McCall } 2000f85e193739c953358c865005855253af4f68a497John McCall llvm_unreachable("fell out of lifetime switch!"); 2001f85e193739c953358c865005855253af4f68a497John McCall } 2002f85e193739c953358c865005855253af4f68a497John McCall 2003f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall BlockFieldFlags flags; 2004f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall if (type->isBlockPointerType()) { 2005f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall flags |= BLOCK_FIELD_IS_BLOCK; 2006f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall } else if (CGM.getContext().isObjCNSObjectType(type) || 2007f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall type->isObjCObjectPointerType()) { 2008f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall flags |= BLOCK_FIELD_IS_OBJECT; 2009f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall } else { 20106bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 2011f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall } 2012f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall 2013f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall if (type.isObjCGCWeak()) 2014f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall flags |= BLOCK_FIELD_IS_WEAK; 2015f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall 201687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar return ::buildByrefHelpers(CGM, byrefInfo, 201787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar ObjectByrefHelpers(valueAlignment, flags)); 201845031c08c608e548ac12caf0547f89574e994b96Mike Stump} 201945031c08c608e548ac12caf0547f89574e994b96Mike Stump 202087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga NainarAddress CodeGenFunction::emitBlockByrefAddress(Address baseAddr, 202187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar const VarDecl *var, 202287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar bool followForward) { 202387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar auto &info = getBlockByrefInfo(var); 202487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar return emitBlockByrefAddress(baseAddr, info, followForward, var->getName()); 20255af02db5a48476e0748f135369663080eae87c64John McCall} 20265af02db5a48476e0748f135369663080eae87c64John McCall 202787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga NainarAddress CodeGenFunction::emitBlockByrefAddress(Address baseAddr, 202887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar const BlockByrefInfo &info, 202987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar bool followForward, 203087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar const llvm::Twine &name) { 203187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // Chase the forwarding address if requested. 203287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (followForward) { 203387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar Address forwardingAddr = 203487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar Builder.CreateStructGEP(baseAddr, 1, getPointerSize(), "forwarding"); 203587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar baseAddr = Address(Builder.CreateLoad(forwardingAddr), info.ByrefAlignment); 203687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 203787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 203887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar return Builder.CreateStructGEP(baseAddr, info.FieldIndex, 203987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar info.FieldOffset, name); 20405af02db5a48476e0748f135369663080eae87c64John McCall} 20415af02db5a48476e0748f135369663080eae87c64John McCall 204287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar/// BuildByrefInfo - This routine changes a __block variable declared as T x 20435af02db5a48476e0748f135369663080eae87c64John McCall/// into: 20445af02db5a48476e0748f135369663080eae87c64John McCall/// 20455af02db5a48476e0748f135369663080eae87c64John McCall/// struct { 20465af02db5a48476e0748f135369663080eae87c64John McCall/// void *__isa; 20475af02db5a48476e0748f135369663080eae87c64John McCall/// void *__forwarding; 20485af02db5a48476e0748f135369663080eae87c64John McCall/// int32_t __flags; 20495af02db5a48476e0748f135369663080eae87c64John McCall/// int32_t __size; 20505af02db5a48476e0748f135369663080eae87c64John McCall/// void *__copy_helper; // only if needed 20515af02db5a48476e0748f135369663080eae87c64John McCall/// void *__destroy_helper; // only if needed 20523ca23d7dc6cb61e6f363a58d9256d548199d120cFariborz Jahanian/// void *__byref_variable_layout;// only if needed 20535af02db5a48476e0748f135369663080eae87c64John McCall/// char padding[X]; // only if needed 20545af02db5a48476e0748f135369663080eae87c64John McCall/// T x; 20555af02db5a48476e0748f135369663080eae87c64John McCall/// } x 20565af02db5a48476e0748f135369663080eae87c64John McCall/// 205787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainarconst BlockByrefInfo &CodeGenFunction::getBlockByrefInfo(const VarDecl *D) { 205887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar auto it = BlockByrefInfos.find(D); 205987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (it != BlockByrefInfos.end()) 206087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar return it->second; 206187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 206287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar llvm::StructType *byrefType = 206387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar llvm::StructType::create(getLLVMContext(), 206487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar "struct.__block_byref_" + D->getNameAsString()); 20655af02db5a48476e0748f135369663080eae87c64John McCall 20665af02db5a48476e0748f135369663080eae87c64John McCall QualType Ty = D->getType(); 20675af02db5a48476e0748f135369663080eae87c64John McCall 206887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar CharUnits size; 20695f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<llvm::Type *, 8> types; 20705af02db5a48476e0748f135369663080eae87c64John McCall 20715af02db5a48476e0748f135369663080eae87c64John McCall // void *__isa; 20720774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall types.push_back(Int8PtrTy); 207387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar size += getPointerSize(); 20745af02db5a48476e0748f135369663080eae87c64John McCall 20755af02db5a48476e0748f135369663080eae87c64John McCall // void *__forwarding; 207687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar types.push_back(llvm::PointerType::getUnqual(byrefType)); 207787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar size += getPointerSize(); 20785af02db5a48476e0748f135369663080eae87c64John McCall 20795af02db5a48476e0748f135369663080eae87c64John McCall // int32_t __flags; 20800774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall types.push_back(Int32Ty); 208187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar size += CharUnits::fromQuantity(4); 20825af02db5a48476e0748f135369663080eae87c64John McCall 20835af02db5a48476e0748f135369663080eae87c64John McCall // int32_t __size; 20840774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall types.push_back(Int32Ty); 208587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar size += CharUnits::fromQuantity(4); 208687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 2087b15c8984ea300624fbbde385d3907667ce1043faFariborz Jahanian // Note that this must match *exactly* the logic in buildByrefHelpers. 208887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar bool hasCopyAndDispose = getContext().BlockRequiresCopying(Ty, D); 208987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (hasCopyAndDispose) { 20905af02db5a48476e0748f135369663080eae87c64John McCall /// void *__copy_helper; 20910774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall types.push_back(Int8PtrTy); 209287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar size += getPointerSize(); 20935af02db5a48476e0748f135369663080eae87c64John McCall 20945af02db5a48476e0748f135369663080eae87c64John McCall /// void *__destroy_helper; 20950774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall types.push_back(Int8PtrTy); 209687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar size += getPointerSize(); 20975af02db5a48476e0748f135369663080eae87c64John McCall } 209887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 20993ca23d7dc6cb61e6f363a58d9256d548199d120cFariborz Jahanian bool HasByrefExtendedLayout = false; 21003ca23d7dc6cb61e6f363a58d9256d548199d120cFariborz Jahanian Qualifiers::ObjCLifetime Lifetime; 21013ca23d7dc6cb61e6f363a58d9256d548199d120cFariborz Jahanian if (getContext().getByrefLifetime(Ty, Lifetime, HasByrefExtendedLayout) && 210287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar HasByrefExtendedLayout) { 21033ca23d7dc6cb61e6f363a58d9256d548199d120cFariborz Jahanian /// void *__byref_variable_layout; 21043ca23d7dc6cb61e6f363a58d9256d548199d120cFariborz Jahanian types.push_back(Int8PtrTy); 210587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar size += CharUnits::fromQuantity(PointerSizeInBytes); 210687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 21075af02db5a48476e0748f135369663080eae87c64John McCall 210887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // T x; 210987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar llvm::Type *varTy = ConvertTypeForMem(Ty); 21105af02db5a48476e0748f135369663080eae87c64John McCall 211187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar bool packed = false; 211287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar CharUnits varAlign = getContext().getDeclAlign(D); 21134967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar CharUnits varOffset = size.alignTo(varAlign); 211487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 211587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // We may have to insert padding. 211687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (varOffset != size) { 211787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar llvm::Type *paddingTy = 211887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar llvm::ArrayType::get(Int8Ty, (varOffset - size).getQuantity()); 211987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 212087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar types.push_back(paddingTy); 212187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar size = varOffset; 212287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 212387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // Conversely, we might have to prevent LLVM from inserting padding. 212487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } else if (CGM.getDataLayout().getABITypeAlignment(varTy) 212587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar > varAlign.getQuantity()) { 212687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar packed = true; 21275af02db5a48476e0748f135369663080eae87c64John McCall } 212887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar types.push_back(varTy); 21295af02db5a48476e0748f135369663080eae87c64John McCall 213087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar byrefType->setBody(types, packed); 213187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 213287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar BlockByrefInfo info; 213387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar info.Type = byrefType; 213487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar info.FieldIndex = types.size() - 1; 213587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar info.FieldOffset = varOffset; 213687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar info.ByrefAlignment = std::max(varAlign, getPointerAlign()); 213787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 213887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar auto pair = BlockByrefInfos.insert({D, info}); 213987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar assert(pair.second && "info was inserted recursively?"); 214087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar return pair.first->second; 21415af02db5a48476e0748f135369663080eae87c64John McCall} 21425af02db5a48476e0748f135369663080eae87c64John McCall 21435af02db5a48476e0748f135369663080eae87c64John McCall/// Initialize the structural components of a __block variable, i.e. 21445af02db5a48476e0748f135369663080eae87c64John McCall/// everything but the actual object. 21455af02db5a48476e0748f135369663080eae87c64John McCallvoid CodeGenFunction::emitByrefStructureInit(const AutoVarEmission &emission) { 2146f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall // Find the address of the local. 214787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar Address addr = emission.Addr; 2148f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall 2149f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall // That's an alloca of the byref structure type. 21502acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::StructType *byrefType = cast<llvm::StructType>( 215187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar cast<llvm::PointerType>(addr.getPointer()->getType())->getElementType()); 215287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 215387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar unsigned nextHeaderIndex = 0; 215487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar CharUnits nextHeaderOffset; 215587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar auto storeHeaderField = [&](llvm::Value *value, CharUnits fieldSize, 215687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar const Twine &name) { 215787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar auto fieldAddr = Builder.CreateStructGEP(addr, nextHeaderIndex, 215887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar nextHeaderOffset, name); 215987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar Builder.CreateStore(value, fieldAddr); 216087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 216187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar nextHeaderIndex++; 216287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar nextHeaderOffset += fieldSize; 216387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar }; 21645af02db5a48476e0748f135369663080eae87c64John McCall 2165f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall // Build the byref helpers if necessary. This is null if we don't need any. 216687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar BlockByrefHelpers *helpers = buildByrefHelpers(*byrefType, emission); 21675af02db5a48476e0748f135369663080eae87c64John McCall 21685af02db5a48476e0748f135369663080eae87c64John McCall const VarDecl &D = *emission.Variable; 21695af02db5a48476e0748f135369663080eae87c64John McCall QualType type = D.getType(); 21705af02db5a48476e0748f135369663080eae87c64John McCall 21713ca23d7dc6cb61e6f363a58d9256d548199d120cFariborz Jahanian bool HasByrefExtendedLayout; 21723ca23d7dc6cb61e6f363a58d9256d548199d120cFariborz Jahanian Qualifiers::ObjCLifetime ByrefLifetime; 21733ca23d7dc6cb61e6f363a58d9256d548199d120cFariborz Jahanian bool ByRefHasLifetime = 21743ca23d7dc6cb61e6f363a58d9256d548199d120cFariborz Jahanian getContext().getByrefLifetime(type, ByrefLifetime, HasByrefExtendedLayout); 217587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 2176f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall llvm::Value *V; 21775af02db5a48476e0748f135369663080eae87c64John McCall 21785af02db5a48476e0748f135369663080eae87c64John McCall // Initialize the 'isa', which is just 0 or 1. 21795af02db5a48476e0748f135369663080eae87c64John McCall int isa = 0; 2180f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall if (type.isObjCGCWeak()) 21815af02db5a48476e0748f135369663080eae87c64John McCall isa = 1; 21825af02db5a48476e0748f135369663080eae87c64John McCall V = Builder.CreateIntToPtr(Builder.getInt32(isa), Int8PtrTy, "isa"); 218387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar storeHeaderField(V, getPointerSize(), "byref.isa"); 21845af02db5a48476e0748f135369663080eae87c64John McCall 21855af02db5a48476e0748f135369663080eae87c64John McCall // Store the address of the variable into its own forwarding pointer. 218687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar storeHeaderField(addr.getPointer(), getPointerSize(), "byref.forwarding"); 21875af02db5a48476e0748f135369663080eae87c64John McCall 21885af02db5a48476e0748f135369663080eae87c64John McCall // Blocks ABI: 21895af02db5a48476e0748f135369663080eae87c64John McCall // c) the flags field is set to either 0 if no helper functions are 21903ca23d7dc6cb61e6f363a58d9256d548199d120cFariborz Jahanian // needed or BLOCK_BYREF_HAS_COPY_DISPOSE if they are, 21915af02db5a48476e0748f135369663080eae87c64John McCall BlockFlags flags; 21923ca23d7dc6cb61e6f363a58d9256d548199d120cFariborz Jahanian if (helpers) flags |= BLOCK_BYREF_HAS_COPY_DISPOSE; 21933ca23d7dc6cb61e6f363a58d9256d548199d120cFariborz Jahanian if (ByRefHasLifetime) { 21943ca23d7dc6cb61e6f363a58d9256d548199d120cFariborz Jahanian if (HasByrefExtendedLayout) flags |= BLOCK_BYREF_LAYOUT_EXTENDED; 21953ca23d7dc6cb61e6f363a58d9256d548199d120cFariborz Jahanian else switch (ByrefLifetime) { 21963ca23d7dc6cb61e6f363a58d9256d548199d120cFariborz Jahanian case Qualifiers::OCL_Strong: 21973ca23d7dc6cb61e6f363a58d9256d548199d120cFariborz Jahanian flags |= BLOCK_BYREF_LAYOUT_STRONG; 21983ca23d7dc6cb61e6f363a58d9256d548199d120cFariborz Jahanian break; 21993ca23d7dc6cb61e6f363a58d9256d548199d120cFariborz Jahanian case Qualifiers::OCL_Weak: 22003ca23d7dc6cb61e6f363a58d9256d548199d120cFariborz Jahanian flags |= BLOCK_BYREF_LAYOUT_WEAK; 22013ca23d7dc6cb61e6f363a58d9256d548199d120cFariborz Jahanian break; 22023ca23d7dc6cb61e6f363a58d9256d548199d120cFariborz Jahanian case Qualifiers::OCL_ExplicitNone: 22033ca23d7dc6cb61e6f363a58d9256d548199d120cFariborz Jahanian flags |= BLOCK_BYREF_LAYOUT_UNRETAINED; 22043ca23d7dc6cb61e6f363a58d9256d548199d120cFariborz Jahanian break; 22053ca23d7dc6cb61e6f363a58d9256d548199d120cFariborz Jahanian case Qualifiers::OCL_None: 22063ca23d7dc6cb61e6f363a58d9256d548199d120cFariborz Jahanian if (!type->isObjCObjectPointerType() && !type->isBlockPointerType()) 22073ca23d7dc6cb61e6f363a58d9256d548199d120cFariborz Jahanian flags |= BLOCK_BYREF_LAYOUT_NON_OBJECT; 22083ca23d7dc6cb61e6f363a58d9256d548199d120cFariborz Jahanian break; 22093ca23d7dc6cb61e6f363a58d9256d548199d120cFariborz Jahanian default: 22103ca23d7dc6cb61e6f363a58d9256d548199d120cFariborz Jahanian break; 22113ca23d7dc6cb61e6f363a58d9256d548199d120cFariborz Jahanian } 22123ca23d7dc6cb61e6f363a58d9256d548199d120cFariborz Jahanian if (CGM.getLangOpts().ObjCGCBitmapPrint) { 22133ca23d7dc6cb61e6f363a58d9256d548199d120cFariborz Jahanian printf("\n Inline flag for BYREF variable layout (%d):", flags.getBitMask()); 22143ca23d7dc6cb61e6f363a58d9256d548199d120cFariborz Jahanian if (flags & BLOCK_BYREF_HAS_COPY_DISPOSE) 22153ca23d7dc6cb61e6f363a58d9256d548199d120cFariborz Jahanian printf(" BLOCK_BYREF_HAS_COPY_DISPOSE"); 22163ca23d7dc6cb61e6f363a58d9256d548199d120cFariborz Jahanian if (flags & BLOCK_BYREF_LAYOUT_MASK) { 22173ca23d7dc6cb61e6f363a58d9256d548199d120cFariborz Jahanian BlockFlags ThisFlag(flags.getBitMask() & BLOCK_BYREF_LAYOUT_MASK); 22183ca23d7dc6cb61e6f363a58d9256d548199d120cFariborz Jahanian if (ThisFlag == BLOCK_BYREF_LAYOUT_EXTENDED) 22193ca23d7dc6cb61e6f363a58d9256d548199d120cFariborz Jahanian printf(" BLOCK_BYREF_LAYOUT_EXTENDED"); 22203ca23d7dc6cb61e6f363a58d9256d548199d120cFariborz Jahanian if (ThisFlag == BLOCK_BYREF_LAYOUT_STRONG) 22213ca23d7dc6cb61e6f363a58d9256d548199d120cFariborz Jahanian printf(" BLOCK_BYREF_LAYOUT_STRONG"); 22223ca23d7dc6cb61e6f363a58d9256d548199d120cFariborz Jahanian if (ThisFlag == BLOCK_BYREF_LAYOUT_WEAK) 22233ca23d7dc6cb61e6f363a58d9256d548199d120cFariborz Jahanian printf(" BLOCK_BYREF_LAYOUT_WEAK"); 22243ca23d7dc6cb61e6f363a58d9256d548199d120cFariborz Jahanian if (ThisFlag == BLOCK_BYREF_LAYOUT_UNRETAINED) 22253ca23d7dc6cb61e6f363a58d9256d548199d120cFariborz Jahanian printf(" BLOCK_BYREF_LAYOUT_UNRETAINED"); 22263ca23d7dc6cb61e6f363a58d9256d548199d120cFariborz Jahanian if (ThisFlag == BLOCK_BYREF_LAYOUT_NON_OBJECT) 22273ca23d7dc6cb61e6f363a58d9256d548199d120cFariborz Jahanian printf(" BLOCK_BYREF_LAYOUT_NON_OBJECT"); 22283ca23d7dc6cb61e6f363a58d9256d548199d120cFariborz Jahanian } 22293ca23d7dc6cb61e6f363a58d9256d548199d120cFariborz Jahanian printf("\n"); 22303ca23d7dc6cb61e6f363a58d9256d548199d120cFariborz Jahanian } 22313ca23d7dc6cb61e6f363a58d9256d548199d120cFariborz Jahanian } 223287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar storeHeaderField(llvm::ConstantInt::get(IntTy, flags.getBitMask()), 223387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar getIntSize(), "byref.flags"); 22345af02db5a48476e0748f135369663080eae87c64John McCall 2235f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall CharUnits byrefSize = CGM.GetTargetTypeStoreSize(byrefType); 2236f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall V = llvm::ConstantInt::get(IntTy, byrefSize.getQuantity()); 223787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar storeHeaderField(V, getIntSize(), "byref.size"); 22385af02db5a48476e0748f135369663080eae87c64John McCall 2239f0c11f7e6848f023ced6a5b51399ba787c7d4d0bJohn McCall if (helpers) { 224087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar storeHeaderField(helpers->CopyHelper, getPointerSize(), 224187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar "byref.copyHelper"); 224287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar storeHeaderField(helpers->DisposeHelper, getPointerSize(), 224387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar "byref.disposeHelper"); 22445af02db5a48476e0748f135369663080eae87c64John McCall } 224587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 22463ca23d7dc6cb61e6f363a58d9256d548199d120cFariborz Jahanian if (ByRefHasLifetime && HasByrefExtendedLayout) { 224787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar auto layoutInfo = CGM.getObjCRuntime().BuildByrefLayout(CGM, type); 224887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar storeHeaderField(layoutInfo, getPointerSize(), "byref.layout"); 22493ca23d7dc6cb61e6f363a58d9256d548199d120cFariborz Jahanian } 22505af02db5a48476e0748f135369663080eae87c64John McCall} 22515af02db5a48476e0748f135369663080eae87c64John McCall 2252d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCallvoid CodeGenFunction::BuildBlockRelease(llvm::Value *V, BlockFieldFlags flags) { 2253673431a2986f750b4d8fadb57abf3f00db27bbbdDaniel Dunbar llvm::Value *F = CGM.getBlockObjectDispose(); 2254bd7370a78604e9a20d698bfe328c1e43f12a0613John McCall llvm::Value *args[] = { 2255bd7370a78604e9a20d698bfe328c1e43f12a0613John McCall Builder.CreateBitCast(V, Int8PtrTy), 2256bd7370a78604e9a20d698bfe328c1e43f12a0613John McCall llvm::ConstantInt::get(Int32Ty, flags.getBitMask()) 2257bd7370a78604e9a20d698bfe328c1e43f12a0613John McCall }; 2258bd7370a78604e9a20d698bfe328c1e43f12a0613John McCall EmitNounwindRuntimeCall(F, args); // FIXME: throwing destructors? 2259797b6327571f9d7b1c45404a56ddcbf9b9298ae8Mike Stump} 22605af02db5a48476e0748f135369663080eae87c64John McCall 22615af02db5a48476e0748f135369663080eae87c64John McCallnamespace { 226287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar /// Release a __block variable. 226387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar struct CallBlockRelease final : EHScopeStack::Cleanup { 22645af02db5a48476e0748f135369663080eae87c64John McCall llvm::Value *Addr; 22655af02db5a48476e0748f135369663080eae87c64John McCall CallBlockRelease(llvm::Value *Addr) : Addr(Addr) {} 22665af02db5a48476e0748f135369663080eae87c64John McCall 2267651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void Emit(CodeGenFunction &CGF, Flags flags) override { 2268f85e193739c953358c865005855253af4f68a497John McCall // Should we be passing FIELD_IS_WEAK here? 22695af02db5a48476e0748f135369663080eae87c64John McCall CGF.BuildBlockRelease(Addr, BLOCK_FIELD_IS_BYREF); 22705af02db5a48476e0748f135369663080eae87c64John McCall } 22715af02db5a48476e0748f135369663080eae87c64John McCall }; 227287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar} // end anonymous namespace 22735af02db5a48476e0748f135369663080eae87c64John McCall 22745af02db5a48476e0748f135369663080eae87c64John McCall/// Enter a cleanup to destroy a __block variable. Note that this 22755af02db5a48476e0748f135369663080eae87c64John McCall/// cleanup should be a no-op if the variable hasn't left the stack 22765af02db5a48476e0748f135369663080eae87c64John McCall/// yet; if a cleanup is required for the variable itself, that needs 22775af02db5a48476e0748f135369663080eae87c64John McCall/// to be done externally. 22785af02db5a48476e0748f135369663080eae87c64John McCallvoid CodeGenFunction::enterByrefCleanup(const AutoVarEmission &emission) { 22795af02db5a48476e0748f135369663080eae87c64John McCall // We don't enter this cleanup if we're in pure-GC mode. 22804e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (CGM.getLangOpts().getGC() == LangOptions::GCOnly) 22815af02db5a48476e0748f135369663080eae87c64John McCall return; 22825af02db5a48476e0748f135369663080eae87c64John McCall 228387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar EHStack.pushCleanup<CallBlockRelease>(NormalAndEHCleanup, 228487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar emission.Addr.getPointer()); 22855af02db5a48476e0748f135369663080eae87c64John McCall} 228613db5cfc4e5f03eb70efe0d227b53b8280f16161John McCall 228713db5cfc4e5f03eb70efe0d227b53b8280f16161John McCall/// Adjust the declaration of something from the blocks API. 228813db5cfc4e5f03eb70efe0d227b53b8280f16161John McCallstatic void configureBlocksRuntimeObject(CodeGenModule &CGM, 228913db5cfc4e5f03eb70efe0d227b53b8280f16161John McCall llvm::Constant *C) { 22906bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines auto *GV = cast<llvm::GlobalValue>(C->stripPointerCasts()); 22914967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 22924967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (CGM.getTarget().getTriple().isOSBinFormatCOFF()) { 22934967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar IdentifierInfo &II = CGM.getContext().Idents.get(C->getName()); 22944967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar TranslationUnitDecl *TUDecl = CGM.getContext().getTranslationUnitDecl(); 22954967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar DeclContext *DC = TranslationUnitDecl::castToDeclContext(TUDecl); 22964967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 22974967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar assert((isa<llvm::Function>(C->stripPointerCasts()) || 22984967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar isa<llvm::GlobalVariable>(C->stripPointerCasts())) && 22994967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar "expected Function or GlobalVariable"); 23004967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 23014967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar const NamedDecl *ND = nullptr; 23024967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar for (const auto &Result : DC->lookup(&II)) 23034967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if ((ND = dyn_cast<FunctionDecl>(Result)) || 23044967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar (ND = dyn_cast<VarDecl>(Result))) 23054967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar break; 23064967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 23074967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // TODO: support static blocks runtime 23084967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (GV->isDeclaration() && (!ND || !ND->hasAttr<DLLExportAttr>())) { 23094967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar GV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass); 23104967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar GV->setLinkage(llvm::GlobalValue::ExternalLinkage); 23114967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } else { 23124967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar GV->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass); 23134967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar GV->setLinkage(llvm::GlobalValue::ExternalLinkage); 23144967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 23154967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 23164967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 23174967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (!CGM.getLangOpts().BlocksRuntimeOptional) 23184967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar return; 23194967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 23206bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (GV->isDeclaration() && GV->hasExternalLinkage()) 232113db5cfc4e5f03eb70efe0d227b53b8280f16161John McCall GV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage); 232213db5cfc4e5f03eb70efe0d227b53b8280f16161John McCall} 232313db5cfc4e5f03eb70efe0d227b53b8280f16161John McCall 232413db5cfc4e5f03eb70efe0d227b53b8280f16161John McCallllvm::Constant *CodeGenModule::getBlockObjectDispose() { 232513db5cfc4e5f03eb70efe0d227b53b8280f16161John McCall if (BlockObjectDispose) 232613db5cfc4e5f03eb70efe0d227b53b8280f16161John McCall return BlockObjectDispose; 232713db5cfc4e5f03eb70efe0d227b53b8280f16161John McCall 232813db5cfc4e5f03eb70efe0d227b53b8280f16161John McCall llvm::Type *args[] = { Int8PtrTy, Int32Ty }; 232913db5cfc4e5f03eb70efe0d227b53b8280f16161John McCall llvm::FunctionType *fty 233013db5cfc4e5f03eb70efe0d227b53b8280f16161John McCall = llvm::FunctionType::get(VoidTy, args, false); 233113db5cfc4e5f03eb70efe0d227b53b8280f16161John McCall BlockObjectDispose = CreateRuntimeFunction(fty, "_Block_object_dispose"); 233213db5cfc4e5f03eb70efe0d227b53b8280f16161John McCall configureBlocksRuntimeObject(*this, BlockObjectDispose); 233313db5cfc4e5f03eb70efe0d227b53b8280f16161John McCall return BlockObjectDispose; 233413db5cfc4e5f03eb70efe0d227b53b8280f16161John McCall} 233513db5cfc4e5f03eb70efe0d227b53b8280f16161John McCall 233613db5cfc4e5f03eb70efe0d227b53b8280f16161John McCallllvm::Constant *CodeGenModule::getBlockObjectAssign() { 233713db5cfc4e5f03eb70efe0d227b53b8280f16161John McCall if (BlockObjectAssign) 233813db5cfc4e5f03eb70efe0d227b53b8280f16161John McCall return BlockObjectAssign; 233913db5cfc4e5f03eb70efe0d227b53b8280f16161John McCall 234013db5cfc4e5f03eb70efe0d227b53b8280f16161John McCall llvm::Type *args[] = { Int8PtrTy, Int8PtrTy, Int32Ty }; 234113db5cfc4e5f03eb70efe0d227b53b8280f16161John McCall llvm::FunctionType *fty 234213db5cfc4e5f03eb70efe0d227b53b8280f16161John McCall = llvm::FunctionType::get(VoidTy, args, false); 234313db5cfc4e5f03eb70efe0d227b53b8280f16161John McCall BlockObjectAssign = CreateRuntimeFunction(fty, "_Block_object_assign"); 234413db5cfc4e5f03eb70efe0d227b53b8280f16161John McCall configureBlocksRuntimeObject(*this, BlockObjectAssign); 234513db5cfc4e5f03eb70efe0d227b53b8280f16161John McCall return BlockObjectAssign; 234613db5cfc4e5f03eb70efe0d227b53b8280f16161John McCall} 234713db5cfc4e5f03eb70efe0d227b53b8280f16161John McCall 234813db5cfc4e5f03eb70efe0d227b53b8280f16161John McCallllvm::Constant *CodeGenModule::getNSConcreteGlobalBlock() { 234913db5cfc4e5f03eb70efe0d227b53b8280f16161John McCall if (NSConcreteGlobalBlock) 235013db5cfc4e5f03eb70efe0d227b53b8280f16161John McCall return NSConcreteGlobalBlock; 235113db5cfc4e5f03eb70efe0d227b53b8280f16161John McCall 235213db5cfc4e5f03eb70efe0d227b53b8280f16161John McCall NSConcreteGlobalBlock = GetOrCreateLLVMGlobal("_NSConcreteGlobalBlock", 23536bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Int8PtrTy->getPointerTo(), 23546bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines nullptr); 235513db5cfc4e5f03eb70efe0d227b53b8280f16161John McCall configureBlocksRuntimeObject(*this, NSConcreteGlobalBlock); 235613db5cfc4e5f03eb70efe0d227b53b8280f16161John McCall return NSConcreteGlobalBlock; 235713db5cfc4e5f03eb70efe0d227b53b8280f16161John McCall} 235813db5cfc4e5f03eb70efe0d227b53b8280f16161John McCall 235913db5cfc4e5f03eb70efe0d227b53b8280f16161John McCallllvm::Constant *CodeGenModule::getNSConcreteStackBlock() { 236013db5cfc4e5f03eb70efe0d227b53b8280f16161John McCall if (NSConcreteStackBlock) 236113db5cfc4e5f03eb70efe0d227b53b8280f16161John McCall return NSConcreteStackBlock; 236213db5cfc4e5f03eb70efe0d227b53b8280f16161John McCall 236313db5cfc4e5f03eb70efe0d227b53b8280f16161John McCall NSConcreteStackBlock = GetOrCreateLLVMGlobal("_NSConcreteStackBlock", 23646bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Int8PtrTy->getPointerTo(), 23656bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines nullptr); 236613db5cfc4e5f03eb70efe0d227b53b8280f16161John McCall configureBlocksRuntimeObject(*this, NSConcreteStackBlock); 23674967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar return NSConcreteStackBlock; 236813db5cfc4e5f03eb70efe0d227b53b8280f16161John McCall} 2369