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

#include <algorithm>

using namespace clang::ast_matchers;

namespace clang {
namespace tidy {
namespace 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->getLocStart(), Callee->getLocEnd()),
                               SM, LangOpts);

  if (CallRange.isValid()) {
    const std::string TypeName =
        TypeParmDecl->getIdentifier()
            ? 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 NamespaceDecl *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) {
  if (!getLangOpts().CPlusPlus11)
    return;

  // 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 (!std::count(Params->begin(), Params->end(), 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 bugprone
} // namespace tidy
} // namespace clang
