25 #include "llvm/ADT/SmallSet.h" 26 #include "llvm/IR/DataLayout.h" 27 #include "llvm/IR/Module.h" 28 #include "llvm/Support/ScopedPrinter.h" 32 using namespace clang;
33 using namespace CodeGen;
36 : Name(name), CXXThisIndex(0), CanBeGlobal(
false), NeedsCopyDispose(
false),
37 HasCXXObject(
false), UsesStret(
false), HasCapturedVariableLayout(
false),
38 CapturesNonExternalType(
false), LocalAddress(
Address::invalid()),
39 StructureType(nullptr), Block(block), DominatingIP(nullptr) {
43 if (!name.empty() && name[0] ==
'\01')
44 name = name.substr(1);
53 llvm::Constant *blockFn);
82 struct BlockCaptureManagedEntity {
94 : CopyKind(CopyType), DisposeKind(DisposeType), CopyFlags(CopyFlags),
95 DisposeFlags(DisposeFlags), CI(&CI), Capture(&Capture) {}
97 bool operator<(
const BlockCaptureManagedEntity &Other)
const {
98 return Capture->
getOffset() < Other.Capture->getOffset();
115 SmallVectorImpl<BlockCaptureManagedEntity> &ManagedCaptures);
124 std::string
Name =
"__block_descriptor_";
138 for (
const BlockCaptureManagedEntity &E : ManagedCaptures) {
139 Name += llvm::to_string(E.Capture->getOffset().getQuantity());
141 if (E.CopyKind == E.DisposeKind) {
145 "shouldn't see BlockCaptureManagedEntity that is None");
161 std::string TypeAtEncoding =
165 std::replace(TypeAtEncoding.begin(), TypeAtEncoding.end(),
'@',
'\1');
166 Name +=
"e" + llvm::to_string(TypeAtEncoding.size()) +
"_" + TypeAtEncoding;
189 llvm::IntegerType *
ulong =
191 llvm::PointerType *i8p =
nullptr;
194 llvm::Type::getInt8PtrTy(
199 std::string descName;
205 if (llvm::GlobalValue *desc = CGM.
getModule().getNamedValue(descName))
206 return llvm::ConstantExpr::getBitCast(desc,
216 elements.addInt(ulong, 0);
225 bool hasInternalHelper =
false;
229 elements.add(copyHelper);
233 elements.add(disposeHelper);
235 if (cast<llvm::Function>(copyHelper->getOperand(0))->hasInternalLinkage() ||
236 cast<llvm::Function>(disposeHelper->getOperand(0))
237 ->hasInternalLinkage())
238 hasInternalHelper =
true;
242 std::string typeAtEncoding =
244 elements.add(llvm::ConstantExpr::getBitCast(
255 elements.addNullPointer(i8p);
257 unsigned AddrSpace = 0;
261 llvm::GlobalValue::LinkageTypes linkage;
262 if (descName.empty()) {
264 descName =
"__block_descriptor_tmp";
265 }
else if (hasInternalHelper) {
270 linkage = llvm::GlobalValue::LinkOnceODRLinkage;
273 llvm::GlobalVariable *global =
275 true, linkage, AddrSpace);
277 if (linkage == llvm::GlobalValue::LinkOnceODRLinkage) {
279 global->setComdat(CGM.
getModule().getOrInsertComdat(descName));
281 global->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
300 struct objc_class *isa;
328 _ResultType (*invoke)(Block_literal *, _ParamTypes...);
331 struct Block_descriptor *block_descriptor;
334 _CapturesTypes captures...;
340 struct BlockLayoutChunk {
352 : Alignment(align), Size(size), Lifetime(lifetime),
353 Capture(capture),
Type(type), FieldType(fieldType) {}
369 bool operator<(
const BlockLayoutChunk &left,
const BlockLayoutChunk &right) {
370 if (left.Alignment != right.Alignment)
371 return left.Alignment > right.Alignment;
373 auto getPrefOrder = [](
const BlockLayoutChunk &chunk) {
374 if (chunk.Capture && chunk.Capture->isByRef())
383 return getPrefOrder(left) < getPrefOrder(right);
393 if (!recordType)
return true;
395 const auto *record = cast<CXXRecordDecl>(recordType->
getDecl());
398 if (!record->hasTrivialDestructor())
return false;
399 if (record->hasNonTrivialCopyConstructor())
return false;
403 return !record->hasMutableFields();
417 if (isa<ParmVarDecl>(var))
437 if (!init)
return nullptr;
449 SmallVectorImpl<llvm::Type*> &elementTypes) {
451 assert(elementTypes.empty());
463 assert((2 * CGM.
getIntSize()).isMultipleOf(GenPtrAlign));
464 elementTypes.push_back(CGM.
IntTy);
465 elementTypes.push_back(CGM.
IntTy);
466 elementTypes.push_back(
474 for (
auto I : Helper->getCustomFieldTypes()) {
478 if (BlockAlign < Align)
480 assert(Offset % Align == 0);
482 elementTypes.push_back(I);
496 elementTypes.push_back(CGM.
IntTy);
497 elementTypes.push_back(CGM.
IntTy);
512 return FD->getType();
529 bool hasNonConstantCustomFields =
false;
530 if (
auto *OpenCLHelper =
532 hasNonConstantCustomFields =
533 !OpenCLHelper->areAllCustomFieldValuesConstant(info);
534 if (!block->
hasCaptures() && !hasNonConstantCustomFields) {
554 "Can't capture 'this' outside a method");
560 std::pair<CharUnits,CharUnits> tinfo
562 maxFieldAlign =
std::max(maxFieldAlign, tinfo.second);
564 layout.push_back(BlockLayoutChunk(tinfo.second, tinfo.first,
566 nullptr, llvmType, thisType));
570 for (
const auto &CI : block->
captures()) {
571 const VarDecl *variable = CI.getVariable();
573 if (CI.isEscapingByref()) {
579 maxFieldAlign =
std::max(maxFieldAlign, align);
584 "capture type differs from the variable type");
628 }
else if (CI.hasCopyExpr()) {
643 if (!record->hasTrivialDestructor()) {
646 if (!record->isExternallyVisible())
655 maxFieldAlign =
std::max(maxFieldAlign, align);
661 BlockLayoutChunk(align, size, lifetime, &CI, llvmType, VT));
665 if (layout.empty()) {
675 llvm::stable_sort(layout);
699 if (endAlign < maxFieldAlign) {
700 SmallVectorImpl<BlockLayoutChunk>::iterator
701 li = layout.begin() + 1, le = layout.end();
705 for (; li != le && endAlign < li->Alignment; ++li)
711 SmallVectorImpl<BlockLayoutChunk>::iterator first = li;
712 for (; li != le; ++li) {
713 assert(endAlign >= li->Alignment);
715 li->setIndex(info, elementTypes.size(), blockSize);
716 elementTypes.push_back(li->Type);
717 blockSize += li->Size;
721 if (endAlign >= maxFieldAlign) {
726 layout.erase(first, li);
730 assert(endAlign ==
getLowBit(blockSize));
734 if (endAlign < maxFieldAlign) {
736 CharUnits padding = newBlockSize - blockSize;
744 elementTypes.push_back(llvm::ArrayType::get(CGM.
Int8Ty,
746 blockSize = newBlockSize;
750 assert(endAlign >= maxFieldAlign);
751 assert(endAlign ==
getLowBit(blockSize));
755 for (SmallVectorImpl<BlockLayoutChunk>::iterator
756 li = layout.begin(), le = layout.end(); li != le; ++li) {
757 if (endAlign < li->Alignment) {
761 CharUnits padding = li->Alignment - endAlign;
762 elementTypes.push_back(llvm::ArrayType::get(CGM.
Int8Ty,
764 blockSize += padding;
767 assert(endAlign >= li->Alignment);
768 li->setIndex(info, elementTypes.size(), blockSize);
769 elementTypes.push_back(li->Type);
770 blockSize += li->Size;
795 if (blockInfo.CanBeGlobal)
return;
799 blockInfo.BlockAlign,
"block");
802 if (!blockInfo.NeedsCopyDispose)
return;
806 for (
const auto &CI : block->
captures()) {
809 if (CI.isByRef())
continue;
812 const VarDecl *variable = CI.getVariable();
833 "expected ObjC ARC to be enabled");
846 if (!blockInfo.DominatingIP)
847 blockInfo.DominatingIP = cast<llvm::Instruction>(addr.
getPointer());
851 if (useArrayEHCleanup)
855 destroyer, useArrayEHCleanup);
866 if (
const auto EWC = dyn_cast<ExprWithCleanups>(E)) {
867 assert(EWC->getNumObjects() != 0);
877 assert(head && *head);
892 assert(head &&
"destroying an empty chain");
897 }
while (head !=
nullptr);
913 return EmitBlockLiteral(blockInfo);
917 std::unique_ptr<CGBlockInfo> blockInfo;
922 return EmitBlockLiteral(*blockInfo);
937 BlockCGF.SanOpts = SanOpts;
938 auto *InvokeFn = BlockCGF.GenerateBlockFunction(
939 CurGD, blockInfo, LocalDeclMap, isLambdaConv, blockInfo.
CanBeGlobal);
940 auto *blockFn = llvm::ConstantExpr::getPointerCast(InvokeFn, GenVoidPtrTy);
949 assert(blockAddr.
isValid() &&
"block has no address!");
952 llvm::Constant *descriptor;
961 isa = llvm::ConstantExpr::getBitCast(blockISA, VoidPtrTy);
980 auto projectField = [&](
unsigned index,
const Twine &
name) ->
Address {
981 return Builder.CreateStructGEP(blockAddr, index,
name);
983 auto storeField = [&](
llvm::Value *value,
unsigned index,
const Twine &
name) {
984 Builder.CreateStore(value, projectField(index,
name));
994 storeField(value, index,
name);
1000 addHeaderField(isa, getPointerSize(),
"block.isa");
1001 addHeaderField(llvm::ConstantInt::get(IntTy, flags.
getBitMask()),
1002 getIntSize(),
"block.flags");
1003 addHeaderField(llvm::ConstantInt::get(IntTy, 0), getIntSize(),
1008 getIntSize(),
"block.size");
1011 getIntSize(),
"block.align");
1013 addHeaderField(blockFn, GenVoidPtrSize,
"block.invoke");
1015 addHeaderField(descriptor, getPointerSize(),
"block.descriptor");
1016 else if (
auto *Helper =
1018 for (
auto I : Helper->getCustomFieldValues(*
this, blockInfo)) {
1032 if (blockDecl->capturesCXXThis()) {
1034 projectField(blockInfo.
CXXThisIndex,
"block.captured-this.addr");
1035 Builder.CreateStore(LoadCXXThis(), addr);
1039 for (
const auto &CI : blockDecl->captures()) {
1040 const VarDecl *variable = CI.getVariable();
1050 Address blockField = projectField(capture.
getIndex(),
"block.captured");
1056 if (blockDecl->isConversionFromLambda()) {
1060 }
else if (CI.isEscapingByref()) {
1061 if (BlockInfo && CI.isNested()) {
1067 src = Builder.CreateStructGEP(LoadBlockStruct(),
1069 "block.capture.addr");
1071 auto I = LocalDeclMap.find(variable);
1072 assert(I != LocalDeclMap.end());
1076 DeclRefExpr declRef(getContext(), const_cast<VarDecl *>(variable),
1080 src = EmitDeclRefLValue(&declRef).getAddress(*
this);
1087 if (CI.isEscapingByref()) {
1091 byrefPointer = Builder.CreateLoad(src,
"byref.capture");
1093 byrefPointer = Builder.CreateBitCast(src.getPointer(), VoidPtrTy);
1096 Builder.CreateStore(byrefPointer, blockField);
1099 }
else if (
const Expr *copyExpr = CI.getCopyExpr()) {
1100 if (blockDecl->isConversionFromLambda()) {
1109 EmitAggExpr(copyExpr, Slot);
1111 EmitSynthesizedCXXCopyCtor(blockField, src, copyExpr);
1116 Builder.CreateStore(src.getPointer(), blockField);
1122 llvm::Value *value = Builder.CreateLoad(src,
"captured");
1123 Builder.CreateStore(value, blockField);
1135 llvm::Value *value = Builder.CreateLoad(src,
"block.captured_block");
1136 value = EmitARCRetainNonBlock(value);
1139 Builder.CreateStore(value, blockField);
1150 DeclRefExpr declRef(getContext(), const_cast<VarDecl *>(variable),
1159 EmitExprAsInit(&l2r, &BlockFieldPseudoVar,
1165 if (!CI.isByRef()) {
1187 if (BlockDescriptorType)
1188 return BlockDescriptorType;
1191 getTypes().ConvertType(getContext().UnsignedLongTy);
1208 "struct.__block_descriptor", UnsignedLongTy, UnsignedLongTy);
1211 unsigned AddrSpace = 0;
1212 if (getLangOpts().
OpenCL)
1214 BlockDescriptorType = llvm::PointerType::get(BlockDescriptorType, AddrSpace);
1215 return BlockDescriptorType;
1219 if (GenericBlockLiteralType)
1220 return GenericBlockLiteralType;
1222 llvm::Type *BlockDescPtrTy = getBlockDescriptorType();
1224 if (getLangOpts().
OpenCL) {
1232 {IntTy, IntTy, getOpenCLRuntime().getGenericVoidPointerType()});
1233 if (
auto *Helper = getTargetCodeGenInfo().getTargetOpenCLBlockHelper()) {
1234 for (
auto I : Helper->getCustomFieldTypes())
1235 StructFields.push_back(I);
1238 StructFields,
"struct.__opencl_block_literal_generic");
1247 GenericBlockLiteralType =
1249 IntTy, IntTy, VoidPtrTy, BlockDescPtrTy);
1252 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);
1488 DI->EmitDeclareOfBlockLiteralArgVariable(
1489 *BlockInfo, D->
getName(), argNum,
1490 cast<llvm::AllocaInst>(alloc.
getPointer()), Builder);
1499 BlockPointer = Builder.CreatePointerCast(
1502 getContext().getLangOpts().
OpenCL 1509 assert(BlockInfo &&
"not in a block invocation function!");
1510 assert(BlockPointer &&
"no block pointer set!");
1518 bool IsLambdaConversionToBlock,
1519 bool BuildGlobalBlock) {
1526 BlockInfo = &blockInfo;
1531 for (DeclMapTy::const_iterator i = ldm.begin(), e = ldm.end(); i != e; ++i) {
1532 const auto *var = dyn_cast<
VarDecl>(i->first);
1533 if (var && !var->hasLocalStorage())
1534 setAddrOfLocalVar(var, i->second);
1544 QualType selfTy = getContext().VoidPtrTy;
1550 if (getLangOpts().
OpenCL)
1551 selfTy = getContext().getPointerType(getContext().getAddrSpaceQualType(
1559 args.push_back(&SelfDecl);
1578 if (BuildGlobalBlock) {
1579 auto GenVoidPtrTy = getContext().getLangOpts().OpenCL
1583 llvm::ConstantExpr::getPointerCast(fn, GenVoidPtrTy));
1587 StartFunction(blockDecl, fnType->
getReturnType(), fn, fnInfo, args,
1598 Address Alloca = CreateTempAlloca(BlockPointer->getType(),
1604 Builder.CreateStore(BlockPointer, Alloca);
1611 Address addr = Builder.CreateStructGEP(
1612 LoadBlockStruct(), blockInfo.
CXXThisIndex,
"block.captured-this");
1613 CXXThisValue = Builder.CreateLoad(addr,
"this");
1617 for (
const auto &CI : blockDecl->
captures()) {
1618 const VarDecl *variable = CI.getVariable();
1624 CreateMemTemp(variable->
getType(),
align,
"block.captured-const");
1626 Builder.CreateStore(capture.
getConstant(), alloca);
1628 setAddrOfLocalVar(variable, alloca);
1632 llvm::BasicBlock *entry = Builder.GetInsertBlock();
1633 llvm::BasicBlock::iterator entry_ptr = Builder.GetInsertPoint();
1636 if (IsLambdaConversionToBlock)
1637 EmitLambdaBlockInvokeBody();
1639 PGO.assignRegionCounters(
GlobalDecl(blockDecl), fn);
1640 incrementProfileCounter(blockDecl->
getBody());
1641 EmitStmt(blockDecl->
getBody());
1645 llvm::BasicBlock *resume = Builder.GetInsertBlock();
1649 Builder.SetInsertPoint(entry, entry_ptr);
1654 for (
const auto &CI : blockDecl->
captures()) {
1655 const VarDecl *variable = CI.getVariable();
1656 DI->EmitLocation(Builder, variable->
getLocation());
1661 auto addr = LocalDeclMap.find(variable)->second;
1662 (void)DI->EmitDeclareOfAutoVariable(variable, addr.getPointer(),
1667 DI->EmitDeclareOfBlockDeclRefVariable(
1668 variable, BlockPointerDbgLoc, Builder, blockInfo,
1669 entry_ptr == entry->end() ? nullptr : &*entry_ptr);
1673 DI->EmitLocation(Builder,
1674 cast<CompoundStmt>(blockDecl->
getBody())->getRBracLoc());
1678 if (resume ==
nullptr)
1679 Builder.ClearInsertionPoint();
1681 Builder.SetInsertPoint(resume);
1683 FinishFunction(cast<CompoundStmt>(blockDecl->
getBody())->getRBracLoc());
1688 static std::pair<BlockCaptureEntityKind, BlockFieldFlags>
1694 return std::make_pair(BlockCaptureEntityKind::CXXRecord,
BlockFieldFlags());
1701 return std::make_pair(BlockCaptureEntityKind::BlockObject, Flags);
1711 return std::make_pair(BlockCaptureEntityKind::NonTrivialCStruct,
1715 return std::make_pair(BlockCaptureEntityKind::ARCWeak, Flags);
1721 return std::make_pair(!isBlockPointer ? BlockCaptureEntityKind::ARCStrong
1722 : BlockCaptureEntityKind::BlockObject,
1736 return std::make_pair(BlockCaptureEntityKind::BlockObject, Flags);
1742 llvm_unreachable(
"after exhaustive PrimitiveCopyKind switch");
1745 static std::pair<BlockCaptureEntityKind, BlockFieldFlags>
1752 SmallVectorImpl<BlockCaptureManagedEntity> &ManagedCaptures) {
1764 ManagedCaptures.emplace_back(CopyInfo.first, DisposeInfo.first,
1765 CopyInfo.second, DisposeInfo.second, CI,
1770 llvm::sort(ManagedCaptures);
1782 : Addr(Addr), FieldFlags(Flags), LoadBlockVarAddr(LoadValue),
1787 if (LoadBlockVarAddr) {
1822 assert((StrKind != CaptureStrKind::Merged ||
1823 (E.CopyKind == E.DisposeKind && E.CopyFlags == E.DisposeFlags)) &&
1824 "different operations and flags");
1826 if (StrKind == CaptureStrKind::DisposeHelper) {
1827 Kind = E.DisposeKind;
1828 Flags = E.DisposeFlags;
1831 Flags = E.CopyFlags;
1835 case BlockCaptureEntityKind::CXXRecord: {
1838 llvm::raw_svector_ostream Out(TyStr);
1840 Str += llvm::to_string(TyStr.size()) + TyStr.c_str();
1843 case BlockCaptureEntityKind::ARCWeak:
1846 case BlockCaptureEntityKind::ARCStrong:
1849 case BlockCaptureEntityKind::BlockObject: {
1859 if (StrKind != CaptureStrKind::DisposeHelper) {
1863 if (StrKind != CaptureStrKind::CopyHelper) {
1877 case BlockCaptureEntityKind::NonTrivialCStruct: {
1883 std::string FuncStr;
1884 if (StrKind == CaptureStrKind::DisposeHelper)
1886 CaptureTy, Alignment, IsVolatile, Ctx);
1891 CaptureTy, Alignment, IsVolatile, Ctx);
1894 Str += llvm::to_string(FuncStr.size()) +
"_" + FuncStr;
1905 const SmallVectorImpl<BlockCaptureManagedEntity> &
Captures,
1907 assert((StrKind == CaptureStrKind::CopyHelper ||
1908 StrKind == CaptureStrKind::DisposeHelper) &&
1909 "unexpected CaptureStrKind");
1910 std::string
Name = StrKind == CaptureStrKind::CopyHelper
1911 ?
"__copy_helper_block_" 1912 :
"__destroy_helper_block_";
1917 Name += llvm::to_string(BlockAlignment.
getQuantity()) +
"_";
1919 for (
const BlockCaptureManagedEntity &E : Captures) {
1920 Name += llvm::to_string(E.Capture->getOffset().getQuantity());
1931 bool EHOnly = ForCopyHelper;
1933 switch (CaptureKind) {
1934 case BlockCaptureEntityKind::CXXRecord:
1935 case BlockCaptureEntityKind::ARCWeak:
1936 case BlockCaptureEntityKind::NonTrivialCStruct:
1937 case BlockCaptureEntityKind::ARCStrong: {
1941 CaptureKind == BlockCaptureEntityKind::ARCStrong
1951 case BlockCaptureEntityKind::BlockObject: {
1973 if (CapturesNonExternalType) {
1977 Fn->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
1994 std::string FuncName =
1996 CaptureStrKind::CopyHelper, CGM);
1998 if (llvm::GlobalValue *Func = CGM.
getModule().getNamedValue(FuncName))
1999 return llvm::ConstantExpr::getBitCast(Func, VoidPtrTy);
2007 args.push_back(&DstDecl);
2009 args.push_back(&SrcDecl);
2018 llvm::Function *Fn =
2022 Fn->setComdat(CGM.
getModule().getOrInsertComdat(FuncName));
2033 FunctionTy,
nullptr,
SC_Static,
false,
false);
2037 StartFunction(FD, ReturnTy, Fn, FI, args);
2041 Address src = GetAddrOfLocalVar(&SrcDecl);
2043 src = Builder.CreateBitCast(src, structPtrTy,
"block.source");
2045 Address dst = GetAddrOfLocalVar(&DstDecl);
2047 dst = Builder.CreateBitCast(dst, structPtrTy,
"block.dest");
2049 for (
const auto &CopiedCapture : CopiedCaptures) {
2055 unsigned index = capture.
getIndex();
2056 Address srcField = Builder.CreateStructGEP(src, index);
2057 Address dstField = Builder.CreateStructGEP(dst, index);
2059 switch (CopiedCapture.CopyKind) {
2060 case BlockCaptureEntityKind::CXXRecord:
2062 assert(CI.
getCopyExpr() &&
"copy expression for variable is missing");
2063 EmitSynthesizedCXXCopyCtor(dstField, srcField, CI.
getCopyExpr());
2065 case BlockCaptureEntityKind::ARCWeak:
2066 EmitARCCopyWeak(dstField, srcField);
2068 case BlockCaptureEntityKind::NonTrivialCStruct: {
2072 callCStructCopyConstructor(MakeAddrLValue(dstField, varType),
2073 MakeAddrLValue(srcField, varType));
2076 case BlockCaptureEntityKind::ARCStrong: {
2077 llvm::Value *srcValue = Builder.CreateLoad(srcField,
"blockcopy.src");
2082 auto *ty = cast<llvm::PointerType>(srcValue->getType());
2083 llvm::Value *null = llvm::ConstantPointerNull::get(ty);
2084 Builder.CreateStore(null, dstField);
2085 EmitARCStoreStrongCall(dstField, srcValue,
true);
2091 EmitARCRetainNonBlock(srcValue);
2097 cast<llvm::Instruction>(dstField.
getPointer())->eraseFromParent();
2101 case BlockCaptureEntityKind::BlockObject: {
2102 llvm::Value *srcValue = Builder.CreateLoad(srcField,
"blockcopy.src");
2103 srcValue = Builder.CreateBitCast(srcValue, VoidPtrTy);
2105 Builder.CreateBitCast(dstField.
getPointer(), VoidPtrTy);
2107 dstAddr, srcValue, llvm::ConstantInt::get(Int32Ty, flags.
getBitMask())
2128 return llvm::ConstantExpr::getBitCast(Fn, VoidPtrTy);
2140 static std::pair<BlockCaptureEntityKind, BlockFieldFlags>
2147 return std::make_pair(BlockCaptureEntityKind::BlockObject, Flags);
2152 return std::make_pair(BlockCaptureEntityKind::CXXRecord,
BlockFieldFlags());
2156 return std::make_pair(BlockCaptureEntityKind::ARCStrong,
2160 return std::make_pair(BlockCaptureEntityKind::ARCWeak,
2163 return std::make_pair(BlockCaptureEntityKind::NonTrivialCStruct,
2168 !LangOpts.ObjCAutoRefCount)
2169 return std::make_pair(BlockCaptureEntityKind::BlockObject,
2175 llvm_unreachable(
"after exhaustive DestructionKind switch");
2189 std::string FuncName =
2191 CaptureStrKind::DisposeHelper, CGM);
2193 if (llvm::GlobalValue *Func = CGM.
getModule().getNamedValue(FuncName))
2194 return llvm::ConstantExpr::getBitCast(Func, VoidPtrTy);
2202 args.push_back(&SrcDecl);
2211 llvm::Function *Fn =
2215 Fn->setComdat(CGM.
getModule().getOrInsertComdat(FuncName));
2225 FunctionTy,
nullptr,
SC_Static,
false,
false);
2229 StartFunction(FD, ReturnTy, Fn, FI, args);
2230 markAsIgnoreThreadCheckingAtRuntime(Fn);
2236 Address src = GetAddrOfLocalVar(&SrcDecl);
2238 src = Builder.CreateBitCast(src, structPtrTy,
"block");
2242 for (
const auto &DestroyedCapture : DestroyedCaptures) {
2258 return llvm::ConstantExpr::getBitCast(Fn, VoidPtrTy);
2294 void profileImpl(llvm::FoldingSetNodeID &
id)
const override {
2295 id.AddInteger(Flags.getBitMask());
2313 void profileImpl(llvm::FoldingSetNodeID &
id)
const override {
2333 llvm::ConstantPointerNull::get(cast<llvm::PointerType>(value->getType()));
2349 void profileImpl(llvm::FoldingSetNodeID &
id)
const override {
2359 ARCStrongBlockByrefHelpers(
CharUnits alignment)
2376 void profileImpl(llvm::FoldingSetNodeID &
id)
const override {
2386 const Expr *CopyExpr;
2390 const Expr *copyExpr)
2393 bool needsCopy()
const override {
return CopyExpr !=
nullptr; }
2396 if (!CopyExpr)
return;
2406 void profileImpl(llvm::FoldingSetNodeID &
id)
const override {
2407 id.AddPointer(VarType.getCanonicalType().getAsOpaquePtr());
2426 bool needsDispose()
const override {
2427 return VarType.isDestructedType();
2432 CGF.
pushDestroy(VarType.isDestructedType(), field, VarType);
2436 void profileImpl(llvm::FoldingSetNodeID &
id)
const override {
2437 id.AddPointer(VarType.getCanonicalType().getAsOpaquePtr());
2442 static llvm::Constant *
2451 args.push_back(&Dst);
2454 args.push_back(&Src);
2463 llvm::Function *Fn =
2468 = &Context.
Idents.
get(
"__Block_byref_object_copy_");
2502 generator.
emitCopy(CGF, destField, srcField);
2507 return llvm::ConstantExpr::getBitCast(Fn, CGF.
Int8PtrTy);
2519 static llvm::Constant *
2529 args.push_back(&Src);
2538 llvm::Function *Fn =
2540 "__Block_byref_object_dispose_",
2544 = &Context.
Idents.
get(
"__Block_byref_object_dispose_");
2561 auto byrefPtrType = byrefInfo.
Type->getPointerTo(0);
2570 return llvm::ConstantExpr::getBitCast(Fn, CGF.
Int8PtrTy);
2586 llvm::FoldingSetNodeID id;
2587 generator.Profile(
id);
2592 if (node)
return static_cast<T*
>(
node);
2597 T *copy =
new (CGM.
getContext()) T(std::forward<T>(generator));
2606 CodeGenFunction::buildByrefHelpers(llvm::StructType &byrefType,
2607 const AutoVarEmission &emission) {
2608 const VarDecl &var = *emission.Variable;
2610 "only escaping __block variables need byref helpers");
2614 auto &byrefInfo = getBlockByrefInfo(&var);
2621 if (
const CXXRecordDecl *record = type->getAsCXXRecordDecl()) {
2622 const Expr *copyExpr =
2624 if (!copyExpr && record->hasTrivialDestructor())
return nullptr;
2627 CGM, byrefInfo, CXXByrefHelpers(valueAlignment, type, copyExpr));
2635 CGM, byrefInfo, NonTrivialCStructByrefHelpers(valueAlignment, type));
2639 if (!type->isObjCRetainableType())
return nullptr;
2657 ARCWeakByrefHelpers(valueAlignment));
2663 if (type->isBlockPointerType()) {
2665 ARCStrongBlockByrefHelpers(valueAlignment));
2671 ARCStrongByrefHelpers(valueAlignment));
2674 llvm_unreachable(
"fell out of lifetime switch!");
2678 if (type->isBlockPointerType()) {
2681 type->isObjCObjectPointerType()) {
2687 if (type.isObjCGCWeak())
2691 ObjectByrefHelpers(valueAlignment, flags));
2696 bool followForward) {
2697 auto &info = getBlockByrefInfo(var);
2698 return emitBlockByrefAddress(baseAddr, info, followForward, var->
getName());
2704 const llvm::Twine &
name) {
2706 if (followForward) {
2707 Address forwardingAddr = Builder.CreateStructGEP(baseAddr, 1,
"forwarding");
2711 return Builder.CreateStructGEP(baseAddr, info.
FieldIndex, name);
2730 auto it = BlockByrefInfos.find(D);
2731 if (it != BlockByrefInfos.end())
2734 llvm::StructType *byrefType =
2744 types.push_back(Int8PtrTy);
2745 size += getPointerSize();
2748 types.push_back(llvm::PointerType::getUnqual(byrefType));
2749 size += getPointerSize();
2752 types.push_back(Int32Ty);
2756 types.push_back(Int32Ty);
2760 bool hasCopyAndDispose = getContext().BlockRequiresCopying(Ty, D);
2761 if (hasCopyAndDispose) {
2763 types.push_back(Int8PtrTy);
2764 size += getPointerSize();
2767 types.push_back(Int8PtrTy);
2768 size += getPointerSize();
2771 bool HasByrefExtendedLayout =
false;
2773 if (getContext().getByrefLifetime(Ty, Lifetime, HasByrefExtendedLayout) &&
2774 HasByrefExtendedLayout) {
2776 types.push_back(Int8PtrTy);
2783 bool packed =
false;
2784 CharUnits varAlign = getContext().getDeclAlign(D);
2788 if (varOffset != size) {
2790 llvm::ArrayType::get(Int8Ty, (varOffset - size).getQuantity());
2792 types.push_back(paddingTy);
2800 types.push_back(varTy);
2802 byrefType->setBody(types, packed);
2805 info.
Type = byrefType;
2810 auto pair = BlockByrefInfos.insert({D, info});
2811 assert(pair.second &&
"info was inserted recursively?");
2812 return pair.first->second;
2822 llvm::StructType *byrefType = cast<llvm::StructType>(
2823 cast<llvm::PointerType>(addr.
getPointer()->getType())->getElementType());
2825 unsigned nextHeaderIndex = 0;
2828 const Twine &
name) {
2829 auto fieldAddr = Builder.CreateStructGEP(addr, nextHeaderIndex,
name);
2830 Builder.CreateStore(value, fieldAddr);
2833 nextHeaderOffset += fieldSize;
2839 const VarDecl &D = *emission.Variable;
2842 bool HasByrefExtendedLayout;
2844 bool ByRefHasLifetime =
2845 getContext().getByrefLifetime(type, ByrefLifetime, HasByrefExtendedLayout);
2853 V = Builder.CreateIntToPtr(Builder.getInt32(isa), Int8PtrTy,
"isa");
2854 storeHeaderField(V, getPointerSize(),
"byref.isa");
2857 storeHeaderField(addr.
getPointer(), getPointerSize(),
"byref.forwarding");
2864 if (ByRefHasLifetime) {
2866 else switch (ByrefLifetime) {
2884 printf(
"\n Inline flag for BYREF variable layout (%d):", flags.getBitMask());
2886 printf(
" BLOCK_BYREF_HAS_COPY_DISPOSE");
2890 printf(
" BLOCK_BYREF_LAYOUT_EXTENDED");
2892 printf(
" BLOCK_BYREF_LAYOUT_STRONG");
2894 printf(
" BLOCK_BYREF_LAYOUT_WEAK");
2896 printf(
" BLOCK_BYREF_LAYOUT_UNRETAINED");
2898 printf(
" BLOCK_BYREF_LAYOUT_NON_OBJECT");
2903 storeHeaderField(llvm::ConstantInt::get(IntTy, flags.getBitMask()),
2904 getIntSize(),
"byref.flags");
2907 V = llvm::ConstantInt::get(IntTy, byrefSize.getQuantity());
2908 storeHeaderField(V, getIntSize(),
"byref.size");
2911 storeHeaderField(helpers->
CopyHelper, getPointerSize(),
2912 "byref.copyHelper");
2914 "byref.disposeHelper");
2917 if (ByRefHasLifetime && HasByrefExtendedLayout) {
2919 storeHeaderField(layoutInfo, getPointerSize(),
"byref.layout");
2927 Builder.CreateBitCast(V, Int8PtrTy),
2928 llvm::ConstantInt::get(Int32Ty, flags.
getBitMask())
2932 EmitRuntimeCallOrInvoke(F, args);
2934 EmitNounwindRuntimeCall(F, args);
2939 bool LoadBlockVarAddr,
bool CanThrow) {
2940 EHStack.pushCleanup<CallBlockRelease>(
Kind, Addr, Flags, LoadBlockVarAddr,
2946 llvm::Constant *C) {
2947 auto *GV = cast<llvm::GlobalValue>(C->stripPointerCasts());
2954 assert((isa<llvm::Function>(C->stripPointerCasts()) ||
2955 isa<llvm::GlobalVariable>(C->stripPointerCasts())) &&
2956 "expected Function or GlobalVariable");
2959 for (
const auto &Result : DC->
lookup(&II))
2960 if ((ND = dyn_cast<FunctionDecl>(Result)) ||
2961 (ND = dyn_cast<
VarDecl>(Result)))
2965 if (GV->isDeclaration() && (!ND || !ND->hasAttr<DLLExportAttr>())) {
2966 GV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
2969 GV->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
2974 if (CGM.
getLangOpts().BlocksRuntimeOptional && GV->isDeclaration() &&
2975 GV->hasExternalLinkage())
2976 GV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage);
2982 if (BlockObjectDispose)
2983 return BlockObjectDispose;
2986 llvm::FunctionType *fty
2987 = llvm::FunctionType::get(VoidTy, args,
false);
2988 BlockObjectDispose = CreateRuntimeFunction(fty,
"_Block_object_dispose");
2990 *
this, cast<llvm::Constant>(BlockObjectDispose.getCallee()));
2991 return BlockObjectDispose;
2995 if (BlockObjectAssign)
2996 return BlockObjectAssign;
2998 llvm::Type *args[] = { Int8PtrTy, Int8PtrTy, Int32Ty };
2999 llvm::FunctionType *fty
3000 = llvm::FunctionType::get(VoidTy, args,
false);
3001 BlockObjectAssign = CreateRuntimeFunction(fty,
"_Block_object_assign");
3003 *
this, cast<llvm::Constant>(BlockObjectAssign.getCallee()));
3004 return BlockObjectAssign;
3008 if (NSConcreteGlobalBlock)
3009 return NSConcreteGlobalBlock;
3011 NSConcreteGlobalBlock = GetOrCreateLLVMGlobal(
"_NSConcreteGlobalBlock",
3012 Int8PtrTy->getPointerTo(),
3015 return NSConcreteGlobalBlock;
3019 if (NSConcreteStackBlock)
3020 return NSConcreteStackBlock;
3022 NSConcreteStackBlock = GetOrCreateLLVMGlobal(
"_NSConcreteStackBlock",
3023 Int8PtrTy->getPointerTo(),
3026 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...
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.
FunctionType - C99 6.7.5.3 - Function Declarators.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee...
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...
constexpr size_t align(size_t Size)
Aligns a size to the pointer alignment.
Expr * getCopyExpr() 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 ...
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, Expr *TrailingRequiresClause=nullptr)
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.
bool ReturnValue(const T &V, APValue &R)
Convers a value to an APValue.
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.
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.
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.
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.
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 (...
BlockVarCopyInit getBlockVarCopyInit(const VarDecl *VD) const
Get the copy initialization expression of the VarDecl VD, or nullptr if none exists.
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...
bool hasReducedDebugInfo() const
Check if type and variable info should be emitted.
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.