summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/AST/Decl.cpp8
-rw-r--r--clang/lib/CodeGen/CGBlocks.cpp28
-rw-r--r--clang/lib/CodeGen/CGClass.cpp2
-rw-r--r--clang/lib/CodeGen/CGDecl.cpp19
-rw-r--r--clang/lib/CodeGen/CGExpr.cpp4
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.h11
-rw-r--r--clang/lib/Sema/ScopeInfo.cpp2
-rw-r--r--clang/lib/Sema/Sema.cpp59
-rw-r--r--clang/lib/Sema/SemaDecl.cpp33
-rw-r--r--clang/lib/Sema/SemaExpr.cpp3
-rw-r--r--clang/lib/Serialization/ASTReaderDecl.cpp1
-rw-r--r--clang/lib/Serialization/ASTWriterDecl.cpp3
12 files changed, 57 insertions, 116 deletions
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index 5a64c67f9b8..272e49a7997 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -2361,14 +2361,6 @@ static DeclT *getDefinitionOrSelf(DeclT *D) {
return D;
}
-bool VarDecl::isEscapingByref() const {
- return hasAttr<BlocksAttr>() && NonParmVarDeclBits.EscapingByref;
-}
-
-bool VarDecl::isNonEscapingByref() const {
- return hasAttr<BlocksAttr>() && !NonParmVarDeclBits.EscapingByref;
-}
-
VarDecl *VarDecl::getTemplateInstantiationPattern() const {
// If it's a variable template specialization, find the template or partial
// specialization from which it was instantiated.
diff --git a/clang/lib/CodeGen/CGBlocks.cpp b/clang/lib/CodeGen/CGBlocks.cpp
index 7230e4e40ad..dae148cbd1e 100644
--- a/clang/lib/CodeGen/CGBlocks.cpp
+++ b/clang/lib/CodeGen/CGBlocks.cpp
@@ -493,11 +493,7 @@ static QualType getCaptureFieldType(const CodeGenFunction &CGF,
return CGF.BlockInfo->getCapture(VD).fieldType();
if (auto *FD = CGF.LambdaCaptureFields.lookup(VD))
return FD->getType();
- // If the captured variable is a non-escaping __block variable, the field
- // type is the reference type. If the variable is a __block variable that
- // already has a reference type, the field type is the variable's type.
- return VD->isNonEscapingByref() ?
- CGF.getContext().getLValueReferenceType(VD->getType()) : VD->getType();
+ return VD->getType();
}
/// Compute the layout of the given block. Attempts to lay the block
@@ -553,7 +549,7 @@ static void computeBlockInfo(CodeGenModule &CGM, CodeGenFunction *CGF,
for (const auto &CI : block->captures()) {
const VarDecl *variable = CI.getVariable();
- if (CI.isEscapingByref()) {
+ if (CI.isByRef()) {
// We have to copy/dispose of the __block reference.
info.NeedsCopyDispose = true;
@@ -1036,7 +1032,7 @@ llvm::Value *CodeGenFunction::EmitBlockLiteral(const CGBlockInfo &blockInfo) {
// The lambda capture in a lambda's conversion-to-block-pointer is
// special; we'll simply emit it directly.
src = Address::invalid();
- } else if (CI.isEscapingByref()) {
+ } else if (CI.isByRef()) {
if (BlockInfo && CI.isNested()) {
// We need to use the capture from the enclosing block.
const CGBlockInfo::Capture &enclosingCapture =
@@ -1064,7 +1060,7 @@ llvm::Value *CodeGenFunction::EmitBlockLiteral(const CGBlockInfo &blockInfo) {
// the block field. There's no need to chase the forwarding
// pointer at this point, since we're building something that will
// live a shorter life than the stack byref anyway.
- if (CI.isEscapingByref()) {
+ if (CI.isByRef()) {
// Get a void* that points to the byref struct.
llvm::Value *byrefPointer;
if (CI.isNested())
@@ -1283,7 +1279,8 @@ RValue CodeGenFunction::EmitBlockCallExpr(const CallExpr *E,
return EmitCall(FnInfo, Callee, ReturnValue, Args);
}
-Address CodeGenFunction::GetAddrOfBlockDecl(const VarDecl *variable) {
+Address CodeGenFunction::GetAddrOfBlockDecl(const VarDecl *variable,
+ bool isByRef) {
assert(BlockInfo && "evaluating block ref without block information?");
const CGBlockInfo::Capture &capture = BlockInfo->getCapture(variable);
@@ -1294,7 +1291,7 @@ Address CodeGenFunction::GetAddrOfBlockDecl(const VarDecl *variable) {
Builder.CreateStructGEP(LoadBlockStruct(), capture.getIndex(),
capture.getOffset(), "block.capture.addr");
- if (variable->isEscapingByref()) {
+ if (isByRef) {
// addr should be a void** right now. Load, then cast the result
// to byref*.
@@ -1308,10 +1305,6 @@ Address CodeGenFunction::GetAddrOfBlockDecl(const VarDecl *variable) {
variable->getName());
}
- assert((!variable->isNonEscapingByref() ||
- capture.fieldType()->isReferenceType()) &&
- "the capture field of a non-escaping variable should have a "
- "reference type");
if (capture.fieldType()->isReferenceType())
addr = EmitLoadOfReference(MakeAddrLValue(addr, capture.fieldType()));
@@ -1663,7 +1656,7 @@ computeCopyInfoForBlockCapture(const BlockDecl::Capture &CI, QualType T,
return std::make_pair(BlockCaptureEntityKind::CXXRecord, BlockFieldFlags());
}
BlockFieldFlags Flags;
- if (CI.isEscapingByref()) {
+ if (CI.isByRef()) {
Flags = BLOCK_FIELD_IS_BYREF;
if (T.isObjCGCWeak())
Flags |= BLOCK_FIELD_IS_WEAK;
@@ -2109,7 +2102,7 @@ getBlockFieldFlagsForObjCObjectPointer(const BlockDecl::Capture &CI,
static std::pair<BlockCaptureEntityKind, BlockFieldFlags>
computeDestroyInfoForBlockCapture(const BlockDecl::Capture &CI, QualType T,
const LangOptions &LangOpts) {
- if (CI.isEscapingByref()) {
+ if (CI.isByRef()) {
BlockFieldFlags Flags = BLOCK_FIELD_IS_BYREF;
if (T.isObjCGCWeak())
Flags |= BLOCK_FIELD_IS_WEAK;
@@ -2571,9 +2564,6 @@ BlockByrefHelpers *
CodeGenFunction::buildByrefHelpers(llvm::StructType &byrefType,
const AutoVarEmission &emission) {
const VarDecl &var = *emission.Variable;
- assert(var.isEscapingByref() &&
- "only escaping __block variables need byref helpers");
-
QualType type = var.getType();
auto &byrefInfo = getBlockByrefInfo(&var);
diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp
index aca0fd6f6e3..468d81cbbb7 100644
--- a/clang/lib/CodeGen/CGClass.cpp
+++ b/clang/lib/CodeGen/CGClass.cpp
@@ -2839,7 +2839,7 @@ void CodeGenFunction::EmitLambdaBlockInvokeBody() {
CallArgList CallArgs;
QualType ThisType = getContext().getPointerType(getContext().getRecordType(Lambda));
- Address ThisPtr = GetAddrOfBlockDecl(variable);
+ Address ThisPtr = GetAddrOfBlockDecl(variable, false);
CallArgs.add(RValue::get(ThisPtr.getPointer()), ThisType);
// Add the rest of the parameters.
diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp
index e4f5d430f26..e74066ef43a 100644
--- a/clang/lib/CodeGen/CGDecl.cpp
+++ b/clang/lib/CodeGen/CGDecl.cpp
@@ -1125,8 +1125,8 @@ CodeGenFunction::EmitAutoVarAlloca(const VarDecl &D) {
AutoVarEmission emission(D);
- bool isEscapingByRef = D.isEscapingByref();
- emission.IsEscapingByRef = isEscapingByRef;
+ bool isByRef = D.hasAttr<BlocksAttr>();
+ emission.IsByRef = isByRef;
CharUnits alignment = getContext().getDeclAlign(&D);
@@ -1165,8 +1165,8 @@ CodeGenFunction::EmitAutoVarAlloca(const VarDecl &D) {
// in OpenCL.
if ((!getLangOpts().OpenCL ||
Ty.getAddressSpace() == LangAS::opencl_constant) &&
- (CGM.getCodeGenOpts().MergeAllConstants && !NRVO &&
- !isEscapingByRef && CGM.isTypeConstant(Ty, true))) {
+ (CGM.getCodeGenOpts().MergeAllConstants && !NRVO && !isByRef &&
+ CGM.isTypeConstant(Ty, true))) {
EmitStaticVarDecl(D, llvm::GlobalValue::InternalLinkage);
// Signal this condition to later callbacks.
@@ -1218,7 +1218,7 @@ CodeGenFunction::EmitAutoVarAlloca(const VarDecl &D) {
} else {
CharUnits allocaAlignment;
llvm::Type *allocaTy;
- if (isEscapingByRef) {
+ if (isByRef) {
auto &byrefInfo = getBlockByrefInfo(&D);
allocaTy = byrefInfo.Type;
allocaAlignment = byrefInfo.ByrefAlignment;
@@ -1418,7 +1418,7 @@ void CodeGenFunction::EmitAutoVarInit(const AutoVarEmission &emission) {
}
// Initialize the structure of a __block variable.
- if (emission.IsEscapingByRef)
+ if (emission.IsByRef)
emitByrefStructureInit(emission);
// Initialize the variable here if it doesn't have a initializer and it is a
@@ -1428,7 +1428,7 @@ void CodeGenFunction::EmitAutoVarInit(const AutoVarEmission &emission) {
type.isNonTrivialToPrimitiveDefaultInitialize() ==
QualType::PDIK_Struct) {
LValue Dst = MakeAddrLValue(emission.getAllocatedAddress(), type);
- if (emission.IsEscapingByRef)
+ if (emission.IsByRef)
drillIntoBlockVariable(*this, Dst, &D);
defaultInitNonTrivialCStructVar(Dst);
return;
@@ -1440,7 +1440,7 @@ void CodeGenFunction::EmitAutoVarInit(const AutoVarEmission &emission) {
// Check whether this is a byref variable that's potentially
// captured and moved by its own initializer. If so, we'll need to
// emit the initializer first, then copy into the variable.
- bool capturedByInit = emission.IsEscapingByRef && isCapturedBy(D, Init);
+ bool capturedByInit = emission.IsByRef && isCapturedBy(D, Init);
Address Loc =
capturedByInit ? emission.Addr : emission.getObjectAddress(*this);
@@ -1634,8 +1634,7 @@ void CodeGenFunction::EmitAutoVarCleanups(const AutoVarEmission &emission) {
// If this is a block variable, call _Block_object_destroy
// (on the unforwarded address). Don't enter this cleanup if we're in pure-GC
// mode.
- if (emission.IsEscapingByRef &&
- CGM.getLangOpts().getGC() != LangOptions::GCOnly) {
+ if (emission.IsByRef && CGM.getLangOpts().getGC() != LangOptions::GCOnly) {
BlockFieldFlags Flags = BLOCK_FIELD_IS_BYREF;
if (emission.Variable->getType().isObjCGCWeak())
Flags |= BLOCK_FIELD_IS_WEAK;
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index 028aa963cda..b74937e9ca1 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -2486,7 +2486,7 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {
}
assert(isa<BlockDecl>(CurCodeDecl));
- Address addr = GetAddrOfBlockDecl(VD);
+ Address addr = GetAddrOfBlockDecl(VD, VD->hasAttr<BlocksAttr>());
return MakeAddrLValue(addr, T, AlignmentSource::Decl);
}
}
@@ -2538,7 +2538,7 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {
}
// Drill into block byref variables.
- bool isBlockByref = VD->isEscapingByref();
+ bool isBlockByref = VD->hasAttr<BlocksAttr>();
if (isBlockByref) {
addr = emitBlockByrefAddress(addr, VD);
}
diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h
index 54289cdd6de..6ea2d75b318 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -1787,7 +1787,7 @@ public:
llvm::Value *ptr);
Address LoadBlockStruct();
- Address GetAddrOfBlockDecl(const VarDecl *var);
+ Address GetAddrOfBlockDecl(const VarDecl *var, bool ByRef);
/// BuildBlockByrefAddress - Computes the location of the
/// data in a variable which is declared as __block.
@@ -2683,9 +2683,8 @@ public:
llvm::Value *NRVOFlag;
- /// True if the variable is a __block variable that is captured by an
- /// escaping block.
- bool IsEscapingByRef;
+ /// True if the variable is a __block variable.
+ bool IsByRef;
/// True if the variable is of aggregate type and has a constant
/// initializer.
@@ -2705,7 +2704,7 @@ public:
AutoVarEmission(const VarDecl &variable)
: Variable(&variable), Addr(Address::invalid()), NRVOFlag(nullptr),
- IsEscapingByRef(false), IsConstantAggregate(false),
+ IsByRef(false), IsConstantAggregate(false),
SizeForLifetimeMarkers(nullptr), AllocaAddr(Address::invalid()) {}
bool wasEmittedAsGlobal() const { return !Addr.isValid(); }
@@ -2735,7 +2734,7 @@ public:
/// Note that this does not chase the forwarding pointer for
/// __block decls.
Address getObjectAddress(CodeGenFunction &CGF) const {
- if (!IsEscapingByRef) return Addr;
+ if (!IsByRef) return Addr;
return CGF.emitBlockByrefAddress(Addr, Variable, /*forward*/ false);
}
diff --git a/clang/lib/Sema/ScopeInfo.cpp b/clang/lib/Sema/ScopeInfo.cpp
index bd8db6f4ed9..62a83ccb70a 100644
--- a/clang/lib/Sema/ScopeInfo.cpp
+++ b/clang/lib/Sema/ScopeInfo.cpp
@@ -54,8 +54,6 @@ void FunctionScopeInfo::Clear() {
PossiblyUnreachableDiags.clear();
WeakObjectUses.clear();
ModifiedNonNullParams.clear();
- Blocks.clear();
- ByrefBlockVars.clear();
}
static const NamedDecl *getBestPropertyDecl(const ObjCPropertyRefExpr *PropE) {
diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp
index ccbbe50093b..d777afe9811 100644
--- a/clang/lib/Sema/Sema.cpp
+++ b/clang/lib/Sema/Sema.cpp
@@ -1401,68 +1401,9 @@ void Sema::RecordParsingTemplateParameterDepth(unsigned Depth) {
"Remove assertion if intentionally called in a non-lambda context.");
}
-// Check that the type of the VarDecl has an accessible copy constructor and
-// resolve its destructor's exception spefication.
-static void checkEscapingByref(VarDecl *VD, Sema &S) {
- QualType T = VD->getType();
- EnterExpressionEvaluationContext scope(
- S, Sema::ExpressionEvaluationContext::PotentiallyEvaluated);
- SourceLocation Loc = VD->getLocation();
- Expr *VarRef = new (S.Context) DeclRefExpr(VD, false, T, VK_LValue, Loc);
- ExprResult Result = S.PerformMoveOrCopyInitialization(
- InitializedEntity::InitializeBlock(Loc, T, false), VD, VD->getType(),
- VarRef, /*AllowNRVO=*/true);
- if (!Result.isInvalid()) {
- Result = S.MaybeCreateExprWithCleanups(Result);
- Expr *Init = Result.getAs<Expr>();
- S.Context.setBlockVarCopyInit(VD, Init, S.canThrow(Init));
- }
-
- // The destructor's exception spefication is needed when IRGen generates
- // block copy/destroy functions. Resolve it here.
- if (const CXXRecordDecl *RD = T->getAsCXXRecordDecl())
- if (CXXDestructorDecl *DD = RD->getDestructor()) {
- auto *FPT = DD->getType()->getAs<FunctionProtoType>();
- S.ResolveExceptionSpec(Loc, FPT);
- }
-}
-
-static void markEscapingByrefs(const FunctionScopeInfo &FSI, Sema &S) {
- // Set the EscapingByref flag of __block variables captured by
- // escaping blocks.
- for (const BlockDecl *BD : FSI.Blocks) {
- if (BD->doesNotEscape())
- continue;
- for (const BlockDecl::Capture &BC : BD->captures()) {
- VarDecl *VD = BC.getVariable();
- if (VD->hasAttr<BlocksAttr>())
- VD->setEscapingByref();
- }
- }
-
- for (VarDecl *VD : FSI.ByrefBlockVars) {
- // __block variables might require us to capture a copy-initializer.
- if (!VD->isEscapingByref())
- continue;
- // It's currently invalid to ever have a __block variable with an
- // array type; should we diagnose that here?
- // Regardless, we don't want to ignore array nesting when
- // constructing this copy.
- if (VD->getType()->isStructureOrClassType())
- checkEscapingByref(VD, S);
- }
-}
-
void Sema::PopFunctionScopeInfo(const AnalysisBasedWarnings::Policy *WP,
const Decl *D, const BlockExpr *blkExpr) {
assert(!FunctionScopes.empty() && "mismatched push/pop!");
-
- // This function shouldn't be called after popping the current function scope.
- // markEscapingByrefs calls PerformMoveOrCopyInitialization, which can call
- // PushFunctionScope, which can cause clearing out PreallocatedFunctionScope
- // when FunctionScopes is empty.
- markEscapingByrefs(*FunctionScopes.back(), *this);
-
FunctionScopeInfo *Scope = FunctionScopes.pop_back_val();
if (LangOpts.OpenMP)
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 441c54dc358..f5ba87f635d 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -11826,8 +11826,37 @@ void Sema::CheckCompleteVariableDeclaration(VarDecl *var) {
QualType type = var->getType();
if (type->isDependentType()) return;
- if (var->hasAttr<BlocksAttr>())
- getCurFunction()->addByrefBlockVar(var);
+ // __block variables might require us to capture a copy-initializer.
+ if (var->hasAttr<BlocksAttr>()) {
+ // It's currently invalid to ever have a __block variable with an
+ // array type; should we diagnose that here?
+
+ // Regardless, we don't want to ignore array nesting when
+ // constructing this copy.
+ if (type->isStructureOrClassType()) {
+ EnterExpressionEvaluationContext scope(
+ *this, ExpressionEvaluationContext::PotentiallyEvaluated);
+ SourceLocation poi = var->getLocation();
+ Expr *varRef =new (Context) DeclRefExpr(var, false, type, VK_LValue, poi);
+ ExprResult result
+ = PerformMoveOrCopyInitialization(
+ InitializedEntity::InitializeBlock(poi, type, false),
+ var, var->getType(), varRef, /*AllowNRVO=*/true);
+ if (!result.isInvalid()) {
+ result = MaybeCreateExprWithCleanups(result);
+ Expr *init = result.getAs<Expr>();
+ Context.setBlockVarCopyInit(var, init, canThrow(init));
+ }
+
+ // The destructor's exception spefication is needed when IRGen generates
+ // block copy/destroy functions. Resolve it here.
+ if (const CXXRecordDecl *RD = type->getAsCXXRecordDecl())
+ if (CXXDestructorDecl *DD = RD->getDestructor()) {
+ auto *FPT = DD->getType()->getAs<FunctionProtoType>();
+ FPT = ResolveExceptionSpec(poi, FPT);
+ }
+ }
+ }
Expr *Init = var->getInit();
bool IsGlobal = GlobalStorage && !var->isStaticLocal();
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 5b5b8220bfc..26fb107688f 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -13530,9 +13530,6 @@ ExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc,
}
}
- if (getCurFunction())
- getCurFunction()->addBlock(BSI->TheDecl);
-
return Result;
}
diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp
index d22a98c13c2..6d541aa9885 100644
--- a/clang/lib/Serialization/ASTReaderDecl.cpp
+++ b/clang/lib/Serialization/ASTReaderDecl.cpp
@@ -1365,7 +1365,6 @@ ASTDeclReader::RedeclarableResult ASTDeclReader::VisitVarDeclImpl(VarDecl *VD) {
VD->NonParmVarDeclBits.IsInitCapture = Record.readInt();
VD->NonParmVarDeclBits.PreviousDeclInSameBlockScope = Record.readInt();
VD->NonParmVarDeclBits.ImplicitParamKind = Record.readInt();
- VD->NonParmVarDeclBits.EscapingByref = Record.readInt();
}
auto VarLinkage = Linkage(Record.readInt());
VD->setCachedLinkage(VarLinkage);
diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp
index 5ec11dda8a9..e120f14b81e 100644
--- a/clang/lib/Serialization/ASTWriterDecl.cpp
+++ b/clang/lib/Serialization/ASTWriterDecl.cpp
@@ -938,7 +938,6 @@ void ASTDeclWriter::VisitVarDecl(VarDecl *D) {
Record.push_back(static_cast<unsigned>(IPD->getParameterKind()));
else
Record.push_back(0);
- Record.push_back(D->isEscapingByref());
}
Record.push_back(D->getLinkageInternal());
@@ -1009,7 +1008,6 @@ void ASTDeclWriter::VisitVarDecl(VarDecl *D) {
!D->isInitCapture() &&
!D->isPreviousDeclInSameBlockScope() &&
!(D->hasAttr<BlocksAttr>() && D->getType()->getAsCXXRecordDecl()) &&
- !D->isEscapingByref() &&
D->getStorageDuration() != SD_Static &&
!D->getMemberSpecializationInfo())
AbbrevToUse = Writer.getDeclVarAbbrev();
@@ -2074,7 +2072,6 @@ void ASTWriter::WriteDeclAbbrevs() {
Abv->Add(BitCodeAbbrevOp(0)); // isInitCapture
Abv->Add(BitCodeAbbrevOp(0)); // isPrevDeclInSameScope
Abv->Add(BitCodeAbbrevOp(0)); // ImplicitParamKind
- Abv->Add(BitCodeAbbrevOp(0)); // EscapingByref
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // Linkage
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // IsInitICE (local)
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // VarKind (local enum)
OpenPOWER on IntegriCloud