//===--- ExceptionAnalyzer.h - clang-tidy -----------------------*- C++ -*-===//
//
// 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
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_UTILS_EXCEPTION_ANALYZER_H
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_UTILS_EXCEPTION_ANALYZER_H

#include "clang/AST/ASTContext.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/StringSet.h"

namespace clang {
namespace tidy {
namespace utils {

/// This class analysis if a `FunctionDecl` can in principle throw an
/// exception, either directly or indirectly. It can be configured to ignore
/// custom exception types.
class ExceptionAnalyzer {
public:
  enum class State : std::int8_t {
    Throwing = 0,    ///< The function can definitly throw given an AST.
    NotThrowing = 1, ///< This function can not throw, given an AST.
    Unknown = 2,     ///< This can happen for extern functions without available
                     ///< definition.
  };

  /// Bundle the gathered information about an entity like a function regarding
  /// it's exception behaviour. The 'NonThrowing'-state can be considered as the
  /// neutral element in terms of information propagation.
  /// In the case of 'Throwing' state it is possible that 'getExceptionTypes'
  /// does not include *ALL* possible types as there is the possibility that
  /// an 'Unknown' function is called that might throw a previously unknown
  /// exception at runtime.
  class ExceptionInfo {
  public:
    using Throwables = llvm::SmallSet<const Type *, 2>;
    static ExceptionInfo createUnknown() {
      return ExceptionInfo(State::Unknown);
    }
    static ExceptionInfo createNonThrowing() {
      return ExceptionInfo(State::Throwing);
    }

    /// By default the exception situation is unknown and must be
    /// clarified step-wise.
    ExceptionInfo() : Behaviour(State::NotThrowing), ContainsUnknown(false) {}
    ExceptionInfo(State S)
        : Behaviour(S), ContainsUnknown(S == State::Unknown) {}

    ExceptionInfo(const ExceptionInfo &) = default;
    ExceptionInfo &operator=(const ExceptionInfo &) = default;
    ExceptionInfo(ExceptionInfo &&) = default;
    ExceptionInfo &operator=(ExceptionInfo &&) = default;

    State getBehaviour() const { return Behaviour; }

    /// Register a single exception type as recognized potential exception to be
    /// thrown.
    void registerException(const Type *ExceptionType);

    /// Registers a `SmallVector` of exception types as recognized potential
    /// exceptions to be thrown.
    void registerExceptions(const Throwables &Exceptions);

    /// Updates the local state according to the other state. That means if
    /// for example a function contains multiple statements the 'ExceptionInfo'
    /// for the final function is the merged result of each statement.
    /// If one of these statements throws the whole function throws and if one
    /// part is unknown and the rest is non-throwing the result will be
    /// unknown.
    ExceptionInfo &merge(const ExceptionInfo &Other);

    /// This method is useful in case 'catch' clauses are analyzed as it is
    /// possible to catch multiple exception types by one 'catch' if they
    /// are a subclass of the 'catch'ed exception type.
    /// Returns 'true' if some exceptions were filtered, otherwise 'false'.
    bool filterByCatch(const Type *BaseClass);

    /// Filter the set of thrown exception type against a set of ignored
    /// types that shall not be considered in the exception analysis.
    /// This includes explicit `std::bad_alloc` ignoring as separate option.
    ExceptionInfo &
    filterIgnoredExceptions(const llvm::StringSet<> &IgnoredTypes,
                            bool IgnoreBadAlloc);

    /// Clear the state to 'NonThrowing' to make the corresponding entity
    /// neutral.
    void clear();

    /// References the set of known exception types that can escape from the
    /// corresponding entity.
    const Throwables &getExceptionTypes() const { return ThrownExceptions; }

    /// Signal if the there is any 'Unknown' element within the scope of
    /// the related entity. This might be relevant if the entity is 'Throwing'
    /// and to ensure that no other exception then 'getExceptionTypes' can
    /// occur. If there is an 'Unknown' element this can not be guaranteed.
    bool containsUnknownElements() const { return ContainsUnknown; }

  private:
    /// Recalculate the 'Behaviour' for example after filtering.
    void reevaluateBehaviour();

    /// Keep track if the entity related to this 'ExceptionInfo' can in princple
    /// throw, if it's unknown or if it won't throw.
    State Behaviour;

    /// Keep track if the entity contains any unknown elements to keep track
    /// of the certainty of decisions and/or correct 'Behaviour' transition
    /// after filtering.
    bool ContainsUnknown;

    /// 'ThrownException' is empty if the 'Behaviour' is either 'NotThrowing' or
    /// 'Unknown'.
    Throwables ThrownExceptions;
  };

  ExceptionAnalyzer() = default;

  void ignoreBadAlloc(bool ShallIgnore) { IgnoreBadAlloc = ShallIgnore; }
  void ignoreExceptions(llvm::StringSet<> ExceptionNames) {
    IgnoredExceptions = std::move(ExceptionNames);
  }

  ExceptionInfo analyze(const FunctionDecl *Func);
  ExceptionInfo analyze(const Stmt *Stmt);

private:
  ExceptionInfo
  throwsException(const FunctionDecl *Func,
                  llvm::SmallSet<const FunctionDecl *, 32> &CallStack);
  ExceptionInfo
  throwsException(const Stmt *St, const ExceptionInfo::Throwables &Caught,
                  llvm::SmallSet<const FunctionDecl *, 32> &CallStack);

  ExceptionInfo analyzeImpl(const FunctionDecl *Func);
  ExceptionInfo analyzeImpl(const Stmt *Stmt);

  template <typename T> ExceptionInfo analyzeDispatch(const T *Node);

  bool IgnoreBadAlloc = true;
  llvm::StringSet<> IgnoredExceptions;
  std::map<const FunctionDecl *, ExceptionInfo> FunctionCache;
};

} // namespace utils
} // namespace tidy
} // namespace clang

#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_UTILS_EXCEPTION_ANALYZER_H
