//===--- CloexecCheck.cpp - clang-tidy-------------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "CloexecCheck.h"
#include "../utils/ASTUtils.h"
#include "clang/AST/ASTContext.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/Lex/Lexer.h"

using namespace clang::ast_matchers;

namespace clang {
namespace tidy {
namespace android {

namespace {
// Helper function to form the correct string mode for Type3.
// Build the replace text. If it's string constant, add <Mode> directly in the
// end of the string. Else, add <Mode>.
std::string buildFixMsgForStringFlag(const Expr *Arg, const SourceManager &SM,
                                     const LangOptions &LangOpts, char Mode) {
  if (Arg->getLocStart().isMacroID())
    return (Lexer::getSourceText(
                CharSourceRange::getTokenRange(Arg->getSourceRange()), SM,
                LangOpts) +
            " \"" + Twine(Mode) + "\"")
        .str();

  StringRef SR = cast<StringLiteral>(Arg->IgnoreParenCasts())->getString();
  return ("\"" + SR + Twine(Mode) + "\"").str();
}
} // namespace

const char *CloexecCheck::FuncDeclBindingStr = "funcDecl";

const char *CloexecCheck::FuncBindingStr ="func";

void CloexecCheck::registerMatchersImpl(
    MatchFinder *Finder, internal::Matcher<FunctionDecl> Function) {
  // We assume all the checked APIs are C functions.
  Finder->addMatcher(
      callExpr(
          callee(functionDecl(isExternC(), Function).bind(FuncDeclBindingStr)))
          .bind(FuncBindingStr),
      this);
}

void CloexecCheck::insertMacroFlag(const MatchFinder::MatchResult &Result,
                                   StringRef MacroFlag, int ArgPos) {
  const auto *MatchedCall = Result.Nodes.getNodeAs<CallExpr>(FuncBindingStr);
  const auto *FlagArg = MatchedCall->getArg(ArgPos);
  const auto *FD = Result.Nodes.getNodeAs<FunctionDecl>(FuncDeclBindingStr);
  SourceManager &SM = *Result.SourceManager;

  if (utils::exprHasBitFlagWithSpelling(FlagArg->IgnoreParenCasts(), SM,
                                        Result.Context->getLangOpts(),
                                        MacroFlag))
    return;

  SourceLocation EndLoc =
      Lexer::getLocForEndOfToken(SM.getFileLoc(FlagArg->getLocEnd()), 0, SM,
                                 Result.Context->getLangOpts());

  diag(EndLoc, "%0 should use %1 where possible")
      << FD << MacroFlag
      << FixItHint::CreateInsertion(EndLoc, (Twine(" | ") + MacroFlag).str());
}

void CloexecCheck::replaceFunc(const MatchFinder::MatchResult &Result,
                               StringRef WarningMsg, StringRef FixMsg) {
  const auto *MatchedCall = Result.Nodes.getNodeAs<CallExpr>(FuncBindingStr);
  diag(MatchedCall->getLocStart(), WarningMsg)
      << FixItHint::CreateReplacement(MatchedCall->getSourceRange(), FixMsg);
}

void CloexecCheck::insertStringFlag(
    const ast_matchers::MatchFinder::MatchResult &Result, const char Mode,
    const int ArgPos) {
  const auto *MatchedCall = Result.Nodes.getNodeAs<CallExpr>(FuncBindingStr);
  const auto *FD = Result.Nodes.getNodeAs<FunctionDecl>(FuncDeclBindingStr);
  const auto *ModeArg = MatchedCall->getArg(ArgPos);

  // Check if the <Mode> may be in the mode string.
  const auto *ModeStr = dyn_cast<StringLiteral>(ModeArg->IgnoreParenCasts());
  if (!ModeStr || (ModeStr->getString().find(Mode) != StringRef::npos))
    return;

  const std::string &ReplacementText = buildFixMsgForStringFlag(
      ModeArg, *Result.SourceManager, Result.Context->getLangOpts(), Mode);

  diag(ModeArg->getLocStart(), "use %0 mode '%1' to set O_CLOEXEC")
      << FD << std::string(1, Mode)
      << FixItHint::CreateReplacement(ModeArg->getSourceRange(),
                                      ReplacementText);
}

StringRef CloexecCheck::getSpellingArg(const MatchFinder::MatchResult &Result,
                                       int N) const {
  const auto *MatchedCall = Result.Nodes.getNodeAs<CallExpr>(FuncBindingStr);
  const SourceManager &SM = *Result.SourceManager;
  return Lexer::getSourceText(
      CharSourceRange::getTokenRange(MatchedCall->getArg(N)->getSourceRange()),
      SM, Result.Context->getLangOpts());
}

} // namespace android
} // namespace tidy
} // namespace clang
