24 #include "llvm/ADT/SmallSet.h" 25 #include "llvm/IR/CallSite.h" 26 #include "llvm/IR/DataLayout.h" 27 #include "llvm/IR/Module.h" 31 using namespace clang;
32 using namespace CodeGen;
35 : Name(name), CXXThisIndex(0), CanBeGlobal(
false), NeedsCopyDispose(
false),
36 HasCXXObject(
false), UsesStret(
false), HasCapturedVariableLayout(
false),
37 LocalAddress(
Address::invalid()), StructureType(nullptr), Block(block),
38 DominatingIP(nullptr) {
42 if (!name.empty() && name[0] ==
'\01')
43 name = name.substr(1);
52 llvm::Constant *blockFn);
84 llvm::IntegerType *
ulong =
86 llvm::PointerType *i8p =
nullptr;
89 llvm::Type::getInt8PtrTy(
98 elements.addInt(ulong, 0);
116 std::string typeAtEncoding =
118 elements.add(llvm::ConstantExpr::getBitCast(
129 elements.addNullPointer(i8p);
131 unsigned AddrSpace = 0;
135 llvm::GlobalVariable *global =
136 elements.finishAndCreateGlobal(
"__block_descriptor_tmp",
158 struct objc_class *isa;
186 _ResultType (*invoke)(Block_literal *, _ParamTypes...);
189 struct Block_descriptor *block_descriptor;
192 _CapturesTypes captures...;
198 struct BlockLayoutChunk {
210 : Alignment(align), Size(size), Lifetime(lifetime),
211 Capture(capture),
Type(type), FieldType(fieldType) {}
227 bool operator<(
const BlockLayoutChunk &left,
const BlockLayoutChunk &right) {
228 if (left.Alignment != right.Alignment)
229 return left.Alignment > right.Alignment;
231 auto getPrefOrder = [](
const BlockLayoutChunk &chunk) {
232 if (chunk.Capture && chunk.Capture->isByRef())
241 return getPrefOrder(left) < getPrefOrder(right);
251 if (!recordType)
return true;
253 const auto *record = cast<CXXRecordDecl>(recordType->
getDecl());
256 if (!record->hasTrivialDestructor())
return false;
257 if (record->hasNonTrivialCopyConstructor())
return false;
261 return !record->hasMutableFields();
275 if (isa<ParmVarDecl>(var))
295 if (!init)
return nullptr;
309 assert(elementTypes.empty());
313 elementTypes.push_back(CGM.
IntTy);
314 elementTypes.push_back(CGM.
IntTy);
319 for (
auto I : Helper->getCustomFieldTypes()) {
323 if (BlockAlign < Align)
325 assert(Offset % Align == 0);
327 elementTypes.push_back(I);
341 elementTypes.push_back(CGM.
IntTy);
342 elementTypes.push_back(CGM.
IntTy);
357 return FD->getType();
370 bool hasNonConstantCustomFields =
false;
371 if (
auto *OpenCLHelper =
373 hasNonConstantCustomFields =
374 !OpenCLHelper->areAllCustomFieldValuesConstant(info);
375 if (!block->
hasCaptures() && !hasNonConstantCustomFields) {
395 "Can't capture 'this' outside a method");
401 std::pair<CharUnits,CharUnits> tinfo
403 maxFieldAlign =
std::max(maxFieldAlign, tinfo.second);
405 layout.push_back(BlockLayoutChunk(tinfo.second, tinfo.first,
407 nullptr, llvmType, thisType));
411 for (
const auto &CI : block->
captures()) {
412 const VarDecl *variable = CI.getVariable();
420 maxFieldAlign =
std::max(maxFieldAlign, align);
464 }
else if (CI.hasCopyExpr()) {
480 if (!record->hasTrivialDestructor()) {
491 maxFieldAlign =
std::max(maxFieldAlign, align);
497 BlockLayoutChunk(align, size, lifetime, &CI, llvmType, VT));
501 if (layout.empty()) {
511 std::stable_sort(layout.begin(), layout.end());
535 if (endAlign < maxFieldAlign) {
537 li = layout.begin() + 1, le = layout.end();
541 for (; li != le && endAlign < li->Alignment; ++li)
548 for (; li != le; ++li) {
549 assert(endAlign >= li->Alignment);
551 li->setIndex(info, elementTypes.size(), blockSize);
552 elementTypes.push_back(li->Type);
553 blockSize += li->Size;
557 if (endAlign >= maxFieldAlign) {
562 layout.erase(first, li);
566 assert(endAlign ==
getLowBit(blockSize));
570 if (endAlign < maxFieldAlign) {
572 CharUnits padding = newBlockSize - blockSize;
580 elementTypes.push_back(llvm::ArrayType::get(CGM.
Int8Ty,
582 blockSize = newBlockSize;
586 assert(endAlign >= maxFieldAlign);
587 assert(endAlign ==
getLowBit(blockSize));
592 li = layout.begin(), le = layout.end(); li != le; ++li) {
593 if (endAlign < li->Alignment) {
597 CharUnits padding = li->Alignment - endAlign;
598 elementTypes.push_back(llvm::ArrayType::get(CGM.
Int8Ty,
600 blockSize += padding;
603 assert(endAlign >= li->Alignment);
604 li->setIndex(info, elementTypes.size(), blockSize);
605 elementTypes.push_back(li->Type);
606 blockSize += li->Size;
631 if (blockInfo.CanBeGlobal)
return;
635 blockInfo.BlockAlign,
"block");
638 if (!blockInfo.NeedsCopyDispose)
return;
642 for (
const auto &CI : block->
captures()) {
645 if (CI.isByRef())
continue;
648 const VarDecl *variable = CI.getVariable();
669 "expected ObjC ARC to be enabled");
683 if (!blockInfo.DominatingIP)
684 blockInfo.DominatingIP = cast<llvm::Instruction>(addr.
getPointer());
688 if (useArrayEHCleanup)
692 destroyer, useArrayEHCleanup);
712 assert(head && *head);
727 assert(head &&
"destroying an empty chain");
732 }
while (head !=
nullptr);
748 return EmitBlockLiteral(blockInfo);
752 std::unique_ptr<CGBlockInfo> blockInfo;
757 return EmitBlockLiteral(*blockInfo);
765 BlockCGF.SanOpts = SanOpts;
766 auto *InvokeFn = BlockCGF.GenerateBlockFunction(
767 CurGD, blockInfo, LocalDeclMap, isLambdaConv, blockInfo.
CanBeGlobal);
776 assert(blockAddr.
isValid() &&
"block has no address!");
779 llvm::Constant *descriptor;
788 isa = llvm::ConstantExpr::getBitCast(blockISA, VoidPtrTy);
809 return Builder.CreateStructGEP(blockAddr, index, offset, name);
814 Builder.CreateStore(value, projectField(index, offset, name));
822 auto addHeaderField =
824 storeField(value, index, offset, name);
830 addHeaderField(isa, getPointerSize(),
"block.isa");
831 addHeaderField(llvm::ConstantInt::get(IntTy, flags.
getBitMask()),
832 getIntSize(),
"block.flags");
833 addHeaderField(llvm::ConstantInt::get(IntTy, 0), getIntSize(),
838 getIntSize(),
"block.size");
841 getIntSize(),
"block.align");
844 addHeaderField(llvm::ConstantExpr::getBitCast(InvokeFn, VoidPtrTy),
845 getPointerSize(),
"block.invoke");
846 addHeaderField(descriptor, getPointerSize(),
"block.descriptor");
847 }
else if (
auto *Helper =
849 for (
auto I : Helper->getCustomFieldValues(*
this, blockInfo)) {
863 if (blockDecl->capturesCXXThis()) {
865 "block.captured-this.addr");
866 Builder.CreateStore(LoadCXXThis(), addr);
870 for (
const auto &CI : blockDecl->captures()) {
871 const VarDecl *variable = CI.getVariable();
888 if (blockDecl->isConversionFromLambda()) {
892 }
else if (CI.isByRef()) {
893 if (BlockInfo && CI.isNested()) {
896 BlockInfo->getCapture(variable);
899 src = Builder.CreateStructGEP(LoadBlockStruct(),
902 "block.capture.addr");
904 auto I = LocalDeclMap.find(variable);
905 assert(I != LocalDeclMap.end());
909 DeclRefExpr declRef(const_cast<VarDecl *>(variable),
913 src = EmitDeclRefLValue(&declRef).getAddress();
924 byrefPointer = Builder.CreateLoad(src,
"byref.capture");
926 byrefPointer = Builder.CreateBitCast(src.getPointer(), VoidPtrTy);
929 Builder.CreateStore(byrefPointer, blockField);
932 }
else if (
const Expr *copyExpr = CI.getCopyExpr()) {
933 if (blockDecl->isConversionFromLambda()) {
942 EmitAggExpr(copyExpr, Slot);
944 EmitSynthesizedCXXCopyCtor(blockField, src, copyExpr);
949 Builder.CreateStore(src.getPointer(), blockField);
955 llvm::Value *value = Builder.CreateLoad(src,
"captured");
956 Builder.CreateStore(value, blockField);
968 llvm::Value *value = Builder.CreateLoad(src,
"block.captured_block");
969 value = EmitARCRetainNonBlock(value);
972 Builder.CreateStore(value, blockField);
983 DeclRefExpr declRef(const_cast<VarDecl *>(variable),
992 EmitExprAsInit(&l2r, &BlockFieldPseudoVar,
1020 if (BlockDescriptorType)
1021 return BlockDescriptorType;
1024 getTypes().ConvertType(getContext().UnsignedLongTy);
1041 "struct.__block_descriptor", UnsignedLongTy, UnsignedLongTy);
1044 unsigned AddrSpace = 0;
1045 if (getLangOpts().OpenCL)
1047 BlockDescriptorType = llvm::PointerType::get(BlockDescriptorType, AddrSpace);
1048 return BlockDescriptorType;
1052 assert(!getLangOpts().OpenCL &&
"OpenCL does not need this");
1054 if (GenericBlockLiteralType)
1055 return GenericBlockLiteralType;
1057 llvm::Type *BlockDescPtrTy = getBlockDescriptorType();
1066 GenericBlockLiteralType =
1068 IntTy, IntTy, VoidPtrTy, BlockDescPtrTy);
1070 return GenericBlockLiteralType;
1088 Builder.CreatePointerCast(BlockPtr, BlockLiteralTy,
"block.literal");
1098 QualType VoidPtrQualTy = getContext().VoidPtrTy;
1100 if (getLangOpts().OpenCL) {
1103 getContext().getPointerType(getContext().getAddrSpaceQualType(
1107 BlockPtr = Builder.CreatePointerCast(BlockPtr, GenericVoidPtrTy);
1120 Func = Builder.CreateAlignedLoad(FuncPtr, getPointerAlign());
1129 llvm::Type *BlockFTyPtr = llvm::PointerType::getUnqual(BlockFTy);
1130 Func = Builder.CreatePointerCast(Func, BlockFTyPtr);
1136 return EmitCall(FnInfo, Callee, ReturnValue, Args);
1141 assert(BlockInfo &&
"evaluating block ref without block information?");
1145 if (capture.
isConstant())
return LocalDeclMap.find(variable)->second;
1148 Builder.CreateStructGEP(LoadBlockStruct(), capture.
getIndex(),
1149 capture.
getOffset(),
"block.capture.addr");
1155 auto &byrefInfo = getBlockByrefInfo(variable);
1156 addr =
Address(Builder.CreateLoad(addr), byrefInfo.ByrefAlignment);
1158 auto byrefPointerType = llvm::PointerType::get(byrefInfo.Type, 0);
1159 addr = Builder.CreateBitCast(addr, byrefPointerType,
"byref.addr");
1161 addr = emitBlockByrefAddress(addr, byrefInfo,
true,
1166 addr = EmitLoadOfReference(MakeAddrLValue(addr, capture.
fieldType()));
1172 llvm::Constant *Addr) {
1173 bool Ok = EmittedGlobalBlocks.insert(std::make_pair(BE, Addr)).second;
1175 assert(Ok &&
"Trying to replace an already-existing global block!");
1181 if (llvm::Constant *
Block = getAddrOfGlobalBlockIfEmitted(BE))
1198 return getAddrOfGlobalBlockIfEmitted(BE);
1203 llvm::Constant *blockFn) {
1209 "Refusing to re-emit a global block.");
1213 auto fields = builder.beginStruct();
1232 fields.addInt(CGM.
IntTy, 0);
1235 fields.add(blockFn);
1244 }
else if (
auto *Helper =
1246 for (
auto I : Helper->getCustomFieldValues(CGM, blockInfo)) {
1251 unsigned AddrSpace = 0;
1255 llvm::Constant *literal = fields.finishAndCreateGlobal(
1256 "__block_literal_global", blockInfo.
BlockAlign,
1272 auto *InitVar =
new llvm::GlobalVariable(CGM.
getModule(), Init->getType(),
1274 Init,
".block_isa_init_ptr");
1275 InitVar->setSection(
".CRT$XCLa");
1282 llvm::Constant *Result =
1283 llvm::ConstantExpr::getPointerCast(literal, RequiredType);
1288 cast<llvm::Function>(blockFn->stripPointerCasts()), Result);
1295 assert(BlockInfo &&
"not emitting prologue of block invocation function?!");
1300 Builder.CreateStore(arg, alloc);
1305 DI->EmitDeclareOfBlockLiteralArgVariable(
1306 *BlockInfo, D->
getName(), argNum,
1307 cast<llvm::AllocaInst>(alloc.
getPointer()), Builder);
1311 SourceLocation StartLoc = BlockInfo->getBlockExpr()->getBody()->getLocStart();
1316 BlockPointer = Builder.CreatePointerCast(
1318 BlockInfo->StructureType->getPointerTo(
1319 getContext().getLangOpts().OpenCL
1326 assert(BlockInfo &&
"not in a block invocation function!");
1327 assert(BlockPointer &&
"no block pointer set!");
1328 return Address(BlockPointer, BlockInfo->BlockAlign);
1335 bool IsLambdaConversionToBlock,
1336 bool BuildGlobalBlock) {
1343 BlockInfo = &blockInfo;
1348 for (DeclMapTy::const_iterator i = ldm.begin(), e = ldm.end(); i != e; ++i) {
1349 const auto *var = dyn_cast<
VarDecl>(i->first);
1350 if (var && !var->hasLocalStorage())
1351 setAddrOfLocalVar(var, i->second);
1361 QualType selfTy = getContext().VoidPtrTy;
1367 if (getLangOpts().OpenCL)
1368 selfTy = getContext().getPointerType(getContext().getAddrSpaceQualType(
1376 args.push_back(&SelfDecl);
1395 if (BuildGlobalBlock) {
1396 auto GenVoidPtrTy = getContext().getLangOpts().OpenCL
1400 llvm::ConstantExpr::getPointerCast(fn, GenVoidPtrTy));
1404 StartFunction(blockDecl, fnType->
getReturnType(), fn, fnInfo, args,
1415 Address Alloca = CreateTempAlloca(BlockPointer->getType(),
1421 Builder.CreateStore(BlockPointer, Alloca);
1429 Builder.CreateStructGEP(LoadBlockStruct(), blockInfo.
CXXThisIndex,
1431 CXXThisValue = Builder.CreateLoad(addr,
"this");
1435 for (
const auto &CI : blockDecl->
captures()) {
1436 const VarDecl *variable = CI.getVariable();
1440 CharUnits align = getContext().getDeclAlign(variable);
1442 CreateMemTemp(variable->
getType(), align,
"block.captured-const");
1444 Builder.CreateStore(capture.
getConstant(), alloca);
1446 setAddrOfLocalVar(variable, alloca);
1450 llvm::BasicBlock *entry = Builder.GetInsertBlock();
1451 llvm::BasicBlock::iterator entry_ptr = Builder.GetInsertPoint();
1454 if (IsLambdaConversionToBlock)
1455 EmitLambdaBlockInvokeBody();
1457 PGO.assignRegionCounters(
GlobalDecl(blockDecl), fn);
1458 incrementProfileCounter(blockDecl->
getBody());
1459 EmitStmt(blockDecl->
getBody());
1463 llvm::BasicBlock *resume = Builder.GetInsertBlock();
1467 Builder.SetInsertPoint(entry, entry_ptr);
1472 for (
const auto &CI : blockDecl->
captures()) {
1473 const VarDecl *variable = CI.getVariable();
1474 DI->EmitLocation(Builder, variable->
getLocation());
1480 auto addr = LocalDeclMap.find(variable)->second;
1481 (void)DI->EmitDeclareOfAutoVariable(variable, addr.getPointer(),
1486 DI->EmitDeclareOfBlockDeclRefVariable(
1487 variable, BlockPointerDbgLoc, Builder, blockInfo,
1488 entry_ptr == entry->end() ? nullptr : &*entry_ptr);
1492 DI->EmitLocation(Builder,
1493 cast<CompoundStmt>(blockDecl->
getBody())->getRBracLoc());
1497 if (resume ==
nullptr)
1498 Builder.ClearInsertionPoint();
1500 Builder.SetInsertPoint(resume);
1502 FinishFunction(cast<CompoundStmt>(blockDecl->
getBody())->getRBracLoc());
1522 struct BlockCaptureManagedEntity {
1531 :
Kind(Type), Flags(Flags), CI(CI), Capture(Capture) {}
1536 static std::pair<BlockCaptureEntityKind, BlockFieldFlags>
1542 return std::make_pair(BlockCaptureEntityKind::CXXRecord,
BlockFieldFlags());
1549 return std::make_pair(BlockCaptureEntityKind::BlockObject, Flags);
1559 return std::make_pair(BlockCaptureEntityKind::NonTrivialCStruct,
1563 return std::make_pair(BlockCaptureEntityKind::ARCWeak, Flags);
1569 return std::make_pair(!isBlockPointer ? BlockCaptureEntityKind::ARCStrong
1570 : BlockCaptureEntityKind::BlockObject,
1584 return std::make_pair(BlockCaptureEntityKind::BlockObject, Flags);
1590 llvm_unreachable(
"after exhaustive PrimitiveCopyKind switch");
1597 llvm::function_ref<std::pair<BlockCaptureEntityKind, BlockFieldFlags>(
1601 const VarDecl *Variable = CI.getVariable();
1606 auto Info = Predicate(CI, Variable->
getType(), LangOpts);
1608 ManagedCaptures.emplace_back(Info.first, Info.second, CI, Capture);
1617 bool LoadBlockVarAddr;
1620 : Addr(Addr), FieldFlags(Flags), LoadBlockVarAddr(LoadValue) {}
1624 if (LoadBlockVarAddr) {
1640 switch (CaptureKind) {
1641 case BlockCaptureEntityKind::CXXRecord:
1642 case BlockCaptureEntityKind::ARCWeak:
1643 case BlockCaptureEntityKind::NonTrivialCStruct:
1644 case BlockCaptureEntityKind::ARCStrong: {
1648 CaptureKind == BlockCaptureEntityKind::ARCStrong
1658 case BlockCaptureEntityKind::BlockObject: {
1666 llvm_unreachable(
"unexpected BlockCaptureEntityKind");
1685 args.push_back(&DstDecl);
1688 args.push_back(&SrcDecl);
1697 llvm::Function *Fn =
1699 "__copy_helper_block_", &CGM.
getModule());
1714 StartFunction(FD, C.
VoidTy, Fn, FI, args);
1718 Address src = GetAddrOfLocalVar(&SrcDecl);
1720 src = Builder.CreateBitCast(src, structPtrTy,
"block.source");
1722 Address dst = GetAddrOfLocalVar(&DstDecl);
1724 dst = Builder.CreateBitCast(dst, structPtrTy,
"block.dest");
1730 for (
const auto &CopiedCapture : CopiedCaptures) {
1736 unsigned index = capture.
getIndex();
1737 Address srcField = Builder.CreateStructGEP(src, index, capture.
getOffset());
1738 Address dstField = Builder.CreateStructGEP(dst, index, capture.
getOffset());
1742 assert(CopiedCapture.Kind == BlockCaptureEntityKind::CXXRecord);
1743 EmitSynthesizedCXXCopyCtor(dstField, srcField, CI.
getCopyExpr());
1744 }
else if (CopiedCapture.Kind == BlockCaptureEntityKind::ARCWeak) {
1745 EmitARCCopyWeak(dstField, srcField);
1748 }
else if (CopiedCapture.Kind ==
1749 BlockCaptureEntityKind::NonTrivialCStruct) {
1751 callCStructCopyConstructor(MakeAddrLValue(dstField, varType),
1752 MakeAddrLValue(srcField, varType));
1754 llvm::Value *srcValue = Builder.CreateLoad(srcField,
"blockcopy.src");
1755 if (CopiedCapture.Kind == BlockCaptureEntityKind::ARCStrong) {
1760 auto *ty = cast<llvm::PointerType>(srcValue->getType());
1761 llvm::Value *null = llvm::ConstantPointerNull::get(ty);
1762 Builder.CreateStore(null, dstField);
1763 EmitARCStoreStrongCall(dstField, srcValue,
true);
1769 EmitARCRetainNonBlock(srcValue);
1775 cast<llvm::Instruction>(dstField.
getPointer())->eraseFromParent();
1778 assert(CopiedCapture.Kind == BlockCaptureEntityKind::BlockObject);
1779 srcValue = Builder.CreateBitCast(srcValue, VoidPtrTy);
1781 Builder.CreateBitCast(dstField.
getPointer(), VoidPtrTy);
1783 dstAddr, srcValue, llvm::ConstantInt::get(Int32Ty, flags.
getBitMask())
1787 bool copyCanThrow =
false;
1788 if (CI.
isByRef() && variable->getType()->getAsCXXRecordDecl()) {
1789 const Expr *copyExpr =
1792 copyCanThrow =
true;
1812 return llvm::ConstantExpr::getBitCast(Fn, VoidPtrTy);
1824 static std::pair<BlockCaptureEntityKind, BlockFieldFlags>
1831 return std::make_pair(BlockCaptureEntityKind::BlockObject, Flags);
1836 return std::make_pair(BlockCaptureEntityKind::CXXRecord,
BlockFieldFlags());
1840 return std::make_pair(BlockCaptureEntityKind::ARCStrong,
1844 return std::make_pair(BlockCaptureEntityKind::ARCWeak,
1847 return std::make_pair(BlockCaptureEntityKind::NonTrivialCStruct,
1852 !LangOpts.ObjCAutoRefCount)
1853 return std::make_pair(BlockCaptureEntityKind::BlockObject,
1859 llvm_unreachable(
"after exhaustive DestructionKind switch");
1876 args.push_back(&SrcDecl);
1885 llvm::Function *Fn =
1887 "__destroy_helper_block_", &CGM.
getModule());
1900 StartFunction(FD, C.
VoidTy, Fn, FI, args);
1905 Address src = GetAddrOfLocalVar(&SrcDecl);
1907 src = Builder.CreateBitCast(src, structPtrTy,
"block");
1915 for (
const auto &DestroyedCapture : DestroyedCaptures) {
1931 return llvm::ConstantExpr::getBitCast(Fn, VoidPtrTy);
1967 void profileImpl(llvm::FoldingSetNodeID &
id)
const override {
1968 id.AddInteger(Flags.getBitMask());
1986 void profileImpl(llvm::FoldingSetNodeID &
id)
const override {
2006 llvm::ConstantPointerNull::get(cast<llvm::PointerType>(value->getType()));
2022 void profileImpl(llvm::FoldingSetNodeID &
id)
const override {
2032 ARCStrongBlockByrefHelpers(
CharUnits alignment)
2049 void profileImpl(llvm::FoldingSetNodeID &
id)
const override {
2059 const Expr *CopyExpr;
2063 const Expr *copyExpr)
2066 bool needsCopy()
const override {
return CopyExpr !=
nullptr; }
2069 if (!CopyExpr)
return;
2079 void profileImpl(llvm::FoldingSetNodeID &
id)
const override {
2080 id.AddPointer(VarType.getCanonicalType().getAsOpaquePtr());
2099 bool needsDispose()
const override {
2100 return VarType.isDestructedType();
2105 CGF.
pushDestroy(VarType.isDestructedType(), field, VarType);
2109 void profileImpl(llvm::FoldingSetNodeID &
id)
const override {
2110 id.AddPointer(VarType.getCanonicalType().getAsOpaquePtr());
2115 static llvm::Constant *
2125 args.push_back(&Dst);
2129 args.push_back(&Src);
2138 llvm::Function *Fn =
2143 = &Context.
Idents.
get(
"__Block_byref_object_copy_");
2175 generator.
emitCopy(CGF, destField, srcField);
2180 return llvm::ConstantExpr::getBitCast(Fn, CGF.
Int8PtrTy);
2192 static llvm::Constant *
2202 args.push_back(&Src);
2211 llvm::Function *Fn =
2213 "__Block_byref_object_dispose_",
2217 = &Context.
Idents.
get(
"__Block_byref_object_dispose_");
2233 auto byrefPtrType = byrefInfo.
Type->getPointerTo(0);
2242 return llvm::ConstantExpr::getBitCast(Fn, CGF.
Int8PtrTy);
2258 llvm::FoldingSetNodeID
id;
2259 generator.Profile(
id);
2264 if (node)
return static_cast<T*
>(node);
2269 T *copy =
new (CGM.
getContext()) T(std::forward<T>(generator));
2278 CodeGenFunction::buildByrefHelpers(llvm::StructType &byrefType,
2279 const AutoVarEmission &emission) {
2280 const VarDecl &var = *emission.Variable;
2283 auto &byrefInfo = getBlockByrefInfo(&var);
2292 if (!copyExpr && record->hasTrivialDestructor())
return nullptr;
2295 CGM, byrefInfo, CXXByrefHelpers(valueAlignment, type, copyExpr));
2303 CGM, byrefInfo, NonTrivialCStructByrefHelpers(valueAlignment, type));
2325 ARCWeakByrefHelpers(valueAlignment));
2333 ARCStrongBlockByrefHelpers(valueAlignment));
2339 ARCStrongByrefHelpers(valueAlignment));
2342 llvm_unreachable(
"fell out of lifetime switch!");
2359 ObjectByrefHelpers(valueAlignment, flags));
2364 bool followForward) {
2365 auto &info = getBlockByrefInfo(var);
2366 return emitBlockByrefAddress(baseAddr, info, followForward, var->
getName());
2372 const llvm::Twine &name) {
2374 if (followForward) {
2376 Builder.CreateStructGEP(baseAddr, 1, getPointerSize(),
"forwarding");
2380 return Builder.CreateStructGEP(baseAddr, info.
FieldIndex,
2400 auto it = BlockByrefInfos.find(D);
2401 if (it != BlockByrefInfos.end())
2404 llvm::StructType *byrefType =
2414 types.push_back(Int8PtrTy);
2415 size += getPointerSize();
2418 types.push_back(llvm::PointerType::getUnqual(byrefType));
2419 size += getPointerSize();
2422 types.push_back(Int32Ty);
2426 types.push_back(Int32Ty);
2430 bool hasCopyAndDispose = getContext().BlockRequiresCopying(Ty, D);
2431 if (hasCopyAndDispose) {
2433 types.push_back(Int8PtrTy);
2434 size += getPointerSize();
2437 types.push_back(Int8PtrTy);
2438 size += getPointerSize();
2441 bool HasByrefExtendedLayout =
false;
2443 if (getContext().getByrefLifetime(Ty, Lifetime, HasByrefExtendedLayout) &&
2444 HasByrefExtendedLayout) {
2446 types.push_back(Int8PtrTy);
2453 bool packed =
false;
2454 CharUnits varAlign = getContext().getDeclAlign(D);
2458 if (varOffset != size) {
2460 llvm::ArrayType::get(Int8Ty, (varOffset - size).getQuantity());
2462 types.push_back(paddingTy);
2470 types.push_back(varTy);
2472 byrefType->setBody(types, packed);
2475 info.
Type = byrefType;
2480 auto pair = BlockByrefInfos.insert({D, info});
2481 assert(pair.second &&
"info was inserted recursively?");
2482 return pair.first->second;
2492 llvm::StructType *byrefType = cast<llvm::StructType>(
2493 cast<llvm::PointerType>(addr.
getPointer()->getType())->getElementType());
2495 unsigned nextHeaderIndex = 0;
2498 const Twine &name) {
2499 auto fieldAddr = Builder.CreateStructGEP(addr, nextHeaderIndex,
2500 nextHeaderOffset, name);
2501 Builder.CreateStore(value, fieldAddr);
2504 nextHeaderOffset += fieldSize;
2510 const VarDecl &D = *emission.Variable;
2513 bool HasByrefExtendedLayout;
2515 bool ByRefHasLifetime =
2516 getContext().getByrefLifetime(type, ByrefLifetime, HasByrefExtendedLayout);
2524 V = Builder.CreateIntToPtr(Builder.getInt32(isa), Int8PtrTy,
"isa");
2525 storeHeaderField(V, getPointerSize(),
"byref.isa");
2528 storeHeaderField(addr.
getPointer(), getPointerSize(),
"byref.forwarding");
2535 if (ByRefHasLifetime) {
2537 else switch (ByrefLifetime) {
2555 printf(
"\n Inline flag for BYREF variable layout (%d):", flags.getBitMask());
2557 printf(
" BLOCK_BYREF_HAS_COPY_DISPOSE");
2561 printf(
" BLOCK_BYREF_LAYOUT_EXTENDED");
2563 printf(
" BLOCK_BYREF_LAYOUT_STRONG");
2565 printf(
" BLOCK_BYREF_LAYOUT_WEAK");
2567 printf(
" BLOCK_BYREF_LAYOUT_UNRETAINED");
2569 printf(
" BLOCK_BYREF_LAYOUT_NON_OBJECT");
2574 storeHeaderField(llvm::ConstantInt::get(IntTy, flags.getBitMask()),
2575 getIntSize(),
"byref.flags");
2578 V = llvm::ConstantInt::get(IntTy, byrefSize.getQuantity());
2579 storeHeaderField(V, getIntSize(),
"byref.size");
2582 storeHeaderField(helpers->
CopyHelper, getPointerSize(),
2583 "byref.copyHelper");
2585 "byref.disposeHelper");
2588 if (ByRefHasLifetime && HasByrefExtendedLayout) {
2590 storeHeaderField(layoutInfo, getPointerSize(),
"byref.layout");
2597 Builder.CreateBitCast(V, Int8PtrTy),
2598 llvm::ConstantInt::get(Int32Ty, flags.
getBitMask())
2600 EmitNounwindRuntimeCall(F, args);
2605 bool LoadBlockVarAddr) {
2606 EHStack.pushCleanup<CallBlockRelease>(
Kind, Addr, Flags, LoadBlockVarAddr);
2611 llvm::Constant *C) {
2612 auto *GV = cast<llvm::GlobalValue>(C->stripPointerCasts());
2619 assert((isa<llvm::Function>(C->stripPointerCasts()) ||
2620 isa<llvm::GlobalVariable>(C->stripPointerCasts())) &&
2621 "expected Function or GlobalVariable");
2624 for (
const auto &Result : DC->
lookup(&II))
2625 if ((ND = dyn_cast<FunctionDecl>(Result)) ||
2626 (ND = dyn_cast<
VarDecl>(Result)))
2630 if (GV->isDeclaration() && (!ND || !ND->hasAttr<DLLExportAttr>())) {
2631 GV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
2634 GV->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
2639 if (CGM.
getLangOpts().BlocksRuntimeOptional && GV->isDeclaration() &&
2640 GV->hasExternalLinkage())
2641 GV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage);
2647 if (BlockObjectDispose)
2648 return BlockObjectDispose;
2651 llvm::FunctionType *fty
2652 = llvm::FunctionType::get(VoidTy, args,
false);
2653 BlockObjectDispose = CreateRuntimeFunction(fty,
"_Block_object_dispose");
2655 return BlockObjectDispose;
2659 if (BlockObjectAssign)
2660 return BlockObjectAssign;
2662 llvm::Type *args[] = { Int8PtrTy, Int8PtrTy, Int32Ty };
2663 llvm::FunctionType *fty
2664 = llvm::FunctionType::get(VoidTy, args,
false);
2665 BlockObjectAssign = CreateRuntimeFunction(fty,
"_Block_object_assign");
2667 return BlockObjectAssign;
2671 if (NSConcreteGlobalBlock)
2672 return NSConcreteGlobalBlock;
2674 NSConcreteGlobalBlock = GetOrCreateLLVMGlobal(
"_NSConcreteGlobalBlock",
2675 Int8PtrTy->getPointerTo(),
2678 return NSConcreteGlobalBlock;
2682 if (NSConcreteStackBlock)
2683 return NSConcreteStackBlock;
2685 NSConcreteStackBlock = GetOrCreateLLVMGlobal(
"_NSConcreteStackBlock",
2686 Int8PtrTy->getPointerTo(),
2689 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.
llvm::PointerType * Int8PtrPtrTy
const llvm::DataLayout & getDataLayout() const
CGOpenCLRuntime & getOpenCLRuntime()
Return a reference to the configured OpenCL runtime.
ReturnValueSlot - Contains the address where the return value of a function can be stored...
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const BlockDecl * getBlockDecl() const
Information about the layout of a __block variable.
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 ...
const Capture & getCapture(const VarDecl *var) const
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.
Represents a function declaration or definition.
llvm::IntegerType * IntTy
int
llvm::Type * getGenericBlockLiteralType()
The type of a generic block literal.
CharUnits getIntAlign() const
const CGFunctionInfo & arrangeBlockFunctionDeclaration(const FunctionProtoType *type, const FunctionArgList &args)
Block invocation functions are C functions with an implicit parameter.
External linkage, which indicates that the entity can be referred to from other translation units...
Other implicit parameter.
CharUnits BlockHeaderForcedGapOffset
const FunctionProtoType * getFunctionType() const
getFunctionType - Return the underlying function type for this block.
Expr * getCopyExpr() const
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.
bool isBlockPointerType() const
CodeGenTypes & getTypes()
const CodeGenOptions & getCodeGenOpts() const
bool hasCaptures() const
True if this block (or its nested blocks) captures anything of local storage from its enclosing scope...
bool HaveInsertPoint() const
HaveInsertPoint - True if an insertion point is defined.
capture_const_iterator capture_begin() const
llvm::LLVMContext & getLLVMContext()
void EmitARCDestroyWeak(Address addr)
void @objc_destroyWeak(i8** addr) Essentially objc_storeWeak(addr, nil).
llvm::Constant * CopyHelper
The standard implementation of ConstantInitBuilder used in Clang.
FunctionType - C99 6.7.5.3 - Function Declarators.
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
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.
ArrayRef< CleanupObject > getObjects() const
CharUnits getPointerSize() const
param_iterator param_end()
static llvm::Constant * buildBlockDescriptor(CodeGenModule &CGM, const CGBlockInfo &blockInfo)
buildBlockDescriptor - Build the block descriptor meta-data for a block.
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
The base class of the type hierarchy.
stable_iterator stable_begin() const
Create a stable reference to the top of the EH stack.
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64
capture_const_iterator capture_end() const
The type would be trivial except that it is volatile-qualified.
Address GetAddrOfLocalVar(const VarDecl *VD)
GetAddrOfLocalVar - Return the address of a local variable.
Represents a variable declaration or definition.
CGBlockInfo(const BlockDecl *blockDecl, StringRef Name)
const T * getAs() const
Member-template getAs<specific type>'.
EHScopeStack::stable_iterator getCleanup() const
This class gathers all debug information during compilation and is responsible for emitting to llvm g...
static std::pair< BlockCaptureEntityKind, BlockFieldFlags > computeCopyInfoForBlockCapture(const BlockDecl::Capture &CI, QualType T, const LangOptions &LangOpts)
virtual llvm::Constant * BuildRCBlockLayout(CodeGen::CodeGenModule &CGM, const CodeGen::CGBlockInfo &blockInfo)=0
llvm::Value * getPointer() const
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 ...
static void destroyBlockInfos(CGBlockInfo *info)
Destroy a chain of block layouts.
SourceLocation getLocStart() const LLVM_READONLY
The collection of all-type qualifiers we support.
void add(RValue rvalue, QualType type)
const AstTypeMatcher< RecordType > recordType
Matches record types (e.g.
llvm::DenseMap< const VarDecl *, FieldDecl * > LambdaCaptureFields
One of these records is kept for each identifier that is lexed.
bool doesNotEscape() const
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.
QualType getPointeeType() const
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.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
llvm::Constant * tryEmitAbstractForInitializer(const VarDecl &D)
Try to emit the initializer of the given declaration as an abstract constant.
bool HasCapturedVariableLayout
HasCapturedVariableLayout : True if block has captured variables and their layout meta-data has been ...
static std::pair< BlockCaptureEntityKind, BlockFieldFlags > computeDestroyInfoForBlockCapture(const BlockDecl::Capture &CI, QualType T, const LangOptions &LangOpts)
bool isReferenceType() const
Denotes a cleanup that should run when a scope is exited using exceptional control flow (a throw stat...
static void findBlockCapturedManagedEntities(const CGBlockInfo &BlockInfo, const LangOptions &LangOpts, SmallVectorImpl< BlockCaptureManagedEntity > &ManagedCaptures, llvm::function_ref< std::pair< BlockCaptureEntityKind, BlockFieldFlags >(const BlockDecl::Capture &, QualType, const LangOptions &)> Predicate)
Find the set of block captures that need to be explicitly copied or destroy.
std::string getObjCEncodingForBlock(const BlockExpr *blockExpr) const
Return the encoded type for this block declaration.
void recordBlockInfo(const BlockExpr *E, llvm::Function *InvokeF, llvm::Value *Block)
Record invoke function and block literal emitted during normal codegen for a block expression...
static AggValueSlot forAddr(Address addr, Qualifiers quals, IsDestructed_t isDestructed, NeedsGCBarriers_t needsGC, IsAliased_t isAliased, Overlap_t mayOverlap, IsZeroed_t isZeroed=IsNotZeroed, IsSanitizerChecked_t isChecked=IsNotSanitizerChecked)
forAddr - Make a slot for an aggregate value.
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++.
CleanupKind getCleanupKind(QualType::DestructionKind kind)
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
An r-value expression (a pr-value in the C++11 taxonomy) produces a temporary value.
CharUnits GetTargetTypeStoreSize(llvm::Type *Ty) const
Return the store size, in character units, of the given LLVM type.
llvm::Value * EmitARCStoreStrongCall(Address addr, llvm::Value *value, bool resultIgnored)
Store into a strong object.
Address GetAddrOfBlockDecl(const VarDecl *var, bool ByRef)
CharUnits - This is an opaque type for sizes expressed in character units.
void EmitARCDestroyStrong(Address addr, ARCPreciseLifetime_t precise)
Destroy a __strong variable.
const BlockDecl * getBlockDecl() const
void setDSOLocal(llvm::GlobalValue *GV) const
virtual TargetOpenCLBlockHelper * getTargetOpenCLBlockHelper() 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 block literal.
llvm::PointerType * VoidPtrTy
uint32_t getBitMask() const
bool isByRef() const
Whether this is a "by ref" capture, i.e.
bool needsEHCleanup(QualType::DestructionKind kind)
Determines whether an EH cleanup is required to destroy a type with the given destruction kind...
llvm::Constant * getAddrOfGlobalBlockIfEmitted(const BlockExpr *BE)
Returns the address of a block which requires no caputres, or null if we've yet to emit the block for...
The type is an Objective-C retainable pointer type that is qualified with the ARC __strong qualifier...
CharUnits getDeclAlign(const Decl *D, bool ForAlignof=false) const
Return a conservative estimate of the alignment of the specified decl D.
Scope - A scope is a transient data structure that is used while parsing the program.
llvm::PointerType * VoidPtrPtrTy
void ForceCleanup(std::initializer_list< llvm::Value **> ValuesToReload={})
Force the emission of cleanups now, instead of waiting until this object is destroyed.
static Capture makeConstant(llvm::Value *value)
CharUnits getPointerAlign() const
llvm::AllocaInst * CreateTempAlloca(llvm::Type *Ty, const Twine &Name="tmp", llvm::Value *ArraySize=nullptr)
CreateTempAlloca - This creates an alloca and inserts it into the entry block if ArraySize is nullptr...
void callCStructMoveConstructor(LValue Dst, LValue Src)
const Stmt * getBody() const
llvm::Constant * getNSConcreteStackBlock()
The type does not fall into any of the following categories.
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.
StringRef Name
Name - The name of the block, kindof.
bool NeedsCopyDispose
True if the block has captures that would necessitate custom copy or dispose helper functions if the ...
lookup_result lookup(DeclarationName Name) const
lookup - Find the declarations (if any) with the given Name in this context.
const BlockExpr * BlockExpression
unsigned getIndex() const
static llvm::Constant * buildCopyHelper(CodeGenModule &CGM, const CGBlockInfo &blockInfo)
Build the helper function to copy a block.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
ASTContext & getContext() const
Represents a prototype with parameter type info, e.g.
llvm::CallInst * EmitNounwindRuntimeCall(llvm::Value *callee, const Twine &name="")
uint32_t getBitMask() const
const CodeGen::CGBlockInfo * BlockInfo
const TargetCodeGenInfo & getTargetCodeGenInfo()
CGBlockInfo - Information to generate a block literal.
virtual void emitCopy(CodeGenFunction &CGF, Address dest, Address src)=0
RValue - This trivial value class is used to represent the result of an expression that is evaluated...
QualType fieldType() const
bool CanBeGlobal
CanBeGlobal - True if the block can be global, i.e.
SourceLocation getLocEnd() const LLVM_READONLY
StringRef getBlockMangledName(GlobalDecl GD, const BlockDecl *BD)
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static void initializeForBlockHeader(CodeGenModule &CGM, CGBlockInfo &info, SmallVectorImpl< llvm::Type *> &elementTypes)
CGBlockInfo * NextBlockInfo
The next block in the block-info chain.
CGObjCRuntime & getObjCRuntime()
Return a reference to the configured Objective-C runtime.
PrimitiveCopyKind isNonTrivialToPrimitiveDestructiveMove() const
Check if this is a non-trivial type that would cause a C struct transitively containing this type to ...
Pepresents a block literal declaration, which is like an unnamed FunctionDecl.
Expr - This represents one expression.
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...
CharUnits getOffset() const
llvm::Constant * DisposeHelper
const T * castAs() const
Member-template castAs<specific type>.
bool isObjCRetainableType() const
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
BlockCaptureEntityKind
Represents a type of copy/destroy operation that should be performed for an entity that's captured by...
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...
const Expr * getCallee() const
ObjCLifetime getObjCLifetime() 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.
bool needsCopyDisposeHelpers() const
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
static Capture makeIndex(unsigned index, CharUnits offset, QualType FieldType)
bool isa(CodeGen::Address addr)
bool isObjCInertUnsafeUnretainedType() const
Was this type written with the special inert-in-MRC __unsafe_unretained qualifier?
static CharUnits getLowBit(CharUnits v)
Get the low bit of a nonzero character count.
const Type * getBaseElementTypeUnsafe() const
Get the base element type of this type, potentially discarding type qualifiers.
const TargetInfo & getTarget() const
const LangOptions & getLangOpts() const
ASTContext & getContext() const
static BlockFieldFlags getBlockFieldFlagsForObjCObjectPointer(const BlockDecl::Capture &CI, QualType T)
static QualType getCaptureFieldType(const CodeGenFunction &CGF, const BlockDecl::Capture &CI)
llvm::Function * getInvokeFunction(const Expr *E)
GlobalDecl - represents a global declaration.
virtual bool needsCopy() const
virtual llvm::Constant * BuildByrefLayout(CodeGen::CodeGenModule &CGM, QualType T)=0
Returns an i8* which points to the byref layout information.
bool isConstQualified() const
Determine whether this type is const-qualified.
param_iterator param_begin()
The l-value was considered opaque, so the alignment was determined from a type.
RecordDecl * getDecl() const
void setBlockContextParameter(const ImplicitParamDecl *D, unsigned argNum, llvm::Value *ptr)
void PopCleanupBlocks(EHScopeStack::stable_iterator OldCleanupStackSize, std::initializer_list< llvm::Value **> ValuesToReload={})
Takes the old cleanup stack size and emits the cleanup blocks that have been added.
bool UsesStret
UsesStret : True if the block uses an stret return.
There is no lifetime qualification on this type.
Address CreateBitCast(Address Addr, llvm::Type *Ty, const llvm::Twine &Name="")
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 nullptr 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...
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.
static DeclContext * castToDeclContext(const TranslationUnitDecl *D)
QualType getReturnType() const
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
A saved depth on the scope stack.
llvm::StructType * StructureType
std::string getNameAsString() const
Get a human-readable name for the declaration, even if it is one of the special kinds of names (C++ c...
static void configureBlocksRuntimeObject(CodeGenModule &CGM, llvm::Constant *C)
Adjust the declaration of something from the blocks API.
SourceLocation getLocStart() const LLVM_READONLY
The type is a struct containing a field whose type is neither PCK_Trivial nor PCK_VolatileTrivial.
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 ...
bool isConversionFromLambda() const
llvm::DenseMap< const VarDecl *, Capture > Captures
The mapping of allocated indexes within the block.
bool isObjCObjectPointerType() const
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.
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
DestructionKind isDestructedType() const
Returns a nonzero value if objects of this type require non-trivial work to clean up after...
llvm::Value * getConstant() const
static Destroyer emitARCIntrinsicUse
const BlockExpr * getBlockExpr() const
All available information about a concrete callee.
virtual bool needsDispose() const
bool operator<(DeclarationName LHS, DeclarationName RHS)
Ordering on two declaration names.
VarDecl * getVariable() const
The variable being captured.
PrimitiveCopyKind isNonTrivialToPrimitiveCopy() const
Check if this is a non-trivial type that would cause a C struct transitively containing this type to ...
unsigned CXXThisIndex
The field index of 'this' within the block, if there is one.
Assigning into this object requires a lifetime extension.
static Destroyer destroyARCStrongImprecise
void FinishFunction(SourceLocation EndLoc=SourceLocation())
FinishFunction - Complete IR generation of the current function.
The type is an Objective-C retainable pointer type that is qualified with the ARC __weak qualifier...
const CGFunctionInfo & arrangeBlockFunctionCall(const CallArgList &args, const FunctionType *type)
A block function is essentially a free function with an extra implicit argument.
std::pair< CharUnits, CharUnits > getTypeInfoInChars(const Type *T) const
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...
void addUsedGlobal(llvm::GlobalValue *GV)
Add a global to a list to be added to the llvm.used metadata.
FunctionArgList - Type for representing both the decl and type of parameters to a function...
bool isObjCGCWeak() const
true when Type is objc's weak.
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.
CharUnits alignmentAtOffset(CharUnits offset) const
Given that this is a non-zero alignment value, what is the alignment at the given offset...
Dataflow Directional Tag Classes.
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...
ArrayRef< Capture > captures() const
bool isNested() const
Whether this is a nested capture, i.e.
Address CreateStructGEP(Address Addr, unsigned Index, CharUnits Offset, const llvm::Twine &Name="")
Parameter for Objective-C 'self' argument.
static llvm::Constant * buildDisposeHelper(CodeGenModule &CGM, const CGBlockInfo &blockInfo)
Build the helper function to dispose of a block.
const Expr * getInit() const
llvm::Constant * getPointer() const
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,...)
bool hasObjCLifetime() const
llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)
llvm::Module & getModule() const
LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource Source=AlignmentSource::Type)
static void pushCaptureCleanup(BlockCaptureEntityKind CaptureKind, Address Field, QualType CaptureType, BlockFieldFlags Flags, bool EHOnly, CodeGenFunction &CGF)
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...
StructBuilder beginStruct(llvm::StructType *structTy=nullptr)
CanQualType UnsignedLongTy
unsigned getNumObjects() const
static llvm::Constant * buildByrefCopyHelper(CodeGenModule &CGM, const BlockByrefInfo &byrefInfo, BlockByrefHelpers &generator)
Build the copy helper for a __block variable.
llvm::PointerType * Int8PtrTy
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.
void SetInternalFunctionAttributes(GlobalDecl GD, llvm::Function *F, const CGFunctionInfo &FI)
Set the attributes on the LLVM function for the given decl and function info.
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()
const Decl * CurFuncDecl
CurFuncDecl - Holds the Decl for the current outermost non-closure context.
A pair of helper functions for a __block variable.
bool capturesCXXThis() const
CharUnits getIntSize() const
Reading or writing from this object requires a barrier call.
TranslationUnitDecl * getTranslationUnitDecl() const
Represents a C++ struct/union/class.
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
void setAddrOfGlobalBlock(const BlockExpr *BE, llvm::Constant *Addr)
Notes that BE's global block is available via Addr.
virtual ~BlockByrefHelpers()
CharUnits BlockHeaderForcedGapSize
llvm::Value * EmitARCRetainBlock(llvm::Value *value, bool mandatory)
Retain the given block, with _Block_copy semantics.
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
__DEVICE__ int max(int __a, int __b)
llvm::Function * GenerateBlockFunction(GlobalDecl GD, const CGBlockInfo &Info, const DeclMapTy &ldm, bool IsLambdaConversionToBlock, bool BuildGlobalBlock)
The top declaration context.
A reference to a declared variable, function, enum, etc.
static RValue get(llvm::Value *V)
RValue EmitBlockCallExpr(const CallExpr *E, ReturnValueSlot ReturnValue)
const internal::VariadicDynCastAllOfMatcher< Decl, BlockDecl > blockDecl
Matches block declarations.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
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.
llvm::Constant * GetAddrOfGlobalBlock(const BlockExpr *BE, StringRef Name)
Gets the address of a block which requires no captures.
An l-value expression is a reference to an object with independent storage.
void enterByrefCleanup(CleanupKind Kind, Address Addr, BlockFieldFlags Flags, bool LoadBlockVarAddr)
Enter a cleanup to destroy a __block variable.
llvm::PointerType * getGenericVoidPointerType()
Information for lazily generating a cleanup.
This represents a decl that may have 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.
const LangOptions & getLangOpts() const
unsigned getTargetAddressSpace(QualType T) const
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.
const LangOptions & getLangOpts() const
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...
Abstract information about a function or function prototype.
SourceLocation getLocation() const
void BuildBlockRelease(llvm::Value *DeclPtr, BlockFieldFlags flags)
void setCleanup(EHScopeStack::stable_iterator cleanup)
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.
void Destroyer(CodeGenFunction &CGF, Address addr, QualType ty)
Qualifiers::ObjCLifetime getObjCLifetime() const
Returns lifetime attribute of this type.
llvm::FunctionType * GetFunctionType(const CGFunctionInfo &Info)
GetFunctionType - Get the LLVM function type for.