20 #include "llvm/ADT/SmallSet.h"
21 #include "llvm/IR/CallSite.h"
22 #include "llvm/IR/DataLayout.h"
23 #include "llvm/IR/Module.h"
27 using namespace clang;
28 using namespace CodeGen;
31 :
Name(name), CXXThisIndex(0), CanBeGlobal(
false), NeedsCopyDispose(
false),
32 HasCXXObject(
false), UsesStret(
false), HasCapturedVariableLayout(
false),
33 LocalAddress(
Address::invalid()), StructureType(nullptr), Block(block),
34 DominatingIP(nullptr) {
38 if (!name.empty() && name[0] ==
'\01')
39 name = name.substr(1);
48 llvm::Constant *blockFn);
84 llvm::Type::getInt8PtrTy(
92 elements.push_back(llvm::ConstantInt::get(ulong, 0));
98 elements.push_back(llvm::ConstantInt::get(ulong,
111 std::string typeAtEncoding =
113 elements.push_back(llvm::ConstantExpr::getBitCast(
124 elements.push_back(llvm::Constant::getNullValue(i8p));
126 llvm::Constant *init = llvm::ConstantStruct::getAnon(elements);
128 llvm::GlobalVariable *global =
129 new llvm::GlobalVariable(CGM.
getModule(), init->getType(),
true,
131 init,
"__block_descriptor_tmp");
149 struct objc_class *isa;
176 _ResultType (*invoke)(Block_literal *, _ParamTypes...);
179 struct Block_descriptor *block_descriptor;
182 _CapturesTypes captures...;
191 struct BlockLayoutChunk {
202 : Alignment(align), Size(size), Lifetime(lifetime),
203 Capture(capture),
Type(type) {}
211 info.
Captures.insert({Capture->getVariable(),
219 bool operator<(
const BlockLayoutChunk &left,
const BlockLayoutChunk &right) {
220 if (left.Alignment != right.Alignment)
221 return left.Alignment > right.Alignment;
223 auto getPrefOrder = [](
const BlockLayoutChunk &chunk) {
224 if (chunk.Capture && chunk.Capture->isByRef())
233 return getPrefOrder(left) < getPrefOrder(right);
243 if (!recordType)
return true;
245 const auto *record = cast<CXXRecordDecl>(recordType->
getDecl());
248 if (!record->hasTrivialDestructor())
return false;
249 if (record->hasNonTrivialCopyConstructor())
return false;
253 return !record->hasMutableFields();
282 if (!init)
return nullptr;
304 assert(elementTypes.empty());
306 elementTypes.push_back(CGM.
IntTy);
307 elementTypes.push_back(CGM.
IntTy);
344 "Can't capture 'this' outside a method");
350 std::pair<CharUnits,CharUnits> tinfo
352 maxFieldAlign = std::max(maxFieldAlign, tinfo.second);
354 layout.push_back(BlockLayoutChunk(tinfo.second, tinfo.first,
360 for (
const auto &CI : block->
captures()) {
361 const VarDecl *variable = CI.getVariable();
369 maxFieldAlign = std::max(maxFieldAlign, align);
413 }
else if (CI.hasCopyExpr()) {
421 if (!record->hasTrivialDestructor()) {
432 maxFieldAlign = std::max(maxFieldAlign, align);
437 layout.push_back(BlockLayoutChunk(align, size, lifetime, &CI, llvmType));
441 if (layout.empty()) {
451 std::stable_sort(layout.begin(), layout.end());
475 if (endAlign < maxFieldAlign) {
477 li = layout.begin() + 1, le = layout.end();
481 for (; li != le && endAlign < li->Alignment; ++li)
488 for (; li != le; ++li) {
489 assert(endAlign >= li->Alignment);
491 li->setIndex(info, elementTypes.size(), blockSize);
492 elementTypes.push_back(li->Type);
493 blockSize += li->Size;
497 if (endAlign >= maxFieldAlign) {
502 layout.erase(first, li);
506 assert(endAlign ==
getLowBit(blockSize));
510 if (endAlign < maxFieldAlign) {
512 CharUnits padding = newBlockSize - blockSize;
520 elementTypes.push_back(llvm::ArrayType::get(CGM.
Int8Ty,
522 blockSize = newBlockSize;
526 assert(endAlign >= maxFieldAlign);
527 assert(endAlign ==
getLowBit(blockSize));
532 li = layout.begin(), le = layout.end(); li != le; ++li) {
533 if (endAlign < li->Alignment) {
537 CharUnits padding = li->Alignment - endAlign;
538 elementTypes.push_back(llvm::ArrayType::get(CGM.
Int8Ty,
540 blockSize += padding;
543 assert(endAlign >= li->Alignment);
544 li->setIndex(info, elementTypes.size(), blockSize);
545 elementTypes.push_back(li->Type);
546 blockSize += li->Size;
571 if (blockInfo.CanBeGlobal)
return;
575 blockInfo.BlockAlign,
"block");
578 if (!blockInfo.NeedsCopyDispose)
return;
582 for (
const auto &CI : block->
captures()) {
585 if (CI.isByRef())
continue;
588 const VarDecl *variable = CI.getVariable();
613 if (!blockInfo.DominatingIP)
614 blockInfo.DominatingIP = cast<llvm::Instruction>(addr.
getPointer());
618 if (useArrayEHCleanup)
622 destroyer, useArrayEHCleanup);
636 i = cleanups.begin(), e = cleanups.end(); i != e; ++i) {
645 assert(head && *head);
660 assert(head &&
"destroying an empty chain");
665 }
while (head !=
nullptr);
675 blockInfo.BlockExpression = blockExpr;
680 std::unique_ptr<CGBlockInfo> blockInfo;
684 blockInfo->BlockExpression = blockExpr;
691 llvm::Constant *blockFn
695 blockFn = llvm::ConstantExpr::getBitCast(blockFn,
VoidPtrTy);
704 isa = llvm::ConstantExpr::getBitCast(isa,
VoidPtrTy);
710 assert(blockAddr.
isValid() &&
"block has no address!");
734 auto addHeaderField =
736 storeField(value, index, offset, name);
742 addHeaderField(llvm::ConstantInt::get(
IntTy, flags.getBitMask()),
744 addHeaderField(llvm::ConstantInt::get(
IntTy, 0),
756 "block.captured-this.addr");
761 for (
const auto &CI : blockDecl->
captures()) {
762 const VarDecl *variable = CI.getVariable();
787 "block.capture.addr");
796 auto it = LocalDeclMap.find(variable);
797 if (it != LocalDeclMap.end()) {
801 const_cast<VarDecl *>(variable),
824 }
else if (
const Expr *copyExpr = CI.getCopyExpr()) {
869 DeclRefExpr declRef(const_cast<VarDecl *>(variable),
902 if (BlockDescriptorType)
903 return BlockDescriptorType;
922 BlockDescriptorType =
924 UnsignedLongTy, UnsignedLongTy,
nullptr);
927 BlockDescriptorType = llvm::PointerType::getUnqual(BlockDescriptorType);
928 return BlockDescriptorType;
932 if (GenericBlockLiteralType)
933 return GenericBlockLiteralType;
944 GenericBlockLiteralType =
947 BlockDescPtrTy,
nullptr);
949 return GenericBlockLiteralType;
992 llvm::Type *BlockFTyPtr = llvm::PointerType::getUnqual(BlockFTy);
996 return EmitCall(FnInfo, Func, ReturnValue, Args);
1001 assert(
BlockInfo &&
"evaluating block ref without block information?");
1005 if (capture.
isConstant())
return LocalDeclMap.find(variable)->second;
1009 capture.
getOffset(),
"block.capture.addr");
1018 auto byrefPointerType = llvm::PointerType::get(byrefInfo.Type, 0);
1042 llvm::Constant *blockFn;
1050 blockFn = llvm::ConstantExpr::getBitCast(blockFn,
VoidPtrTy);
1057 llvm::Constant *blockFn) {
1073 fields[2] = llvm::Constant::getNullValue(CGM.
IntTy);
1076 fields[3] = blockFn;
1081 llvm::Constant *init = llvm::ConstantStruct::getAnon(fields);
1083 llvm::GlobalVariable *literal =
1084 new llvm::GlobalVariable(CGM.
getModule(),
1089 "__block_literal_global");
1095 return llvm::ConstantExpr::getBitCast(literal, requiredType);
1101 assert(
BlockInfo &&
"not emitting prologue of block invocation function?!");
1115 DI->EmitDeclareOfBlockLiteralArgVariable(*
BlockInfo, arg, argNum,
1131 assert(
BlockInfo &&
"not in a block invocation function!");
1140 bool IsLambdaConversionToBlock) {
1152 for (DeclMapTy::const_iterator i = ldm.begin(), e = ldm.end(); i != e; ++i) {
1153 const auto *var = dyn_cast<
VarDecl>(i->first);
1154 if (var && !var->hasLocalStorage())
1155 setAddrOfLocalVar(var, i->second);
1170 args.push_back(&selfDecl);
1222 for (
const auto &CI : blockDecl->
captures()) {
1223 const VarDecl *variable = CI.getVariable();
1233 setAddrOfLocalVar(variable, alloca);
1237 llvm::BasicBlock *entry =
Builder.GetInsertBlock();
1241 if (IsLambdaConversionToBlock)
1250 llvm::BasicBlock *resume =
Builder.GetInsertBlock();
1254 Builder.SetInsertPoint(entry, entry_ptr);
1259 for (
const auto &CI : blockDecl->
captures()) {
1260 const VarDecl *variable = CI.getVariable();
1267 auto addr = LocalDeclMap.find(variable)->second;
1268 DI->EmitDeclareOfAutoVariable(variable, addr.getPointer(),
1273 DI->EmitDeclareOfBlockDeclRefVariable(
1274 variable, BlockPointerDbgLoc,
Builder, blockInfo,
1275 entry_ptr == entry->end() ?
nullptr : &*entry_ptr);
1280 cast<CompoundStmt>(blockDecl->
getBody())->getRBracLoc());
1284 if (resume ==
nullptr)
1285 Builder.ClearInsertionPoint();
1287 Builder.SetInsertPoint(resume);
1327 args.push_back(&dstDecl);
1330 args.push_back(&srcDecl);
1339 llvm::Function *Fn =
1372 for (
const auto &CI : blockDecl->
captures()) {
1373 const VarDecl *variable = CI.getVariable();
1379 const Expr *copyExpr = CI.getCopyExpr();
1382 bool useARCWeakCopy =
false;
1383 bool useARCStrongCopy =
false;
1386 assert(!CI.isByRef());
1389 }
else if (CI.isByRef()) {
1405 useARCWeakCopy =
true;
1412 if (!isBlockPointer)
1413 useARCStrongCopy =
true;
1430 unsigned index = capture.
getIndex();
1437 }
else if (useARCWeakCopy) {
1441 if (useARCStrongCopy) {
1446 auto *ty = cast<llvm::PointerType>(srcValue->getType());
1447 llvm::Value *null = llvm::ConstantPointerNull::get(ty);
1459 cast<llvm::Instruction>(dstField.
getPointer())->eraseFromParent();
1469 bool copyCanThrow =
false;
1471 const Expr *copyExpr =
1474 copyCanThrow =
true;
1489 return llvm::ConstantExpr::getBitCast(Fn,
VoidPtrTy);
1506 args.push_back(&srcDecl);
1515 llvm::Function *Fn =
1545 for (
const auto &CI : blockDecl->
captures()) {
1546 const VarDecl *variable = CI.getVariable();
1555 bool useARCWeakDestroy =
false;
1556 bool useARCStrongDestroy =
false;
1563 if (record->hasTrivialDestructor())
1565 dtor = record->getDestructor();
1577 useARCStrongDestroy =
true;
1581 useARCWeakDestroy =
true;
1603 }
else if (useARCWeakDestroy) {
1607 }
else if (useARCStrongDestroy) {
1624 return llvm::ConstantExpr::getBitCast(Fn,
VoidPtrTy);
1660 void profileImpl(llvm::FoldingSetNodeID &
id)
const override {
1661 id.AddInteger(Flags.getBitMask());
1679 void profileImpl(llvm::FoldingSetNodeID &
id)
const override {
1699 llvm::ConstantPointerNull::get(cast<llvm::PointerType>(value->getType()));
1715 void profileImpl(llvm::FoldingSetNodeID &
id)
const override {
1725 ARCStrongBlockByrefHelpers(
CharUnits alignment)
1742 void profileImpl(llvm::FoldingSetNodeID &
id)
const override {
1752 const Expr *CopyExpr;
1756 const Expr *copyExpr)
1759 bool needsCopy()
const override {
return CopyExpr !=
nullptr; }
1762 if (!CopyExpr)
return;
1772 void profileImpl(llvm::FoldingSetNodeID &
id)
const override {
1773 id.AddPointer(VarType.getCanonicalType().getAsOpaquePtr());
1778 static llvm::Constant *
1788 args.push_back(&dst);
1792 args.push_back(&src);
1801 llvm::Function *Fn =
1806 = &Context.
Idents.
get(
"__Block_byref_object_copy_");
1838 generator.
emitCopy(CGF, destField, srcField);
1843 return llvm::ConstantExpr::getBitCast(Fn, CGF.
Int8PtrTy);
1855 static llvm::Constant *
1865 args.push_back(&src);
1874 llvm::Function *Fn =
1876 "__Block_byref_object_dispose_",
1880 = &Context.
Idents.
get(
"__Block_byref_object_dispose_");
1896 auto byrefPtrType = byrefInfo.
Type->getPointerTo(0);
1905 return llvm::ConstantExpr::getBitCast(Fn, CGF.
Int8PtrTy);
1921 llvm::FoldingSetNodeID
id;
1922 generator.Profile(
id);
1927 if (node)
return static_cast<T*
>(node);
1932 T *copy =
new (CGM.
getContext()) T(std::move(generator));
1941 CodeGenFunction::buildByrefHelpers(llvm::StructType &byrefType,
1942 const AutoVarEmission &emission) {
1943 const VarDecl &var = *emission.Variable;
1955 if (!copyExpr && record->hasTrivialDestructor())
return nullptr;
1958 CGM, byrefInfo, CXXByrefHelpers(valueAlignment, type, copyExpr));
1981 ARCWeakByrefHelpers(valueAlignment));
1989 ARCStrongBlockByrefHelpers(valueAlignment));
1995 ARCStrongByrefHelpers(valueAlignment));
1998 llvm_unreachable(
"fell out of lifetime switch!");
2015 ObjectByrefHelpers(valueAlignment, flags));
2020 bool followForward) {
2028 const llvm::Twine &name) {
2030 if (followForward) {
2056 auto it = BlockByrefInfos.find(D);
2057 if (it != BlockByrefInfos.end())
2060 llvm::StructType *byrefType =
2074 types.push_back(llvm::PointerType::getUnqual(byrefType));
2087 if (hasCopyAndDispose) {
2097 bool HasByrefExtendedLayout =
false;
2099 if (
getContext().getByrefLifetime(Ty, Lifetime, HasByrefExtendedLayout) &&
2100 HasByrefExtendedLayout) {
2109 bool packed =
false;
2114 if (varOffset != size) {
2116 llvm::ArrayType::get(
Int8Ty, (varOffset - size).getQuantity());
2118 types.push_back(paddingTy);
2126 types.push_back(varTy);
2128 byrefType->setBody(types, packed);
2131 info.
Type = byrefType;
2136 auto pair = BlockByrefInfos.insert({D, info});
2137 assert(pair.second &&
"info was inserted recursively?");
2138 return pair.first->second;
2148 llvm::StructType *byrefType = cast<llvm::StructType>(
2151 unsigned nextHeaderIndex = 0;
2154 const Twine &name) {
2156 nextHeaderOffset, name);
2160 nextHeaderOffset += fieldSize;
2166 const VarDecl &D = *emission.Variable;
2169 bool HasByrefExtendedLayout;
2171 bool ByRefHasLifetime =
2191 if (ByRefHasLifetime) {
2193 else switch (ByrefLifetime) {
2211 printf(
"\n Inline flag for BYREF variable layout (%d):", flags.getBitMask());
2213 printf(
" BLOCK_BYREF_HAS_COPY_DISPOSE");
2217 printf(
" BLOCK_BYREF_LAYOUT_EXTENDED");
2219 printf(
" BLOCK_BYREF_LAYOUT_STRONG");
2221 printf(
" BLOCK_BYREF_LAYOUT_WEAK");
2223 printf(
" BLOCK_BYREF_LAYOUT_UNRETAINED");
2225 printf(
" BLOCK_BYREF_LAYOUT_NON_OBJECT");
2230 storeHeaderField(llvm::ConstantInt::get(
IntTy, flags.getBitMask()),
2234 V = llvm::ConstantInt::get(
IntTy, byrefSize.getQuantity());
2235 storeHeaderField(V,
getIntSize(),
"byref.size");
2239 "byref.copyHelper");
2241 "byref.disposeHelper");
2244 if (ByRefHasLifetime && HasByrefExtendedLayout) {
2263 CallBlockRelease(
llvm::Value *Addr) : Addr(Addr) {}
2287 llvm::Constant *C) {
2288 if (!CGM.
getLangOpts().BlocksRuntimeOptional)
return;
2290 auto *GV = cast<llvm::GlobalValue>(C->stripPointerCasts());
2291 if (GV->isDeclaration() && GV->hasExternalLinkage())
2292 GV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage);
2296 if (BlockObjectDispose)
2297 return BlockObjectDispose;
2300 llvm::FunctionType *fty
2301 = llvm::FunctionType::get(
VoidTy, args,
false);
2302 BlockObjectDispose = CreateRuntimeFunction(fty,
"_Block_object_dispose");
2304 return BlockObjectDispose;
2308 if (BlockObjectAssign)
2309 return BlockObjectAssign;
2312 llvm::FunctionType *fty
2313 = llvm::FunctionType::get(
VoidTy, args,
false);
2314 BlockObjectAssign = CreateRuntimeFunction(fty,
"_Block_object_assign");
2316 return BlockObjectAssign;
2320 if (NSConcreteGlobalBlock)
2321 return NSConcreteGlobalBlock;
2323 NSConcreteGlobalBlock = GetOrCreateLLVMGlobal(
"_NSConcreteGlobalBlock",
2327 return NSConcreteGlobalBlock;
2331 if (NSConcreteStackBlock)
2332 return NSConcreteStackBlock;
2334 NSConcreteStackBlock = GetOrCreateLLVMGlobal(
"_NSConcreteStackBlock",
2338 return NSConcreteStackBlock;
void enterNonTrivialFullExpression(const ExprWithCleanups *E)
Enter a full-expression with a non-trivial number of objects to clean up.
ReturnValueSlot - Contains the address where the return value of a function can be stored...
Information about the layout of a __block variable.
Address EmitLoadOfReference(Address Ref, const ReferenceType *RefTy, AlignmentSource *Source=nullptr)
llvm::Constant * GenerateCopyHelperFunction(const CGBlockInfo &blockInfo)
Generate the copy-helper function for a block closure object: static void block_copy_helper(block_t *...
static llvm::Constant * generateByrefDisposeHelper(CodeGenFunction &CGF, const BlockByrefInfo &byrefInfo, BlockByrefHelpers &generator)
Generate code for a __block variable's dispose helper.
FunctionDecl - An instance of this class is created to represent a function declaration or definition...
llvm::Value * BlockPointer
CK_LValueToRValue - A conversion which causes the extraction of an r-value from the operand gl-value...
llvm::IntegerType * IntTy
int
llvm::Type * getGenericBlockLiteralType()
The type of a generic block literal.
void ActivateCleanupBlock(EHScopeStack::stable_iterator Cleanup, llvm::Instruction *DominatingIP)
ActivateCleanupBlock - Activates an initially-inactive cleanup.
void EmitCallArgs(CallArgList &Args, const T *CallArgTypeInfo, llvm::iterator_range< CallExpr::const_arg_iterator > ArgRange, const FunctionDecl *CalleeDecl=nullptr, unsigned ParamsToSkip=0)
EmitCallArgs - Emit call arguments for a function.
StringRef getName() const
getName - Get the name of identifier for this declaration as a StringRef.
CharUnits BlockHeaderForcedGapOffset
static llvm::Constant * buildByrefDisposeHelper(CodeGenModule &CGM, const BlockByrefInfo &byrefInfo, BlockByrefHelpers &generator)
Build the dispose helper for a __block variable.
A class which contains all the information about a particular captured value.
Destroyer * getDestroyer(QualType::DestructionKind destructionKind)
A (possibly-)qualified type.
CodeGenTypes & getTypes()
llvm::Type * ConvertTypeForMem(QualType T)
CharUnits getDeclAlign(const Decl *D, bool ForAlignof=false) const
Return a conservative estimate of the alignment of the specified decl D.
DestructionKind isDestructedType() const
Returns a nonzero value if objects of this type require non-trivial work to clean up after...
llvm::Module & getModule() const
llvm::LLVMContext & getLLVMContext()
void EmitARCDestroyWeak(Address addr)
void @objc_destroyWeak(i8** addr) Essentially objc_storeWeak(addr, nil).
llvm::Constant * CopyHelper
FunctionType - C99 6.7.5.3 - Function Declarators.
CharUnits getOffset() const
static T * buildByrefHelpers(CodeGenModule &CGM, const BlockByrefInfo &byrefInfo, T &&generator)
Lazily build the copy and dispose helpers for a __block variable with the given information.
llvm::AllocaInst * CreateTempAlloca(llvm::Type *Ty, const Twine &Name="tmp")
CreateTempAlloca - This creates a alloca and inserts it into the entry block.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
Address getAddress() const
param_iterator param_end()
std::string getObjCEncodingForBlock(const BlockExpr *blockExpr) const
Return the encoded type for this block declaration.
static llvm::Constant * buildBlockDescriptor(CodeGenModule &CGM, const CGBlockInfo &blockInfo)
buildBlockDescriptor - Build the block descriptor meta-data for a block.
const llvm::DataLayout & getDataLayout() const
llvm::Value * LoadCXXThis()
LoadCXXThis - Load the value of 'this'.
Emit only debug info necessary for generating line number tables (-gline-tables-only).
const Expr * getInit() const
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
void EmitARCCopyWeak(Address dst, Address src)
void @objc_copyWeak(i8** dest, i8** src) Disregards the current value in dest.
const LangOptions & getLangOpts() const
bool isBlockPointerType() const
llvm::Value * EmitARCRetainNonBlock(llvm::Value *value)
Retain the given object, with normal retain semantics.
const CGFunctionInfo & arrangeFreeFunctionDeclaration(QualType ResTy, const FunctionArgList &Args, const FunctionType::ExtInfo &Info, bool isVariadic)
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64
uint32_t getBitMask() const
Address GetAddrOfLocalVar(const VarDecl *VD)
GetAddrOfLocalVar - Return the address of a local variable.
VarDecl - An instance of this class is created to represent a variable declaration or definition...
CGBlockInfo(const BlockDecl *blockDecl, StringRef Name)
bool capturesCXXThis() const
const Expr * getCallee() const
ObjCLifetime getObjCLifetime() const
bool hasCaptures() const
hasCaptures - True if this block (or its nested blocks) captures anything of local storage from its e...
const FunctionProtoType * getFunctionType() const
getFunctionType - Return the underlying function type for this block.
This class gathers all debug information during compilation and is responsible for emitting to llvm g...
CharUnits GetTargetTypeStoreSize(llvm::Type *Ty) const
Return the store size, in character units, of the given LLVM type.
virtual llvm::Constant * BuildRCBlockLayout(CodeGen::CodeGenModule &CGM, const CodeGen::CGBlockInfo &blockInfo)=0
llvm::Type * ConvertTypeForMem(QualType T)
ConvertTypeForMem - Convert type T into a llvm::Type.
capture_iterator capture_begin()
Represents an expression – generally a full-expression – that introduces cleanups to be run at the en...
bool isObjCRetainableType() const
static void destroyBlockInfos(CGBlockInfo *info)
Destroy a chain of block layouts.
The collection of all-type qualifiers we support.
llvm::Constant * getPointer() const
One of these records is kept for each identifier that is lexed.
void emitByrefStructureInit(const AutoVarEmission &emission)
Initialize the structural components of a __block variable, i.e.
CGBlockInfo * FirstBlockInfo
FirstBlockInfo - The head of a singly-linked-list of block layouts.
class LLVM_ALIGNAS(8) DependentTemplateSpecializationType const IdentifierInfo * Name
Represents a template specialization type whose template cannot be resolved, e.g. ...
CGDebugInfo * getDebugInfo()
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
llvm::Type * ConvertType(QualType T)
ConvertType - Convert type T into a llvm::Type.
CharUnits getIntSize() const
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
void EmitExprAsInit(const Expr *init, const ValueDecl *D, LValue lvalue, bool capturedByInit)
EmitExprAsInit - Emits the code necessary to initialize a location in memory with the given initializ...
bool HasCapturedVariableLayout
HasCapturedVariableLayout : True if block has captured variables and their layout meta-data has been ...
bool isReferenceType() const
const Stmt * getBody() const
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
static llvm::Constant * generateByrefCopyHelper(CodeGenFunction &CGF, const BlockByrefInfo &byrefInfo, BlockByrefHelpers &generator)
Stmt * getBody() const override
getBody - If this Decl represents a declaration for a body of code, such as a function or method defi...
static bool isSafeForCXXConstantCapture(QualType type)
Determines if the given type is safe for constant capture in C++.
RValue EmitCall(const CGFunctionInfo &FnInfo, llvm::Value *Callee, ReturnValueSlot ReturnValue, const CallArgList &Args, CGCalleeInfo CalleeInfo=CGCalleeInfo(), llvm::Instruction **callOrInvoke=nullptr)
EmitCall - Generate a call of the given function, expecting the given result type, and using the given argument list which specifies both the LLVM arguments and the types they were derived from.
An r-value expression (a pr-value in the C++11 taxonomy) produces a temporary value.
static ApplyDebugLocation CreateArtificial(CodeGenFunction &CGF)
Apply TemporaryLocation if it is valid.
const Capture & getCapture(const VarDecl *var) const
llvm::Value * EmitARCStoreStrongCall(Address addr, llvm::Value *value, bool resultIgnored)
Store into a strong object.
Address GetAddrOfBlockDecl(const VarDecl *var, bool ByRef)
const LangOptions & getLangOpts() const
CharUnits - This is an opaque type for sizes expressed in character units.
void EmitARCDestroyStrong(Address addr, ARCPreciseLifetime_t precise)
Destroy a __strong variable.
static Capture makeIndex(unsigned index, CharUnits offset)
QualType getReturnType() const
bool HasCXXObject
HasCXXObject - True if the block's custom copy/dispose functions need to be run even in GC mode...
llvm::Value * EmitBlockLiteral(const BlockExpr *)
Emit a block literal expression in the current function.
llvm::PointerType * VoidPtrTy
bool getByrefLifetime(QualType Ty, Qualifiers::ObjCLifetime &Lifetime, bool &HasByrefExtendedLayout) const
Returns true, if given type has a known lifetime.
bool needsEHCleanup(QualType::DestructionKind kind)
Determines whether an EH cleanup is required to destroy a type with the given destruction kind...
RecordDecl * getDecl() const
CharUnits getPointerSize() const
std::string getNameAsString() const
getNameAsString - Get a human-readable name for the declaration, even if it is one of the special kin...
Scope - A scope is a transient data structure that is used while parsing the program.
llvm::PointerType * VoidPtrPtrTy
void incrementProfileCounter(const Stmt *S)
Increment the profiler's counter for the given statement.
void EmitStmt(const Stmt *S)
EmitStmt - Emit the code for the statement.
void assignRegionCounters(GlobalDecl GD, llvm::Function *Fn)
Assign counters to regions and configure them for PGO of a given function.
static Capture makeConstant(llvm::Value *value)
GlobalDecl CurGD
CurGD - The GlobalDecl for the current function being compiled.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
llvm::Constant * getNSConcreteStackBlock()
std::pair< CharUnits, CharUnits > getTypeInfoInChars(const Type *T) const
static FunctionDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation NLoc, DeclarationName N, QualType T, TypeSourceInfo *TInfo, StorageClass SC, bool isInlineSpecified=false, bool hasWrittenPrototype=true, bool isConstexprSpecified=false)
This object can be modified without requiring retains or releases.
bool NeedsCopyDispose
True if the block needs a custom copy or dispose function.
const BlockExpr * BlockExpression
llvm::CallSite EmitRuntimeCallOrInvoke(llvm::Value *callee, ArrayRef< llvm::Value * > args, const Twine &name="")
Emits a call or invoke instruction to the given runtime function.
LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource AlignSource=AlignmentSource::Type)
static llvm::Constant * buildCopyHelper(CodeGenModule &CGM, const CGBlockInfo &blockInfo)
Build the helper function to copy a block.
ExtInfo getExtInfo() const
Represents a prototype with parameter type info, e.g.
bool isConversionFromLambda() const
llvm::CallInst * EmitNounwindRuntimeCall(llvm::Value *callee, const Twine &name="")
const CodeGen::CGBlockInfo * BlockInfo
llvm::Function * GenerateBlockFunction(GlobalDecl GD, const CGBlockInfo &Info, const DeclMapTy &ldm, bool IsLambdaConversionToBlock)
Qualifiers::ObjCLifetime getObjCLifetime() const
Returns lifetime attribute of this type.
CGBlockInfo - Information to generate a block literal.
virtual void emitCopy(CodeGenFunction &CGF, Address dest, Address src)=0
unsigned getNumObjects() const
RValue - This trivial value class is used to represent the result of an expression that is evaluated...
bool CanBeGlobal
CanBeGlobal - True if the block can be global, i.e.
SourceLocation getLocEnd() const LLVM_READONLY
StringRef getBlockMangledName(GlobalDecl GD, const BlockDecl *BD)
capture_iterator capture_end()
bool isObjCInertUnsafeUnretainedType() const
Was this type written with the special inert-in-MRC __unsafe_unretained qualifier?
CGBlockInfo * NextBlockInfo
The next block in the block-info chain.
CGObjCRuntime & getObjCRuntime()
Return a reference to the configured Objective-C runtime.
llvm::Value * getPointer() const
BlockDecl - This represents a block literal declaration, which is like an unnamed FunctionDecl...
QualType getPointeeType() const
unsigned getIndex() const
Expr - This represents one expression.
virtual bool needsCopy() const
void EmitARCMoveWeak(Address dst, Address src)
void @objc_moveWeak(i8** dest, i8** src) Disregards the current value in dest.
Enters a new scope for capturing cleanups, all of which will be executed once the scope is exited...
llvm::Constant * DisposeHelper
void SetInternalFunctionAttributes(const Decl *D, llvm::Function *F, const CGFunctionInfo &FI)
Set the attributes on the LLVM function for the given decl and function info.
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
Represents a C++ destructor within a class.
static llvm::Constant * buildGlobalBlock(CodeGenModule &CGM, const CGBlockInfo &blockInfo, llvm::Constant *blockFn)
Build the given block as a global block.
llvm::Constant * GenerateDestroyHelperFunction(const CGBlockInfo &blockInfo)
Generate the destroy-helper function for a block closure object: static void block_destroy_helper(blo...
TranslationUnitDecl * getTranslationUnitDecl() const
bool isObjCGCWeak() const
true when Type is objc's weak.
void EmitLambdaBlockInvokeBody()
ASTContext & getContext() const
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
internal::Matcher< T > id(StringRef ID, const internal::BindableMatcher< T > &InnerMatcher)
If the provided matcher matches a node, binds the node to ID.
void add(RValue rvalue, QualType type, bool needscopy=false)
stable_iterator stable_begin() const
Create a stable reference to the top of the EH stack.
llvm::LLVMContext & getLLVMContext()
bool ReturnSlotInterferesWithArgs(const CGFunctionInfo &FI)
Return true iff the given type uses an argument slot when 'sret' is used as a return type...
llvm::IntegerType * Int32Ty
bool isa(CodeGen::Address addr)
static OMPLinearClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, OpenMPLinearClauseKind Modifier, SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, ArrayRef< Expr * > PL, ArrayRef< Expr * > IL, Expr *Step, Expr *CalcStep)
Creates clause with a list of variables VL and a linear step Step.
static CharUnits getLowBit(CharUnits v)
Get the low bit of a nonzero character count.
static AggValueSlot forAddr(Address addr, Qualifiers quals, IsDestructed_t isDestructed, NeedsGCBarriers_t needsGC, IsAliased_t isAliased, IsZeroed_t isZeroed=IsNotZeroed)
forAddr - Make a slot for an aggregate value.
GlobalDecl - represents a global declaration.
EHScopeStack::stable_iterator getCleanup() const
virtual llvm::Constant * BuildByrefLayout(CodeGen::CodeGenModule &CGM, QualType T)=0
Returns an i8* which points to the byref layout information.
bool hasObjCLifetime() const
param_iterator param_begin()
The l-value was considered opaque, so the alignment was determined from a type.
void setBlockContextParameter(const ImplicitParamDecl *D, unsigned argNum, llvm::Value *ptr)
bool UsesStret
UsesStret : True if the block uses an stret return.
void enterByrefCleanup(const AutoVarEmission &emission)
Enter a cleanup to destroy a __block variable.
bool HaveInsertPoint() const
HaveInsertPoint - True if an insertion point is defined.
There is no lifetime qualification on this type.
Address CreateBitCast(Address Addr, llvm::Type *Ty, const llvm::Twine &Name="")
ArrayRef< CleanupObject > getObjects() const
Assigning into this object requires the old value to be released and the new value to be retained...
Expr * getBlockVarCopyInits(const VarDecl *VD)
Get the copy initialization expression of the VarDecl VD, or NULL if none exists. ...
void PushDestructorCleanup(QualType T, Address Addr)
PushDestructorCleanup - Push a cleanup to call the complete-object destructor of an object of the giv...
ASTContext & getContext() const
void pushDestroy(QualType::DestructionKind dtorKind, Address addr, QualType type)
pushDestroy - Push the standard destructor for the given type as at least a normal cleanup...
Encodes a location in the source.
CharUnits getPointerAlign() const
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
LValue EmitDeclRefLValue(const DeclRefExpr *E)
const TemplateArgument * iterator
A saved depth on the scope stack.
llvm::StructType * StructureType
static void configureBlocksRuntimeObject(CodeGenModule &CGM, llvm::Constant *C)
Adjust the declaration of something from the blocks API.
const BlockByrefInfo & getBlockByrefInfo(const VarDecl *var)
BuildByrefInfo - This routine changes a __block variable declared as T x into:
A scoped helper to set the current debug location to the specified location or preferred location of ...
llvm::DenseMap< const VarDecl *, Capture > Captures
The mapping of allocated indexes within the block.
const CodeGenOptions & getCodeGenOpts() const
const Type * getBaseElementTypeUnsafe() const
Get the base element type of this type, potentially discarding type qualifiers.
llvm::Constant * getBlockObjectDispose()
void StartFunction(GlobalDecl GD, QualType RetTy, llvm::Function *Fn, const CGFunctionInfo &FnInfo, const FunctionArgList &Args, SourceLocation Loc=SourceLocation(), SourceLocation StartLoc=SourceLocation())
Emit code for the start of a function.
const LangOptions & getLangOpts() const
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
const T * castAs() const
Member-template castAs<specific type>.
bool operator<(DeclarationName LHS, DeclarationName RHS)
Ordering on two declaration names.
virtual bool needsDispose() const
unsigned CXXThisIndex
The field index of 'this' within the block, if there is one.
Assigning into this object requires a lifetime extension.
const BlockDecl * getBlockDecl() const
static Destroyer destroyARCStrongImprecise
void FinishFunction(SourceLocation EndLoc=SourceLocation())
FinishFunction - Complete IR generation of the current function.
const CGFunctionInfo & arrangeBlockFunctionCall(const CallArgList &args, const FunctionType *type)
A block function call is essentially a free-function call with an extra implicit argument.
ConstantAddress GetAddrOfConstantCString(const std::string &Str, const char *GlobalName=nullptr)
Returns a pointer to a character array containing the literal and a terminating '\0' character...
llvm::Value * EmitScalarExpr(const Expr *E, bool IgnoreResultAssign=false)
EmitScalarExpr - Emit the computation of the specified expression of LLVM scalar type, returning the result.
FunctionArgList - Type for representing both the decl and type of parameters to a function...
static llvm::Constant * tryCaptureAsConstant(CodeGenModule &CGM, CodeGenFunction *CGF, const VarDecl *var)
It is illegal to modify a const object after initialization.
CGFunctionInfo - Class to encapsulate the information about a function definition.
This class organizes the cross-function state that is used while generating LLVM code.
const unsigned BlockHeaderSize
The number of fields in a block header.
static const Type * getElementType(const Expr *BaseExpr)
virtual llvm::Constant * BuildGCBlockLayout(CodeGen::CodeGenModule &CGM, const CodeGen::CGBlockInfo &blockInfo)=0
Address LoadBlockStruct()
static void computeBlockInfo(CodeGenModule &CGM, CodeGenFunction *CGF, CGBlockInfo &info)
Compute the layout of the given block.
llvm::FoldingSet< BlockByrefHelpers > ByrefHelpersCache
Address CreateMemTemp(QualType T, const Twine &Name="tmp")
CreateMemTemp - Create a temporary memory object of the given type, with appropriate alignment...
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
Address CreateStructGEP(Address Addr, unsigned Index, CharUnits Offset, const llvm::Twine &Name="")
llvm::LoadInst * CreateAlignedLoad(llvm::Value *Addr, CharUnits Align, const llvm::Twine &Name="")
llvm::Value * getConstant() const
static llvm::Constant * buildDisposeHelper(CodeGenModule &CGM, const CGBlockInfo &blockInfo)
Build the helper function to dispose of a block.
std::unique_ptr< DiagnosticConsumer > create(StringRef OutputFile, DiagnosticOptions *Diags, bool MergeChildRecords=false)
Returns a DiagnosticConsumer that serializes diagnostics to a bitcode file.
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
detail::InMemoryDirectory::const_iterator E
llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)
void EmitAggExpr(const Expr *E, AggValueSlot AS)
EmitAggExpr - Emit the computation of the specified expression of aggregate type. ...
llvm::DenseMap< const Decl *, Address > DeclMapTy
static void enterBlockScope(CodeGenFunction &CGF, BlockDecl *block)
Enter the scope of a block.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
const T * getAs() const
Member-template getAs<specific type>'.
CharUnits getIntAlign() const
CanQualType UnsignedLongTy
static llvm::Constant * buildByrefCopyHelper(CodeGenModule &CGM, const BlockByrefInfo &byrefInfo, BlockByrefHelpers &generator)
Build the copy helper for a __block variable.
llvm::PointerType * Int8PtrTy
Base for LValueReferenceType and RValueReferenceType.
void EmitSynthesizedCXXCopyCtor(Address Dest, Address Src, const Expr *Exp)
static CGBlockInfo * findAndRemoveBlockInfo(CGBlockInfo **head, const BlockDecl *block)
Find the layout for the given block in a linked list and remove it.
llvm::Constant * GetAddrOfGlobalBlock(const BlockExpr *BE, const char *)
Gets the address of a block which requires no captures.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
virtual void emitDispose(CodeGenFunction &CGF, Address field)=0
Internal linkage, which indicates that the entity can be referred to from within the translation unit...
llvm::Constant * getBlockObjectAssign()
llvm::Constant * EmitConstantInit(const VarDecl &D, CodeGenFunction *CGF=nullptr)
Try to emit the initializer for the given declaration as a constant; returns 0 if the expression cann...
const Decl * CurFuncDecl
CurFuncDecl - Holds the Decl for the current outermost non-closure context.
A pair of helper functions for a __block variable.
Reading or writing from this object requires a barrier call.
static void initializeForBlockHeader(CodeGenModule &CGM, CGBlockInfo &info, SmallVectorImpl< llvm::Type * > &elementTypes)
Represents a C++ struct/union/class.
CharUnits alignmentAtOffset(CharUnits offset) const
Given that this is a non-zero alignment value, what is the alignment at the given offset...
bool isObjCObjectPointerType() const
llvm::Type * ConvertType(QualType T)
uint32_t getBitMask() const
void PopCleanupBlocks(EHScopeStack::stable_iterator OldCleanupStackSize)
Takes the old cleanup stack size and emits the cleanup blocks that have been added.
const BlockDecl * getBlockDecl() const
virtual ~BlockByrefHelpers()
CharUnits BlockHeaderForcedGapSize
llvm::Value * EmitARCRetainBlock(llvm::Value *value, bool mandatory)
Retain the given block, with _Block_copy semantics.
void ForceCleanup()
Force the emission of cleanups now, instead of waiting until this object is destroyed.
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
unsigned getTargetAddressSpace(QualType T) const
A reference to a declared variable, function, enum, etc.
static RValue get(llvm::Value *V)
RValue EmitBlockCallExpr(const CallExpr *E, ReturnValueSlot ReturnValue)
static ApplyDebugLocation CreateEmpty(CodeGenFunction &CGF)
Set the IRBuilder to not attach debug locations.
llvm::Constant * getNSConcreteGlobalBlock()
llvm::Type * getBlockDescriptorType()
Fetches the type of a generic block descriptor.
An l-value expression is a reference to an object with independent storage.
const BlockExpr * getBlockExpr() const
SourceLocation getLocation() const
Information for lazily generating a cleanup.
llvm::Instruction * DominatingIP
An instruction which dominates the full-expression that the block is inside.
bool isConstQualified() const
Determine whether this type is const-qualified.
static bool isObjCNSObjectType(QualType Ty)
Return true if this is an NSObject object with its NSObject attribute set.
CharUnits RoundUpToAlignment(const CharUnits &Align) const
RoundUpToAlignment - Returns the next integer (mod 2**64) that is greater than or equal to this quant...
CallArgList - Type for representing both the value and type of arguments in a call.
Address emitBlockByrefAddress(Address baseAddr, const VarDecl *V, bool followForward=true)
BuildBlockByrefAddress - Computes the location of the data in a variable which is declared as __block...
A class which abstracts out some details necessary for making a call.
bool BlockRequiresCopying(QualType Ty, const VarDecl *D)
Returns true iff we need copy/dispose helpers for the given type.
void BuildBlockRelease(llvm::Value *DeclPtr, BlockFieldFlags flags)
void setCleanup(EHScopeStack::stable_iterator cleanup)
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
void Destroyer(CodeGenFunction &CGF, Address addr, QualType ty)
unsigned char PointerSizeInBytes
llvm::FunctionType * GetFunctionType(const CGFunctionInfo &Info)
GetFunctionType - Get the LLVM function type for.