20 #include "llvm/ADT/SmallSet.h"
21 #include "llvm/IR/CallSite.h"
22 #include "llvm/IR/DataLayout.h"
23 #include "llvm/IR/Module.h"
27 using namespace clang;
28 using namespace CodeGen;
31 : Name(name), CXXThisIndex(0), CanBeGlobal(
false), NeedsCopyDispose(
false),
32 HasCXXObject(
false), UsesStret(
false), HasCapturedVariableLayout(
false),
33 StructureType(nullptr), Block(block),
34 DominatingIP(nullptr) {
38 if (!name.empty() && name[0] ==
'\01')
39 name = name.substr(1);
48 llvm::Constant *blockFn);
81 llvm::Type *i8p =
NULL;
84 llvm::Type::getInt8PtrTy(
92 elements.push_back(llvm::ConstantInt::get(ulong, 0));
98 elements.push_back(llvm::ConstantInt::get(ulong,
111 std::string typeAtEncoding =
113 elements.push_back(llvm::ConstantExpr::getBitCast(
124 elements.push_back(llvm::Constant::getNullValue(i8p));
126 llvm::Constant *init = llvm::ConstantStruct::getAnon(elements);
128 llvm::GlobalVariable *global =
129 new llvm::GlobalVariable(CGM.
getModule(), init->getType(),
true,
131 init,
"__block_descriptor_tmp");
149 struct objc_class *isa;
176 _ResultType (*invoke)(Block_literal *, _ParamTypes...);
179 struct Block_descriptor *block_descriptor;
182 _CapturesTypes captures...;
191 struct BlockLayoutChunk {
202 : Alignment(align), Size(size), Lifetime(lifetime),
203 Capture(capture),
Type(type) {}
210 info.
Captures[Capture->getVariable()]
217 bool operator<(
const BlockLayoutChunk &left,
const BlockLayoutChunk &right) {
219 bool LeftByref = left.Capture ? left.Capture->isByRef() :
false;
220 bool RightByref = right.Capture ? right.Capture->isByRef() :
false;
223 left.Alignment >= right.Alignment)
225 else if (LeftByref && left.Alignment >= right.Alignment)
228 left.Alignment >= right.Alignment)
231 LeftValue = left.Alignment;
233 right.Alignment >= left.Alignment)
235 else if (RightByref && right.Alignment >= left.Alignment)
238 right.Alignment >= left.Alignment)
241 RightValue = right.Alignment;
243 return LeftValue > RightValue;
253 if (!recordType)
return true;
255 const auto *record = cast<CXXRecordDecl>(recordType->
getDecl());
258 if (!record->hasTrivialDestructor())
return false;
259 if (record->hasNonTrivialCopyConstructor())
return false;
263 return !record->hasMutableFields();
292 if (!init)
return nullptr;
308 CharUnits ptrSize, ptrAlign, intSize, intAlign;
313 assert(intSize <= ptrSize &&
"layout assumptions horribly violated");
316 if (2 * intSize < ptrAlign) headerSize += ptrSize;
317 else headerSize += 2 * intSize;
318 headerSize += 2 * ptrSize;
323 assert(elementTypes.empty());
326 elementTypes.push_back(i8p);
327 elementTypes.push_back(intTy);
328 elementTypes.push_back(intTy);
329 elementTypes.push_back(i8p);
365 "Can't capture 'this' outside a method");
369 std::pair<CharUnits,CharUnits> tinfo
371 maxFieldAlign = std::max(maxFieldAlign, tinfo.second);
373 layout.push_back(BlockLayoutChunk(tinfo.second, tinfo.first,
379 for (
const auto &CI : block->
captures()) {
380 const VarDecl *variable = CI.getVariable();
390 std::pair<CharUnits,CharUnits> tinfo
392 maxFieldAlign = std::max(maxFieldAlign, tinfo.second);
394 layout.push_back(BlockLayoutChunk(tinfo.second, tinfo.first,
429 }
else if (CI.hasCopyExpr()) {
437 if (!record->hasTrivialDestructor()) {
448 maxFieldAlign = std::max(maxFieldAlign, align);
450 llvm::Type *llvmType =
453 layout.push_back(BlockLayoutChunk(align, size, lifetime, &CI, llvmType));
457 if (layout.empty()) {
467 std::stable_sort(layout.begin(), layout.end());
491 if (endAlign < maxFieldAlign) {
493 li = layout.begin() + 1, le = layout.end();
497 for (; li != le && endAlign < li->Alignment; ++li)
504 for (; li != le; ++li) {
505 assert(endAlign >= li->Alignment);
507 li->setIndex(info, elementTypes.size());
508 elementTypes.push_back(li->Type);
509 blockSize += li->Size;
513 if (endAlign >= maxFieldAlign) {
523 layout.erase(first, li);
527 assert(endAlign ==
getLowBit(blockSize));
531 if (endAlign < maxFieldAlign) {
533 CharUnits padding = newBlockSize - blockSize;
535 elementTypes.push_back(llvm::ArrayType::get(CGM.
Int8Ty,
537 blockSize = newBlockSize;
541 assert(endAlign >= maxFieldAlign);
542 assert(endAlign ==
getLowBit(blockSize));
547 li = layout.begin(), le = layout.end(); li != le; ++li) {
548 if (endAlign < li->Alignment) {
552 CharUnits padding = li->Alignment - endAlign;
553 elementTypes.push_back(llvm::ArrayType::get(CGM.
Int8Ty,
555 blockSize += padding;
558 assert(endAlign >= li->Alignment);
559 li->setIndex(info, elementTypes.size());
560 elementTypes.push_back(li->Type);
561 blockSize += li->Size;
586 if (blockInfo.CanBeGlobal)
return;
591 blockInfo.Address->setAlignment(blockInfo.BlockAlign.getQuantity());
594 if (!blockInfo.NeedsCopyDispose)
return;
598 for (
const auto &CI : block->
captures()) {
601 if (CI.isByRef())
continue;
604 const VarDecl *variable = CI.getVariable();
625 blockInfo.StructureType, blockInfo.Address, capture.
getIndex());
628 if (!blockInfo.DominatingIP)
629 blockInfo.DominatingIP = cast<llvm::Instruction>(addr);
633 if (useArrayEHCleanup)
637 destroyer, useArrayEHCleanup);
651 i = cleanups.begin(), e = cleanups.end(); i != e; ++i) {
660 assert(head && *head);
675 assert(head &&
"destroying an empty chain");
680 }
while (head !=
nullptr);
690 blockInfo.BlockExpression = blockExpr;
691 return EmitBlockLiteral(blockInfo);
695 std::unique_ptr<CGBlockInfo> blockInfo;
699 blockInfo->BlockExpression = blockExpr;
700 return EmitBlockLiteral(*blockInfo);
706 llvm::Constant *blockFn
710 blockFn = llvm::ConstantExpr::getBitCast(blockFn,
VoidPtrTy);
718 llvm::Constant *isa = CGM.getNSConcreteStackBlock();
719 isa = llvm::ConstantExpr::getBitCast(isa,
VoidPtrTy);
725 llvm::AllocaInst *blockAddr = blockInfo.
Address;
726 assert(blockAddr &&
"block has no address!");
737 isa,
Builder.CreateStructGEP(blockTy, blockAddr, 0,
"block.isa"));
740 Builder.CreateStructGEP(blockTy, blockAddr, 1,
"block.flags"));
742 llvm::ConstantInt::get(
IntTy, 0),
743 Builder.CreateStructGEP(blockTy, blockAddr, 2,
"block.reserved"));
745 blockFn,
Builder.CreateStructGEP(blockTy, blockAddr, 3,
"block.invoke"));
746 Builder.CreateStore(descriptor,
Builder.CreateStructGEP(blockTy, blockAddr, 4,
747 "block.descriptor"));
755 blockTy, blockAddr, blockInfo.
CXXThisIndex,
"block.captured-this.addr");
756 Builder.CreateStore(LoadCXXThis(), addr);
760 for (
const auto &CI : blockDecl->
captures()) {
761 const VarDecl *variable = CI.getVariable();
773 blockTy, blockAddr, capture.
getIndex(),
"block.captured");
778 if (BlockInfo && CI.isNested()) {
781 BlockInfo->getCapture(variable);
784 src =
Builder.CreateStructGEP(BlockInfo->StructureType, LoadBlockStruct(),
786 "block.capture.addr");
795 src = LocalDeclMap.lookup(variable);
798 const_cast<VarDecl *>(variable),
801 src = EmitDeclRefLValue(&declRef).getAddress();
821 }
else if (
const Expr *copyExpr = CI.getCopyExpr()) {
830 EmitAggExpr(copyExpr, Slot);
832 EmitSynthesizedCXXCopyCtor(blockField, src, copyExpr);
851 LValue srcLV = MakeAddrLValue(src, type, align);
853 value = EmitARCRetainNonBlock(value);
856 LValue destLV = MakeAddrLValue(blockField, type, align);
857 EmitStoreOfScalar(value, destLV,
true);
869 DeclRefExpr declRef(const_cast<VarDecl *>(variable),
878 EmitExprAsInit(&l2r, &blockFieldPseudoVar,
879 MakeAddrLValue(blockField, type, align),
894 Builder.CreateBitCast(blockAddr,
902 if (BlockDescriptorType)
903 return BlockDescriptorType;
905 llvm::Type *UnsignedLongTy =
922 BlockDescriptorType =
924 UnsignedLongTy, UnsignedLongTy,
nullptr);
927 BlockDescriptorType = llvm::PointerType::getUnqual(BlockDescriptorType);
928 return BlockDescriptorType;
932 if (GenericBlockLiteralType)
933 return GenericBlockLiteralType;
944 GenericBlockLiteralType =
947 BlockDescPtrTy,
nullptr);
949 return GenericBlockLiteralType;
961 llvm::Type *BlockLiteralTy =
962 llvm::PointerType::getUnqual(CGM.getGenericBlockLiteralType());
966 Builder.CreateBitCast(Callee, BlockLiteralTy,
"block.literal");
970 CGM.getGenericBlockLiteralType(), BlockLiteral, 3);
989 CGM.getTypes().arrangeBlockFunctionCall(Args, FuncTy);
992 llvm::Type *BlockFTy = CGM.getTypes().GetFunctionType(FnInfo);
994 llvm::Type *BlockFTyPtr = llvm::PointerType::getUnqual(BlockFTy);
995 Func =
Builder.CreateBitCast(Func, BlockFTyPtr);
998 return EmitCall(FnInfo, Func, ReturnValue, Args);
1003 assert(BlockInfo &&
"evaluating block ref without block information?");
1007 if (capture.
isConstant())
return LocalDeclMap[variable];
1010 Builder.CreateStructGEP(BlockInfo->StructureType, LoadBlockStruct(),
1011 capture.
getIndex(),
"block.capture.addr");
1017 addr =
Builder.CreateLoad(addr);
1018 auto *byrefType = BuildByRefType(variable);
1019 llvm::PointerType *byrefPointerType = llvm::PointerType::get(byrefType, 0);
1020 addr =
Builder.CreateBitCast(addr, byrefPointerType,
1024 addr =
Builder.CreateStructGEP(byrefType, addr, 1,
"byref.forwarding");
1025 addr =
Builder.CreateLoad(addr,
"byref.addr.forwarded");
1028 addr =
Builder.CreateBitCast(addr, byrefPointerType);
1029 addr =
Builder.CreateStructGEP(byrefType, addr,
1030 getByRefValueLLVMField(variable).second,
1035 addr =
Builder.CreateLoad(addr,
"ref.tmp");
1050 llvm::Constant *blockFn;
1052 llvm::DenseMap<const Decl*, llvm::Value*> LocalDeclMap;
1058 blockFn = llvm::ConstantExpr::getBitCast(blockFn,
VoidPtrTy);
1065 llvm::Constant *blockFn) {
1081 fields[2] = llvm::Constant::getNullValue(CGM.
IntTy);
1084 fields[3] = blockFn;
1089 llvm::Constant *init = llvm::ConstantStruct::getAnon(fields);
1091 llvm::GlobalVariable *literal =
1092 new llvm::GlobalVariable(CGM.
getModule(),
1097 "__block_literal_global");
1101 llvm::Type *requiredType =
1103 return llvm::ConstantExpr::getBitCast(literal, requiredType);
1109 const DeclMapTy &ldm,
1110 bool IsLambdaConversionToBlock) {
1117 BlockInfo = &blockInfo;
1122 for (DeclMapTy::const_iterator i = ldm.begin(), e = ldm.end(); i != e; ++i) {
1123 const auto *var = dyn_cast<
VarDecl>(i->first);
1124 if (var && !var->hasLocalStorage())
1125 LocalDeclMap[var] = i->second;
1136 IdentifierInfo *II = &CGM.getContext().Idents.get(
".block_descriptor");
1140 args.push_back(&selfDecl);
1147 const CGFunctionInfo &fnInfo = CGM.getTypes().arrangeFreeFunctionDeclaration(
1150 if (CGM.ReturnSlotInterferesWithArgs(fnInfo))
1153 llvm::FunctionType *fnLLVMType = CGM.getTypes().GetFunctionType(fnInfo);
1155 StringRef name = CGM.getBlockMangledName(GD, blockDecl);
1158 CGM.SetInternalFunctionAttributes(blockDecl, fn, fnInfo);
1161 StartFunction(blockDecl, fnType->
getReturnType(), fn, fnInfo, args,
1169 LocalDeclMap.erase(&selfDecl);
1170 BlockPointer =
Builder.CreateBitCast(blockAddr,
1176 if (CGM.getCodeGenOpts().OptimizationLevel == 0) {
1178 llvm::AllocaInst *Alloca = CreateTempAlloca(BlockPointer->getType(),
1181 Alloca->setAlignment(Align);
1185 Builder.CreateAlignedStore(BlockPointer, Alloca, Align);
1186 BlockPointerDbgLoc = Alloca;
1195 CXXThisValue =
Builder.CreateLoad(addr,
"this");
1199 for (
const auto &CI : blockDecl->
captures()) {
1200 const VarDecl *variable = CI.getVariable();
1206 llvm::AllocaInst *alloca =
1207 CreateMemTemp(variable->
getType(),
"block.captured-const");
1208 alloca->setAlignment(align);
1212 LocalDeclMap[variable] = alloca;
1216 llvm::BasicBlock *entry =
Builder.GetInsertBlock();
1217 llvm::BasicBlock::iterator entry_ptr =
Builder.GetInsertPoint();
1220 if (IsLambdaConversionToBlock)
1221 EmitLambdaBlockInvokeBody();
1223 PGO.assignRegionCounters(blockDecl, fn);
1224 incrementProfileCounter(blockDecl->
getBody());
1225 EmitStmt(blockDecl->
getBody());
1229 llvm::BasicBlock *resume =
Builder.GetInsertBlock();
1233 Builder.SetInsertPoint(entry, entry_ptr);
1238 for (
const auto &CI : blockDecl->
captures()) {
1239 const VarDecl *variable = CI.getVariable();
1242 if (CGM.getCodeGenOpts().getDebugInfo()
1246 DI->EmitDeclareOfAutoVariable(variable, LocalDeclMap[variable],
1251 DI->EmitDeclareOfBlockDeclRefVariable(variable, BlockPointerDbgLoc,
1253 entry_ptr == entry->end()
1254 ?
nullptr : entry_ptr);
1259 cast<CompoundStmt>(blockDecl->
getBody())->getRBracLoc());
1263 if (resume ==
nullptr)
1264 Builder.ClearInsertionPoint();
1266 Builder.SetInsertPoint(resume);
1268 FinishFunction(cast<CompoundStmt>(blockDecl->
getBody())->getRBracLoc());
1307 args.push_back(&dstDecl);
1310 args.push_back(&srcDecl);
1312 const CGFunctionInfo &FI = CGM.getTypes().arrangeFreeFunctionDeclaration(
1317 llvm::FunctionType *LTy = CGM.getTypes().GetFunctionType(FI);
1319 llvm::Function *Fn =
1321 "__copy_helper_block_", &CGM.getModule());
1324 = &CGM.getContext().Idents.get(
"__copy_helper_block_");
1334 StartFunction(FD, C.
VoidTy, Fn, FI, args);
1337 llvm::Type *structPtrTy = blockInfo.
StructureType->getPointerTo();
1340 src =
Builder.CreateLoad(src);
1341 src =
Builder.CreateBitCast(src, structPtrTy,
"block.source");
1344 dst =
Builder.CreateLoad(dst);
1345 dst =
Builder.CreateBitCast(dst, structPtrTy,
"block.dest");
1349 for (
const auto &CI : blockDecl->
captures()) {
1350 const VarDecl *variable = CI.getVariable();
1356 const Expr *copyExpr = CI.getCopyExpr();
1359 bool useARCWeakCopy =
false;
1360 bool useARCStrongCopy =
false;
1363 assert(!CI.isByRef());
1366 }
else if (CI.isByRef()) {
1383 useARCWeakCopy =
true;
1390 if (!isBlockPointer)
1391 useARCStrongCopy =
true;
1407 unsigned index = capture.
getIndex();
1415 EmitSynthesizedCXXCopyCtor(dstField, srcField, copyExpr);
1416 }
else if (useARCWeakCopy) {
1417 EmitARCCopyWeak(dstField, srcField);
1420 if (useARCStrongCopy) {
1424 if (CGM.getCodeGenOpts().OptimizationLevel == 0) {
1425 auto *ty = cast<llvm::PointerType>(srcValue->getType());
1426 llvm::Value *null = llvm::ConstantPointerNull::get(ty);
1427 Builder.CreateStore(null, dstField);
1428 EmitARCStoreStrongCall(dstField, srcValue,
true);
1434 EmitARCRetainNonBlock(srcValue);
1438 cast<llvm::Instruction>(dstField)->eraseFromParent();
1447 bool copyCanThrow =
false;
1449 const Expr *copyExpr =
1450 CGM.getContext().getBlockVarCopyInits(variable);
1452 copyCanThrow =
true;
1457 EmitRuntimeCallOrInvoke(CGM.getBlockObjectAssign(), args);
1459 EmitNounwindRuntimeCall(CGM.getBlockObjectAssign(), args);
1467 return llvm::ConstantExpr::getBitCast(Fn,
VoidPtrTy);
1484 args.push_back(&srcDecl);
1486 const CGFunctionInfo &FI = CGM.getTypes().arrangeFreeFunctionDeclaration(
1491 llvm::FunctionType *LTy = CGM.getTypes().GetFunctionType(FI);
1493 llvm::Function *Fn =
1495 "__destroy_helper_block_", &CGM.getModule());
1498 = &CGM.getContext().Idents.get(
"__destroy_helper_block_");
1507 StartFunction(FD, C.
VoidTy, Fn, FI, args);
1510 llvm::Type *structPtrTy = blockInfo.
StructureType->getPointerTo();
1513 src =
Builder.CreateLoad(src);
1514 src =
Builder.CreateBitCast(src, structPtrTy,
"block");
1520 for (
const auto &CI : blockDecl->
captures()) {
1521 const VarDecl *variable = CI.getVariable();
1530 bool useARCWeakDestroy =
false;
1531 bool useARCStrongDestroy =
false;
1538 if (record->hasTrivialDestructor())
1540 dtor = record->getDestructor();
1557 useARCWeakDestroy =
true;
1561 useARCStrongDestroy =
true;
1567 unsigned index = capture.
getIndex();
1573 PushDestructorCleanup(dtor, srcField);
1576 }
else if (useARCWeakDestroy) {
1577 EmitARCDestroyWeak(srcField);
1580 }
else if (useARCStrongDestroy) {
1589 BuildBlockRelease(value, flags);
1597 return llvm::ConstantExpr::getBitCast(Fn,
VoidPtrTy);
1608 : ByrefHelpers(alignment), Flags(flags) {}
1622 llvm::Value *args[] = { destField, srcValue, flagsVal };
1633 void profileImpl(llvm::FoldingSetNodeID &
id)
const override {
1634 id.AddInteger(Flags.getBitMask());
1641 ARCWeakByrefHelpers(
CharUnits alignment) : ByrefHelpers(alignment) {}
1652 void profileImpl(llvm::FoldingSetNodeID &
id)
const override {
1662 ARCStrongByrefHelpers(
CharUnits alignment) : ByrefHelpers(alignment) {}
1669 llvm::LoadInst *value = CGF.
Builder.CreateLoad(srcField);
1670 value->setAlignment(Alignment.getQuantity());
1673 llvm::ConstantPointerNull::get(cast<llvm::PointerType>(value->getType()));
1676 llvm::StoreInst *store = CGF.
Builder.CreateStore(null, destField);
1677 store->setAlignment(Alignment.getQuantity());
1682 llvm::StoreInst *store = CGF.
Builder.CreateStore(value, destField);
1683 store->setAlignment(Alignment.getQuantity());
1685 store = CGF.
Builder.CreateStore(null, srcField);
1686 store->setAlignment(Alignment.getQuantity());
1693 void profileImpl(llvm::FoldingSetNodeID &
id)
const override {
1703 ARCStrongBlockByrefHelpers(
CharUnits alignment) : ByrefHelpers(alignment) {}
1710 llvm::LoadInst *oldValue = CGF.
Builder.CreateLoad(srcField);
1711 oldValue->setAlignment(Alignment.getQuantity());
1715 llvm::StoreInst *store = CGF.
Builder.CreateStore(copy, destField);
1716 store->setAlignment(Alignment.getQuantity());
1723 void profileImpl(llvm::FoldingSetNodeID &
id)
const override {
1733 const Expr *CopyExpr;
1737 const Expr *copyExpr)
1738 : ByrefHelpers(alignment), VarType(type), CopyExpr(copyExpr) {}
1740 bool needsCopy()
const override {
return CopyExpr !=
nullptr; }
1743 if (!CopyExpr)
return;
1753 void profileImpl(llvm::FoldingSetNodeID &
id)
const override {
1754 id.AddPointer(VarType.getCanonicalType().getAsOpaquePtr());
1759 static llvm::Constant *
1761 llvm::StructType &byrefType,
1762 unsigned valueFieldIndex,
1771 args.push_back(&dst);
1775 args.push_back(&src);
1785 llvm::Function *Fn =
1790 = &Context.
Idents.
get(
"__Block_byref_object_copy_");
1802 llvm::Type *byrefPtrType = byrefType.getPointerTo(0);
1806 destField = CGF.
Builder.CreateLoad(destField);
1807 destField = CGF.
Builder.CreateBitCast(destField, byrefPtrType);
1808 destField = CGF.
Builder.CreateStructGEP(&byrefType, destField,
1809 valueFieldIndex,
"x");
1813 srcField = CGF.
Builder.CreateLoad(srcField);
1814 srcField = CGF.
Builder.CreateBitCast(srcField, byrefPtrType);
1816 CGF.
Builder.CreateStructGEP(&byrefType, srcField, valueFieldIndex,
"x");
1818 byrefInfo.
emitCopy(CGF, destField, srcField);
1823 return llvm::ConstantExpr::getBitCast(Fn, CGF.
Int8PtrTy);
1828 llvm::StructType &byrefType,
1829 unsigned byrefValueIndex,
1836 static llvm::Constant *
1838 llvm::StructType &byrefType,
1839 unsigned byrefValueIndex,
1847 args.push_back(&src);
1857 llvm::Function *Fn =
1859 "__Block_byref_object_dispose_",
1863 = &Context.
Idents.
get(
"__Block_byref_object_dispose_");
1875 V = CGF.
Builder.CreateLoad(V);
1876 V = CGF.
Builder.CreateBitCast(V, byrefType.getPointerTo(0));
1877 V = CGF.
Builder.CreateStructGEP(&byrefType, V, byrefValueIndex,
"x");
1884 return llvm::ConstantExpr::getBitCast(Fn, CGF.
Int8PtrTy);
1889 llvm::StructType &byrefType,
1890 unsigned byrefValueIndex,
1899 llvm::StructType &byrefTy,
1900 unsigned byrefValueIndex,
1904 byrefInfo.Alignment = std::max(byrefInfo.Alignment,
1907 llvm::FoldingSetNodeID
id;
1908 byrefInfo.Profile(
id);
1913 if (node)
return static_cast<T*
>(node);
1915 byrefInfo.CopyHelper =
1917 byrefInfo.DisposeHelper =
1920 T *copy =
new (CGM.
getContext()) T(byrefInfo);
1929 CodeGenFunction::buildByrefHelpers(llvm::StructType &byrefType,
1930 const AutoVarEmission &emission) {
1931 const VarDecl &var = *emission.Variable;
1934 unsigned byrefValueIndex = getByRefValueLLVMField(&var).second;
1937 const Expr *copyExpr = CGM.getContext().getBlockVarCopyInits(&var);
1938 if (!copyExpr && record->hasTrivialDestructor())
return nullptr;
1940 CXXByrefHelpers byrefInfo(emission.Alignment, type, copyExpr);
1965 ARCWeakByrefHelpers byrefInfo(emission.Alignment);
1974 ARCStrongBlockByrefHelpers byrefInfo(emission.Alignment);
1980 ARCStrongByrefHelpers byrefInfo(emission.Alignment);
1984 llvm_unreachable(
"fell out of lifetime switch!");
1990 }
else if (CGM.getContext().isObjCNSObjectType(type) ||
2000 ObjectByrefHelpers byrefInfo(emission.Alignment, flags);
2004 std::pair<llvm::Type *, unsigned>
2006 assert(ByRefValueInfo.count(VD) &&
"Did not find value!");
2008 return ByRefValueInfo.find(VD)->second;
2013 auto P = getByRefValueLLVMField(V);
2015 Builder.CreateStructGEP(
P.first, BaseAddr, 1,
"forwarding");
2016 Loc =
Builder.CreateLoad(Loc);
2037 std::pair<llvm::Type *, unsigned> &Info = ByRefValueInfo[D];
2045 llvm::StructType *ByRefType =
2053 types.push_back(llvm::PointerType::getUnqual(ByRefType));
2062 if (HasCopyAndDispose) {
2069 bool HasByrefExtendedLayout =
false;
2071 if (
getContext().getByrefLifetime(Ty, Lifetime, HasByrefExtendedLayout) &&
2072 HasByrefExtendedLayout)
2076 bool Packed =
false;
2083 unsigned CurrentOffsetInBytes = 4 * 2;
2086 unsigned noPointers = 2;
2087 if (HasCopyAndDispose)
2089 if (HasByrefExtendedLayout)
2092 CurrentOffsetInBytes += noPointers * CGM.getDataLayout().getTypeAllocSize(
Int8PtrTy);
2095 unsigned AlignedOffsetInBytes =
2096 llvm::RoundUpToAlignment(CurrentOffsetInBytes, Align.
getQuantity());
2098 unsigned NumPaddingBytes = AlignedOffsetInBytes - CurrentOffsetInBytes;
2099 if (NumPaddingBytes > 0) {
2103 if (NumPaddingBytes > 1)
2104 Ty = llvm::ArrayType::get(Ty, NumPaddingBytes);
2106 types.push_back(Ty);
2114 types.push_back(ConvertTypeForMem(Ty));
2116 ByRefType->setBody(types, Packed);
2118 Info.first = ByRefType;
2120 Info.second = types.size() - 1;
2132 llvm::StructType *byrefType = cast<llvm::StructType>(
2139 const VarDecl &D = *emission.Variable;
2142 bool HasByrefExtendedLayout;
2144 bool ByRefHasLifetime =
2155 Builder.CreateStructGEP(
nullptr, addr, 0,
"byref.isa"));
2159 addr,
Builder.CreateStructGEP(
nullptr, addr, 1,
"byref.forwarding"));
2166 if (ByRefHasLifetime) {
2168 else switch (ByrefLifetime) {
2185 if (CGM.getLangOpts().ObjCGCBitmapPrint) {
2186 printf(
"\n Inline flag for BYREF variable layout (%d):", flags.
getBitMask());
2188 printf(
" BLOCK_BYREF_HAS_COPY_DISPOSE");
2192 printf(
" BLOCK_BYREF_LAYOUT_EXTENDED");
2194 printf(
" BLOCK_BYREF_LAYOUT_STRONG");
2196 printf(
" BLOCK_BYREF_LAYOUT_WEAK");
2198 printf(
" BLOCK_BYREF_LAYOUT_UNRETAINED");
2200 printf(
" BLOCK_BYREF_LAYOUT_NON_OBJECT");
2207 Builder.CreateStructGEP(
nullptr, addr, 2,
"byref.flags"));
2209 CharUnits byrefSize = CGM.GetTargetTypeStoreSize(byrefType);
2212 Builder.CreateStructGEP(
nullptr, addr, 3,
"byref.size"));
2216 Builder.CreateStore(helpers->CopyHelper, copy_helper);
2219 Builder.CreateStore(helpers->DisposeHelper, destroy_helper);
2221 if (ByRefHasLifetime && HasByrefExtendedLayout) {
2222 llvm::Constant* ByrefLayoutInfo = CGM.getObjCRuntime().BuildByrefLayout(CGM, type);
2224 Builder.CreateStructGEP(
nullptr, addr, helpers ? 6 : 4,
"byref.layout");
2226 llvm::Type *DesTy = ByrefLayoutInfo->getType();
2227 DesTy = DesTy->getPointerTo();
2229 Builder.CreateStore(ByrefLayoutInfo, BC);
2239 EmitNounwindRuntimeCall(F, args);
2245 CallBlockRelease(
llvm::Value *Addr) : Addr(Addr) {}
2268 llvm::Constant *C) {
2269 if (!CGM.
getLangOpts().BlocksRuntimeOptional)
return;
2271 auto *GV = cast<llvm::GlobalValue>(C->stripPointerCasts());
2272 if (GV->isDeclaration() && GV->hasExternalLinkage())
2273 GV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage);
2277 if (BlockObjectDispose)
2278 return BlockObjectDispose;
2281 llvm::FunctionType *fty
2282 = llvm::FunctionType::get(
VoidTy, args,
false);
2285 return BlockObjectDispose;
2289 if (BlockObjectAssign)
2290 return BlockObjectAssign;
2293 llvm::FunctionType *fty
2294 = llvm::FunctionType::get(
VoidTy, args,
false);
2297 return BlockObjectAssign;
2301 if (NSConcreteGlobalBlock)
2302 return NSConcreteGlobalBlock;
2304 NSConcreteGlobalBlock = GetOrCreateLLVMGlobal(
"_NSConcreteGlobalBlock",
2308 return NSConcreteGlobalBlock;
2312 if (NSConcreteStackBlock)
2313 return NSConcreteStackBlock;
2315 NSConcreteStackBlock = GetOrCreateLLVMGlobal(
"_NSConcreteStackBlock",
2319 return NSConcreteStackBlock;
void enterNonTrivialFullExpression(const ExprWithCleanups *E)
llvm::Value * GetAddrOfBlockDecl(const VarDecl *var, bool ByRef)
llvm::Constant * GenerateCopyHelperFunction(const CGBlockInfo &blockInfo)
llvm::IntegerType * IntTy
int
llvm::Type * getGenericBlockLiteralType()
The type of a generic block literal.
CharUnits BlockHeaderForcedGapOffset
virtual void emitDispose(CodeGenFunction &CGF, llvm::Value *field)=0
void EmitARCMoveWeak(llvm::Value *dst, llvm::Value *src)
Destroyer * getDestroyer(QualType::DestructionKind destructionKind)
A pair of helper functions for a __block variable.
CodeGenTypes & getTypes()
CharUnits getDeclAlign(const Decl *D, bool ForAlignof=false) const
Return a conservative estimate of the alignment of the specified decl D.
virtual bool needsCopy() const
DestructionKind isDestructedType() const
llvm::Module & getModule() const
llvm::LLVMContext & getLLVMContext()
llvm::AllocaInst * CreateTempAlloca(llvm::Type *Ty, const Twine &Name="tmp")
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static Capture makeIndex(unsigned index)
param_iterator param_end()
std::string getObjCEncodingForBlock(const BlockExpr *blockExpr) const
Return the encoded type for this block declaration.
static llvm::Constant * buildBlockDescriptor(CodeGenModule &CGM, const CGBlockInfo &blockInfo)
const Expr * getInit() const
bool isBlockPointerType() const
const CGFunctionInfo & arrangeFreeFunctionDeclaration(QualType ResTy, const FunctionArgList &Args, const FunctionType::ExtInfo &Info, bool isVariadic)
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64
bool hasStrongOrWeakObjCLifetime() const
True if the lifetime is either strong or weak.
uint32_t getBitMask() const
CGBlockInfo(const BlockDecl *blockDecl, StringRef Name)
bool capturesCXXThis() const
const Expr * getCallee() const
ObjCLifetime getObjCLifetime() const
const FunctionProtoType * getFunctionType() const
getFunctionType - Return the underlying function type for this block.
virtual llvm::Constant * BuildRCBlockLayout(CodeGen::CodeGenModule &CGM, const CodeGen::CGBlockInfo &blockInfo)=0
llvm::Type * ConvertTypeForMem(QualType T)
capture_iterator capture_begin()
bool isObjCRetainableType() const
static void destroyBlockInfos(CGBlockInfo *info)
Destroy a chain of block layouts.
void emitByrefStructureInit(const AutoVarEmission &emission)
CGBlockInfo * FirstBlockInfo
FirstBlockInfo - The head of a singly-linked-list of block layouts.
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 ...
bool HasCapturedVariableLayout
bool isReferenceType() const
const Stmt * getBody() const
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
Stmt * getBody() const override
static bool isSafeForCXXConstantCapture(QualType type)
Determines if the given type is safe for constant capture in C++.
An r-value expression (a pr-value in the C++11 taxonomy) produces a temporary value.
static ApplyDebugLocation CreateArtificial(CodeGenFunction &CGF)
Apply TemporaryLocation if it is valid. Otherwise switch to an artificial debug location that has a v...
void EmitARCDestroyStrong(llvm::Value *addr, ARCPreciseLifetime_t precise)
static T * buildByrefHelpers(CodeGenModule &CGM, llvm::StructType &byrefTy, unsigned byrefValueIndex, T &byrefInfo)
const Capture & getCapture(const VarDecl *var) const
void EmitSynthesizedCXXCopyCtor(llvm::Value *Dest, llvm::Value *Src, const Expr *Exp)
void Destroyer(CodeGenFunction &CGF, llvm::Value *addr, QualType ty)
const LangOptions & getLangOpts() const
QualType getReturnType() const
llvm::GlobalVariable * GetAddrOfConstantCString(const std::string &Str, const char *GlobalName=nullptr, unsigned Alignment=0)
llvm::Value * EmitBlockLiteral(const BlockExpr *)
Emit a block literal expression in the current function.
llvm::PointerType * VoidPtrTy
bool getByrefLifetime(QualType Ty, Qualifiers::ObjCLifetime &Lifetime, bool &HasByrefExtendedLayout) const
bool needsEHCleanup(QualType::DestructionKind kind)
RecordDecl * getDecl() const
void pushDestroy(QualType::DestructionKind dtorKind, llvm::Value *addr, QualType type)
static OMPLinearClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, ArrayRef< Expr * > IL, Expr *Step, Expr *CalcStep)
Creates clause with a list of variables VL and a linear step Step.
std::string getNameAsString() const
llvm::PointerType * VoidPtrPtrTy
static Capture makeConstant(llvm::Value *value)
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
llvm::Type * BuildByRefType(const VarDecl *var)
llvm::Constant * getNSConcreteStackBlock()
std::pair< CharUnits, CharUnits > getTypeInfoInChars(const Type *T) const
static FunctionDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation NLoc, DeclarationName N, QualType T, TypeSourceInfo *TInfo, StorageClass SC, bool isInlineSpecified=false, bool hasWrittenPrototype=true, bool isConstexprSpecified=false)
bool NeedsCopyDispose
True if the block needs a custom copy or dispose function.
const BlockExpr * BlockExpression
static llvm::Constant * buildCopyHelper(CodeGenModule &CGM, const CGBlockInfo &blockInfo)
Build the helper function to copy a block.
ExtInfo getExtInfo() const
bool isConversionFromLambda() const
llvm::CallInst * EmitNounwindRuntimeCall(llvm::Value *callee, const Twine &name="")
llvm::Function * GenerateBlockFunction(GlobalDecl GD, const CGBlockInfo &Info, const DeclMapTy &ldm, bool IsLambdaConversionToBlock)
void PushDestructorCleanup(QualType T, llvm::Value *Addr)
Qualifiers::ObjCLifetime getObjCLifetime() const
getObjCLifetime - Returns lifetime attribute of this type.
CGBlockInfo - Information to generate a block literal.
unsigned getNumObjects() const
const TargetInfo & getTarget() const
SourceLocation getLocEnd() const LLVM_READONLY
static llvm::Constant * buildByrefCopyHelper(CodeGenModule &CGM, llvm::StructType &byrefType, unsigned byrefValueIndex, CodeGenModule::ByrefHelpers &info)
Build the copy helper for a __block variable.
capture_iterator capture_end()
CGBlockInfo * NextBlockInfo
CGObjCRuntime & getObjCRuntime()
Return a reference to the configured Objective-C runtime.
QualType getPointeeType() const
unsigned getIndex() const
Enters a new scope for capturing cleanups, all of which will be executed once the scope is exited...
llvm::Value * GetAddrOfLocalVar(const VarDecl *VD)
GetAddrOfLocalVar - Return the address of a local variable.
Represents a C++ destructor within a class.
static llvm::Constant * buildGlobalBlock(CodeGenModule &CGM, const CGBlockInfo &blockInfo, llvm::Constant *blockFn)
Build the given block as a global block.
llvm::Constant * GenerateDestroyHelperFunction(const CGBlockInfo &blockInfo)
TranslationUnitDecl * getTranslationUnitDecl() const
bool isObjCGCWeak() const
isObjCGCWeak true when Type is objc's weak.
llvm::FoldingSet< ByrefHelpers > ByrefHelpersCache
ASTContext & getContext() const
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
internal::Matcher< T > id(StringRef ID, const internal::BindableMatcher< T > &InnerMatcher)
If the provided matcher matches a node, binds the node to ID.
void add(RValue rvalue, QualType type, bool needscopy=false)
stable_iterator stable_begin() const
std::pair< llvm::Type *, unsigned > getByRefValueLLVMField(const ValueDecl *VD) const
llvm::IntegerType * Int32Ty
static CharUnits getLowBit(CharUnits v)
EHScopeStack::stable_iterator getCleanup() const
param_iterator param_begin()
void enterByrefCleanup(const AutoVarEmission &emission)
bool HaveInsertPoint() const
There is no lifetime qualification on this type.
ArrayRef< CleanupObject > getObjects() const
llvm::Constant * CreateRuntimeFunction(llvm::FunctionType *Ty, StringRef Name, llvm::AttributeSet ExtraAttrs=llvm::AttributeSet())
Create a new runtime function with the specified type and name.
ASTContext & getContext() const
virtual bool needsDispose() const
Encodes a location in the source. The SourceManager can decode this to get at the full include stack...
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
llvm::StructType * StructureType
static void configureBlocksRuntimeObject(CodeGenModule &CGM, llvm::Constant *C)
Adjust the declaration of something from the blocks API.
llvm::DenseMap< const VarDecl *, Capture > Captures
The mapping of allocated indexes within the block.
const CodeGenOptions & getCodeGenOpts() const
const Type * getBaseElementTypeUnsafe() const
llvm::Constant * getBlockObjectDispose()
void StartFunction(GlobalDecl GD, QualType RetTy, llvm::Function *Fn, const CGFunctionInfo &FnInfo, const FunctionArgList &Args, SourceLocation Loc=SourceLocation(), SourceLocation StartLoc=SourceLocation())
Emit code for the start of a function.
const LangOptions & getLangOpts() const
bool operator<(DeclarationName LHS, DeclarationName RHS)
unsigned CXXThisIndex
The field index of 'this' within the block, if there is one.
Assigning into this object requires a lifetime extension.
const BlockDecl * getBlockDecl() const
static Destroyer destroyARCStrongImprecise
void FinishFunction(SourceLocation EndLoc=SourceLocation())
void EmitARCDestroyWeak(llvm::Value *addr)
static llvm::Constant * tryCaptureAsConstant(CodeGenModule &CGM, CodeGenFunction *CGF, const VarDecl *var)
const unsigned BlockHeaderSize
The number of fields in a block header.
llvm::AllocaInst * Address
static const Type * getElementType(const Expr *BaseExpr)
virtual llvm::Constant * BuildGCBlockLayout(CodeGen::CodeGenModule &CGM, const CodeGen::CGBlockInfo &blockInfo)=0
static void computeBlockInfo(CodeGenModule &CGM, CodeGenFunction *CGF, CGBlockInfo &info)
unsigned char PointerAlignInBytes
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
llvm::Value * getConstant() const
static llvm::Constant * buildDisposeHelper(CodeGenModule &CGM, const CGBlockInfo &blockInfo)
Build the helper function to dispose of a block.
std::unique_ptr< DiagnosticConsumer > create(StringRef OutputFile, DiagnosticOptions *Diags, bool MergeChildRecords=false)
Returns a DiagnosticConsumer that serializes diagnostics to a bitcode file.
static llvm::Constant * generateByrefCopyHelper(CodeGenFunction &CGF, llvm::StructType &byrefType, unsigned valueFieldIndex, CodeGenModule::ByrefHelpers &byrefInfo)
static void enterBlockScope(CodeGenFunction &CGF, BlockDecl *block)
CanQualType UnsignedLongTy
llvm::Value * BuildBlockByrefAddress(llvm::Value *BaseAddr, const VarDecl *V)
llvm::PointerType * Int8PtrTy
static CGBlockInfo * findAndRemoveBlockInfo(CGBlockInfo **head, const BlockDecl *block)
Find the layout for the given block in a linked list and remove it.
llvm::Constant * GetAddrOfGlobalBlock(const BlockExpr *BE, const char *)
Gets the address of a block which requires no captures.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
Internal linkage, which indicates that the entity can be referred to from within the translation unit...
llvm::Constant * getBlockObjectAssign()
llvm::Constant * EmitConstantInit(const VarDecl &D, CodeGenFunction *CGF=nullptr)
Reading or writing from this object requires a barrier call.
static void initializeForBlockHeader(CodeGenModule &CGM, CGBlockInfo &info, SmallVectorImpl< llvm::Type * > &elementTypes)
Represents a C++ struct/union/class.
BoundNodesTreeBuilder *const Builder
bool isObjCObjectPointerType() const
uint32_t getBitMask() const
void PopCleanupBlocks(EHScopeStack::stable_iterator OldCleanupStackSize)
Takes the old cleanup stack size and emits the cleanup blocks that have been added.
const BlockDecl * getBlockDecl() const
CharUnits BlockHeaderForcedGapSize
llvm::Value * EmitARCRetainBlock(llvm::Value *value, bool mandatory)
llvm::Value * EmitARCStoreStrongCall(llvm::Value *addr, llvm::Value *value, bool resultIgnored)
void ForceCleanup()
Force the emission of cleanups now, instead of waiting until this object is destroyed.
unsigned getTargetAddressSpace(QualType T) const
A reference to a declared variable, function, enum, etc. [C99 6.5.1p2].
static RValue get(llvm::Value *V)
RValue EmitBlockCallExpr(const CallExpr *E, ReturnValueSlot ReturnValue)
virtual void emitCopy(CodeGenFunction &CGF, llvm::Value *dest, llvm::Value *src)=0
static AggValueSlot forAddr(llvm::Value *addr, CharUnits align, Qualifiers quals, IsDestructed_t isDestructed, NeedsGCBarriers_t needsGC, IsAliased_t isAliased, IsZeroed_t isZeroed=IsNotZeroed)
static ApplyDebugLocation CreateEmpty(CodeGenFunction &CGF)
llvm::Constant * getNSConcreteGlobalBlock()
llvm::Type * getBlockDescriptorType()
Fetches the type of a generic block descriptor.
An l-value expression is a reference to an object with independent storage.
const BlockExpr * getBlockExpr() const
SourceLocation getLocation() const
llvm::Instruction * DominatingIP
static llvm::Constant * buildByrefDisposeHelper(CodeGenModule &CGM, llvm::StructType &byrefType, unsigned byrefValueIndex, CodeGenModule::ByrefHelpers &info)
Build the dispose helper for a __block variable.
bool isConstQualified() const
Determine whether this type is const-qualified.
CharUnits RoundUpToAlignment(const CharUnits &Align) const
static llvm::Constant * generateByrefDisposeHelper(CodeGenFunction &CGF, llvm::StructType &byrefType, unsigned byrefValueIndex, CodeGenModule::ByrefHelpers &byrefInfo)
Generate code for a __block variable's dispose helper.
bool BlockRequiresCopying(QualType Ty, const VarDecl *D)
Returns true iff we need copy/dispose helpers for the given type.
void BuildBlockRelease(llvm::Value *DeclPtr, BlockFieldFlags flags)
void setCleanup(EHScopeStack::stable_iterator cleanup)
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
llvm::FunctionType * GetFunctionType(const CGFunctionInfo &Info)
GetFunctionType - Get the LLVM function type for.