[clang-tools-extra] r232338 - Move remove-cstr-calls from a standalone executable to a clang-tidy check readability-redundant-string-cstr

Alexander Kornienko alexfh at google.com
Sun Mar 15 17:32:25 PDT 2015


Author: alexfh
Date: Sun Mar 15 19:32:25 2015
New Revision: 232338

URL: http://llvm.org/viewvc/llvm-project?rev=232338&view=rev
Log:
Move remove-cstr-calls from a standalone executable to a clang-tidy check readability-redundant-string-cstr

http://reviews.llvm.org/D7318

Patch by Richard Thomson!

Added:
    clang-tools-extra/trunk/clang-tidy/readability/RedundantStringCStrCheck.cpp
    clang-tools-extra/trunk/clang-tidy/readability/RedundantStringCStrCheck.h
    clang-tools-extra/trunk/test/clang-tidy/readability-redundant-string-cstr.cpp
Removed:
    clang-tools-extra/trunk/remove-cstr-calls/CMakeLists.txt
    clang-tools-extra/trunk/remove-cstr-calls/Makefile
    clang-tools-extra/trunk/remove-cstr-calls/RemoveCStrCalls.cpp
    clang-tools-extra/trunk/test/remove-cstr-calls/basic.cpp
Modified:
    clang-tools-extra/trunk/CMakeLists.txt
    clang-tools-extra/trunk/clang-tidy/readability/CMakeLists.txt
    clang-tools-extra/trunk/clang-tidy/readability/ReadabilityTidyModule.cpp
    clang-tools-extra/trunk/test/CMakeLists.txt

Modified: clang-tools-extra/trunk/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/CMakeLists.txt?rev=232338&r1=232337&r2=232338&view=diff
==============================================================================
--- clang-tools-extra/trunk/CMakeLists.txt (original)
+++ clang-tools-extra/trunk/CMakeLists.txt Sun Mar 15 19:32:25 2015
@@ -2,7 +2,6 @@ add_subdirectory(clang-apply-replacement
 add_subdirectory(clang-modernize)
 add_subdirectory(clang-rename)
 add_subdirectory(modularize)
-add_subdirectory(remove-cstr-calls)
 if(CLANG_ENABLE_STATIC_ANALYZER)
 add_subdirectory(clang-tidy)
 endif()

Modified: clang-tools-extra/trunk/clang-tidy/readability/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/readability/CMakeLists.txt?rev=232338&r1=232337&r2=232338&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/readability/CMakeLists.txt (original)
+++ clang-tools-extra/trunk/clang-tidy/readability/CMakeLists.txt Sun Mar 15 19:32:25 2015
@@ -7,6 +7,7 @@ add_clang_library(clangTidyReadabilityMo
   FunctionSizeCheck.cpp
   NamespaceCommentCheck.cpp
   ReadabilityTidyModule.cpp
+  RedundantStringCStrCheck.cpp
   RedundantSmartptrGetCheck.cpp
   ShrinkToFitCheck.cpp
 

Modified: clang-tools-extra/trunk/clang-tidy/readability/ReadabilityTidyModule.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/readability/ReadabilityTidyModule.cpp?rev=232338&r1=232337&r2=232338&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/readability/ReadabilityTidyModule.cpp (original)
+++ clang-tools-extra/trunk/clang-tidy/readability/ReadabilityTidyModule.cpp Sun Mar 15 19:32:25 2015
@@ -15,6 +15,7 @@
 #include "ElseAfterReturnCheck.h"
 #include "FunctionSizeCheck.h"
 #include "RedundantSmartptrGetCheck.h"
+#include "RedundantStringCStrCheck.h"
 #include "ShrinkToFitCheck.h"
 
 namespace clang {
@@ -34,19 +35,20 @@ public:
         "readability-function-size");
     CheckFactories.registerCheck<RedundantSmartptrGetCheck>(
         "readability-redundant-smartptr-get");
-    CheckFactories.registerCheck<ShrinkToFitCheck>(
-        "readability-shrink-to-fit");
+    CheckFactories.registerCheck<RedundantStringCStrCheck>(
+        "readability-redundant-string-cstr");
+    CheckFactories.registerCheck<ShrinkToFitCheck>("readability-shrink-to-fit");
   }
 };
 
-} // namespace readability
+// Register the ReadabilityModule using this statically initialized variable.
+static ClangTidyModuleRegistry::Add<ReadabilityModule>
+    X("readability-module", "Adds readability-related checks.");
 
-// Register the MiscTidyModule using this statically initialized variable.
-static ClangTidyModuleRegistry::Add<readability::ReadabilityModule>
-X("readability-module", "Adds readability-related checks.");
+} // namespace readability
 
 // This anchor is used to force the linker to link in the generated object file
-// and thus register the MiscModule.
+// and thus register the ReadabilityModule.
 volatile int ReadabilityModuleAnchorSource = 0;
 
 } // namespace tidy

Added: clang-tools-extra/trunk/clang-tidy/readability/RedundantStringCStrCheck.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/readability/RedundantStringCStrCheck.cpp?rev=232338&view=auto
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/readability/RedundantStringCStrCheck.cpp (added)
+++ clang-tools-extra/trunk/clang-tidy/readability/RedundantStringCStrCheck.cpp Sun Mar 15 19:32:25 2015
@@ -0,0 +1,138 @@
+//===- RedundantStringCStrCheck.cpp - Check for redundant c_str calls -----===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file implements a check for redundant calls of c_str() on strings.
+//
+//===----------------------------------------------------------------------===//
+
+#include "RedundantStringCStrCheck.h"
+#include "clang/Lex/Lexer.h"
+
+namespace clang {
+
+using namespace ast_matchers;
+
+namespace {
+
+template <typename T>
+StringRef getText(const ast_matchers::MatchFinder::MatchResult &Result,
+                  T const &Node) {
+  return Lexer::getSourceText(
+      CharSourceRange::getTokenRange(Node.getSourceRange()),
+      *Result.SourceManager, Result.Context->getLangOpts());
+}
+
+// Return true if expr needs to be put in parens when it is an argument of a
+// prefix unary operator, e.g. when it is a binary or ternary operator
+// syntactically.
+bool needParensAfterUnaryOperator(const Expr &ExprNode) {
+  if (isa<clang::BinaryOperator>(&ExprNode) ||
+      isa<clang::ConditionalOperator>(&ExprNode)) {
+    return true;
+  }
+  if (const auto *Op = dyn_cast<CXXOperatorCallExpr>(&ExprNode)) {
+    return Op->getNumArgs() == 2 && Op->getOperator() != OO_PlusPlus &&
+           Op->getOperator() != OO_MinusMinus && Op->getOperator() != OO_Call &&
+           Op->getOperator() != OO_Subscript;
+  }
+  return false;
+}
+
+// Format a pointer to an expression: prefix with '*' but simplify
+// when it already begins with '&'.  Return empty string on failure.
+std::string
+formatDereference(const ast_matchers::MatchFinder::MatchResult &Result,
+                  const Expr &ExprNode) {
+  if (const auto *Op = dyn_cast<clang::UnaryOperator>(&ExprNode)) {
+    if (Op->getOpcode() == UO_AddrOf) {
+      // Strip leading '&'.
+      return getText(Result, *Op->getSubExpr()->IgnoreParens());
+    }
+  }
+  StringRef Text = getText(Result, ExprNode);
+  if (Text.empty())
+    return std::string();
+  // Add leading '*'.
+  if (needParensAfterUnaryOperator(ExprNode)) {
+    return (llvm::Twine("*(") + Text + ")").str();
+  }
+  return (llvm::Twine("*") + Text).str();
+}
+
+const char StringConstructor[] =
+    "::std::basic_string<char, std::char_traits<char>, std::allocator<char> >"
+    "::basic_string";
+
+const char StringCStrMethod[] =
+    "::std::basic_string<char, std::char_traits<char>, std::allocator<char> >"
+    "::c_str";
+
+} // end namespace
+
+namespace tidy {
+namespace readability {
+
+void RedundantStringCStrCheck::registerMatchers(
+    ast_matchers::MatchFinder *Finder) {
+  Finder->addMatcher(
+      constructExpr(
+          hasDeclaration(methodDecl(hasName(StringConstructor))),
+          argumentCountIs(2),
+          // The first argument must have the form x.c_str() or p->c_str()
+          // where the method is string::c_str().  We can use the copy
+          // constructor of string instead (or the compiler might share
+          // the string object).
+          hasArgument(
+              0, memberCallExpr(callee(memberExpr().bind("member")),
+                                callee(methodDecl(hasName(StringCStrMethod))),
+                                on(expr().bind("arg"))).bind("call")),
+          // The second argument is the alloc object which must not be
+          // present explicitly.
+          hasArgument(1, defaultArgExpr())),
+      this);
+  Finder->addMatcher(
+      constructExpr(
+          // Implicit constructors of these classes are overloaded
+          // wrt. string types and they internally make a StringRef
+          // referring to the argument.  Passing a string directly to
+          // them is preferred to passing a char pointer.
+          hasDeclaration(
+              methodDecl(anyOf(hasName("::llvm::StringRef::StringRef"),
+                               hasName("::llvm::Twine::Twine")))),
+          argumentCountIs(1),
+          // The only argument must have the form x.c_str() or p->c_str()
+          // where the method is string::c_str().  StringRef also has
+          // a constructor from string which is more efficient (avoids
+          // strlen), so we can construct StringRef from the string
+          // directly.
+          hasArgument(
+              0, memberCallExpr(callee(memberExpr().bind("member")),
+                                callee(methodDecl(hasName(StringCStrMethod))),
+                                on(expr().bind("arg"))).bind("call"))),
+      this);
+}
+
+void RedundantStringCStrCheck::check(const MatchFinder::MatchResult &Result) {
+  const auto *Call = Result.Nodes.getStmtAs<CallExpr>("call");
+  const auto *Arg = Result.Nodes.getStmtAs<Expr>("arg");
+  bool Arrow = Result.Nodes.getStmtAs<MemberExpr>("member")->isArrow();
+  // Replace the "call" node with the "arg" node, prefixed with '*'
+  // if the call was using '->' rather than '.'.
+  std::string ArgText =
+      Arrow ? formatDereference(Result, *Arg) : getText(Result, *Arg).str();
+  if (ArgText.empty())
+    return;
+
+  diag(Call->getLocStart(), "redundant call to `c_str()`")
+      << FixItHint::CreateReplacement(Call->getSourceRange(), ArgText);
+}
+
+} // namespace readability
+} // namespace tidy
+} // namespace clang

Added: clang-tools-extra/trunk/clang-tidy/readability/RedundantStringCStrCheck.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/readability/RedundantStringCStrCheck.h?rev=232338&view=auto
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/readability/RedundantStringCStrCheck.h (added)
+++ clang-tools-extra/trunk/clang-tidy/readability/RedundantStringCStrCheck.h Sun Mar 15 19:32:25 2015
@@ -0,0 +1,32 @@
+//===--- RedundantStringCStrCheck.h - clang-tidy ----------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_REDUNDANTSTRINGCSTRCHECK_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_REDUNDANTSTRINGCSTRCHECK_H
+
+#include "../ClangTidy.h"
+
+namespace clang {
+namespace tidy {
+namespace readability {
+
+/// \brief Finds unnecessary calls to std::string::c_str().
+class RedundantStringCStrCheck : public ClangTidyCheck {
+public:
+  RedundantStringCStrCheck(StringRef Name, ClangTidyContext *Context)
+      : ClangTidyCheck(Name, Context) {}
+  void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+  void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+};
+
+} // namespace readability
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_REDUNDANTSTRINGCSTRCHECK_H

Removed: clang-tools-extra/trunk/remove-cstr-calls/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/remove-cstr-calls/CMakeLists.txt?rev=232337&view=auto
==============================================================================
--- clang-tools-extra/trunk/remove-cstr-calls/CMakeLists.txt (original)
+++ clang-tools-extra/trunk/remove-cstr-calls/CMakeLists.txt (removed)
@@ -1,17 +0,0 @@
-set(LLVM_LINK_COMPONENTS
-  Support
-  )
-
-add_clang_executable(remove-cstr-calls
-  RemoveCStrCalls.cpp
-  )
-
-target_link_libraries(remove-cstr-calls
-  clangAST
-  clangASTMatchers
-  clangBasic
-  clangFrontend
-  clangLex
-  clangTooling
-  clangToolingCore
-  )

Removed: clang-tools-extra/trunk/remove-cstr-calls/Makefile
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/remove-cstr-calls/Makefile?rev=232337&view=auto
==============================================================================
--- clang-tools-extra/trunk/remove-cstr-calls/Makefile (original)
+++ clang-tools-extra/trunk/remove-cstr-calls/Makefile (removed)
@@ -1,25 +0,0 @@
-##===- tools/extra/remove-cstr-calls/Makefile --------------*- Makefile -*-===##
-#
-#                     The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-CLANG_LEVEL := ../../..
-
-TOOLNAME = remove-cstr-calls
-NO_INSTALL = 1
-
-# No plugins, optimize startup time.
-TOOL_NO_EXPORTS = 1
-
-include $(CLANG_LEVEL)/../../Makefile.config
-LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser bitreader support mc option
-USEDLIBS = clangTooling.a clangFrontend.a clangSerialization.a clangDriver.a \
-           clangToolingCore.a clangRewriteFrontend.a clangRewrite.a \
-           clangParse.a clangSema.a clangAnalysis.a \
-           clangAST.a clangASTMatchers.a clangEdit.a clangLex.a clangBasic.a
-
-include $(CLANG_LEVEL)/Makefile

Removed: clang-tools-extra/trunk/remove-cstr-calls/RemoveCStrCalls.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/remove-cstr-calls/RemoveCStrCalls.cpp?rev=232337&view=auto
==============================================================================
--- clang-tools-extra/trunk/remove-cstr-calls/RemoveCStrCalls.cpp (original)
+++ clang-tools-extra/trunk/remove-cstr-calls/RemoveCStrCalls.cpp (removed)
@@ -1,237 +0,0 @@
-//===- examples/Tooling/RemoveCStrCalls.cpp - Redundant c_str call removal ===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-//  This file implements a tool that prints replacements that remove redundant
-//  calls of c_str() on strings.
-//
-//  Usage:
-//  remove-cstr-calls <cmake-output-dir> <file1> <file2> ...
-//
-//  Where <cmake-output-dir> is a CMake build directory in which a file named
-//  compile_commands.json exists (enable -DCMAKE_EXPORT_COMPILE_COMMANDS in
-//  CMake to get this output).
-//
-//  <file1> ... specify the paths of files in the CMake source tree. This path
-//  is looked up in the compile command database. If the path of a file is
-//  absolute, it needs to point into CMake's source tree. If the path is
-//  relative, the current working directory needs to be in the CMake source
-//  tree and the file must be in a subdirectory of the current working
-//  directory. "./" prefixes in the relative files will be automatically
-//  removed, but the rest of a relative path must be a suffix of a path in
-//  the compile command line database.
-//
-//  For example, to use remove-cstr-calls on all files in a subtree of the
-//  source tree, use:
-//
-//    /path/in/subtree $ find . -name '*.cpp'|
-//        xargs remove-cstr-calls /path/to/build
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/ASTMatchers/ASTMatchers.h"
-#include "clang/ASTMatchers/ASTMatchFinder.h"
-#include "clang/Basic/SourceManager.h"
-#include "clang/Frontend/FrontendActions.h"
-#include "clang/Lex/Lexer.h"
-#include "clang/Tooling/CompilationDatabase.h"
-#include "clang/Tooling/Refactoring.h"
-#include "clang/Tooling/Tooling.h"
-#include "llvm/ADT/Twine.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/Path.h"
-#include "llvm/Support/Signals.h"
-#include "llvm/Support/raw_ostream.h"
-#include <system_error>
-
-using namespace clang;
-using namespace clang::ast_matchers;
-using namespace llvm;
-using clang::tooling::newFrontendActionFactory;
-using clang::tooling::Replacement;
-using clang::tooling::CompilationDatabase;
-
-// FIXME: Pull out helper methods in here into more fitting places.
-
-// Returns the text that makes up 'node' in the source.
-// Returns an empty string if the text cannot be found.
-template <typename T>
-static std::string getText(const SourceManager &SourceManager, const T &Node) {
-  SourceLocation StartSpellingLocation =
-      SourceManager.getSpellingLoc(Node.getLocStart());
-  SourceLocation EndSpellingLocation =
-      SourceManager.getSpellingLoc(Node.getLocEnd());
-  if (!StartSpellingLocation.isValid() || !EndSpellingLocation.isValid()) {
-    return std::string();
-  }
-  bool Invalid = true;
-  const char *Text =
-      SourceManager.getCharacterData(StartSpellingLocation, &Invalid);
-  if (Invalid) {
-    return std::string();
-  }
-  std::pair<FileID, unsigned> Start =
-      SourceManager.getDecomposedLoc(StartSpellingLocation);
-  std::pair<FileID, unsigned> End =
-      SourceManager.getDecomposedLoc(Lexer::getLocForEndOfToken(
-          EndSpellingLocation, 0, SourceManager, LangOptions()));
-  if (Start.first != End.first) {
-    // Start and end are in different files.
-    return std::string();
-  }
-  if (End.second < Start.second) {
-    // Shuffling text with macros may cause this.
-    return std::string();
-  }
-  return std::string(Text, End.second - Start.second);
-}
-
-// Return true if expr needs to be put in parens when it is an argument of a
-// prefix unary operator, e.g. when it is a binary or ternary operator
-// syntactically.
-static bool needParensAfterUnaryOperator(const Expr &ExprNode) {
-  if (dyn_cast<clang::BinaryOperator>(&ExprNode) ||
-      dyn_cast<clang::ConditionalOperator>(&ExprNode)) {
-    return true;
-  }
-  if (const CXXOperatorCallExpr *op =
-      dyn_cast<CXXOperatorCallExpr>(&ExprNode)) {
-    return op->getNumArgs() == 2 &&
-        op->getOperator() != OO_PlusPlus &&
-        op->getOperator() != OO_MinusMinus &&
-        op->getOperator() != OO_Call &&
-        op->getOperator() != OO_Subscript;
-  }
-  return false;
-}
-
-// Format a pointer to an expression: prefix with '*' but simplify
-// when it already begins with '&'.  Return empty string on failure.
-static std::string formatDereference(const SourceManager &SourceManager,
-                              const Expr &ExprNode) {
-  if (const clang::UnaryOperator *Op =
-      dyn_cast<clang::UnaryOperator>(&ExprNode)) {
-    if (Op->getOpcode() == UO_AddrOf) {
-      // Strip leading '&'.
-      return getText(SourceManager, *Op->getSubExpr()->IgnoreParens());
-    }
-  }
-  const std::string Text = getText(SourceManager, ExprNode);
-  if (Text.empty()) return std::string();
-  // Add leading '*'.
-  if (needParensAfterUnaryOperator(ExprNode)) {
-    return std::string("*(") + Text + ")";
-  }
-  return std::string("*") + Text;
-}
-
-namespace {
-class FixCStrCall : public ast_matchers::MatchFinder::MatchCallback {
- public:
-  FixCStrCall(tooling::Replacements *Replace)
-      : Replace(Replace) {}
-
-  virtual void run(const ast_matchers::MatchFinder::MatchResult &Result) {
-    const CallExpr *Call =
-        Result.Nodes.getStmtAs<CallExpr>("call");
-    const Expr *Arg =
-        Result.Nodes.getStmtAs<Expr>("arg");
-    const bool Arrow =
-        Result.Nodes.getStmtAs<MemberExpr>("member")->isArrow();
-    // Replace the "call" node with the "arg" node, prefixed with '*'
-    // if the call was using '->' rather than '.'.
-    const std::string ArgText = Arrow ?
-        formatDereference(*Result.SourceManager, *Arg) :
-        getText(*Result.SourceManager, *Arg);
-    if (ArgText.empty()) return;
-
-    Replace->insert(Replacement(*Result.SourceManager, Call, ArgText));
-  }
-
- private:
-  tooling::Replacements *Replace;
-};
-} // end namespace
-
-const char *StringConstructor =
-    "::std::basic_string<char, std::char_traits<char>, std::allocator<char> >"
-    "::basic_string";
-
-const char *StringCStrMethod =
-    "::std::basic_string<char, std::char_traits<char>, std::allocator<char> >"
-    "::c_str";
-
-cl::opt<std::string> BuildPath(
-  cl::Positional,
-  cl::desc("<build-path>"));
-
-cl::list<std::string> SourcePaths(
-  cl::Positional,
-  cl::desc("<source0> [... <sourceN>]"),
-  cl::OneOrMore);
-
-int main(int argc, const char **argv) {
-  llvm::sys::PrintStackTraceOnErrorSignal();
-  std::unique_ptr<CompilationDatabase> Compilations(
-      tooling::FixedCompilationDatabase::loadFromCommandLine(argc, argv));
-  cl::ParseCommandLineOptions(argc, argv);
-  if (!Compilations) {
-    std::string ErrorMessage;
-    Compilations =
-        CompilationDatabase::loadFromDirectory(BuildPath, ErrorMessage);
-    if (!Compilations)
-      llvm::report_fatal_error(ErrorMessage);
-  }
-  tooling::RefactoringTool Tool(*Compilations, SourcePaths);
-  ast_matchers::MatchFinder Finder;
-  FixCStrCall Callback(&Tool.getReplacements());
-  Finder.addMatcher(
-      constructExpr(
-          hasDeclaration(methodDecl(hasName(StringConstructor))),
-          argumentCountIs(2),
-          // The first argument must have the form x.c_str() or p->c_str()
-          // where the method is string::c_str().  We can use the copy
-          // constructor of string instead (or the compiler might share
-          // the string object).
-          hasArgument(
-              0,
-              id("call", memberCallExpr(
-                  callee(id("member", memberExpr())),
-                  callee(methodDecl(hasName(StringCStrMethod))),
-                  on(id("arg", expr()))))),
-          // The second argument is the alloc object which must not be
-          // present explicitly.
-          hasArgument(
-              1,
-              defaultArgExpr())),
-      &Callback);
-  Finder.addMatcher(
-      constructExpr(
-          // Implicit constructors of these classes are overloaded
-          // wrt. string types and they internally make a StringRef
-          // referring to the argument.  Passing a string directly to
-          // them is preferred to passing a char pointer.
-          hasDeclaration(methodDecl(anyOf(
-              hasName("::llvm::StringRef::StringRef"),
-              hasName("::llvm::Twine::Twine")))),
-          argumentCountIs(1),
-          // The only argument must have the form x.c_str() or p->c_str()
-          // where the method is string::c_str().  StringRef also has
-          // a constructor from string which is more efficient (avoids
-          // strlen), so we can construct StringRef from the string
-          // directly.
-          hasArgument(
-              0,
-              id("call", memberCallExpr(
-                  callee(id("member", memberExpr())),
-                  callee(methodDecl(hasName(StringCStrMethod))),
-                  on(id("arg", expr())))))),
-      &Callback);
-  return Tool.runAndSave(newFrontendActionFactory(&Finder).get());
-}

Modified: clang-tools-extra/trunk/test/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/CMakeLists.txt?rev=232338&r1=232337&r2=232338&view=diff
==============================================================================
--- clang-tools-extra/trunk/test/CMakeLists.txt (original)
+++ clang-tools-extra/trunk/test/CMakeLists.txt Sun Mar 15 19:32:25 2015
@@ -42,7 +42,6 @@ set(CLANG_TOOLS_TEST_DEPS
   clang-tidy
   modularize
   pp-trace
-  remove-cstr-calls
 
   # Unit tests
   ExtraToolsUnitTests

Added: clang-tools-extra/trunk/test/clang-tidy/readability-redundant-string-cstr.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/readability-redundant-string-cstr.cpp?rev=232338&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/readability-redundant-string-cstr.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/readability-redundant-string-cstr.cpp Sun Mar 15 19:32:25 2015
@@ -0,0 +1,42 @@
+// RUN: $(dirname %s)/check_clang_tidy.sh %s readability-redundant-string-cstr %t
+// REQUIRES: shell
+
+namespace std {
+template <typename T>
+class allocator {};
+template <typename T>
+class char_traits {};
+template <typename C, typename T, typename A>
+struct basic_string {
+  basic_string();
+  basic_string(const C *p, const A &a = A());
+  const C *c_str() const;
+};
+typedef basic_string<char, std::char_traits<char>, std::allocator<char>> string;
+}
+namespace llvm {
+struct StringRef {
+  StringRef(const char *p);
+  StringRef(const std::string &);
+};
+}
+
+void f1(const std::string &s) {
+  f1(s.c_str());
+  // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: redundant call to `c_str()` [readability-redundant-string-cstr]
+  // CHECK-FIXES: {{^  }}f1(s);{{$}}
+}
+void f2(const llvm::StringRef r) {
+  std::string s;
+  f2(s.c_str());
+  // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: redundant call {{.*}}
+  // CHECK-FIXES: {{^  }}std::string s;{{$}}
+  // CHECK-FIXES-NEXT: {{^  }}f2(s);{{$}}
+}
+void f3(const llvm::StringRef &r) {
+  std::string s;
+  f3(s.c_str());
+  // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: redundant call {{.*}}
+  // CHECK-FIXES: {{^  }}std::string s;{{$}}
+  // CHECK-FIXES-NEXT: {{^  }}f3(s);{{$}}
+}

Removed: clang-tools-extra/trunk/test/remove-cstr-calls/basic.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/remove-cstr-calls/basic.cpp?rev=232337&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/remove-cstr-calls/basic.cpp (original)
+++ clang-tools-extra/trunk/test/remove-cstr-calls/basic.cpp (removed)
@@ -1,39 +0,0 @@
-// RUN: grep -Ev "// *[A-Z-]+:" %s > %t.cpp
-// RUN: remove-cstr-calls . %t.cpp --
-// RUN: FileCheck -input-file=%t.cpp %s
-// REQUIRES: shell
-
-namespace std {
-template<typename T> class allocator {};
-template<typename T> class char_traits {};
-template<typename C, typename T, typename A> struct basic_string {
-  basic_string();
-  basic_string(const C *p, const A& a = A());
-  const C *c_str() const;
-};
-typedef basic_string<char, std::char_traits<char>, std::allocator<char> > string;
-}
-namespace llvm {
-struct StringRef {
-  StringRef(const char *p);
-  StringRef(const std::string &);
-};
-}
-
-void f1(const std::string &s) {
-  f1(s.c_str());
-  // CHECK: void f1
-  // CHECK-NEXT: f1(s)
-}
-void f2(const llvm::StringRef r) {
-  std::string s;
-  f2(s.c_str());
-  // CHECK: std::string s; 
-  // CHECK-NEXT: f2(s)
-}
-void f3(const llvm::StringRef &r) {
-  std::string s;
-  f3(s.c_str());
-  // CHECK: std::string s;
-  // CHECK: f3(s)
-}





More information about the cfe-commits mailing list