24 #include "llvm/ADT/SmallSet.h" 25 #include "llvm/IR/DataLayout.h" 26 #include "llvm/IR/Module.h" 27 #include "llvm/Support/ScopedPrinter.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 CapturesNonExternalType(
false), LocalAddress(
Address::invalid()),
38 StructureType(nullptr), Block(block), DominatingIP(nullptr) {
42 if (!name.empty() && name[0] ==
'\01')
43 name = name.substr(1);
52 llvm::Constant *blockFn);
81 struct BlockCaptureManagedEntity {
93 : CopyKind(CopyType), DisposeKind(DisposeType), CopyFlags(CopyFlags),
94 DisposeFlags(DisposeFlags), CI(&CI), Capture(&Capture) {}
96 bool operator<(
const BlockCaptureManagedEntity &Other)
const {
97 return Capture->
getOffset() < Other.Capture->getOffset();
114 SmallVectorImpl<BlockCaptureManagedEntity> &ManagedCaptures);
123 std::string
Name =
"__block_descriptor_";
137 for (
const BlockCaptureManagedEntity &E : ManagedCaptures) {
138 Name += llvm::to_string(E.Capture->getOffset().getQuantity());
140 if (E.CopyKind == E.DisposeKind) {
144 "shouldn't see BlockCaptureManagedEntity that is None");
160 std::string TypeAtEncoding =
164 std::replace(TypeAtEncoding.begin(), TypeAtEncoding.end(),
'@',
'\1');
165 Name +=
"e" + llvm::to_string(TypeAtEncoding.size()) +
"_" + TypeAtEncoding;
188 llvm::IntegerType *
ulong =
190 llvm::PointerType *i8p =
nullptr;
193 llvm::Type::getInt8PtrTy(
198 std::string descName;
204 if (llvm::GlobalValue *desc = CGM.
getModule().getNamedValue(descName))
205 return llvm::ConstantExpr::getBitCast(desc,
215 elements.addInt(ulong, 0);
224 bool hasInternalHelper =
false;
228 elements.add(copyHelper);
232 elements.add(disposeHelper);
234 if (cast<llvm::Function>(copyHelper->getOperand(0))->hasInternalLinkage() ||
235 cast<llvm::Function>(disposeHelper->getOperand(0))
236 ->hasInternalLinkage())
237 hasInternalHelper =
true;
241 std::string typeAtEncoding =
243 elements.add(llvm::ConstantExpr::getBitCast(
254 elements.addNullPointer(i8p);
256 unsigned AddrSpace = 0;
260 llvm::GlobalValue::LinkageTypes linkage;
261 if (descName.empty()) {
263 descName =
"__block_descriptor_tmp";
264 }
else if (hasInternalHelper) {
269 linkage = llvm::GlobalValue::LinkOnceODRLinkage;
272 llvm::GlobalVariable *global =
274 true, linkage, AddrSpace);
276 if (linkage == llvm::GlobalValue::LinkOnceODRLinkage) {
278 global->setComdat(CGM.
getModule().getOrInsertComdat(descName));
280 global->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
299 struct objc_class *isa;
327 _ResultType (*invoke)(Block_literal *, _ParamTypes...);
330 struct Block_descriptor *block_descriptor;
333 _CapturesTypes captures...;
339 struct BlockLayoutChunk {
351 : Alignment(align), Size(size), Lifetime(lifetime),
352 Capture(capture),
Type(type), FieldType(fieldType) {}
368 bool operator<(
const BlockLayoutChunk &left,
const BlockLayoutChunk &right) {
369 if (left.Alignment != right.Alignment)
370 return left.Alignment > right.Alignment;
372 auto getPrefOrder = [](
const BlockLayoutChunk &chunk) {
373 if (chunk.Capture && chunk.Capture->isByRef())
382 return getPrefOrder(left) < getPrefOrder(right);
392 if (!recordType)
return true;
394 const auto *record = cast<CXXRecordDecl>(recordType->
getDecl());
397 if (!record->hasTrivialDestructor())
return false;
398 if (record->hasNonTrivialCopyConstructor())
return false;
402 return !record->hasMutableFields();
416 if (isa<ParmVarDecl>(var))
436 if (!init)
return nullptr;
448 SmallVectorImpl<llvm::Type*> &elementTypes) {
450 assert(elementTypes.empty());
462 assert((2 * CGM.
getIntSize()).isMultipleOf(GenPtrAlign));
463 elementTypes.push_back(CGM.
IntTy);
464 elementTypes.push_back(CGM.
IntTy);
465 elementTypes.push_back(
473 for (
auto I : Helper->getCustomFieldTypes()) {
477 if (BlockAlign < Align)
479 assert(Offset % Align == 0);
481 elementTypes.push_back(I);
495 elementTypes.push_back(CGM.
IntTy);
496 elementTypes.push_back(CGM.
IntTy);
511 return FD->getType();
528 bool hasNonConstantCustomFields =
false;
529 if (
auto *OpenCLHelper =
531 hasNonConstantCustomFields =
532 !OpenCLHelper->areAllCustomFieldValuesConstant(info);
533 if (!block->
hasCaptures() && !hasNonConstantCustomFields) {
553 "Can't capture 'this' outside a method");
559 std::pair<CharUnits,CharUnits> tinfo
561 maxFieldAlign =
std::max(maxFieldAlign, tinfo.second);
563 layout.push_back(BlockLayoutChunk(tinfo.second, tinfo.first,
565 nullptr, llvmType, thisType));
569 for (
const auto &CI : block->
captures()) {
570 const VarDecl *variable = CI.getVariable();
572 if (CI.isEscapingByref()) {
578 maxFieldAlign =
std::max(maxFieldAlign, align);
583 "capture type differs from the variable type");
627 }
else if (CI.hasCopyExpr()) {
642 if (!record->hasTrivialDestructor()) {
645 if (!record->isExternallyVisible())
654 maxFieldAlign =
std::max(maxFieldAlign, align);
660 BlockLayoutChunk(align, size, lifetime, &CI, llvmType, VT));
664 if (layout.empty()) {
674 llvm::stable_sort(layout);
698 if (endAlign < maxFieldAlign) {
699 SmallVectorImpl<BlockLayoutChunk>::iterator
700 li = layout.begin() + 1, le = layout.end();
704 for (; li != le && endAlign < li->Alignment; ++li)
710 SmallVectorImpl<BlockLayoutChunk>::iterator first = li;
711 for (; li != le; ++li) {
712 assert(endAlign >= li->Alignment);
714 li->setIndex(info, elementTypes.size(), blockSize);
715 elementTypes.push_back(li->Type);
716 blockSize += li->Size;
720 if (endAlign >= maxFieldAlign) {
725 layout.erase(first, li);
729 assert(endAlign ==
getLowBit(blockSize));
733 if (endAlign < maxFieldAlign) {
735 CharUnits padding = newBlockSize - blockSize;
743 elementTypes.push_back(llvm::ArrayType::get(CGM.
Int8Ty,
745 blockSize = newBlockSize;
749 assert(endAlign >= maxFieldAlign);
750 assert(endAlign ==
getLowBit(blockSize));
754 for (SmallVectorImpl<BlockLayoutChunk>::iterator
755 li = layout.begin(), le = layout.end(); li != le; ++li) {
756 if (endAlign < li->Alignment) {
760 CharUnits padding = li->Alignment - endAlign;
761 elementTypes.push_back(llvm::ArrayType::get(CGM.
Int8Ty,
763 blockSize += padding;
766 assert(endAlign >= li->Alignment);
767 li->setIndex(info, elementTypes.size(), blockSize);
768 elementTypes.push_back(li->Type);
769 blockSize += li->Size;
794 if (blockInfo.CanBeGlobal)
return;
798 blockInfo.BlockAlign,
"block");
801 if (!blockInfo.NeedsCopyDispose)
return;
805 for (
const auto &CI : block->
captures()) {
808 if (CI.isByRef())
continue;
811 const VarDecl *variable = CI.getVariable();
832 "expected ObjC ARC to be enabled");
845 if (!blockInfo.DominatingIP)
846 blockInfo.DominatingIP = cast<llvm::Instruction>(addr.
getPointer());
850 if (useArrayEHCleanup)
854 destroyer, useArrayEHCleanup);
865 if (
const auto EWC = dyn_cast<ExprWithCleanups>(E)) {
866 assert(EWC->getNumObjects() != 0);
876 assert(head && *head);
891 assert(head &&
"destroying an empty chain");
896 }
while (head !=
nullptr);
912 return EmitBlockLiteral(blockInfo);
916 std::unique_ptr<CGBlockInfo> blockInfo;
921 return EmitBlockLiteral(*blockInfo);
936 BlockCGF.SanOpts = SanOpts;
937 auto *InvokeFn = BlockCGF.GenerateBlockFunction(
938 CurGD, blockInfo, LocalDeclMap, isLambdaConv, blockInfo.
CanBeGlobal);
939 auto *blockFn = llvm::ConstantExpr::getPointerCast(InvokeFn, GenVoidPtrTy);
948 assert(blockAddr.
isValid() &&
"block has no address!");
951 llvm::Constant *descriptor;
960 isa = llvm::ConstantExpr::getBitCast(blockISA, VoidPtrTy);
979 auto projectField = [&](
unsigned index,
const Twine &
name) ->
Address {
980 return Builder.CreateStructGEP(blockAddr, index,
name);
982 auto storeField = [&](
llvm::Value *value,
unsigned index,
const Twine &
name) {
983 Builder.CreateStore(value, projectField(index,
name));
993 storeField(value, index,
name);
999 addHeaderField(isa, getPointerSize(),
"block.isa");
1000 addHeaderField(llvm::ConstantInt::get(IntTy, flags.
getBitMask()),
1001 getIntSize(),
"block.flags");
1002 addHeaderField(llvm::ConstantInt::get(IntTy, 0), getIntSize(),
1007 getIntSize(),
"block.size");
1010 getIntSize(),
"block.align");
1012 addHeaderField(blockFn, GenVoidPtrSize,
"block.invoke");
1014 addHeaderField(descriptor, getPointerSize(),
"block.descriptor");
1015 else if (
auto *Helper =
1017 for (
auto I : Helper->getCustomFieldValues(*
this, blockInfo)) {
1031 if (blockDecl->capturesCXXThis()) {
1033 projectField(blockInfo.
CXXThisIndex,
"block.captured-this.addr");
1034 Builder.CreateStore(LoadCXXThis(), addr);
1038 for (
const auto &CI : blockDecl->captures()) {
1039 const VarDecl *variable = CI.getVariable();
1049 Address blockField = projectField(capture.
getIndex(),
"block.captured");
1055 if (blockDecl->isConversionFromLambda()) {
1059 }
else if (CI.isEscapingByref()) {
1060 if (BlockInfo && CI.isNested()) {
1066 src = Builder.CreateStructGEP(LoadBlockStruct(),
1068 "block.capture.addr");
1070 auto I = LocalDeclMap.find(variable);
1071 assert(I != LocalDeclMap.end());
1075 DeclRefExpr declRef(getContext(), const_cast<VarDecl *>(variable),
1079 src = EmitDeclRefLValue(&declRef).getAddress();
1086 if (CI.isEscapingByref()) {
1090 byrefPointer = Builder.CreateLoad(src,
"byref.capture");
1092 byrefPointer = Builder.CreateBitCast(src.getPointer(), VoidPtrTy);
1095 Builder.CreateStore(byrefPointer, blockField);
1098 }
else if (
const Expr *copyExpr = CI.getCopyExpr()) {
1099 if (blockDecl->isConversionFromLambda()) {
1108 EmitAggExpr(copyExpr, Slot);
1110 EmitSynthesizedCXXCopyCtor(blockField, src, copyExpr);
1115 Builder.CreateStore(src.getPointer(), blockField);
1121 llvm::Value *value = Builder.CreateLoad(src,
"captured");
1122 Builder.CreateStore(value, blockField);
1134 llvm::Value *value = Builder.CreateLoad(src,
"block.captured_block");
1135 value = EmitARCRetainNonBlock(value);
1138 Builder.CreateStore(value, blockField);
1149 DeclRefExpr declRef(getContext(), const_cast<VarDecl *>(variable),
1158 EmitExprAsInit(&l2r, &BlockFieldPseudoVar,
1164 if (!CI.isByRef()) {
1186 if (BlockDescriptorType)
1187 return BlockDescriptorType;
1190 getTypes().ConvertType(getContext().UnsignedLongTy);
1207 "struct.__block_descriptor", UnsignedLongTy, UnsignedLongTy);
1210 unsigned AddrSpace = 0;
1211 if (getLangOpts().OpenCL)
1213 BlockDescriptorType = llvm::PointerType::get(BlockDescriptorType, AddrSpace);
1214 return BlockDescriptorType;
1218 if (GenericBlockLiteralType)
1219 return GenericBlockLiteralType;
1221 llvm::Type *BlockDescPtrTy = getBlockDescriptorType();
1223 if (getLangOpts().OpenCL) {
1231 {IntTy, IntTy, getOpenCLRuntime().getGenericVoidPointerType()});
1232 if (
auto *Helper = getTargetCodeGenInfo().getTargetOpenCLBlockHelper()) {
1233 for (
auto I : Helper->getCustomFieldTypes())
1234 StructFields.push_back(I);
1237 StructFields,
"struct.__opencl_block_literal_generic");
1246 GenericBlockLiteralType =
1248 IntTy, IntTy, VoidPtrTy, BlockDescPtrTy);
1251 return GenericBlockLiteralType;
1265 if (getLangOpts().OpenCL) {
1270 llvm::Value *BlockDescriptor = Builder.CreatePointerCast(
1282 llvm::Value *FuncPtr = Builder.CreateStructGEP(GenBlockTy, BlockPtr, 2);
1283 Func = Builder.CreateAlignedLoad(FuncPtr, getPointerAlign());
1287 BlockPtr = Builder.CreatePointerCast(
1288 BlockPtr, llvm::PointerType::get(GenBlockTy, 0),
"block.literal");
1290 llvm::Value *FuncPtr = Builder.CreateStructGEP(GenBlockTy, BlockPtr, 3);
1293 BlockPtr = Builder.CreatePointerCast(BlockPtr, VoidPtrTy);
1299 Func = Builder.CreateAlignedLoad(FuncPtr, getPointerAlign());
1309 llvm::Type *BlockFTyPtr = llvm::PointerType::getUnqual(BlockFTy);
1310 Func = Builder.CreatePointerCast(Func, BlockFTyPtr);
1316 return EmitCall(FnInfo, Callee, ReturnValue, Args);
1320 assert(BlockInfo &&
"evaluating block ref without block information?");
1324 if (capture.
isConstant())
return LocalDeclMap.find(variable)->second;
1326 Address addr = Builder.CreateStructGEP(LoadBlockStruct(), capture.
getIndex(),
1327 "block.capture.addr");
1333 auto &byrefInfo = getBlockByrefInfo(variable);
1334 addr =
Address(Builder.CreateLoad(addr), byrefInfo.ByrefAlignment);
1336 auto byrefPointerType = llvm::PointerType::get(byrefInfo.Type, 0);
1337 addr = Builder.CreateBitCast(addr, byrefPointerType,
"byref.addr");
1339 addr = emitBlockByrefAddress(addr, byrefInfo,
true,
1345 "the capture field of a non-escaping variable should have a " 1348 addr = EmitLoadOfReference(MakeAddrLValue(addr, capture.
fieldType()));
1354 llvm::Constant *Addr) {
1355 bool Ok = EmittedGlobalBlocks.insert(std::make_pair(BE, Addr)).second;
1357 assert(Ok &&
"Trying to replace an already-existing global block!");
1363 if (llvm::Constant *
Block = getAddrOfGlobalBlockIfEmitted(BE))
1380 return getAddrOfGlobalBlockIfEmitted(BE);
1385 llvm::Constant *blockFn) {
1391 "Refusing to re-emit a global block.");
1395 auto fields = builder.beginStruct();
1414 fields.addInt(CGM.
IntTy, 0);
1421 fields.add(blockFn);
1426 }
else if (
auto *Helper =
1428 for (
auto I : Helper->getCustomFieldValues(CGM, blockInfo)) {
1433 unsigned AddrSpace = 0;
1437 llvm::GlobalVariable *literal = fields.finishAndCreateGlobal(
1438 "__block_literal_global", blockInfo.
BlockAlign,
1441 literal->addAttribute(
"objc_arc_inert");
1456 auto *InitVar =
new llvm::GlobalVariable(CGM.
getModule(), Init->getType(),
1458 Init,
".block_isa_init_ptr");
1459 InitVar->setSection(
".CRT$XCLa");
1466 llvm::Constant *Result =
1467 llvm::ConstantExpr::getPointerCast(literal, RequiredType);
1472 cast<llvm::Function>(blockFn->stripPointerCasts()), Result);
1479 assert(BlockInfo &&
"not emitting prologue of block invocation function?!");
1484 Builder.CreateStore(arg, alloc);
1489 DI->EmitDeclareOfBlockLiteralArgVariable(
1490 *BlockInfo, D->
getName(), argNum,
1491 cast<llvm::AllocaInst>(alloc.
getPointer()), Builder);
1500 BlockPointer = Builder.CreatePointerCast(
1503 getContext().getLangOpts().OpenCL
1510 assert(BlockInfo &&
"not in a block invocation function!");
1511 assert(BlockPointer &&
"no block pointer set!");
1519 bool IsLambdaConversionToBlock,
1520 bool BuildGlobalBlock) {
1527 BlockInfo = &blockInfo;
1532 for (DeclMapTy::const_iterator
i = ldm.begin(), e = ldm.end();
i != e; ++
i) {
1533 const auto *var = dyn_cast<
VarDecl>(
i->first);
1534 if (var && !var->hasLocalStorage())
1535 setAddrOfLocalVar(var,
i->second);
1545 QualType selfTy = getContext().VoidPtrTy;
1551 if (getLangOpts().OpenCL)
1552 selfTy = getContext().getPointerType(getContext().getAddrSpaceQualType(
1560 args.push_back(&SelfDecl);
1579 if (BuildGlobalBlock) {
1580 auto GenVoidPtrTy = getContext().getLangOpts().OpenCL
1584 llvm::ConstantExpr::getPointerCast(fn, GenVoidPtrTy));
1588 StartFunction(blockDecl, fnType->
getReturnType(), fn, fnInfo, args,
1599 Address Alloca = CreateTempAlloca(BlockPointer->getType(),
1605 Builder.CreateStore(BlockPointer, Alloca);
1612 Address addr = Builder.CreateStructGEP(
1613 LoadBlockStruct(), blockInfo.
CXXThisIndex,
"block.captured-this");
1614 CXXThisValue = Builder.CreateLoad(addr,
"this");
1618 for (
const auto &CI : blockDecl->
captures()) {
1619 const VarDecl *variable = CI.getVariable();
1623 CharUnits align = getContext().getDeclAlign(variable);
1625 CreateMemTemp(variable->
getType(), align,
"block.captured-const");
1627 Builder.CreateStore(capture.
getConstant(), alloca);
1629 setAddrOfLocalVar(variable, alloca);
1633 llvm::BasicBlock *entry = Builder.GetInsertBlock();
1634 llvm::BasicBlock::iterator entry_ptr = Builder.GetInsertPoint();
1637 if (IsLambdaConversionToBlock)
1638 EmitLambdaBlockInvokeBody();
1640 PGO.assignRegionCounters(
GlobalDecl(blockDecl), fn);
1641 incrementProfileCounter(blockDecl->
getBody());
1642 EmitStmt(blockDecl->
getBody());
1646 llvm::BasicBlock *resume = Builder.GetInsertBlock();
1650 Builder.SetInsertPoint(entry, entry_ptr);
1655 for (
const auto &CI : blockDecl->
captures()) {
1656 const VarDecl *variable = CI.getVariable();
1657 DI->EmitLocation(Builder, variable->
getLocation());
1663 auto addr = LocalDeclMap.find(variable)->second;
1664 (void)DI->EmitDeclareOfAutoVariable(variable, addr.getPointer(),
1669 DI->EmitDeclareOfBlockDeclRefVariable(
1670 variable, BlockPointerDbgLoc, Builder, blockInfo,
1671 entry_ptr == entry->end() ? nullptr : &*entry_ptr);
1675 DI->EmitLocation(Builder,
1676 cast<CompoundStmt>(blockDecl->
getBody())->getRBracLoc());
1680 if (resume ==
nullptr)
1681 Builder.ClearInsertionPoint();
1683 Builder.SetInsertPoint(resume);
1685 FinishFunction(cast<CompoundStmt>(blockDecl->
getBody())->getRBracLoc());
1690 static std::pair<BlockCaptureEntityKind, BlockFieldFlags>
1696 return std::make_pair(BlockCaptureEntityKind::CXXRecord,
BlockFieldFlags());
1703 return std::make_pair(BlockCaptureEntityKind::BlockObject, Flags);
1713 return std::make_pair(BlockCaptureEntityKind::NonTrivialCStruct,
1717 return std::make_pair(BlockCaptureEntityKind::ARCWeak, Flags);
1723 return std::make_pair(!isBlockPointer ? BlockCaptureEntityKind::ARCStrong
1724 : BlockCaptureEntityKind::BlockObject,
1738 return std::make_pair(BlockCaptureEntityKind::BlockObject, Flags);
1744 llvm_unreachable(
"after exhaustive PrimitiveCopyKind switch");
1747 static std::pair<BlockCaptureEntityKind, BlockFieldFlags>
1754 SmallVectorImpl<BlockCaptureManagedEntity> &ManagedCaptures) {
1766 ManagedCaptures.emplace_back(CopyInfo.first, DisposeInfo.first,
1767 CopyInfo.second, DisposeInfo.second, CI,
1772 llvm::sort(ManagedCaptures);
1784 : Addr(Addr), FieldFlags(Flags), LoadBlockVarAddr(LoadValue),
1789 if (LoadBlockVarAddr) {
1824 assert((StrKind != CaptureStrKind::Merged ||
1825 (E.CopyKind == E.DisposeKind && E.CopyFlags == E.DisposeFlags)) &&
1826 "different operations and flags");
1828 if (StrKind == CaptureStrKind::DisposeHelper) {
1829 Kind = E.DisposeKind;
1830 Flags = E.DisposeFlags;
1833 Flags = E.CopyFlags;
1837 case BlockCaptureEntityKind::CXXRecord: {
1840 llvm::raw_svector_ostream Out(TyStr);
1842 Str += llvm::to_string(TyStr.size()) + TyStr.c_str();
1845 case BlockCaptureEntityKind::ARCWeak:
1848 case BlockCaptureEntityKind::ARCStrong:
1851 case BlockCaptureEntityKind::BlockObject: {
1861 if (StrKind != CaptureStrKind::DisposeHelper) {
1865 if (StrKind != CaptureStrKind::CopyHelper) {
1879 case BlockCaptureEntityKind::NonTrivialCStruct: {
1885 std::string FuncStr;
1886 if (StrKind == CaptureStrKind::DisposeHelper)
1888 CaptureTy, Alignment, IsVolatile, Ctx);
1893 CaptureTy, Alignment, IsVolatile, Ctx);
1896 Str += llvm::to_string(FuncStr.size()) +
"_" + FuncStr;
1907 const SmallVectorImpl<BlockCaptureManagedEntity> &
Captures,
1909 assert((StrKind == CaptureStrKind::CopyHelper ||
1910 StrKind == CaptureStrKind::DisposeHelper) &&
1911 "unexpected CaptureStrKind");
1912 std::string
Name = StrKind == CaptureStrKind::CopyHelper
1913 ?
"__copy_helper_block_" 1914 :
"__destroy_helper_block_";
1919 Name += llvm::to_string(BlockAlignment.
getQuantity()) +
"_";
1921 for (
const BlockCaptureManagedEntity &E : Captures) {
1922 Name += llvm::to_string(E.Capture->getOffset().getQuantity());
1933 bool EHOnly = ForCopyHelper;
1935 switch (CaptureKind) {
1936 case BlockCaptureEntityKind::CXXRecord:
1937 case BlockCaptureEntityKind::ARCWeak:
1938 case BlockCaptureEntityKind::NonTrivialCStruct:
1939 case BlockCaptureEntityKind::ARCStrong: {
1943 CaptureKind == BlockCaptureEntityKind::ARCStrong
1953 case BlockCaptureEntityKind::BlockObject: {
1975 if (CapturesNonExternalType) {
1979 Fn->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
1996 std::string FuncName =
1998 CaptureStrKind::CopyHelper, CGM);
2000 if (llvm::GlobalValue *Func = CGM.
getModule().getNamedValue(FuncName))
2001 return llvm::ConstantExpr::getBitCast(Func, VoidPtrTy);
2009 args.push_back(&DstDecl);
2011 args.push_back(&SrcDecl);
2020 llvm::Function *Fn =
2024 Fn->setComdat(CGM.
getModule().getOrInsertComdat(FuncName));
2035 FunctionTy,
nullptr,
SC_Static,
false,
false);
2039 StartFunction(FD, ReturnTy, Fn, FI, args);
2043 Address src = GetAddrOfLocalVar(&SrcDecl);
2045 src = Builder.CreateBitCast(src, structPtrTy,
"block.source");
2047 Address dst = GetAddrOfLocalVar(&DstDecl);
2049 dst = Builder.CreateBitCast(dst, structPtrTy,
"block.dest");
2051 for (
const auto &CopiedCapture : CopiedCaptures) {
2057 unsigned index = capture.
getIndex();
2058 Address srcField = Builder.CreateStructGEP(src, index);
2059 Address dstField = Builder.CreateStructGEP(dst, index);
2061 switch (CopiedCapture.CopyKind) {
2062 case BlockCaptureEntityKind::CXXRecord:
2064 assert(CI.
getCopyExpr() &&
"copy expression for variable is missing");
2065 EmitSynthesizedCXXCopyCtor(dstField, srcField, CI.
getCopyExpr());
2067 case BlockCaptureEntityKind::ARCWeak:
2068 EmitARCCopyWeak(dstField, srcField);
2070 case BlockCaptureEntityKind::NonTrivialCStruct: {
2074 callCStructCopyConstructor(MakeAddrLValue(dstField, varType),
2075 MakeAddrLValue(srcField, varType));
2078 case BlockCaptureEntityKind::ARCStrong: {
2079 llvm::Value *srcValue = Builder.CreateLoad(srcField,
"blockcopy.src");
2084 auto *ty = cast<llvm::PointerType>(srcValue->getType());
2085 llvm::Value *null = llvm::ConstantPointerNull::get(ty);
2086 Builder.CreateStore(null, dstField);
2087 EmitARCStoreStrongCall(dstField, srcValue,
true);
2093 EmitARCRetainNonBlock(srcValue);
2099 cast<llvm::Instruction>(dstField.
getPointer())->eraseFromParent();
2103 case BlockCaptureEntityKind::BlockObject: {
2104 llvm::Value *srcValue = Builder.CreateLoad(srcField,
"blockcopy.src");
2105 srcValue = Builder.CreateBitCast(srcValue, VoidPtrTy);
2107 Builder.CreateBitCast(dstField.
getPointer(), VoidPtrTy);
2109 dstAddr, srcValue, llvm::ConstantInt::get(Int32Ty, flags.
getBitMask())
2130 return llvm::ConstantExpr::getBitCast(Fn, VoidPtrTy);
2142 static std::pair<BlockCaptureEntityKind, BlockFieldFlags>
2149 return std::make_pair(BlockCaptureEntityKind::BlockObject, Flags);
2154 return std::make_pair(BlockCaptureEntityKind::CXXRecord,
BlockFieldFlags());
2158 return std::make_pair(BlockCaptureEntityKind::ARCStrong,
2162 return std::make_pair(BlockCaptureEntityKind::ARCWeak,
2165 return std::make_pair(BlockCaptureEntityKind::NonTrivialCStruct,
2170 !LangOpts.ObjCAutoRefCount)
2171 return std::make_pair(BlockCaptureEntityKind::BlockObject,
2177 llvm_unreachable(
"after exhaustive DestructionKind switch");
2191 std::string FuncName =
2193 CaptureStrKind::DisposeHelper, CGM);
2195 if (llvm::GlobalValue *Func = CGM.
getModule().getNamedValue(FuncName))
2196 return llvm::ConstantExpr::getBitCast(Func, VoidPtrTy);
2204 args.push_back(&SrcDecl);
2213 llvm::Function *Fn =
2217 Fn->setComdat(CGM.
getModule().getOrInsertComdat(FuncName));
2227 FunctionTy,
nullptr,
SC_Static,
false,
false);
2231 StartFunction(FD, ReturnTy, Fn, FI, args);
2232 markAsIgnoreThreadCheckingAtRuntime(Fn);
2238 Address src = GetAddrOfLocalVar(&SrcDecl);
2240 src = Builder.CreateBitCast(src, structPtrTy,
"block");
2244 for (
const auto &DestroyedCapture : DestroyedCaptures) {
2260 return llvm::ConstantExpr::getBitCast(Fn, VoidPtrTy);
2296 void profileImpl(llvm::FoldingSetNodeID &
id)
const override {
2297 id.AddInteger(Flags.getBitMask());
2315 void profileImpl(llvm::FoldingSetNodeID &
id)
const override {
2335 llvm::ConstantPointerNull::get(cast<llvm::PointerType>(value->getType()));
2351 void profileImpl(llvm::FoldingSetNodeID &
id)
const override {
2361 ARCStrongBlockByrefHelpers(
CharUnits alignment)
2378 void profileImpl(llvm::FoldingSetNodeID &
id)
const override {
2388 const Expr *CopyExpr;
2392 const Expr *copyExpr)
2395 bool needsCopy()
const override {
return CopyExpr !=
nullptr; }
2398 if (!CopyExpr)
return;
2408 void profileImpl(llvm::FoldingSetNodeID &
id)
const override {
2409 id.AddPointer(VarType.getCanonicalType().getAsOpaquePtr());
2428 bool needsDispose()
const override {
2429 return VarType.isDestructedType();
2434 CGF.
pushDestroy(VarType.isDestructedType(), field, VarType);
2438 void profileImpl(llvm::FoldingSetNodeID &
id)
const override {
2439 id.AddPointer(VarType.getCanonicalType().getAsOpaquePtr());
2444 static llvm::Constant *
2453 args.push_back(&Dst);
2456 args.push_back(&Src);
2465 llvm::Function *Fn =
2470 = &Context.
Idents.
get(
"__Block_byref_object_copy_");
2504 generator.
emitCopy(CGF, destField, srcField);
2509 return llvm::ConstantExpr::getBitCast(Fn, CGF.
Int8PtrTy);
2521 static llvm::Constant *
2531 args.push_back(&Src);
2540 llvm::Function *Fn =
2542 "__Block_byref_object_dispose_",
2546 = &Context.
Idents.
get(
"__Block_byref_object_dispose_");
2563 auto byrefPtrType = byrefInfo.
Type->getPointerTo(0);
2572 return llvm::ConstantExpr::getBitCast(Fn, CGF.
Int8PtrTy);
2588 llvm::FoldingSetNodeID
id;
2589 generator.Profile(
id);
2594 if (node)
return static_cast<T*
>(
node);
2599 T *copy =
new (CGM.
getContext()) T(std::forward<T>(generator));
2608 CodeGenFunction::buildByrefHelpers(llvm::StructType &byrefType,
2609 const AutoVarEmission &emission) {
2610 const VarDecl &var = *emission.Variable;
2612 "only escaping __block variables need byref helpers");
2616 auto &byrefInfo = getBlockByrefInfo(&var);
2623 if (
const CXXRecordDecl *record = type->getAsCXXRecordDecl()) {
2624 const Expr *copyExpr =
2626 if (!copyExpr && record->hasTrivialDestructor())
return nullptr;
2629 CGM, byrefInfo, CXXByrefHelpers(valueAlignment, type, copyExpr));
2637 CGM, byrefInfo, NonTrivialCStructByrefHelpers(valueAlignment, type));
2641 if (!type->isObjCRetainableType())
return nullptr;
2659 ARCWeakByrefHelpers(valueAlignment));
2665 if (type->isBlockPointerType()) {
2667 ARCStrongBlockByrefHelpers(valueAlignment));
2673 ARCStrongByrefHelpers(valueAlignment));
2676 llvm_unreachable(
"fell out of lifetime switch!");
2680 if (type->isBlockPointerType()) {
2683 type->isObjCObjectPointerType()) {
2689 if (type.isObjCGCWeak())
2693 ObjectByrefHelpers(valueAlignment, flags));
2698 bool followForward) {
2699 auto &info = getBlockByrefInfo(var);
2700 return emitBlockByrefAddress(baseAddr, info, followForward, var->
getName());
2706 const llvm::Twine &
name) {
2708 if (followForward) {
2709 Address forwardingAddr = Builder.CreateStructGEP(baseAddr, 1,
"forwarding");
2713 return Builder.CreateStructGEP(baseAddr, info.
FieldIndex, name);
2732 auto it = BlockByrefInfos.find(D);
2733 if (it != BlockByrefInfos.end())
2736 llvm::StructType *byrefType =
2746 types.push_back(Int8PtrTy);
2747 size += getPointerSize();
2750 types.push_back(llvm::PointerType::getUnqual(byrefType));
2751 size += getPointerSize();
2754 types.push_back(Int32Ty);
2758 types.push_back(Int32Ty);
2762 bool hasCopyAndDispose = getContext().BlockRequiresCopying(Ty, D);
2763 if (hasCopyAndDispose) {
2765 types.push_back(Int8PtrTy);
2766 size += getPointerSize();
2769 types.push_back(Int8PtrTy);
2770 size += getPointerSize();
2773 bool HasByrefExtendedLayout =
false;
2775 if (getContext().getByrefLifetime(Ty, Lifetime, HasByrefExtendedLayout) &&
2776 HasByrefExtendedLayout) {
2778 types.push_back(Int8PtrTy);
2785 bool packed =
false;
2786 CharUnits varAlign = getContext().getDeclAlign(D);
2790 if (varOffset != size) {
2792 llvm::ArrayType::get(Int8Ty, (varOffset - size).getQuantity());
2794 types.push_back(paddingTy);
2802 types.push_back(varTy);
2804 byrefType->setBody(types, packed);
2807 info.
Type = byrefType;
2812 auto pair = BlockByrefInfos.insert({D, info});
2813 assert(pair.second &&
"info was inserted recursively?");
2814 return pair.first->second;
2824 llvm::StructType *byrefType = cast<llvm::StructType>(
2825 cast<llvm::PointerType>(addr.
getPointer()->getType())->getElementType());
2827 unsigned nextHeaderIndex = 0;
2830 const Twine &
name) {
2831 auto fieldAddr = Builder.CreateStructGEP(addr, nextHeaderIndex,
name);
2832 Builder.CreateStore(value, fieldAddr);
2835 nextHeaderOffset += fieldSize;
2841 const VarDecl &D = *emission.Variable;
2844 bool HasByrefExtendedLayout;
2846 bool ByRefHasLifetime =
2847 getContext().getByrefLifetime(type, ByrefLifetime, HasByrefExtendedLayout);
2855 V = Builder.CreateIntToPtr(Builder.getInt32(isa), Int8PtrTy,
"isa");
2856 storeHeaderField(V, getPointerSize(),
"byref.isa");
2859 storeHeaderField(addr.
getPointer(), getPointerSize(),
"byref.forwarding");
2866 if (ByRefHasLifetime) {
2868 else switch (ByrefLifetime) {
2886 printf(
"\n Inline flag for BYREF variable layout (%d):", flags.getBitMask());
2888 printf(
" BLOCK_BYREF_HAS_COPY_DISPOSE");
2892 printf(
" BLOCK_BYREF_LAYOUT_EXTENDED");
2894 printf(
" BLOCK_BYREF_LAYOUT_STRONG");
2896 printf(
" BLOCK_BYREF_LAYOUT_WEAK");
2898 printf(
" BLOCK_BYREF_LAYOUT_UNRETAINED");
2900 printf(
" BLOCK_BYREF_LAYOUT_NON_OBJECT");
2905 storeHeaderField(llvm::ConstantInt::get(IntTy, flags.getBitMask()),
2906 getIntSize(),
"byref.flags");
2909 V = llvm::ConstantInt::get(IntTy, byrefSize.getQuantity());
2910 storeHeaderField(V, getIntSize(),
"byref.size");
2913 storeHeaderField(helpers->
CopyHelper, getPointerSize(),
2914 "byref.copyHelper");
2916 "byref.disposeHelper");
2919 if (ByRefHasLifetime && HasByrefExtendedLayout) {
2921 storeHeaderField(layoutInfo, getPointerSize(),
"byref.layout");
2929 Builder.CreateBitCast(V, Int8PtrTy),
2930 llvm::ConstantInt::get(Int32Ty, flags.
getBitMask())
2934 EmitRuntimeCallOrInvoke(F, args);
2936 EmitNounwindRuntimeCall(F, args);
2941 bool LoadBlockVarAddr,
bool CanThrow) {
2942 EHStack.pushCleanup<CallBlockRelease>(
Kind, Addr, Flags, LoadBlockVarAddr,
2948 llvm::Constant *C) {
2949 auto *GV = cast<llvm::GlobalValue>(C->stripPointerCasts());
2956 assert((isa<llvm::Function>(C->stripPointerCasts()) ||
2957 isa<llvm::GlobalVariable>(C->stripPointerCasts())) &&
2958 "expected Function or GlobalVariable");
2961 for (
const auto &Result : DC->
lookup(&II))
2962 if ((ND = dyn_cast<FunctionDecl>(Result)) ||
2963 (ND = dyn_cast<
VarDecl>(Result)))
2967 if (GV->isDeclaration() && (!ND || !ND->hasAttr<DLLExportAttr>())) {
2968 GV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
2971 GV->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
2976 if (CGM.
getLangOpts().BlocksRuntimeOptional && GV->isDeclaration() &&
2977 GV->hasExternalLinkage())
2978 GV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage);
2984 if (BlockObjectDispose)
2985 return BlockObjectDispose;
2988 llvm::FunctionType *fty
2989 = llvm::FunctionType::get(VoidTy, args,
false);
2990 BlockObjectDispose = CreateRuntimeFunction(fty,
"_Block_object_dispose");
2992 *
this, cast<llvm::Constant>(BlockObjectDispose.getCallee()));
2993 return BlockObjectDispose;
2997 if (BlockObjectAssign)
2998 return BlockObjectAssign;
3000 llvm::Type *args[] = { Int8PtrTy, Int8PtrTy, Int32Ty };
3001 llvm::FunctionType *fty
3002 = llvm::FunctionType::get(VoidTy, args,
false);
3003 BlockObjectAssign = CreateRuntimeFunction(fty,
"_Block_object_assign");
3005 *
this, cast<llvm::Constant>(BlockObjectAssign.getCallee()));
3006 return BlockObjectAssign;
3010 if (NSConcreteGlobalBlock)
3011 return NSConcreteGlobalBlock;
3013 NSConcreteGlobalBlock = GetOrCreateLLVMGlobal(
"_NSConcreteGlobalBlock",
3014 Int8PtrTy->getPointerTo(),
3017 return NSConcreteGlobalBlock;
3021 if (NSConcreteStackBlock)
3022 return NSConcreteStackBlock;
3024 NSConcreteStackBlock = GetOrCreateLLVMGlobal(
"_NSConcreteStackBlock",
3025 Int8PtrTy->getPointerTo(),
3028 return NSConcreteStackBlock;
const CGFunctionInfo & arrangeBuiltinFunctionDeclaration(QualType resultType, const FunctionArgList &args)
A builtin function is a freestanding function using the default C conventions.
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.
Address CreateStructGEP(Address Addr, unsigned Index, const llvm::Twine &Name="")
QualType getAddrSpaceQualType(QualType T, LangAS AddressSpace) const
Return the uniqued reference to the type for an address space qualified type with the specified type ...
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...
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, ConstexprSpecKind ConstexprKind=CSK_unspecified)
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.
void SetLLVMFunctionAttributes(GlobalDecl GD, const CGFunctionInfo &Info, llvm::Function *F)
Set the LLVM function attributes (sext, zext, etc).
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.
BlockVarCopyInit getBlockVarCopyInit(const VarDecl *VD) const
Get the copy initialization expression of the VarDecl VD, or nullptr if none exists.
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.
QualType getLValueReferenceType(QualType T, bool SpelledAsLValue=true) const
Return the uniqued reference to the type for an lvalue reference to the specified type...
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...
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.
Objects with "hidden" visibility are not seen by the dynamic linker.
CGBlockInfo(const BlockDecl *blockDecl, StringRef Name)
const T * getAs() const
Member-template getAs<specific type>'.
EHScopeStack::stable_iterator getCleanup() const
static void setBlockHelperAttributesVisibility(bool CapturesNonExternalType, llvm::Function *Fn, const CGFunctionInfo &FI, CodeGenModule &CGM)
bool supportsCOMDAT() const
LangAS
Defines the address space values used by the address space qualifier of QualType. ...
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.
const internal::VariadicDynCastAllOfMatcher< Stmt, BlockExpr > blockExpr
Matches a reference to a block.
static void pushCaptureCleanup(BlockCaptureEntityKind CaptureKind, Address Field, QualType CaptureType, BlockFieldFlags Flags, bool ForCopyHelper, VarDecl *Var, CodeGenFunction &CGF)
static void destroyBlockInfos(CGBlockInfo *info)
Destroy a chain of block layouts.
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
uint64_t getPointerWidth(unsigned AddrSpace) const
Return the width of pointers on this target, for the specified address space.
static std::string getBlockCaptureStr(const BlockCaptureManagedEntity &E, CaptureStrKind StrKind, CharUnits BlockAlignment, CodeGenModule &CGM)
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 isObjCInertUnsafeUnretainedType() const
Was this type written with the special inert-in-ARC __unsafe_unretained qualifier?
bool HasCapturedVariableLayout
HasCapturedVariableLayout : True if block has captured variables and their layout meta-data has been ...
FullExpr - Represents a "full-expression" node.
SourceLocation getBeginLoc() const LLVM_READONLY
bool isReferenceType() const
Denotes a cleanup that should run when a scope is exited using exceptional control flow (a throw stat...
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++.
__DEVICE__ int max(int __a, int __b)
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.
Expr * getCopyExpr() const
virtual std::string getRCBlockLayoutStr(CodeGen::CodeGenModule &CGM, const CGBlockInfo &blockInfo)
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 isVolatileQualified() const
Determine whether this type is volatile-qualified.
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()
static std::string getNonTrivialCopyConstructorStr(QualType QT, CharUnits Alignment, bool IsVolatile, ASTContext &Ctx)
The type does not fall into any of the following categories.
This object can be modified without requiring retains or releases.
StringRef Name
Name - The name of the block, kindof.
bool isEscapingByref() const
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.
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.
StringRef getBlockMangledName(GlobalDecl GD, const BlockDecl *BD)
static void findBlockCapturedManagedEntities(const CGBlockInfo &BlockInfo, const LangOptions &LangOpts, SmallVectorImpl< BlockCaptureManagedEntity > &ManagedCaptures)
Find the set of block captures that need to be explicitly copied or destroy.
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.
Represents a block literal declaration, which is like an unnamed FunctionDecl.
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).
unsigned long ulong
An unsigned 64-bit integer.
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.
Represents a C++ destructor within a class.
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...
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)
llvm::FunctionCallee getBlockObjectAssign()
bool isa(CodeGen::Address addr)
QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const
Return a normal function type with a typed argument list.
static bool CanThrow(Expr *E, ASTContext &Ctx)
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)
Address GetAddrOfBlockDecl(const VarDecl *var)
static QualType getCaptureFieldType(const CodeGenFunction &CGF, const BlockDecl::Capture &CI)
llvm::Function * getInvokeFunction(const Expr *E)
GlobalDecl - represents a global declaration.
static std::string getBlockDescriptorName(const CGBlockInfo &BlockInfo, CodeGenModule &CGM)
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="")
llvm::FunctionCallee getBlockObjectDispose()
Assigning into this object requires the old value to be released and the new value to be retained...
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)
void BuildBlockRelease(llvm::Value *DeclPtr, BlockFieldFlags flags, bool CanThrow)
QualType getReturnType() const
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
SourceLocation getBeginLoc() const LLVM_READONLY
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 std::string getCopyDestroyHelperFuncName(const SmallVectorImpl< BlockCaptureManagedEntity > &Captures, CharUnits BlockAlignment, CaptureStrKind StrKind, CodeGenModule &CGM)
static void configureBlocksRuntimeObject(CodeGenModule &CGM, llvm::Constant *C)
Adjust the declaration of something from the blocks API.
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 CapturesNonExternalType
Indicates whether an object of a non-external C++ class is captured.
static bool cxxDestructorCanThrow(QualType T)
Check if T is a C++ class that has a destructor that can throw.
bool isConversionFromLambda() const
void enterNonTrivialFullExpression(const FullExpr *E)
Enter a full-expression with a non-trivial number of objects to clean up.
llvm::DenseMap< const VarDecl *, Capture > Captures
The mapping of allocated indexes within the block.
bool isNonEscapingByref() const
Indicates the capture is a __block variable that is never captured by an escaping block...
bool isObjCObjectPointerType() const
static bool isBlockPointer(Expr *Arg)
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.
void SetLLVMFunctionAttributesForDefinition(const Decl *D, llvm::Function *F)
Set the LLVM function attributes which only apply to a function definition.
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.
MangleContext & getMangleContext()
Gets the mangle context.
void enterByrefCleanup(CleanupKind Kind, Address Addr, BlockFieldFlags Flags, bool LoadBlockVarAddr, bool CanThrow)
Enter a cleanup to destroy a __block variable.
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.
virtual void mangleTypeName(QualType T, raw_ostream &)=0
Generates a unique string for an externally visible type for use with TBAA or type uniquing...
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.
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,...) __attribute__((format(printf
bool hasObjCLifetime() const
llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)
bool isEscapingByref() const
Indicates the capture is a __block variable that is captured by a block that can potentially escape (...
llvm::Module & getModule() const
LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource Source=AlignmentSource::Type)
llvm::DenseMap< const Decl *, Address > DeclMapTy
static void enterBlockScope(CodeGenFunction &CGF, BlockDecl *block)
Enter the scope of a block.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
StructBuilder beginStruct(llvm::StructType *structTy=nullptr)
CanQualType UnsignedLongTy
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...
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.
static std::string getNonTrivialDestructorStr(QualType QT, CharUnits Alignment, bool IsVolatile, ASTContext &Ctx)
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.
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
virtual ~BlockByrefHelpers()
CharUnits BlockHeaderForcedGapSize
SourceLocation getEndLoc() const LLVM_READONLY
llvm::Value * EmitARCRetainBlock(llvm::Value *value, bool mandatory)
Retain the given block, with _Block_copy semantics.
uint64_t getPointerAlign(unsigned AddrSpace) const
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.
CGCXXABI & getCXXABI() const
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.
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.
const LangOptions & getLangOpts() const
unsigned getTargetAddressSpace(QualType T) const
llvm::CallInst * EmitNounwindRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
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
static std::pair< BlockCaptureEntityKind, BlockFieldFlags > computeDestroyInfoForBlockCapture(const BlockDecl::Capture &CI, QualType T, const LangOptions &LangOpts)
bool isExternallyVisible() const
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.