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

using namespace clang::ast_matchers;

namespace clang::tidy::bugprone {

namespace {

AST_MATCHER(EnumDecl, isCompleteAndHasNoZeroValue) {
  const EnumDecl *Definition = Node.getDefinition();
  return Definition && Node.isComplete() &&
         std::none_of(Definition->enumerator_begin(),
                      Definition->enumerator_end(),
                      [](const EnumConstantDecl *Value) {
                        return Value->getInitVal().isZero();
                      });
}

} // namespace

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

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

bool NonZeroEnumToBoolConversionCheck::isLanguageVersionSupported(
    const LangOptions &LangOpts) const {
  return LangOpts.CPlusPlus;
}

void NonZeroEnumToBoolConversionCheck::registerMatchers(MatchFinder *Finder) {
  // Excluding bitwise operators (binary and overload) to avoid false-positives
  // in code like this 'if (e & SUCCESS) {'.
  auto ExcludedOperators = binaryOperation(hasAnyOperatorName(
      "|", "&", "^", "<<", ">>", "~", "|=", "&=", "^=", "<<=", ">>="));

  Finder->addMatcher(
      castExpr(hasCastKind(CK_IntegralToBoolean),
               unless(isExpansionInSystemHeader()), hasType(booleanType()),
               hasSourceExpression(
                   expr(hasType(qualType(hasCanonicalType(hasDeclaration(
                            enumDecl(isCompleteAndHasNoZeroValue(),
                                     unless(matchers::matchesAnyListedName(
                                         EnumIgnoreList)))
                                .bind("enum"))))),
                        unless(declRefExpr(to(enumConstantDecl()))),
                        unless(ignoringParenImpCasts(ExcludedOperators)))),
               unless(hasAncestor(staticAssertDecl())))
          .bind("cast"),
      this);
}

void NonZeroEnumToBoolConversionCheck::check(
    const MatchFinder::MatchResult &Result) {
  const auto *Cast = Result.Nodes.getNodeAs<CastExpr>("cast");
  const auto *Enum = Result.Nodes.getNodeAs<EnumDecl>("enum");

  diag(Cast->getExprLoc(), "conversion of %0 into 'bool' will always return "
                           "'true', enum doesn't have a zero-value enumerator")
      << Enum;
  diag(Enum->getLocation(), "enum is defined here", DiagnosticIDs::Note);
}

} // namespace clang::tidy::bugprone
