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 unsigned AddrSpace = 0;
131 llvm::GlobalVariable *global =
132 new llvm::GlobalVariable(CGM.
getModule(), init->getType(),
true,
134 init,
"__block_descriptor_tmp",
nullptr,
135 llvm::GlobalValue::NotThreadLocal,
154 struct objc_class *isa;
181 _ResultType (*invoke)(Block_literal *, _ParamTypes...);
184 struct Block_descriptor *block_descriptor;
187 _CapturesTypes captures...;
196 struct BlockLayoutChunk {
207 : Alignment(align), Size(size), Lifetime(lifetime),
208 Capture(capture),
Type(type) {}
216 info.
Captures.insert({Capture->getVariable(),
224 bool operator<(
const BlockLayoutChunk &left,
const BlockLayoutChunk &right) {
225 if (left.Alignment != right.Alignment)
226 return left.Alignment > right.Alignment;
228 auto getPrefOrder = [](
const BlockLayoutChunk &chunk) {
229 if (chunk.Capture && chunk.Capture->isByRef())
238 return getPrefOrder(left) < getPrefOrder(right);
248 if (!recordType)
return true;
250 const auto *record = cast<CXXRecordDecl>(recordType->
getDecl());
253 if (!record->hasTrivialDestructor())
return false;
254 if (record->hasNonTrivialCopyConstructor())
return false;
258 return !record->hasMutableFields();
272 if (isa<ParmVarDecl>(var))
292 if (!init)
return nullptr;
314 assert(elementTypes.empty());
316 elementTypes.push_back(CGM.
IntTy);
317 elementTypes.push_back(CGM.
IntTy);
354 "Can't capture 'this' outside a method");
360 std::pair<CharUnits,CharUnits> tinfo
362 maxFieldAlign =
std::max(maxFieldAlign, tinfo.second);
364 layout.push_back(BlockLayoutChunk(tinfo.second, tinfo.first,
370 for (
const auto &CI : block->
captures()) {
371 const VarDecl *variable = CI.getVariable();
379 maxFieldAlign =
std::max(maxFieldAlign, align);
423 }
else if (CI.hasCopyExpr()) {
431 if (!record->hasTrivialDestructor()) {
442 maxFieldAlign =
std::max(maxFieldAlign, align);
447 layout.push_back(BlockLayoutChunk(align, size, lifetime, &CI, llvmType));
451 if (layout.empty()) {
461 std::stable_sort(layout.begin(), layout.end());
485 if (endAlign < maxFieldAlign) {
487 li = layout.begin() + 1, le = layout.end();
491 for (; li != le && endAlign < li->Alignment; ++li)
498 for (; li != le; ++li) {
499 assert(endAlign >= li->Alignment);
501 li->setIndex(info, elementTypes.size(), blockSize);
502 elementTypes.push_back(li->Type);
503 blockSize += li->Size;
507 if (endAlign >= maxFieldAlign) {
512 layout.erase(first, li);
516 assert(endAlign ==
getLowBit(blockSize));
520 if (endAlign < maxFieldAlign) {
522 CharUnits padding = newBlockSize - blockSize;
530 elementTypes.push_back(llvm::ArrayType::get(CGM.
Int8Ty,
532 blockSize = newBlockSize;
536 assert(endAlign >= maxFieldAlign);
537 assert(endAlign ==
getLowBit(blockSize));
542 li = layout.begin(), le = layout.end(); li != le; ++li) {
543 if (endAlign < li->Alignment) {
547 CharUnits padding = li->Alignment - endAlign;
548 elementTypes.push_back(llvm::ArrayType::get(CGM.
Int8Ty,
550 blockSize += padding;
553 assert(endAlign >= li->Alignment);
554 li->setIndex(info, elementTypes.size(), blockSize);
555 elementTypes.push_back(li->Type);
556 blockSize += li->Size;
581 if (blockInfo.CanBeGlobal)
return;
585 blockInfo.BlockAlign,
"block");
588 if (!blockInfo.NeedsCopyDispose)
return;
592 for (
const auto &CI : block->
captures()) {
595 if (CI.isByRef())
continue;
598 const VarDecl *variable = CI.getVariable();
623 if (!blockInfo.DominatingIP)
624 blockInfo.DominatingIP = cast<llvm::Instruction>(addr.
getPointer());
628 if (useArrayEHCleanup)
632 destroyer, useArrayEHCleanup);
646 i = cleanups.begin(), e = cleanups.end(); i != e; ++i) {
655 assert(head && *head);
670 assert(head &&
"destroying an empty chain");
675 }
while (head !=
nullptr);
685 blockInfo.BlockExpression = blockExpr;
690 std::unique_ptr<CGBlockInfo> blockInfo;
694 blockInfo->BlockExpression = blockExpr;
701 llvm::Constant *blockFn
705 blockFn = llvm::ConstantExpr::getBitCast(blockFn,
VoidPtrTy);
714 isa = llvm::ConstantExpr::getBitCast(isa,
VoidPtrTy);
720 assert(blockAddr.
isValid() &&
"block has no address!");
744 auto addHeaderField =
746 storeField(value, index, offset, name);
752 addHeaderField(llvm::ConstantInt::get(
IntTy, flags.getBitMask()),
754 addHeaderField(llvm::ConstantInt::get(
IntTy, 0),
766 "block.captured-this.addr");
771 for (
const auto &CI : blockDecl->
captures()) {
772 const VarDecl *variable = CI.getVariable();
793 }
else if (CI.isByRef()) {
803 "block.capture.addr");
805 auto I = LocalDeclMap.find(variable);
806 assert(
I != LocalDeclMap.end());
810 DeclRefExpr declRef(const_cast<VarDecl *>(variable),
833 }
else if (
const Expr *copyExpr = CI.getCopyExpr()) {
877 DeclRefExpr declRef(const_cast<VarDecl *>(variable),
910 if (BlockDescriptorType)
911 return BlockDescriptorType;
930 BlockDescriptorType =
932 UnsignedLongTy, UnsignedLongTy,
nullptr);
935 unsigned AddrSpace = 0;
938 BlockDescriptorType = llvm::PointerType::get(BlockDescriptorType, AddrSpace);
939 return BlockDescriptorType;
943 if (GenericBlockLiteralType)
944 return GenericBlockLiteralType;
955 GenericBlockLiteralType =
958 BlockDescPtrTy,
nullptr);
960 return GenericBlockLiteralType;
1003 llvm::Type *BlockFTyPtr = llvm::PointerType::getUnqual(BlockFTy);
1007 return EmitCall(FnInfo, Func, ReturnValue, Args);
1012 assert(
BlockInfo &&
"evaluating block ref without block information?");
1016 if (capture.
isConstant())
return LocalDeclMap.find(variable)->second;
1020 capture.
getOffset(),
"block.capture.addr");
1029 auto byrefPointerType = llvm::PointerType::get(byrefInfo.Type, 0);
1053 llvm::Constant *blockFn;
1061 blockFn = llvm::ConstantExpr::getBitCast(blockFn,
VoidPtrTy);
1068 llvm::Constant *blockFn) {
1084 fields[2] = llvm::Constant::getNullValue(CGM.
IntTy);
1087 fields[3] = blockFn;
1092 llvm::Constant *init = llvm::ConstantStruct::getAnon(fields);
1094 llvm::GlobalVariable *literal =
1095 new llvm::GlobalVariable(CGM.
getModule(),
1100 "__block_literal_global");
1106 return llvm::ConstantExpr::getBitCast(literal, requiredType);
1112 assert(
BlockInfo &&
"not emitting prologue of block invocation function?!");
1125 DI->setLocation(D->getLocation());
1126 DI->EmitDeclareOfBlockLiteralArgVariable(*
BlockInfo, arg, argNum,
1142 assert(
BlockInfo &&
"not in a block invocation function!");
1151 bool IsLambdaConversionToBlock) {
1163 for (DeclMapTy::const_iterator i = ldm.begin(), e = ldm.end(); i != e; ++i) {
1164 const auto *var = dyn_cast<
VarDecl>(i->first);
1165 if (var && !var->hasLocalStorage())
1166 setAddrOfLocalVar(var, i->second);
1181 args.push_back(&selfDecl);
1202 blockDecl->getLocation(),
1232 for (
const auto &CI : blockDecl->
captures()) {
1233 const VarDecl *variable = CI.getVariable();
1243 setAddrOfLocalVar(variable, alloca);
1247 llvm::BasicBlock *entry =
Builder.GetInsertBlock();
1251 if (IsLambdaConversionToBlock)
1260 llvm::BasicBlock *resume =
Builder.GetInsertBlock();
1264 Builder.SetInsertPoint(entry, entry_ptr);
1269 for (
const auto &CI : blockDecl->
captures()) {
1270 const VarDecl *variable = CI.getVariable();
1271 DI->EmitLocation(
Builder, variable->getLocation());
1277 auto addr = LocalDeclMap.find(variable)->second;
1278 DI->EmitDeclareOfAutoVariable(variable, addr.getPointer(),
1283 DI->EmitDeclareOfBlockDeclRefVariable(
1284 variable, BlockPointerDbgLoc,
Builder, blockInfo,
1285 entry_ptr == entry->end() ?
nullptr : &*entry_ptr);
1290 cast<CompoundStmt>(blockDecl->
getBody())->getRBracLoc());
1294 if (resume ==
nullptr)
1295 Builder.ClearInsertionPoint();
1297 Builder.SetInsertPoint(resume);
1337 args.push_back(&dstDecl);
1340 args.push_back(&srcDecl);
1349 llvm::Function *Fn =
1382 for (
const auto &CI : blockDecl->
captures()) {
1383 const VarDecl *variable = CI.getVariable();
1389 const Expr *copyExpr = CI.getCopyExpr();
1392 bool useARCWeakCopy =
false;
1393 bool useARCStrongCopy =
false;
1396 assert(!CI.isByRef());
1399 }
else if (CI.isByRef()) {
1415 useARCWeakCopy =
true;
1422 if (!isBlockPointer)
1423 useARCStrongCopy =
true;
1440 unsigned index = capture.
getIndex();
1447 }
else if (useARCWeakCopy) {
1451 if (useARCStrongCopy) {
1456 auto *ty = cast<llvm::PointerType>(srcValue->getType());
1457 llvm::Value *null = llvm::ConstantPointerNull::get(ty);
1469 cast<llvm::Instruction>(dstField.
getPointer())->eraseFromParent();
1479 bool copyCanThrow =
false;
1481 const Expr *copyExpr =
1484 copyCanThrow =
true;
1499 return llvm::ConstantExpr::getBitCast(Fn,
VoidPtrTy);
1516 args.push_back(&srcDecl);
1525 llvm::Function *Fn =
1555 for (
const auto &CI : blockDecl->
captures()) {
1556 const VarDecl *variable = CI.getVariable();
1565 bool useARCWeakDestroy =
false;
1566 bool useARCStrongDestroy =
false;
1573 if (record->hasTrivialDestructor())
1575 dtor = record->getDestructor();
1587 useARCStrongDestroy =
true;
1591 useARCWeakDestroy =
true;
1613 }
else if (useARCWeakDestroy) {
1617 }
else if (useARCStrongDestroy) {
1634 return llvm::ConstantExpr::getBitCast(Fn,
VoidPtrTy);
1670 void profileImpl(llvm::FoldingSetNodeID &
id)
const override {
1671 id.AddInteger(Flags.getBitMask());
1689 void profileImpl(llvm::FoldingSetNodeID &
id)
const override {
1709 llvm::ConstantPointerNull::get(cast<llvm::PointerType>(value->getType()));
1725 void profileImpl(llvm::FoldingSetNodeID &
id)
const override {
1735 ARCStrongBlockByrefHelpers(
CharUnits alignment)
1752 void profileImpl(llvm::FoldingSetNodeID &
id)
const override {
1762 const Expr *CopyExpr;
1766 const Expr *copyExpr)
1769 bool needsCopy()
const override {
return CopyExpr !=
nullptr; }
1772 if (!CopyExpr)
return;
1782 void profileImpl(llvm::FoldingSetNodeID &
id)
const override {
1783 id.AddPointer(VarType.getCanonicalType().getAsOpaquePtr());
1788 static llvm::Constant *
1798 args.push_back(&dst);
1802 args.push_back(&src);
1811 llvm::Function *Fn =
1816 = &Context.
Idents.
get(
"__Block_byref_object_copy_");
1848 generator.
emitCopy(CGF, destField, srcField);
1853 return llvm::ConstantExpr::getBitCast(Fn, CGF.
Int8PtrTy);
1865 static llvm::Constant *
1875 args.push_back(&src);
1884 llvm::Function *Fn =
1886 "__Block_byref_object_dispose_",
1890 = &Context.
Idents.
get(
"__Block_byref_object_dispose_");
1906 auto byrefPtrType = byrefInfo.
Type->getPointerTo(0);
1915 return llvm::ConstantExpr::getBitCast(Fn, CGF.
Int8PtrTy);
1931 llvm::FoldingSetNodeID
id;
1932 generator.Profile(
id);
1937 if (node)
return static_cast<T*
>(node);
1942 T *copy =
new (CGM.
getContext()) T(std::move(generator));
1951 CodeGenFunction::buildByrefHelpers(llvm::StructType &byrefType,
1952 const AutoVarEmission &emission) {
1953 const VarDecl &var = *emission.Variable;
1965 if (!copyExpr && record->hasTrivialDestructor())
return nullptr;
1968 CGM, byrefInfo, CXXByrefHelpers(valueAlignment, type, copyExpr));
1991 ARCWeakByrefHelpers(valueAlignment));
1999 ARCStrongBlockByrefHelpers(valueAlignment));
2005 ARCStrongByrefHelpers(valueAlignment));
2008 llvm_unreachable(
"fell out of lifetime switch!");
2025 ObjectByrefHelpers(valueAlignment, flags));
2030 bool followForward) {
2038 const llvm::Twine &name) {
2040 if (followForward) {
2066 auto it = BlockByrefInfos.find(D);
2067 if (it != BlockByrefInfos.end())
2070 llvm::StructType *byrefType =
2084 types.push_back(llvm::PointerType::getUnqual(byrefType));
2097 if (hasCopyAndDispose) {
2107 bool HasByrefExtendedLayout =
false;
2109 if (
getContext().getByrefLifetime(Ty, Lifetime, HasByrefExtendedLayout) &&
2110 HasByrefExtendedLayout) {
2119 bool packed =
false;
2124 if (varOffset != size) {
2126 llvm::ArrayType::get(
Int8Ty, (varOffset - size).getQuantity());
2128 types.push_back(paddingTy);
2136 types.push_back(varTy);
2138 byrefType->setBody(types, packed);
2141 info.
Type = byrefType;
2146 auto pair = BlockByrefInfos.insert({D, info});
2147 assert(pair.second &&
"info was inserted recursively?");
2148 return pair.first->second;
2158 llvm::StructType *byrefType = cast<llvm::StructType>(
2159 cast<llvm::PointerType>(addr.
getPointer()->getType())->getElementType());
2161 unsigned nextHeaderIndex = 0;
2164 const Twine &name) {
2166 nextHeaderOffset, name);
2170 nextHeaderOffset += fieldSize;
2176 const VarDecl &D = *emission.Variable;
2179 bool HasByrefExtendedLayout;
2181 bool ByRefHasLifetime =
2201 if (ByRefHasLifetime) {
2203 else switch (ByrefLifetime) {
2221 printf(
"\n Inline flag for BYREF variable layout (%d):", flags.getBitMask());
2223 printf(
" BLOCK_BYREF_HAS_COPY_DISPOSE");
2227 printf(
" BLOCK_BYREF_LAYOUT_EXTENDED");
2229 printf(
" BLOCK_BYREF_LAYOUT_STRONG");
2231 printf(
" BLOCK_BYREF_LAYOUT_WEAK");
2233 printf(
" BLOCK_BYREF_LAYOUT_UNRETAINED");
2235 printf(
" BLOCK_BYREF_LAYOUT_NON_OBJECT");
2240 storeHeaderField(llvm::ConstantInt::get(
IntTy, flags.getBitMask()),
2244 V = llvm::ConstantInt::get(
IntTy, byrefSize.getQuantity());
2245 storeHeaderField(V,
getIntSize(),
"byref.size");
2249 "byref.copyHelper");
2251 "byref.disposeHelper");
2254 if (ByRefHasLifetime && HasByrefExtendedLayout) {
2273 CallBlockRelease(
llvm::Value *Addr) : Addr(Addr) {}
2297 llvm::Constant *C) {
2298 auto *GV = cast<llvm::GlobalValue>(C->stripPointerCasts());
2305 assert((isa<llvm::Function>(C->stripPointerCasts()) ||
2306 isa<llvm::GlobalVariable>(C->stripPointerCasts())) &&
2307 "expected Function or GlobalVariable");
2311 if ((ND = dyn_cast<FunctionDecl>(
Result)) ||
2316 if (GV->isDeclaration() && (!ND || !ND->hasAttr<DLLExportAttr>())) {
2317 GV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
2320 GV->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
2328 if (GV->isDeclaration() && GV->hasExternalLinkage())
2329 GV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage);
2333 if (BlockObjectDispose)
2334 return BlockObjectDispose;
2337 llvm::FunctionType *fty
2338 = llvm::FunctionType::get(
VoidTy, args,
false);
2339 BlockObjectDispose = CreateRuntimeFunction(fty,
"_Block_object_dispose");
2341 return BlockObjectDispose;
2345 if (BlockObjectAssign)
2346 return BlockObjectAssign;
2349 llvm::FunctionType *fty
2350 = llvm::FunctionType::get(
VoidTy, args,
false);
2351 BlockObjectAssign = CreateRuntimeFunction(fty,
"_Block_object_assign");
2353 return BlockObjectAssign;
2357 if (NSConcreteGlobalBlock)
2358 return NSConcreteGlobalBlock;
2360 NSConcreteGlobalBlock = GetOrCreateLLVMGlobal(
"_NSConcreteGlobalBlock",
2364 return NSConcreteGlobalBlock;
2368 if (NSConcreteStackBlock)
2369 return NSConcreteStackBlock;
2371 NSConcreteStackBlock = GetOrCreateLLVMGlobal(
"_NSConcreteStackBlock",
2375 return NSConcreteStackBlock;
const CGFunctionInfo & arrangeBuiltinFunctionDeclaration(QualType resultType, const FunctionArgList &args)
A builtin function is a freestanding function using the default C conventions.
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
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.
const CGFunctionInfo & arrangeBlockFunctionDeclaration(const FunctionProtoType *type, const FunctionArgList &args)
Block invocation functions are C functions with an implicit parameter.
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.
External linkage, which indicates that the entity can be referred to from other translation units...
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.
ArrayRef< Capture > captures() const
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'.
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
CharUnits alignTo(const CharUnits &Align) const
alignTo - Returns the next integer (mod 2**64) that is greater than or equal to this quantity and is ...
bool isBlockPointerType() const
llvm::Value * EmitARCRetainNonBlock(llvm::Value *value)
Retain the given object, with normal retain semantics.
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.
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
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.
detail::InMemoryDirectory::const_iterator I
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.
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
const TargetInfo & getTarget() 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)
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.
Emit only debug info necessary for generating line number tables (-gline-tables-only).
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.
capture_const_iterator capture_begin() const
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 CharUnits getLowBit(CharUnits v)
Get the low bit of a nonzero character count.
The result type of a method or function.
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
static DeclContext * castToDeclContext(const TranslationUnitDecl *D)
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.
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, Stmt *PreInit, Expr *PostUpdate)
Creates clause with a list of variables VL and a linear step Step.
capture_const_iterator capture_end() const
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.
static bool isBlockPointer(Expr *Arg)
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>.
lookup_result lookup(DeclarationName Name) const
lookup - Find the declarations (if any) with the given Name in this context.
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 is essentially a free function 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.
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
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
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="")
int printf(__constant const char *st,...)
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
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. ...
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
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...
char __ovld __cnfn max(char x, char y)
Returns y if x < y, otherwise it returns x.
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]).
TranslationUnitDecl - The top declaration context.
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
Information for lazily generating a cleanup.
NamedDecl - This represents a decl with a name.
llvm::Instruction * DominatingIP
An instruction which dominates the full-expression that the block is inside.
unsigned long ulong
An unsigned 64-bit integer.
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.
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...
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.