Path: blob/main/contrib/llvm-project/clang/lib/CodeGen/CGBlocks.cpp
35233 views
//===--- CGBlocks.cpp - Emit LLVM Code for declarations ---------*- C++ -*-===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This contains code to emit blocks.9//10//===----------------------------------------------------------------------===//1112#include "CGBlocks.h"13#include "CGCXXABI.h"14#include "CGDebugInfo.h"15#include "CGObjCRuntime.h"16#include "CGOpenCLRuntime.h"17#include "CodeGenFunction.h"18#include "CodeGenModule.h"19#include "ConstantEmitter.h"20#include "TargetInfo.h"21#include "clang/AST/Attr.h"22#include "clang/AST/DeclObjC.h"23#include "clang/CodeGen/ConstantInitBuilder.h"24#include "llvm/ADT/SmallSet.h"25#include "llvm/IR/DataLayout.h"26#include "llvm/IR/Module.h"27#include "llvm/Support/ScopedPrinter.h"28#include <algorithm>29#include <cstdio>3031using namespace clang;32using namespace CodeGen;3334CGBlockInfo::CGBlockInfo(const BlockDecl *block, StringRef name)35: Name(name), CXXThisIndex(0), CanBeGlobal(false), NeedsCopyDispose(false),36NoEscape(false), HasCXXObject(false), UsesStret(false),37HasCapturedVariableLayout(false), CapturesNonExternalType(false),38LocalAddress(RawAddress::invalid()), StructureType(nullptr),39Block(block) {4041// Skip asm prefix, if any. 'name' is usually taken directly from42// the mangled name of the enclosing function.43if (!name.empty() && name[0] == '\01')44name = name.substr(1);45}4647// Anchor the vtable to this translation unit.48BlockByrefHelpers::~BlockByrefHelpers() {}4950/// Build the given block as a global block.51static llvm::Constant *buildGlobalBlock(CodeGenModule &CGM,52const CGBlockInfo &blockInfo,53llvm::Constant *blockFn);5455/// Build the helper function to copy a block.56static llvm::Constant *buildCopyHelper(CodeGenModule &CGM,57const CGBlockInfo &blockInfo) {58return CodeGenFunction(CGM).GenerateCopyHelperFunction(blockInfo);59}6061/// Build the helper function to dispose of a block.62static llvm::Constant *buildDisposeHelper(CodeGenModule &CGM,63const CGBlockInfo &blockInfo) {64return CodeGenFunction(CGM).GenerateDestroyHelperFunction(blockInfo);65}6667namespace {6869enum class CaptureStrKind {70// String for the copy helper.71CopyHelper,72// String for the dispose helper.73DisposeHelper,74// Merge the strings for the copy helper and dispose helper.75Merged76};7778} // end anonymous namespace7980static std::string getBlockCaptureStr(const CGBlockInfo::Capture &Cap,81CaptureStrKind StrKind,82CharUnits BlockAlignment,83CodeGenModule &CGM);8485static std::string getBlockDescriptorName(const CGBlockInfo &BlockInfo,86CodeGenModule &CGM) {87std::string Name = "__block_descriptor_";88Name += llvm::to_string(BlockInfo.BlockSize.getQuantity()) + "_";8990if (BlockInfo.NeedsCopyDispose) {91if (CGM.getLangOpts().Exceptions)92Name += "e";93if (CGM.getCodeGenOpts().ObjCAutoRefCountExceptions)94Name += "a";95Name += llvm::to_string(BlockInfo.BlockAlign.getQuantity()) + "_";9697for (auto &Cap : BlockInfo.SortedCaptures) {98if (Cap.isConstantOrTrivial())99continue;100101Name += llvm::to_string(Cap.getOffset().getQuantity());102103if (Cap.CopyKind == Cap.DisposeKind) {104// If CopyKind and DisposeKind are the same, merge the capture105// information.106assert(Cap.CopyKind != BlockCaptureEntityKind::None &&107"shouldn't see BlockCaptureManagedEntity that is None");108Name += getBlockCaptureStr(Cap, CaptureStrKind::Merged,109BlockInfo.BlockAlign, CGM);110} else {111// If CopyKind and DisposeKind are not the same, which can happen when112// either Kind is None or the captured object is a __strong block,113// concatenate the copy and dispose strings.114Name += getBlockCaptureStr(Cap, CaptureStrKind::CopyHelper,115BlockInfo.BlockAlign, CGM);116Name += getBlockCaptureStr(Cap, CaptureStrKind::DisposeHelper,117BlockInfo.BlockAlign, CGM);118}119}120Name += "_";121}122123std::string TypeAtEncoding;124125if (!CGM.getCodeGenOpts().DisableBlockSignatureString) {126TypeAtEncoding =127CGM.getContext().getObjCEncodingForBlock(BlockInfo.getBlockExpr());128/// Replace occurrences of '@' with '\1'. '@' is reserved on ELF platforms129/// as a separator between symbol name and symbol version.130std::replace(TypeAtEncoding.begin(), TypeAtEncoding.end(), '@', '\1');131}132Name += "e" + llvm::to_string(TypeAtEncoding.size()) + "_" + TypeAtEncoding;133Name += "l" + CGM.getObjCRuntime().getRCBlockLayoutStr(CGM, BlockInfo);134return Name;135}136137/// buildBlockDescriptor - Build the block descriptor meta-data for a block.138/// buildBlockDescriptor is accessed from 5th field of the Block_literal139/// meta-data and contains stationary information about the block literal.140/// Its definition will have 4 (or optionally 6) words.141/// \code142/// struct Block_descriptor {143/// unsigned long reserved;144/// unsigned long size; // size of Block_literal metadata in bytes.145/// void *copy_func_helper_decl; // optional copy helper.146/// void *destroy_func_decl; // optional destructor helper.147/// void *block_method_encoding_address; // @encode for block literal signature.148/// void *block_layout_info; // encoding of captured block variables.149/// };150/// \endcode151static llvm::Constant *buildBlockDescriptor(CodeGenModule &CGM,152const CGBlockInfo &blockInfo) {153ASTContext &C = CGM.getContext();154155llvm::IntegerType *ulong =156cast<llvm::IntegerType>(CGM.getTypes().ConvertType(C.UnsignedLongTy));157llvm::PointerType *i8p = nullptr;158if (CGM.getLangOpts().OpenCL)159i8p = llvm::PointerType::get(160CGM.getLLVMContext(), C.getTargetAddressSpace(LangAS::opencl_constant));161else162i8p = CGM.VoidPtrTy;163164std::string descName;165166// If an equivalent block descriptor global variable exists, return it.167if (C.getLangOpts().ObjC &&168CGM.getLangOpts().getGC() == LangOptions::NonGC) {169descName = getBlockDescriptorName(blockInfo, CGM);170if (llvm::GlobalValue *desc = CGM.getModule().getNamedValue(descName))171return desc;172}173174// If there isn't an equivalent block descriptor global variable, create a new175// one.176ConstantInitBuilder builder(CGM);177auto elements = builder.beginStruct();178179// reserved180elements.addInt(ulong, 0);181182// Size183// FIXME: What is the right way to say this doesn't fit? We should give184// a user diagnostic in that case. Better fix would be to change the185// API to size_t.186elements.addInt(ulong, blockInfo.BlockSize.getQuantity());187188// Optional copy/dispose helpers.189bool hasInternalHelper = false;190if (blockInfo.NeedsCopyDispose) {191// copy_func_helper_decl192llvm::Constant *copyHelper = buildCopyHelper(CGM, blockInfo);193elements.add(copyHelper);194195// destroy_func_decl196llvm::Constant *disposeHelper = buildDisposeHelper(CGM, blockInfo);197elements.add(disposeHelper);198199if (cast<llvm::Function>(copyHelper->stripPointerCasts())200->hasInternalLinkage() ||201cast<llvm::Function>(disposeHelper->stripPointerCasts())202->hasInternalLinkage())203hasInternalHelper = true;204}205206// Signature. Mandatory ObjC-style method descriptor @encode sequence.207if (CGM.getCodeGenOpts().DisableBlockSignatureString) {208elements.addNullPointer(i8p);209} else {210std::string typeAtEncoding =211CGM.getContext().getObjCEncodingForBlock(blockInfo.getBlockExpr());212elements.add(CGM.GetAddrOfConstantCString(typeAtEncoding).getPointer());213}214215// GC layout.216if (C.getLangOpts().ObjC) {217if (CGM.getLangOpts().getGC() != LangOptions::NonGC)218elements.add(CGM.getObjCRuntime().BuildGCBlockLayout(CGM, blockInfo));219else220elements.add(CGM.getObjCRuntime().BuildRCBlockLayout(CGM, blockInfo));221}222else223elements.addNullPointer(i8p);224225unsigned AddrSpace = 0;226if (C.getLangOpts().OpenCL)227AddrSpace = C.getTargetAddressSpace(LangAS::opencl_constant);228229llvm::GlobalValue::LinkageTypes linkage;230if (descName.empty()) {231linkage = llvm::GlobalValue::InternalLinkage;232descName = "__block_descriptor_tmp";233} else if (hasInternalHelper) {234// If either the copy helper or the dispose helper has internal linkage,235// the block descriptor must have internal linkage too.236linkage = llvm::GlobalValue::InternalLinkage;237} else {238linkage = llvm::GlobalValue::LinkOnceODRLinkage;239}240241llvm::GlobalVariable *global =242elements.finishAndCreateGlobal(descName, CGM.getPointerAlign(),243/*constant*/ true, linkage, AddrSpace);244245if (linkage == llvm::GlobalValue::LinkOnceODRLinkage) {246if (CGM.supportsCOMDAT())247global->setComdat(CGM.getModule().getOrInsertComdat(descName));248global->setVisibility(llvm::GlobalValue::HiddenVisibility);249global->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);250}251252return global;253}254255/*256Purely notional variadic template describing the layout of a block.257258template <class _ResultType, class... _ParamTypes, class... _CaptureTypes>259struct Block_literal {260/// Initialized to one of:261/// extern void *_NSConcreteStackBlock[];262/// extern void *_NSConcreteGlobalBlock[];263///264/// In theory, we could start one off malloc'ed by setting265/// BLOCK_NEEDS_FREE, giving it a refcount of 1, and using266/// this isa:267/// extern void *_NSConcreteMallocBlock[];268struct objc_class *isa;269270/// These are the flags (with corresponding bit number) that the271/// compiler is actually supposed to know about.272/// 23. BLOCK_IS_NOESCAPE - indicates that the block is non-escaping273/// 25. BLOCK_HAS_COPY_DISPOSE - indicates that the block274/// descriptor provides copy and dispose helper functions275/// 26. BLOCK_HAS_CXX_OBJ - indicates that there's a captured276/// object with a nontrivial destructor or copy constructor277/// 28. BLOCK_IS_GLOBAL - indicates that the block is allocated278/// as global memory279/// 29. BLOCK_USE_STRET - indicates that the block function280/// uses stret, which objc_msgSend needs to know about281/// 30. BLOCK_HAS_SIGNATURE - indicates that the block has an282/// @encoded signature string283/// And we're not supposed to manipulate these:284/// 24. BLOCK_NEEDS_FREE - indicates that the block has been moved285/// to malloc'ed memory286/// 27. BLOCK_IS_GC - indicates that the block has been moved to287/// to GC-allocated memory288/// Additionally, the bottom 16 bits are a reference count which289/// should be zero on the stack.290int flags;291292/// Reserved; should be zero-initialized.293int reserved;294295/// Function pointer generated from block literal.296_ResultType (*invoke)(Block_literal *, _ParamTypes...);297298/// Block description metadata generated from block literal.299struct Block_descriptor *block_descriptor;300301/// Captured values follow.302_CapturesTypes captures...;303};304*/305306namespace {307/// A chunk of data that we actually have to capture in the block.308struct BlockLayoutChunk {309CharUnits Alignment;310CharUnits Size;311const BlockDecl::Capture *Capture; // null for 'this'312llvm::Type *Type;313QualType FieldType;314BlockCaptureEntityKind CopyKind, DisposeKind;315BlockFieldFlags CopyFlags, DisposeFlags;316317BlockLayoutChunk(CharUnits align, CharUnits size,318const BlockDecl::Capture *capture, llvm::Type *type,319QualType fieldType, BlockCaptureEntityKind CopyKind,320BlockFieldFlags CopyFlags,321BlockCaptureEntityKind DisposeKind,322BlockFieldFlags DisposeFlags)323: Alignment(align), Size(size), Capture(capture), Type(type),324FieldType(fieldType), CopyKind(CopyKind), DisposeKind(DisposeKind),325CopyFlags(CopyFlags), DisposeFlags(DisposeFlags) {}326327/// Tell the block info that this chunk has the given field index.328void setIndex(CGBlockInfo &info, unsigned index, CharUnits offset) {329if (!Capture) {330info.CXXThisIndex = index;331info.CXXThisOffset = offset;332} else {333info.SortedCaptures.push_back(CGBlockInfo::Capture::makeIndex(334index, offset, FieldType, CopyKind, CopyFlags, DisposeKind,335DisposeFlags, Capture));336}337}338339bool isTrivial() const {340return CopyKind == BlockCaptureEntityKind::None &&341DisposeKind == BlockCaptureEntityKind::None;342}343};344345/// Order by 1) all __strong together 2) next, all block together 3) next,346/// all byref together 4) next, all __weak together. Preserve descending347/// alignment in all situations.348bool operator<(const BlockLayoutChunk &left, const BlockLayoutChunk &right) {349if (left.Alignment != right.Alignment)350return left.Alignment > right.Alignment;351352auto getPrefOrder = [](const BlockLayoutChunk &chunk) {353switch (chunk.CopyKind) {354case BlockCaptureEntityKind::ARCStrong:355return 0;356case BlockCaptureEntityKind::BlockObject:357switch (chunk.CopyFlags.getBitMask()) {358case BLOCK_FIELD_IS_OBJECT:359return 0;360case BLOCK_FIELD_IS_BLOCK:361return 1;362case BLOCK_FIELD_IS_BYREF:363return 2;364default:365break;366}367break;368case BlockCaptureEntityKind::ARCWeak:369return 3;370default:371break;372}373return 4;374};375376return getPrefOrder(left) < getPrefOrder(right);377}378} // end anonymous namespace379380static std::pair<BlockCaptureEntityKind, BlockFieldFlags>381computeCopyInfoForBlockCapture(const BlockDecl::Capture &CI, QualType T,382const LangOptions &LangOpts);383384static std::pair<BlockCaptureEntityKind, BlockFieldFlags>385computeDestroyInfoForBlockCapture(const BlockDecl::Capture &CI, QualType T,386const LangOptions &LangOpts);387388static void addBlockLayout(CharUnits align, CharUnits size,389const BlockDecl::Capture *capture, llvm::Type *type,390QualType fieldType,391SmallVectorImpl<BlockLayoutChunk> &Layout,392CGBlockInfo &Info, CodeGenModule &CGM) {393if (!capture) {394// 'this' capture.395Layout.push_back(BlockLayoutChunk(396align, size, capture, type, fieldType, BlockCaptureEntityKind::None,397BlockFieldFlags(), BlockCaptureEntityKind::None, BlockFieldFlags()));398return;399}400401const LangOptions &LangOpts = CGM.getLangOpts();402BlockCaptureEntityKind CopyKind, DisposeKind;403BlockFieldFlags CopyFlags, DisposeFlags;404405std::tie(CopyKind, CopyFlags) =406computeCopyInfoForBlockCapture(*capture, fieldType, LangOpts);407std::tie(DisposeKind, DisposeFlags) =408computeDestroyInfoForBlockCapture(*capture, fieldType, LangOpts);409Layout.push_back(BlockLayoutChunk(align, size, capture, type, fieldType,410CopyKind, CopyFlags, DisposeKind,411DisposeFlags));412413if (Info.NoEscape)414return;415416if (!Layout.back().isTrivial())417Info.NeedsCopyDispose = true;418}419420/// Determines if the given type is safe for constant capture in C++.421static bool isSafeForCXXConstantCapture(QualType type) {422const RecordType *recordType =423type->getBaseElementTypeUnsafe()->getAs<RecordType>();424425// Only records can be unsafe.426if (!recordType) return true;427428const auto *record = cast<CXXRecordDecl>(recordType->getDecl());429430// Maintain semantics for classes with non-trivial dtors or copy ctors.431if (!record->hasTrivialDestructor()) return false;432if (record->hasNonTrivialCopyConstructor()) return false;433434// Otherwise, we just have to make sure there aren't any mutable435// fields that might have changed since initialization.436return !record->hasMutableFields();437}438439/// It is illegal to modify a const object after initialization.440/// Therefore, if a const object has a constant initializer, we don't441/// actually need to keep storage for it in the block; we'll just442/// rematerialize it at the start of the block function. This is443/// acceptable because we make no promises about address stability of444/// captured variables.445static llvm::Constant *tryCaptureAsConstant(CodeGenModule &CGM,446CodeGenFunction *CGF,447const VarDecl *var) {448// Return if this is a function parameter. We shouldn't try to449// rematerialize default arguments of function parameters.450if (isa<ParmVarDecl>(var))451return nullptr;452453QualType type = var->getType();454455// We can only do this if the variable is const.456if (!type.isConstQualified()) return nullptr;457458// Furthermore, in C++ we have to worry about mutable fields:459// C++ [dcl.type.cv]p4:460// Except that any class member declared mutable can be461// modified, any attempt to modify a const object during its462// lifetime results in undefined behavior.463if (CGM.getLangOpts().CPlusPlus && !isSafeForCXXConstantCapture(type))464return nullptr;465466// If the variable doesn't have any initializer (shouldn't this be467// invalid?), it's not clear what we should do. Maybe capture as468// zero?469const Expr *init = var->getInit();470if (!init) return nullptr;471472return ConstantEmitter(CGM, CGF).tryEmitAbstractForInitializer(*var);473}474475/// Get the low bit of a nonzero character count. This is the476/// alignment of the nth byte if the 0th byte is universally aligned.477static CharUnits getLowBit(CharUnits v) {478return CharUnits::fromQuantity(v.getQuantity() & (~v.getQuantity() + 1));479}480481static void initializeForBlockHeader(CodeGenModule &CGM, CGBlockInfo &info,482SmallVectorImpl<llvm::Type*> &elementTypes) {483484assert(elementTypes.empty());485if (CGM.getLangOpts().OpenCL) {486// The header is basically 'struct { int; int; generic void *;487// custom_fields; }'. Assert that struct is packed.488auto GenPtrAlign = CharUnits::fromQuantity(489CGM.getTarget().getPointerAlign(LangAS::opencl_generic) / 8);490auto GenPtrSize = CharUnits::fromQuantity(491CGM.getTarget().getPointerWidth(LangAS::opencl_generic) / 8);492assert(CGM.getIntSize() <= GenPtrSize);493assert(CGM.getIntAlign() <= GenPtrAlign);494assert((2 * CGM.getIntSize()).isMultipleOf(GenPtrAlign));495elementTypes.push_back(CGM.IntTy); /* total size */496elementTypes.push_back(CGM.IntTy); /* align */497elementTypes.push_back(498CGM.getOpenCLRuntime()499.getGenericVoidPointerType()); /* invoke function */500unsigned Offset =5012 * CGM.getIntSize().getQuantity() + GenPtrSize.getQuantity();502unsigned BlockAlign = GenPtrAlign.getQuantity();503if (auto *Helper =504CGM.getTargetCodeGenInfo().getTargetOpenCLBlockHelper()) {505for (auto *I : Helper->getCustomFieldTypes()) /* custom fields */ {506// TargetOpenCLBlockHelp needs to make sure the struct is packed.507// If necessary, add padding fields to the custom fields.508unsigned Align = CGM.getDataLayout().getABITypeAlign(I).value();509if (BlockAlign < Align)510BlockAlign = Align;511assert(Offset % Align == 0);512Offset += CGM.getDataLayout().getTypeAllocSize(I);513elementTypes.push_back(I);514}515}516info.BlockAlign = CharUnits::fromQuantity(BlockAlign);517info.BlockSize = CharUnits::fromQuantity(Offset);518} else {519// The header is basically 'struct { void *; int; int; void *; void *; }'.520// Assert that the struct is packed.521assert(CGM.getIntSize() <= CGM.getPointerSize());522assert(CGM.getIntAlign() <= CGM.getPointerAlign());523assert((2 * CGM.getIntSize()).isMultipleOf(CGM.getPointerAlign()));524info.BlockAlign = CGM.getPointerAlign();525info.BlockSize = 3 * CGM.getPointerSize() + 2 * CGM.getIntSize();526elementTypes.push_back(CGM.VoidPtrTy);527elementTypes.push_back(CGM.IntTy);528elementTypes.push_back(CGM.IntTy);529elementTypes.push_back(CGM.VoidPtrTy);530elementTypes.push_back(CGM.getBlockDescriptorType());531}532}533534static QualType getCaptureFieldType(const CodeGenFunction &CGF,535const BlockDecl::Capture &CI) {536const VarDecl *VD = CI.getVariable();537538// If the variable is captured by an enclosing block or lambda expression,539// use the type of the capture field.540if (CGF.BlockInfo && CI.isNested())541return CGF.BlockInfo->getCapture(VD).fieldType();542if (auto *FD = CGF.LambdaCaptureFields.lookup(VD))543return FD->getType();544// If the captured variable is a non-escaping __block variable, the field545// type is the reference type. If the variable is a __block variable that546// already has a reference type, the field type is the variable's type.547return VD->isNonEscapingByref() ?548CGF.getContext().getLValueReferenceType(VD->getType()) : VD->getType();549}550551/// Compute the layout of the given block. Attempts to lay the block552/// out with minimal space requirements.553static void computeBlockInfo(CodeGenModule &CGM, CodeGenFunction *CGF,554CGBlockInfo &info) {555ASTContext &C = CGM.getContext();556const BlockDecl *block = info.getBlockDecl();557558SmallVector<llvm::Type*, 8> elementTypes;559initializeForBlockHeader(CGM, info, elementTypes);560bool hasNonConstantCustomFields = false;561if (auto *OpenCLHelper =562CGM.getTargetCodeGenInfo().getTargetOpenCLBlockHelper())563hasNonConstantCustomFields =564!OpenCLHelper->areAllCustomFieldValuesConstant(info);565if (!block->hasCaptures() && !hasNonConstantCustomFields) {566info.StructureType =567llvm::StructType::get(CGM.getLLVMContext(), elementTypes, true);568info.CanBeGlobal = true;569return;570}571else if (C.getLangOpts().ObjC &&572CGM.getLangOpts().getGC() == LangOptions::NonGC)573info.HasCapturedVariableLayout = true;574575if (block->doesNotEscape())576info.NoEscape = true;577578// Collect the layout chunks.579SmallVector<BlockLayoutChunk, 16> layout;580layout.reserve(block->capturesCXXThis() +581(block->capture_end() - block->capture_begin()));582583CharUnits maxFieldAlign;584585// First, 'this'.586if (block->capturesCXXThis()) {587assert(CGF && isa_and_nonnull<CXXMethodDecl>(CGF->CurFuncDecl) &&588"Can't capture 'this' outside a method");589QualType thisType = cast<CXXMethodDecl>(CGF->CurFuncDecl)->getThisType();590591// Theoretically, this could be in a different address space, so592// don't assume standard pointer size/align.593llvm::Type *llvmType = CGM.getTypes().ConvertType(thisType);594auto TInfo = CGM.getContext().getTypeInfoInChars(thisType);595maxFieldAlign = std::max(maxFieldAlign, TInfo.Align);596597addBlockLayout(TInfo.Align, TInfo.Width, nullptr, llvmType, thisType,598layout, info, CGM);599}600601// Next, all the block captures.602for (const auto &CI : block->captures()) {603const VarDecl *variable = CI.getVariable();604605if (CI.isEscapingByref()) {606// Just use void* instead of a pointer to the byref type.607CharUnits align = CGM.getPointerAlign();608maxFieldAlign = std::max(maxFieldAlign, align);609610// Since a __block variable cannot be captured by lambdas, its type and611// the capture field type should always match.612assert(CGF && getCaptureFieldType(*CGF, CI) == variable->getType() &&613"capture type differs from the variable type");614addBlockLayout(align, CGM.getPointerSize(), &CI, CGM.VoidPtrTy,615variable->getType(), layout, info, CGM);616continue;617}618619// Otherwise, build a layout chunk with the size and alignment of620// the declaration.621if (llvm::Constant *constant = tryCaptureAsConstant(CGM, CGF, variable)) {622info.SortedCaptures.push_back(623CGBlockInfo::Capture::makeConstant(constant, &CI));624continue;625}626627QualType VT = getCaptureFieldType(*CGF, CI);628629if (CGM.getLangOpts().CPlusPlus)630if (const CXXRecordDecl *record = VT->getAsCXXRecordDecl())631if (CI.hasCopyExpr() || !record->hasTrivialDestructor()) {632info.HasCXXObject = true;633if (!record->isExternallyVisible())634info.CapturesNonExternalType = true;635}636637CharUnits size = C.getTypeSizeInChars(VT);638CharUnits align = C.getDeclAlign(variable);639640maxFieldAlign = std::max(maxFieldAlign, align);641642llvm::Type *llvmType =643CGM.getTypes().ConvertTypeForMem(VT);644645addBlockLayout(align, size, &CI, llvmType, VT, layout, info, CGM);646}647648// If that was everything, we're done here.649if (layout.empty()) {650info.StructureType =651llvm::StructType::get(CGM.getLLVMContext(), elementTypes, true);652info.CanBeGlobal = true;653info.buildCaptureMap();654return;655}656657// Sort the layout by alignment. We have to use a stable sort here658// to get reproducible results. There should probably be an659// llvm::array_pod_stable_sort.660llvm::stable_sort(layout);661662// Needed for blocks layout info.663info.BlockHeaderForcedGapOffset = info.BlockSize;664info.BlockHeaderForcedGapSize = CharUnits::Zero();665666CharUnits &blockSize = info.BlockSize;667info.BlockAlign = std::max(maxFieldAlign, info.BlockAlign);668669// Assuming that the first byte in the header is maximally aligned,670// get the alignment of the first byte following the header.671CharUnits endAlign = getLowBit(blockSize);672673// If the end of the header isn't satisfactorily aligned for the674// maximum thing, look for things that are okay with the header-end675// alignment, and keep appending them until we get something that's676// aligned right. This algorithm is only guaranteed optimal if677// that condition is satisfied at some point; otherwise we can get678// things like:679// header // next byte has alignment 4680// something_with_size_5; // next byte has alignment 1681// something_with_alignment_8;682// which has 7 bytes of padding, as opposed to the naive solution683// which might have less (?).684if (endAlign < maxFieldAlign) {685SmallVectorImpl<BlockLayoutChunk>::iterator686li = layout.begin() + 1, le = layout.end();687688// Look for something that the header end is already689// satisfactorily aligned for.690for (; li != le && endAlign < li->Alignment; ++li)691;692693// If we found something that's naturally aligned for the end of694// the header, keep adding things...695if (li != le) {696SmallVectorImpl<BlockLayoutChunk>::iterator first = li;697for (; li != le; ++li) {698assert(endAlign >= li->Alignment);699700li->setIndex(info, elementTypes.size(), blockSize);701elementTypes.push_back(li->Type);702blockSize += li->Size;703endAlign = getLowBit(blockSize);704705// ...until we get to the alignment of the maximum field.706if (endAlign >= maxFieldAlign) {707++li;708break;709}710}711// Don't re-append everything we just appended.712layout.erase(first, li);713}714}715716assert(endAlign == getLowBit(blockSize));717718// At this point, we just have to add padding if the end align still719// isn't aligned right.720if (endAlign < maxFieldAlign) {721CharUnits newBlockSize = blockSize.alignTo(maxFieldAlign);722CharUnits padding = newBlockSize - blockSize;723724// If we haven't yet added any fields, remember that there was an725// initial gap; this need to go into the block layout bit map.726if (blockSize == info.BlockHeaderForcedGapOffset) {727info.BlockHeaderForcedGapSize = padding;728}729730elementTypes.push_back(llvm::ArrayType::get(CGM.Int8Ty,731padding.getQuantity()));732blockSize = newBlockSize;733endAlign = getLowBit(blockSize); // might be > maxFieldAlign734}735736assert(endAlign >= maxFieldAlign);737assert(endAlign == getLowBit(blockSize));738// Slam everything else on now. This works because they have739// strictly decreasing alignment and we expect that size is always a740// multiple of alignment.741for (SmallVectorImpl<BlockLayoutChunk>::iterator742li = layout.begin(), le = layout.end(); li != le; ++li) {743if (endAlign < li->Alignment) {744// size may not be multiple of alignment. This can only happen with745// an over-aligned variable. We will be adding a padding field to746// make the size be multiple of alignment.747CharUnits padding = li->Alignment - endAlign;748elementTypes.push_back(llvm::ArrayType::get(CGM.Int8Ty,749padding.getQuantity()));750blockSize += padding;751endAlign = getLowBit(blockSize);752}753assert(endAlign >= li->Alignment);754li->setIndex(info, elementTypes.size(), blockSize);755elementTypes.push_back(li->Type);756blockSize += li->Size;757endAlign = getLowBit(blockSize);758}759760info.buildCaptureMap();761info.StructureType =762llvm::StructType::get(CGM.getLLVMContext(), elementTypes, true);763}764765/// Emit a block literal expression in the current function.766llvm::Value *CodeGenFunction::EmitBlockLiteral(const BlockExpr *blockExpr) {767// If the block has no captures, we won't have a pre-computed768// layout for it.769if (!blockExpr->getBlockDecl()->hasCaptures())770// The block literal is emitted as a global variable, and the block invoke771// function has to be extracted from its initializer.772if (llvm::Constant *Block = CGM.getAddrOfGlobalBlockIfEmitted(blockExpr))773return Block;774775CGBlockInfo blockInfo(blockExpr->getBlockDecl(), CurFn->getName());776computeBlockInfo(CGM, this, blockInfo);777blockInfo.BlockExpression = blockExpr;778if (!blockInfo.CanBeGlobal)779blockInfo.LocalAddress = CreateTempAlloca(blockInfo.StructureType,780blockInfo.BlockAlign, "block");781return EmitBlockLiteral(blockInfo);782}783784llvm::Value *CodeGenFunction::EmitBlockLiteral(const CGBlockInfo &blockInfo) {785bool IsOpenCL = CGM.getContext().getLangOpts().OpenCL;786auto GenVoidPtrTy =787IsOpenCL ? CGM.getOpenCLRuntime().getGenericVoidPointerType() : VoidPtrTy;788LangAS GenVoidPtrAddr = IsOpenCL ? LangAS::opencl_generic : LangAS::Default;789auto GenVoidPtrSize = CharUnits::fromQuantity(790CGM.getTarget().getPointerWidth(GenVoidPtrAddr) / 8);791// Using the computed layout, generate the actual block function.792bool isLambdaConv = blockInfo.getBlockDecl()->isConversionFromLambda();793CodeGenFunction BlockCGF{CGM, true};794BlockCGF.SanOpts = SanOpts;795auto *InvokeFn = BlockCGF.GenerateBlockFunction(796CurGD, blockInfo, LocalDeclMap, isLambdaConv, blockInfo.CanBeGlobal);797auto *blockFn = llvm::ConstantExpr::getPointerCast(InvokeFn, GenVoidPtrTy);798799// If there is nothing to capture, we can emit this as a global block.800if (blockInfo.CanBeGlobal)801return CGM.getAddrOfGlobalBlockIfEmitted(blockInfo.BlockExpression);802803// Otherwise, we have to emit this as a local block.804805RawAddress blockAddr = blockInfo.LocalAddress;806assert(blockAddr.isValid() && "block has no address!");807808llvm::Constant *isa;809llvm::Constant *descriptor;810BlockFlags flags;811if (!IsOpenCL) {812// If the block is non-escaping, set field 'isa 'to NSConcreteGlobalBlock813// and set the BLOCK_IS_GLOBAL bit of field 'flags'. Copying a non-escaping814// block just returns the original block and releasing it is a no-op.815llvm::Constant *blockISA = blockInfo.NoEscape816? CGM.getNSConcreteGlobalBlock()817: CGM.getNSConcreteStackBlock();818isa = blockISA;819820// Build the block descriptor.821descriptor = buildBlockDescriptor(CGM, blockInfo);822823// Compute the initial on-stack block flags.824if (!CGM.getCodeGenOpts().DisableBlockSignatureString)825flags = BLOCK_HAS_SIGNATURE;826if (blockInfo.HasCapturedVariableLayout)827flags |= BLOCK_HAS_EXTENDED_LAYOUT;828if (blockInfo.NeedsCopyDispose)829flags |= BLOCK_HAS_COPY_DISPOSE;830if (blockInfo.HasCXXObject)831flags |= BLOCK_HAS_CXX_OBJ;832if (blockInfo.UsesStret)833flags |= BLOCK_USE_STRET;834if (blockInfo.NoEscape)835flags |= BLOCK_IS_NOESCAPE | BLOCK_IS_GLOBAL;836}837838auto projectField = [&](unsigned index, const Twine &name) -> Address {839return Builder.CreateStructGEP(blockAddr, index, name);840};841auto storeField = [&](llvm::Value *value, unsigned index, const Twine &name) {842Builder.CreateStore(value, projectField(index, name));843};844845// Initialize the block header.846{847// We assume all the header fields are densely packed.848unsigned index = 0;849CharUnits offset;850auto addHeaderField = [&](llvm::Value *value, CharUnits size,851const Twine &name) {852storeField(value, index, name);853offset += size;854index++;855};856857if (!IsOpenCL) {858addHeaderField(isa, getPointerSize(), "block.isa");859addHeaderField(llvm::ConstantInt::get(IntTy, flags.getBitMask()),860getIntSize(), "block.flags");861addHeaderField(llvm::ConstantInt::get(IntTy, 0), getIntSize(),862"block.reserved");863} else {864addHeaderField(865llvm::ConstantInt::get(IntTy, blockInfo.BlockSize.getQuantity()),866getIntSize(), "block.size");867addHeaderField(868llvm::ConstantInt::get(IntTy, blockInfo.BlockAlign.getQuantity()),869getIntSize(), "block.align");870}871addHeaderField(blockFn, GenVoidPtrSize, "block.invoke");872if (!IsOpenCL)873addHeaderField(descriptor, getPointerSize(), "block.descriptor");874else if (auto *Helper =875CGM.getTargetCodeGenInfo().getTargetOpenCLBlockHelper()) {876for (auto I : Helper->getCustomFieldValues(*this, blockInfo)) {877addHeaderField(878I.first,879CharUnits::fromQuantity(880CGM.getDataLayout().getTypeAllocSize(I.first->getType())),881I.second);882}883}884}885886// Finally, capture all the values into the block.887const BlockDecl *blockDecl = blockInfo.getBlockDecl();888889// First, 'this'.890if (blockDecl->capturesCXXThis()) {891Address addr =892projectField(blockInfo.CXXThisIndex, "block.captured-this.addr");893Builder.CreateStore(LoadCXXThis(), addr);894}895896// Next, captured variables.897for (const auto &CI : blockDecl->captures()) {898const VarDecl *variable = CI.getVariable();899const CGBlockInfo::Capture &capture = blockInfo.getCapture(variable);900901// Ignore constant captures.902if (capture.isConstant()) continue;903904QualType type = capture.fieldType();905906// This will be a [[type]]*, except that a byref entry will just be907// an i8**.908Address blockField = projectField(capture.getIndex(), "block.captured");909910// Compute the address of the thing we're going to move into the911// block literal.912Address src = Address::invalid();913914if (blockDecl->isConversionFromLambda()) {915// The lambda capture in a lambda's conversion-to-block-pointer is916// special; we'll simply emit it directly.917src = Address::invalid();918} else if (CI.isEscapingByref()) {919if (BlockInfo && CI.isNested()) {920// We need to use the capture from the enclosing block.921const CGBlockInfo::Capture &enclosingCapture =922BlockInfo->getCapture(variable);923924// This is a [[type]]*, except that a byref entry will just be an i8**.925src = Builder.CreateStructGEP(LoadBlockStruct(),926enclosingCapture.getIndex(),927"block.capture.addr");928} else {929auto I = LocalDeclMap.find(variable);930assert(I != LocalDeclMap.end());931src = I->second;932}933} else {934DeclRefExpr declRef(getContext(), const_cast<VarDecl *>(variable),935/*RefersToEnclosingVariableOrCapture*/ CI.isNested(),936type.getNonReferenceType(), VK_LValue,937SourceLocation());938src = EmitDeclRefLValue(&declRef).getAddress();939};940941// For byrefs, we just write the pointer to the byref struct into942// the block field. There's no need to chase the forwarding943// pointer at this point, since we're building something that will944// live a shorter life than the stack byref anyway.945if (CI.isEscapingByref()) {946// Get a void* that points to the byref struct.947llvm::Value *byrefPointer;948if (CI.isNested())949byrefPointer = Builder.CreateLoad(src, "byref.capture");950else951byrefPointer = src.emitRawPointer(*this);952953// Write that void* into the capture field.954Builder.CreateStore(byrefPointer, blockField);955956// If we have a copy constructor, evaluate that into the block field.957} else if (const Expr *copyExpr = CI.getCopyExpr()) {958if (blockDecl->isConversionFromLambda()) {959// If we have a lambda conversion, emit the expression960// directly into the block instead.961AggValueSlot Slot =962AggValueSlot::forAddr(blockField, Qualifiers(),963AggValueSlot::IsDestructed,964AggValueSlot::DoesNotNeedGCBarriers,965AggValueSlot::IsNotAliased,966AggValueSlot::DoesNotOverlap);967EmitAggExpr(copyExpr, Slot);968} else {969EmitSynthesizedCXXCopyCtor(blockField, src, copyExpr);970}971972// If it's a reference variable, copy the reference into the block field.973} else if (type->getAs<ReferenceType>()) {974Builder.CreateStore(src.emitRawPointer(*this), blockField);975976// If type is const-qualified, copy the value into the block field.977} else if (type.isConstQualified() &&978type.getObjCLifetime() == Qualifiers::OCL_Strong &&979CGM.getCodeGenOpts().OptimizationLevel != 0) {980llvm::Value *value = Builder.CreateLoad(src, "captured");981Builder.CreateStore(value, blockField);982983// If this is an ARC __strong block-pointer variable, don't do a984// block copy.985//986// TODO: this can be generalized into the normal initialization logic:987// we should never need to do a block-copy when initializing a local988// variable, because the local variable's lifetime should be strictly989// contained within the stack block's.990} else if (type.getObjCLifetime() == Qualifiers::OCL_Strong &&991type->isBlockPointerType()) {992// Load the block and do a simple retain.993llvm::Value *value = Builder.CreateLoad(src, "block.captured_block");994value = EmitARCRetainNonBlock(value);995996// Do a primitive store to the block field.997Builder.CreateStore(value, blockField);998999// Otherwise, fake up a POD copy into the block field.1000} else {1001// Fake up a new variable so that EmitScalarInit doesn't think1002// we're referring to the variable in its own initializer.1003ImplicitParamDecl BlockFieldPseudoVar(getContext(), type,1004ImplicitParamKind::Other);10051006// We use one of these or the other depending on whether the1007// reference is nested.1008DeclRefExpr declRef(getContext(), const_cast<VarDecl *>(variable),1009/*RefersToEnclosingVariableOrCapture*/ CI.isNested(),1010type, VK_LValue, SourceLocation());10111012ImplicitCastExpr l2r(ImplicitCastExpr::OnStack, type, CK_LValueToRValue,1013&declRef, VK_PRValue, FPOptionsOverride());1014// FIXME: Pass a specific location for the expr init so that the store is1015// attributed to a reasonable location - otherwise it may be attributed to1016// locations of subexpressions in the initialization.1017EmitExprAsInit(&l2r, &BlockFieldPseudoVar,1018MakeAddrLValue(blockField, type, AlignmentSource::Decl),1019/*captured by init*/ false);1020}10211022// Push a cleanup for the capture if necessary.1023if (!blockInfo.NoEscape && !blockInfo.NeedsCopyDispose)1024continue;10251026// Ignore __block captures; there's nothing special in the on-stack block1027// that we need to do for them.1028if (CI.isByRef())1029continue;10301031// Ignore objects that aren't destructed.1032QualType::DestructionKind dtorKind = type.isDestructedType();1033if (dtorKind == QualType::DK_none)1034continue;10351036CodeGenFunction::Destroyer *destroyer;10371038// Block captures count as local values and have imprecise semantics.1039// They also can't be arrays, so need to worry about that.1040//1041// For const-qualified captures, emit clang.arc.use to ensure the captured1042// object doesn't get released while we are still depending on its validity1043// within the block.1044if (type.isConstQualified() &&1045type.getObjCLifetime() == Qualifiers::OCL_Strong &&1046CGM.getCodeGenOpts().OptimizationLevel != 0) {1047assert(CGM.getLangOpts().ObjCAutoRefCount &&1048"expected ObjC ARC to be enabled");1049destroyer = emitARCIntrinsicUse;1050} else if (dtorKind == QualType::DK_objc_strong_lifetime) {1051destroyer = destroyARCStrongImprecise;1052} else {1053destroyer = getDestroyer(dtorKind);1054}10551056CleanupKind cleanupKind = NormalCleanup;1057bool useArrayEHCleanup = needsEHCleanup(dtorKind);1058if (useArrayEHCleanup)1059cleanupKind = NormalAndEHCleanup;10601061// Extend the lifetime of the capture to the end of the scope enclosing the1062// block expression except when the block decl is in the list of RetExpr's1063// cleanup objects, in which case its lifetime ends after the full1064// expression.1065auto IsBlockDeclInRetExpr = [&]() {1066auto *EWC = llvm::dyn_cast_or_null<ExprWithCleanups>(RetExpr);1067if (EWC)1068for (auto &C : EWC->getObjects())1069if (auto *BD = C.dyn_cast<BlockDecl *>())1070if (BD == blockDecl)1071return true;1072return false;1073};10741075if (IsBlockDeclInRetExpr())1076pushDestroy(cleanupKind, blockField, type, destroyer, useArrayEHCleanup);1077else1078pushLifetimeExtendedDestroy(cleanupKind, blockField, type, destroyer,1079useArrayEHCleanup);1080}10811082// Cast to the converted block-pointer type, which happens (somewhat1083// unfortunately) to be a pointer to function type.1084llvm::Value *result = Builder.CreatePointerCast(1085blockAddr.getPointer(), ConvertType(blockInfo.getBlockExpr()->getType()));10861087if (IsOpenCL) {1088CGM.getOpenCLRuntime().recordBlockInfo(blockInfo.BlockExpression, InvokeFn,1089result, blockInfo.StructureType);1090}10911092return result;1093}109410951096llvm::Type *CodeGenModule::getBlockDescriptorType() {1097if (BlockDescriptorType)1098return BlockDescriptorType;10991100llvm::Type *UnsignedLongTy =1101getTypes().ConvertType(getContext().UnsignedLongTy);11021103// struct __block_descriptor {1104// unsigned long reserved;1105// unsigned long block_size;1106//1107// // later, the following will be added1108//1109// struct {1110// void (*copyHelper)();1111// void (*copyHelper)();1112// } helpers; // !!! optional1113//1114// const char *signature; // the block signature1115// const char *layout; // reserved1116// };1117BlockDescriptorType = llvm::StructType::create(1118"struct.__block_descriptor", UnsignedLongTy, UnsignedLongTy);11191120// Now form a pointer to that.1121unsigned AddrSpace = 0;1122if (getLangOpts().OpenCL)1123AddrSpace = getContext().getTargetAddressSpace(LangAS::opencl_constant);1124BlockDescriptorType = llvm::PointerType::get(BlockDescriptorType, AddrSpace);1125return BlockDescriptorType;1126}11271128llvm::Type *CodeGenModule::getGenericBlockLiteralType() {1129if (GenericBlockLiteralType)1130return GenericBlockLiteralType;11311132llvm::Type *BlockDescPtrTy = getBlockDescriptorType();11331134if (getLangOpts().OpenCL) {1135// struct __opencl_block_literal_generic {1136// int __size;1137// int __align;1138// __generic void *__invoke;1139// /* custom fields */1140// };1141SmallVector<llvm::Type *, 8> StructFields(1142{IntTy, IntTy, getOpenCLRuntime().getGenericVoidPointerType()});1143if (auto *Helper = getTargetCodeGenInfo().getTargetOpenCLBlockHelper()) {1144llvm::append_range(StructFields, Helper->getCustomFieldTypes());1145}1146GenericBlockLiteralType = llvm::StructType::create(1147StructFields, "struct.__opencl_block_literal_generic");1148} else {1149// struct __block_literal_generic {1150// void *__isa;1151// int __flags;1152// int __reserved;1153// void (*__invoke)(void *);1154// struct __block_descriptor *__descriptor;1155// };1156GenericBlockLiteralType =1157llvm::StructType::create("struct.__block_literal_generic", VoidPtrTy,1158IntTy, IntTy, VoidPtrTy, BlockDescPtrTy);1159}11601161return GenericBlockLiteralType;1162}11631164RValue CodeGenFunction::EmitBlockCallExpr(const CallExpr *E,1165ReturnValueSlot ReturnValue) {1166const auto *BPT = E->getCallee()->getType()->castAs<BlockPointerType>();1167llvm::Value *BlockPtr = EmitScalarExpr(E->getCallee());1168llvm::Type *GenBlockTy = CGM.getGenericBlockLiteralType();1169llvm::Value *Func = nullptr;1170QualType FnType = BPT->getPointeeType();1171ASTContext &Ctx = getContext();1172CallArgList Args;11731174if (getLangOpts().OpenCL) {1175// For OpenCL, BlockPtr is already casted to generic block literal.11761177// First argument of a block call is a generic block literal casted to1178// generic void pointer, i.e. i8 addrspace(4)*1179llvm::Type *GenericVoidPtrTy =1180CGM.getOpenCLRuntime().getGenericVoidPointerType();1181llvm::Value *BlockDescriptor = Builder.CreatePointerCast(1182BlockPtr, GenericVoidPtrTy);1183QualType VoidPtrQualTy = Ctx.getPointerType(1184Ctx.getAddrSpaceQualType(Ctx.VoidTy, LangAS::opencl_generic));1185Args.add(RValue::get(BlockDescriptor), VoidPtrQualTy);1186// And the rest of the arguments.1187EmitCallArgs(Args, FnType->getAs<FunctionProtoType>(), E->arguments());11881189// We *can* call the block directly unless it is a function argument.1190if (!isa<ParmVarDecl>(E->getCalleeDecl()))1191Func = CGM.getOpenCLRuntime().getInvokeFunction(E->getCallee());1192else {1193llvm::Value *FuncPtr = Builder.CreateStructGEP(GenBlockTy, BlockPtr, 2);1194Func = Builder.CreateAlignedLoad(GenericVoidPtrTy, FuncPtr,1195getPointerAlign());1196}1197} else {1198// Bitcast the block literal to a generic block literal.1199BlockPtr =1200Builder.CreatePointerCast(BlockPtr, UnqualPtrTy, "block.literal");1201// Get pointer to the block invoke function1202llvm::Value *FuncPtr = Builder.CreateStructGEP(GenBlockTy, BlockPtr, 3);12031204// First argument is a block literal casted to a void pointer1205BlockPtr = Builder.CreatePointerCast(BlockPtr, VoidPtrTy);1206Args.add(RValue::get(BlockPtr), Ctx.VoidPtrTy);1207// And the rest of the arguments.1208EmitCallArgs(Args, FnType->getAs<FunctionProtoType>(), E->arguments());12091210// Load the function.1211Func = Builder.CreateAlignedLoad(VoidPtrTy, FuncPtr, getPointerAlign());1212}12131214const FunctionType *FuncTy = FnType->castAs<FunctionType>();1215const CGFunctionInfo &FnInfo =1216CGM.getTypes().arrangeBlockFunctionCall(Args, FuncTy);12171218// Prepare the callee.1219CGCallee Callee(CGCalleeInfo(), Func);12201221// And call the block.1222return EmitCall(FnInfo, Callee, ReturnValue, Args);1223}12241225Address CodeGenFunction::GetAddrOfBlockDecl(const VarDecl *variable) {1226assert(BlockInfo && "evaluating block ref without block information?");1227const CGBlockInfo::Capture &capture = BlockInfo->getCapture(variable);12281229// Handle constant captures.1230if (capture.isConstant()) return LocalDeclMap.find(variable)->second;12311232Address addr = Builder.CreateStructGEP(LoadBlockStruct(), capture.getIndex(),1233"block.capture.addr");12341235if (variable->isEscapingByref()) {1236// addr should be a void** right now. Load, then cast the result1237// to byref*.12381239auto &byrefInfo = getBlockByrefInfo(variable);1240addr = Address(Builder.CreateLoad(addr), byrefInfo.Type,1241byrefInfo.ByrefAlignment);12421243addr = emitBlockByrefAddress(addr, byrefInfo, /*follow*/ true,1244variable->getName());1245}12461247assert((!variable->isNonEscapingByref() ||1248capture.fieldType()->isReferenceType()) &&1249"the capture field of a non-escaping variable should have a "1250"reference type");1251if (capture.fieldType()->isReferenceType())1252addr = EmitLoadOfReference(MakeAddrLValue(addr, capture.fieldType()));12531254return addr;1255}12561257void CodeGenModule::setAddrOfGlobalBlock(const BlockExpr *BE,1258llvm::Constant *Addr) {1259bool Ok = EmittedGlobalBlocks.insert(std::make_pair(BE, Addr)).second;1260(void)Ok;1261assert(Ok && "Trying to replace an already-existing global block!");1262}12631264llvm::Constant *1265CodeGenModule::GetAddrOfGlobalBlock(const BlockExpr *BE,1266StringRef Name) {1267if (llvm::Constant *Block = getAddrOfGlobalBlockIfEmitted(BE))1268return Block;12691270CGBlockInfo blockInfo(BE->getBlockDecl(), Name);1271blockInfo.BlockExpression = BE;12721273// Compute information about the layout, etc., of this block.1274computeBlockInfo(*this, nullptr, blockInfo);12751276// Using that metadata, generate the actual block function.1277{1278CodeGenFunction::DeclMapTy LocalDeclMap;1279CodeGenFunction(*this).GenerateBlockFunction(1280GlobalDecl(), blockInfo, LocalDeclMap,1281/*IsLambdaConversionToBlock*/ false, /*BuildGlobalBlock*/ true);1282}12831284return getAddrOfGlobalBlockIfEmitted(BE);1285}12861287static llvm::Constant *buildGlobalBlock(CodeGenModule &CGM,1288const CGBlockInfo &blockInfo,1289llvm::Constant *blockFn) {1290assert(blockInfo.CanBeGlobal);1291// Callers should detect this case on their own: calling this function1292// generally requires computing layout information, which is a waste of time1293// if we've already emitted this block.1294assert(!CGM.getAddrOfGlobalBlockIfEmitted(blockInfo.BlockExpression) &&1295"Refusing to re-emit a global block.");12961297// Generate the constants for the block literal initializer.1298ConstantInitBuilder builder(CGM);1299auto fields = builder.beginStruct();13001301bool IsOpenCL = CGM.getLangOpts().OpenCL;1302bool IsWindows = CGM.getTarget().getTriple().isOSWindows();1303if (!IsOpenCL) {1304// isa1305if (IsWindows)1306fields.addNullPointer(CGM.Int8PtrPtrTy);1307else1308fields.add(CGM.getNSConcreteGlobalBlock());13091310// __flags1311BlockFlags flags = BLOCK_IS_GLOBAL;1312if (!CGM.getCodeGenOpts().DisableBlockSignatureString)1313flags |= BLOCK_HAS_SIGNATURE;1314if (blockInfo.UsesStret)1315flags |= BLOCK_USE_STRET;13161317fields.addInt(CGM.IntTy, flags.getBitMask());13181319// Reserved1320fields.addInt(CGM.IntTy, 0);1321} else {1322fields.addInt(CGM.IntTy, blockInfo.BlockSize.getQuantity());1323fields.addInt(CGM.IntTy, blockInfo.BlockAlign.getQuantity());1324}13251326// Function1327fields.add(blockFn);13281329if (!IsOpenCL) {1330// Descriptor1331fields.add(buildBlockDescriptor(CGM, blockInfo));1332} else if (auto *Helper =1333CGM.getTargetCodeGenInfo().getTargetOpenCLBlockHelper()) {1334for (auto *I : Helper->getCustomFieldValues(CGM, blockInfo)) {1335fields.add(I);1336}1337}13381339unsigned AddrSpace = 0;1340if (CGM.getContext().getLangOpts().OpenCL)1341AddrSpace = CGM.getContext().getTargetAddressSpace(LangAS::opencl_global);13421343llvm::GlobalVariable *literal = fields.finishAndCreateGlobal(1344"__block_literal_global", blockInfo.BlockAlign,1345/*constant*/ !IsWindows, llvm::GlobalVariable::InternalLinkage, AddrSpace);13461347literal->addAttribute("objc_arc_inert");13481349// Windows does not allow globals to be initialised to point to globals in1350// different DLLs. Any such variables must run code to initialise them.1351if (IsWindows) {1352auto *Init = llvm::Function::Create(llvm::FunctionType::get(CGM.VoidTy,1353{}), llvm::GlobalValue::InternalLinkage, ".block_isa_init",1354&CGM.getModule());1355llvm::IRBuilder<> b(llvm::BasicBlock::Create(CGM.getLLVMContext(), "entry",1356Init));1357b.CreateAlignedStore(CGM.getNSConcreteGlobalBlock(),1358b.CreateStructGEP(literal->getValueType(), literal, 0),1359CGM.getPointerAlign().getAsAlign());1360b.CreateRetVoid();1361// We can't use the normal LLVM global initialisation array, because we1362// need to specify that this runs early in library initialisation.1363auto *InitVar = new llvm::GlobalVariable(CGM.getModule(), Init->getType(),1364/*isConstant*/true, llvm::GlobalValue::InternalLinkage,1365Init, ".block_isa_init_ptr");1366InitVar->setSection(".CRT$XCLa");1367CGM.addUsedGlobal(InitVar);1368}13691370// Return a constant of the appropriately-casted type.1371llvm::Type *RequiredType =1372CGM.getTypes().ConvertType(blockInfo.getBlockExpr()->getType());1373llvm::Constant *Result =1374llvm::ConstantExpr::getPointerCast(literal, RequiredType);1375CGM.setAddrOfGlobalBlock(blockInfo.BlockExpression, Result);1376if (CGM.getContext().getLangOpts().OpenCL)1377CGM.getOpenCLRuntime().recordBlockInfo(1378blockInfo.BlockExpression,1379cast<llvm::Function>(blockFn->stripPointerCasts()), Result,1380literal->getValueType());1381return Result;1382}13831384void CodeGenFunction::setBlockContextParameter(const ImplicitParamDecl *D,1385unsigned argNum,1386llvm::Value *arg) {1387assert(BlockInfo && "not emitting prologue of block invocation function?!");13881389// Allocate a stack slot like for any local variable to guarantee optimal1390// debug info at -O0. The mem2reg pass will eliminate it when optimizing.1391RawAddress alloc = CreateMemTemp(D->getType(), D->getName() + ".addr");1392Builder.CreateStore(arg, alloc);1393if (CGDebugInfo *DI = getDebugInfo()) {1394if (CGM.getCodeGenOpts().hasReducedDebugInfo()) {1395DI->setLocation(D->getLocation());1396DI->EmitDeclareOfBlockLiteralArgVariable(1397*BlockInfo, D->getName(), argNum,1398cast<llvm::AllocaInst>(alloc.getPointer()), Builder);1399}1400}14011402SourceLocation StartLoc = BlockInfo->getBlockExpr()->getBody()->getBeginLoc();1403ApplyDebugLocation Scope(*this, StartLoc);14041405// Instead of messing around with LocalDeclMap, just set the value1406// directly as BlockPointer.1407BlockPointer = Builder.CreatePointerCast(1408arg,1409llvm::PointerType::get(1410getLLVMContext(),1411getContext().getLangOpts().OpenCL1412? getContext().getTargetAddressSpace(LangAS::opencl_generic)1413: 0),1414"block");1415}14161417Address CodeGenFunction::LoadBlockStruct() {1418assert(BlockInfo && "not in a block invocation function!");1419assert(BlockPointer && "no block pointer set!");1420return Address(BlockPointer, BlockInfo->StructureType, BlockInfo->BlockAlign);1421}14221423llvm::Function *CodeGenFunction::GenerateBlockFunction(1424GlobalDecl GD, const CGBlockInfo &blockInfo, const DeclMapTy &ldm,1425bool IsLambdaConversionToBlock, bool BuildGlobalBlock) {1426const BlockDecl *blockDecl = blockInfo.getBlockDecl();14271428CurGD = GD;14291430CurEHLocation = blockInfo.getBlockExpr()->getEndLoc();14311432BlockInfo = &blockInfo;14331434// Arrange for local static and local extern declarations to appear1435// to be local to this function as well, in case they're directly1436// referenced in a block.1437for (DeclMapTy::const_iterator i = ldm.begin(), e = ldm.end(); i != e; ++i) {1438const auto *var = dyn_cast<VarDecl>(i->first);1439if (var && !var->hasLocalStorage())1440setAddrOfLocalVar(var, i->second);1441}14421443// Begin building the function declaration.14441445// Build the argument list.1446FunctionArgList args;14471448// The first argument is the block pointer. Just take it as a void*1449// and cast it later.1450QualType selfTy = getContext().VoidPtrTy;14511452// For OpenCL passed block pointer can be private AS local variable or1453// global AS program scope variable (for the case with and without captures).1454// Generic AS is used therefore to be able to accommodate both private and1455// generic AS in one implementation.1456if (getLangOpts().OpenCL)1457selfTy = getContext().getPointerType(getContext().getAddrSpaceQualType(1458getContext().VoidTy, LangAS::opencl_generic));14591460const IdentifierInfo *II = &CGM.getContext().Idents.get(".block_descriptor");14611462ImplicitParamDecl SelfDecl(getContext(), const_cast<BlockDecl *>(blockDecl),1463SourceLocation(), II, selfTy,1464ImplicitParamKind::ObjCSelf);1465args.push_back(&SelfDecl);14661467// Now add the rest of the parameters.1468args.append(blockDecl->param_begin(), blockDecl->param_end());14691470// Create the function declaration.1471const FunctionProtoType *fnType = blockInfo.getBlockExpr()->getFunctionType();1472const CGFunctionInfo &fnInfo =1473CGM.getTypes().arrangeBlockFunctionDeclaration(fnType, args);1474if (CGM.ReturnSlotInterferesWithArgs(fnInfo))1475blockInfo.UsesStret = true;14761477llvm::FunctionType *fnLLVMType = CGM.getTypes().GetFunctionType(fnInfo);14781479StringRef name = CGM.getBlockMangledName(GD, blockDecl);1480llvm::Function *fn = llvm::Function::Create(1481fnLLVMType, llvm::GlobalValue::InternalLinkage, name, &CGM.getModule());1482CGM.SetInternalFunctionAttributes(blockDecl, fn, fnInfo);14831484if (BuildGlobalBlock) {1485auto GenVoidPtrTy = getContext().getLangOpts().OpenCL1486? CGM.getOpenCLRuntime().getGenericVoidPointerType()1487: VoidPtrTy;1488buildGlobalBlock(CGM, blockInfo,1489llvm::ConstantExpr::getPointerCast(fn, GenVoidPtrTy));1490}14911492// Begin generating the function.1493StartFunction(blockDecl, fnType->getReturnType(), fn, fnInfo, args,1494blockDecl->getLocation(),1495blockInfo.getBlockExpr()->getBody()->getBeginLoc());14961497// Okay. Undo some of what StartFunction did.14981499// At -O0 we generate an explicit alloca for the BlockPointer, so the RA1500// won't delete the dbg.declare intrinsics for captured variables.1501llvm::Value *BlockPointerDbgLoc = BlockPointer;1502if (CGM.getCodeGenOpts().OptimizationLevel == 0) {1503// Allocate a stack slot for it, so we can point the debugger to it1504Address Alloca = CreateTempAlloca(BlockPointer->getType(),1505getPointerAlign(),1506"block.addr");1507// Set the DebugLocation to empty, so the store is recognized as a1508// frame setup instruction by llvm::DwarfDebug::beginFunction().1509auto NL = ApplyDebugLocation::CreateEmpty(*this);1510Builder.CreateStore(BlockPointer, Alloca);1511BlockPointerDbgLoc = Alloca.emitRawPointer(*this);1512}15131514// If we have a C++ 'this' reference, go ahead and force it into1515// existence now.1516if (blockDecl->capturesCXXThis()) {1517Address addr = Builder.CreateStructGEP(1518LoadBlockStruct(), blockInfo.CXXThisIndex, "block.captured-this");1519CXXThisValue = Builder.CreateLoad(addr, "this");1520}15211522// Also force all the constant captures.1523for (const auto &CI : blockDecl->captures()) {1524const VarDecl *variable = CI.getVariable();1525const CGBlockInfo::Capture &capture = blockInfo.getCapture(variable);1526if (!capture.isConstant()) continue;15271528CharUnits align = getContext().getDeclAlign(variable);1529Address alloca =1530CreateMemTemp(variable->getType(), align, "block.captured-const");15311532Builder.CreateStore(capture.getConstant(), alloca);15331534setAddrOfLocalVar(variable, alloca);1535}15361537// Save a spot to insert the debug information for all the DeclRefExprs.1538llvm::BasicBlock *entry = Builder.GetInsertBlock();1539llvm::BasicBlock::iterator entry_ptr = Builder.GetInsertPoint();1540--entry_ptr;15411542if (IsLambdaConversionToBlock)1543EmitLambdaBlockInvokeBody();1544else {1545PGO.assignRegionCounters(GlobalDecl(blockDecl), fn);1546incrementProfileCounter(blockDecl->getBody());1547EmitStmt(blockDecl->getBody());1548}15491550// Remember where we were...1551llvm::BasicBlock *resume = Builder.GetInsertBlock();15521553// Go back to the entry.1554if (entry_ptr->getNextNonDebugInstruction())1555entry_ptr = entry_ptr->getNextNonDebugInstruction()->getIterator();1556else1557entry_ptr = entry->end();1558Builder.SetInsertPoint(entry, entry_ptr);15591560// Emit debug information for all the DeclRefExprs.1561// FIXME: also for 'this'1562if (CGDebugInfo *DI = getDebugInfo()) {1563for (const auto &CI : blockDecl->captures()) {1564const VarDecl *variable = CI.getVariable();1565DI->EmitLocation(Builder, variable->getLocation());15661567if (CGM.getCodeGenOpts().hasReducedDebugInfo()) {1568const CGBlockInfo::Capture &capture = blockInfo.getCapture(variable);1569if (capture.isConstant()) {1570auto addr = LocalDeclMap.find(variable)->second;1571(void)DI->EmitDeclareOfAutoVariable(1572variable, addr.emitRawPointer(*this), Builder);1573continue;1574}15751576DI->EmitDeclareOfBlockDeclRefVariable(1577variable, BlockPointerDbgLoc, Builder, blockInfo,1578entry_ptr == entry->end() ? nullptr : &*entry_ptr);1579}1580}1581// Recover location if it was changed in the above loop.1582DI->EmitLocation(Builder,1583cast<CompoundStmt>(blockDecl->getBody())->getRBracLoc());1584}15851586// And resume where we left off.1587if (resume == nullptr)1588Builder.ClearInsertionPoint();1589else1590Builder.SetInsertPoint(resume);15911592FinishFunction(cast<CompoundStmt>(blockDecl->getBody())->getRBracLoc());15931594return fn;1595}15961597static std::pair<BlockCaptureEntityKind, BlockFieldFlags>1598computeCopyInfoForBlockCapture(const BlockDecl::Capture &CI, QualType T,1599const LangOptions &LangOpts) {1600if (CI.getCopyExpr()) {1601assert(!CI.isByRef());1602// don't bother computing flags1603return std::make_pair(BlockCaptureEntityKind::CXXRecord, BlockFieldFlags());1604}1605BlockFieldFlags Flags;1606if (CI.isEscapingByref()) {1607Flags = BLOCK_FIELD_IS_BYREF;1608if (T.isObjCGCWeak())1609Flags |= BLOCK_FIELD_IS_WEAK;1610return std::make_pair(BlockCaptureEntityKind::BlockObject, Flags);1611}16121613Flags = BLOCK_FIELD_IS_OBJECT;1614bool isBlockPointer = T->isBlockPointerType();1615if (isBlockPointer)1616Flags = BLOCK_FIELD_IS_BLOCK;16171618switch (T.isNonTrivialToPrimitiveCopy()) {1619case QualType::PCK_Struct:1620return std::make_pair(BlockCaptureEntityKind::NonTrivialCStruct,1621BlockFieldFlags());1622case QualType::PCK_ARCWeak:1623// We need to register __weak direct captures with the runtime.1624return std::make_pair(BlockCaptureEntityKind::ARCWeak, Flags);1625case QualType::PCK_ARCStrong:1626// We need to retain the copied value for __strong direct captures.1627// If it's a block pointer, we have to copy the block and assign that to1628// the destination pointer, so we might as well use _Block_object_assign.1629// Otherwise we can avoid that.1630return std::make_pair(!isBlockPointer ? BlockCaptureEntityKind::ARCStrong1631: BlockCaptureEntityKind::BlockObject,1632Flags);1633case QualType::PCK_Trivial:1634case QualType::PCK_VolatileTrivial: {1635if (!T->isObjCRetainableType())1636// For all other types, the memcpy is fine.1637return std::make_pair(BlockCaptureEntityKind::None, BlockFieldFlags());16381639// Honor the inert __unsafe_unretained qualifier, which doesn't actually1640// make it into the type system.1641if (T->isObjCInertUnsafeUnretainedType())1642return std::make_pair(BlockCaptureEntityKind::None, BlockFieldFlags());16431644// Special rules for ARC captures:1645Qualifiers QS = T.getQualifiers();16461647// Non-ARC captures of retainable pointers are strong and1648// therefore require a call to _Block_object_assign.1649if (!QS.getObjCLifetime() && !LangOpts.ObjCAutoRefCount)1650return std::make_pair(BlockCaptureEntityKind::BlockObject, Flags);16511652// Otherwise the memcpy is fine.1653return std::make_pair(BlockCaptureEntityKind::None, BlockFieldFlags());1654}1655}1656llvm_unreachable("after exhaustive PrimitiveCopyKind switch");1657}16581659namespace {1660/// Release a __block variable.1661struct CallBlockRelease final : EHScopeStack::Cleanup {1662Address Addr;1663BlockFieldFlags FieldFlags;1664bool LoadBlockVarAddr, CanThrow;16651666CallBlockRelease(Address Addr, BlockFieldFlags Flags, bool LoadValue,1667bool CT)1668: Addr(Addr), FieldFlags(Flags), LoadBlockVarAddr(LoadValue),1669CanThrow(CT) {}16701671void Emit(CodeGenFunction &CGF, Flags flags) override {1672llvm::Value *BlockVarAddr;1673if (LoadBlockVarAddr) {1674BlockVarAddr = CGF.Builder.CreateLoad(Addr);1675} else {1676BlockVarAddr = Addr.emitRawPointer(CGF);1677}16781679CGF.BuildBlockRelease(BlockVarAddr, FieldFlags, CanThrow);1680}1681};1682} // end anonymous namespace16831684/// Check if \p T is a C++ class that has a destructor that can throw.1685bool CodeGenFunction::cxxDestructorCanThrow(QualType T) {1686if (const auto *RD = T->getAsCXXRecordDecl())1687if (const CXXDestructorDecl *DD = RD->getDestructor())1688return DD->getType()->castAs<FunctionProtoType>()->canThrow();1689return false;1690}16911692// Return a string that has the information about a capture.1693static std::string getBlockCaptureStr(const CGBlockInfo::Capture &Cap,1694CaptureStrKind StrKind,1695CharUnits BlockAlignment,1696CodeGenModule &CGM) {1697std::string Str;1698ASTContext &Ctx = CGM.getContext();1699const BlockDecl::Capture &CI = *Cap.Cap;1700QualType CaptureTy = CI.getVariable()->getType();17011702BlockCaptureEntityKind Kind;1703BlockFieldFlags Flags;17041705// CaptureStrKind::Merged should be passed only when the operations and the1706// flags are the same for copy and dispose.1707assert((StrKind != CaptureStrKind::Merged ||1708(Cap.CopyKind == Cap.DisposeKind &&1709Cap.CopyFlags == Cap.DisposeFlags)) &&1710"different operations and flags");17111712if (StrKind == CaptureStrKind::DisposeHelper) {1713Kind = Cap.DisposeKind;1714Flags = Cap.DisposeFlags;1715} else {1716Kind = Cap.CopyKind;1717Flags = Cap.CopyFlags;1718}17191720switch (Kind) {1721case BlockCaptureEntityKind::CXXRecord: {1722Str += "c";1723SmallString<256> TyStr;1724llvm::raw_svector_ostream Out(TyStr);1725CGM.getCXXABI().getMangleContext().mangleCanonicalTypeName(CaptureTy, Out);1726Str += llvm::to_string(TyStr.size()) + TyStr.c_str();1727break;1728}1729case BlockCaptureEntityKind::ARCWeak:1730Str += "w";1731break;1732case BlockCaptureEntityKind::ARCStrong:1733Str += "s";1734break;1735case BlockCaptureEntityKind::BlockObject: {1736const VarDecl *Var = CI.getVariable();1737unsigned F = Flags.getBitMask();1738if (F & BLOCK_FIELD_IS_BYREF) {1739Str += "r";1740if (F & BLOCK_FIELD_IS_WEAK)1741Str += "w";1742else {1743// If CaptureStrKind::Merged is passed, check both the copy expression1744// and the destructor.1745if (StrKind != CaptureStrKind::DisposeHelper) {1746if (Ctx.getBlockVarCopyInit(Var).canThrow())1747Str += "c";1748}1749if (StrKind != CaptureStrKind::CopyHelper) {1750if (CodeGenFunction::cxxDestructorCanThrow(CaptureTy))1751Str += "d";1752}1753}1754} else {1755assert((F & BLOCK_FIELD_IS_OBJECT) && "unexpected flag value");1756if (F == BLOCK_FIELD_IS_BLOCK)1757Str += "b";1758else1759Str += "o";1760}1761break;1762}1763case BlockCaptureEntityKind::NonTrivialCStruct: {1764bool IsVolatile = CaptureTy.isVolatileQualified();1765CharUnits Alignment = BlockAlignment.alignmentAtOffset(Cap.getOffset());17661767Str += "n";1768std::string FuncStr;1769if (StrKind == CaptureStrKind::DisposeHelper)1770FuncStr = CodeGenFunction::getNonTrivialDestructorStr(1771CaptureTy, Alignment, IsVolatile, Ctx);1772else1773// If CaptureStrKind::Merged is passed, use the copy constructor string.1774// It has all the information that the destructor string has.1775FuncStr = CodeGenFunction::getNonTrivialCopyConstructorStr(1776CaptureTy, Alignment, IsVolatile, Ctx);1777// The underscore is necessary here because non-trivial copy constructor1778// and destructor strings can start with a number.1779Str += llvm::to_string(FuncStr.size()) + "_" + FuncStr;1780break;1781}1782case BlockCaptureEntityKind::None:1783break;1784}17851786return Str;1787}17881789static std::string getCopyDestroyHelperFuncName(1790const SmallVectorImpl<CGBlockInfo::Capture> &Captures,1791CharUnits BlockAlignment, CaptureStrKind StrKind, CodeGenModule &CGM) {1792assert((StrKind == CaptureStrKind::CopyHelper ||1793StrKind == CaptureStrKind::DisposeHelper) &&1794"unexpected CaptureStrKind");1795std::string Name = StrKind == CaptureStrKind::CopyHelper1796? "__copy_helper_block_"1797: "__destroy_helper_block_";1798if (CGM.getLangOpts().Exceptions)1799Name += "e";1800if (CGM.getCodeGenOpts().ObjCAutoRefCountExceptions)1801Name += "a";1802Name += llvm::to_string(BlockAlignment.getQuantity()) + "_";18031804for (auto &Cap : Captures) {1805if (Cap.isConstantOrTrivial())1806continue;1807Name += llvm::to_string(Cap.getOffset().getQuantity());1808Name += getBlockCaptureStr(Cap, StrKind, BlockAlignment, CGM);1809}18101811return Name;1812}18131814static void pushCaptureCleanup(BlockCaptureEntityKind CaptureKind,1815Address Field, QualType CaptureType,1816BlockFieldFlags Flags, bool ForCopyHelper,1817VarDecl *Var, CodeGenFunction &CGF) {1818bool EHOnly = ForCopyHelper;18191820switch (CaptureKind) {1821case BlockCaptureEntityKind::CXXRecord:1822case BlockCaptureEntityKind::ARCWeak:1823case BlockCaptureEntityKind::NonTrivialCStruct:1824case BlockCaptureEntityKind::ARCStrong: {1825if (CaptureType.isDestructedType() &&1826(!EHOnly || CGF.needsEHCleanup(CaptureType.isDestructedType()))) {1827CodeGenFunction::Destroyer *Destroyer =1828CaptureKind == BlockCaptureEntityKind::ARCStrong1829? CodeGenFunction::destroyARCStrongImprecise1830: CGF.getDestroyer(CaptureType.isDestructedType());1831CleanupKind Kind =1832EHOnly ? EHCleanup1833: CGF.getCleanupKind(CaptureType.isDestructedType());1834CGF.pushDestroy(Kind, Field, CaptureType, Destroyer, Kind & EHCleanup);1835}1836break;1837}1838case BlockCaptureEntityKind::BlockObject: {1839if (!EHOnly || CGF.getLangOpts().Exceptions) {1840CleanupKind Kind = EHOnly ? EHCleanup : NormalAndEHCleanup;1841// Calls to _Block_object_dispose along the EH path in the copy helper1842// function don't throw as newly-copied __block variables always have a1843// reference count of 2.1844bool CanThrow =1845!ForCopyHelper && CGF.cxxDestructorCanThrow(CaptureType);1846CGF.enterByrefCleanup(Kind, Field, Flags, /*LoadBlockVarAddr*/ true,1847CanThrow);1848}1849break;1850}1851case BlockCaptureEntityKind::None:1852break;1853}1854}18551856static void setBlockHelperAttributesVisibility(bool CapturesNonExternalType,1857llvm::Function *Fn,1858const CGFunctionInfo &FI,1859CodeGenModule &CGM) {1860if (CapturesNonExternalType) {1861CGM.SetInternalFunctionAttributes(GlobalDecl(), Fn, FI);1862} else {1863Fn->setVisibility(llvm::GlobalValue::HiddenVisibility);1864Fn->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);1865CGM.SetLLVMFunctionAttributes(GlobalDecl(), FI, Fn, /*IsThunk=*/false);1866CGM.SetLLVMFunctionAttributesForDefinition(nullptr, Fn);1867}1868}1869/// Generate the copy-helper function for a block closure object:1870/// static void block_copy_helper(block_t *dst, block_t *src);1871/// The runtime will have previously initialized 'dst' by doing a1872/// bit-copy of 'src'.1873///1874/// Note that this copies an entire block closure object to the heap;1875/// it should not be confused with a 'byref copy helper', which moves1876/// the contents of an individual __block variable to the heap.1877llvm::Constant *1878CodeGenFunction::GenerateCopyHelperFunction(const CGBlockInfo &blockInfo) {1879std::string FuncName = getCopyDestroyHelperFuncName(1880blockInfo.SortedCaptures, blockInfo.BlockAlign,1881CaptureStrKind::CopyHelper, CGM);18821883if (llvm::GlobalValue *Func = CGM.getModule().getNamedValue(FuncName))1884return Func;18851886ASTContext &C = getContext();18871888QualType ReturnTy = C.VoidTy;18891890FunctionArgList args;1891ImplicitParamDecl DstDecl(C, C.VoidPtrTy, ImplicitParamKind::Other);1892args.push_back(&DstDecl);1893ImplicitParamDecl SrcDecl(C, C.VoidPtrTy, ImplicitParamKind::Other);1894args.push_back(&SrcDecl);18951896const CGFunctionInfo &FI =1897CGM.getTypes().arrangeBuiltinFunctionDeclaration(ReturnTy, args);18981899// FIXME: it would be nice if these were mergeable with things with1900// identical semantics.1901llvm::FunctionType *LTy = CGM.getTypes().GetFunctionType(FI);19021903llvm::Function *Fn =1904llvm::Function::Create(LTy, llvm::GlobalValue::LinkOnceODRLinkage,1905FuncName, &CGM.getModule());1906if (CGM.supportsCOMDAT())1907Fn->setComdat(CGM.getModule().getOrInsertComdat(FuncName));19081909SmallVector<QualType, 2> ArgTys;1910ArgTys.push_back(C.VoidPtrTy);1911ArgTys.push_back(C.VoidPtrTy);19121913setBlockHelperAttributesVisibility(blockInfo.CapturesNonExternalType, Fn, FI,1914CGM);1915StartFunction(GlobalDecl(), ReturnTy, Fn, FI, args);1916auto AL = ApplyDebugLocation::CreateArtificial(*this);19171918Address src = GetAddrOfLocalVar(&SrcDecl);1919src = Address(Builder.CreateLoad(src), blockInfo.StructureType,1920blockInfo.BlockAlign);19211922Address dst = GetAddrOfLocalVar(&DstDecl);1923dst = Address(Builder.CreateLoad(dst), blockInfo.StructureType,1924blockInfo.BlockAlign);19251926for (auto &capture : blockInfo.SortedCaptures) {1927if (capture.isConstantOrTrivial())1928continue;19291930const BlockDecl::Capture &CI = *capture.Cap;1931QualType captureType = CI.getVariable()->getType();1932BlockFieldFlags flags = capture.CopyFlags;19331934unsigned index = capture.getIndex();1935Address srcField = Builder.CreateStructGEP(src, index);1936Address dstField = Builder.CreateStructGEP(dst, index);19371938switch (capture.CopyKind) {1939case BlockCaptureEntityKind::CXXRecord:1940// If there's an explicit copy expression, we do that.1941assert(CI.getCopyExpr() && "copy expression for variable is missing");1942EmitSynthesizedCXXCopyCtor(dstField, srcField, CI.getCopyExpr());1943break;1944case BlockCaptureEntityKind::ARCWeak:1945EmitARCCopyWeak(dstField, srcField);1946break;1947case BlockCaptureEntityKind::NonTrivialCStruct: {1948// If this is a C struct that requires non-trivial copy construction,1949// emit a call to its copy constructor.1950QualType varType = CI.getVariable()->getType();1951callCStructCopyConstructor(MakeAddrLValue(dstField, varType),1952MakeAddrLValue(srcField, varType));1953break;1954}1955case BlockCaptureEntityKind::ARCStrong: {1956llvm::Value *srcValue = Builder.CreateLoad(srcField, "blockcopy.src");1957// At -O0, store null into the destination field (so that the1958// storeStrong doesn't over-release) and then call storeStrong.1959// This is a workaround to not having an initStrong call.1960if (CGM.getCodeGenOpts().OptimizationLevel == 0) {1961auto *ty = cast<llvm::PointerType>(srcValue->getType());1962llvm::Value *null = llvm::ConstantPointerNull::get(ty);1963Builder.CreateStore(null, dstField);1964EmitARCStoreStrongCall(dstField, srcValue, true);19651966// With optimization enabled, take advantage of the fact that1967// the blocks runtime guarantees a memcpy of the block data, and1968// just emit a retain of the src field.1969} else {1970EmitARCRetainNonBlock(srcValue);19711972// Unless EH cleanup is required, we don't need this anymore, so kill1973// it. It's not quite worth the annoyance to avoid creating it in the1974// first place.1975if (!needsEHCleanup(captureType.isDestructedType()))1976if (auto *I =1977cast_or_null<llvm::Instruction>(dstField.getBasePointer()))1978I->eraseFromParent();1979}1980break;1981}1982case BlockCaptureEntityKind::BlockObject: {1983llvm::Value *srcValue = Builder.CreateLoad(srcField, "blockcopy.src");1984llvm::Value *dstAddr = dstField.emitRawPointer(*this);1985llvm::Value *args[] = {1986dstAddr, srcValue, llvm::ConstantInt::get(Int32Ty, flags.getBitMask())1987};19881989if (CI.isByRef() && C.getBlockVarCopyInit(CI.getVariable()).canThrow())1990EmitRuntimeCallOrInvoke(CGM.getBlockObjectAssign(), args);1991else1992EmitNounwindRuntimeCall(CGM.getBlockObjectAssign(), args);1993break;1994}1995case BlockCaptureEntityKind::None:1996continue;1997}19981999// Ensure that we destroy the copied object if an exception is thrown later2000// in the helper function.2001pushCaptureCleanup(capture.CopyKind, dstField, captureType, flags,2002/*ForCopyHelper*/ true, CI.getVariable(), *this);2003}20042005FinishFunction();20062007return Fn;2008}20092010static BlockFieldFlags2011getBlockFieldFlagsForObjCObjectPointer(const BlockDecl::Capture &CI,2012QualType T) {2013BlockFieldFlags Flags = BLOCK_FIELD_IS_OBJECT;2014if (T->isBlockPointerType())2015Flags = BLOCK_FIELD_IS_BLOCK;2016return Flags;2017}20182019static std::pair<BlockCaptureEntityKind, BlockFieldFlags>2020computeDestroyInfoForBlockCapture(const BlockDecl::Capture &CI, QualType T,2021const LangOptions &LangOpts) {2022if (CI.isEscapingByref()) {2023BlockFieldFlags Flags = BLOCK_FIELD_IS_BYREF;2024if (T.isObjCGCWeak())2025Flags |= BLOCK_FIELD_IS_WEAK;2026return std::make_pair(BlockCaptureEntityKind::BlockObject, Flags);2027}20282029switch (T.isDestructedType()) {2030case QualType::DK_cxx_destructor:2031return std::make_pair(BlockCaptureEntityKind::CXXRecord, BlockFieldFlags());2032case QualType::DK_objc_strong_lifetime:2033// Use objc_storeStrong for __strong direct captures; the2034// dynamic tools really like it when we do this.2035return std::make_pair(BlockCaptureEntityKind::ARCStrong,2036getBlockFieldFlagsForObjCObjectPointer(CI, T));2037case QualType::DK_objc_weak_lifetime:2038// Support __weak direct captures.2039return std::make_pair(BlockCaptureEntityKind::ARCWeak,2040getBlockFieldFlagsForObjCObjectPointer(CI, T));2041case QualType::DK_nontrivial_c_struct:2042return std::make_pair(BlockCaptureEntityKind::NonTrivialCStruct,2043BlockFieldFlags());2044case QualType::DK_none: {2045// Non-ARC captures are strong, and we need to use _Block_object_dispose.2046// But honor the inert __unsafe_unretained qualifier, which doesn't actually2047// make it into the type system.2048if (T->isObjCRetainableType() && !T.getQualifiers().hasObjCLifetime() &&2049!LangOpts.ObjCAutoRefCount && !T->isObjCInertUnsafeUnretainedType())2050return std::make_pair(BlockCaptureEntityKind::BlockObject,2051getBlockFieldFlagsForObjCObjectPointer(CI, T));2052// Otherwise, we have nothing to do.2053return std::make_pair(BlockCaptureEntityKind::None, BlockFieldFlags());2054}2055}2056llvm_unreachable("after exhaustive DestructionKind switch");2057}20582059/// Generate the destroy-helper function for a block closure object:2060/// static void block_destroy_helper(block_t *theBlock);2061///2062/// Note that this destroys a heap-allocated block closure object;2063/// it should not be confused with a 'byref destroy helper', which2064/// destroys the heap-allocated contents of an individual __block2065/// variable.2066llvm::Constant *2067CodeGenFunction::GenerateDestroyHelperFunction(const CGBlockInfo &blockInfo) {2068std::string FuncName = getCopyDestroyHelperFuncName(2069blockInfo.SortedCaptures, blockInfo.BlockAlign,2070CaptureStrKind::DisposeHelper, CGM);20712072if (llvm::GlobalValue *Func = CGM.getModule().getNamedValue(FuncName))2073return Func;20742075ASTContext &C = getContext();20762077QualType ReturnTy = C.VoidTy;20782079FunctionArgList args;2080ImplicitParamDecl SrcDecl(C, C.VoidPtrTy, ImplicitParamKind::Other);2081args.push_back(&SrcDecl);20822083const CGFunctionInfo &FI =2084CGM.getTypes().arrangeBuiltinFunctionDeclaration(ReturnTy, args);20852086// FIXME: We'd like to put these into a mergable by content, with2087// internal linkage.2088llvm::FunctionType *LTy = CGM.getTypes().GetFunctionType(FI);20892090llvm::Function *Fn =2091llvm::Function::Create(LTy, llvm::GlobalValue::LinkOnceODRLinkage,2092FuncName, &CGM.getModule());2093if (CGM.supportsCOMDAT())2094Fn->setComdat(CGM.getModule().getOrInsertComdat(FuncName));20952096SmallVector<QualType, 1> ArgTys;2097ArgTys.push_back(C.VoidPtrTy);20982099setBlockHelperAttributesVisibility(blockInfo.CapturesNonExternalType, Fn, FI,2100CGM);2101StartFunction(GlobalDecl(), ReturnTy, Fn, FI, args);2102markAsIgnoreThreadCheckingAtRuntime(Fn);21032104auto AL = ApplyDebugLocation::CreateArtificial(*this);21052106Address src = GetAddrOfLocalVar(&SrcDecl);2107src = Address(Builder.CreateLoad(src), blockInfo.StructureType,2108blockInfo.BlockAlign);21092110CodeGenFunction::RunCleanupsScope cleanups(*this);21112112for (auto &capture : blockInfo.SortedCaptures) {2113if (capture.isConstantOrTrivial())2114continue;21152116const BlockDecl::Capture &CI = *capture.Cap;2117BlockFieldFlags flags = capture.DisposeFlags;21182119Address srcField = Builder.CreateStructGEP(src, capture.getIndex());21202121pushCaptureCleanup(capture.DisposeKind, srcField,2122CI.getVariable()->getType(), flags,2123/*ForCopyHelper*/ false, CI.getVariable(), *this);2124}21252126cleanups.ForceCleanup();21272128FinishFunction();21292130return Fn;2131}21322133namespace {21342135/// Emits the copy/dispose helper functions for a __block object of id type.2136class ObjectByrefHelpers final : public BlockByrefHelpers {2137BlockFieldFlags Flags;21382139public:2140ObjectByrefHelpers(CharUnits alignment, BlockFieldFlags flags)2141: BlockByrefHelpers(alignment), Flags(flags) {}21422143void emitCopy(CodeGenFunction &CGF, Address destField,2144Address srcField) override {2145destField = destField.withElementType(CGF.Int8Ty);21462147srcField = srcField.withElementType(CGF.Int8PtrTy);2148llvm::Value *srcValue = CGF.Builder.CreateLoad(srcField);21492150unsigned flags = (Flags | BLOCK_BYREF_CALLER).getBitMask();21512152llvm::Value *flagsVal = llvm::ConstantInt::get(CGF.Int32Ty, flags);2153llvm::FunctionCallee fn = CGF.CGM.getBlockObjectAssign();21542155llvm::Value *args[] = {destField.emitRawPointer(CGF), srcValue, flagsVal};2156CGF.EmitNounwindRuntimeCall(fn, args);2157}21582159void emitDispose(CodeGenFunction &CGF, Address field) override {2160field = field.withElementType(CGF.Int8PtrTy);2161llvm::Value *value = CGF.Builder.CreateLoad(field);21622163CGF.BuildBlockRelease(value, Flags | BLOCK_BYREF_CALLER, false);2164}21652166void profileImpl(llvm::FoldingSetNodeID &id) const override {2167id.AddInteger(Flags.getBitMask());2168}2169};21702171/// Emits the copy/dispose helpers for an ARC __block __weak variable.2172class ARCWeakByrefHelpers final : public BlockByrefHelpers {2173public:2174ARCWeakByrefHelpers(CharUnits alignment) : BlockByrefHelpers(alignment) {}21752176void emitCopy(CodeGenFunction &CGF, Address destField,2177Address srcField) override {2178CGF.EmitARCMoveWeak(destField, srcField);2179}21802181void emitDispose(CodeGenFunction &CGF, Address field) override {2182CGF.EmitARCDestroyWeak(field);2183}21842185void profileImpl(llvm::FoldingSetNodeID &id) const override {2186// 0 is distinguishable from all pointers and byref flags2187id.AddInteger(0);2188}2189};21902191/// Emits the copy/dispose helpers for an ARC __block __strong variable2192/// that's not of block-pointer type.2193class ARCStrongByrefHelpers final : public BlockByrefHelpers {2194public:2195ARCStrongByrefHelpers(CharUnits alignment) : BlockByrefHelpers(alignment) {}21962197void emitCopy(CodeGenFunction &CGF, Address destField,2198Address srcField) override {2199// Do a "move" by copying the value and then zeroing out the old2200// variable.22012202llvm::Value *value = CGF.Builder.CreateLoad(srcField);22032204llvm::Value *null =2205llvm::ConstantPointerNull::get(cast<llvm::PointerType>(value->getType()));22062207if (CGF.CGM.getCodeGenOpts().OptimizationLevel == 0) {2208CGF.Builder.CreateStore(null, destField);2209CGF.EmitARCStoreStrongCall(destField, value, /*ignored*/ true);2210CGF.EmitARCStoreStrongCall(srcField, null, /*ignored*/ true);2211return;2212}2213CGF.Builder.CreateStore(value, destField);2214CGF.Builder.CreateStore(null, srcField);2215}22162217void emitDispose(CodeGenFunction &CGF, Address field) override {2218CGF.EmitARCDestroyStrong(field, ARCImpreciseLifetime);2219}22202221void profileImpl(llvm::FoldingSetNodeID &id) const override {2222// 1 is distinguishable from all pointers and byref flags2223id.AddInteger(1);2224}2225};22262227/// Emits the copy/dispose helpers for an ARC __block __strong2228/// variable that's of block-pointer type.2229class ARCStrongBlockByrefHelpers final : public BlockByrefHelpers {2230public:2231ARCStrongBlockByrefHelpers(CharUnits alignment)2232: BlockByrefHelpers(alignment) {}22332234void emitCopy(CodeGenFunction &CGF, Address destField,2235Address srcField) override {2236// Do the copy with objc_retainBlock; that's all that2237// _Block_object_assign would do anyway, and we'd have to pass the2238// right arguments to make sure it doesn't get no-op'ed.2239llvm::Value *oldValue = CGF.Builder.CreateLoad(srcField);2240llvm::Value *copy = CGF.EmitARCRetainBlock(oldValue, /*mandatory*/ true);2241CGF.Builder.CreateStore(copy, destField);2242}22432244void emitDispose(CodeGenFunction &CGF, Address field) override {2245CGF.EmitARCDestroyStrong(field, ARCImpreciseLifetime);2246}22472248void profileImpl(llvm::FoldingSetNodeID &id) const override {2249// 2 is distinguishable from all pointers and byref flags2250id.AddInteger(2);2251}2252};22532254/// Emits the copy/dispose helpers for a __block variable with a2255/// nontrivial copy constructor or destructor.2256class CXXByrefHelpers final : public BlockByrefHelpers {2257QualType VarType;2258const Expr *CopyExpr;22592260public:2261CXXByrefHelpers(CharUnits alignment, QualType type,2262const Expr *copyExpr)2263: BlockByrefHelpers(alignment), VarType(type), CopyExpr(copyExpr) {}22642265bool needsCopy() const override { return CopyExpr != nullptr; }2266void emitCopy(CodeGenFunction &CGF, Address destField,2267Address srcField) override {2268if (!CopyExpr) return;2269CGF.EmitSynthesizedCXXCopyCtor(destField, srcField, CopyExpr);2270}22712272void emitDispose(CodeGenFunction &CGF, Address field) override {2273EHScopeStack::stable_iterator cleanupDepth = CGF.EHStack.stable_begin();2274CGF.PushDestructorCleanup(VarType, field);2275CGF.PopCleanupBlocks(cleanupDepth);2276}22772278void profileImpl(llvm::FoldingSetNodeID &id) const override {2279id.AddPointer(VarType.getCanonicalType().getAsOpaquePtr());2280}2281};22822283/// Emits the copy/dispose helpers for a __block variable that is a non-trivial2284/// C struct.2285class NonTrivialCStructByrefHelpers final : public BlockByrefHelpers {2286QualType VarType;22872288public:2289NonTrivialCStructByrefHelpers(CharUnits alignment, QualType type)2290: BlockByrefHelpers(alignment), VarType(type) {}22912292void emitCopy(CodeGenFunction &CGF, Address destField,2293Address srcField) override {2294CGF.callCStructMoveConstructor(CGF.MakeAddrLValue(destField, VarType),2295CGF.MakeAddrLValue(srcField, VarType));2296}22972298bool needsDispose() const override {2299return VarType.isDestructedType();2300}23012302void emitDispose(CodeGenFunction &CGF, Address field) override {2303EHScopeStack::stable_iterator cleanupDepth = CGF.EHStack.stable_begin();2304CGF.pushDestroy(VarType.isDestructedType(), field, VarType);2305CGF.PopCleanupBlocks(cleanupDepth);2306}23072308void profileImpl(llvm::FoldingSetNodeID &id) const override {2309id.AddPointer(VarType.getCanonicalType().getAsOpaquePtr());2310}2311};2312} // end anonymous namespace23132314static llvm::Constant *2315generateByrefCopyHelper(CodeGenFunction &CGF, const BlockByrefInfo &byrefInfo,2316BlockByrefHelpers &generator) {2317ASTContext &Context = CGF.getContext();23182319QualType ReturnTy = Context.VoidTy;23202321FunctionArgList args;2322ImplicitParamDecl Dst(Context, Context.VoidPtrTy, ImplicitParamKind::Other);2323args.push_back(&Dst);23242325ImplicitParamDecl Src(Context, Context.VoidPtrTy, ImplicitParamKind::Other);2326args.push_back(&Src);23272328const CGFunctionInfo &FI =2329CGF.CGM.getTypes().arrangeBuiltinFunctionDeclaration(ReturnTy, args);23302331llvm::FunctionType *LTy = CGF.CGM.getTypes().GetFunctionType(FI);23322333// FIXME: We'd like to put these into a mergable by content, with2334// internal linkage.2335llvm::Function *Fn =2336llvm::Function::Create(LTy, llvm::GlobalValue::InternalLinkage,2337"__Block_byref_object_copy_", &CGF.CGM.getModule());23382339SmallVector<QualType, 2> ArgTys;2340ArgTys.push_back(Context.VoidPtrTy);2341ArgTys.push_back(Context.VoidPtrTy);23422343CGF.CGM.SetInternalFunctionAttributes(GlobalDecl(), Fn, FI);23442345CGF.StartFunction(GlobalDecl(), ReturnTy, Fn, FI, args);2346// Create a scope with an artificial location for the body of this function.2347auto AL = ApplyDebugLocation::CreateArtificial(CGF);23482349if (generator.needsCopy()) {2350// dst->x2351Address destField = CGF.GetAddrOfLocalVar(&Dst);2352destField = Address(CGF.Builder.CreateLoad(destField), byrefInfo.Type,2353byrefInfo.ByrefAlignment);2354destField =2355CGF.emitBlockByrefAddress(destField, byrefInfo, false, "dest-object");23562357// src->x2358Address srcField = CGF.GetAddrOfLocalVar(&Src);2359srcField = Address(CGF.Builder.CreateLoad(srcField), byrefInfo.Type,2360byrefInfo.ByrefAlignment);2361srcField =2362CGF.emitBlockByrefAddress(srcField, byrefInfo, false, "src-object");23632364generator.emitCopy(CGF, destField, srcField);2365}23662367CGF.FinishFunction();23682369return Fn;2370}23712372/// Build the copy helper for a __block variable.2373static llvm::Constant *buildByrefCopyHelper(CodeGenModule &CGM,2374const BlockByrefInfo &byrefInfo,2375BlockByrefHelpers &generator) {2376CodeGenFunction CGF(CGM);2377return generateByrefCopyHelper(CGF, byrefInfo, generator);2378}23792380/// Generate code for a __block variable's dispose helper.2381static llvm::Constant *2382generateByrefDisposeHelper(CodeGenFunction &CGF,2383const BlockByrefInfo &byrefInfo,2384BlockByrefHelpers &generator) {2385ASTContext &Context = CGF.getContext();2386QualType R = Context.VoidTy;23872388FunctionArgList args;2389ImplicitParamDecl Src(CGF.getContext(), Context.VoidPtrTy,2390ImplicitParamKind::Other);2391args.push_back(&Src);23922393const CGFunctionInfo &FI =2394CGF.CGM.getTypes().arrangeBuiltinFunctionDeclaration(R, args);23952396llvm::FunctionType *LTy = CGF.CGM.getTypes().GetFunctionType(FI);23972398// FIXME: We'd like to put these into a mergable by content, with2399// internal linkage.2400llvm::Function *Fn =2401llvm::Function::Create(LTy, llvm::GlobalValue::InternalLinkage,2402"__Block_byref_object_dispose_",2403&CGF.CGM.getModule());24042405SmallVector<QualType, 1> ArgTys;2406ArgTys.push_back(Context.VoidPtrTy);24072408CGF.CGM.SetInternalFunctionAttributes(GlobalDecl(), Fn, FI);24092410CGF.StartFunction(GlobalDecl(), R, Fn, FI, args);2411// Create a scope with an artificial location for the body of this function.2412auto AL = ApplyDebugLocation::CreateArtificial(CGF);24132414if (generator.needsDispose()) {2415Address addr = CGF.GetAddrOfLocalVar(&Src);2416addr = Address(CGF.Builder.CreateLoad(addr), byrefInfo.Type,2417byrefInfo.ByrefAlignment);2418addr = CGF.emitBlockByrefAddress(addr, byrefInfo, false, "object");24192420generator.emitDispose(CGF, addr);2421}24222423CGF.FinishFunction();24242425return Fn;2426}24272428/// Build the dispose helper for a __block variable.2429static llvm::Constant *buildByrefDisposeHelper(CodeGenModule &CGM,2430const BlockByrefInfo &byrefInfo,2431BlockByrefHelpers &generator) {2432CodeGenFunction CGF(CGM);2433return generateByrefDisposeHelper(CGF, byrefInfo, generator);2434}24352436/// Lazily build the copy and dispose helpers for a __block variable2437/// with the given information.2438template <class T>2439static T *buildByrefHelpers(CodeGenModule &CGM, const BlockByrefInfo &byrefInfo,2440T &&generator) {2441llvm::FoldingSetNodeID id;2442generator.Profile(id);24432444void *insertPos;2445BlockByrefHelpers *node2446= CGM.ByrefHelpersCache.FindNodeOrInsertPos(id, insertPos);2447if (node) return static_cast<T*>(node);24482449generator.CopyHelper = buildByrefCopyHelper(CGM, byrefInfo, generator);2450generator.DisposeHelper = buildByrefDisposeHelper(CGM, byrefInfo, generator);24512452T *copy = new (CGM.getContext()) T(std::forward<T>(generator));2453CGM.ByrefHelpersCache.InsertNode(copy, insertPos);2454return copy;2455}24562457/// Build the copy and dispose helpers for the given __block variable2458/// emission. Places the helpers in the global cache. Returns null2459/// if no helpers are required.2460BlockByrefHelpers *2461CodeGenFunction::buildByrefHelpers(llvm::StructType &byrefType,2462const AutoVarEmission &emission) {2463const VarDecl &var = *emission.Variable;2464assert(var.isEscapingByref() &&2465"only escaping __block variables need byref helpers");24662467QualType type = var.getType();24682469auto &byrefInfo = getBlockByrefInfo(&var);24702471// The alignment we care about for the purposes of uniquing byref2472// helpers is the alignment of the actual byref value field.2473CharUnits valueAlignment =2474byrefInfo.ByrefAlignment.alignmentAtOffset(byrefInfo.FieldOffset);24752476if (const CXXRecordDecl *record = type->getAsCXXRecordDecl()) {2477const Expr *copyExpr =2478CGM.getContext().getBlockVarCopyInit(&var).getCopyExpr();2479if (!copyExpr && record->hasTrivialDestructor()) return nullptr;24802481return ::buildByrefHelpers(2482CGM, byrefInfo, CXXByrefHelpers(valueAlignment, type, copyExpr));2483}24842485// If type is a non-trivial C struct type that is non-trivial to2486// destructly move or destroy, build the copy and dispose helpers.2487if (type.isNonTrivialToPrimitiveDestructiveMove() == QualType::PCK_Struct ||2488type.isDestructedType() == QualType::DK_nontrivial_c_struct)2489return ::buildByrefHelpers(2490CGM, byrefInfo, NonTrivialCStructByrefHelpers(valueAlignment, type));24912492// Otherwise, if we don't have a retainable type, there's nothing to do.2493// that the runtime does extra copies.2494if (!type->isObjCRetainableType()) return nullptr;24952496Qualifiers qs = type.getQualifiers();24972498// If we have lifetime, that dominates.2499if (Qualifiers::ObjCLifetime lifetime = qs.getObjCLifetime()) {2500switch (lifetime) {2501case Qualifiers::OCL_None: llvm_unreachable("impossible");25022503// These are just bits as far as the runtime is concerned.2504case Qualifiers::OCL_ExplicitNone:2505case Qualifiers::OCL_Autoreleasing:2506return nullptr;25072508// Tell the runtime that this is ARC __weak, called by the2509// byref routines.2510case Qualifiers::OCL_Weak:2511return ::buildByrefHelpers(CGM, byrefInfo,2512ARCWeakByrefHelpers(valueAlignment));25132514// ARC __strong __block variables need to be retained.2515case Qualifiers::OCL_Strong:2516// Block pointers need to be copied, and there's no direct2517// transfer possible.2518if (type->isBlockPointerType()) {2519return ::buildByrefHelpers(CGM, byrefInfo,2520ARCStrongBlockByrefHelpers(valueAlignment));25212522// Otherwise, we transfer ownership of the retain from the stack2523// to the heap.2524} else {2525return ::buildByrefHelpers(CGM, byrefInfo,2526ARCStrongByrefHelpers(valueAlignment));2527}2528}2529llvm_unreachable("fell out of lifetime switch!");2530}25312532BlockFieldFlags flags;2533if (type->isBlockPointerType()) {2534flags |= BLOCK_FIELD_IS_BLOCK;2535} else if (CGM.getContext().isObjCNSObjectType(type) ||2536type->isObjCObjectPointerType()) {2537flags |= BLOCK_FIELD_IS_OBJECT;2538} else {2539return nullptr;2540}25412542if (type.isObjCGCWeak())2543flags |= BLOCK_FIELD_IS_WEAK;25442545return ::buildByrefHelpers(CGM, byrefInfo,2546ObjectByrefHelpers(valueAlignment, flags));2547}25482549Address CodeGenFunction::emitBlockByrefAddress(Address baseAddr,2550const VarDecl *var,2551bool followForward) {2552auto &info = getBlockByrefInfo(var);2553return emitBlockByrefAddress(baseAddr, info, followForward, var->getName());2554}25552556Address CodeGenFunction::emitBlockByrefAddress(Address baseAddr,2557const BlockByrefInfo &info,2558bool followForward,2559const llvm::Twine &name) {2560// Chase the forwarding address if requested.2561if (followForward) {2562Address forwardingAddr = Builder.CreateStructGEP(baseAddr, 1, "forwarding");2563baseAddr = Address(Builder.CreateLoad(forwardingAddr), info.Type,2564info.ByrefAlignment);2565}25662567return Builder.CreateStructGEP(baseAddr, info.FieldIndex, name);2568}25692570/// BuildByrefInfo - This routine changes a __block variable declared as T x2571/// into:2572///2573/// struct {2574/// void *__isa;2575/// void *__forwarding;2576/// int32_t __flags;2577/// int32_t __size;2578/// void *__copy_helper; // only if needed2579/// void *__destroy_helper; // only if needed2580/// void *__byref_variable_layout;// only if needed2581/// char padding[X]; // only if needed2582/// T x;2583/// } x2584///2585const BlockByrefInfo &CodeGenFunction::getBlockByrefInfo(const VarDecl *D) {2586auto it = BlockByrefInfos.find(D);2587if (it != BlockByrefInfos.end())2588return it->second;25892590llvm::StructType *byrefType =2591llvm::StructType::create(getLLVMContext(),2592"struct.__block_byref_" + D->getNameAsString());25932594QualType Ty = D->getType();25952596CharUnits size;2597SmallVector<llvm::Type *, 8> types;25982599// void *__isa;2600types.push_back(VoidPtrTy);2601size += getPointerSize();26022603// void *__forwarding;2604types.push_back(VoidPtrTy);2605size += getPointerSize();26062607// int32_t __flags;2608types.push_back(Int32Ty);2609size += CharUnits::fromQuantity(4);26102611// int32_t __size;2612types.push_back(Int32Ty);2613size += CharUnits::fromQuantity(4);26142615// Note that this must match *exactly* the logic in buildByrefHelpers.2616bool hasCopyAndDispose = getContext().BlockRequiresCopying(Ty, D);2617if (hasCopyAndDispose) {2618/// void *__copy_helper;2619types.push_back(VoidPtrTy);2620size += getPointerSize();26212622/// void *__destroy_helper;2623types.push_back(VoidPtrTy);2624size += getPointerSize();2625}26262627bool HasByrefExtendedLayout = false;2628Qualifiers::ObjCLifetime Lifetime = Qualifiers::OCL_None;2629if (getContext().getByrefLifetime(Ty, Lifetime, HasByrefExtendedLayout) &&2630HasByrefExtendedLayout) {2631/// void *__byref_variable_layout;2632types.push_back(VoidPtrTy);2633size += CharUnits::fromQuantity(PointerSizeInBytes);2634}26352636// T x;2637llvm::Type *varTy = ConvertTypeForMem(Ty);26382639bool packed = false;2640CharUnits varAlign = getContext().getDeclAlign(D);2641CharUnits varOffset = size.alignTo(varAlign);26422643// We may have to insert padding.2644if (varOffset != size) {2645llvm::Type *paddingTy =2646llvm::ArrayType::get(Int8Ty, (varOffset - size).getQuantity());26472648types.push_back(paddingTy);2649size = varOffset;26502651// Conversely, we might have to prevent LLVM from inserting padding.2652} else if (CGM.getDataLayout().getABITypeAlign(varTy) >2653uint64_t(varAlign.getQuantity())) {2654packed = true;2655}2656types.push_back(varTy);26572658byrefType->setBody(types, packed);26592660BlockByrefInfo info;2661info.Type = byrefType;2662info.FieldIndex = types.size() - 1;2663info.FieldOffset = varOffset;2664info.ByrefAlignment = std::max(varAlign, getPointerAlign());26652666auto pair = BlockByrefInfos.insert({D, info});2667assert(pair.second && "info was inserted recursively?");2668return pair.first->second;2669}26702671/// Initialize the structural components of a __block variable, i.e.2672/// everything but the actual object.2673void CodeGenFunction::emitByrefStructureInit(const AutoVarEmission &emission) {2674// Find the address of the local.2675Address addr = emission.Addr;26762677// That's an alloca of the byref structure type.2678llvm::StructType *byrefType = cast<llvm::StructType>(addr.getElementType());26792680unsigned nextHeaderIndex = 0;2681CharUnits nextHeaderOffset;2682auto storeHeaderField = [&](llvm::Value *value, CharUnits fieldSize,2683const Twine &name) {2684auto fieldAddr = Builder.CreateStructGEP(addr, nextHeaderIndex, name);2685Builder.CreateStore(value, fieldAddr);26862687nextHeaderIndex++;2688nextHeaderOffset += fieldSize;2689};26902691// Build the byref helpers if necessary. This is null if we don't need any.2692BlockByrefHelpers *helpers = buildByrefHelpers(*byrefType, emission);26932694const VarDecl &D = *emission.Variable;2695QualType type = D.getType();26962697bool HasByrefExtendedLayout = false;2698Qualifiers::ObjCLifetime ByrefLifetime = Qualifiers::OCL_None;2699bool ByRefHasLifetime =2700getContext().getByrefLifetime(type, ByrefLifetime, HasByrefExtendedLayout);27012702llvm::Value *V;27032704// Initialize the 'isa', which is just 0 or 1.2705int isa = 0;2706if (type.isObjCGCWeak())2707isa = 1;2708V = Builder.CreateIntToPtr(Builder.getInt32(isa), Int8PtrTy, "isa");2709storeHeaderField(V, getPointerSize(), "byref.isa");27102711// Store the address of the variable into its own forwarding pointer.2712storeHeaderField(addr.emitRawPointer(*this), getPointerSize(),2713"byref.forwarding");27142715// Blocks ABI:2716// c) the flags field is set to either 0 if no helper functions are2717// needed or BLOCK_BYREF_HAS_COPY_DISPOSE if they are,2718BlockFlags flags;2719if (helpers) flags |= BLOCK_BYREF_HAS_COPY_DISPOSE;2720if (ByRefHasLifetime) {2721if (HasByrefExtendedLayout) flags |= BLOCK_BYREF_LAYOUT_EXTENDED;2722else switch (ByrefLifetime) {2723case Qualifiers::OCL_Strong:2724flags |= BLOCK_BYREF_LAYOUT_STRONG;2725break;2726case Qualifiers::OCL_Weak:2727flags |= BLOCK_BYREF_LAYOUT_WEAK;2728break;2729case Qualifiers::OCL_ExplicitNone:2730flags |= BLOCK_BYREF_LAYOUT_UNRETAINED;2731break;2732case Qualifiers::OCL_None:2733if (!type->isObjCObjectPointerType() && !type->isBlockPointerType())2734flags |= BLOCK_BYREF_LAYOUT_NON_OBJECT;2735break;2736default:2737break;2738}2739if (CGM.getLangOpts().ObjCGCBitmapPrint) {2740printf("\n Inline flag for BYREF variable layout (%d):", flags.getBitMask());2741if (flags & BLOCK_BYREF_HAS_COPY_DISPOSE)2742printf(" BLOCK_BYREF_HAS_COPY_DISPOSE");2743if (flags & BLOCK_BYREF_LAYOUT_MASK) {2744BlockFlags ThisFlag(flags.getBitMask() & BLOCK_BYREF_LAYOUT_MASK);2745if (ThisFlag == BLOCK_BYREF_LAYOUT_EXTENDED)2746printf(" BLOCK_BYREF_LAYOUT_EXTENDED");2747if (ThisFlag == BLOCK_BYREF_LAYOUT_STRONG)2748printf(" BLOCK_BYREF_LAYOUT_STRONG");2749if (ThisFlag == BLOCK_BYREF_LAYOUT_WEAK)2750printf(" BLOCK_BYREF_LAYOUT_WEAK");2751if (ThisFlag == BLOCK_BYREF_LAYOUT_UNRETAINED)2752printf(" BLOCK_BYREF_LAYOUT_UNRETAINED");2753if (ThisFlag == BLOCK_BYREF_LAYOUT_NON_OBJECT)2754printf(" BLOCK_BYREF_LAYOUT_NON_OBJECT");2755}2756printf("\n");2757}2758}2759storeHeaderField(llvm::ConstantInt::get(IntTy, flags.getBitMask()),2760getIntSize(), "byref.flags");27612762CharUnits byrefSize = CGM.GetTargetTypeStoreSize(byrefType);2763V = llvm::ConstantInt::get(IntTy, byrefSize.getQuantity());2764storeHeaderField(V, getIntSize(), "byref.size");27652766if (helpers) {2767storeHeaderField(helpers->CopyHelper, getPointerSize(),2768"byref.copyHelper");2769storeHeaderField(helpers->DisposeHelper, getPointerSize(),2770"byref.disposeHelper");2771}27722773if (ByRefHasLifetime && HasByrefExtendedLayout) {2774auto layoutInfo = CGM.getObjCRuntime().BuildByrefLayout(CGM, type);2775storeHeaderField(layoutInfo, getPointerSize(), "byref.layout");2776}2777}27782779void CodeGenFunction::BuildBlockRelease(llvm::Value *V, BlockFieldFlags flags,2780bool CanThrow) {2781llvm::FunctionCallee F = CGM.getBlockObjectDispose();2782llvm::Value *args[] = {V,2783llvm::ConstantInt::get(Int32Ty, flags.getBitMask())};27842785if (CanThrow)2786EmitRuntimeCallOrInvoke(F, args);2787else2788EmitNounwindRuntimeCall(F, args);2789}27902791void CodeGenFunction::enterByrefCleanup(CleanupKind Kind, Address Addr,2792BlockFieldFlags Flags,2793bool LoadBlockVarAddr, bool CanThrow) {2794EHStack.pushCleanup<CallBlockRelease>(Kind, Addr, Flags, LoadBlockVarAddr,2795CanThrow);2796}27972798/// Adjust the declaration of something from the blocks API.2799static void configureBlocksRuntimeObject(CodeGenModule &CGM,2800llvm::Constant *C) {2801auto *GV = cast<llvm::GlobalValue>(C->stripPointerCasts());28022803if (CGM.getTarget().getTriple().isOSBinFormatCOFF()) {2804const IdentifierInfo &II = CGM.getContext().Idents.get(C->getName());2805TranslationUnitDecl *TUDecl = CGM.getContext().getTranslationUnitDecl();2806DeclContext *DC = TranslationUnitDecl::castToDeclContext(TUDecl);28072808assert((isa<llvm::Function>(C->stripPointerCasts()) ||2809isa<llvm::GlobalVariable>(C->stripPointerCasts())) &&2810"expected Function or GlobalVariable");28112812const NamedDecl *ND = nullptr;2813for (const auto *Result : DC->lookup(&II))2814if ((ND = dyn_cast<FunctionDecl>(Result)) ||2815(ND = dyn_cast<VarDecl>(Result)))2816break;28172818// TODO: support static blocks runtime2819if (GV->isDeclaration() && (!ND || !ND->hasAttr<DLLExportAttr>())) {2820GV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);2821GV->setLinkage(llvm::GlobalValue::ExternalLinkage);2822} else {2823GV->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);2824GV->setLinkage(llvm::GlobalValue::ExternalLinkage);2825}2826}28272828if (CGM.getLangOpts().BlocksRuntimeOptional && GV->isDeclaration() &&2829GV->hasExternalLinkage())2830GV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage);28312832CGM.setDSOLocal(GV);2833}28342835llvm::FunctionCallee CodeGenModule::getBlockObjectDispose() {2836if (BlockObjectDispose)2837return BlockObjectDispose;28382839llvm::Type *args[] = { Int8PtrTy, Int32Ty };2840llvm::FunctionType *fty2841= llvm::FunctionType::get(VoidTy, args, false);2842BlockObjectDispose = CreateRuntimeFunction(fty, "_Block_object_dispose");2843configureBlocksRuntimeObject(2844*this, cast<llvm::Constant>(BlockObjectDispose.getCallee()));2845return BlockObjectDispose;2846}28472848llvm::FunctionCallee CodeGenModule::getBlockObjectAssign() {2849if (BlockObjectAssign)2850return BlockObjectAssign;28512852llvm::Type *args[] = { Int8PtrTy, Int8PtrTy, Int32Ty };2853llvm::FunctionType *fty2854= llvm::FunctionType::get(VoidTy, args, false);2855BlockObjectAssign = CreateRuntimeFunction(fty, "_Block_object_assign");2856configureBlocksRuntimeObject(2857*this, cast<llvm::Constant>(BlockObjectAssign.getCallee()));2858return BlockObjectAssign;2859}28602861llvm::Constant *CodeGenModule::getNSConcreteGlobalBlock() {2862if (NSConcreteGlobalBlock)2863return NSConcreteGlobalBlock;28642865NSConcreteGlobalBlock = GetOrCreateLLVMGlobal(2866"_NSConcreteGlobalBlock", Int8PtrTy, LangAS::Default, nullptr);2867configureBlocksRuntimeObject(*this, NSConcreteGlobalBlock);2868return NSConcreteGlobalBlock;2869}28702871llvm::Constant *CodeGenModule::getNSConcreteStackBlock() {2872if (NSConcreteStackBlock)2873return NSConcreteStackBlock;28742875NSConcreteStackBlock = GetOrCreateLLVMGlobal(2876"_NSConcreteStackBlock", Int8PtrTy, LangAS::Default, nullptr);2877configureBlocksRuntimeObject(*this, NSConcreteStackBlock);2878return NSConcreteStackBlock;2879}288028812882