From: Alexander Kornienko Date: Fri, 31 Jul 2015 13:34:58 +0000 (+0000) Subject: [clang-tidy] Support replacements in macro arguments in misc-inefficient-algorithm X-Git-Tag: studio-1.4~1123 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=b4fbb173f0892105806e93520486c81225dc029d;p=platform%2Fupstream%2Fllvm.git [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 --- diff --git a/clang-tools-extra/clang-tidy/misc/InefficientAlgorithmCheck.cpp b/clang-tools-extra/clang-tidy/misc/InefficientAlgorithmCheck.cpp index 8d58a81..3ca6c81 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("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 ea668c2..754e400 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 ms;