This is an archive of the discontinued LLVM Phabricator instance.

[clang-tidy] Support detecting for-range loop in inefficient-vector-operation check.
ClosedPublic

Authored by hokein on Apr 24 2017, 8:38 AM.

Diff Detail

Repository
rL LLVM

Event Timeline

hokein created this revision.Apr 24 2017, 8:38 AM
Eugene.Zelenko added inline comments.
docs/clang-tidy/checks/performance-inefficient-vector-operation.rst
6 ↗(On Diff #96402)

Please use `` to highlight language elements. Same below.

hokein updated this revision to Diff 96516.Apr 25 2017, 12:58 AM
hokein marked an inline comment as done.

Fix doc.

alexfh edited edge metadata.Apr 26 2017, 6:57 AM

Cool! A few nits.

clang-tidy/performance/InefficientVectorOperationCheck.cpp
56 ↗(On Diff #96516)

I'd just inline the expression and remove the local variable, since it doesn't seem to bring any benefits.

103 ↗(On Diff #96516)

s/Interested/Interesting/

129 ↗(On Diff #96516)

It might be valuable to support more complex expressions here, though it would require more involved fixes, e.g.

for (const auto& e : *source)
  v.push_back(e);

->

v.reserve(source->size());
for (const auto& e : *source)
  v.push_back(e);

or even like this:

for (const auto& e : *some(complex)->container().expression())
  v.push_back(e);

->

const auto& source_container = *some(complex)->container().expression();
v.reserve(source_container.size());
for (const auto& e : source_container)
  v.push_back(e);

Maybe leave a FIXME for this?

152 ↗(On Diff #96516)

const Stmt *LoopStmt = ForLoop ? ForLoop : RangeLoop;

185 ↗(On Diff #96516)

No need to qualify StringRef and Lexer. Here and a couple of other instances in this function.

198 ↗(On Diff #96516)

Does the check handle destination vector not being empty before the push_back loop? We'd need to reserve destination.size() + source.size() items in this case.

If this is not handled yet, please add a FIXME.

hokein updated this revision to Diff 96738.Apr 26 2017, 7:22 AM
hokein marked 6 inline comments as done.

Address review comments.

Thanks for the comments!

clang-tidy/performance/InefficientVectorOperationCheck.cpp
129 ↗(On Diff #96516)

Nice brainstorm, added a FIXME.

152 ↗(On Diff #96516)

We can't do it because ForLoop and RangeLoop are different types.

198 ↗(On Diff #96516)

This case should not happen, because we only find the push_back loop before which there are no usages (defined as DeclRefExpr that refers to vector`v`) of the vector v.

alexfh accepted this revision.Apr 26 2017, 9:51 AM

LG

clang-tidy/performance/InefficientVectorOperationCheck.cpp
153 ↗(On Diff #96738)

nit: Please remove the extra space after the asterisk.

152 ↗(On Diff #96516)

Yup, static_cast<Stmt*> would be more ugly. This could still be shortened a bit:

const Stmt *LoopStmt = ForLoop;
if (!LoopStmt)
  LoopStmt = RangeLoop;

Not that it makes too much difference though. Up to you.

This revision is now accepted and ready to land.Apr 26 2017, 9:51 AM
hokein updated this revision to Diff 96775.Apr 26 2017, 9:55 AM
hokein marked 2 inline comments as done.

Address remaining nits.

This revision was automatically updated to reflect the committed changes.