//===--- MultiwayPathsCoveredCheck.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 "MultiwayPathsCoveredCheck.h"
#include "clang/AST/ASTContext.h"

#include <limits>

using namespace clang::ast_matchers;

namespace clang {
namespace tidy {
namespace hicpp {

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

void MultiwayPathsCoveredCheck::registerMatchers(MatchFinder *Finder) {
  Finder->addMatcher(
      switchStmt(
          hasCondition(expr(
              // Match on switch statements that have either a bit-field or
              // an integer condition. The ordering in 'anyOf()' is
              // important because the last condition is the most general.
              anyOf(ignoringImpCasts(memberExpr(hasDeclaration(
                        fieldDecl(isBitField()).bind("bitfield")))),
                    ignoringImpCasts(declRefExpr().bind("non-enum-condition"))),
              // 'unless()' must be the last match here and must be bound,
              // otherwise the matcher does not work correctly, because it
              // will not explicitly ignore enum conditions.
              unless(ignoringImpCasts(
                  declRefExpr(hasType(enumType())).bind("enum-condition"))))))
          .bind("switch"),
      this);

  // This option is noisy, therefore matching is configurable.
  if (WarnOnMissingElse) {
    Finder->addMatcher(ifStmt(hasParent(ifStmt()), unless(hasElse(anything())))
                           .bind("else-if"),
                       this);
  }
}

static std::pair<std::size_t, bool> countCaseLabels(const SwitchStmt *Switch) {
  std::size_t CaseCount = 0;
  bool HasDefault = false;

  const SwitchCase *CurrentCase = Switch->getSwitchCaseList();
  while (CurrentCase) {
    ++CaseCount;
    if (isa<DefaultStmt>(CurrentCase))
      HasDefault = true;

    CurrentCase = CurrentCase->getNextSwitchCase();
  }

  return std::make_pair(CaseCount, HasDefault);
}

/// This function calculate 2 ** Bits and returns
/// numeric_limits<std::size_t>::max() if an overflow occured.
static std::size_t twoPow(std::size_t Bits) {
  return Bits >= std::numeric_limits<std::size_t>::digits
             ? std::numeric_limits<std::size_t>::max()
             : static_cast<size_t>(1) << Bits;
}

/// Get the number of possible values that can be switched on for the type T.
///
/// \return - 0 if bitcount could not be determined
///         - numeric_limits<std::size_t>::max() when overflow appeared due to
///           more than 64 bits type size.
static std::size_t getNumberOfPossibleValues(QualType T,
                                             const ASTContext &Context) {
  // `isBooleanType` must come first because `bool` is an integral type as well
  // and would not return 2 as result.
  if (T->isBooleanType())
    return 2;
  else if (T->isIntegralType(Context))
    return twoPow(Context.getTypeSize(T));
  else
    return 1;
}

void MultiwayPathsCoveredCheck::check(const MatchFinder::MatchResult &Result) {
  if (const auto *ElseIfWithoutElse =
          Result.Nodes.getNodeAs<IfStmt>("else-if")) {
    diag(ElseIfWithoutElse->getBeginLoc(),
         "potentially uncovered codepath; add an ending else statement");
    return;
  }
  const auto *Switch = Result.Nodes.getNodeAs<SwitchStmt>("switch");
  std::size_t SwitchCaseCount;
  bool SwitchHasDefault;
  std::tie(SwitchCaseCount, SwitchHasDefault) = countCaseLabels(Switch);

  // Checks the sanity of 'switch' statements that actually do define
  // a default branch but might be degenerated by having no or only one case.
  if (SwitchHasDefault) {
    handleSwitchWithDefault(Switch, SwitchCaseCount);
    return;
  }
  // Checks all 'switch' statements that do not define a default label.
  // Here the heavy lifting happens.
  if (!SwitchHasDefault && SwitchCaseCount > 0) {
    handleSwitchWithoutDefault(Switch, SwitchCaseCount, Result);
    return;
  }
  // Warns for degenerated 'switch' statements that neither define a case nor
  // a default label.
  // FIXME: Evaluate, if emitting a fix-it to simplify that statement is 
  // reasonable.
  if (!SwitchHasDefault && SwitchCaseCount == 0) {
    diag(Switch->getBeginLoc(),
         "switch statement without labels has no effect");
    return;
  }
  llvm_unreachable("matched a case, that was not explicitly handled");
}

void MultiwayPathsCoveredCheck::handleSwitchWithDefault(
    const SwitchStmt *Switch, std::size_t CaseCount) {
  assert(CaseCount > 0 && "Switch statement with supposedly one default "
                          "branch did not contain any case labels");
  if (CaseCount == 1 || CaseCount == 2)
    diag(Switch->getBeginLoc(),
         CaseCount == 1
             ? "degenerated switch with default label only"
             : "switch could be better written as an if/else statement");
}

void MultiwayPathsCoveredCheck::handleSwitchWithoutDefault(
    const SwitchStmt *Switch, std::size_t CaseCount,
    const MatchFinder::MatchResult &Result) {
  // The matcher only works because some nodes are explicitly matched and
  // bound but ignored. This is necessary to build the excluding logic for
  // enums and 'switch' statements without a 'default' branch.
  assert(!Result.Nodes.getNodeAs<DeclRefExpr>("enum-condition") &&
         "switch over enum is handled by warnings already, explicitly ignoring "
         "them");
  // Determine the number of case labels. Because 'default' is not present
  // and duplicating case labels is not allowed this number represents
  // the number of codepaths. It can be directly compared to 'MaxPathsPossible'
  // to see if some cases are missing.
  // CaseCount == 0 is caught in DegenerateSwitch. Necessary because the
  // matcher used for here does not match on degenerate 'switch'.
  assert(CaseCount > 0 && "Switch statement without any case found. This case "
                          "should be excluded by the matcher and is handled "
                          "separatly.");
  std::size_t MaxPathsPossible = [&]() {
    if (const auto *GeneralCondition =
            Result.Nodes.getNodeAs<DeclRefExpr>("non-enum-condition")) {
      return getNumberOfPossibleValues(GeneralCondition->getType(),
                                       *Result.Context);
    }
    if (const auto *BitfieldDecl =
            Result.Nodes.getNodeAs<FieldDecl>("bitfield")) {
      return twoPow(BitfieldDecl->getBitWidthValue(*Result.Context));
    }

    return static_cast<std::size_t>(0);
  }();

  // FIXME: Transform the 'switch' into an 'if' for CaseCount == 1.
  if (CaseCount < MaxPathsPossible)
    diag(Switch->getBeginLoc(),
         CaseCount == 1 ? "switch with only one case; use an if statement"
                        : "potential uncovered code path; add a default label");
}
} // namespace hicpp
} // namespace tidy
} // namespace clang
