diff options
author | Alexander Kornienko <alexfh@google.com> | 2015-07-31 13:34:58 +0000 |
---|---|---|
committer | Alexander Kornienko <alexfh@google.com> | 2015-07-31 13:34:58 +0000 |
commit | b4fbb173f0892105806e93520486c81225dc029d (patch) | |
tree | dbb4db48d1a7464693e438f6ec2321edb8f85db7 | |
parent | a2ce083d2daac54f3c026a2e0e04fc53338c47c6 (diff) | |
download | bcm5719-llvm-b4fbb173f0892105806e93520486c81225dc029d.tar.gz bcm5719-llvm-b4fbb173f0892105806e93520486c81225dc029d.zip |
[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
-rw-r--r-- | clang-tools-extra/clang-tidy/misc/InefficientAlgorithmCheck.cpp | 45 | ||||
-rw-r--r-- | clang-tools-extra/test/clang-tidy/misc-inefficient-algorithm.cpp | 6 |
2 files changed, 40 insertions, 11 deletions
diff --git a/clang-tools-extra/clang-tidy/misc/InefficientAlgorithmCheck.cpp b/clang-tools-extra/clang-tidy/misc/InefficientAlgorithmCheck.cpp index 8d58a814951..3ca6c8196d7 100644 --- a/clang-tools-extra/clang-tidy/misc/InefficientAlgorithmCheck.cpp +++ b/clang-tools-extra/clang-tidy/misc/InefficientAlgorithmCheck.cpp @@ -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(), diff --git a/clang-tools-extra/test/clang-tidy/misc-inefficient-algorithm.cpp b/clang-tools-extra/test/clang-tidy/misc-inefficient-algorithm.cpp index ea668c2bedd..754e4007a4e 100644 --- a/clang-tools-extra/test/clang-tidy/misc-inefficient-algorithm.cpp +++ b/clang-tools-extra/test/clang-tidy/misc-inefficient-algorithm.cpp @@ -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; |