//===--- MissingStdForwardCheck.cpp - clang-tidy --------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "MissingStdForwardCheck.h"
#include "../utils/Matchers.h"
#include "clang/AST/ASTContext.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/Basic/IdentifierTable.h"

using namespace clang::ast_matchers;

namespace clang::tidy::cppcoreguidelines {

namespace {

using matchers::hasUnevaluatedContext;

AST_MATCHER_P(QualType, possiblyPackExpansionOf,
              ast_matchers::internal::Matcher<QualType>, InnerMatcher) {
  return InnerMatcher.matches(Node.getNonPackExpansionType(), Finder, Builder);
}

AST_MATCHER(ParmVarDecl, isTemplateTypeParameter) {
  ast_matchers::internal::Matcher<QualType> Inner = possiblyPackExpansionOf(
      qualType(rValueReferenceType(),
               references(templateTypeParmType(
                   hasDeclaration(templateTypeParmDecl()))),
               unless(references(qualType(isConstQualified())))));
  if (!Inner.matches(Node.getType(), Finder, Builder))
    return false;

  const auto *Function = dyn_cast<FunctionDecl>(Node.getDeclContext());
  if (!Function)
    return false;

  const FunctionTemplateDecl *FuncTemplate =
      Function->getDescribedFunctionTemplate();
  if (!FuncTemplate)
    return false;

  QualType ParamType =
      Node.getType().getNonPackExpansionType()->getPointeeType();
  const auto *TemplateType = ParamType->getAsCanonical<TemplateTypeParmType>();
  if (!TemplateType)
    return false;

  return TemplateType->getDepth() ==
         FuncTemplate->getTemplateParameters()->getDepth();
}

AST_MATCHER_P(NamedDecl, hasSameNameAsBoundNode, std::string, BindingID) {
  IdentifierInfo *II = Node.getIdentifier();
  if (nullptr == II)
    return false;
  StringRef Name = II->getName();

  return Builder->removeBindings(
      [this, Name](const ast_matchers::internal::BoundNodesMap &Nodes) {
        const DynTypedNode &BN = Nodes.getNode(this->BindingID);
        if (const auto *ND = BN.get<NamedDecl>()) {
          if (!isa<FieldDecl, CXXMethodDecl, VarDecl>(ND))
            return true;
          return ND->getName() != Name;
        }
        return true;
      });
}

AST_MATCHER_P(LambdaCapture, hasCaptureKind, LambdaCaptureKind, Kind) {
  return Node.getCaptureKind() == Kind;
}

AST_MATCHER_P(LambdaExpr, hasCaptureDefaultKind, LambdaCaptureDefault, Kind) {
  return Node.getCaptureDefault() == Kind;
}

AST_MATCHER(VarDecl, hasIdentifier) {
  const IdentifierInfo *ID = Node.getIdentifier();
  return ID != nullptr && !ID->isPlaceholder();
}

} // namespace

void MissingStdForwardCheck::registerMatchers(MatchFinder *Finder) {
  auto RefToParmImplicit = allOf(
      equalsBoundNode("var"), hasInitializer(ignoringParenImpCasts(
                                  declRefExpr(to(equalsBoundNode("param"))))));
  auto RefToParm = capturesVar(
      varDecl(anyOf(hasSameNameAsBoundNode("param"), RefToParmImplicit)));

  auto CaptureInRef =
      allOf(hasCaptureDefaultKind(LambdaCaptureDefault::LCD_ByRef),
            unless(hasAnyCapture(
                capturesVar(varDecl(hasSameNameAsBoundNode("param"))))));
  auto CaptureByRefExplicit = hasAnyCapture(
      allOf(hasCaptureKind(LambdaCaptureKind::LCK_ByRef), RefToParm));

  auto CapturedInBody = lambdaExpr(anyOf(CaptureInRef, CaptureByRefExplicit));
  auto CapturedInCaptureList = hasAnyCapture(capturesVar(
      varDecl(hasInitializer(ignoringParenImpCasts(equalsBoundNode("call"))))));

  auto CapturedInLambda = hasDeclContext(cxxRecordDecl(
      isLambda(),
      hasParent(lambdaExpr(forCallable(equalsBoundNode("func")),
                           anyOf(CapturedInCaptureList, CapturedInBody)))));

  auto ToParam = hasAnyParameter(parmVarDecl(equalsBoundNode("param")));

  auto ForwardCallMatcher = callExpr(
      callExpr().bind("call"), argumentCountIs(1),
      hasArgument(0, declRefExpr(to(varDecl().bind("var")))),
      forCallable(
          anyOf(allOf(equalsBoundNode("func"),
                      functionDecl(hasAnyParameter(parmVarDecl(allOf(
                          equalsBoundNode("param"), equalsBoundNode("var")))))),
                CapturedInLambda)),
      callee(unresolvedLookupExpr(hasAnyDeclaration(
          namedDecl(hasUnderlyingDecl(hasName(ForwardFunction)))))),

      unless(anyOf(hasAncestor(typeLoc()),
                   hasAncestor(expr(hasUnevaluatedContext())))));

  Finder->addMatcher(
      parmVarDecl(
          parmVarDecl().bind("param"), hasIdentifier(),
          unless(hasAttr(attr::Kind::Unused)), isTemplateTypeParameter(),
          hasAncestor(functionDecl().bind("func")),
          hasAncestor(functionDecl(
              isDefinition(), equalsBoundNode("func"), ToParam,
              unless(anyOf(isDeleted(), hasDescendant(ForwardCallMatcher)))))),
      this);
}

void MissingStdForwardCheck::check(const MatchFinder::MatchResult &Result) {
  const auto *Param = Result.Nodes.getNodeAs<ParmVarDecl>("param");

  if (!Param)
    return;

  diag(Param->getLocation(),
       "forwarding reference parameter %0 is never forwarded "
       "inside the function body")
      << Param;
}

MissingStdForwardCheck::MissingStdForwardCheck(StringRef Name,
                                               ClangTidyContext *Context)
    : ClangTidyCheck(Name, Context),
      ForwardFunction(Options.get("ForwardFunction", "::std::forward")) {}

void MissingStdForwardCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
  Options.store(Opts, "ForwardFunction", ForwardFunction);
}

} // namespace clang::tidy::cppcoreguidelines
