//===- 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"
#include "clang/Tooling/FixIt.h"

using namespace clang::ast_matchers;

namespace clang {
namespace tidy {
namespace readability {

namespace {

// 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 tooling::fixit::getText(*Op->getSubExpr()->IgnoreParens(),
                                     *Result.Context);
    }
  }
  StringRef Text = tooling::fixit::getText(ExprNode, *Result.Context);

  if (Text.empty())
    return std::string();
  // Add leading '*'.
  if (needParensAfterUnaryOperator(ExprNode)) {
    return (llvm::Twine("*(") + Text + ")").str();
  }
  return (llvm::Twine("*") + Text).str();
}

} // end namespace

void RedundantStringCStrCheck::registerMatchers(
    ast_matchers::MatchFinder *Finder) {
  // Only register the matchers for C++; the functionality currently does not
  // provide any benefit to other languages, despite being benign.
  if (!getLangOpts().CPlusPlus)
    return;

  // Match expressions of type 'string' or 'string*'.
  const auto StringDecl = type(hasUnqualifiedDesugaredType(recordType(
      hasDeclaration(cxxRecordDecl(hasName("::std::basic_string"))))));
  const auto StringExpr =
      expr(anyOf(hasType(StringDecl), hasType(qualType(pointsTo(StringDecl)))));

  // Match string constructor.
  const auto StringConstructorExpr = expr(anyOf(
      cxxConstructExpr(argumentCountIs(1),
                       hasDeclaration(cxxMethodDecl(hasName("basic_string")))),
      cxxConstructExpr(
          argumentCountIs(2),
          hasDeclaration(cxxMethodDecl(hasName("basic_string"))),
          // If present, the second argument is the alloc object which must not
          // be present explicitly.
          hasArgument(1, cxxDefaultArgExpr()))));

  // Match a call to the string 'c_str()' method.
  const auto StringCStrCallExpr =
      cxxMemberCallExpr(on(StringExpr.bind("arg")),
                        callee(memberExpr().bind("member")),
                        callee(cxxMethodDecl(hasAnyName("c_str", "data"))))
          .bind("call");

  // Detect redundant 'c_str()' calls through a string constructor.
  Finder->addMatcher(cxxConstructExpr(StringConstructorExpr,
                                      hasArgument(0, StringCStrCallExpr)),
                     this);

  // Detect: 's == str.c_str()'  ->  's == str'
  Finder->addMatcher(
      cxxOperatorCallExpr(
          anyOf(
              hasOverloadedOperatorName("<"), hasOverloadedOperatorName(">"),
              hasOverloadedOperatorName(">="), hasOverloadedOperatorName("<="),
              hasOverloadedOperatorName("!="), hasOverloadedOperatorName("=="),
              hasOverloadedOperatorName("+")),
          anyOf(allOf(hasArgument(0, StringExpr),
                      hasArgument(1, StringCStrCallExpr)),
                allOf(hasArgument(0, StringCStrCallExpr),
                      hasArgument(1, StringExpr)))),
      this);

  // Detect: 'dst += str.c_str()'  ->  'dst += str'
  // Detect: 's = str.c_str()'  ->  's = str'
  Finder->addMatcher(cxxOperatorCallExpr(anyOf(hasOverloadedOperatorName("="),
                                               hasOverloadedOperatorName("+=")),
                                         hasArgument(0, StringExpr),
                                         hasArgument(1, StringCStrCallExpr)),
                     this);

  // Detect: 'dst.append(str.c_str())'  ->  'dst.append(str)'
  Finder->addMatcher(
      cxxMemberCallExpr(on(StringExpr), callee(decl(cxxMethodDecl(hasAnyName(
                                            "append", "assign", "compare")))),
                        argumentCountIs(1), hasArgument(0, StringCStrCallExpr)),
      this);

  // Detect: 'dst.compare(p, n, str.c_str())'  ->  'dst.compare(p, n, str)'
  Finder->addMatcher(
      cxxMemberCallExpr(on(StringExpr),
                        callee(decl(cxxMethodDecl(hasName("compare")))),
                        argumentCountIs(3), hasArgument(2, StringCStrCallExpr)),
      this);

  // Detect: 'dst.find(str.c_str())'  ->  'dst.find(str)'
  Finder->addMatcher(
      cxxMemberCallExpr(on(StringExpr),
                        callee(decl(cxxMethodDecl(hasAnyName(
                            "find", "find_first_not_of", "find_first_of",
                            "find_last_not_of", "find_last_of", "rfind")))),
                        anyOf(argumentCountIs(1), argumentCountIs(2)),
                        hasArgument(0, StringCStrCallExpr)),
      this);

  // Detect: 'dst.insert(pos, str.c_str())'  ->  'dst.insert(pos, str)'
  Finder->addMatcher(
      cxxMemberCallExpr(on(StringExpr),
                        callee(decl(cxxMethodDecl(hasName("insert")))),
                        argumentCountIs(2), hasArgument(1, StringCStrCallExpr)),
      this);

  // Detect redundant 'c_str()' calls through a StringRef constructor.
  Finder->addMatcher(
      cxxConstructExpr(
          // 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(cxxMethodDecl(hasAnyName(
              "::llvm::StringRef::StringRef", "::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, StringCStrCallExpr)),
      this);
}

void RedundantStringCStrCheck::check(const MatchFinder::MatchResult &Result) {
  const auto *Call = Result.Nodes.getNodeAs<CallExpr>("call");
  const auto *Arg = Result.Nodes.getNodeAs<Expr>("arg");
  const auto *Member = Result.Nodes.getNodeAs<MemberExpr>("member");
  bool Arrow = 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)
            : tooling::fixit::getText(*Arg, *Result.Context).str();
  if (ArgText.empty())
    return;

  diag(Call->getBeginLoc(), "redundant call to %0")
      << Member->getMemberDecl()
      << FixItHint::CreateReplacement(Call->getSourceRange(), ArgText);
}

} // namespace readability
} // namespace tidy
} // namespace clang
