[clang-tools-extra] r243747 - [clang-tidy] Support replacements in macro arguments in misc-inefficient-algorithm

Alexander Kornienko alexfh at google.com
Fri Jul 31 06:34:58 PDT 2015


Author: alexfh
Date: Fri Jul 31 08:34:58 2015
New Revision: 243747

URL: http://llvm.org/viewvc/llvm-project?rev=243747&view=rev
Log:
[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

Modified:
    clang-tools-extra/trunk/clang-tidy/misc/InefficientAlgorithmCheck.cpp
    clang-tools-extra/trunk/test/clang-tidy/misc-inefficient-algorithm.cpp

Modified: clang-tools-extra/trunk/clang-tidy/misc/InefficientAlgorithmCheck.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/misc/InefficientAlgorithmCheck.cpp?rev=243747&r1=243746&r2=243747&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/misc/InefficientAlgorithmCheck.cpp (original)
+++ clang-tools-extra/trunk/clang-tidy/misc/InefficientAlgorithmCheck.cpp Fri Jul 31 08:34:58 2015
@@ -105,18 +105,41 @@ void InefficientAlgorithmCheck::check(co
   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(),

Modified: clang-tools-extra/trunk/test/clang-tidy/misc-inefficient-algorithm.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/misc-inefficient-algorithm.cpp?rev=243747&r1=243746&r2=243747&view=diff
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/misc-inefficient-algorithm.cpp (original)
+++ clang-tools-extra/trunk/test/clang-tidy/misc-inefficient-algorithm.cpp Fri Jul 31 08:34:58 2015
@@ -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;





More information about the cfe-commits mailing list