//===- Diagnostics.h - MLIR Diagnostics -------------------------*- 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
//
//===----------------------------------------------------------------------===//
//
// This file defines utilities for emitting diagnostics.
//
//===----------------------------------------------------------------------===//

#ifndef MLIR_IR_DIAGNOSTICS_H
#define MLIR_IR_DIAGNOSTICS_H

#include "mlir/IR/Location.h"
#include <functional>

namespace llvm {
class MemoryBuffer;
class SMLoc;
class SourceMgr;
} // end namespace llvm

namespace mlir {
class DiagnosticEngine;
struct LogicalResult;
class MLIRContext;
class Operation;
class OperationName;
class OpPrintingFlags;
class Type;
class Value;

namespace detail {
struct DiagnosticEngineImpl;
} // end namespace detail

/// Defines the different supported severity of a diagnostic.
enum class DiagnosticSeverity {
  Note,
  Warning,
  Error,
  Remark,
};

//===----------------------------------------------------------------------===//
// DiagnosticArgument
//===----------------------------------------------------------------------===//

/// A variant type that holds a single argument for a diagnostic.
class DiagnosticArgument {
public:
  /// Note: The constructors below are only exposed due to problems accessing
  /// constructors from type traits, they should not be used directly by users.
  // Construct from an Attribute.
  explicit DiagnosticArgument(Attribute attr);
  // Construct from a floating point number.
  explicit DiagnosticArgument(double val)
      : kind(DiagnosticArgumentKind::Double), doubleVal(val) {}
  explicit DiagnosticArgument(float val) : DiagnosticArgument(double(val)) {}
  // Construct from a signed integer.
  template <typename T>
  explicit DiagnosticArgument(
      T val, typename std::enable_if<std::is_signed<T>::value &&
                                     std::numeric_limits<T>::is_integer &&
                                     sizeof(T) <= sizeof(int64_t)>::type * = 0)
      : kind(DiagnosticArgumentKind::Integer), opaqueVal(int64_t(val)) {}
  // Construct from an unsigned integer.
  template <typename T>
  explicit DiagnosticArgument(
      T val, typename std::enable_if<std::is_unsigned<T>::value &&
                                     std::numeric_limits<T>::is_integer &&
                                     sizeof(T) <= sizeof(uint64_t)>::type * = 0)
      : kind(DiagnosticArgumentKind::Unsigned), opaqueVal(uint64_t(val)) {}
  // Construct from a string reference.
  explicit DiagnosticArgument(StringRef val)
      : kind(DiagnosticArgumentKind::String), stringVal(val) {}
  // Construct from a Type.
  explicit DiagnosticArgument(Type val);

  /// Enum that represents the different kinds of diagnostic arguments
  /// supported.
  enum class DiagnosticArgumentKind {
    Attribute,
    Double,
    Integer,
    String,
    Type,
    Unsigned,
  };

  /// Outputs this argument to a stream.
  void print(raw_ostream &os) const;

  /// Returns the kind of this argument.
  DiagnosticArgumentKind getKind() const { return kind; }

  /// Returns this argument as an Attribute.
  Attribute getAsAttribute() const;

  /// Returns this argument as a double.
  double getAsDouble() const {
    assert(getKind() == DiagnosticArgumentKind::Double);
    return doubleVal;
  }

  /// Returns this argument as a signed integer.
  int64_t getAsInteger() const {
    assert(getKind() == DiagnosticArgumentKind::Integer);
    return static_cast<int64_t>(opaqueVal);
  }

  /// Returns this argument as a string.
  StringRef getAsString() const {
    assert(getKind() == DiagnosticArgumentKind::String);
    return stringVal;
  }

  /// Returns this argument as a Type.
  Type getAsType() const;

  /// Returns this argument as an unsigned integer.
  uint64_t getAsUnsigned() const {
    assert(getKind() == DiagnosticArgumentKind::Unsigned);
    return static_cast<uint64_t>(opaqueVal);
  }

private:
  friend class Diagnostic;

  /// The kind of this argument.
  DiagnosticArgumentKind kind;

  /// The value of this argument.
  union {
    double doubleVal;
    intptr_t opaqueVal;
    StringRef stringVal;
  };
};

inline raw_ostream &operator<<(raw_ostream &os, const DiagnosticArgument &arg) {
  arg.print(os);
  return os;
}

//===----------------------------------------------------------------------===//
// Diagnostic
//===----------------------------------------------------------------------===//

/// This class contains all of the information necessary to report a diagnostic
/// to the DiagnosticEngine. It should generally not be constructed directly,
/// and instead used transitively via InFlightDiagnostic.
class Diagnostic {
  using NoteVector = std::vector<std::unique_ptr<Diagnostic>>;

public:
  Diagnostic(Location loc, DiagnosticSeverity severity)
      : loc(loc), severity(severity) {}
  Diagnostic(Diagnostic &&) = default;
  Diagnostic &operator=(Diagnostic &&) = default;

  /// Returns the severity of this diagnostic.
  DiagnosticSeverity getSeverity() const { return severity; }

  /// Returns the source location for this diagnostic.
  Location getLocation() const { return loc; }

  /// Returns the current list of diagnostic arguments.
  MutableArrayRef<DiagnosticArgument> getArguments() { return arguments; }
  ArrayRef<DiagnosticArgument> getArguments() const { return arguments; }

  /// Stream operator for inserting new diagnostic arguments.
  template <typename Arg>
  typename std::enable_if<
      !std::is_convertible<Arg, StringRef>::value &&
          std::is_constructible<DiagnosticArgument, Arg>::value,
      Diagnostic &>::type
  operator<<(Arg &&val) {
    arguments.push_back(DiagnosticArgument(std::forward<Arg>(val)));
    return *this;
  }
  Diagnostic &operator<<(StringAttr val);

  /// Stream in a string literal.
  Diagnostic &operator<<(const char *val) {
    arguments.push_back(DiagnosticArgument(val));
    return *this;
  }

  /// Stream in a Twine argument.
  Diagnostic &operator<<(char val);
  Diagnostic &operator<<(const Twine &val);
  Diagnostic &operator<<(Twine &&val);

  /// Stream in an OperationName.
  Diagnostic &operator<<(OperationName val);

  /// Stream in an Operation.
  Diagnostic &operator<<(Operation &val);
  Diagnostic &operator<<(Operation *val) {
    return *this << *val;
  }
  /// Append an operation with the given printing flags.
  Diagnostic &appendOp(Operation &val, const OpPrintingFlags &flags);

  /// Stream in a Value.
  Diagnostic &operator<<(Value val);

  /// Stream in a range.
  template <typename T, typename ValueT = llvm::detail::ValueOfRange<T>>
  std::enable_if_t<!std::is_constructible<DiagnosticArgument, T>::value,
                   Diagnostic &>
  operator<<(T &&range) {
    return appendRange(range);
  }

  /// Append a range to the diagnostic. The default delimiter between elements
  /// is ','.
  template <typename T>
  Diagnostic &appendRange(const T &c, const char *delim = ", ") {
    llvm::interleave(
        c, [this](const auto &a) { *this << a; }, [&]() { *this << delim; });
    return *this;
  }

  /// Append arguments to the diagnostic.
  template <typename Arg1, typename Arg2, typename... Args>
  Diagnostic &append(Arg1 &&arg1, Arg2 &&arg2, Args &&... args) {
    append(std::forward<Arg1>(arg1));
    return append(std::forward<Arg2>(arg2), std::forward<Args>(args)...);
  }
  /// Append one argument to the diagnostic.
  template <typename Arg> Diagnostic &append(Arg &&arg) {
    *this << std::forward<Arg>(arg);
    return *this;
  }

  /// Outputs this diagnostic to a stream.
  void print(raw_ostream &os) const;

  /// Converts the diagnostic to a string.
  std::string str() const;

  /// Attaches a note to this diagnostic. A new location may be optionally
  /// provided, if not, then the location defaults to the one specified for this
  /// diagnostic. Notes may not be attached to other notes.
  Diagnostic &attachNote(Optional<Location> noteLoc = llvm::None);

  using note_iterator = llvm::pointee_iterator<NoteVector::iterator>;
  using const_note_iterator =
      llvm::pointee_iterator<NoteVector::const_iterator>;

  /// Returns the notes held by this diagnostic.
  iterator_range<note_iterator> getNotes() {
    return llvm::make_pointee_range(notes);
  }
  iterator_range<const_note_iterator> getNotes() const {
    return llvm::make_pointee_range(notes);
  }

  /// Allow a diagnostic to be converted to 'failure'.
  operator LogicalResult() const;

private:
  Diagnostic(const Diagnostic &rhs) = delete;
  Diagnostic &operator=(const Diagnostic &rhs) = delete;

  /// The source location.
  Location loc;

  /// The severity of this diagnostic.
  DiagnosticSeverity severity;

  /// The current list of arguments.
  SmallVector<DiagnosticArgument, 4> arguments;

  /// A list of string values used as arguments. This is used to guarantee the
  /// liveness of non-constant strings used in diagnostics.
  std::vector<std::unique_ptr<char[]>> strings;

  /// A list of attached notes.
  NoteVector notes;
};

inline raw_ostream &operator<<(raw_ostream &os, const Diagnostic &diag) {
  diag.print(os);
  return os;
}

//===----------------------------------------------------------------------===//
// InFlightDiagnostic
//===----------------------------------------------------------------------===//

/// This class represents a diagnostic that is inflight and set to be reported.
/// This allows for last minute modifications of the diagnostic before it is
/// emitted by a DiagnosticEngine.
class InFlightDiagnostic {
public:
  InFlightDiagnostic() = default;
  InFlightDiagnostic(InFlightDiagnostic &&rhs)
      : owner(rhs.owner), impl(std::move(rhs.impl)) {
    // Reset the rhs diagnostic.
    rhs.impl.reset();
    rhs.abandon();
  }
  ~InFlightDiagnostic() {
    if (isInFlight())
      report();
  }

  /// Stream operator for new diagnostic arguments.
  template <typename Arg> InFlightDiagnostic &operator<<(Arg &&arg) & {
    return append(std::forward<Arg>(arg));
  }
  template <typename Arg> InFlightDiagnostic &&operator<<(Arg &&arg) && {
    return std::move(append(std::forward<Arg>(arg)));
  }

  /// Append arguments to the diagnostic.
  template <typename... Args> InFlightDiagnostic &append(Args &&... args) & {
    assert(isActive() && "diagnostic not active");
    if (isInFlight())
      impl->append(std::forward<Args>(args)...);
    return *this;
  }
  template <typename... Args> InFlightDiagnostic &&append(Args &&... args) && {
    return std::move(append(std::forward<Args>(args)...));
  }

  /// Attaches a note to this diagnostic.
  Diagnostic &attachNote(Optional<Location> noteLoc = llvm::None) {
    assert(isActive() && "diagnostic not active");
    return impl->attachNote(noteLoc);
  }

  /// Reports the diagnostic to the engine.
  void report();

  /// Abandons this diagnostic so that it will no longer be reported.
  void abandon();

  /// Allow an inflight diagnostic to be converted to 'failure', otherwise
  /// 'success' if this is an empty diagnostic.
  operator LogicalResult() const;

private:
  InFlightDiagnostic &operator=(const InFlightDiagnostic &) = delete;
  InFlightDiagnostic &operator=(InFlightDiagnostic &&) = delete;
  InFlightDiagnostic(DiagnosticEngine *owner, Diagnostic &&rhs)
      : owner(owner), impl(std::move(rhs)) {}

  /// Returns true if the diagnostic is still active, i.e. it has a live
  /// diagnostic.
  bool isActive() const { return impl.hasValue(); }

  /// Returns true if the diagnostic is still in flight to be reported.
  bool isInFlight() const { return owner; }

  // Allow access to the constructor.
  friend DiagnosticEngine;

  /// The engine that this diagnostic is to report to.
  DiagnosticEngine *owner = nullptr;

  /// The raw diagnostic that is inflight to be reported.
  Optional<Diagnostic> impl;
};

//===----------------------------------------------------------------------===//
// DiagnosticEngine
//===----------------------------------------------------------------------===//

/// This class is the main interface for diagnostics. The DiagnosticEngine
/// manages the registration of diagnostic handlers as well as the core API for
/// diagnostic emission. This class should not be constructed directly, but
/// instead interfaced with via an MLIRContext instance.
class DiagnosticEngine {
public:
  ~DiagnosticEngine();

  // Diagnostic handler registration and use. MLIR supports the ability for the
  // IR to carry arbitrary metadata about operation location information. If a
  // problem is detected by the compiler, it can invoke the emitError /
  // emitWarning / emitRemark method on an Operation and have it get reported
  // through this interface.
  //
  // Tools using MLIR are encouraged to register error handlers and define a
  // schema for their location information.  If they don't, then warnings and
  // notes will be dropped and errors will be emitted to errs.

  /// The handler type for MLIR diagnostics. This function takes a diagnostic as
  /// input, and returns success if the handler has fully processed this
  /// diagnostic. Returns failure otherwise.
  using HandlerTy = std::function<LogicalResult(Diagnostic &)>;

  /// A handle to a specific registered handler object.
  using HandlerID = uint64_t;

  /// Register a new handler for diagnostics to the engine. Diagnostics are
  /// process by handlers in stack-like order, meaning that the last added
  /// handlers will process diagnostics first. This function returns a unique
  /// identifier for the registered handler, which can be used to unregister
  /// this handler at a later time.
  HandlerID registerHandler(const HandlerTy &handler);

  /// Set the diagnostic handler with a function that returns void. This is a
  /// convenient wrapper for handlers that always completely process the given
  /// diagnostic.
  template <typename FuncTy, typename RetT = decltype(std::declval<FuncTy>()(
                                 std::declval<Diagnostic &>()))>
  std::enable_if_t<std::is_same<RetT, void>::value, HandlerID>
  registerHandler(FuncTy &&handler) {
    return registerHandler([=](Diagnostic &diag) {
      handler(diag);
      return success();
    });
  }

  /// Erase the registered diagnostic handler with the given identifier.
  void eraseHandler(HandlerID id);

  /// Create a new inflight diagnostic with the given location and severity.
  InFlightDiagnostic emit(Location loc, DiagnosticSeverity severity) {
    assert(severity != DiagnosticSeverity::Note &&
           "notes should not be emitted directly");
    return InFlightDiagnostic(this, Diagnostic(loc, severity));
  }

  /// Emit a diagnostic using the registered issue handler if present, or with
  /// the default behavior if not.
  void emit(Diagnostic diag);

private:
  friend class MLIRContextImpl;
  DiagnosticEngine();

  /// The internal implementation of the DiagnosticEngine.
  std::unique_ptr<detail::DiagnosticEngineImpl> impl;
};

/// Utility method to emit an error message using this location.
InFlightDiagnostic emitError(Location loc);
InFlightDiagnostic emitError(Location loc, const Twine &message);

/// Utility method to emit a warning message using this location.
InFlightDiagnostic emitWarning(Location loc);
InFlightDiagnostic emitWarning(Location loc, const Twine &message);

/// Utility method to emit a remark message using this location.
InFlightDiagnostic emitRemark(Location loc);
InFlightDiagnostic emitRemark(Location loc, const Twine &message);

/// Overloads of the above emission functions that take an optionally null
/// location. If the location is null, no diagnostic is emitted and a failure is
/// returned. Given that the provided location may be null, these methods take
/// the diagnostic arguments directly instead of relying on the returned
/// InFlightDiagnostic.
template <typename... Args>
LogicalResult emitOptionalError(Optional<Location> loc, Args &&... args) {
  if (loc)
    return emitError(*loc).append(std::forward<Args>(args)...);
  return failure();
}
template <typename... Args>
LogicalResult emitOptionalWarning(Optional<Location> loc, Args &&... args) {
  if (loc)
    return emitWarning(*loc).append(std::forward<Args>(args)...);
  return failure();
}
template <typename... Args>
LogicalResult emitOptionalRemark(Optional<Location> loc, Args &&... args) {
  if (loc)
    return emitRemark(*loc).append(std::forward<Args>(args)...);
  return failure();
}

//===----------------------------------------------------------------------===//
// ScopedDiagnosticHandler
//===----------------------------------------------------------------------===//

/// This diagnostic handler is a simple RAII class that registers and erases a
/// diagnostic handler on a given context. This class can be either be used
/// directly, or in conjunction with a derived diagnostic handler.
class ScopedDiagnosticHandler {
public:
  explicit ScopedDiagnosticHandler(MLIRContext *ctx) : handlerID(0), ctx(ctx) {}
  template <typename FuncTy>
  ScopedDiagnosticHandler(MLIRContext *ctx, FuncTy &&handler)
      : handlerID(0), ctx(ctx) {
    setHandler(std::forward<FuncTy>(handler));
  }
  ~ScopedDiagnosticHandler();

protected:
  /// Set the handler to manage via RAII.
  template <typename FuncTy> void setHandler(FuncTy &&handler) {
    auto &diagEngine = ctx->getDiagEngine();
    if (handlerID)
      diagEngine.eraseHandler(handlerID);
    handlerID = diagEngine.registerHandler(std::forward<FuncTy>(handler));
  }

private:
  /// The unique id for the scoped handler.
  DiagnosticEngine::HandlerID handlerID;

  /// The context to erase the handler from.
  MLIRContext *ctx;
};

//===----------------------------------------------------------------------===//
// SourceMgrDiagnosticHandler
//===----------------------------------------------------------------------===//

namespace detail {
struct SourceMgrDiagnosticHandlerImpl;
} // end namespace detail

/// This class is a utility diagnostic handler for use with llvm::SourceMgr.
class SourceMgrDiagnosticHandler : public ScopedDiagnosticHandler {
public:
  /// This type represents a functor used to filter out locations when printing
  /// a diagnostic. It should return true if the provided location is okay to
  /// display, false otherwise. If all locations in a diagnostic are filtered
  /// out, the first location is used as the sole location. When deciding
  /// whether or not to filter a location, this function should not recurse into
  /// any nested location. This recursion is handled automatically by the
  /// caller.
  using ShouldShowLocFn = llvm::unique_function<bool(Location)>;

  SourceMgrDiagnosticHandler(llvm::SourceMgr &mgr, MLIRContext *ctx,
                             raw_ostream &os,
                             ShouldShowLocFn &&shouldShowLocFn = {});
  SourceMgrDiagnosticHandler(llvm::SourceMgr &mgr, MLIRContext *ctx,
                             ShouldShowLocFn &&shouldShowLocFn = {});
  ~SourceMgrDiagnosticHandler();

  /// Emit the given diagnostic information with the held source manager.
  void emitDiagnostic(Location loc, Twine message, DiagnosticSeverity kind,
                      bool displaySourceLine = true);

protected:
  /// Emit the given diagnostic with the held source manager.
  void emitDiagnostic(Diagnostic &diag);

  /// Get a memory buffer for the given file, or nullptr if no file is
  /// available.
  const llvm::MemoryBuffer *getBufferForFile(StringRef filename);

  /// The source manager that we are wrapping.
  llvm::SourceMgr &mgr;

  /// The output stream to use when printing diagnostics.
  raw_ostream &os;

  /// A functor used when determining if a location for a diagnostic should be
  /// shown. If null, all locations should be shown.
  ShouldShowLocFn shouldShowLocFn;

private:
  /// Convert a location into the given memory buffer into an SMLoc.
  llvm::SMLoc convertLocToSMLoc(FileLineColLoc loc);

  /// Given a location, returns the first nested location (including 'loc') that
  /// can be shown to the user.
  Optional<Location> findLocToShow(Location loc);

  /// The maximum depth that a call stack will be printed.
  /// TODO: This should be a tunable flag.
  unsigned callStackLimit = 10;

  std::unique_ptr<detail::SourceMgrDiagnosticHandlerImpl> impl;
};

//===----------------------------------------------------------------------===//
// SourceMgrDiagnosticVerifierHandler
//===----------------------------------------------------------------------===//

namespace detail {
struct SourceMgrDiagnosticVerifierHandlerImpl;
} // end namespace detail

/// This class is a utility diagnostic handler for use with llvm::SourceMgr that
/// verifies that emitted diagnostics match 'expected-*' lines on the
/// corresponding line of the source file.
class SourceMgrDiagnosticVerifierHandler : public SourceMgrDiagnosticHandler {
public:
  SourceMgrDiagnosticVerifierHandler(llvm::SourceMgr &srcMgr, MLIRContext *ctx,
                                     raw_ostream &out);
  SourceMgrDiagnosticVerifierHandler(llvm::SourceMgr &srcMgr, MLIRContext *ctx);
  ~SourceMgrDiagnosticVerifierHandler();

  /// Returns the status of the handler and verifies that all expected
  /// diagnostics were emitted. This return success if all diagnostics were
  /// verified correctly, failure otherwise.
  LogicalResult verify();

private:
  /// Process a single diagnostic.
  void process(Diagnostic &diag);

  /// Process a FileLineColLoc diagnostic.
  void process(FileLineColLoc loc, StringRef msg, DiagnosticSeverity kind);

  std::unique_ptr<detail::SourceMgrDiagnosticVerifierHandlerImpl> impl;
};

//===----------------------------------------------------------------------===//
// ParallelDiagnosticHandler
//===----------------------------------------------------------------------===//

namespace detail {
struct ParallelDiagnosticHandlerImpl;
} // end namespace detail

/// This class is a utility diagnostic handler for use when multi-threading some
/// part of the compiler where diagnostics may be emitted. This handler ensures
/// a deterministic ordering to the emitted diagnostics that mirrors that of a
/// single-threaded compilation.
class ParallelDiagnosticHandler {
public:
  ParallelDiagnosticHandler(MLIRContext *ctx);
  ~ParallelDiagnosticHandler();

  /// Set the order id for the current thread. This is required to be set by
  /// each thread that will be emitting diagnostics to this handler. The orderID
  /// corresponds to the order in which diagnostics would be emitted when
  /// executing synchronously. For example, if we were processing a list
  /// of operations [a, b, c] on a single-thread. Diagnostics emitted while
  /// processing operation 'a' would be emitted before those for 'b' or 'c'.
  /// This corresponds 1-1 with the 'orderID'. The thread that is processing 'a'
  /// should set the orderID to '0'; the thread processing 'b' should set it to
  /// '1'; and so on and so forth. This provides a way for the handler to
  /// deterministically order the diagnostics that it receives given the thread
  /// that it is receiving on.
  void setOrderIDForThread(size_t orderID);

  /// Remove the order id for the current thread. This removes the thread from
  /// diagnostics tracking.
  void eraseOrderIDForThread();

private:
  std::unique_ptr<detail::ParallelDiagnosticHandlerImpl> impl;
};
} // namespace mlir

#endif
