diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/AST/Decl.cpp | 8 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGBlocks.cpp | 28 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGClass.cpp | 2 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGDecl.cpp | 19 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGExpr.cpp | 4 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenFunction.h | 11 | ||||
-rw-r--r-- | clang/lib/Sema/ScopeInfo.cpp | 2 | ||||
-rw-r--r-- | clang/lib/Sema/Sema.cpp | 59 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 33 | ||||
-rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 3 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTReaderDecl.cpp | 1 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTWriterDecl.cpp | 3 |
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) |