25#include "llvm/IR/DataLayout.h"
26#include "llvm/IR/Module.h"
27#include "llvm/Support/ScopedPrinter.h"
32using namespace CodeGen;
35 : Name(name), CXXThisIndex(0), CanBeGlobal(
false), NeedsCopyDispose(
false),
37 HasCapturedVariableLayout(
false), CapturesNonExternalType(
false),
38 LocalAddress(
RawAddress::invalid()), StructureType(nullptr),
43 if (!name.empty() && name[0] ==
'\01')
44 name = name.substr(1);
53 llvm::Constant *blockFn);
69enum class CaptureStrKind {
81 CaptureStrKind StrKind,
87 std::string Name =
"__block_descriptor_";
98 if (Cap.isConstantOrTrivial())
101 Name += llvm::to_string(Cap.getOffset().getQuantity());
103 if (Cap.CopyKind == Cap.DisposeKind) {
107 "shouldn't see BlockCaptureManagedEntity that is None");
123 std::string TypeAtEncoding;
130 std::replace(TypeAtEncoding.begin(), TypeAtEncoding.end(),
'@',
'\1');
132 Name +=
"e" + llvm::to_string(TypeAtEncoding.size()) +
"_" + TypeAtEncoding;
155 llvm::IntegerType *
ulong =
157 llvm::PointerType *i8p =
nullptr;
159 i8p = llvm::PointerType::get(
164 std::string descName;
167 if (
C.getLangOpts().ObjC &&
170 if (llvm::GlobalValue *desc = CGM.
getModule().getNamedValue(descName))
180 elements.addInt(
ulong, 0);
189 bool hasInternalHelper =
false;
193 elements.add(copyHelper);
197 elements.add(disposeHelper);
199 if (cast<llvm::Function>(copyHelper->stripPointerCasts())
200 ->hasInternalLinkage() ||
201 cast<llvm::Function>(disposeHelper->stripPointerCasts())
202 ->hasInternalLinkage())
203 hasInternalHelper =
true;
208 elements.addNullPointer(i8p);
210 std::string typeAtEncoding =
216 if (
C.getLangOpts().ObjC) {
223 elements.addNullPointer(i8p);
225 unsigned AddrSpace = 0;
226 if (
C.getLangOpts().OpenCL)
229 llvm::GlobalValue::LinkageTypes linkage;
230 if (descName.empty()) {
231 linkage = llvm::GlobalValue::InternalLinkage;
232 descName =
"__block_descriptor_tmp";
233 }
else if (hasInternalHelper) {
236 linkage = llvm::GlobalValue::InternalLinkage;
238 linkage = llvm::GlobalValue::LinkOnceODRLinkage;
241 llvm::GlobalVariable *global =
243 true, linkage, AddrSpace);
245 if (linkage == llvm::GlobalValue::LinkOnceODRLinkage) {
247 global->setComdat(CGM.
getModule().getOrInsertComdat(descName));
248 global->setVisibility(llvm::GlobalValue::HiddenVisibility);
249 global->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
268 struct objc_class *isa;
296 _ResultType (*invoke)(Block_literal *, _ParamTypes...);
299 struct Block_descriptor *block_descriptor;
302 _CapturesTypes captures...;
308 struct BlockLayoutChunk {
324 FieldType(fieldType), CopyKind(CopyKind), DisposeKind(DisposeKind),
325 CopyFlags(CopyFlags), DisposeFlags(DisposeFlags) {}
334 index, offset, FieldType, CopyKind, CopyFlags, DisposeKind,
340 return CopyKind == BlockCaptureEntityKind::None &&
341 DisposeKind == BlockCaptureEntityKind::None;
348 bool operator<(
const BlockLayoutChunk &left,
const BlockLayoutChunk &right) {
349 if (left.Alignment != right.Alignment)
350 return left.Alignment > right.Alignment;
352 auto getPrefOrder = [](
const BlockLayoutChunk &chunk) {
353 switch (chunk.CopyKind) {
357 switch (chunk.CopyFlags.getBitMask()) {
376 return getPrefOrder(left) < getPrefOrder(right);
380static std::pair<BlockCaptureEntityKind, BlockFieldFlags>
384static std::pair<BlockCaptureEntityKind, BlockFieldFlags>
395 Layout.push_back(BlockLayoutChunk(
405 std::tie(CopyKind, CopyFlags) =
407 std::tie(DisposeKind, DisposeFlags) =
409 Layout.push_back(BlockLayoutChunk(align, size, capture,
type, fieldType,
410 CopyKind, CopyFlags, DisposeKind,
416 if (!Layout.back().isTrivial())
428 const auto *record = cast<CXXRecordDecl>(
recordType->getDecl());
431 if (!record->hasTrivialDestructor())
return false;
432 if (record->hasNonTrivialCopyConstructor())
return false;
436 return !record->hasMutableFields();
450 if (isa<ParmVarDecl>(var))
456 if (!
type.isConstQualified())
return nullptr;
469 const Expr *init = var->getInit();
470 if (!init)
return nullptr;
484 assert(elementTypes.empty());
494 assert((2 * CGM.
getIntSize()).isMultipleOf(GenPtrAlign));
495 elementTypes.push_back(CGM.
IntTy);
496 elementTypes.push_back(CGM.
IntTy);
497 elementTypes.push_back(
502 unsigned BlockAlign = GenPtrAlign.getQuantity();
505 for (
auto *I : Helper->getCustomFieldTypes()) {
508 unsigned Align = CGM.
getDataLayout().getABITypeAlign(I).value();
509 if (BlockAlign < Align)
511 assert(Offset % Align == 0);
513 elementTypes.push_back(I);
527 elementTypes.push_back(CGM.
IntTy);
528 elementTypes.push_back(CGM.
IntTy);
543 return FD->getType();
560 bool hasNonConstantCustomFields =
false;
561 if (
auto *OpenCLHelper =
563 hasNonConstantCustomFields =
564 !OpenCLHelper->areAllCustomFieldValuesConstant(info);
565 if (!block->
hasCaptures() && !hasNonConstantCustomFields) {
571 else if (
C.getLangOpts().ObjC &&
587 assert(CGF && isa_and_nonnull<CXXMethodDecl>(CGF->
CurFuncDecl) &&
588 "Can't capture 'this' outside a method");
595 maxFieldAlign = std::max(maxFieldAlign, TInfo.Align);
597 addBlockLayout(TInfo.Align, TInfo.Width,
nullptr, llvmType, thisType,
602 for (
const auto &CI : block->
captures()) {
603 const VarDecl *variable = CI.getVariable();
605 if (CI.isEscapingByref()) {
608 maxFieldAlign = std::max(maxFieldAlign, align);
613 "capture type differs from the variable type");
615 variable->
getType(), layout, info, CGM);
631 if (CI.hasCopyExpr() || !record->hasTrivialDestructor()) {
633 if (!record->isExternallyVisible())
640 maxFieldAlign = std::max(maxFieldAlign, align);
642 llvm::Type *llvmType =
645 addBlockLayout(align, size, &CI, llvmType, VT, layout, info, CGM);
649 if (layout.empty()) {
660 llvm::stable_sort(layout);
684 if (endAlign < maxFieldAlign) {
686 li = layout.begin() + 1, le = layout.end();
690 for (; li != le && endAlign < li->Alignment; ++li)
697 for (; li != le; ++li) {
698 assert(endAlign >= li->Alignment);
700 li->setIndex(info, elementTypes.size(), blockSize);
701 elementTypes.push_back(li->Type);
702 blockSize += li->Size;
706 if (endAlign >= maxFieldAlign) {
712 layout.erase(first, li);
716 assert(endAlign ==
getLowBit(blockSize));
720 if (endAlign < maxFieldAlign) {
722 CharUnits padding = newBlockSize - blockSize;
730 elementTypes.push_back(llvm::ArrayType::get(CGM.
Int8Ty,
732 blockSize = newBlockSize;
736 assert(endAlign >= maxFieldAlign);
737 assert(endAlign ==
getLowBit(blockSize));
742 li = layout.begin(), le = layout.end(); li != le; ++li) {
743 if (endAlign < li->Alignment) {
747 CharUnits padding = li->Alignment - endAlign;
748 elementTypes.push_back(llvm::ArrayType::get(CGM.
Int8Ty,
750 blockSize += padding;
753 assert(endAlign >= li->Alignment);
754 li->setIndex(info, elementTypes.size(), blockSize);
755 elementTypes.push_back(li->Type);
756 blockSize += li->Size;
769 if (!
blockExpr->getBlockDecl()->hasCaptures())
778 if (!blockInfo.CanBeGlobal)
780 blockInfo.BlockAlign,
"block");
795 auto *InvokeFn = BlockCGF.GenerateBlockFunction(
797 auto *blockFn = llvm::ConstantExpr::getPointerCast(InvokeFn, GenVoidPtrTy);
806 assert(blockAddr.
isValid() &&
"block has no address!");
809 llvm::Constant *descriptor;
815 llvm::Constant *blockISA = blockInfo.
NoEscape
838 auto projectField = [&](
unsigned index,
const Twine &
name) ->
Address {
841 auto storeField = [&](llvm::Value *value,
unsigned index,
const Twine &
name) {
850 auto addHeaderField = [&](llvm::Value *value,
CharUnits size,
852 storeField(value, index, name);
871 addHeaderField(blockFn, GenVoidPtrSize,
"block.invoke");
874 else if (
auto *Helper =
876 for (
auto I : Helper->getCustomFieldValues(*
this, blockInfo)) {
892 projectField(blockInfo.
CXXThisIndex,
"block.captured-this.addr");
897 for (
const auto &CI :
blockDecl->captures()) {
898 const VarDecl *variable = CI.getVariable();
908 Address blockField = projectField(capture.
getIndex(),
"block.captured");
914 if (
blockDecl->isConversionFromLambda()) {
918 }
else if (CI.isEscapingByref()) {
927 "block.capture.addr");
929 auto I = LocalDeclMap.find(variable);
930 assert(I != LocalDeclMap.end());
945 if (CI.isEscapingByref()) {
947 llvm::Value *byrefPointer;
957 }
else if (
const Expr *copyExpr = CI.getCopyExpr()) {
958 if (
blockDecl->isConversionFromLambda()) {
977 }
else if (
type.isConstQualified() &&
991 type->isBlockPointerType()) {
1044 if (
type.isConstQualified() &&
1048 "expected ObjC ARC to be enabled");
1058 if (useArrayEHCleanup)
1065 auto IsBlockDeclInRetExpr = [&]() {
1066 auto *EWC = llvm::dyn_cast_or_null<ExprWithCleanups>(
RetExpr);
1068 for (
auto &
C : EWC->getObjects())
1075 if (IsBlockDeclInRetExpr())
1076 pushDestroy(cleanupKind, blockField,
type, destroyer, useArrayEHCleanup);
1084 llvm::Value *result =
Builder.CreatePointerCast(
1097 if (BlockDescriptorType)
1098 return BlockDescriptorType;
1100 llvm::Type *UnsignedLongTy =
1117 BlockDescriptorType = llvm::StructType::create(
1118 "struct.__block_descriptor", UnsignedLongTy, UnsignedLongTy);
1121 unsigned AddrSpace = 0;
1124 BlockDescriptorType = llvm::PointerType::get(BlockDescriptorType, AddrSpace);
1125 return BlockDescriptorType;
1129 if (GenericBlockLiteralType)
1130 return GenericBlockLiteralType;
1144 llvm::append_range(StructFields, Helper->getCustomFieldTypes());
1146 GenericBlockLiteralType = llvm::StructType::create(
1147 StructFields,
"struct.__opencl_block_literal_generic");
1156 GenericBlockLiteralType =
1157 llvm::StructType::create(
"struct.__block_literal_generic",
VoidPtrTy,
1161 return GenericBlockLiteralType;
1166 llvm::CallBase **CallOrInvoke) {
1170 llvm::Value *
Func =
nullptr;
1180 llvm::Type *GenericVoidPtrTy =
1182 llvm::Value *BlockDescriptor =
Builder.CreatePointerCast(
1183 BlockPtr, GenericVoidPtrTy);
1191 if (!isa<ParmVarDecl>(
E->getCalleeDecl()))
1227 assert(
BlockInfo &&
"evaluating block ref without block information?");
1231 if (capture.
isConstant())
return LocalDeclMap.find(variable)->second;
1234 "block.capture.addr");
1242 byrefInfo.ByrefAlignment);
1250 "the capture field of a non-escaping variable should have a "
1259 llvm::Constant *Addr) {
1260 bool Ok = EmittedGlobalBlocks.insert(std::make_pair(BE, Addr)).second;
1262 assert(
Ok &&
"Trying to replace an already-existing global block!");
1290 llvm::Constant *blockFn) {
1296 "Refusing to re-emit a global block.");
1321 fields.addInt(CGM.
IntTy, 0);
1328 fields.add(blockFn);
1333 }
else if (
auto *Helper =
1335 for (
auto *I : Helper->getCustomFieldValues(CGM, blockInfo)) {
1340 unsigned AddrSpace = 0;
1344 llvm::GlobalVariable *literal = fields.finishAndCreateGlobal(
1345 "__block_literal_global", blockInfo.
BlockAlign,
1346 !IsWindows, llvm::GlobalVariable::InternalLinkage, AddrSpace);
1348 literal->addAttribute(
"objc_arc_inert");
1353 auto *
Init = llvm::Function::Create(llvm::FunctionType::get(CGM.
VoidTy,
1354 {}), llvm::GlobalValue::InternalLinkage,
".block_isa_init",
1356 llvm::IRBuilder<>
b(llvm::BasicBlock::Create(CGM.
getLLVMContext(),
"entry",
1359 b.CreateStructGEP(literal->getValueType(), literal, 0),
1364 auto *InitVar =
new llvm::GlobalVariable(CGM.
getModule(),
Init->getType(),
1365 true, llvm::GlobalValue::InternalLinkage,
1366 Init,
".block_isa_init_ptr");
1367 InitVar->setSection(
".CRT$XCLa");
1372 llvm::Type *RequiredType =
1375 llvm::ConstantExpr::getPointerCast(literal, RequiredType);
1380 cast<llvm::Function>(blockFn->stripPointerCasts()),
Result,
1381 literal->getValueType());
1388 assert(
BlockInfo &&
"not emitting prologue of block invocation function?!");
1397 DI->EmitDeclareOfBlockLiteralArgVariable(
1399 cast<llvm::AllocaInst>(alloc.
getPointer()->stripPointerCasts()),
1411 llvm::PointerType::get(
1420 assert(
BlockInfo &&
"not in a block invocation function!");