12#include <mlir/IR/Diagnostics.h>
13#include <mlir/IR/Operation.h>
15#include <llvm/ADT/STLFunctionalExtras.h>
16#include <llvm/ADT/Twine.h>
17#include <llvm/Support/ErrorHandling.h>
26class InFlightDiagnosticWrapper {
30 class DefaultAndFailInFlightDiagnostic :
public mlir::InFlightDiagnostic {
32 DefaultAndFailInFlightDiagnostic(mlir::InFlightDiagnostic &&base)
33 : mlir::InFlightDiagnostic(std::move(base)) {}
35 DefaultAndFailInFlightDiagnostic(DefaultAndFailInFlightDiagnostic &&other)
36 : mlir::InFlightDiagnostic(std::move(other)) {}
38 ~DefaultAndFailInFlightDiagnostic() {
45 InFlightDiagnostic::report();
50 std::variant<mlir::InFlightDiagnostic, DefaultAndFailInFlightDiagnostic> inner;
52 explicit InFlightDiagnosticWrapper(DefaultAndFailInFlightDiagnostic &&diag)
53 : inner(std::move(diag)) {}
63 : InFlightDiagnosticWrapper(
64 DefaultAndFailInFlightDiagnostic(
mlir::
detail::getDefaultDiagnosticEmitFn(ctx)())
71 : InFlightDiagnosticWrapper(loc.getContext()) {}
74 template <
typename Arg> InFlightDiagnosticWrapper &
operator<<(Arg &&arg) & {
75 return append(std::forward<Arg>(arg));
78 template <
typename Arg> InFlightDiagnosticWrapper &&
operator<<(Arg &&arg) && {
79 return std::move(
append(std::forward<Arg>(arg)));
83 template <
typename... Args> InFlightDiagnosticWrapper &
append(Args &&...args) & {
84 std::visit([&](
auto &diag) { diag.append(std::forward<Args>(args)...); }, inner);
88 template <
typename... Args> InFlightDiagnosticWrapper &&
append(Args &&...args) && {
89 return std::move(
append(std::forward<Args>(args)...));
93 mlir::Diagnostic &
attachNote(std::optional<mlir::Location> noteLoc = std::nullopt) {
94 return std::visit([&](
auto &diag) -> mlir::Diagnostic & {
95 return diag.attachNote(noteLoc);
101 return std::visit([](
auto &diag) -> mlir::Diagnostic * {
102 return diag.getUnderlyingDiagnostic();
108 std::visit([](
auto &diag) { diag.report(); }, inner);
113 std::visit([](
auto &diag) { diag.abandon(); }, inner);
118 operator mlir::LogicalResult()
const {
119 return std::visit([](
const auto &diag) -> mlir::LogicalResult {
return diag; }, inner);
124 operator mlir::ParseResult()
const {
return mlir::ParseResult(mlir::LogicalResult(*
this)); }
128 template <
typename T>
operator mlir::FailureOr<T>()
const {
return mlir::failure(); }
133 InFlightDiagnosticWrapper &
operator=(InFlightDiagnosticWrapper &&) =
delete;
134 InFlightDiagnosticWrapper &
operator=(
const InFlightDiagnosticWrapper &) =
delete;
152inline void ensure(
bool condition,
const llvm::Twine &errMsg) {
154 llvm::report_fatal_error(errMsg);
169 llvm::function_ref<mlir::InFlightDiagnostic()> emitError, mlir::MLIRContext *ctx
180 assert(emitError &&
"emitError must be non-null");
Wrapper around InFlightDiagnostic that can either be a regular InFlightDiagnostic or a special versio...
InFlightDiagnosticWrapper & operator=(const InFlightDiagnosticWrapper &)=delete
InFlightDiagnosticWrapper & operator<<(Arg &&arg) &
Stream operator for new diagnostic arguments.
InFlightDiagnosticWrapper && append(Args &&...args) &&
Append arguments to the diagnostic.
mlir::Diagnostic & attachNote(std::optional< mlir::Location > noteLoc=std::nullopt)
Attaches a note to this diagnostic.
InFlightDiagnosticWrapper(const mlir::Location &loc)
Constructor for DefaultAndFailInFlightDiagnostic from Location.
InFlightDiagnosticWrapper && operator<<(Arg &&arg) &&
Stream operator for new diagnostic arguments.
InFlightDiagnosticWrapper(InFlightDiagnosticWrapper &&)=default
void report()
Reports the diagnostic to the engine.
mlir::Diagnostic * getUnderlyingDiagnostic()
Returns the underlying diagnostic or nullptr if this diagnostic isn't active.
void abandon()
Abandons this diagnostic so that it will no longer be reported.
InFlightDiagnosticWrapper(mlir::InFlightDiagnostic &&diag)
Constructor for regular InFlightDiagnostic.
InFlightDiagnosticWrapper(mlir::MLIRContext *ctx)
Constructor for DefaultAndFailInFlightDiagnostic from MLIRContext.
InFlightDiagnosticWrapper(const InFlightDiagnosticWrapper &)=delete
InFlightDiagnosticWrapper & operator=(InFlightDiagnosticWrapper &&)=delete
InFlightDiagnosticWrapper & append(Args &&...args) &
Append arguments to the diagnostic.
void ensure(bool condition, const llvm::Twine &errMsg)
llvm::function_ref< InFlightDiagnosticWrapper()> EmitErrorFn
Callback to produce an error diagnostic.
OwningEmitErrorFn getEmitOpErrFn(mlir::Operation *op)
OwningEmitErrorFn wrapNonNullableInFlightDiagnostic(llvm::function_ref< mlir::InFlightDiagnostic()> emitError)
std::function< InFlightDiagnosticWrapper()> OwningEmitErrorFn
This type is required in cases like the functions below to take ownership of the lambda so it is not ...
OwningEmitErrorFn wrapNullableInFlightDiagnostic(llvm::function_ref< mlir::InFlightDiagnostic()> emitError, mlir::MLIRContext *ctx)
If the given emitError is non-null, return it.