//===--- UseTransparentFunctorsCheck.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 "UseTransparentFunctorsCheck.h"
#include "clang/AST/ASTContext.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"

using namespace clang::ast_matchers;

namespace clang {
namespace tidy {
namespace modernize {

UseTransparentFunctorsCheck::UseTransparentFunctorsCheck(
    StringRef Name, ClangTidyContext *Context)
    : ClangTidyCheck(Name, Context), SafeMode(Options.get("SafeMode", 0)) {}

void UseTransparentFunctorsCheck::storeOptions(
    ClangTidyOptions::OptionMap &Opts) {
  Options.store(Opts, "SafeMode", SafeMode ? 1 : 0);
}

void UseTransparentFunctorsCheck::registerMatchers(MatchFinder *Finder) {
  if (!getLangOpts().CPlusPlus14)
    return;

  const auto TransparentFunctors =
      classTemplateSpecializationDecl(
          unless(hasAnyTemplateArgument(refersToType(voidType()))),
          hasAnyName("::std::plus", "::std::minus", "::std::multiplies",
                     "::std::divides", "::std::modulus", "::std::negate",
                     "::std::equal_to", "::std::not_equal_to", "::std::greater",
                     "::std::less", "::std::greater_equal", "::std::less_equal",
                     "::std::logical_and", "::std::logical_or",
                     "::std::logical_not", "::std::bit_and", "::std::bit_or",
                     "::std::bit_xor", "::std::bit_not"))
          .bind("FunctorClass");

  // Non-transparent functor mentioned as a template parameter. FIXIT.
  Finder->addMatcher(
      loc(qualType(
              unless(elaboratedType()),
              hasDeclaration(classTemplateSpecializationDecl(
                  unless(hasAnyTemplateArgument(templateArgument(refersToType(
                      qualType(pointsTo(qualType(isAnyCharacter()))))))),
                  hasAnyTemplateArgument(
                      templateArgument(refersToType(qualType(hasDeclaration(
                                           TransparentFunctors))))
                          .bind("Functor"))))))
          .bind("FunctorParentLoc"),
      this);

  if (SafeMode)
    return;

  // Non-transparent functor constructed. No FIXIT. There is no easy way
  // to rule out the problematic char* vs string case.
  Finder->addMatcher(cxxConstructExpr(hasDeclaration(cxxMethodDecl(
                                          ofClass(TransparentFunctors))),
                                      unless(isInTemplateInstantiation()))
                         .bind("FuncInst"),
                     this);
}

static const StringRef Message = "prefer transparent functors '%0'";

template <typename T> static T getInnerTypeLocAs(TypeLoc Loc) {
  T Result;
  while (Result.isNull() && !Loc.isNull()) {
    Result = Loc.getAs<T>();
    Loc = Loc.getNextTypeLoc();
  }
  return Result;
}

void UseTransparentFunctorsCheck::check(
    const MatchFinder::MatchResult &Result) {
  const auto *FuncClass =
      Result.Nodes.getNodeAs<ClassTemplateSpecializationDecl>("FunctorClass");
  if (const auto *FuncInst =
          Result.Nodes.getNodeAs<CXXConstructExpr>("FuncInst")) {
    diag(FuncInst->getLocStart(), Message)
          << (FuncClass->getName() + "<>").str();
    return;
  }

  const auto *Functor = Result.Nodes.getNodeAs<TemplateArgument>("Functor");
  const auto FunctorParentLoc =
      Result.Nodes.getNodeAs<TypeLoc>("FunctorParentLoc")
          ->getAs<TemplateSpecializationTypeLoc>();

  if (!FunctorParentLoc)
    return;

  unsigned ArgNum = 0;
  const auto *FunctorParentType =
      FunctorParentLoc.getType()->castAs<TemplateSpecializationType>();
  for (; ArgNum < FunctorParentType->getNumArgs(); ++ArgNum) {
    const TemplateArgument &Arg = FunctorParentType->getArg(ArgNum);
    if (Arg.getKind() != TemplateArgument::Type)
      continue;
    QualType ParentArgType = Arg.getAsType();
    if (ParentArgType->isRecordType() &&
        ParentArgType->getAsCXXRecordDecl() ==
            Functor->getAsType()->getAsCXXRecordDecl())
      break;
  }
  // Functor is a default template argument.
  if (ArgNum == FunctorParentType->getNumArgs())
    return;
  TemplateArgumentLoc FunctorLoc = FunctorParentLoc.getArgLoc(ArgNum);
  auto FunctorTypeLoc = getInnerTypeLocAs<TemplateSpecializationTypeLoc>(
      FunctorLoc.getTypeSourceInfo()->getTypeLoc());
  if (FunctorTypeLoc.isNull())
    return;

  SourceLocation ReportLoc = FunctorLoc.getLocation();
  diag(ReportLoc, Message) << (FuncClass->getName() + "<>").str()
                           << FixItHint::CreateRemoval(
                                  FunctorTypeLoc.getArgLoc(0).getSourceRange());
}

} // namespace modernize
} // namespace tidy
} // namespace clang
