diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Sema/Scope.cpp | 24 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 33 | ||||
-rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 10 | ||||
-rw-r--r-- | clang/lib/Sema/SemaStmt.cpp | 9 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTReaderDecl.cpp | 2 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTWriterDecl.cpp | 4 |
6 files changed, 31 insertions, 51 deletions
diff --git a/clang/lib/Sema/Scope.cpp b/clang/lib/Sema/Scope.cpp index eae5a328bfa..5a46ba26d29 100644 --- a/clang/lib/Sema/Scope.cpp +++ b/clang/lib/Sema/Scope.cpp @@ -92,7 +92,6 @@ void Scope::Init(Scope *parent, unsigned flags) { UsingDirectives.clear(); Entity = nullptr; ErrorTrap.reset(); - NRVO.setPointerAndInt(nullptr, 0); } bool Scope::containedInPrototypeScope() const { @@ -119,19 +118,15 @@ void Scope::AddFlags(unsigned FlagsToSet) { Flags |= FlagsToSet; } -void Scope::mergeNRVOIntoParent() { - if (VarDecl *Candidate = NRVO.getPointer()) { - if (isDeclScope(Candidate)) - Candidate->setNRVOVariable(true); +void Scope::setNRVOCandidate(VarDecl *Candidate) { + for (Decl *D : DeclsInScope) { + VarDecl *VD = dyn_cast<VarDecl>(D); + if (VD && VD != Candidate && VD->isNRVOCandidate()) + VD->setNRVOVariable(false); } - if (getEntity()) - return; - - if (NRVO.getInt()) - getParent()->setNoNRVO(); - else if (NRVO.getPointer()) - getParent()->addNRVOCandidate(NRVO.getPointer()); + if (Scope *parent = getParent()) + parent->setNRVOCandidate(Candidate); } LLVM_DUMP_METHOD void Scope::dump() const { dumpImpl(llvm::errs()); } @@ -191,9 +186,4 @@ void Scope::dumpImpl(raw_ostream &OS) const { OS << "MSCurManglingNumber: " << getMSCurManglingNumber() << '\n'; if (const DeclContext *DC = getEntity()) OS << "Entity : (clang::DeclContext*)" << DC << '\n'; - - if (NRVO.getInt()) - OS << "NRVO not allowed\n"; - else if (NRVO.getPointer()) - OS << "NRVO candidate : (clang::VarDecl*)" << NRVO.getPointer() << '\n'; } diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 9a6a286db78..e0be9efe966 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -1798,8 +1798,6 @@ static void CheckPoppedLabel(LabelDecl *L, Sema &S) { } void Sema::ActOnPopScope(SourceLocation Loc, Scope *S) { - S->mergeNRVOIntoParent(); - if (S->decl_empty()) return; assert((S->getFlags() & (Scope::DeclScope | Scope::TemplateParamScope)) && "Scope shouldn't contain decls!"); @@ -12611,21 +12609,24 @@ Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D, /// optimization. /// /// Each of the variables that is subject to the named return value -/// optimization will be marked as NRVO variables in the AST, and any +/// optimization will be marked as NRVO variable candidates in the AST, and any /// return statement that has a marked NRVO variable as its NRVO candidate can /// use the named return value optimization. /// -/// This function applies a very simplistic algorithm for NRVO: if every return -/// statement in the scope of a variable has the same NRVO candidate, that -/// candidate is an NRVO variable. +/// This function applies a very simplistic algorithm for NRVO: if every +/// reachable return statement in the scope of a variable has the same NRVO +/// candidate, that candidate is an NRVO variable. void Sema::computeNRVO(Stmt *Body, FunctionScopeInfo *Scope) { - ReturnStmt **Returns = Scope->Returns.data(); + for (ReturnStmt *Return : Scope->Returns) { + const VarDecl *Candidate = Return->getNRVOCandidate(); + if (!Candidate) + continue; - for (unsigned I = 0, E = Scope->Returns.size(); I != E; ++I) { - if (const VarDecl *NRVOCandidate = Returns[I]->getNRVOCandidate()) { - if (!NRVOCandidate->isNRVOVariable()) - Returns[I]->setNRVOCandidate(nullptr); - } + if (Candidate->isNRVOCandidate()) + const_cast<VarDecl*>(Candidate)->setNRVOVariable(true); + + if (!Candidate->isNRVOVariable()) + Return->setNRVOCandidate(nullptr); } } @@ -12754,12 +12755,8 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body, else if (CXXDestructorDecl *Destructor = dyn_cast<CXXDestructorDecl>(FD)) MarkVTableUsed(FD->getLocation(), Destructor->getParent()); - // Try to apply the named return value optimization. We have to check - // if we can do this here because lambdas keep return statements around - // to deduce an implicit return type. - if (FD->getReturnType()->isRecordType() && - (!getLangOpts().CPlusPlus || !FD->isDependentContext())) - computeNRVO(Body, getCurFunction()); + // Try to apply the named return value optimization. + computeNRVO(Body, getCurFunction()); } // GNU warning -Wmissing-prototypes: diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index aeedd6b1691..220d6906954 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -13385,13 +13385,9 @@ ExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc, if (Body && getCurFunction()->HasPotentialAvailabilityViolations) DiagnoseUnguardedAvailabilityViolations(BSI->TheDecl); - // Try to apply the named return value optimization. We have to check again - // if we can do this, though, because blocks keep return statements around - // to deduce an implicit return type. - if (getLangOpts().CPlusPlus && RetTy->isRecordType() && - !BSI->TheDecl->isDependentContext()) - computeNRVO(Body, BSI); - + // Try to apply the named return value optimization. + computeNRVO(Body, BSI); + BlockExpr *Result = new (Context) BlockExpr(BSI->TheDecl, BlockTy); AnalysisBasedWarnings::Policy WP = AnalysisWarnings.getDefaultPolicy(); PopFunctionScopeInfo(&WP, Result->getBlockDecl(), Result); diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp index ccf25ee9ebe..04f51145104 100644 --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/lib/Sema/SemaStmt.cpp @@ -3455,12 +3455,9 @@ Sema::ActOnReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp, ExpressionEvaluationContext::DiscardedStatement) return R; - if (VarDecl *VD = - const_cast<VarDecl*>(cast<ReturnStmt>(R.get())->getNRVOCandidate())) { - CurScope->addNRVOCandidate(VD); - } else { - CurScope->setNoNRVO(); - } + VarDecl *VD = + const_cast<VarDecl*>(cast<ReturnStmt>(R.get())->getNRVOCandidate()); + CurScope->setNRVOCandidate(VD); CheckJumpOutOfSEHFinally(*this, ReturnLoc, *CurScope->getFnParent()); diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index a1ce26d27ca..699a98ce4f5 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -1326,7 +1326,7 @@ ASTDeclReader::RedeclarableResult ASTDeclReader::VisitVarDeclImpl(VarDecl *VD) { VD->NonParmVarDeclBits.IsThisDeclarationADemotedDefinition = Record.readInt(); VD->NonParmVarDeclBits.ExceptionVar = Record.readInt(); - VD->NonParmVarDeclBits.NRVOVariable = Record.readInt(); + VD->NonParmVarDeclBits.NRVOMode = Record.readInt(); VD->NonParmVarDeclBits.CXXForRangeDecl = Record.readInt(); VD->NonParmVarDeclBits.ObjCForDecl = Record.readInt(); VD->NonParmVarDeclBits.ARCPseudoStrong = Record.readInt(); diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp index cf35a2bc1fc..c1f983e5ce8 100644 --- a/clang/lib/Serialization/ASTWriterDecl.cpp +++ b/clang/lib/Serialization/ASTWriterDecl.cpp @@ -918,7 +918,7 @@ void ASTDeclWriter::VisitVarDecl(VarDecl *D) { if (!isa<ParmVarDecl>(D)) { Record.push_back(D->isThisDeclarationADemotedDefinition()); Record.push_back(D->isExceptionVariable()); - Record.push_back(D->isNRVOVariable()); + Record.push_back(D->getNRVOMode()); Record.push_back(D->isCXXForRangeDecl()); Record.push_back(D->isObjCForDecl()); Record.push_back(D->isARCPseudoStrong()); @@ -2031,7 +2031,7 @@ void ASTWriter::WriteDeclAbbrevs() { Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // InitStyle Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsThisDeclarationADemotedDefinition Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isExceptionVariable - Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isNRVOVariable + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // NRVOMode Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isCXXForRangeDecl Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isObjCForDecl Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isARCPseudoStrong |