forked from OSchip/llvm-project
[clang-tidy] Support replacements in macro arguments in misc-inefficient-algorithm
Summary: Support replacements in macro arguments in the misc-inefficient-algorithm check. Reviewers: klimek Subscribers: cfe-commits Differential Revision: http://reviews.llvm.org/D11677 llvm-svn: 243747
This commit is contained in:
parent
a2ce083d2d
commit
b4fbb173f0
|
@ -105,18 +105,41 @@ void InefficientAlgorithmCheck::check(const MatchFinder::MatchResult &Result) {
|
|||
const auto *IneffContExpr = Result.Nodes.getNodeAs<Expr>("IneffContExpr");
|
||||
FixItHint Hint;
|
||||
|
||||
if (!AlgCall->getLocStart().isMacroID() && !Maplike && CompatibleTypes) {
|
||||
SourceManager &SM = *Result.SourceManager;
|
||||
LangOptions LangOpts = Result.Context->getLangOpts();
|
||||
|
||||
CharSourceRange CallRange =
|
||||
CharSourceRange::getTokenRange(AlgCall->getSourceRange());
|
||||
|
||||
// FIXME: Create a common utility to extract a file range that the given token
|
||||
// sequence is exactly spelled at (without macro argument expansions etc.).
|
||||
// We can't use Lexer::makeFileCharRange here, because for
|
||||
//
|
||||
// #define F(x) x
|
||||
// x(a b c);
|
||||
//
|
||||
// it will return "x(a b c)", when given the range "a"-"c". It makes sense for
|
||||
// removals, but not for replacements.
|
||||
//
|
||||
// This code is over-simplified, but works for many real cases.
|
||||
if (SM.isMacroArgExpansion(CallRange.getBegin()) &&
|
||||
SM.isMacroArgExpansion(CallRange.getEnd())) {
|
||||
CallRange.setBegin(SM.getSpellingLoc(CallRange.getBegin()));
|
||||
CallRange.setEnd(SM.getSpellingLoc(CallRange.getEnd()));
|
||||
}
|
||||
|
||||
if (!CallRange.getBegin().isMacroID() && !Maplike && CompatibleTypes) {
|
||||
StringRef ContainerText = Lexer::getSourceText(
|
||||
CharSourceRange::getTokenRange(IneffContExpr->getSourceRange()), SM,
|
||||
LangOpts);
|
||||
StringRef ParamText = Lexer::getSourceText(
|
||||
CharSourceRange::getTokenRange(AlgParam->getSourceRange()), SM,
|
||||
LangOpts);
|
||||
std::string ReplacementText =
|
||||
(llvm::Twine(Lexer::getSourceText(
|
||||
CharSourceRange::getTokenRange(IneffContExpr->getSourceRange()),
|
||||
*Result.SourceManager, Result.Context->getLangOpts())) +
|
||||
(PtrToContainer ? "->" : ".") + AlgDecl->getName() + "(" +
|
||||
Lexer::getSourceText(
|
||||
CharSourceRange::getTokenRange(AlgParam->getSourceRange()),
|
||||
*Result.SourceManager, Result.Context->getLangOpts()) +
|
||||
")").str();
|
||||
Hint = FixItHint::CreateReplacement(AlgCall->getSourceRange(),
|
||||
ReplacementText);
|
||||
(llvm::Twine(ContainerText) + (PtrToContainer ? "->" : ".") +
|
||||
AlgDecl->getName() + "(" + ParamText + ")")
|
||||
.str();
|
||||
Hint = FixItHint::CreateReplacement(CallRange, ReplacementText);
|
||||
}
|
||||
|
||||
diag(AlgCall->getLocStart(),
|
||||
|
|
|
@ -76,6 +76,12 @@ int main() {
|
|||
auto c = count(s.begin(), s.end(), 43);
|
||||
// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: this STL algorithm call should be
|
||||
// CHECK-FIXES: {{^ }}auto c = s.count(43);{{$}}
|
||||
|
||||
#define SECOND(x, y, z) y
|
||||
SECOND(q,std::count(s.begin(), s.end(), 22),w);
|
||||
// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: this STL algorithm call should be
|
||||
// CHECK-FIXES: {{^ }}SECOND(q,s.count(22),w);{{$}}
|
||||
|
||||
it = find_if(s.begin(), s.end(), [](int) { return false; });
|
||||
|
||||
std::multiset<int> ms;
|
||||
|
|
Loading…
Reference in New Issue