Introduce a check which suggests when it might be helpful to use "emplace" methods. The initial version only works with std::vector and push_back (e.g V.push_back(T(1, 2)) -> V.emplace_back(1, 2)). It could be extended to work with other containers and methods.
Details
Diff Detail
Event Timeline
- Fix handling of push_back(X(/* comment */)).
- Don't try to emit a warning when the callee comes from a macro expansion.
- Get rid of a weird/wrong comment about checking for "default constructors".
As a side note, I'd appreciate advice on how to apply this check to the llvm codebase (via some kind of cmake invocation?) and gather numbers.
Missing the .rst file.
Did you use the check_clang_tidy.py script to create the template?
clang-tidy/performance/EmplaceCheck.cpp | ||
---|---|---|
25 | This change can potentially break exception guarantees of the code. | |
26 | Just say functionDecl(hasName("std::vector::push_back")) and you can remove the type check. | |
84 | It's usually preferable, and sometimes easier to write, to do erases instead of replacements. | |
88 | What you want is getTokenRange(Call->getCallee()->getSourceRange()) | |
clang-tidy/performance/EmplaceCheck.h | ||
18 | Needs a comment | |
19 | What's the scope? | |
test/clang-tidy/performance-emplace-into-containers.cpp | ||
26 | We have to make sure the arguments are compatible with perfect forwarding. v.push_back(Y({})); // {} can't be passed to perfect forwarding v.push_back(Y(NULL)); // NULL can't be passed to perfect forwarding | |
28 | At least one of the cases should match the whole exact message, to make sure it is correct. | |
42 | We should also test implicit conversions. v1.push_back(0); | |
46 | Why not? | |
50 | We need tests for copy/move construction. v1.push_back(x); // should not be changed v1.push_back(FunctionThatReturnsX()); // should not be changed |
clang-tidy/performance/EmplaceCheck.cpp | ||
---|---|---|
26 | Should use "::std::vector::push_back" just to be sure it doesn't explode when evil people have: namespace frobble { namespace std { template <typename T> class vector { void push_back(const T&); }; } } | |
38 | I think this goes against our coding standards and should be return StringRef();. |
Yep, I think the best idea is to take all the goodies from this check and add it to modernize-use-emplace
Thanks for the valuable feedback! I'll keep all of it in mind when writing checks in the future.
I'm closing this revision since D20964 is in.
Needs a comment