Lines Matching +full:literal +full:- +full:block
1 //===--- CGBlocks.cpp - Emit LLVM Code for declarations ---------*- C++ -*-===//
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
11 //===----------------------------------------------------------------------===//
35 CGBlockInfo::CGBlockInfo(const BlockDecl *block, StringRef name) in CGBlockInfo() argument
40 Block(block) { in CGBlockInfo()
51 /// Build the given block as a global block.
56 /// Build the helper function to copy a block.
62 /// Build the helper function to dispose of a block.
113 // either Kind is None or the captured object is a __strong block, in getBlockDescriptorName()
138 /// buildBlockDescriptor - Build the block descriptor meta-data for a block.
140 /// meta-data and contains stationary information about the block literal.
148 /// void *block_method_encoding_address; // @encode for block literal signature.
149 /// void *block_layout_info; // encoding of captured block variables.
167 // If an equivalent block descriptor global variable exists, return it. in buildBlockDescriptor()
175 // If there isn't an equivalent block descriptor global variable, create a new in buildBlockDescriptor()
200 if (cast<llvm::Function>(copyHelper->stripPointerCasts()) in buildBlockDescriptor()
201 ->hasInternalLinkage() || in buildBlockDescriptor()
202 cast<llvm::Function>(disposeHelper->stripPointerCasts()) in buildBlockDescriptor()
203 ->hasInternalLinkage()) in buildBlockDescriptor()
207 // Signature. Mandatory ObjC-style method descriptor @encode sequence. in buildBlockDescriptor()
236 // the block descriptor must have internal linkage too. in buildBlockDescriptor()
248 global->setComdat(CGM.getModule().getOrInsertComdat(descName)); in buildBlockDescriptor()
249 global->setVisibility(llvm::GlobalValue::HiddenVisibility); in buildBlockDescriptor()
250 global->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global); in buildBlockDescriptor()
257 Purely notional variadic template describing the layout of a block.
273 /// 23. BLOCK_IS_NOESCAPE - indicates that the block is non-escaping
274 /// 25. BLOCK_HAS_COPY_DISPOSE - indicates that the block
276 /// 26. BLOCK_HAS_CXX_OBJ - indicates that there's a captured
278 /// 28. BLOCK_IS_GLOBAL - indicates that the block is allocated
280 /// 29. BLOCK_USE_STRET - indicates that the block function
282 /// 30. BLOCK_HAS_SIGNATURE - indicates that the block has an
285 /// 24. BLOCK_NEEDS_FREE - indicates that the block has been moved
287 /// 27. BLOCK_IS_GC - indicates that the block has been moved to
288 /// to GC-allocated memory
293 /// Reserved; should be zero-initialized.
296 /// Function pointer generated from block literal.
299 /// Block description metadata generated from block literal.
308 /// A chunk of data that we actually have to capture in the block.
328 /// Tell the block info that this chunk has the given field index.
346 /// Order by 1) all __strong together 2) next, all block together 3) next,
424 type->getBaseElementTypeUnsafe()->getAs<RecordType>(); in isSafeForCXXConstantCapture()
429 const auto *record = cast<CXXRecordDecl>(recordType->getDecl()); in isSafeForCXXConstantCapture()
431 // Maintain semantics for classes with non-trivial dtors or copy ctors. in isSafeForCXXConstantCapture()
432 if (!record->hasTrivialDestructor()) return false; in isSafeForCXXConstantCapture()
433 if (record->hasNonTrivialCopyConstructor()) return false; in isSafeForCXXConstantCapture()
437 return !record->hasMutableFields(); in isSafeForCXXConstantCapture()
442 /// actually need to keep storage for it in the block; we'll just
443 /// rematerialize it at the start of the block function. This is
454 QualType type = var->getType(); in tryCaptureAsConstant()
470 const Expr *init = var->getInit(); in tryCaptureAsConstant()
506 for (auto *I : Helper->getCustomFieldTypes()) /* custom fields */ { in initializeForBlockHeader()
539 // If the variable is captured by an enclosing block or lambda expression, in getCaptureFieldType()
542 return CGF.BlockInfo->getCapture(VD).fieldType(); in getCaptureFieldType()
544 return FD->getType(); in getCaptureFieldType()
545 // If the captured variable is a non-escaping __block variable, the field in getCaptureFieldType()
548 return VD->isNonEscapingByref() ? in getCaptureFieldType()
549 CGF.getContext().getLValueReferenceType(VD->getType()) : VD->getType(); in getCaptureFieldType()
552 /// Compute the layout of the given block. Attempts to lay the block
557 const BlockDecl *block = info.getBlockDecl(); in computeBlockInfo() local
565 !OpenCLHelper->areAllCustomFieldValuesConstant(info); in computeBlockInfo()
566 if (!block->hasCaptures() && !hasNonConstantCustomFields) { in computeBlockInfo()
576 if (block->doesNotEscape()) in computeBlockInfo()
581 layout.reserve(block->capturesCXXThis() + in computeBlockInfo()
582 (block->capture_end() - block->capture_begin())); in computeBlockInfo()
587 if (block->capturesCXXThis()) { in computeBlockInfo()
588 assert(CGF && isa_and_nonnull<CXXMethodDecl>(CGF->CurFuncDecl) && in computeBlockInfo()
590 QualType thisType = cast<CXXMethodDecl>(CGF->CurFuncDecl)->getThisType(); in computeBlockInfo()
602 // Next, all the block captures. in computeBlockInfo()
603 for (const auto &CI : block->captures()) { in computeBlockInfo()
613 assert(CGF && getCaptureFieldType(*CGF, CI) == variable->getType() && in computeBlockInfo()
616 variable->getType(), layout, info, CGM); in computeBlockInfo()
631 if (const CXXRecordDecl *record = VT->getAsCXXRecordDecl()) in computeBlockInfo()
632 if (CI.hasCopyExpr() || !record->hasTrivialDestructor()) { in computeBlockInfo()
634 if (!record->isExternallyVisible()) in computeBlockInfo()
675 // maximum thing, look for things that are okay with the header-end in computeBlockInfo()
691 for (; li != le && endAlign < li->Alignment; ++li) in computeBlockInfo()
699 assert(endAlign >= li->Alignment); in computeBlockInfo()
701 li->setIndex(info, elementTypes.size(), blockSize); in computeBlockInfo()
702 elementTypes.push_back(li->Type); in computeBlockInfo()
703 blockSize += li->Size; in computeBlockInfo()
712 // Don't re-append everything we just appended. in computeBlockInfo()
723 CharUnits padding = newBlockSize - blockSize; in computeBlockInfo()
726 // initial gap; this need to go into the block layout bit map. in computeBlockInfo()
744 if (endAlign < li->Alignment) { in computeBlockInfo()
746 // an over-aligned variable. We will be adding a padding field to in computeBlockInfo()
748 CharUnits padding = li->Alignment - endAlign; in computeBlockInfo()
754 assert(endAlign >= li->Alignment); in computeBlockInfo()
755 li->setIndex(info, elementTypes.size(), blockSize); in computeBlockInfo()
756 elementTypes.push_back(li->Type); in computeBlockInfo()
757 blockSize += li->Size; in computeBlockInfo()
766 /// Emit a block literal expression in the current function.
768 // If the block has no captures, we won't have a pre-computed in EmitBlockLiteral()
770 if (!blockExpr->getBlockDecl()->hasCaptures()) in EmitBlockLiteral()
771 // The block literal is emitted as a global variable, and the block invoke in EmitBlockLiteral()
773 if (llvm::Constant *Block = CGM.getAddrOfGlobalBlockIfEmitted(blockExpr)) in EmitBlockLiteral() local
774 return Block; in EmitBlockLiteral()
776 CGBlockInfo blockInfo(blockExpr->getBlockDecl(), CurFn->getName()); in EmitBlockLiteral()
781 blockInfo.BlockAlign, "block"); in EmitBlockLiteral()
792 // Using the computed layout, generate the actual block function. in EmitBlockLiteral()
793 bool isLambdaConv = blockInfo.getBlockDecl()->isConversionFromLambda(); in EmitBlockLiteral()
800 // If there is nothing to capture, we can emit this as a global block. in EmitBlockLiteral()
804 // Otherwise, we have to emit this as a local block. in EmitBlockLiteral()
807 assert(blockAddr.isValid() && "block has no address!"); in EmitBlockLiteral()
813 // If the block is non-escaping, set field 'isa 'to NSConcreteGlobalBlock in EmitBlockLiteral()
814 // and set the BLOCK_IS_GLOBAL bit of field 'flags'. Copying a non-escaping in EmitBlockLiteral()
815 // block just returns the original block and releasing it is a no-op. in EmitBlockLiteral()
821 // Build the block descriptor. in EmitBlockLiteral()
824 // Compute the initial on-stack block flags. in EmitBlockLiteral()
839 auto projectField = [&](unsigned index, const Twine &name) -> Address { in EmitBlockLiteral()
846 // Initialize the block header. in EmitBlockLiteral()
859 addHeaderField(isa, getPointerSize(), "block.isa"); in EmitBlockLiteral()
861 getIntSize(), "block.flags"); in EmitBlockLiteral()
863 "block.reserved"); in EmitBlockLiteral()
867 getIntSize(), "block.size"); in EmitBlockLiteral()
870 getIntSize(), "block.align"); in EmitBlockLiteral()
872 addHeaderField(blockFn, GenVoidPtrSize, "block.invoke"); in EmitBlockLiteral()
874 addHeaderField(descriptor, getPointerSize(), "block.descriptor"); in EmitBlockLiteral()
877 for (auto I : Helper->getCustomFieldValues(*this, blockInfo)) { in EmitBlockLiteral()
881 CGM.getDataLayout().getTypeAllocSize(I.first->getType())), in EmitBlockLiteral()
887 // Finally, capture all the values into the block. in EmitBlockLiteral()
891 if (blockDecl->capturesCXXThis()) { in EmitBlockLiteral()
893 projectField(blockInfo.CXXThisIndex, "block.captured-this.addr"); in EmitBlockLiteral()
898 for (const auto &CI : blockDecl->captures()) { in EmitBlockLiteral()
909 Address blockField = projectField(capture.getIndex(), "block.captured"); in EmitBlockLiteral()
912 // block literal. in EmitBlockLiteral()
915 if (blockDecl->isConversionFromLambda()) { in EmitBlockLiteral()
916 // The lambda capture in a lambda's conversion-to-block-pointer is in EmitBlockLiteral()
921 // We need to use the capture from the enclosing block. in EmitBlockLiteral()
923 BlockInfo->getCapture(variable); in EmitBlockLiteral()
928 "block.capture.addr"); in EmitBlockLiteral()
932 src = I->second; in EmitBlockLiteral()
943 // the block field. There's no need to chase the forwarding in EmitBlockLiteral()
957 // If we have a copy constructor, evaluate that into the block field. in EmitBlockLiteral()
959 if (blockDecl->isConversionFromLambda()) { in EmitBlockLiteral()
961 // directly into the block instead. in EmitBlockLiteral()
973 // If it's a reference variable, copy the reference into the block field. in EmitBlockLiteral()
974 } else if (type->getAs<ReferenceType>()) { in EmitBlockLiteral()
977 // If type is const-qualified, copy the value into the block field. in EmitBlockLiteral()
984 // If this is an ARC __strong block-pointer variable, don't do a in EmitBlockLiteral()
985 // block copy. in EmitBlockLiteral()
988 // we should never need to do a block-copy when initializing a local in EmitBlockLiteral()
990 // contained within the stack block's. in EmitBlockLiteral()
992 type->isBlockPointerType()) { in EmitBlockLiteral()
993 // Load the block and do a simple retain. in EmitBlockLiteral()
994 llvm::Value *value = Builder.CreateLoad(src, "block.captured_block"); in EmitBlockLiteral()
997 // Do a primitive store to the block field. in EmitBlockLiteral()
1000 // Otherwise, fake up a POD copy into the block field. in EmitBlockLiteral()
1016 // attributed to a reasonable location - otherwise it may be attributed to in EmitBlockLiteral()
1027 // Ignore __block captures; there's nothing special in the on-stack block in EmitBlockLiteral()
1039 // Block captures count as local values and have imprecise semantics. in EmitBlockLiteral()
1042 // For const-qualified captures, emit clang.arc.use to ensure the captured in EmitBlockLiteral()
1044 // within the block. in EmitBlockLiteral()
1063 // block expression except when the block decl is in the list of RetExpr's in EmitBlockLiteral()
1069 for (auto &C : EWC->getObjects()) in EmitBlockLiteral()
1083 // Cast to the converted block-pointer type, which happens (somewhat in EmitBlockLiteral()
1086 blockAddr.getPointer(), ConvertType(blockInfo.getBlockExpr()->getType())); in EmitBlockLiteral()
1115 // const char *signature; // the block signature in getBlockDescriptorType()
1145 llvm::append_range(StructFields, Helper->getCustomFieldTypes()); in getGenericBlockLiteralType()
1167 const auto *BPT = E->getCallee()->getType()->castAs<BlockPointerType>(); in EmitBlockCallExpr()
1168 llvm::Value *BlockPtr = EmitScalarExpr(E->getCallee()); in EmitBlockCallExpr()
1171 QualType FnType = BPT->getPointeeType(); in EmitBlockCallExpr()
1176 // For OpenCL, BlockPtr is already casted to generic block literal. in EmitBlockCallExpr()
1178 // First argument of a block call is a generic block literal casted to in EmitBlockCallExpr()
1188 EmitCallArgs(Args, FnType->getAs<FunctionProtoType>(), E->arguments()); in EmitBlockCallExpr()
1190 // We *can* call the block directly unless it is a function argument. in EmitBlockCallExpr()
1191 if (!isa<ParmVarDecl>(E->getCalleeDecl())) in EmitBlockCallExpr()
1192 Func = CGM.getOpenCLRuntime().getInvokeFunction(E->getCallee()); in EmitBlockCallExpr()
1199 // Bitcast the block literal to a generic block literal. in EmitBlockCallExpr()
1201 Builder.CreatePointerCast(BlockPtr, UnqualPtrTy, "block.literal"); in EmitBlockCallExpr()
1202 // Get pointer to the block invoke function in EmitBlockCallExpr()
1205 // First argument is a block literal casted to a void pointer in EmitBlockCallExpr()
1209 EmitCallArgs(Args, FnType->getAs<FunctionProtoType>(), E->arguments()); in EmitBlockCallExpr()
1215 const FunctionType *FuncTy = FnType->castAs<FunctionType>(); in EmitBlockCallExpr()
1222 // And call the block. in EmitBlockCallExpr()
1227 assert(BlockInfo && "evaluating block ref without block information?"); in GetAddrOfBlockDecl()
1228 const CGBlockInfo::Capture &capture = BlockInfo->getCapture(variable); in GetAddrOfBlockDecl()
1231 if (capture.isConstant()) return LocalDeclMap.find(variable)->second; in GetAddrOfBlockDecl()
1234 "block.capture.addr"); in GetAddrOfBlockDecl()
1236 if (variable->isEscapingByref()) { in GetAddrOfBlockDecl()
1245 variable->getName()); in GetAddrOfBlockDecl()
1248 assert((!variable->isNonEscapingByref() || in GetAddrOfBlockDecl()
1249 capture.fieldType()->isReferenceType()) && in GetAddrOfBlockDecl()
1250 "the capture field of a non-escaping variable should have a " in GetAddrOfBlockDecl()
1252 if (capture.fieldType()->isReferenceType()) in GetAddrOfBlockDecl()
1262 assert(Ok && "Trying to replace an already-existing global block!"); in setAddrOfGlobalBlock()
1268 if (llvm::Constant *Block = getAddrOfGlobalBlockIfEmitted(BE)) in GetAddrOfGlobalBlock() local
1269 return Block; in GetAddrOfGlobalBlock()
1271 CGBlockInfo blockInfo(BE->getBlockDecl(), Name); in GetAddrOfGlobalBlock()
1274 // Compute information about the layout, etc., of this block. in GetAddrOfGlobalBlock()
1277 // Using that metadata, generate the actual block function. in GetAddrOfGlobalBlock()
1294 // if we've already emitted this block. in buildGlobalBlock()
1296 "Refusing to re-emit a global block."); in buildGlobalBlock()
1298 // Generate the constants for the block literal initializer. in buildGlobalBlock()
1335 for (auto *I : Helper->getCustomFieldValues(CGM, blockInfo)) { in buildGlobalBlock()
1344 llvm::GlobalVariable *literal = fields.finishAndCreateGlobal( in buildGlobalBlock() local
1348 literal->addAttribute("objc_arc_inert"); in buildGlobalBlock()
1359 b.CreateStructGEP(literal->getValueType(), literal, 0), in buildGlobalBlock()
1364 auto *InitVar = new llvm::GlobalVariable(CGM.getModule(), Init->getType(), in buildGlobalBlock()
1367 InitVar->setSection(".CRT$XCLa"); in buildGlobalBlock()
1371 // Return a constant of the appropriately-casted type. in buildGlobalBlock()
1373 CGM.getTypes().ConvertType(blockInfo.getBlockExpr()->getType()); in buildGlobalBlock()
1375 llvm::ConstantExpr::getPointerCast(literal, RequiredType); in buildGlobalBlock()
1380 cast<llvm::Function>(blockFn->stripPointerCasts()), Result, in buildGlobalBlock()
1381 literal->getValueType()); in buildGlobalBlock()
1388 assert(BlockInfo && "not emitting prologue of block invocation function?!"); in setBlockContextParameter()
1391 // debug info at -O0. The mem2reg pass will eliminate it when optimizing. in setBlockContextParameter()
1392 RawAddress alloc = CreateMemTemp(D->getType(), D->getName() + ".addr"); in setBlockContextParameter()
1396 DI->setLocation(D->getLocation()); in setBlockContextParameter()
1397 DI->EmitDeclareOfBlockLiteralArgVariable( in setBlockContextParameter()
1398 *BlockInfo, D->getName(), argNum, in setBlockContextParameter()
1403 SourceLocation StartLoc = BlockInfo->getBlockExpr()->getBody()->getBeginLoc(); in setBlockContextParameter()
1415 "block"); in setBlockContextParameter()
1419 assert(BlockInfo && "not in a block invocation function!"); in LoadBlockStruct()
1420 assert(BlockPointer && "no block pointer set!"); in LoadBlockStruct()
1421 return Address(BlockPointer, BlockInfo->StructureType, BlockInfo->BlockAlign); in LoadBlockStruct()
1431 CurEHLocation = blockInfo.getBlockExpr()->getEndLoc(); in GenerateBlockFunction()
1437 // referenced in a block. in GenerateBlockFunction()
1439 const auto *var = dyn_cast<VarDecl>(i->first); in GenerateBlockFunction()
1440 if (var && !var->hasLocalStorage()) in GenerateBlockFunction()
1441 setAddrOfLocalVar(var, i->second); in GenerateBlockFunction()
1449 // The first argument is the block pointer. Just take it as a void* in GenerateBlockFunction()
1453 // For OpenCL passed block pointer can be private AS local variable or in GenerateBlockFunction()
1469 args.append(blockDecl->param_begin(), blockDecl->param_end()); in GenerateBlockFunction()
1472 const FunctionProtoType *fnType = blockInfo.getBlockExpr()->getFunctionType(); in GenerateBlockFunction()
1494 StartFunction(blockDecl, fnType->getReturnType(), fn, fnInfo, args, in GenerateBlockFunction()
1495 blockDecl->getLocation(), in GenerateBlockFunction()
1496 blockInfo.getBlockExpr()->getBody()->getBeginLoc()); in GenerateBlockFunction()
1500 // At -O0 we generate an explicit alloca for the BlockPointer, so the RA in GenerateBlockFunction()
1505 Address Alloca = CreateTempAlloca(BlockPointer->getType(), in GenerateBlockFunction()
1507 "block.addr"); in GenerateBlockFunction()
1517 if (blockDecl->capturesCXXThis()) { in GenerateBlockFunction()
1519 LoadBlockStruct(), blockInfo.CXXThisIndex, "block.captured-this"); in GenerateBlockFunction()
1524 for (const auto &CI : blockDecl->captures()) { in GenerateBlockFunction()
1531 CreateMemTemp(variable->getType(), align, "block.captured-const"); in GenerateBlockFunction()
1541 --entry_ptr; in GenerateBlockFunction()
1547 incrementProfileCounter(blockDecl->getBody()); in GenerateBlockFunction()
1548 EmitStmt(blockDecl->getBody()); in GenerateBlockFunction()
1555 if (entry_ptr->getNextNonDebugInstruction()) in GenerateBlockFunction()
1556 entry_ptr = entry_ptr->getNextNonDebugInstruction()->getIterator(); in GenerateBlockFunction()
1558 entry_ptr = entry->end(); in GenerateBlockFunction()
1564 for (const auto &CI : blockDecl->captures()) { in GenerateBlockFunction()
1566 DI->EmitLocation(Builder, variable->getLocation()); in GenerateBlockFunction()
1571 auto addr = LocalDeclMap.find(variable)->second; in GenerateBlockFunction()
1572 (void)DI->EmitDeclareOfAutoVariable( in GenerateBlockFunction()
1577 DI->EmitDeclareOfBlockDeclRefVariable( in GenerateBlockFunction()
1579 entry_ptr == entry->end() ? nullptr : &*entry_ptr); in GenerateBlockFunction()
1583 DI->EmitLocation(Builder, in GenerateBlockFunction()
1584 cast<CompoundStmt>(blockDecl->getBody())->getRBracLoc()); in GenerateBlockFunction()
1593 FinishFunction(cast<CompoundStmt>(blockDecl->getBody())->getRBracLoc()); in GenerateBlockFunction()
1615 bool isBlockPointer = T->isBlockPointerType(); in computeCopyInfoForBlockCapture()
1628 // If it's a block pointer, we have to copy the block and assign that to in computeCopyInfoForBlockCapture()
1636 if (!T->isObjCRetainableType()) in computeCopyInfoForBlockCapture()
1642 if (T->isObjCInertUnsafeUnretainedType()) in computeCopyInfoForBlockCapture()
1648 // Non-ARC captures of retainable pointers are strong and in computeCopyInfoForBlockCapture()
1687 if (const auto *RD = T->getAsCXXRecordDecl()) in cxxDestructorCanThrow()
1688 if (const CXXDestructorDecl *DD = RD->getDestructor()) in cxxDestructorCanThrow()
1689 return DD->getType()->castAs<FunctionProtoType>()->canThrow(); in cxxDestructorCanThrow()
1701 QualType CaptureTy = CI.getVariable()->getType(); in getBlockCaptureStr()
1778 // The underscore is necessary here because non-trivial copy constructor in getBlockCaptureStr()
1843 // function don't throw as newly-copied __block variables always have a in pushCaptureCleanup()
1864 Fn->setVisibility(llvm::GlobalValue::HiddenVisibility); in setBlockHelperAttributesVisibility()
1865 Fn->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global); in setBlockHelperAttributesVisibility()
1870 /// Generate the copy-helper function for a block closure object:
1873 /// bit-copy of 'src'.
1875 /// Note that this copies an entire block closure object to the heap;
1908 Fn->setComdat(CGM.getModule().getOrInsertComdat(FuncName)); in GenerateCopyHelperFunction()
1932 QualType captureType = CI.getVariable()->getType(); in GenerateCopyHelperFunction()
1949 // If this is a C struct that requires non-trivial copy construction, in GenerateCopyHelperFunction()
1951 QualType varType = CI.getVariable()->getType(); in GenerateCopyHelperFunction()
1958 // At -O0, store null into the destination field (so that the in GenerateCopyHelperFunction()
1959 // storeStrong doesn't over-release) and then call storeStrong. in GenerateCopyHelperFunction()
1962 auto *ty = cast<llvm::PointerType>(srcValue->getType()); in GenerateCopyHelperFunction()
1968 // the blocks runtime guarantees a memcpy of the block data, and in GenerateCopyHelperFunction()
1979 I->eraseFromParent(); in GenerateCopyHelperFunction()
2015 if (T->isBlockPointerType()) in getBlockFieldFlagsForObjCObjectPointer()
2046 // Non-ARC captures are strong, and we need to use _Block_object_dispose. in computeDestroyInfoForBlockCapture()
2049 if (T->isObjCRetainableType() && !T.getQualifiers().hasObjCLifetime() && in computeDestroyInfoForBlockCapture()
2050 !LangOpts.ObjCAutoRefCount && !T->isObjCInertUnsafeUnretainedType()) in computeDestroyInfoForBlockCapture()
2060 /// Generate the destroy-helper function for a block closure object:
2063 /// Note that this destroys a heap-allocated block closure object;
2065 /// destroys the heap-allocated contents of an individual __block
2095 Fn->setComdat(CGM.getModule().getOrInsertComdat(FuncName)); in GenerateDestroyHelperFunction()
2123 CI.getVariable()->getType(), flags, in GenerateDestroyHelperFunction()
2193 /// that's not of block-pointer type.
2206 llvm::ConstantPointerNull::get(cast<llvm::PointerType>(value->getType())); in emitCopy()
2229 /// variable that's of block-pointer type.
2239 // right arguments to make sure it doesn't get no-op'ed. in emitCopy()
2284 /// Emits the copy/dispose helpers for a __block variable that is a non-trivial
2351 // dst->x in generateByrefCopyHelper()
2356 CGF.emitBlockByrefAddress(destField, byrefInfo, false, "dest-object"); in generateByrefCopyHelper()
2358 // src->x in generateByrefCopyHelper()
2363 CGF.emitBlockByrefAddress(srcField, byrefInfo, false, "src-object"); in generateByrefCopyHelper()
2477 if (const CXXRecordDecl *record = type->getAsCXXRecordDecl()) { in buildByrefHelpers()
2480 if (!copyExpr && record->hasTrivialDestructor()) return nullptr; in buildByrefHelpers()
2486 // If type is a non-trivial C struct type that is non-trivial to in buildByrefHelpers()
2495 if (!type->isObjCRetainableType()) return nullptr; in buildByrefHelpers()
2517 // Block pointers need to be copied, and there's no direct in buildByrefHelpers()
2519 if (type->isBlockPointerType()) { in buildByrefHelpers()
2534 if (type->isBlockPointerType()) { in buildByrefHelpers()
2537 type->isObjCObjectPointerType()) { in buildByrefHelpers()
2554 return emitBlockByrefAddress(baseAddr, info, followForward, var->getName()); in emitBlockByrefAddress()
2571 /// BuildByrefInfo - This routine changes a __block variable declared as T x
2589 return it->second; in getBlockByrefInfo()
2593 "struct.__block_byref_" + D->getNameAsString()); in getBlockByrefInfo()
2595 QualType Ty = D->getType(); in getBlockByrefInfo()
2647 llvm::ArrayType::get(Int8Ty, (varOffset - size).getQuantity()); in getBlockByrefInfo()
2659 byrefType->setBody(types, packed); in getBlockByrefInfo()
2663 info.FieldIndex = types.size() - 1; in getBlockByrefInfo()
2669 return pair.first->second; in getBlockByrefInfo()
2734 if (!type->isObjCObjectPointerType() && !type->isBlockPointerType()) in emitByrefStructureInit()
2768 storeHeaderField(helpers->CopyHelper, getPointerSize(), in emitByrefStructureInit()
2770 storeHeaderField(helpers->DisposeHelper, getPointerSize(), in emitByrefStructureInit()
2802 auto *GV = cast<llvm::GlobalValue>(C->stripPointerCasts()); in configureBlocksRuntimeObject()
2805 const IdentifierInfo &II = CGM.getContext().Idents.get(C->getName()); in configureBlocksRuntimeObject()
2809 assert((isa<llvm::Function>(C->stripPointerCasts()) || in configureBlocksRuntimeObject()
2810 isa<llvm::GlobalVariable>(C->stripPointerCasts())) && in configureBlocksRuntimeObject()
2814 for (const auto *Result : DC->lookup(&II)) in configureBlocksRuntimeObject()
2820 if (GV->isDeclaration() && (!ND || !ND->hasAttr<DLLExportAttr>())) { in configureBlocksRuntimeObject()
2821 GV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass); in configureBlocksRuntimeObject()
2822 GV->setLinkage(llvm::GlobalValue::ExternalLinkage); in configureBlocksRuntimeObject()
2824 GV->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass); in configureBlocksRuntimeObject()
2825 GV->setLinkage(llvm::GlobalValue::ExternalLinkage); in configureBlocksRuntimeObject()
2829 if (CGM.getLangOpts().BlocksRuntimeOptional && GV->isDeclaration() && in configureBlocksRuntimeObject()
2830 GV->hasExternalLinkage()) in configureBlocksRuntimeObject()
2831 GV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage); in configureBlocksRuntimeObject()