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

using namespace clang::ast_matchers;

namespace clang {
namespace tidy {
namespace performance {

NoAutomaticMoveCheck::NoAutomaticMoveCheck(StringRef Name,
                                           ClangTidyContext *Context)
    : ClangTidyCheck(Name, Context),
      AllowedTypes(
          utils::options::parseStringList(Options.get("AllowedTypes", ""))) {}

void NoAutomaticMoveCheck::registerMatchers(MatchFinder *Finder) {
  const auto ConstLocalVariable =
      varDecl(hasLocalStorage(), unless(hasType(lValueReferenceType())),
              hasType(qualType(
                  isConstQualified(),
                  hasCanonicalType(matchers::isExpensiveToCopy()),
                  unless(hasDeclaration(namedDecl(
                      matchers::matchesAnyListedName(AllowedTypes)))))))
          .bind("vardecl");

  // A matcher for a `DstT::DstT(const Src&)` where DstT also has a
  // `DstT::DstT(Src&&)`.
  const auto LValueRefCtor = cxxConstructorDecl(
      hasParameter(0,
                   hasType(lValueReferenceType(pointee(type().bind("SrcT"))))),
      ofClass(cxxRecordDecl(hasMethod(cxxConstructorDecl(
          hasParameter(0, hasType(rValueReferenceType(
                              pointee(type(equalsBoundNode("SrcT")))))))))));

  Finder->addMatcher(
      traverse(TK_AsIs,
               returnStmt(hasReturnValue(
                   ignoringElidableConstructorCall(ignoringParenImpCasts(
                       cxxConstructExpr(
                           hasDeclaration(LValueRefCtor),
                           hasArgument(0, ignoringParenImpCasts(declRefExpr(
                                              to(ConstLocalVariable)))))
                           .bind("ctor_call")))))),
      this);
}

void NoAutomaticMoveCheck::check(const MatchFinder::MatchResult &Result) {
  const auto *Var = Result.Nodes.getNodeAs<VarDecl>("vardecl");
  const auto *CtorCall = Result.Nodes.getNodeAs<Expr>("ctor_call");
  diag(CtorCall->getExprLoc(), "constness of '%0' prevents automatic move")
      << Var->getName();
}

void NoAutomaticMoveCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
  Options.store(Opts, "AllowedTypes",
                utils::options::serializeStringList(AllowedTypes));
}

} // namespace performance
} // namespace tidy
} // namespace clang
