Repository: llvm/llvm-project
File: clang-tools-extra/clang-tidy/modernize/UseEqualsDeleteCheck.cpp (C++)

Code before:
}

AST_MATCHER(Decl, isUsed) { return Node.isUsed(); }

AST_MATCHER(CXXMethodDecl, isSpecialFunction) {
  if (const auto *Constructor = dyn_cast<CXXConstructorDecl>(&Node))
    return Constructor->isDefaultConstructor() ||
           Constructor->isCopyOrMoveConstructor();

  return isa<CXXDestructorDecl>(Node) || Node.isCopyAssignmentOperator() ||
         Node.isMoveAssignmentOperator();
}

AST_MATCHER(CXXMethodDecl, hasPublicOverload) {
  const DeclContext::lookup_result LookupResult =
      Node.getParent()->lookup(Node.getNameInfo().getName());

  if (LookupResult.isSingleResult())
    return false; // No overloads

  auto IsPublicOverload = [](const Decl *Overload) {
    return isa<CXXMethodDecl>(Overload) && Overload->getAccess() == AS_public;
  };

  return std::any_of(LookupResult.begin(), LookupResult.end(),
                     IsPublicOverload);
}
} // namespace

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

UseEqualsDeleteCheck::UseEqualsDeleteCheck(StringRef Name,
                                           ClangTidyContext *Context)
    : ClangTidyCheck(Name, Context),
      IgnoreMacros(Options.get("IgnoreMacros", true)) {}

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

void UseEqualsDeleteCheck::registerMatchers(MatchFinder *Finder) {
  auto PrivateSpecialFn = cxxMethodDecl(isPrivate(), isSpecialFunction());

  Finder->addMatcher(
      cxxMethodDecl(
          PrivateSpecialFn, unless(hasAnyDefinition()), unless(isUsed()),
          // Ensure that all methods except private special member functions are
          // defined.
          unless(ofClass(hasMethod(cxxMethodDecl(unless(PrivateSpecialFn),
                                                 unless(hasAnyDefinition()))))))

Review comment (suggestion):
```suggestion
  return llvm::any_of(LookupResult, IsPublicOverload);
```

Code after:

AST_MATCHER(Decl, isUsed) { return Node.isUsed(); }

AST_MATCHER(CXXMethodDecl, isSpecialFunction) {
  if (const auto *Constructor = dyn_cast<CXXConstructorDecl>(&Node))
    return Constructor->isDefaultConstructor() ||
           Constructor->isCopyOrMoveConstructor();

  return isa<CXXDestructorDecl>(Node) || Node.isCopyAssignmentOperator() ||
         Node.isMoveAssignmentOperator();
}

AST_MATCHER(CXXMethodDecl, hasPublicOverload) {
  const DeclContext::lookup_result LookupResult =
      Node.getParent()->lookup(Node.getNameInfo().getName());

  if (LookupResult.isSingleResult())
    return false; // No overloads

  static constexpr auto IsPublicOverload = [](const Decl *Overload) {
    return isa<CXXMethodDecl, FunctionTemplateDecl>(Overload) &&
           Overload->getAccess() == AS_public;
  };

  return llvm::any_of(LookupResult, IsPublicOverload);
}
} // namespace

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

UseEqualsDeleteCheck::UseEqualsDeleteCheck(StringRef Name,
                                           ClangTidyContext *Context)
    : ClangTidyCheck(Name, Context),
      IgnoreMacros(Options.get("IgnoreMacros", true)) {}

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

void UseEqualsDeleteCheck::registerMatchers(MatchFinder *Finder) {
  auto PrivateSpecialFn = cxxMethodDecl(isPrivate(), isSpecialFunction());

  Finder->addMatcher(
      cxxMethodDecl(
          PrivateSpecialFn, unless(hasAnyDefinition()), unless(isUsed()),
          // Ensure that all methods except private special member functions are
          // defined.
          unless(ofClass(hasMethod(cxxMethodDecl(unless(PrivateSpecialFn),
                                                 unless(hasAnyDefinition()))))))
          .bind(SpecialFunction),