24 #include "llvm/ADT/SmallSet.h" 25 #include "llvm/IR/CallSite.h" 26 #include "llvm/IR/DataLayout.h" 27 #include "llvm/IR/Module.h" 31 using namespace clang;
32 using namespace CodeGen;
35 : Name(name), CXXThisIndex(0), CanBeGlobal(
false), NeedsCopyDispose(
false),
36 HasCXXObject(
false), UsesStret(
false), HasCapturedVariableLayout(
false),
37 LocalAddress(
Address::invalid()), StructureType(nullptr), Block(block),
38 DominatingIP(nullptr) {
42 if (!name.empty() && name[0] ==
'\01')
43 name = name.substr(1);
52 llvm::Constant *blockFn);
84 llvm::IntegerType *
ulong =
86 llvm::PointerType *i8p =
nullptr;
89 llvm::Type::getInt8PtrTy(
98 elements.addInt(ulong, 0);
116 std::string typeAtEncoding =
118 elements.add(llvm::ConstantExpr::getBitCast(
129 elements.addNullPointer(i8p);
131 unsigned AddrSpace = 0;
135 llvm::GlobalVariable *global =
136 elements.finishAndCreateGlobal(
"__block_descriptor_tmp",
158 struct objc_class *isa;
185 _ResultType (*invoke)(Block_literal *, _ParamTypes...);
188 struct Block_descriptor *block_descriptor;
191 _CapturesTypes captures...;
197 struct BlockLayoutChunk {
209 : Alignment(align), Size(size), Lifetime(lifetime),
210 Capture(capture),
Type(type), FieldType(fieldType) {}
226 bool operator<(
const BlockLayoutChunk &left,
const BlockLayoutChunk &right) {
227 if (left.Alignment != right.Alignment)
228 return left.Alignment > right.Alignment;
230 auto getPrefOrder = [](
const BlockLayoutChunk &chunk) {
231 if (chunk.Capture && chunk.Capture->isByRef())
240 return getPrefOrder(left) < getPrefOrder(right);
250 if (!recordType)
return true;
252 const auto *record = cast<CXXRecordDecl>(recordType->
getDecl());
255 if (!record->hasTrivialDestructor())
return false;
256 if (record->hasNonTrivialCopyConstructor())
return false;
260 return !record->hasMutableFields();
274 if (isa<ParmVarDecl>(var))
294 if (!init)
return nullptr;
308 assert(elementTypes.empty());
320 assert((2 * CGM.
getIntSize()).isMultipleOf(GenPtrAlign));
321 elementTypes.push_back(CGM.
IntTy);
322 elementTypes.push_back(CGM.
IntTy);
323 elementTypes.push_back(
331 for (
auto I : Helper->getCustomFieldTypes()) {
335 if (BlockAlign < Align)
337 assert(Offset % Align == 0);
339 elementTypes.push_back(I);
353 elementTypes.push_back(CGM.
IntTy);
354 elementTypes.push_back(CGM.
IntTy);
369 return FD->getType();
382 bool hasNonConstantCustomFields =
false;
383 if (
auto *OpenCLHelper =
385 hasNonConstantCustomFields =
386 !OpenCLHelper->areAllCustomFieldValuesConstant(info);
387 if (!block->
hasCaptures() && !hasNonConstantCustomFields) {
407 "Can't capture 'this' outside a method");
413 std::pair<CharUnits,CharUnits> tinfo
415 maxFieldAlign =
std::max(maxFieldAlign, tinfo.second);
417 layout.push_back(BlockLayoutChunk(tinfo.second, tinfo.first,
419 nullptr, llvmType, thisType));
423 for (
const auto &CI : block->
captures()) {
424 const VarDecl *variable = CI.getVariable();
432 maxFieldAlign =
std::max(maxFieldAlign, align);
476 }
else if (CI.hasCopyExpr()) {
484 if (!record->hasTrivialDestructor()) {
495 maxFieldAlign =
std::max(maxFieldAlign, align);
501 BlockLayoutChunk(align, size, lifetime, &CI, llvmType, VT));
505 if (layout.empty()) {
515 std::stable_sort(layout.begin(), layout.end());
539 if (endAlign < maxFieldAlign) {
541 li = layout.begin() + 1, le = layout.end();
545 for (; li != le && endAlign < li->Alignment; ++li)
552 for (; li != le; ++li) {
553 assert(endAlign >= li->Alignment);
555 li->setIndex(info, elementTypes.size(), blockSize);
556 elementTypes.push_back(li->Type);
557 blockSize += li->Size;
561 if (endAlign >= maxFieldAlign) {
566 layout.erase(first, li);
570 assert(endAlign ==
getLowBit(blockSize));
574 if (endAlign < maxFieldAlign) {
576 CharUnits padding = newBlockSize - blockSize;
584 elementTypes.push_back(llvm::ArrayType::get(CGM.
Int8Ty,
586 blockSize = newBlockSize;
590 assert(endAlign >= maxFieldAlign);
591 assert(endAlign ==
getLowBit(blockSize));
596 li = layout.begin(), le = layout.end(); li != le; ++li) {
597 if (endAlign < li->Alignment) {
601 CharUnits padding = li->Alignment - endAlign;
602 elementTypes.push_back(llvm::ArrayType::get(CGM.
Int8Ty,
604 blockSize += padding;
607 assert(endAlign >= li->Alignment);
608 li->setIndex(info, elementTypes.size(), blockSize);
609 elementTypes.push_back(li->Type);
610 blockSize += li->Size;
635 if (blockInfo.CanBeGlobal)
return;
639 blockInfo.BlockAlign,
"block");
642 if (!blockInfo.NeedsCopyDispose)
return;
646 for (
const auto &CI : block->
captures()) {
649 if (CI.isByRef())
continue;
652 const VarDecl *variable = CI.getVariable();
673 "expected ObjC ARC to be enabled");
687 if (!blockInfo.DominatingIP)
688 blockInfo.DominatingIP = cast<llvm::Instruction>(addr.
getPointer());
692 if (useArrayEHCleanup)
696 destroyer, useArrayEHCleanup);
710 i = cleanups.begin(), e = cleanups.end(); i != e; ++i) {
719 assert(head && *head);
734 assert(head &&
"destroying an empty chain");
739 }
while (head !=
nullptr);
744 llvm::Function **InvokeF) {
752 auto *GV = cast<llvm::GlobalVariable>(
753 cast<llvm::Constant>(
Block)->stripPointerCasts());
754 auto *BlockInit = cast<llvm::ConstantStruct>(GV->getInitializer());
755 *InvokeF = cast<llvm::Function>(
756 BlockInit->getAggregateElement(2)->stripPointerCasts());
763 return EmitBlockLiteral(blockInfo, InvokeF);
767 std::unique_ptr<CGBlockInfo> blockInfo;
772 return EmitBlockLiteral(*blockInfo, InvokeF);
776 llvm::Function **InvokeF) {
788 BlockCGF.SanOpts = SanOpts;
789 auto *InvokeFn = BlockCGF.GenerateBlockFunction(
790 CurGD, blockInfo, LocalDeclMap, isLambdaConv, blockInfo.
CanBeGlobal);
793 auto *blockFn = llvm::ConstantExpr::getPointerCast(InvokeFn, GenVoidPtrTy);
802 assert(blockAddr.
isValid() &&
"block has no address!");
805 llvm::Constant *descriptor;
828 return Builder.CreateStructGEP(blockAddr, index, offset, name);
833 Builder.CreateStore(value, projectField(index, offset, name));
841 auto addHeaderField =
843 storeField(value, index, offset, name);
849 addHeaderField(isa, getPointerSize(),
"block.isa");
850 addHeaderField(llvm::ConstantInt::get(IntTy, flags.
getBitMask()),
851 getIntSize(),
"block.flags");
852 addHeaderField(llvm::ConstantInt::get(IntTy, 0), getIntSize(),
857 getIntSize(),
"block.size");
860 getIntSize(),
"block.align");
862 addHeaderField(blockFn, GenVoidPtrSize,
"block.invoke");
864 addHeaderField(descriptor, getPointerSize(),
"block.descriptor");
865 else if (
auto *Helper =
867 for (
auto I : Helper->getCustomFieldValues(*
this, blockInfo)) {
881 if (blockDecl->capturesCXXThis()) {
883 "block.captured-this.addr");
884 Builder.CreateStore(LoadCXXThis(), addr);
888 for (
const auto &CI : blockDecl->captures()) {
889 const VarDecl *variable = CI.getVariable();
906 if (blockDecl->isConversionFromLambda()) {
910 }
else if (CI.isByRef()) {
911 if (BlockInfo && CI.isNested()) {
914 BlockInfo->getCapture(variable);
917 src = Builder.CreateStructGEP(LoadBlockStruct(),
920 "block.capture.addr");
922 auto I = LocalDeclMap.find(variable);
923 assert(I != LocalDeclMap.end());
927 DeclRefExpr declRef(const_cast<VarDecl *>(variable),
931 src = EmitDeclRefLValue(&declRef).getAddress();
942 byrefPointer = Builder.CreateLoad(src,
"byref.capture");
944 byrefPointer = Builder.CreateBitCast(src.getPointer(), VoidPtrTy);
947 Builder.CreateStore(byrefPointer, blockField);
950 }
else if (
const Expr *copyExpr = CI.getCopyExpr()) {
951 if (blockDecl->isConversionFromLambda()) {
959 EmitAggExpr(copyExpr, Slot);
961 EmitSynthesizedCXXCopyCtor(blockField, src, copyExpr);
966 Builder.CreateStore(src.getPointer(), blockField);
972 llvm::Value *value = Builder.CreateLoad(src,
"captured");
973 Builder.CreateStore(value, blockField);
985 llvm::Value *value = Builder.CreateLoad(src,
"block.captured_block");
986 value = EmitARCRetainNonBlock(value);
989 Builder.CreateStore(value, blockField);
1000 DeclRefExpr declRef(const_cast<VarDecl *>(variable),
1009 EmitExprAsInit(&l2r, &BlockFieldPseudoVar,
1015 if (!CI.isByRef()) {
1032 if (BlockDescriptorType)
1033 return BlockDescriptorType;
1036 getTypes().ConvertType(getContext().UnsignedLongTy);
1053 "struct.__block_descriptor", UnsignedLongTy, UnsignedLongTy);
1056 unsigned AddrSpace = 0;
1057 if (getLangOpts().OpenCL)
1059 BlockDescriptorType = llvm::PointerType::get(BlockDescriptorType, AddrSpace);
1060 return BlockDescriptorType;
1064 if (GenericBlockLiteralType)
1065 return GenericBlockLiteralType;
1067 llvm::Type *BlockDescPtrTy = getBlockDescriptorType();
1069 if (getLangOpts().OpenCL) {
1077 {IntTy, IntTy, getOpenCLRuntime().getGenericVoidPointerType()});
1078 if (
auto *Helper = getTargetCodeGenInfo().getTargetOpenCLBlockHelper()) {
1079 for (
auto I : Helper->getCustomFieldTypes())
1080 StructFields.push_back(I);
1083 StructFields,
"struct.__opencl_block_literal_generic");
1092 GenericBlockLiteralType =
1094 IntTy, IntTy, VoidPtrTy, BlockDescPtrTy);
1097 return GenericBlockLiteralType;
1112 unsigned AddrSpace = 0;
1113 if (getLangOpts().OpenCL)
1121 Builder.CreatePointerCast(BlockPtr, BlockLiteralTy,
"block.literal");
1131 QualType VoidPtrQualTy = getContext().VoidPtrTy;
1133 if (getLangOpts().OpenCL) {
1136 getContext().getPointerType(getContext().getAddrSpaceQualType(
1140 BlockPtr = Builder.CreatePointerCast(BlockPtr, GenericVoidPtrTy);
1149 llvm::Value *Func = Builder.CreateAlignedLoad(FuncPtr, getPointerAlign());
1158 llvm::Type *BlockFTyPtr = llvm::PointerType::getUnqual(BlockFTy);
1159 Func = Builder.CreatePointerCast(Func, BlockFTyPtr);
1165 return EmitCall(FnInfo, Callee, ReturnValue, Args);
1170 assert(BlockInfo &&
"evaluating block ref without block information?");
1174 if (capture.
isConstant())
return LocalDeclMap.find(variable)->second;
1177 Builder.CreateStructGEP(LoadBlockStruct(), capture.
getIndex(),
1178 capture.
getOffset(),
"block.capture.addr");
1184 auto &byrefInfo = getBlockByrefInfo(variable);
1185 addr =
Address(Builder.CreateLoad(addr), byrefInfo.ByrefAlignment);
1187 auto byrefPointerType = llvm::PointerType::get(byrefInfo.Type, 0);
1188 addr = Builder.CreateBitCast(addr, byrefPointerType,
"byref.addr");
1190 addr = emitBlockByrefAddress(addr, byrefInfo,
true,
1195 addr = EmitLoadOfReference(MakeAddrLValue(addr, capture.
fieldType()));
1201 llvm::Constant *Addr) {
1202 bool Ok = EmittedGlobalBlocks.insert(std::make_pair(BE, Addr)).second;
1204 assert(Ok &&
"Trying to replace an already-existing global block!");
1210 if (llvm::Constant *
Block = getAddrOfGlobalBlockIfEmitted(BE))
1227 return getAddrOfGlobalBlockIfEmitted(BE);
1232 llvm::Constant *blockFn) {
1238 "Refusing to re-emit a global block.");
1242 auto fields = builder.beginStruct();
1257 fields.addInt(CGM.
IntTy, 0);
1264 fields.add(blockFn);
1269 }
else if (
auto *Helper =
1271 for (
auto I : Helper->getCustomFieldValues(CGM, blockInfo)) {
1276 unsigned AddrSpace = 0;
1280 llvm::Constant *literal = fields.finishAndCreateGlobal(
1281 "__block_literal_global", blockInfo.
BlockAlign,
1287 llvm::Constant *Result =
1288 llvm::ConstantExpr::getPointerCast(literal, RequiredType);
1296 assert(BlockInfo &&
"not emitting prologue of block invocation function?!");
1301 Builder.CreateStore(arg, alloc);
1306 DI->EmitDeclareOfBlockLiteralArgVariable(
1307 *BlockInfo, D->
getName(), argNum,
1308 cast<llvm::AllocaInst>(alloc.
getPointer()), Builder);
1312 SourceLocation StartLoc = BlockInfo->getBlockExpr()->getBody()->getLocStart();
1317 BlockPointer = Builder.CreatePointerCast(
1319 BlockInfo->StructureType->getPointerTo(
1320 getContext().getLangOpts().OpenCL
1327 assert(BlockInfo &&
"not in a block invocation function!");
1328 assert(BlockPointer &&
"no block pointer set!");
1329 return Address(BlockPointer, BlockInfo->BlockAlign);
1336 bool IsLambdaConversionToBlock,
1337 bool BuildGlobalBlock) {
1344 BlockInfo = &blockInfo;
1349 for (DeclMapTy::const_iterator i = ldm.begin(), e = ldm.end(); i != e; ++i) {
1350 const auto *var = dyn_cast<
VarDecl>(i->first);
1351 if (var && !var->hasLocalStorage())
1352 setAddrOfLocalVar(var, i->second);
1362 QualType selfTy = getContext().VoidPtrTy;
1368 if (getLangOpts().OpenCL)
1369 selfTy = getContext().getPointerType(getContext().getAddrSpaceQualType(
1377 args.push_back(&SelfDecl);
1396 if (BuildGlobalBlock) {
1397 auto GenVoidPtrTy = getContext().getLangOpts().OpenCL
1401 llvm::ConstantExpr::getPointerCast(fn, GenVoidPtrTy));
1405 StartFunction(blockDecl, fnType->
getReturnType(), fn, fnInfo, args,
1416 Address Alloca = CreateTempAlloca(BlockPointer->getType(),
1422 Builder.CreateStore(BlockPointer, Alloca);
1430 Builder.CreateStructGEP(LoadBlockStruct(), blockInfo.
CXXThisIndex,
1432 CXXThisValue = Builder.CreateLoad(addr,
"this");
1436 for (
const auto &CI : blockDecl->
captures()) {
1437 const VarDecl *variable = CI.getVariable();
1441 CharUnits align = getContext().getDeclAlign(variable);
1443 CreateMemTemp(variable->
getType(), align,
"block.captured-const");
1445 Builder.CreateStore(capture.
getConstant(), alloca);
1447 setAddrOfLocalVar(variable, alloca);
1451 llvm::BasicBlock *entry = Builder.GetInsertBlock();
1452 llvm::BasicBlock::iterator entry_ptr = Builder.GetInsertPoint();
1455 if (IsLambdaConversionToBlock)
1456 EmitLambdaBlockInvokeBody();
1458 PGO.assignRegionCounters(
GlobalDecl(blockDecl), fn);
1459 incrementProfileCounter(blockDecl->
getBody());
1460 EmitStmt(blockDecl->
getBody());
1464 llvm::BasicBlock *resume = Builder.GetInsertBlock();
1468 Builder.SetInsertPoint(entry, entry_ptr);
1473 for (
const auto &CI : blockDecl->
captures()) {
1474 const VarDecl *variable = CI.getVariable();
1475 DI->EmitLocation(Builder, variable->
getLocation());
1481 auto addr = LocalDeclMap.find(variable)->second;
1482 DI->EmitDeclareOfAutoVariable(variable, addr.getPointer(),
1487 DI->EmitDeclareOfBlockDeclRefVariable(
1488 variable, BlockPointerDbgLoc, Builder, blockInfo,
1489 entry_ptr == entry->end() ? nullptr : &*entry_ptr);
1493 DI->EmitLocation(Builder,
1494 cast<CompoundStmt>(blockDecl->
getBody())->getRBracLoc());
1498 if (resume ==
nullptr)
1499 Builder.ClearInsertionPoint();
1501 Builder.SetInsertPoint(resume);
1503 FinishFunction(cast<CompoundStmt>(blockDecl->
getBody())->getRBracLoc());
1522 struct BlockCaptureManagedEntity {
1531 :
Kind(Type), Flags(Flags), CI(CI), Capture(Capture) {}
1536 static std::pair<BlockCaptureEntityKind, BlockFieldFlags>
1542 return std::make_pair(BlockCaptureEntityKind::CXXRecord,
BlockFieldFlags());
1549 return std::make_pair(BlockCaptureEntityKind::BlockObject, Flags);
1565 return std::make_pair(BlockCaptureEntityKind::ARCWeak, Flags);
1572 return std::make_pair(!isBlockPointer ? BlockCaptureEntityKind::ARCStrong
1573 : BlockCaptureEntityKind::BlockObject,
1580 return std::make_pair(BlockCaptureEntityKind::BlockObject, Flags);
1590 llvm::function_ref<std::pair<BlockCaptureEntityKind, BlockFieldFlags>(
1594 const VarDecl *Variable = CI.getVariable();
1599 auto Info = Predicate(CI, Variable->
getType(), LangOpts);
1601 ManagedCaptures.emplace_back(Info.first, Info.second, CI, Capture);
1620 args.push_back(&DstDecl);
1623 args.push_back(&SrcDecl);
1632 llvm::Function *Fn =
1634 "__copy_helper_block_", &CGM.
getModule());
1649 StartFunction(FD, C.
VoidTy, Fn, FI, args);
1653 Address src = GetAddrOfLocalVar(&SrcDecl);
1655 src = Builder.CreateBitCast(src, structPtrTy,
"block.source");
1657 Address dst = GetAddrOfLocalVar(&DstDecl);
1659 dst = Builder.CreateBitCast(dst, structPtrTy,
"block.dest");
1665 for (
const auto &CopiedCapture : CopiedCaptures) {
1670 unsigned index = capture.
getIndex();
1671 Address srcField = Builder.CreateStructGEP(src, index, capture.
getOffset());
1672 Address dstField = Builder.CreateStructGEP(dst, index, capture.
getOffset());
1676 assert(CopiedCapture.Kind == BlockCaptureEntityKind::CXXRecord);
1677 EmitSynthesizedCXXCopyCtor(dstField, srcField, CI.
getCopyExpr());
1678 }
else if (CopiedCapture.Kind == BlockCaptureEntityKind::ARCWeak) {
1679 EmitARCCopyWeak(dstField, srcField);
1681 llvm::Value *srcValue = Builder.CreateLoad(srcField,
"blockcopy.src");
1682 if (CopiedCapture.Kind == BlockCaptureEntityKind::ARCStrong) {
1687 auto *ty = cast<llvm::PointerType>(srcValue->getType());
1688 llvm::Value *null = llvm::ConstantPointerNull::get(ty);
1689 Builder.CreateStore(null, dstField);
1690 EmitARCStoreStrongCall(dstField, srcValue,
true);
1696 EmitARCRetainNonBlock(srcValue);
1700 cast<llvm::Instruction>(dstField.
getPointer())->eraseFromParent();
1703 assert(CopiedCapture.Kind == BlockCaptureEntityKind::BlockObject);
1704 srcValue = Builder.CreateBitCast(srcValue, VoidPtrTy);
1706 Builder.CreateBitCast(dstField.
getPointer(), VoidPtrTy);
1708 dstAddr, srcValue, llvm::ConstantInt::get(Int32Ty, flags.
getBitMask())
1712 bool copyCanThrow =
false;
1713 if (CI.
isByRef() && variable->getType()->getAsCXXRecordDecl()) {
1714 const Expr *copyExpr =
1717 copyCanThrow =
true;
1732 return llvm::ConstantExpr::getBitCast(Fn, VoidPtrTy);
1735 static std::pair<BlockCaptureEntityKind, BlockFieldFlags>
1743 return std::make_pair(BlockCaptureEntityKind::BlockObject, Flags);
1747 if (Record->hasTrivialDestructor())
1749 return std::make_pair(BlockCaptureEntityKind::CXXRecord,
BlockFieldFlags());
1766 return std::make_pair(BlockCaptureEntityKind::ARCStrong, Flags);
1770 return std::make_pair(BlockCaptureEntityKind::ARCWeak, Flags);
1775 return std::make_pair(BlockCaptureEntityKind::BlockObject, Flags);
1795 args.push_back(&SrcDecl);
1804 llvm::Function *Fn =
1806 "__destroy_helper_block_", &CGM.
getModule());
1819 StartFunction(FD, C.
VoidTy, Fn, FI, args);
1824 Address src = GetAddrOfLocalVar(&SrcDecl);
1826 src = Builder.CreateBitCast(src, structPtrTy,
"block");
1834 for (
const auto &DestroyedCapture : DestroyedCaptures) {
1843 if (DestroyedCapture.Kind == BlockCaptureEntityKind::CXXRecord) {
1846 PushDestructorCleanup(Dtor, srcField);
1849 }
else if (DestroyedCapture.Kind == BlockCaptureEntityKind::ARCWeak) {
1850 EmitARCDestroyWeak(srcField);
1853 }
else if (DestroyedCapture.Kind == BlockCaptureEntityKind::ARCStrong) {
1860 assert(DestroyedCapture.Kind == BlockCaptureEntityKind::BlockObject);
1861 llvm::Value *value = Builder.CreateLoad(srcField);
1862 value = Builder.CreateBitCast(value, VoidPtrTy);
1863 BuildBlockRelease(value, flags);
1871 return llvm::ConstantExpr::getBitCast(Fn, VoidPtrTy);
1907 void profileImpl(llvm::FoldingSetNodeID &
id)
const override {
1908 id.AddInteger(Flags.getBitMask());
1926 void profileImpl(llvm::FoldingSetNodeID &
id)
const override {
1946 llvm::ConstantPointerNull::get(cast<llvm::PointerType>(value->getType()));
1962 void profileImpl(llvm::FoldingSetNodeID &
id)
const override {
1972 ARCStrongBlockByrefHelpers(
CharUnits alignment)
1989 void profileImpl(llvm::FoldingSetNodeID &
id)
const override {
1999 const Expr *CopyExpr;
2003 const Expr *copyExpr)
2006 bool needsCopy()
const override {
return CopyExpr !=
nullptr; }
2009 if (!CopyExpr)
return;
2019 void profileImpl(llvm::FoldingSetNodeID &
id)
const override {
2020 id.AddPointer(VarType.getCanonicalType().getAsOpaquePtr());
2025 static llvm::Constant *
2035 args.push_back(&Dst);
2039 args.push_back(&Src);
2048 llvm::Function *Fn =
2053 = &Context.
Idents.
get(
"__Block_byref_object_copy_");
2085 generator.
emitCopy(CGF, destField, srcField);
2090 return llvm::ConstantExpr::getBitCast(Fn, CGF.
Int8PtrTy);
2102 static llvm::Constant *
2112 args.push_back(&Src);
2121 llvm::Function *Fn =
2123 "__Block_byref_object_dispose_",
2127 = &Context.
Idents.
get(
"__Block_byref_object_dispose_");
2143 auto byrefPtrType = byrefInfo.
Type->getPointerTo(0);
2152 return llvm::ConstantExpr::getBitCast(Fn, CGF.
Int8PtrTy);
2168 llvm::FoldingSetNodeID
id;
2169 generator.Profile(
id);
2174 if (node)
return static_cast<T*
>(node);
2179 T *copy =
new (CGM.
getContext())
T(std::forward<T>(generator));
2188 CodeGenFunction::buildByrefHelpers(llvm::StructType &byrefType,
2189 const AutoVarEmission &emission) {
2190 const VarDecl &var = *emission.Variable;
2193 auto &byrefInfo = getBlockByrefInfo(&var);
2202 if (!copyExpr && record->hasTrivialDestructor())
return nullptr;
2205 CGM, byrefInfo, CXXByrefHelpers(valueAlignment, type, copyExpr));
2228 ARCWeakByrefHelpers(valueAlignment));
2236 ARCStrongBlockByrefHelpers(valueAlignment));
2242 ARCStrongByrefHelpers(valueAlignment));
2245 llvm_unreachable(
"fell out of lifetime switch!");
2262 ObjectByrefHelpers(valueAlignment, flags));
2267 bool followForward) {
2268 auto &info = getBlockByrefInfo(var);
2269 return emitBlockByrefAddress(baseAddr, info, followForward, var->
getName());
2275 const llvm::Twine &name) {
2277 if (followForward) {
2279 Builder.CreateStructGEP(baseAddr, 1, getPointerSize(),
"forwarding");
2283 return Builder.CreateStructGEP(baseAddr, info.
FieldIndex,
2303 auto it = BlockByrefInfos.find(D);
2304 if (it != BlockByrefInfos.end())
2307 llvm::StructType *byrefType =
2317 types.push_back(Int8PtrTy);
2318 size += getPointerSize();
2321 types.push_back(llvm::PointerType::getUnqual(byrefType));
2322 size += getPointerSize();
2325 types.push_back(Int32Ty);
2329 types.push_back(Int32Ty);
2333 bool hasCopyAndDispose = getContext().BlockRequiresCopying(Ty, D);
2334 if (hasCopyAndDispose) {
2336 types.push_back(Int8PtrTy);
2337 size += getPointerSize();
2340 types.push_back(Int8PtrTy);
2341 size += getPointerSize();
2344 bool HasByrefExtendedLayout =
false;
2346 if (getContext().getByrefLifetime(Ty, Lifetime, HasByrefExtendedLayout) &&
2347 HasByrefExtendedLayout) {
2349 types.push_back(Int8PtrTy);
2356 bool packed =
false;
2357 CharUnits varAlign = getContext().getDeclAlign(D);
2361 if (varOffset != size) {
2363 llvm::ArrayType::get(Int8Ty, (varOffset - size).getQuantity());
2365 types.push_back(paddingTy);
2373 types.push_back(varTy);
2375 byrefType->setBody(types, packed);
2378 info.
Type = byrefType;
2383 auto pair = BlockByrefInfos.insert({D, info});
2384 assert(pair.second &&
"info was inserted recursively?");
2385 return pair.first->second;
2395 llvm::StructType *byrefType = cast<llvm::StructType>(
2396 cast<llvm::PointerType>(addr.
getPointer()->getType())->getElementType());
2398 unsigned nextHeaderIndex = 0;
2401 const Twine &name) {
2402 auto fieldAddr = Builder.CreateStructGEP(addr, nextHeaderIndex,
2403 nextHeaderOffset, name);
2404 Builder.CreateStore(value, fieldAddr);
2407 nextHeaderOffset += fieldSize;
2413 const VarDecl &D = *emission.Variable;
2416 bool HasByrefExtendedLayout;
2418 bool ByRefHasLifetime =
2419 getContext().getByrefLifetime(type, ByrefLifetime, HasByrefExtendedLayout);
2427 V = Builder.CreateIntToPtr(Builder.getInt32(isa), Int8PtrTy,
"isa");
2428 storeHeaderField(V, getPointerSize(),
"byref.isa");
2431 storeHeaderField(addr.
getPointer(), getPointerSize(),
"byref.forwarding");
2438 if (ByRefHasLifetime) {
2440 else switch (ByrefLifetime) {
2458 printf(
"\n Inline flag for BYREF variable layout (%d):", flags.getBitMask());
2460 printf(
" BLOCK_BYREF_HAS_COPY_DISPOSE");
2464 printf(
" BLOCK_BYREF_LAYOUT_EXTENDED");
2466 printf(
" BLOCK_BYREF_LAYOUT_STRONG");
2468 printf(
" BLOCK_BYREF_LAYOUT_WEAK");
2470 printf(
" BLOCK_BYREF_LAYOUT_UNRETAINED");
2472 printf(
" BLOCK_BYREF_LAYOUT_NON_OBJECT");
2477 storeHeaderField(llvm::ConstantInt::get(IntTy, flags.getBitMask()),
2478 getIntSize(),
"byref.flags");
2481 V = llvm::ConstantInt::get(IntTy, byrefSize.getQuantity());
2482 storeHeaderField(V, getIntSize(),
"byref.size");
2485 storeHeaderField(helpers->
CopyHelper, getPointerSize(),
2486 "byref.copyHelper");
2488 "byref.disposeHelper");
2491 if (ByRefHasLifetime && HasByrefExtendedLayout) {
2493 storeHeaderField(layoutInfo, getPointerSize(),
"byref.layout");
2500 Builder.CreateBitCast(V, Int8PtrTy),
2501 llvm::ConstantInt::get(Int32Ty, flags.
getBitMask())
2503 EmitNounwindRuntimeCall(F, args);
2510 CallBlockRelease(
llvm::Value *Addr) : Addr(Addr) {}
2534 llvm::Constant *C) {
2535 auto *GV = cast<llvm::GlobalValue>(C->stripPointerCasts());
2542 assert((isa<llvm::Function>(C->stripPointerCasts()) ||
2543 isa<llvm::GlobalVariable>(C->stripPointerCasts())) &&
2544 "expected Function or GlobalVariable");
2547 for (
const auto &Result : DC->
lookup(&II))
2548 if ((ND = dyn_cast<FunctionDecl>(Result)) ||
2549 (ND = dyn_cast<
VarDecl>(Result)))
2553 if (GV->isDeclaration() && (!ND || !ND->hasAttr<DLLExportAttr>())) {
2554 GV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
2557 GV->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
2565 if (GV->isDeclaration() && GV->hasExternalLinkage())
2566 GV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage);
2570 if (BlockObjectDispose)
2571 return BlockObjectDispose;
2574 llvm::FunctionType *fty
2575 = llvm::FunctionType::get(VoidTy, args,
false);
2576 BlockObjectDispose = CreateRuntimeFunction(fty,
"_Block_object_dispose");
2578 return BlockObjectDispose;
2582 if (BlockObjectAssign)
2583 return BlockObjectAssign;
2585 llvm::Type *args[] = { Int8PtrTy, Int8PtrTy, Int32Ty };
2586 llvm::FunctionType *fty
2587 = llvm::FunctionType::get(VoidTy, args,
false);
2588 BlockObjectAssign = CreateRuntimeFunction(fty,
"_Block_object_assign");
2590 return BlockObjectAssign;
2594 if (NSConcreteGlobalBlock)
2595 return NSConcreteGlobalBlock;
2597 NSConcreteGlobalBlock = GetOrCreateLLVMGlobal(
"_NSConcreteGlobalBlock",
2598 Int8PtrTy->getPointerTo(),
2601 return NSConcreteGlobalBlock;
2605 if (NSConcreteStackBlock)
2606 return NSConcreteStackBlock;
2608 NSConcreteStackBlock = GetOrCreateLLVMGlobal(
"_NSConcreteStackBlock",
2609 Int8PtrTy->getPointerTo(),
2612 return NSConcreteStackBlock;
const CGFunctionInfo & arrangeBuiltinFunctionDeclaration(QualType resultType, const FunctionArgList &args)
A builtin function is a freestanding function using the default C conventions.
void enterNonTrivialFullExpression(const ExprWithCleanups *E)
Enter a full-expression with a non-trivial number of objects to clean up.
const llvm::DataLayout & getDataLayout() const
CGOpenCLRuntime & getOpenCLRuntime()
Return a reference to the configured OpenCL runtime.
ReturnValueSlot - Contains the address where the return value of a function can be stored...
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const BlockDecl * getBlockDecl() const
Information about the layout of a __block variable.
CharUnits alignTo(const CharUnits &Align) const
alignTo - Returns the next integer (mod 2**64) that is greater than or equal to this quantity and is ...
const Capture & getCapture(const VarDecl *var) const
llvm::Constant * GenerateCopyHelperFunction(const CGBlockInfo &blockInfo)
Generate the copy-helper function for a block closure object: static void block_copy_helper(block_t *...
static llvm::Constant * generateByrefDisposeHelper(CodeGenFunction &CGF, const BlockByrefInfo &byrefInfo, BlockByrefHelpers &generator)
Generate code for a __block variable's dispose helper.
An instance of this class is created to represent a function declaration or definition.
llvm::IntegerType * IntTy
int
llvm::Type * getGenericBlockLiteralType()
The type of a generic block literal.
CharUnits getIntAlign() const
const CGFunctionInfo & arrangeBlockFunctionDeclaration(const FunctionProtoType *type, const FunctionArgList &args)
Block invocation functions are C functions with an implicit parameter.
External linkage, which indicates that the entity can be referred to from other translation units...
Other implicit parameter.
CharUnits BlockHeaderForcedGapOffset
const FunctionProtoType * getFunctionType() const
getFunctionType - Return the underlying function type for this block.
Expr * getCopyExpr() const
static llvm::Constant * buildByrefDisposeHelper(CodeGenModule &CGM, const BlockByrefInfo &byrefInfo, BlockByrefHelpers &generator)
Build the dispose helper for a __block variable.
A class which contains all the information about a particular captured value.
Destroyer * getDestroyer(QualType::DestructionKind destructionKind)
A (possibly-)qualified type.
bool isBlockPointerType() const
CodeGenTypes & getTypes()
const CodeGenOptions & getCodeGenOpts() const
bool hasCaptures() const
hasCaptures - True if this block (or its nested blocks) captures anything of local storage from its e...
bool HaveInsertPoint() const
HaveInsertPoint - True if an insertion point is defined.
capture_const_iterator capture_begin() const
llvm::LLVMContext & getLLVMContext()
void EmitARCDestroyWeak(Address addr)
void @objc_destroyWeak(i8** addr) Essentially objc_storeWeak(addr, nil).
llvm::Constant * CopyHelper
The standard implementation of ConstantInitBuilder used in Clang.
FunctionType - C99 6.7.5.3 - Function Declarators.
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
static T * buildByrefHelpers(CodeGenModule &CGM, const BlockByrefInfo &byrefInfo, T &&generator)
Lazily build the copy and dispose helpers for a __block variable with the given information.
ArrayRef< CleanupObject > getObjects() const
CharUnits getPointerSize() const
param_iterator param_end()
static llvm::Constant * buildBlockDescriptor(CodeGenModule &CGM, const CGBlockInfo &blockInfo)
buildBlockDescriptor - Build the block descriptor meta-data for a block.
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
The base class of the type hierarchy.
stable_iterator stable_begin() const
Create a stable reference to the top of the EH stack.
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64
capture_const_iterator capture_end() const
Address GetAddrOfLocalVar(const VarDecl *VD)
GetAddrOfLocalVar - Return the address of a local variable.
VarDecl - An instance of this class is created to represent a variable declaration or definition...
CGBlockInfo(const BlockDecl *blockDecl, StringRef Name)
const T * getAs() const
Member-template getAs<specific type>'.
EHScopeStack::stable_iterator getCleanup() 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.
Represents an expression – generally a full-expression – that introduces cleanups to be run at the ...
static void destroyBlockInfos(CGBlockInfo *info)
Destroy a chain of block layouts.
SourceLocation getLocStart() const LLVM_READONLY
The collection of all-type qualifiers we support.
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.
One of these records is kept for each identifier that is lexed.
void emitByrefStructureInit(const AutoVarEmission &emission)
Initialize the structural components of a __block variable, i.e.
CGBlockInfo * FirstBlockInfo
FirstBlockInfo - The head of a singly-linked-list of block layouts.
QualType getPointeeType() const
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
llvm::Type * ConvertType(QualType T)
ConvertType - Convert type T into a llvm::Type.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
llvm::Constant * tryEmitAbstractForInitializer(const VarDecl &D)
Try to emit the initializer of the given declaration as an abstract constant.
bool HasCapturedVariableLayout
HasCapturedVariableLayout : True if block has captured variables and their layout meta-data has been ...
static std::pair< BlockCaptureEntityKind, BlockFieldFlags > computeDestroyInfoForBlockCapture(const BlockDecl::Capture &CI, QualType T, const LangOptions &LangOpts)
bool isReferenceType() const
static void findBlockCapturedManagedEntities(const CGBlockInfo &BlockInfo, const LangOptions &LangOpts, SmallVectorImpl< BlockCaptureManagedEntity > &ManagedCaptures, llvm::function_ref< std::pair< BlockCaptureEntityKind, BlockFieldFlags >(const BlockDecl::Capture &, QualType, const LangOptions &)> Predicate)
Find the set of block captures that need to be explicitly copied or destroy.
std::string getObjCEncodingForBlock(const BlockExpr *blockExpr) const
Return the encoded type for this block declaration.
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++.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
An r-value expression (a pr-value in the C++11 taxonomy) produces a temporary value.
CharUnits GetTargetTypeStoreSize(llvm::Type *Ty) const
Return the store size, in character units, of the given LLVM type.
llvm::Value * EmitARCStoreStrongCall(Address addr, llvm::Value *value, bool resultIgnored)
Store into a strong object.
Address GetAddrOfBlockDecl(const VarDecl *var, bool ByRef)
CharUnits - This is an opaque type for sizes expressed in character units.
void EmitARCDestroyStrong(Address addr, ARCPreciseLifetime_t precise)
Destroy a __strong variable.
const BlockDecl * getBlockDecl() const
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::PointerType * VoidPtrTy
uint32_t getBitMask() const
bool isByRef() const
Whether this is a "by ref" capture, i.e.
bool needsEHCleanup(QualType::DestructionKind kind)
Determines whether an EH cleanup is required to destroy a type with the given destruction kind...
llvm::Constant * getAddrOfGlobalBlockIfEmitted(const BlockExpr *BE)
Returns the address of a block which requires no caputres, or null if we've yet to emit the block for...
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
CXXDestructorDecl * getDestructor() const
Returns the destructor decl for this class.
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...
llvm::Value * EmitBlockLiteral(const BlockExpr *, llvm::Function **InvokeF=nullptr)
Emit block literal.
const Stmt * getBody() const
llvm::Constant * getNSConcreteStackBlock()
static FunctionDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation NLoc, DeclarationName N, QualType T, TypeSourceInfo *TInfo, StorageClass SC, bool isInlineSpecified=false, bool hasWrittenPrototype=true, bool isConstexprSpecified=false)
This object can be modified without requiring retains or releases.
StringRef Name
Name - The name of the block, kindof.
bool NeedsCopyDispose
True if the block needs a custom copy or dispose function.
lookup_result lookup(DeclarationName Name) const
lookup - Find the declarations (if any) with the given Name in this context.
const BlockExpr * BlockExpression
unsigned getIndex() const
static llvm::Constant * buildCopyHelper(CodeGenModule &CGM, const CGBlockInfo &blockInfo)
Build the helper function to copy a block.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
ASTContext & getContext() const
Represents a prototype with parameter type info, e.g.
llvm::CallInst * EmitNounwindRuntimeCall(llvm::Value *callee, const Twine &name="")
uint32_t getBitMask() const
const CodeGen::CGBlockInfo * BlockInfo
const TargetCodeGenInfo & getTargetCodeGenInfo()
CGBlockInfo - Information to generate a block literal.
virtual void emitCopy(CodeGenFunction &CGF, Address dest, Address src)=0
RValue - This trivial value class is used to represent the result of an expression that is evaluated...
QualType fieldType() const
bool CanBeGlobal
CanBeGlobal - True if the block can be global, i.e.
SourceLocation getLocEnd() const LLVM_READONLY
StringRef getBlockMangledName(GlobalDecl GD, const BlockDecl *BD)
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static void initializeForBlockHeader(CodeGenModule &CGM, CGBlockInfo &info, SmallVectorImpl< llvm::Type *> &elementTypes)
CGBlockInfo * NextBlockInfo
The next block in the block-info chain.
CGObjCRuntime & getObjCRuntime()
Return a reference to the configured Objective-C runtime.
BlockDecl - This represents a block literal declaration, which is like an unnamed FunctionDecl...
Expr - This represents one expression.
void EmitARCMoveWeak(Address dst, Address src)
void @objc_moveWeak(i8** dest, i8** src) Disregards the current value in dest.
Emit only debug info necessary for generating line number tables (-gline-tables-only).
Enters a new scope for capturing cleanups, all of which will be executed once the scope is exited...
const FunctionProtoType * T
CharUnits getOffset() const
llvm::Constant * DisposeHelper
const T * castAs() const
Member-template castAs<specific type>.
void SetInternalFunctionAttributes(const Decl *D, llvm::Function *F, const CGFunctionInfo &FI)
Set the attributes on the LLVM function for the given decl and function info.
bool isObjCRetainableType() const
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
BlockCaptureEntityKind
Represents a type of copy/destroy operation that should be performed for an entity that's captured by...
static llvm::Constant * buildGlobalBlock(CodeGenModule &CGM, const CGBlockInfo &blockInfo, llvm::Constant *blockFn)
Build the given block as a global block.
llvm::Constant * GenerateDestroyHelperFunction(const CGBlockInfo &blockInfo)
Generate the destroy-helper function for a block closure object: static void block_destroy_helper(blo...
const Expr * getCallee() const
ObjCLifetime getObjCLifetime() const
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
internal::Matcher< T > id(StringRef ID, const internal::BindableMatcher< T > &InnerMatcher)
If the provided matcher matches a node, binds the node to ID.
void add(RValue rvalue, QualType type, bool needscopy=false)
bool ReturnSlotInterferesWithArgs(const CGFunctionInfo &FI)
Return true iff the given type uses an argument slot when 'sret' is used as a return type...
llvm::IntegerType * Int32Ty
static Capture makeIndex(unsigned index, CharUnits offset, QualType FieldType)
bool isa(CodeGen::Address addr)
bool isObjCInertUnsafeUnretainedType() const
Was this type written with the special inert-in-MRC __unsafe_unretained qualifier?
static CharUnits getLowBit(CharUnits v)
Get the low bit of a nonzero character count.
const Type * getBaseElementTypeUnsafe() const
Get the base element type of this type, potentially discarding type qualifiers.
const TargetInfo & getTarget() const
const LangOptions & getLangOpts() const
ASTContext & getContext() const
static AggValueSlot forAddr(Address addr, Qualifiers quals, IsDestructed_t isDestructed, NeedsGCBarriers_t needsGC, IsAliased_t isAliased, IsZeroed_t isZeroed=IsNotZeroed)
forAddr - Make a slot for an aggregate value.
static QualType getCaptureFieldType(const CodeGenFunction &CGF, const BlockDecl::Capture &CI)
GlobalDecl - represents a global declaration.
virtual bool needsCopy() const
virtual llvm::Constant * BuildByrefLayout(CodeGen::CodeGenModule &CGM, QualType T)=0
Returns an i8* which points to the byref layout information.
bool isConstQualified() const
Determine whether this type is const-qualified.
param_iterator param_begin()
The l-value was considered opaque, so the alignment was determined from a type.
RecordDecl * getDecl() const
void setBlockContextParameter(const ImplicitParamDecl *D, unsigned argNum, llvm::Value *ptr)
void PopCleanupBlocks(EHScopeStack::stable_iterator OldCleanupStackSize, std::initializer_list< llvm::Value **> ValuesToReload={})
Takes the old cleanup stack size and emits the cleanup blocks that have been added.
bool UsesStret
UsesStret : True if the block uses an stret return.
void enterByrefCleanup(const AutoVarEmission &emission)
Enter a cleanup to destroy a __block variable.
There is no lifetime qualification on this type.
Address CreateBitCast(Address Addr, llvm::Type *Ty, const llvm::Twine &Name="")
Assigning into this object requires the old value to be released and the new value to be retained...
Expr * getBlockVarCopyInits(const VarDecl *VD)
Get the copy initialization expression of the VarDecl VD, or nullptr if none exists.
void PushDestructorCleanup(QualType T, Address Addr)
PushDestructorCleanup - Push a cleanup to call the complete-object destructor of an object of the giv...
void pushDestroy(QualType::DestructionKind dtorKind, Address addr, QualType type)
pushDestroy - Push the standard destructor for the given type as at least a normal cleanup...
Encodes a location in the source.
static DeclContext * castToDeclContext(const TranslationUnitDecl *D)
QualType getReturnType() const
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
A saved depth on the scope stack.
llvm::StructType * StructureType
std::string getNameAsString() const
getNameAsString - Get a human-readable name for the declaration, even if it is one of the special kin...
static void configureBlocksRuntimeObject(CodeGenModule &CGM, llvm::Constant *C)
Adjust the declaration of something from the blocks API.
const BlockByrefInfo & getBlockByrefInfo(const VarDecl *var)
BuildByrefInfo - This routine changes a __block variable declared as T x into:
A scoped helper to set the current debug location to the specified location or preferred location of ...
bool isConversionFromLambda() const
llvm::DenseMap< const VarDecl *, Capture > Captures
The mapping of allocated indexes within the block.
bool isObjCObjectPointerType() const
static bool isBlockPointer(Expr *Arg)
llvm::Constant * getBlockObjectDispose()
void StartFunction(GlobalDecl GD, QualType RetTy, llvm::Function *Fn, const CGFunctionInfo &FnInfo, const FunctionArgList &Args, SourceLocation Loc=SourceLocation(), SourceLocation StartLoc=SourceLocation())
Emit code for the start of a function.
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
DestructionKind isDestructedType() const
Returns a nonzero value if objects of this type require non-trivial work to clean up after...
llvm::Value * getConstant() const
static Destroyer emitARCIntrinsicUse
const BlockExpr * getBlockExpr() const
All available information about a concrete callee.
virtual bool needsDispose() const
bool operator<(DeclarationName LHS, DeclarationName RHS)
Ordering on two declaration names.
VarDecl * getVariable() const
The variable being captured.
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.
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...
FunctionArgList - Type for representing both the decl and type of parameters to a function...
bool isObjCGCWeak() const
true when Type is objc's weak.
static llvm::Constant * tryCaptureAsConstant(CodeGenModule &CGM, CodeGenFunction *CGF, const VarDecl *var)
It is illegal to modify a const object after initialization.
CGFunctionInfo - Class to encapsulate the information about a function definition.
This class organizes the cross-function state that is used while generating LLVM code.
CharUnits alignmentAtOffset(CharUnits offset) const
Given that this is a non-zero alignment value, what is the alignment at the given offset...
Dataflow Directional Tag Classes.
virtual llvm::Constant * BuildGCBlockLayout(CodeGen::CodeGenModule &CGM, const CodeGen::CGBlockInfo &blockInfo)=0
Address LoadBlockStruct()
static void computeBlockInfo(CodeGenModule &CGM, CodeGenFunction *CGF, CGBlockInfo &info)
Compute the layout of the given block.
llvm::FoldingSet< BlockByrefHelpers > ByrefHelpersCache
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
ArrayRef< Capture > captures() const
bool isNested() const
Whether this is a nested capture, i.e.
Address CreateStructGEP(Address Addr, unsigned Index, CharUnits Offset, const llvm::Twine &Name="")
Parameter for Objective-C 'self' argument.
static llvm::Constant * buildDisposeHelper(CodeGenModule &CGM, const CGBlockInfo &blockInfo)
Build the helper function to dispose of a block.
const Expr * getInit() const
llvm::Constant * getPointer() const
std::unique_ptr< DiagnosticConsumer > create(StringRef OutputFile, DiagnosticOptions *Diags, bool MergeChildRecords=false)
Returns a DiagnosticConsumer that serializes diagnostics to a bitcode file.
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
int printf(__constant const char *st,...)
bool hasObjCLifetime() const
llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)
llvm::Module & getModule() const
llvm::DenseMap< const Decl *, Address > DeclMapTy
static void enterBlockScope(CodeGenFunction &CGF, BlockDecl *block)
Enter the scope of a block.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
StructBuilder beginStruct(llvm::StructType *structTy=nullptr)
CanQualType UnsignedLongTy
unsigned getNumObjects() const
static llvm::Constant * buildByrefCopyHelper(CodeGenModule &CGM, const BlockByrefInfo &byrefInfo, BlockByrefHelpers &generator)
Build the copy helper for a __block variable.
llvm::PointerType * Int8PtrTy
void EmitSynthesizedCXXCopyCtor(Address Dest, Address Src, const Expr *Exp)
static CGBlockInfo * findAndRemoveBlockInfo(CGBlockInfo **head, const BlockDecl *block)
Find the layout for the given block in a linked list and remove it.
virtual void emitDispose(CodeGenFunction &CGF, Address field)=0
Internal linkage, which indicates that the entity can be referred to from within the translation unit...
llvm::Constant * getBlockObjectAssign()
char __ovld __cnfn max(char x, char y)
Returns y if x < y, otherwise it returns x.
const Decl * CurFuncDecl
CurFuncDecl - Holds the Decl for the current outermost non-closure context.
A pair of helper functions for a __block variable.
bool capturesCXXThis() const
CharUnits getIntSize() const
Reading or writing from this object requires a barrier call.
TranslationUnitDecl * getTranslationUnitDecl() const
Represents a C++ struct/union/class.
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
void setAddrOfGlobalBlock(const BlockExpr *BE, llvm::Constant *Addr)
Notes that BE's global block is available via Addr.
virtual ~BlockByrefHelpers()
CharUnits BlockHeaderForcedGapSize
llvm::Value * EmitARCRetainBlock(llvm::Value *value, bool mandatory)
Retain the given block, with _Block_copy semantics.
uint64_t getPointerAlign(unsigned AddrSpace) const
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
StringRef getName() const
getName - Get the name of identifier for this declaration as a StringRef.
llvm::Function * GenerateBlockFunction(GlobalDecl GD, const CGBlockInfo &Info, const DeclMapTy &ldm, bool IsLambdaConversionToBlock, bool BuildGlobalBlock)
TranslationUnitDecl - 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)
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.
NamedDecl - This represents a decl with a name.
llvm::Instruction * DominatingIP
An instruction which dominates the full-expression that the block is inside.
unsigned long ulong
An unsigned 64-bit integer.
unsigned getTargetAddressSpace(QualType T) const
static bool isObjCNSObjectType(QualType Ty)
Return true if this is an NSObject object with its NSObject attribute set.
SourceLocation getLocStart() const LLVM_READONLY
CallArgList - Type for representing both the value and type of arguments in a call.
const LangOptions & getLangOpts() const
Address emitBlockByrefAddress(Address baseAddr, const VarDecl *V, bool followForward=true)
BuildBlockByrefAddress - Computes the location of the data in a variable which is declared as __block...
Abstract information about a function or function prototype.
SourceLocation getLocation() const
void BuildBlockRelease(llvm::Value *DeclPtr, BlockFieldFlags flags)
void setCleanup(EHScopeStack::stable_iterator cleanup)
static OMPLinearClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, OpenMPLinearClauseKind Modifier, SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL, ArrayRef< Expr *> PL, ArrayRef< Expr *> IL, Expr *Step, Expr *CalcStep, Stmt *PreInit, Expr *PostUpdate)
Creates clause with a list of variables VL and a linear step Step.
void Destroyer(CodeGenFunction &CGF, Address addr, QualType ty)
Qualifiers::ObjCLifetime getObjCLifetime() const
Returns lifetime attribute of this type.
llvm::FunctionType * GetFunctionType(const CGFunctionInfo &Info)
GetFunctionType - Get the LLVM function type for.