//===--- MoveForwardingReferenceCheck.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 "MoveForwardingReferenceCheck.h"
#include "clang/Lex/Lexer.h"

using namespace clang::ast_matchers;

namespace clang::tidy::bugprone {

static void replaceMoveWithForward(const UnresolvedLookupExpr *Callee,
                                   const ParmVarDecl *ParmVar,
                                   const TemplateTypeParmDecl *TypeParmDecl,
                                   DiagnosticBuilder &Diag,
                                   const ASTContext &Context) {
  const SourceManager &SM = Context.getSourceManager();
  const LangOptions &LangOpts = Context.getLangOpts();

  CharSourceRange CallRange =
      Lexer::makeFileCharRange(CharSourceRange::getTokenRange(
                                   Callee->getBeginLoc(), Callee->getEndLoc()),
                               SM, LangOpts);

  if (CallRange.isValid()) {
    const std::string TypeName =
        (TypeParmDecl->getIdentifier() && !TypeParmDecl->isImplicit())
            ? TypeParmDecl->getName().str()
            : (llvm::Twine("decltype(") + ParmVar->getName() + ")").str();

    const std::string ForwardName =
        (llvm::Twine("forward<") + TypeName + ">").str();

    // Create a replacement only if we see a "standard" way of calling
    // std::move(). This will hopefully prevent erroneous replacements if the
    // code does unusual things (e.g. create an alias for std::move() in
    // another namespace).
    NestedNameSpecifier *NNS = Callee->getQualifier();
    if (!NNS) {
      // Called as "move" (i.e. presumably the code had a "using std::move;").
      // We still conservatively put a "std::" in front of the forward because
      // we don't know whether the code also had a "using std::forward;".
      Diag << FixItHint::CreateReplacement(CallRange, "std::" + ForwardName);
    } else if (const NamespaceBaseDecl *Namespace = NNS->getAsNamespace()) {
      if (Namespace->getName() == "std") {
        if (!NNS->getPrefix()) {
          // Called as "std::move".
          Diag << FixItHint::CreateReplacement(CallRange,
                                               "std::" + ForwardName);
        } else if (NNS->getPrefix()->getKind() == NestedNameSpecifier::Global) {
          // Called as "::std::move".
          Diag << FixItHint::CreateReplacement(CallRange,
                                               "::std::" + ForwardName);
        }
      }
    }
  }
}

void MoveForwardingReferenceCheck::registerMatchers(MatchFinder *Finder) {
  // Matches a ParmVarDecl for a forwarding reference, i.e. a non-const rvalue
  // reference of a function template parameter type.
  auto ForwardingReferenceParmMatcher =
      parmVarDecl(
          hasType(qualType(rValueReferenceType(),
                           references(templateTypeParmType(hasDeclaration(
                               templateTypeParmDecl().bind("type-parm-decl")))),
                           unless(references(qualType(isConstQualified()))))))
          .bind("parm-var");

  Finder->addMatcher(
      callExpr(callee(unresolvedLookupExpr(
                          hasAnyDeclaration(namedDecl(
                              hasUnderlyingDecl(hasName("::std::move")))))
                          .bind("lookup")),
               argumentCountIs(1),
               hasArgument(0, ignoringParenImpCasts(declRefExpr(
                                  to(ForwardingReferenceParmMatcher)))))
          .bind("call-move"),
      this);
}

void MoveForwardingReferenceCheck::check(
    const MatchFinder::MatchResult &Result) {
  const auto *CallMove = Result.Nodes.getNodeAs<CallExpr>("call-move");
  const auto *UnresolvedLookup =
      Result.Nodes.getNodeAs<UnresolvedLookupExpr>("lookup");
  const auto *ParmVar = Result.Nodes.getNodeAs<ParmVarDecl>("parm-var");
  const auto *TypeParmDecl =
      Result.Nodes.getNodeAs<TemplateTypeParmDecl>("type-parm-decl");

  // Get the FunctionDecl and FunctionTemplateDecl containing the function
  // parameter.
  const auto *FuncForParam = dyn_cast<FunctionDecl>(ParmVar->getDeclContext());
  if (!FuncForParam)
    return;
  const FunctionTemplateDecl *FuncTemplate =
      FuncForParam->getDescribedFunctionTemplate();
  if (!FuncTemplate)
    return;

  // Check that the template type parameter belongs to the same function
  // template as the function parameter of that type. (This implies that type
  // deduction will happen on the type.)
  const TemplateParameterList *Params = FuncTemplate->getTemplateParameters();
  if (!llvm::is_contained(*Params, TypeParmDecl))
    return;

  auto Diag = diag(CallMove->getExprLoc(),
                   "forwarding reference passed to std::move(), which may "
                   "unexpectedly cause lvalues to be moved; use "
                   "std::forward() instead");

  replaceMoveWithForward(UnresolvedLookup, ParmVar, TypeParmDecl, Diag,
                         *Result.Context);
}

} // namespace clang::tidy::bugprone
