#include "CGBlocks.h"
#include "CGCXXABI.h"
#include "CGDebugInfo.h"
#include "CGObjCRuntime.h"
#include "CGOpenCLRuntime.h"
#include "CodeGenFunction.h"
#include "CodeGenModule.h"
#include "ConstantEmitter.h"
#include "TargetInfo.h"
#include "clang/AST/Attr.h"
#include "clang/AST/DeclObjC.h"
#include "clang/CodeGen/ConstantInitBuilder.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/ScopedPrinter.h"
#include <algorithm>
#include <cstdio>
usingnamespaceclang;
usingnamespaceCodeGen;
CGBlockInfo::CGBlockInfo(const BlockDecl *block, StringRef name)
: … { … }
BlockByrefHelpers::~BlockByrefHelpers() { … }
static llvm::Constant *buildGlobalBlock(CodeGenModule &CGM,
const CGBlockInfo &blockInfo,
llvm::Constant *blockFn);
static llvm::Constant *buildCopyHelper(CodeGenModule &CGM,
const CGBlockInfo &blockInfo) { … }
static llvm::Constant *buildDisposeHelper(CodeGenModule &CGM,
const CGBlockInfo &blockInfo) { … }
namespace {
enum class CaptureStrKind { … };
}
static std::string getBlockCaptureStr(const CGBlockInfo::Capture &Cap,
CaptureStrKind StrKind,
CharUnits BlockAlignment,
CodeGenModule &CGM);
static std::string getBlockDescriptorName(const CGBlockInfo &BlockInfo,
CodeGenModule &CGM) { … }
static llvm::Constant *buildBlockDescriptor(CodeGenModule &CGM,
const CGBlockInfo &blockInfo) { … }
namespace {
struct BlockLayoutChunk { … };
bool operator<(const BlockLayoutChunk &left, const BlockLayoutChunk &right) { … }
}
static std::pair<BlockCaptureEntityKind, BlockFieldFlags>
computeCopyInfoForBlockCapture(const BlockDecl::Capture &CI, QualType T,
const LangOptions &LangOpts);
static std::pair<BlockCaptureEntityKind, BlockFieldFlags>
computeDestroyInfoForBlockCapture(const BlockDecl::Capture &CI, QualType T,
const LangOptions &LangOpts);
static void addBlockLayout(CharUnits align, CharUnits size,
const BlockDecl::Capture *capture, llvm::Type *type,
QualType fieldType,
SmallVectorImpl<BlockLayoutChunk> &Layout,
CGBlockInfo &Info, CodeGenModule &CGM) { … }
static bool isSafeForCXXConstantCapture(QualType type) { … }
static llvm::Constant *tryCaptureAsConstant(CodeGenModule &CGM,
CodeGenFunction *CGF,
const VarDecl *var) { … }
static CharUnits getLowBit(CharUnits v) { … }
static void initializeForBlockHeader(CodeGenModule &CGM, CGBlockInfo &info,
SmallVectorImpl<llvm::Type*> &elementTypes) { … }
static QualType getCaptureFieldType(const CodeGenFunction &CGF,
const BlockDecl::Capture &CI) { … }
static void computeBlockInfo(CodeGenModule &CGM, CodeGenFunction *CGF,
CGBlockInfo &info) { … }
llvm::Value *CodeGenFunction::EmitBlockLiteral(const BlockExpr *blockExpr) { … }
llvm::Value *CodeGenFunction::EmitBlockLiteral(const CGBlockInfo &blockInfo) { … }
llvm::Type *CodeGenModule::getBlockDescriptorType() { … }
llvm::Type *CodeGenModule::getGenericBlockLiteralType() { … }
RValue CodeGenFunction::EmitBlockCallExpr(const CallExpr *E,
ReturnValueSlot ReturnValue,
llvm::CallBase **CallOrInvoke) { … }
Address CodeGenFunction::GetAddrOfBlockDecl(const VarDecl *variable) { … }
void CodeGenModule::setAddrOfGlobalBlock(const BlockExpr *BE,
llvm::Constant *Addr) { … }
llvm::Constant *
CodeGenModule::GetAddrOfGlobalBlock(const BlockExpr *BE,
StringRef Name) { … }
static llvm::Constant *buildGlobalBlock(CodeGenModule &CGM,
const CGBlockInfo &blockInfo,
llvm::Constant *blockFn) { … }
void CodeGenFunction::setBlockContextParameter(const ImplicitParamDecl *D,
unsigned argNum,
llvm::Value *arg) { … }
Address CodeGenFunction::LoadBlockStruct() { … }
llvm::Function *CodeGenFunction::GenerateBlockFunction(
GlobalDecl GD, const CGBlockInfo &blockInfo, const DeclMapTy &ldm,
bool IsLambdaConversionToBlock, bool BuildGlobalBlock) { … }
static std::pair<BlockCaptureEntityKind, BlockFieldFlags>
computeCopyInfoForBlockCapture(const BlockDecl::Capture &CI, QualType T,
const LangOptions &LangOpts) { … }
namespace {
struct CallBlockRelease final : EHScopeStack::Cleanup { … };
}
bool CodeGenFunction::cxxDestructorCanThrow(QualType T) { … }
static std::string getBlockCaptureStr(const CGBlockInfo::Capture &Cap,
CaptureStrKind StrKind,
CharUnits BlockAlignment,
CodeGenModule &CGM) { … }
static std::string getCopyDestroyHelperFuncName(
const SmallVectorImpl<CGBlockInfo::Capture> &Captures,
CharUnits BlockAlignment, CaptureStrKind StrKind, CodeGenModule &CGM) { … }
static void pushCaptureCleanup(BlockCaptureEntityKind CaptureKind,
Address Field, QualType CaptureType,
BlockFieldFlags Flags, bool ForCopyHelper,
VarDecl *Var, CodeGenFunction &CGF) { … }
static void setBlockHelperAttributesVisibility(bool CapturesNonExternalType,
llvm::Function *Fn,
const CGFunctionInfo &FI,
CodeGenModule &CGM) { … }
llvm::Constant *
CodeGenFunction::GenerateCopyHelperFunction(const CGBlockInfo &blockInfo) { … }
static BlockFieldFlags
getBlockFieldFlagsForObjCObjectPointer(const BlockDecl::Capture &CI,
QualType T) { … }
static std::pair<BlockCaptureEntityKind, BlockFieldFlags>
computeDestroyInfoForBlockCapture(const BlockDecl::Capture &CI, QualType T,
const LangOptions &LangOpts) { … }
llvm::Constant *
CodeGenFunction::GenerateDestroyHelperFunction(const CGBlockInfo &blockInfo) { … }
namespace {
class ObjectByrefHelpers final : public BlockByrefHelpers { … };
class ARCWeakByrefHelpers final : public BlockByrefHelpers { … };
class ARCStrongByrefHelpers final : public BlockByrefHelpers { … };
class ARCStrongBlockByrefHelpers final : public BlockByrefHelpers { … };
class CXXByrefHelpers final : public BlockByrefHelpers { … };
class NonTrivialCStructByrefHelpers final : public BlockByrefHelpers { … };
}
static llvm::Constant *
generateByrefCopyHelper(CodeGenFunction &CGF, const BlockByrefInfo &byrefInfo,
BlockByrefHelpers &generator) { … }
static llvm::Constant *buildByrefCopyHelper(CodeGenModule &CGM,
const BlockByrefInfo &byrefInfo,
BlockByrefHelpers &generator) { … }
static llvm::Constant *
generateByrefDisposeHelper(CodeGenFunction &CGF,
const BlockByrefInfo &byrefInfo,
BlockByrefHelpers &generator) { … }
static llvm::Constant *buildByrefDisposeHelper(CodeGenModule &CGM,
const BlockByrefInfo &byrefInfo,
BlockByrefHelpers &generator) { … }
template <class T>
static T *buildByrefHelpers(CodeGenModule &CGM, const BlockByrefInfo &byrefInfo,
T &&generator) { … }
BlockByrefHelpers *
CodeGenFunction::buildByrefHelpers(llvm::StructType &byrefType,
const AutoVarEmission &emission) { … }
Address CodeGenFunction::emitBlockByrefAddress(Address baseAddr,
const VarDecl *var,
bool followForward) { … }
Address CodeGenFunction::emitBlockByrefAddress(Address baseAddr,
const BlockByrefInfo &info,
bool followForward,
const llvm::Twine &name) { … }
const BlockByrefInfo &CodeGenFunction::getBlockByrefInfo(const VarDecl *D) { … }
void CodeGenFunction::emitByrefStructureInit(const AutoVarEmission &emission) { … }
void CodeGenFunction::BuildBlockRelease(llvm::Value *V, BlockFieldFlags flags,
bool CanThrow) { … }
void CodeGenFunction::enterByrefCleanup(CleanupKind Kind, Address Addr,
BlockFieldFlags Flags,
bool LoadBlockVarAddr, bool CanThrow) { … }
static void configureBlocksRuntimeObject(CodeGenModule &CGM,
llvm::Constant *C) { … }
llvm::FunctionCallee CodeGenModule::getBlockObjectDispose() { … }
llvm::FunctionCallee CodeGenModule::getBlockObjectAssign() { … }
llvm::Constant *CodeGenModule::getNSConcreteGlobalBlock() { … }
llvm::Constant *CodeGenModule::getNSConcreteStackBlock() { … }