summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexander Kornienko <alexfh@google.com>2015-07-31 13:34:58 +0000
committerAlexander Kornienko <alexfh@google.com>2015-07-31 13:34:58 +0000
commitb4fbb173f0892105806e93520486c81225dc029d (patch)
treedbb4db48d1a7464693e438f6ec2321edb8f85db7
parenta2ce083d2daac54f3c026a2e0e04fc53338c47c6 (diff)
downloadbcm5719-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.cpp45
-rw-r--r--clang-tools-extra/test/clang-tidy/misc-inefficient-algorithm.cpp6
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;
OpenPOWER on IntegriCloud