25#include "llvm/ADT/SmallSet.h"
26#include "llvm/IR/DataLayout.h"
27#include "llvm/IR/Module.h"
28#include "llvm/Support/ScopedPrinter.h"
33using namespace CodeGen;
36 : Name(name), CXXThisIndex(0), CanBeGlobal(
false), NeedsCopyDispose(
false),
38 HasCapturedVariableLayout(
false), CapturesNonExternalType(
false),
39 LocalAddress(
RawAddress::invalid()), StructureType(nullptr),
44 if (!name.empty() && name[0] ==
'\01')
45 name = name.substr(1);
54 llvm::Constant *blockFn);
70enum class CaptureStrKind {
82 CaptureStrKind StrKind,
88 std::string Name =
"__block_descriptor_";
99 if (Cap.isConstantOrTrivial())
102 Name += llvm::to_string(Cap.getOffset().getQuantity());
104 if (Cap.CopyKind == Cap.DisposeKind) {
108 "shouldn't see BlockCaptureManagedEntity that is None");
124 std::string TypeAtEncoding =
128 std::replace(TypeAtEncoding.begin(), TypeAtEncoding.end(),
'@',
'\1');
129 Name +=
"e" + llvm::to_string(TypeAtEncoding.size()) +
"_" + TypeAtEncoding;
152 llvm::IntegerType *
ulong =
154 llvm::PointerType *i8p =
nullptr;
156 i8p = llvm::PointerType::get(
161 std::string descName;
164 if (
C.getLangOpts().ObjC &&
167 if (llvm::GlobalValue *desc = CGM.
getModule().getNamedValue(descName))
177 elements.addInt(
ulong, 0);
186 bool hasInternalHelper =
false;
190 elements.add(copyHelper);
194 elements.add(disposeHelper);
196 if (cast<llvm::Function>(copyHelper->stripPointerCasts())
197 ->hasInternalLinkage() ||
198 cast<llvm::Function>(disposeHelper->stripPointerCasts())
199 ->hasInternalLinkage())
200 hasInternalHelper =
true;
204 std::string typeAtEncoding =
209 if (
C.getLangOpts().ObjC) {
216 elements.addNullPointer(i8p);
218 unsigned AddrSpace = 0;
219 if (
C.getLangOpts().OpenCL)
222 llvm::GlobalValue::LinkageTypes linkage;
223 if (descName.empty()) {
224 linkage = llvm::GlobalValue::InternalLinkage;
225 descName =
"__block_descriptor_tmp";
226 }
else if (hasInternalHelper) {
229 linkage = llvm::GlobalValue::InternalLinkage;
231 linkage = llvm::GlobalValue::LinkOnceODRLinkage;
234 llvm::GlobalVariable *global =
236 true, linkage, AddrSpace);
238 if (linkage == llvm::GlobalValue::LinkOnceODRLinkage) {
240 global->setComdat(CGM.
getModule().getOrInsertComdat(descName));
241 global->setVisibility(llvm::GlobalValue::HiddenVisibility);
242 global->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
261 struct objc_class *isa;
289 _ResultType (*invoke)(Block_literal *, _ParamTypes...);
292 struct Block_descriptor *block_descriptor;
295 _CapturesTypes captures...;
301 struct BlockLayoutChunk {
317 FieldType(fieldType), CopyKind(CopyKind), DisposeKind(DisposeKind),
318 CopyFlags(CopyFlags), DisposeFlags(DisposeFlags) {}
327 index, offset, FieldType, CopyKind, CopyFlags, DisposeKind,
333 return CopyKind == BlockCaptureEntityKind::None &&
334 DisposeKind == BlockCaptureEntityKind::None;
341 bool operator<(
const BlockLayoutChunk &left,
const BlockLayoutChunk &right) {
342 if (left.Alignment != right.Alignment)
343 return left.Alignment > right.Alignment;
345 auto getPrefOrder = [](
const BlockLayoutChunk &chunk) {
346 switch (chunk.CopyKind) {
350 switch (chunk.CopyFlags.getBitMask()) {
369 return getPrefOrder(left) < getPrefOrder(right);
373static std::pair<BlockCaptureEntityKind, BlockFieldFlags>
377static std::pair<BlockCaptureEntityKind, BlockFieldFlags>
388 Layout.push_back(BlockLayoutChunk(
398 std::tie(CopyKind, CopyFlags) =
400 std::tie(DisposeKind, DisposeFlags) =
402 Layout.push_back(BlockLayoutChunk(align, size, capture,
type, fieldType,
403 CopyKind, CopyFlags, DisposeKind,
409 if (!Layout.back().isTrivial())
421 const auto *record = cast<CXXRecordDecl>(
recordType->getDecl());
424 if (!record->hasTrivialDestructor())
return false;
425 if (record->hasNonTrivialCopyConstructor())
return false;
429 return !record->hasMutableFields();
443 if (isa<ParmVarDecl>(var))
449 if (!
type.isConstQualified())
return nullptr;
463 if (!init)
return nullptr;
477 assert(elementTypes.empty());
487 assert((2 * CGM.
getIntSize()).isMultipleOf(GenPtrAlign));
488 elementTypes.push_back(CGM.
IntTy);
489 elementTypes.push_back(CGM.
IntTy);
490 elementTypes.push_back(
495 unsigned BlockAlign = GenPtrAlign.getQuantity();
498 for (
auto *I : Helper->getCustomFieldTypes()) {
501 unsigned Align = CGM.
getDataLayout().getABITypeAlign(I).value();
502 if (BlockAlign < Align)
504 assert(Offset % Align == 0);
506 elementTypes.push_back(I);
520 elementTypes.push_back(CGM.
IntTy);
521 elementTypes.push_back(CGM.
IntTy);
536 return FD->getType();
553 bool hasNonConstantCustomFields =
false;
554 if (
auto *OpenCLHelper =
556 hasNonConstantCustomFields =
557 !OpenCLHelper->areAllCustomFieldValuesConstant(info);
558 if (!block->
hasCaptures() && !hasNonConstantCustomFields) {
564 else if (
C.getLangOpts().ObjC &&
581 "Can't capture 'this' outside a method");
588 maxFieldAlign = std::max(maxFieldAlign, TInfo.Align);
590 addBlockLayout(TInfo.Align, TInfo.Width,
nullptr, llvmType, thisType,
595 for (
const auto &CI : block->
captures()) {
596 const VarDecl *variable = CI.getVariable();
598 if (CI.isEscapingByref()) {
601 maxFieldAlign = std::max(maxFieldAlign, align);
606 "capture type differs from the variable type");
608 variable->
getType(), layout, info, CGM);
624 if (CI.hasCopyExpr() || !record->hasTrivialDestructor()) {
626 if (!record->isExternallyVisible())
633 maxFieldAlign = std::max(maxFieldAlign, align);
635 llvm::Type *llvmType =
638 addBlockLayout(align, size, &CI, llvmType, VT, layout, info, CGM);
642 if (layout.empty()) {
653 llvm::stable_sort(layout);
677 if (endAlign < maxFieldAlign) {
679 li = layout.begin() + 1, le = layout.end();
683 for (; li != le && endAlign < li->Alignment; ++li)
690 for (; li != le; ++li) {
691 assert(endAlign >= li->Alignment);
693 li->setIndex(info, elementTypes.size(), blockSize);
694 elementTypes.push_back(li->Type);
695 blockSize += li->Size;
699 if (endAlign >= maxFieldAlign) {
705 layout.erase(first, li);
709 assert(endAlign ==
getLowBit(blockSize));
713 if (endAlign < maxFieldAlign) {
715 CharUnits padding = newBlockSize - blockSize;
723 elementTypes.push_back(llvm::ArrayType::get(CGM.
Int8Ty,
725 blockSize = newBlockSize;
729 assert(endAlign >= maxFieldAlign);
730 assert(endAlign ==
getLowBit(blockSize));
735 li = layout.begin(), le = layout.end(); li != le; ++li) {
736 if (endAlign < li->Alignment) {
740 CharUnits padding = li->Alignment - endAlign;
741 elementTypes.push_back(llvm::ArrayType::get(CGM.
Int8Ty,
743 blockSize += padding;
746 assert(endAlign >= li->Alignment);
747 li->setIndex(info, elementTypes.size(), blockSize);
748 elementTypes.push_back(li->Type);
749 blockSize += li->Size;
762 if (!
blockExpr->getBlockDecl()->hasCaptures())
771 if (!blockInfo.CanBeGlobal)
773 blockInfo.BlockAlign,
"block");
788 auto *InvokeFn = BlockCGF.GenerateBlockFunction(
790 auto *blockFn = llvm::ConstantExpr::getPointerCast(InvokeFn, GenVoidPtrTy);
799 assert(blockAddr.
isValid() &&
"block has no address!");
802 llvm::Constant *descriptor;
808 llvm::Constant *blockISA = blockInfo.
NoEscape
830 auto projectField = [&](
unsigned index,
const Twine &
name) ->
Address {
833 auto storeField = [&](llvm::Value *value,
unsigned index,
const Twine &
name) {
842 auto addHeaderField = [&](llvm::Value *value,
CharUnits size,
844 storeField(value, index, name);
863 addHeaderField(blockFn, GenVoidPtrSize,
"block.invoke");
866 else if (
auto *Helper =
868 for (
auto I : Helper->getCustomFieldValues(*
this, blockInfo)) {
884 projectField(blockInfo.
CXXThisIndex,
"block.captured-this.addr");
889 for (
const auto &CI :
blockDecl->captures()) {
890 const VarDecl *variable = CI.getVariable();
900 Address blockField = projectField(capture.
getIndex(),
"block.captured");
906 if (
blockDecl->isConversionFromLambda()) {
910 }
else if (CI.isEscapingByref()) {
919 "block.capture.addr");
921 auto I = LocalDeclMap.find(variable);
922 assert(I != LocalDeclMap.end());
937 if (CI.isEscapingByref()) {
939 llvm::Value *byrefPointer;
949 }
else if (
const Expr *copyExpr = CI.getCopyExpr()) {
950 if (
blockDecl->isConversionFromLambda()) {
969 }
else if (
type.isConstQualified() &&
983 type->isBlockPointerType()) {
1036 if (
type.isConstQualified() &&
1040 "expected ObjC ARC to be enabled");
1050 if (useArrayEHCleanup)
1057 auto IsBlockDeclInRetExpr = [&]() {
1058 auto *EWC = llvm::dyn_cast_or_null<ExprWithCleanups>(
RetExpr);
1060 for (
auto &
C : EWC->getObjects())
1067 if (IsBlockDeclInRetExpr())
1068 pushDestroy(cleanupKind, blockField,
type, destroyer, useArrayEHCleanup);
1076 llvm::Value *result =
Builder.CreatePointerCast(
1089 if (BlockDescriptorType)
1090 return BlockDescriptorType;
1092 llvm::Type *UnsignedLongTy =
1109 BlockDescriptorType = llvm::StructType::create(
1110 "struct.__block_descriptor", UnsignedLongTy, UnsignedLongTy);
1113 unsigned AddrSpace = 0;
1116 BlockDescriptorType = llvm::PointerType::get(BlockDescriptorType, AddrSpace);
1117 return BlockDescriptorType;
1121 if (GenericBlockLiteralType)
1122 return GenericBlockLiteralType;
1136 llvm::append_range(StructFields, Helper->getCustomFieldTypes());
1138 GenericBlockLiteralType = llvm::StructType::create(
1139 StructFields,
"struct.__opencl_block_literal_generic");
1148 GenericBlockLiteralType =
1149 llvm::StructType::create(
"struct.__block_literal_generic",
VoidPtrTy,
1153 return GenericBlockLiteralType;
1161 llvm::Value *
Func =
nullptr;
1171 llvm::Type *GenericVoidPtrTy =
1173 llvm::Value *BlockDescriptor =
Builder.CreatePointerCast(
1174 BlockPtr, GenericVoidPtrTy);
1218 assert(
BlockInfo &&
"evaluating block ref without block information?");
1222 if (capture.
isConstant())
return LocalDeclMap.find(variable)->second;
1225 "block.capture.addr");
1233 byrefInfo.ByrefAlignment);
1241 "the capture field of a non-escaping variable should have a "
1250 llvm::Constant *Addr) {
1251 bool Ok = EmittedGlobalBlocks.insert(std::make_pair(BE, Addr)).second;
1253 assert(Ok &&
"Trying to replace an already-existing global block!");
1281 llvm::Constant *blockFn) {
1287 "Refusing to re-emit a global block.");
1310 fields.addInt(CGM.
IntTy, 0);
1317 fields.add(blockFn);
1322 }
else if (
auto *Helper =
1324 for (
auto *I : Helper->getCustomFieldValues(CGM, blockInfo)) {
1329 unsigned AddrSpace = 0;
1333 llvm::GlobalVariable *literal = fields.finishAndCreateGlobal(
1334 "__block_literal_global", blockInfo.
BlockAlign,
1335 !IsWindows, llvm::GlobalVariable::InternalLinkage, AddrSpace);
1337 literal->addAttribute(
"objc_arc_inert");
1342 auto *
Init = llvm::Function::Create(llvm::FunctionType::get(CGM.
VoidTy,
1343 {}), llvm::GlobalValue::InternalLinkage,
".block_isa_init",
1345 llvm::IRBuilder<>
b(llvm::BasicBlock::Create(CGM.
getLLVMContext(),
"entry",
1348 b.CreateStructGEP(literal->getValueType(), literal, 0),
1353 auto *InitVar =
new llvm::GlobalVariable(CGM.
getModule(),
Init->getType(),
1354 true, llvm::GlobalValue::InternalLinkage,
1355 Init,
".block_isa_init_ptr");
1356 InitVar->setSection(
".CRT$XCLa");
1361 llvm::Type *RequiredType =
1364 llvm::ConstantExpr::getPointerCast(literal, RequiredType);
1369 cast<llvm::Function>(blockFn->stripPointerCasts()),
Result,
1370 literal->getValueType());
1377 assert(
BlockInfo &&
"not emitting prologue of block invocation function?!");
1386 DI->EmitDeclareOfBlockLiteralArgVariable(
1399 llvm::PointerType::get(
1408 assert(
BlockInfo &&
"not in a block invocation function!");
1415 bool IsLambdaConversionToBlock,
bool BuildGlobalBlock) {
1427 for (DeclMapTy::const_iterator i = ldm.begin(), e = ldm.end(); i != e; ++i) {
1428 const auto *var = dyn_cast<VarDecl>(i->first);
1429 if (var && !var->hasLocalStorage())
1430 setAddrOfLocalVar(var, i->second);
1455 args.push_back(&SelfDecl);
1470 llvm::Function *fn = llvm::Function::Create(
1471 fnLLVMType, llvm::GlobalValue::InternalLinkage, name, &
CGM.
getModule());
1474 if (BuildGlobalBlock) {
1479 llvm::ConstantExpr::getPointerCast(fn, GenVoidPtrTy));
1513 for (
const auto &CI :
blockDecl->captures()) {
1514 const VarDecl *variable = CI.getVariable();
1524 setAddrOfLocalVar(variable, alloca);
1528 llvm::BasicBlock *entry =
Builder.GetInsertBlock();
1529 llvm::BasicBlock::iterator entry_ptr =
Builder.GetInsertPoint();
1532 if (IsLambdaConversionToBlock)
1541 llvm::BasicBlock *resume =
Builder.GetInsertBlock();
1544 if (entry_ptr->getNextNonDebugInstruction())
1545 entry_ptr = entry_ptr->getNextNonDebugInstruction()->getIterator();
1547 entry_ptr = entry->end();
1548 Builder.SetInsertPoint(entry, entry_ptr);
1553 for (
const auto &CI :
blockDecl->captures()) {
1554 const VarDecl *variable = CI.getVariable();
1560 auto addr = LocalDeclMap.find(variable)->second;
1561 (void)DI->EmitDeclareOfAutoVariable(
1566 DI->EmitDeclareOfBlockDeclRefVariable(
1567 variable, BlockPointerDbgLoc,
Builder, blockInfo,
1568 entry_ptr == entry->end() ? nullptr : &*entry_ptr);
1573 cast<CompoundStmt>(
blockDecl->getBody())->getRBracLoc());
1577 if (resume ==
nullptr)
1578 Builder.ClearInsertionPoint();
1580 Builder.SetInsertPoint(resume);
1587static std::pair<BlockCaptureEntityKind, BlockFieldFlags>
1598 if (
T.isObjCGCWeak())
1608 switch (
T.isNonTrivialToPrimitiveCopy()) {
1646 llvm_unreachable(
"after exhaustive PrimitiveCopyKind switch");
1658 : Addr(Addr), FieldFlags(Flags), LoadBlockVarAddr(LoadValue),
1662 llvm::Value *BlockVarAddr;
1663 if (LoadBlockVarAddr) {
1666 BlockVarAddr = Addr.emitRawPointer(CGF);
1684 CaptureStrKind StrKind,
1697 assert((StrKind != CaptureStrKind::Merged ||
1700 "different operations and flags");
1702 if (StrKind == CaptureStrKind::DisposeHelper) {
1714 llvm::raw_svector_ostream Out(TyStr);
1716 Str += llvm::to_string(TyStr.size()) + TyStr.c_str();
1735 if (StrKind != CaptureStrKind::DisposeHelper) {
1739 if (StrKind != CaptureStrKind::CopyHelper) {
1758 std::string FuncStr;
1759 if (StrKind == CaptureStrKind::DisposeHelper)
1761 CaptureTy, Alignment, IsVolatile, Ctx);
1766 CaptureTy, Alignment, IsVolatile, Ctx);
1769 Str += llvm::to_string(FuncStr.size()) +
"_" + FuncStr;
1782 assert((StrKind == CaptureStrKind::CopyHelper ||
1783 StrKind == CaptureStrKind::DisposeHelper) &&
1784 "unexpected CaptureStrKind");
1785 std::string Name = StrKind == CaptureStrKind::CopyHelper
1786 ?
"__copy_helper_block_"
1787 :
"__destroy_helper_block_";
1792 Name += llvm::to_string(BlockAlignment.
getQuantity()) +
"_";
1794 for (
auto &Cap : Captures) {
1795 if (Cap.isConstantOrTrivial())
1797 Name += llvm::to_string(Cap.getOffset().getQuantity());
1808 bool EHOnly = ForCopyHelper;
1810 switch (CaptureKind) {
1850 if (CapturesNonExternalType) {
1853 Fn->setVisibility(llvm::GlobalValue::HiddenVisibility);
1854 Fn->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
1871 CaptureStrKind::CopyHelper,
CGM);
1882 args.push_back(&DstDecl);
1884 args.push_back(&SrcDecl);
1893 llvm::Function *Fn =
1894 llvm::Function::Create(LTy, llvm::GlobalValue::LinkOnceODRLinkage,
1897 Fn->setComdat(
CGM.
getModule().getOrInsertComdat(FuncName));
1900 ArgTys.push_back(
C.VoidPtrTy);
1901 ArgTys.push_back(
C.VoidPtrTy);
1924 unsigned index = capture.
getIndex();
1931 assert(CI.
getCopyExpr() &&
"copy expression for variable is missing");
1951 auto *ty = cast<llvm::PointerType>(srcValue->getType());
1952 llvm::Value *null = llvm::ConstantPointerNull::get(ty);
1968 I->eraseFromParent();
1975 llvm::Value *args[] = {
2009static std::pair<BlockCaptureEntityKind, BlockFieldFlags>
2014 if (
T.isObjCGCWeak())
2019 switch (
T.isDestructedType()) {
2046 llvm_unreachable(
"after exhaustive DestructionKind switch");
2060 CaptureStrKind::DisposeHelper,
CGM);
2071 args.push_back(&SrcDecl);
2080 llvm::Function *Fn =
2081 llvm::Function::Create(LTy, llvm::GlobalValue::LinkOnceODRLinkage,
2084 Fn->setComdat(
CGM.
getModule().getOrInsertComdat(FuncName));
2087 ArgTys.push_back(
C.VoidPtrTy);
2100 CodeGenFunction::RunCleanupsScope cleanups(*
this);
2116 cleanups.ForceCleanup();
2142 llvm::Value *flagsVal = llvm::ConstantInt::get(CGF.
Int32Ty, flags);
2145 llvm::Value *args[] = {destField.
emitRawPointer(CGF), srcValue, flagsVal};
2156 void profileImpl(llvm::FoldingSetNodeID &
id)
const override {
2157 id.AddInteger(Flags.getBitMask());
2175 void profileImpl(llvm::FoldingSetNodeID &
id)
const override {
2195 llvm::ConstantPointerNull::get(cast<llvm::PointerType>(value->getType()));
2211 void profileImpl(llvm::FoldingSetNodeID &
id)
const override {
2221 ARCStrongBlockByrefHelpers(
CharUnits alignment)
2238 void profileImpl(llvm::FoldingSetNodeID &
id)
const override {
2248 const Expr *CopyExpr;
2252 const Expr *copyExpr)
2255 bool needsCopy()
const override {
return CopyExpr !=
nullptr; }
2258 if (!CopyExpr)
return;
2268 void profileImpl(llvm::FoldingSetNodeID &
id)
const override {
2269 id.AddPointer(VarType.getCanonicalType().getAsOpaquePtr());
2288 bool needsDispose()
const override {
2289 return VarType.isDestructedType();
2294 CGF.
pushDestroy(VarType.isDestructedType(), field, VarType);
2298 void profileImpl(llvm::FoldingSetNodeID &
id)
const override {
2299 id.AddPointer(VarType.getCanonicalType().getAsOpaquePtr());
2304static llvm::Constant *
2313 args.push_back(&Dst);
2316 args.push_back(&Src);
2325 llvm::Function *Fn =
2326 llvm::Function::Create(LTy, llvm::GlobalValue::InternalLinkage,
2354 generator.
emitCopy(CGF, destField, srcField);
2371static llvm::Constant *
2381 args.push_back(&Src);
2390 llvm::Function *Fn =
2391 llvm::Function::Create(LTy, llvm::GlobalValue::InternalLinkage,
2392 "__Block_byref_object_dispose_",
2431 llvm::FoldingSetNodeID id;
2432 generator.Profile(
id);
2437 if (node)
return static_cast<T*
>(node);
2442 T *copy =
new (CGM.
getContext())
T(std::forward<T>(generator));
2451CodeGenFunction::buildByrefHelpers(llvm::StructType &byrefType,
2452 const AutoVarEmission &emission) {
2453 const VarDecl &var = *emission.Variable;
2455 "only escaping __block variables need byref helpers");
2467 const Expr *copyExpr =
2469 if (!copyExpr && record->hasTrivialDestructor())
return nullptr;
2471 return ::buildByrefHelpers(
2472 CGM, byrefInfo, CXXByrefHelpers(valueAlignment,
type, copyExpr));
2479 return ::buildByrefHelpers(
2480 CGM, byrefInfo, NonTrivialCStructByrefHelpers(valueAlignment,
type));
2484 if (!
type->isObjCRetainableType())
return nullptr;
2501 return ::buildByrefHelpers(
CGM, byrefInfo,
2502 ARCWeakByrefHelpers(valueAlignment));
2508 if (
type->isBlockPointerType()) {
2509 return ::buildByrefHelpers(
CGM, byrefInfo,
2510 ARCStrongBlockByrefHelpers(valueAlignment));
2515 return ::buildByrefHelpers(
CGM, byrefInfo,
2516 ARCStrongByrefHelpers(valueAlignment));
2519 llvm_unreachable(
"fell out of lifetime switch!");
2523 if (
type->isBlockPointerType()) {
2526 type->isObjCObjectPointerType()) {
2532 if (
type.isObjCGCWeak())
2535 return ::buildByrefHelpers(
CGM, byrefInfo,
2536 ObjectByrefHelpers(valueAlignment, flags));
2541 bool followForward) {
2549 const llvm::Twine &name) {
2551 if (followForward) {
2576 auto it = BlockByrefInfos.find(D);
2577 if (it != BlockByrefInfos.end())
2580 llvm::StructType *byrefType =
2607 if (hasCopyAndDispose) {
2617 bool HasByrefExtendedLayout =
false;
2619 if (
getContext().getByrefLifetime(Ty, Lifetime, HasByrefExtendedLayout) &&
2620 HasByrefExtendedLayout) {
2629 bool packed =
false;
2634 if (varOffset != size) {
2635 llvm::Type *paddingTy =
2636 llvm::ArrayType::get(
Int8Ty, (varOffset - size).getQuantity());
2638 types.push_back(paddingTy);
2646 types.push_back(varTy);
2648 byrefType->setBody(
types, packed);
2651 info.
Type = byrefType;
2656 auto pair = BlockByrefInfos.insert({D, info});
2657 assert(pair.second &&
"info was inserted recursively?");
2658 return pair.first->second;
2668 llvm::StructType *byrefType = cast<llvm::StructType>(addr.
getElementType());
2670 unsigned nextHeaderIndex = 0;
2672 auto storeHeaderField = [&](llvm::Value *value,
CharUnits fieldSize,
2673 const Twine &
name) {
2678 nextHeaderOffset += fieldSize;
2684 const VarDecl &D = *emission.Variable;
2687 bool HasByrefExtendedLayout =
false;
2689 bool ByRefHasLifetime =
2696 if (
type.isObjCGCWeak())
2703 "byref.forwarding");
2710 if (ByRefHasLifetime) {
2712 else switch (ByrefLifetime) {
2723 if (!
type->isObjCObjectPointerType() && !
type->isBlockPointerType())
2730 printf(
"\n Inline flag for BYREF variable layout (%d):", flags.
getBitMask());
2732 printf(
" BLOCK_BYREF_HAS_COPY_DISPOSE");
2736 printf(
" BLOCK_BYREF_LAYOUT_EXTENDED");
2738 printf(
" BLOCK_BYREF_LAYOUT_STRONG");
2740 printf(
" BLOCK_BYREF_LAYOUT_WEAK");
2742 printf(
" BLOCK_BYREF_LAYOUT_UNRETAINED");
2744 printf(
" BLOCK_BYREF_LAYOUT_NON_OBJECT");
2758 "byref.copyHelper");
2760 "byref.disposeHelper");
2763 if (ByRefHasLifetime && HasByrefExtendedLayout) {
2772 llvm::Value *args[] = {
V,
2783 bool LoadBlockVarAddr,
bool CanThrow) {
2784 EHStack.pushCleanup<CallBlockRelease>(
Kind, Addr, Flags, LoadBlockVarAddr,
2790 llvm::Constant *
C) {
2791 auto *GV = cast<llvm::GlobalValue>(
C->stripPointerCasts());
2798 assert((isa<llvm::Function>(
C->stripPointerCasts()) ||
2799 isa<llvm::GlobalVariable>(
C->stripPointerCasts())) &&
2800 "expected Function or GlobalVariable");
2804 if ((ND = dyn_cast<FunctionDecl>(
Result)) ||
2805 (ND = dyn_cast<VarDecl>(
Result)))
2809 if (GV->isDeclaration() && (!ND || !ND->
hasAttr<DLLExportAttr>())) {
2810 GV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
2811 GV->setLinkage(llvm::GlobalValue::ExternalLinkage);
2813 GV->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
2814 GV->setLinkage(llvm::GlobalValue::ExternalLinkage);
2818 if (CGM.
getLangOpts().BlocksRuntimeOptional && GV->isDeclaration() &&
2819 GV->hasExternalLinkage())
2820 GV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage);
2826 if (BlockObjectDispose)
2827 return BlockObjectDispose;
2830 llvm::FunctionType *fty
2831 = llvm::FunctionType::get(
VoidTy, args,
false);
2834 *
this, cast<llvm::Constant>(BlockObjectDispose.getCallee()));
2835 return BlockObjectDispose;
2839 if (BlockObjectAssign)
2840 return BlockObjectAssign;
2843 llvm::FunctionType *fty
2844 = llvm::FunctionType::get(
VoidTy, args,
false);
2847 *
this, cast<llvm::Constant>(BlockObjectAssign.getCallee()));
2848 return BlockObjectAssign;
2852 if (NSConcreteGlobalBlock)
2853 return NSConcreteGlobalBlock;
2858 return NSConcreteGlobalBlock;
2862 if (NSConcreteStackBlock)
2863 return NSConcreteStackBlock;
2868 return NSConcreteStackBlock;
static bool CanThrow(Expr *E, ASTContext &Ctx)
static llvm::Constant * buildByrefDisposeHelper(CodeGenModule &CGM, const BlockByrefInfo &byrefInfo, BlockByrefHelpers &generator)
Build the dispose helper for a __block variable.
static llvm::Constant * buildBlockDescriptor(CodeGenModule &CGM, const CGBlockInfo &blockInfo)
buildBlockDescriptor - Build the block descriptor meta-data for a block.
static void addBlockLayout(CharUnits align, CharUnits size, const BlockDecl::Capture *capture, llvm::Type *type, QualType fieldType, SmallVectorImpl< BlockLayoutChunk > &Layout, CGBlockInfo &Info, CodeGenModule &CGM)
static llvm::Constant * generateByrefDisposeHelper(CodeGenFunction &CGF, const BlockByrefInfo &byrefInfo, BlockByrefHelpers &generator)
Generate code for a __block variable's dispose helper.
static QualType getCaptureFieldType(const CodeGenFunction &CGF, const BlockDecl::Capture &CI)
static std::string getCopyDestroyHelperFuncName(const SmallVectorImpl< CGBlockInfo::Capture > &Captures, CharUnits BlockAlignment, CaptureStrKind StrKind, CodeGenModule &CGM)
static std::string getBlockDescriptorName(const CGBlockInfo &BlockInfo, CodeGenModule &CGM)
static llvm::Constant * buildCopyHelper(CodeGenModule &CGM, const CGBlockInfo &blockInfo)
Build the helper function to copy a block.
static std::string getBlockCaptureStr(const CGBlockInfo::Capture &Cap, CaptureStrKind StrKind, CharUnits BlockAlignment, CodeGenModule &CGM)
static llvm::Constant * tryCaptureAsConstant(CodeGenModule &CGM, CodeGenFunction *CGF, const VarDecl *var)
It is illegal to modify a const object after initialization.
static llvm::Constant * generateByrefCopyHelper(CodeGenFunction &CGF, const BlockByrefInfo &byrefInfo, BlockByrefHelpers &generator)
static std::pair< BlockCaptureEntityKind, BlockFieldFlags > computeDestroyInfoForBlockCapture(const BlockDecl::Capture &CI, QualType T, const LangOptions &LangOpts)
static llvm::Constant * buildByrefCopyHelper(CodeGenModule &CGM, const BlockByrefInfo &byrefInfo, BlockByrefHelpers &generator)
Build the copy helper for a __block variable.
static BlockFieldFlags getBlockFieldFlagsForObjCObjectPointer(const BlockDecl::Capture &CI, QualType T)
static void computeBlockInfo(CodeGenModule &CGM, CodeGenFunction *CGF, CGBlockInfo &info)
Compute the layout of the given block.
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.
static llvm::Constant * buildGlobalBlock(CodeGenModule &CGM, const CGBlockInfo &blockInfo, llvm::Constant *blockFn)
Build the given block as a global block.
static llvm::Constant * buildDisposeHelper(CodeGenModule &CGM, const CGBlockInfo &blockInfo)
Build the helper function to dispose of a block.
static void configureBlocksRuntimeObject(CodeGenModule &CGM, llvm::Constant *C)
Adjust the declaration of something from the blocks API.
static bool isSafeForCXXConstantCapture(QualType type)
Determines if the given type is safe for constant capture in C++.
static void pushCaptureCleanup(BlockCaptureEntityKind CaptureKind, Address Field, QualType CaptureType, BlockFieldFlags Flags, bool ForCopyHelper, VarDecl *Var, CodeGenFunction &CGF)
static std::pair< BlockCaptureEntityKind, BlockFieldFlags > computeCopyInfoForBlockCapture(const BlockDecl::Capture &CI, QualType T, const LangOptions &LangOpts)
static void setBlockHelperAttributesVisibility(bool CapturesNonExternalType, llvm::Function *Fn, const CGFunctionInfo &FI, CodeGenModule &CGM)
static void initializeForBlockHeader(CodeGenModule &CGM, CGBlockInfo &info, SmallVectorImpl< llvm::Type * > &elementTypes)
static CharUnits getLowBit(CharUnits v)
Get the low bit of a nonzero character count.
static bool isTrivial(ASTContext &Ctx, const Expr *E)
Checks if the expression is constant or does not have non-trivial function calls.
static bool isBlockPointer(Expr *Arg)
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
bool getByrefLifetime(QualType Ty, Qualifiers::ObjCLifetime &Lifetime, bool &HasByrefExtendedLayout) const
Returns true, if given type has a known lifetime.
TranslationUnitDecl * getTranslationUnitDecl() const
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
QualType getLValueReferenceType(QualType T, bool SpelledAsLValue=true) const
Return the uniqued reference to the type for an lvalue reference to the specified type.
bool BlockRequiresCopying(QualType Ty, const VarDecl *D)
Returns true iff we need copy/dispose helpers for the given type.
const LangOptions & getLangOpts() const
BlockVarCopyInit getBlockVarCopyInit(const VarDecl *VD) const
Get the copy initialization expression of the VarDecl VD, or nullptr if none exists.
TypeInfoChars getTypeInfoInChars(const Type *T) const
CharUnits getDeclAlign(const Decl *D, bool ForAlignof=false) const
Return a conservative estimate of the alignment of the specified decl D.
static bool isObjCNSObjectType(QualType Ty)
Return true if this is an NSObject object with its NSObject attribute set.
std::string getObjCEncodingForBlock(const BlockExpr *blockExpr) const
Return the encoded type for this block declaration.
QualType getAddrSpaceQualType(QualType T, LangAS AddressSpace) const
Return the uniqued reference to the type for an address space qualified type with the specified type ...
unsigned getTargetAddressSpace(LangAS AS) const
A class which contains all the information about a particular captured value.
bool isNested() const
Whether this is a nested capture, i.e.
Expr * getCopyExpr() const
bool isByRef() const
Whether this is a "by ref" capture, i.e.
VarDecl * getVariable() const
The variable being captured.
bool isEscapingByref() const
Represents a block literal declaration, which is like an unnamed FunctionDecl.
capture_const_iterator capture_begin() const
capture_const_iterator capture_end() const
ArrayRef< Capture > captures() const
bool capturesCXXThis() const
bool doesNotEscape() const
bool hasCaptures() const
True if this block (or its nested blocks) captures anything of local storage from its enclosing scope...
bool isConversionFromLambda() const
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
const Stmt * getBody() const
SourceLocation getEndLoc() const LLVM_READONLY
const FunctionProtoType * getFunctionType() const
getFunctionType - Return the underlying function type for this block.
const BlockDecl * getBlockDecl() const
Represents a C++ destructor within a class.
Represents a C++ struct/union/class.
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
CharUnits - This is an opaque type for sizes expressed in character units.
CharUnits alignmentAtOffset(CharUnits offset) const
Given that this is a non-zero alignment value, what is the alignment at the given offset?
llvm::Align getAsAlign() const
getAsAlign - Returns Quantity as a valid llvm::Align, Beware llvm::Align assumes power of two 8-bit b...
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
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 ...
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
bool hasReducedDebugInfo() const
Check if type and variable info should be emitted.
Like RawAddress, an abstract representation of an aligned address, but the pointer contained in this ...
llvm::Value * getBasePointer() const
llvm::Value * emitRawPointer(CodeGenFunction &CGF) const
Return the pointer contained in this class after authenticating it and adding offset to it if necessa...
llvm::Type * getElementType() const
Return the type of the values stored in this address.
Address withElementType(llvm::Type *ElemTy) const
Return address with different element type, but same pointer and alignment.
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.
A scoped helper to set the current debug location to the specified location or preferred location of ...
static ApplyDebugLocation CreateArtificial(CodeGenFunction &CGF)
Apply TemporaryLocation if it is valid.
static ApplyDebugLocation CreateEmpty(CodeGenFunction &CGF)
Set the IRBuilder to not attach debug locations.
A pair of helper functions for a __block variable.
virtual ~BlockByrefHelpers()
virtual void emitCopy(CodeGenFunction &CGF, Address dest, Address src)=0
virtual bool needsCopy() const
llvm::Constant * CopyHelper
virtual void emitDispose(CodeGenFunction &CGF, Address field)=0
virtual bool needsDispose() const
llvm::Constant * DisposeHelper
Information about the layout of a __block variable.
uint32_t getBitMask() const
uint32_t getBitMask() const
const BlockDecl::Capture * Cap
BlockFieldFlags DisposeFlags
static Capture makeIndex(unsigned index, CharUnits offset, QualType FieldType, BlockCaptureEntityKind CopyKind, BlockFieldFlags CopyFlags, BlockCaptureEntityKind DisposeKind, BlockFieldFlags DisposeFlags, const BlockDecl::Capture *Cap)
BlockCaptureEntityKind CopyKind
bool isConstantOrTrivial() const
QualType fieldType() const
BlockFieldFlags CopyFlags
BlockCaptureEntityKind DisposeKind
llvm::Value * getConstant() const
unsigned getIndex() const
static Capture makeConstant(llvm::Value *value, const BlockDecl::Capture *Cap)
CharUnits getOffset() const
CGBlockInfo - Information to generate a block literal.
CGBlockInfo(const BlockDecl *blockDecl, StringRef Name)
unsigned CXXThisIndex
The field index of 'this' within the block, if there is one.
const BlockDecl * getBlockDecl() const
llvm::StructType * StructureType
CharUnits BlockHeaderForcedGapOffset
bool UsesStret
UsesStret : True if the block uses an stret return.
const BlockExpr * BlockExpression
const BlockExpr * getBlockExpr() const
bool HasCapturedVariableLayout
HasCapturedVariableLayout : True if block has captured variables and their layout meta-data has been ...
bool CapturesNonExternalType
Indicates whether an object of a non-external C++ class is captured.
bool NeedsCopyDispose
True if the block has captures that would necessitate custom copy or dispose helper functions if the ...
bool CanBeGlobal
CanBeGlobal - True if the block can be global, i.e.
bool HasCXXObject
HasCXXObject - True if the block's custom copy/dispose functions need to be run even in GC mode.
CharUnits BlockHeaderForcedGapSize
const Capture & getCapture(const VarDecl *var) const
llvm::SmallVector< Capture, 4 > SortedCaptures
The block's captures. Non-constant captures are sorted by their offsets.
bool NoEscape
Indicates whether the block is non-escaping.
llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)
Address CreateStructGEP(Address Addr, unsigned Index, const llvm::Twine &Name="")
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
llvm::LoadInst * CreateAlignedLoad(llvm::Type *Ty, llvm::Value *Addr, CharUnits Align, const llvm::Twine &Name="")
MangleContext & getMangleContext()
Gets the mangle context.
Abstract information about a function or function prototype.
All available information about a concrete callee.
This class gathers all debug information during compilation and is responsible for emitting to llvm g...
CGFunctionInfo - Class to encapsulate the information about a function definition.
virtual llvm::Constant * BuildByrefLayout(CodeGen::CodeGenModule &CGM, QualType T)=0
Returns an i8* which points to the byref layout information.
virtual std::string getRCBlockLayoutStr(CodeGen::CodeGenModule &CGM, const CGBlockInfo &blockInfo)
virtual llvm::Constant * BuildGCBlockLayout(CodeGen::CodeGenModule &CGM, const CodeGen::CGBlockInfo &blockInfo)=0
virtual llvm::Constant * BuildRCBlockLayout(CodeGen::CodeGenModule &CGM, const CodeGen::CGBlockInfo &blockInfo)=0
llvm::Function * getInvokeFunction(const Expr *E)
void recordBlockInfo(const BlockExpr *E, llvm::Function *InvokeF, llvm::Value *Block, llvm::Type *BlockTy)
Record invoke function and block literal emitted during normal codegen for a block expression.
llvm::PointerType * getGenericVoidPointerType()
CallArgList - Type for representing both the value and type of arguments in a call.
void add(RValue rvalue, QualType type)
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
void EmitARCDestroyWeak(Address addr)
void FinishFunction(SourceLocation EndLoc=SourceLocation())
FinishFunction - Complete IR generation of the current function.
void enterByrefCleanup(CleanupKind Kind, Address Addr, BlockFieldFlags Flags, bool LoadBlockVarAddr, bool CanThrow)
Enter a cleanup to destroy a __block variable.
GlobalDecl CurGD
CurGD - The GlobalDecl for the current function being compiled.
static bool cxxDestructorCanThrow(QualType T)
Check if T is a C++ class that has a destructor that can throw.
SanitizerSet SanOpts
Sanitizers enabled for this function.
void EmitARCMoveWeak(Address dst, Address src)
void pushLifetimeExtendedDestroy(CleanupKind kind, Address addr, QualType type, Destroyer *destroyer, bool useEHCleanupForArray)
RValue EmitBlockCallExpr(const CallExpr *E, ReturnValueSlot ReturnValue)
const BlockByrefInfo & getBlockByrefInfo(const VarDecl *var)
void EmitCallArgs(CallArgList &Args, PrototypeWrapper Prototype, llvm::iterator_range< CallExpr::const_arg_iterator > ArgRange, AbstractCallee AC=AbstractCallee(), unsigned ParamsToSkip=0, EvaluationOrder Order=EvaluationOrder::Default)
void EmitSynthesizedCXXCopyCtor(Address Dest, Address Src, const Expr *Exp)
void callCStructMoveConstructor(LValue Dst, LValue Src)
void callCStructCopyConstructor(LValue Dst, LValue Src)
const LangOptions & getLangOpts() 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...
const CodeGen::CGBlockInfo * BlockInfo
Address EmitLoadOfReference(LValue RefLVal, LValueBaseInfo *PointeeBaseInfo=nullptr, TBAAAccessInfo *PointeeTBAAInfo=nullptr)
void EmitExprAsInit(const Expr *init, const ValueDecl *D, LValue lvalue, bool capturedByInit)
EmitExprAsInit - Emits the code necessary to initialize a location in memory with the given initializ...
void emitByrefStructureInit(const AutoVarEmission &emission)
llvm::Value * EmitARCStoreStrongCall(Address addr, llvm::Value *value, bool resultIgnored)
RValue EmitCall(const CGFunctionInfo &CallInfo, const CGCallee &Callee, ReturnValueSlot ReturnValue, const CallArgList &Args, llvm::CallBase **callOrInvoke, bool IsMustTail, SourceLocation Loc)
EmitCall - Generate a call of the given function, expecting the given result type,...
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.
llvm::Type * ConvertTypeForMem(QualType T)
llvm::Value * EmitARCRetainBlock(llvm::Value *value, bool mandatory)
RawAddress CreateMemTemp(QualType T, const Twine &Name="tmp", RawAddress *Alloca=nullptr)
CreateMemTemp - Create a temporary memory object of the given type, with appropriate alignmen and cas...
void EmitLambdaBlockInvokeBody()
Destroyer * getDestroyer(QualType::DestructionKind destructionKind)
static std::string getNonTrivialDestructorStr(QualType QT, CharUnits Alignment, bool IsVolatile, ASTContext &Ctx)
llvm::DenseMap< const Decl *, Address > DeclMapTy
llvm::Constant * GenerateDestroyHelperFunction(const CGBlockInfo &blockInfo)
const Expr * RetExpr
If a return statement is being visited, this holds the return statment's result expression.
void EmitARCCopyWeak(Address dst, Address src)
void PushDestructorCleanup(QualType T, Address Addr)
PushDestructorCleanup - Push a cleanup to call the complete-object destructor of an object of the giv...
llvm::Value * BlockPointer
void setBlockContextParameter(const ImplicitParamDecl *D, unsigned argNum, llvm::Value *ptr)
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 markAsIgnoreThreadCheckingAtRuntime(llvm::Function *Fn)
Annotate the function with an attribute that disables TSan checking at runtime.
CGDebugInfo * getDebugInfo()
Address LoadBlockStruct()
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...
LValue EmitDeclRefLValue(const DeclRefExpr *E)
llvm::Constant * GenerateCopyHelperFunction(const CGBlockInfo &blockInfo)
void EmitAggExpr(const Expr *E, AggValueSlot AS)
EmitAggExpr - Emit the computation of the specified expression of aggregate type.
llvm::Function * GenerateBlockFunction(GlobalDecl GD, const CGBlockInfo &Info, const DeclMapTy &ldm, bool IsLambdaConversionToBlock, bool BuildGlobalBlock)
llvm::CallInst * EmitNounwindRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
ASTContext & getContext() const
llvm::Value * EmitBlockLiteral(const BlockExpr *)
Emit block literal.
void Destroyer(CodeGenFunction &CGF, Address addr, QualType ty)
const Decl * CurFuncDecl
CurFuncDecl - Holds the Decl for the current outermost non-closure context.
void pushDestroy(QualType::DestructionKind dtorKind, Address addr, QualType type)
bool needsEHCleanup(QualType::DestructionKind kind)
Determines whether an EH cleanup is required to destroy a type with the given destruction kind.
llvm::DenseMap< const ValueDecl *, FieldDecl * > LambdaCaptureFields
CleanupKind getCleanupKind(QualType::DestructionKind kind)
llvm::Type * ConvertType(QualType T)
Address GetAddrOfBlockDecl(const VarDecl *var)
llvm::CallBase * EmitRuntimeCallOrInvoke(llvm::FunctionCallee callee, ArrayRef< llvm::Value * > args, const Twine &name="")
llvm::Value * EmitARCRetainNonBlock(llvm::Value *value)
LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource Source=AlignmentSource::Type)
llvm::Value * LoadCXXThis()
LoadCXXThis - Load the value of 'this'.
Address GetAddrOfLocalVar(const VarDecl *VD)
GetAddrOfLocalVar - Return the address of a local variable.
Address ReturnValue
ReturnValue - The temporary alloca to hold the return value.
static Destroyer destroyARCStrongImprecise
void EmitStmt(const Stmt *S, ArrayRef< const Attr * > Attrs=std::nullopt)
EmitStmt - Emit the code for the statement.
llvm::LLVMContext & getLLVMContext()
llvm::Value * EmitScalarExpr(const Expr *E, bool IgnoreResultAssign=false)
EmitScalarExpr - Emit the computation of the specified expression of LLVM scalar type,...
void incrementProfileCounter(const Stmt *S, llvm::Value *StepV=nullptr)
Increment the profiler's counter for the given statement by StepV.
static std::string getNonTrivialCopyConstructorStr(QualType QT, CharUnits Alignment, bool IsVolatile, ASTContext &Ctx)
static Destroyer emitARCIntrinsicUse
void BuildBlockRelease(llvm::Value *DeclPtr, BlockFieldFlags flags, bool CanThrow)
void EmitARCDestroyStrong(Address addr, ARCPreciseLifetime_t precise)
This class organizes the cross-function state that is used while generating LLVM code.
StringRef getBlockMangledName(GlobalDecl GD, const BlockDecl *BD)
llvm::FunctionCallee getBlockObjectAssign()
llvm::FoldingSet< BlockByrefHelpers > ByrefHelpersCache
void SetInternalFunctionAttributes(GlobalDecl GD, llvm::Function *F, const CGFunctionInfo &FI)
Set the attributes on the LLVM function for the given decl and function info.
void setDSOLocal(llvm::GlobalValue *GV) const
llvm::Module & getModule() const
llvm::FunctionCallee CreateRuntimeFunction(llvm::FunctionType *Ty, StringRef Name, llvm::AttributeList ExtraAttrs=llvm::AttributeList(), bool Local=false, bool AssumeConvergent=false)
Create or return a runtime function declaration with the specified type and name.
CharUnits GetTargetTypeStoreSize(llvm::Type *Ty) const
Return the store size, in character units, of the given LLVM type.
void setAddrOfGlobalBlock(const BlockExpr *BE, llvm::Constant *Addr)
Notes that BE's global block is available via Addr.
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.
const LangOptions & getLangOpts() const
CodeGenTypes & getTypes()
CGOpenCLRuntime & getOpenCLRuntime()
Return a reference to the configured OpenCL runtime.
const TargetInfo & getTarget() const
void addUsedGlobal(llvm::GlobalValue *GV)
Add a global to a list to be added to the llvm.used metadata.
const llvm::DataLayout & getDataLayout() const
llvm::Constant * getNSConcreteGlobalBlock()
CGCXXABI & getCXXABI() const
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...
bool ReturnSlotInterferesWithArgs(const CGFunctionInfo &FI)
Return true iff the given type uses an argument slot when 'sret' is used as a return type.
llvm::Constant * GetOrCreateLLVMGlobal(StringRef MangledName, llvm::Type *Ty, LangAS AddrSpace, const VarDecl *D, ForDefinition_t IsForDefinition=NotForDefinition)
GetOrCreateLLVMGlobal - If the specified mangled name is not in the module, create and return an llvm...
ASTContext & getContext() const
llvm::Constant * getNSConcreteStackBlock()
bool supportsCOMDAT() const
const TargetCodeGenInfo & getTargetCodeGenInfo()
const CodeGenOptions & getCodeGenOpts() const
llvm::FunctionCallee getBlockObjectDispose()
llvm::LLVMContext & getLLVMContext()
CGObjCRuntime & getObjCRuntime()
Return a reference to the configured Objective-C runtime.
void SetLLVMFunctionAttributes(GlobalDecl GD, const CGFunctionInfo &Info, llvm::Function *F, bool IsThunk)
Set the LLVM function attributes (sext, zext, etc).
llvm::Type * getGenericBlockLiteralType()
The type of a generic block literal.
void SetLLVMFunctionAttributesForDefinition(const Decl *D, llvm::Function *F)
Set the LLVM function attributes which only apply to a function definition.
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 assignRegionCounters(GlobalDecl GD, llvm::Function *Fn)
Assign counters to regions and configure them for PGO of a given function.
llvm::Type * ConvertType(QualType T)
ConvertType - Convert type T into a llvm::Type.
llvm::FunctionType * GetFunctionType(const CGFunctionInfo &Info)
GetFunctionType - Get the LLVM function type for.
const CGFunctionInfo & arrangeBlockFunctionCall(const CallArgList &args, const FunctionType *type)
A block function is essentially a free function with an extra implicit argument.
const CGFunctionInfo & arrangeBuiltinFunctionDeclaration(QualType resultType, const FunctionArgList &args)
A builtin function is a freestanding function using the default C conventions.
const CGFunctionInfo & arrangeBlockFunctionDeclaration(const FunctionProtoType *type, const FunctionArgList &args)
Block invocation functions are C functions with an implicit parameter.
llvm::Type * ConvertTypeForMem(QualType T, bool ForBitField=false)
ConvertTypeForMem - Convert type T into a llvm::Type.
llvm::Constant * getPointer() const
llvm::Constant * tryEmitAbstractForInitializer(const VarDecl &D)
Try to emit the initializer of the given declaration as an abstract constant.
StructBuilder beginStruct(llvm::StructType *structTy=nullptr)
The standard implementation of ConstantInitBuilder used in Clang.
Information for lazily generating a cleanup.
A saved depth on the scope stack.
stable_iterator stable_begin() const
Create a stable reference to the top of the EH stack.
FunctionArgList - Type for representing both the decl and type of parameters to a function.
Address getAddress(CodeGenFunction &CGF) const
RValue - This trivial value class is used to represent the result of an expression that is evaluated.
static RValue get(llvm::Value *V)
An abstract representation of an aligned address.
llvm::Value * getPointer() const
ReturnValueSlot - Contains the address where the return value of a function can be stored,...
virtual TargetOpenCLBlockHelper * getTargetOpenCLBlockHelper() const
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
lookup_result lookup(DeclarationName Name) const
lookup - Find the declarations (if any) with the given Name in this context.
A reference to a declared variable, function, enum, etc.
SourceLocation getLocation() const
This represents one expression.
Represents difference between two FPOptions values.
Represents a prototype with parameter type info, e.g.
FunctionType - C99 6.7.5.3 - Function Declarators.
QualType getReturnType() const
GlobalDecl - represents a global declaration.
One of these records is kept for each identifier that is lexed.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
virtual void mangleCanonicalTypeName(QualType T, raw_ostream &, bool NormalizeIntegers=false)=0
Generates a unique string for an externally visible type for use with TBAA or type uniquing.
This represents a decl that may have a name.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
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...
A (possibly-)qualified type.
bool isVolatileQualified() const
Determine whether this type is volatile-qualified.
@ DK_objc_strong_lifetime
DestructionKind isDestructedType() const
Returns a nonzero value if objects of this type require non-trivial work to clean up after.
@ PCK_Struct
The type is a struct containing a field whose type is neither PCK_Trivial nor PCK_VolatileTrivial.
@ PCK_Trivial
The type does not fall into any of the following categories.
@ PCK_ARCStrong
The type is an Objective-C retainable pointer type that is qualified with the ARC __strong qualifier.
@ PCK_VolatileTrivial
The type would be trivial except that it is volatile-qualified.
@ PCK_ARCWeak
The type is an Objective-C retainable pointer type that is qualified with the ARC __weak qualifier.
The collection of all-type qualifiers we support.
@ OCL_Strong
Assigning into this object requires the old value to be released and the new value to be retained.
@ OCL_ExplicitNone
This object can be modified without requiring retains or releases.
@ OCL_None
There is no lifetime qualification on this type.
@ OCL_Weak
Reading or writing from this object requires a barrier call.
@ OCL_Autoreleasing
Assigning into this object requires a lifetime extension.
ObjCLifetime getObjCLifetime() const
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
Base for LValueReferenceType and RValueReferenceType.
Scope - A scope is a transient data structure that is used while parsing the program.
Encodes a location in the source.
SourceLocation getBeginLoc() const LLVM_READONLY
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
uint64_t getPointerWidth(LangAS AddrSpace) const
Return the width of pointers on this target, for the specified address space.
uint64_t getPointerAlign(LangAS AddrSpace) const
The top declaration context.
static DeclContext * castToDeclContext(const TranslationUnitDecl *D)
The base class of the type hierarchy.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool isBlockPointerType() const
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isObjCInertUnsafeUnretainedType() const
Was this type written with the special inert-in-ARC __unsafe_unretained qualifier?
const T * getAs() const
Member-template getAs<specific type>'.
bool isObjCRetainableType() const
Represents a variable declaration or definition.
const Expr * getInit() const
bool isNonEscapingByref() const
Indicates the capture is a __block variable that is never captured by an escaping block.
bool isEscapingByref() const
Indicates the capture is a __block variable that is captured by a block that can potentially escape (...
@ BLOCK_HAS_EXTENDED_LAYOUT
@ BLOCK_BYREF_LAYOUT_MASK
@ BLOCK_BYREF_LAYOUT_WEAK
@ BLOCK_BYREF_LAYOUT_STRONG
@ BLOCK_BYREF_LAYOUT_EXTENDED
@ BLOCK_BYREF_LAYOUT_NON_OBJECT
@ BLOCK_BYREF_HAS_COPY_DISPOSE
@ BLOCK_BYREF_LAYOUT_UNRETAINED
@ Decl
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
BlockCaptureEntityKind
Represents a type of copy/destroy operation that should be performed for an entity that's captured by...
@ NormalCleanup
Denotes a cleanup that should run when a scope is exited using normal control flow (falling off the e...
@ EHCleanup
Denotes a cleanup that should run when a scope is exited using exceptional control flow (a throw stat...
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const internal::VariadicDynCastAllOfMatcher< Stmt, BlockExpr > blockExpr
Matches a reference to a block.
const AstTypeMatcher< RecordType > recordType
Matches record types (e.g.
const internal::VariadicDynCastAllOfMatcher< Decl, BlockDecl > blockDecl
Matches block declarations.
constexpr size_t align(size_t Size)
Aligns a size to the pointer alignment.
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
bool operator<(DeclarationName LHS, DeclarationName RHS)
Ordering on two declaration names.
@ Result
The result type of a method or function.
LangAS
Defines the address space values used by the address space qualifier of QualType.
@ VK_PRValue
A pr-value expression (in the C++11 taxonomy) produces a temporary value.
@ VK_LValue
An l-value expression is a reference to an object with independent storage.
const FunctionProtoType * T
@ Other
Other implicit parameter.
@ ObjCSelf
Parameter for Objective-C 'self' argument.
int printf(__constant const char *st,...) __attribute__((format(printf
unsigned long ulong
An unsigned 64-bit integer.
Expr * getCopyExpr() const
llvm::PointerType * VoidPtrTy
llvm::PointerType * Int8PtrPtrTy
CharUnits getIntAlign() const
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64
CharUnits getPointerSize() const
unsigned char PointerSizeInBytes
CharUnits getIntSize() const
llvm::IntegerType * Int32Ty
llvm::IntegerType * IntTy
int
llvm::PointerType * Int8PtrTy
llvm::PointerType * UnqualPtrTy
CharUnits getPointerAlign() const