aboutsummaryrefslogtreecommitdiff
path: root/clang-tidy/performance
diff options
context:
space:
mode:
authorHaojian Wu <hokein@google.com>2017-05-16 10:39:55 +0000
committerHaojian Wu <hokein@google.com>2017-05-16 10:39:55 +0000
commit18140c41ccaf948359c9ee26f1ef6e8ec7167946 (patch)
treec20a7e4945ea40fe8a68e6c5513e15b3d173cd56 /clang-tidy/performance
parentb63045dd3c77409cffac841f7e3f761e45befed3 (diff)
[clang-tidy] Add "emplace_back" detection in inefficient-vector-operation.
Reviewers: alexfh, aaron.ballman Reviewed By: alexfh Subscribers: cfe-commits, Prazek, malcolm.parsons, xazax.hun Tags: #clang-tools-extra Differential Revision: https://reviews.llvm.org/D33209 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@303157 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'clang-tidy/performance')
-rw-r--r--clang-tidy/performance/InefficientVectorOperationCheck.cpp36
1 files changed, 20 insertions, 16 deletions
diff --git a/clang-tidy/performance/InefficientVectorOperationCheck.cpp b/clang-tidy/performance/InefficientVectorOperationCheck.cpp
index 2f311da0..33c68f01 100644
--- a/clang-tidy/performance/InefficientVectorOperationCheck.cpp
+++ b/clang-tidy/performance/InefficientVectorOperationCheck.cpp
@@ -39,14 +39,14 @@ namespace {
// - VectorVarDeclName: 'v' in (as VarDecl).
// - VectorVarDeclStmatName: The entire 'std::vector<T> v;' statement (as
// DeclStmt).
-// - PushBackCallName: 'v.push_back(i)' (as cxxMemberCallExpr).
+// - PushBackOrEmplaceBackCallName: 'v.push_back(i)' (as cxxMemberCallExpr).
// - LoopInitVarName: 'i' (as VarDecl).
// - LoopEndExpr: '10+1' (as Expr).
static const char LoopCounterName[] = "for_loop_counter";
static const char LoopParentName[] = "loop_parent";
static const char VectorVarDeclName[] = "vector_var_decl";
static const char VectorVarDeclStmtName[] = "vector_var_decl_stmt";
-static const char PushBackCallName[] = "push_back_call";
+static const char PushBackOrEmplaceBackCallName[] = "append_call";
static const char LoopInitVarName[] = "loop_init_var";
static const char LoopEndExprName[] = "loop_end_expr";
@@ -81,13 +81,13 @@ void InefficientVectorOperationCheck::registerMatchers(MatchFinder *Finder) {
const auto VectorVarDecl =
varDecl(hasInitializer(VectorDefaultConstructorCall))
.bind(VectorVarDeclName);
- const auto PushBackCallExpr =
+ const auto VectorAppendCallExpr =
cxxMemberCallExpr(
- callee(cxxMethodDecl(hasName("push_back"))), on(hasType(VectorDecl)),
+ callee(cxxMethodDecl(hasAnyName("push_back", "emplace_back"))),
+ on(hasType(VectorDecl)),
onImplicitObjectArgument(declRefExpr(to(VectorVarDecl))))
- .bind(PushBackCallName);
- const auto PushBackCall =
- expr(anyOf(PushBackCallExpr, exprWithCleanups(has(PushBackCallExpr))));
+ .bind(PushBackOrEmplaceBackCallName);
+ const auto VectorAppendCall = expr(ignoringImplicit(VectorAppendCallExpr));
const auto VectorVarDefStmt =
declStmt(hasSingleDecl(equalsBoundNode(VectorVarDeclName)))
.bind(VectorVarDeclStmtName);
@@ -98,9 +98,11 @@ void InefficientVectorOperationCheck::registerMatchers(MatchFinder *Finder) {
const auto RefersToLoopVar = ignoringParenImpCasts(
declRefExpr(to(varDecl(equalsBoundNode(LoopInitVarName)))));
- // Matchers for the loop whose body has only 1 push_back calling statement.
- const auto HasInterestingLoopBody = hasBody(anyOf(
- compoundStmt(statementCountIs(1), has(PushBackCall)), PushBackCall));
+ // Matchers for the loop whose body has only 1 push_back/emplace_back calling
+ // statement.
+ const auto HasInterestingLoopBody =
+ hasBody(anyOf(compoundStmt(statementCountIs(1), has(VectorAppendCall)),
+ VectorAppendCall));
const auto InInterestingCompoundStmt =
hasParent(compoundStmt(has(VectorVarDefStmt)).bind(LoopParentName));
@@ -145,8 +147,8 @@ void InefficientVectorOperationCheck::check(
const auto *ForLoop = Result.Nodes.getNodeAs<ForStmt>(LoopCounterName);
const auto *RangeLoop =
Result.Nodes.getNodeAs<CXXForRangeStmt>(RangeLoopName);
- const auto *PushBackCall =
- Result.Nodes.getNodeAs<CXXMemberCallExpr>(PushBackCallName);
+ const auto *VectorAppendCall =
+ Result.Nodes.getNodeAs<CXXMemberCallExpr>(PushBackOrEmplaceBackCallName);
const auto *LoopEndExpr = Result.Nodes.getNodeAs<Expr>(LoopEndExprName);
const auto *LoopParent = Result.Nodes.getNodeAs<CompoundStmt>(LoopParentName);
@@ -173,7 +175,7 @@ void InefficientVectorOperationCheck::check(
llvm::StringRef VectorVarName = Lexer::getSourceText(
CharSourceRange::getTokenRange(
- PushBackCall->getImplicitObjectArgument()->getSourceRange()),
+ VectorAppendCall->getImplicitObjectArgument()->getSourceRange()),
SM, Context->getLangOpts());
std::string ReserveStmt;
@@ -197,9 +199,11 @@ void InefficientVectorOperationCheck::check(
ReserveStmt = (VectorVarName + ".reserve(" + LoopEndSource + ");\n").str();
}
- auto Diag = diag(PushBackCall->getLocStart(),
- "'push_back' is called inside a loop; "
- "consider pre-allocating the vector capacity before the loop");
+ auto Diag =
+ diag(VectorAppendCall->getLocStart(),
+ "%0 is called inside a loop; "
+ "consider pre-allocating the vector capacity before the loop")
+ << VectorAppendCall->getMethodDecl()->getDeclName();
if (!ReserveStmt.empty())
Diag << FixItHint::CreateInsertion(LoopStmt->getLocStart(), ReserveStmt);