summaryrefslogtreecommitdiff
path: root/external/apache2/llvm/dist/clang/lib/CodeGen/CGBlocks.cpp
diff options
context:
space:
mode:
authorjoerg <joerg@NetBSD.org>2021-05-30 01:25:15 +0000
committerjoerg <joerg@NetBSD.org>2021-05-30 01:25:15 +0000
commit13fbcb42fff2606c3ce926a7c4bb8989aa18758c (patch)
treedcace6c89967106796d44b1a7c5e2269a20967e2 /external/apache2/llvm/dist/clang/lib/CodeGen/CGBlocks.cpp
parent13338e33506ade63440b4ba74479551bdc21c0f6 (diff)
Import clang 249b40b558955afe5ac2b549edcf2d7f859c8cc9.
Diffstat (limited to 'external/apache2/llvm/dist/clang/lib/CodeGen/CGBlocks.cpp')
-rw-r--r--external/apache2/llvm/dist/clang/lib/CodeGen/CGBlocks.cpp272
1 files changed, 100 insertions, 172 deletions
diff --git a/external/apache2/llvm/dist/clang/lib/CodeGen/CGBlocks.cpp b/external/apache2/llvm/dist/clang/lib/CodeGen/CGBlocks.cpp
index f90d9439af2..e5286761ee8 100644
--- a/external/apache2/llvm/dist/clang/lib/CodeGen/CGBlocks.cpp
+++ b/external/apache2/llvm/dist/clang/lib/CodeGen/CGBlocks.cpp
@@ -19,6 +19,7 @@
#include "CodeGenModule.h"
#include "ConstantEmitter.h"
#include "TargetInfo.h"
+#include "clang/AST/Attr.h"
#include "clang/AST/DeclObjC.h"
#include "clang/CodeGen/ConstantInitBuilder.h"
#include "llvm/ADT/SmallSet.h"
@@ -35,7 +36,7 @@ CGBlockInfo::CGBlockInfo(const BlockDecl *block, StringRef name)
: Name(name), CXXThisIndex(0), CanBeGlobal(false), NeedsCopyDispose(false),
HasCXXObject(false), UsesStret(false), HasCapturedVariableLayout(false),
CapturesNonExternalType(false), LocalAddress(Address::invalid()),
- StructureType(nullptr), Block(block), DominatingIP(nullptr) {
+ StructureType(nullptr), Block(block) {
// Skip asm prefix, if any. 'name' is usually taken directly from
// the mangled name of the enclosing function.
@@ -556,11 +557,10 @@ static void computeBlockInfo(CodeGenModule &CGM, CodeGenFunction *CGF,
// Theoretically, this could be in a different address space, so
// don't assume standard pointer size/align.
llvm::Type *llvmType = CGM.getTypes().ConvertType(thisType);
- std::pair<CharUnits,CharUnits> tinfo
- = CGM.getContext().getTypeInfoInChars(thisType);
- maxFieldAlign = std::max(maxFieldAlign, tinfo.second);
+ auto TInfo = CGM.getContext().getTypeInfoInChars(thisType);
+ maxFieldAlign = std::max(maxFieldAlign, TInfo.Align);
- layout.push_back(BlockLayoutChunk(tinfo.second, tinfo.first,
+ layout.push_back(BlockLayoutChunk(TInfo.Align, TInfo.Width,
Qualifiers::OCL_None,
nullptr, llvmType, thisType));
}
@@ -579,7 +579,7 @@ static void computeBlockInfo(CodeGenModule &CGM, CodeGenFunction *CGF,
// Since a __block variable cannot be captured by lambdas, its type and
// the capture field type should always match.
- assert(getCaptureFieldType(*CGF, CI) == variable->getType() &&
+ assert(CGF && getCaptureFieldType(*CGF, CI) == variable->getType() &&
"capture type differs from the variable type");
layout.push_back(BlockLayoutChunk(align, CGM.getPointerSize(),
Qualifiers::OCL_None, &CI,
@@ -774,151 +774,23 @@ static void computeBlockInfo(CodeGenModule &CGM, CodeGenFunction *CGF,
llvm::StructType::get(CGM.getLLVMContext(), elementTypes, true);
}
-/// Enter the scope of a block. This should be run at the entrance to
-/// a full-expression so that the block's cleanups are pushed at the
-/// right place in the stack.
-static void enterBlockScope(CodeGenFunction &CGF, BlockDecl *block) {
- assert(CGF.HaveInsertPoint());
-
- // Allocate the block info and place it at the head of the list.
- CGBlockInfo &blockInfo =
- *new CGBlockInfo(block, CGF.CurFn->getName());
- blockInfo.NextBlockInfo = CGF.FirstBlockInfo;
- CGF.FirstBlockInfo = &blockInfo;
-
- // Compute information about the layout, etc., of this block,
- // pushing cleanups as necessary.
- computeBlockInfo(CGF.CGM, &CGF, blockInfo);
-
- // Nothing else to do if it can be global.
- if (blockInfo.CanBeGlobal) return;
-
- // Make the allocation for the block.
- blockInfo.LocalAddress = CGF.CreateTempAlloca(blockInfo.StructureType,
- blockInfo.BlockAlign, "block");
-
- // If there are cleanups to emit, enter them (but inactive).
- if (!blockInfo.NeedsCopyDispose) return;
-
- // Walk through the captures (in order) and find the ones not
- // captured by constant.
- for (const auto &CI : block->captures()) {
- // Ignore __block captures; there's nothing special in the
- // on-stack block that we need to do for them.
- if (CI.isByRef()) continue;
-
- // Ignore variables that are constant-captured.
- const VarDecl *variable = CI.getVariable();
- CGBlockInfo::Capture &capture = blockInfo.getCapture(variable);
- if (capture.isConstant()) continue;
-
- // Ignore objects that aren't destructed.
- QualType VT = getCaptureFieldType(CGF, CI);
- QualType::DestructionKind dtorKind = VT.isDestructedType();
- if (dtorKind == QualType::DK_none) continue;
-
- CodeGenFunction::Destroyer *destroyer;
-
- // Block captures count as local values and have imprecise semantics.
- // They also can't be arrays, so need to worry about that.
- //
- // For const-qualified captures, emit clang.arc.use to ensure the captured
- // object doesn't get released while we are still depending on its validity
- // within the block.
- if (VT.isConstQualified() &&
- VT.getObjCLifetime() == Qualifiers::OCL_Strong &&
- CGF.CGM.getCodeGenOpts().OptimizationLevel != 0) {
- assert(CGF.CGM.getLangOpts().ObjCAutoRefCount &&
- "expected ObjC ARC to be enabled");
- destroyer = CodeGenFunction::emitARCIntrinsicUse;
- } else if (dtorKind == QualType::DK_objc_strong_lifetime) {
- destroyer = CodeGenFunction::destroyARCStrongImprecise;
- } else {
- destroyer = CGF.getDestroyer(dtorKind);
- }
-
- // GEP down to the address.
- Address addr =
- CGF.Builder.CreateStructGEP(blockInfo.LocalAddress, capture.getIndex());
-
- // We can use that GEP as the dominating IP.
- if (!blockInfo.DominatingIP)
- blockInfo.DominatingIP = cast<llvm::Instruction>(addr.getPointer());
-
- CleanupKind cleanupKind = InactiveNormalCleanup;
- bool useArrayEHCleanup = CGF.needsEHCleanup(dtorKind);
- if (useArrayEHCleanup)
- cleanupKind = InactiveNormalAndEHCleanup;
-
- CGF.pushDestroy(cleanupKind, addr, VT,
- destroyer, useArrayEHCleanup);
-
- // Remember where that cleanup was.
- capture.setCleanup(CGF.EHStack.stable_begin());
- }
-}
-
-/// Enter a full-expression with a non-trivial number of objects to
-/// clean up. This is in this file because, at the moment, the only
-/// kind of cleanup object is a BlockDecl*.
-void CodeGenFunction::enterNonTrivialFullExpression(const FullExpr *E) {
- if (const auto EWC = dyn_cast<ExprWithCleanups>(E)) {
- assert(EWC->getNumObjects() != 0);
- for (const ExprWithCleanups::CleanupObject &C : EWC->getObjects())
- enterBlockScope(*this, C);
- }
-}
-
-/// Find the layout for the given block in a linked list and remove it.
-static CGBlockInfo *findAndRemoveBlockInfo(CGBlockInfo **head,
- const BlockDecl *block) {
- while (true) {
- assert(head && *head);
- CGBlockInfo *cur = *head;
-
- // If this is the block we're looking for, splice it out of the list.
- if (cur->getBlockDecl() == block) {
- *head = cur->NextBlockInfo;
- return cur;
- }
-
- head = &cur->NextBlockInfo;
- }
-}
-
-/// Destroy a chain of block layouts.
-void CodeGenFunction::destroyBlockInfos(CGBlockInfo *head) {
- assert(head && "destroying an empty chain");
- do {
- CGBlockInfo *cur = head;
- head = cur->NextBlockInfo;
- delete cur;
- } while (head != nullptr);
-}
-
/// Emit a block literal expression in the current function.
llvm::Value *CodeGenFunction::EmitBlockLiteral(const BlockExpr *blockExpr) {
// If the block has no captures, we won't have a pre-computed
// layout for it.
- if (!blockExpr->getBlockDecl()->hasCaptures()) {
+ if (!blockExpr->getBlockDecl()->hasCaptures())
// The block literal is emitted as a global variable, and the block invoke
// function has to be extracted from its initializer.
- if (llvm::Constant *Block = CGM.getAddrOfGlobalBlockIfEmitted(blockExpr)) {
+ if (llvm::Constant *Block = CGM.getAddrOfGlobalBlockIfEmitted(blockExpr))
return Block;
- }
- CGBlockInfo blockInfo(blockExpr->getBlockDecl(), CurFn->getName());
- computeBlockInfo(CGM, this, blockInfo);
- blockInfo.BlockExpression = blockExpr;
- return EmitBlockLiteral(blockInfo);
- }
- // Find the block info for this block and take ownership of it.
- std::unique_ptr<CGBlockInfo> blockInfo;
- blockInfo.reset(findAndRemoveBlockInfo(&FirstBlockInfo,
- blockExpr->getBlockDecl()));
-
- blockInfo->BlockExpression = blockExpr;
- return EmitBlockLiteral(*blockInfo);
+ CGBlockInfo blockInfo(blockExpr->getBlockDecl(), CurFn->getName());
+ computeBlockInfo(CGM, this, blockInfo);
+ blockInfo.BlockExpression = blockExpr;
+ if (!blockInfo.CanBeGlobal)
+ blockInfo.LocalAddress = CreateTempAlloca(blockInfo.StructureType,
+ blockInfo.BlockAlign, "block");
+ return EmitBlockLiteral(blockInfo);
}
llvm::Value *CodeGenFunction::EmitBlockLiteral(const CGBlockInfo &blockInfo) {
@@ -1076,7 +948,7 @@ llvm::Value *CodeGenFunction::EmitBlockLiteral(const CGBlockInfo &blockInfo) {
/*RefersToEnclosingVariableOrCapture*/ CI.isNested(),
type.getNonReferenceType(), VK_LValue,
SourceLocation());
- src = EmitDeclRefLValue(&declRef).getAddress();
+ src = EmitDeclRefLValue(&declRef).getAddress(*this);
};
// For byrefs, we just write the pointer to the byref struct into
@@ -1151,7 +1023,7 @@ llvm::Value *CodeGenFunction::EmitBlockLiteral(const CGBlockInfo &blockInfo) {
type, VK_LValue, SourceLocation());
ImplicitCastExpr l2r(ImplicitCastExpr::OnStack, type, CK_LValueToRValue,
- &declRef, VK_RValue);
+ &declRef, VK_RValue, FPOptionsOverride());
// FIXME: Pass a specific location for the expr init so that the store is
// attributed to a reasonable location - otherwise it may be attributed to
// locations of subexpressions in the initialization.
@@ -1160,12 +1032,64 @@ llvm::Value *CodeGenFunction::EmitBlockLiteral(const CGBlockInfo &blockInfo) {
/*captured by init*/ false);
}
- // Activate the cleanup if layout pushed one.
- if (!CI.isByRef()) {
- EHScopeStack::stable_iterator cleanup = capture.getCleanup();
- if (cleanup.isValid())
- ActivateCleanupBlock(cleanup, blockInfo.DominatingIP);
+ // Push a cleanup for the capture if necessary.
+ if (!blockInfo.NeedsCopyDispose)
+ continue;
+
+ // Ignore __block captures; there's nothing special in the on-stack block
+ // that we need to do for them.
+ if (CI.isByRef())
+ continue;
+
+ // Ignore objects that aren't destructed.
+ QualType::DestructionKind dtorKind = type.isDestructedType();
+ if (dtorKind == QualType::DK_none)
+ continue;
+
+ CodeGenFunction::Destroyer *destroyer;
+
+ // Block captures count as local values and have imprecise semantics.
+ // They also can't be arrays, so need to worry about that.
+ //
+ // For const-qualified captures, emit clang.arc.use to ensure the captured
+ // object doesn't get released while we are still depending on its validity
+ // within the block.
+ if (type.isConstQualified() &&
+ type.getObjCLifetime() == Qualifiers::OCL_Strong &&
+ CGM.getCodeGenOpts().OptimizationLevel != 0) {
+ assert(CGM.getLangOpts().ObjCAutoRefCount &&
+ "expected ObjC ARC to be enabled");
+ destroyer = emitARCIntrinsicUse;
+ } else if (dtorKind == QualType::DK_objc_strong_lifetime) {
+ destroyer = destroyARCStrongImprecise;
+ } else {
+ destroyer = getDestroyer(dtorKind);
}
+
+ CleanupKind cleanupKind = NormalCleanup;
+ bool useArrayEHCleanup = needsEHCleanup(dtorKind);
+ if (useArrayEHCleanup)
+ cleanupKind = NormalAndEHCleanup;
+
+ // Extend the lifetime of the capture to the end of the scope enclosing the
+ // block expression except when the block decl is in the list of RetExpr's
+ // cleanup objects, in which case its lifetime ends after the full
+ // expression.
+ auto IsBlockDeclInRetExpr = [&]() {
+ auto *EWC = llvm::dyn_cast_or_null<ExprWithCleanups>(RetExpr);
+ if (EWC)
+ for (auto &C : EWC->getObjects())
+ if (auto *BD = C.dyn_cast<BlockDecl *>())
+ if (BD == blockDecl)
+ return true;
+ return false;
+ };
+
+ if (IsBlockDeclInRetExpr())
+ pushDestroy(cleanupKind, blockField, type, destroyer, useArrayEHCleanup);
+ else
+ pushLifetimeExtendedDestroy(cleanupKind, blockField, type, destroyer,
+ useArrayEHCleanup);
}
// Cast to the converted block-pointer type, which happens (somewhat
@@ -1266,8 +1190,10 @@ RValue CodeGenFunction::EmitBlockCallExpr(const CallExpr *E,
// First argument of a block call is a generic block literal casted to
// generic void pointer, i.e. i8 addrspace(4)*
+ llvm::Type *GenericVoidPtrTy =
+ CGM.getOpenCLRuntime().getGenericVoidPointerType();
llvm::Value *BlockDescriptor = Builder.CreatePointerCast(
- BlockPtr, CGM.getOpenCLRuntime().getGenericVoidPointerType());
+ BlockPtr, GenericVoidPtrTy);
QualType VoidPtrQualTy = Ctx.getPointerType(
Ctx.getAddrSpaceQualType(Ctx.VoidTy, LangAS::opencl_generic));
Args.add(RValue::get(BlockDescriptor), VoidPtrQualTy);
@@ -1279,7 +1205,8 @@ RValue CodeGenFunction::EmitBlockCallExpr(const CallExpr *E,
Func = CGM.getOpenCLRuntime().getInvokeFunction(E->getCallee());
else {
llvm::Value *FuncPtr = Builder.CreateStructGEP(GenBlockTy, BlockPtr, 2);
- Func = Builder.CreateAlignedLoad(FuncPtr, getPointerAlign());
+ Func = Builder.CreateAlignedLoad(GenericVoidPtrTy, FuncPtr,
+ getPointerAlign());
}
} else {
// Bitcast the block literal to a generic block literal.
@@ -1295,7 +1222,7 @@ RValue CodeGenFunction::EmitBlockCallExpr(const CallExpr *E,
EmitCallArgs(Args, FnType->getAs<FunctionProtoType>(), E->arguments());
// Load the function.
- Func = Builder.CreateAlignedLoad(FuncPtr, getPointerAlign());
+ Func = Builder.CreateAlignedLoad(VoidPtrTy, FuncPtr, getPointerAlign());
}
const FunctionType *FuncTy = FnType->castAs<FunctionType>();
@@ -1448,7 +1375,8 @@ static llvm::Constant *buildGlobalBlock(CodeGenModule &CGM,
llvm::IRBuilder<> b(llvm::BasicBlock::Create(CGM.getLLVMContext(), "entry",
Init));
b.CreateAlignedStore(CGM.getNSConcreteGlobalBlock(),
- b.CreateStructGEP(literal, 0), CGM.getPointerAlign().getQuantity());
+ b.CreateStructGEP(literal, 0),
+ CGM.getPointerAlign().getAsAlign());
b.CreateRetVoid();
// We can't use the normal LLVM global initialisation array, because we
// need to specify that this runs early in library initialisation.
@@ -1482,8 +1410,7 @@ void CodeGenFunction::setBlockContextParameter(const ImplicitParamDecl *D,
Address alloc = CreateMemTemp(D->getType(), D->getName() + ".addr");
Builder.CreateStore(arg, alloc);
if (CGDebugInfo *DI = getDebugInfo()) {
- if (CGM.getCodeGenOpts().getDebugInfo() >=
- codegenoptions::LimitedDebugInfo) {
+ if (CGM.getCodeGenOpts().hasReducedDebugInfo()) {
DI->setLocation(D->getLocation());
DI->EmitDeclareOfBlockLiteralArgVariable(
*BlockInfo, D->getName(), argNum,
@@ -1655,8 +1582,7 @@ CodeGenFunction::GenerateBlockFunction(GlobalDecl GD,
const VarDecl *variable = CI.getVariable();
DI->EmitLocation(Builder, variable->getLocation());
- if (CGM.getCodeGenOpts().getDebugInfo() >=
- codegenoptions::LimitedDebugInfo) {
+ if (CGM.getCodeGenOpts().hasReducedDebugInfo()) {
const CGBlockInfo::Capture &capture = blockInfo.getCapture(variable);
if (capture.isConstant()) {
auto addr = LocalDeclMap.find(variable)->second;
@@ -1976,7 +1902,7 @@ static void setBlockHelperAttributesVisibility(bool CapturesNonExternalType,
} else {
Fn->setVisibility(llvm::GlobalValue::HiddenVisibility);
Fn->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
- CGM.SetLLVMFunctionAttributes(GlobalDecl(), FI, Fn);
+ CGM.SetLLVMFunctionAttributes(GlobalDecl(), FI, Fn, /*IsThunk=*/false);
CGM.SetLLVMFunctionAttributesForDefinition(nullptr, Fn);
}
}
@@ -2032,11 +1958,13 @@ CodeGenFunction::GenerateCopyHelperFunction(const CGBlockInfo &blockInfo) {
FunctionDecl *FD = FunctionDecl::Create(
C, C.getTranslationUnitDecl(), SourceLocation(), SourceLocation(), II,
FunctionTy, nullptr, SC_Static, false, false);
-
setBlockHelperAttributesVisibility(blockInfo.CapturesNonExternalType, Fn, FI,
CGM);
+ // This is necessary to avoid inheriting the previous line number.
+ FD->setImplicit();
StartFunction(FD, ReturnTy, Fn, FI, args);
- ApplyDebugLocation NL{*this, blockInfo.getBlockExpr()->getBeginLoc()};
+ auto AL = ApplyDebugLocation::CreateArtificial(*this);
+
llvm::Type *structPtrTy = blockInfo.StructureType->getPointerTo();
Address src = GetAddrOfLocalVar(&SrcDecl);
@@ -2227,10 +2155,12 @@ CodeGenFunction::GenerateDestroyHelperFunction(const CGBlockInfo &blockInfo) {
setBlockHelperAttributesVisibility(blockInfo.CapturesNonExternalType, Fn, FI,
CGM);
+ // This is necessary to avoid inheriting the previous line number.
+ FD->setImplicit();
StartFunction(FD, ReturnTy, Fn, FI, args);
markAsIgnoreThreadCheckingAtRuntime(Fn);
- ApplyDebugLocation NL{*this, blockInfo.getBlockExpr()->getBeginLoc()};
+ auto AL = ApplyDebugLocation::CreateArtificial(*this);
llvm::Type *structPtrTy = blockInfo.StructureType->getPointerTo();
@@ -2770,7 +2700,7 @@ const BlockByrefInfo &CodeGenFunction::getBlockByrefInfo(const VarDecl *D) {
}
bool HasByrefExtendedLayout = false;
- Qualifiers::ObjCLifetime Lifetime;
+ Qualifiers::ObjCLifetime Lifetime = Qualifiers::OCL_None;
if (getContext().getByrefLifetime(Ty, Lifetime, HasByrefExtendedLayout) &&
HasByrefExtendedLayout) {
/// void *__byref_variable_layout;
@@ -2840,8 +2770,8 @@ void CodeGenFunction::emitByrefStructureInit(const AutoVarEmission &emission) {
const VarDecl &D = *emission.Variable;
QualType type = D.getType();
- bool HasByrefExtendedLayout;
- Qualifiers::ObjCLifetime ByrefLifetime;
+ bool HasByrefExtendedLayout = false;
+ Qualifiers::ObjCLifetime ByrefLifetime = Qualifiers::OCL_None;
bool ByRefHasLifetime =
getContext().getByrefLifetime(type, ByrefLifetime, HasByrefExtendedLayout);
@@ -2957,7 +2887,7 @@ static void configureBlocksRuntimeObject(CodeGenModule &CGM,
"expected Function or GlobalVariable");
const NamedDecl *ND = nullptr;
- for (const auto &Result : DC->lookup(&II))
+ for (const auto *Result : DC->lookup(&II))
if ((ND = dyn_cast<FunctionDecl>(Result)) ||
(ND = dyn_cast<VarDecl>(Result)))
break;
@@ -3009,9 +2939,8 @@ llvm::Constant *CodeGenModule::getNSConcreteGlobalBlock() {
if (NSConcreteGlobalBlock)
return NSConcreteGlobalBlock;
- NSConcreteGlobalBlock = GetOrCreateLLVMGlobal("_NSConcreteGlobalBlock",
- Int8PtrTy->getPointerTo(),
- nullptr);
+ NSConcreteGlobalBlock =
+ GetOrCreateLLVMGlobal("_NSConcreteGlobalBlock", Int8PtrTy, 0, nullptr);
configureBlocksRuntimeObject(*this, NSConcreteGlobalBlock);
return NSConcreteGlobalBlock;
}
@@ -3020,9 +2949,8 @@ llvm::Constant *CodeGenModule::getNSConcreteStackBlock() {
if (NSConcreteStackBlock)
return NSConcreteStackBlock;
- NSConcreteStackBlock = GetOrCreateLLVMGlobal("_NSConcreteStackBlock",
- Int8PtrTy->getPointerTo(),
- nullptr);
+ NSConcreteStackBlock =
+ GetOrCreateLLVMGlobal("_NSConcreteStackBlock", Int8PtrTy, 0, nullptr);
configureBlocksRuntimeObject(*this, NSConcreteStackBlock);
return NSConcreteStackBlock;
}