// Part of the Crubit project, under the Apache License v2.0 with LLVM
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

#ifndef CRUBIT_LIFETIME_ANNOTATIONS_FUNCTION_LIFETIMES_H_
#define CRUBIT_LIFETIME_ANNOTATIONS_FUNCTION_LIFETIMES_H_

#include <iosfwd>
#include <string>
#include <variant>

#include "lifetime_annotations/lifetime_substitutions.h"
#include "lifetime_annotations/type_lifetimes.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/Type.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Error.h"

namespace clang {
namespace tidy {
namespace lifetimes {

// Interface used to create lifetimes in FunctionLifetimes::CreateForDecl.
// CreateReturnLifetimes will be called with the ValueLifetimes that were
// created through calls to CreateParamLifetimes.
class FunctionLifetimeFactory {
 public:
  virtual ~FunctionLifetimeFactory() {}
  virtual llvm::Expected<ValueLifetimes> CreateParamLifetimes(
      clang::QualType type) const = 0;
  virtual llvm::Expected<ValueLifetimes> CreateReturnLifetimes(
      clang::QualType type,
      const llvm::SmallVector<ValueLifetimes>& param_lifetimes,
      const std::optional<ValueLifetimes>& this_lifetimes) const = 0;
};

// Implementation of FunctionLifetimeFactory that defers to a LifetimeFactory.
class FunctionLifetimeFactorySingleCallback : public FunctionLifetimeFactory {
 public:
  FunctionLifetimeFactorySingleCallback(LifetimeFactory factory)
      : factory_(std::move(factory)) {}
  llvm::Expected<ValueLifetimes> CreateParamLifetimes(
      clang::QualType type) const override {
    return ValueLifetimes::Create(type, factory_);
  }
  llvm::Expected<ValueLifetimes> CreateReturnLifetimes(
      clang::QualType type,
      const llvm::SmallVector<ValueLifetimes>& /*param_lifetimes*/,
      const std::optional<ValueLifetimes>& /*this_lifetimes*/) const override {
    return ValueLifetimes::Create(type, factory_);
  }

 private:
  LifetimeFactory factory_;
};

// Lifetimes for the signature of a function.
class FunctionLifetimes {
 public:
  // Returns lifetimes for the `i`-th parameter.
  // These are the same number and order as FunctionDecl::parameters().
  const ValueLifetimes& GetParamLifetimes(size_t i) const {
    return param_lifetimes_[i];
  }

  // Returns the number of function parameters (excluding the implicit `this).
  const size_t GetNumParams() const { return param_lifetimes_.size(); }

  // Lifetimes for the return type.
  const ValueLifetimes& GetReturnLifetimes() const { return return_lifetimes_; }

  // Lifetimes for the `this` parameter for non-static member functions.
  const ValueLifetimes& GetThisLifetimes() const {
    assert(this_lifetimes_.has_value());
    return *this_lifetimes_;
  }

  // Returns whether this FunctionLifetimes represents a non-static method.
  bool IsNonStaticMethod() const { return this_lifetimes_.has_value(); }

  // Creates lifetimes for a function with a given decl.
  // Only fails if lifetime_factory fails.
  // Lifetimes will be created first for the object parameter, if any, then for
  // parameters in increasing order, and finally for the return type.
  static llvm::Expected<FunctionLifetimes> CreateForDecl(
      const clang::FunctionDecl* function,
      const FunctionLifetimeFactory& lifetime_factory);

  static llvm::Expected<FunctionLifetimes> CreateForFunctionType(
      const clang::FunctionProtoType* function,
      const FunctionLifetimeFactory& lifetime_factory);

  // TODO(veluca): add support for pointer-to-member-fn.

  // Creates a copy of this FunctionLifetimes with the same structure, but
  // fresh, unrelated lifetimes independently of whether the lifetimes where
  // identical in this FunctionLifetimes.
  // TODO(veluca): remove this method once FunctionLifetimes keeps track of its
  // own type, and replace it with an appropriate call to Create().
  llvm::Expected<FunctionLifetimes> CreateCopy(
      const LifetimeFactory& factory) const;

  // Returns FunctionLifetimes for a method that this method overrides.
  // Precondition: `IsNonStaticMethod()` is true,
  // `method`'s signature is compatible with this FunctionLifetimes except for
  // the `this` parameter.
  FunctionLifetimes ForOverriddenMethod(const clang::CXXMethodDecl* method);

  // Checks if this FunctionLifetimes represents valid lifetimes for the given
  // Decl.
  bool IsValidForDecl(const clang::FunctionDecl* function);

  // Returns a human-readable representation of `func_lifetimes`. Formats
  // lifetimes using `formatter`, or Lifetime::DebugString() if `formatter` is
  // null.
  std::string DebugString(LifetimeFormatter formatter = [](Lifetime l) {
    return l.DebugString();
  }) const;

  // Returns true if `predicate` returns true for any lifetime that appears in
  // the `FunctionLifetimes`.
  bool HasAny(const std::function<bool(Lifetime)>& predicate) const;

  // Returns the set of all lifetimes that are either lifetime parameters of
  // this function, or (if this FunctionLifetimes is a declaration of a method)
  // of the enclosing class.
  llvm::DenseSet<Lifetime> AllFreeLifetimes() const;

  // Applies `subst` to all lifetimes in this FunctionLifetimes.
  // Any lifetime parameter declarations will moved to the innermost location
  // that is valid for the new lifetimes. Note that this operation is
  // well-defined and declarations of lifetime parameters can only "move up";
  // in particular, it results lifetime parameters being as tightly bound as
  // possible, which is what we want inference to infer.
  void SubstituteLifetimes(const LifetimeSubstitutions& subst);

  // Traverses all the lifetimes in the function signature, recursively. The
  // visit is done in post-order on the lifetime tree of this type.
  void Traverse(std::function<void(Lifetime&, Variance)> visitor);
  void Traverse(std::function<void(const Lifetime&, Variance)> visitor) const;

 private:
  llvm::SmallVector<ValueLifetimes> param_lifetimes_;
  ValueLifetimes return_lifetimes_;
  std::optional<ValueLifetimes> this_lifetimes_;

  static llvm::Expected<FunctionLifetimes> Create(
      const clang::FunctionProtoType* type, const clang::QualType this_type,
      const FunctionLifetimeFactory& lifetime_factory);
};

std::ostream& operator<<(std::ostream& os,
                         const FunctionLifetimes& func_lifetimes);

// An error that occurred while analyzing a function.
struct FunctionAnalysisError {
  explicit FunctionAnalysisError(llvm::StringRef message = "")
      : message(message) {}

  explicit FunctionAnalysisError(const llvm::Error& err) {
    ::llvm::raw_string_ostream stream(message);
    stream << err;
  }

  // Human-readable description of the error.
  std::string message;
};

// Lifetimes for a function, or an error if we couldn't analyze the function.
// We can't use llvm::Expected<FunctionLifetimes> for this because:
// - llvm::Expected doesn't allow us to check for an error state without moving
//   the error out of the llvm::Expected
// - llvm::Expected asserts in the destructor if we didn't check for an error
using FunctionLifetimesOrError =
    std::variant<FunctionAnalysisError, FunctionLifetimes>;

}  // namespace lifetimes
}  // namespace tidy
}  // namespace clang

#endif  // CRUBIT_LIFETIME_ANNOTATIONS_FUNCTION_LIFETIMES_H_
