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

using namespace clang::ast_matchers;

namespace clang {
namespace tidy {
namespace modernize {

static const char SpecialFunction[] = "SpecialFunction";
static const char DeletedNotPublic[] = "DeletedNotPublic";

void UseEqualsDeleteCheck::registerMatchers(MatchFinder *Finder) {
  if (!getLangOpts().CPlusPlus)
    return;

  auto PrivateSpecialFn = cxxMethodDecl(
      isPrivate(),
      anyOf(cxxConstructorDecl(anyOf(isDefaultConstructor(),
                                     isCopyConstructor(), isMoveConstructor())),
            cxxMethodDecl(
                anyOf(isCopyAssignmentOperator(), isMoveAssignmentOperator())),
            cxxDestructorDecl()));

  Finder->addMatcher(
      cxxMethodDecl(
          PrivateSpecialFn,
          unless(anyOf(hasBody(stmt()), isDefaulted(), isDeleted(),
                       ast_matchers::isTemplateInstantiation(),
                       // Ensure that all methods except private special member
                       // functions are defined.
                       hasParent(cxxRecordDecl(hasMethod(unless(
                           anyOf(PrivateSpecialFn, hasBody(stmt()), isPure(),
                                 isDefaulted(), isDeleted()))))))))
          .bind(SpecialFunction),
      this);

  Finder->addMatcher(
      cxxMethodDecl(isDeleted(), unless(isPublic())).bind(DeletedNotPublic),
      this);
}

void UseEqualsDeleteCheck::check(const MatchFinder::MatchResult &Result) {
  if (const auto *Func =
          Result.Nodes.getNodeAs<CXXMethodDecl>(SpecialFunction)) {
    SourceLocation EndLoc = Lexer::getLocForEndOfToken(
        Func->getLocEnd(), 0, *Result.SourceManager, getLangOpts());

    // FIXME: Improve FixItHint to make method public
    diag(Func->getLocation(),
         "use '= delete' to prohibit calling of a special member function")
        << FixItHint::CreateInsertion(EndLoc, " = delete");
  } else if (const auto *Func =
                 Result.Nodes.getNodeAs<CXXMethodDecl>(DeletedNotPublic)) {
    // FIXME: Add FixItHint to make method public
    diag(Func->getLocation(), "deleted member function should be public");
  }
}

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