LLZK 0.1.0
Veridise's ZK Language IR
Loading...
Searching...
No Matches
ErrorHelper.h
Go to the documentation of this file.
1//===-- ErrorHelper.h -------------------------------------------*- C++ -*-===//
2//
3// Part of the LLZK Project, under the Apache License v2.0.
4// See LICENSE.txt for license information.
5// Copyright 2025 Veridise Inc.
6// SPDX-License-Identifier: Apache-2.0
7//
8//===----------------------------------------------------------------------===//
9
10#pragma once
11
12#include <mlir/IR/Diagnostics.h>
13#include <mlir/IR/Operation.h>
14
15#include <llvm/ADT/STLFunctionalExtras.h>
16#include <llvm/ADT/Twine.h>
17#include <llvm/Support/ErrorHandling.h>
18
19#include <variant>
20
21namespace llzk {
22
26class InFlightDiagnosticWrapper {
27private:
30 class DefaultAndFailInFlightDiagnostic : public mlir::InFlightDiagnostic {
31 public:
32 DefaultAndFailInFlightDiagnostic(mlir::InFlightDiagnostic &&base)
33 : mlir::InFlightDiagnostic(std::move(base)) {}
34
35 DefaultAndFailInFlightDiagnostic(DefaultAndFailInFlightDiagnostic &&other)
36 : mlir::InFlightDiagnostic(std::move(other)) {}
37
38 ~DefaultAndFailInFlightDiagnostic() {
40 report();
41 }
42 }
43
44 void report() {
45 InFlightDiagnostic::report();
46 assert(false);
47 }
48 };
49
50 std::variant<mlir::InFlightDiagnostic, DefaultAndFailInFlightDiagnostic> inner;
51
52 explicit InFlightDiagnosticWrapper(DefaultAndFailInFlightDiagnostic &&diag)
53 : inner(std::move(diag)) {}
54
55public:
57 explicit InFlightDiagnosticWrapper(mlir::InFlightDiagnostic &&diag) : inner(std::move(diag)) {}
58
62 explicit InFlightDiagnosticWrapper(mlir::MLIRContext *ctx)
63 : InFlightDiagnosticWrapper(
64 DefaultAndFailInFlightDiagnostic(mlir::detail::getDefaultDiagnosticEmitFn(ctx)())
65 ) {}
66
70 explicit InFlightDiagnosticWrapper(const mlir::Location &loc)
71 : InFlightDiagnosticWrapper(loc.getContext()) {}
72
74 template <typename Arg> InFlightDiagnosticWrapper &operator<<(Arg &&arg) & {
75 return append(std::forward<Arg>(arg));
76 }
77
78 template <typename Arg> InFlightDiagnosticWrapper &&operator<<(Arg &&arg) && {
79 return std::move(append(std::forward<Arg>(arg)));
80 }
81
83 template <typename... Args> InFlightDiagnosticWrapper &append(Args &&...args) & {
84 std::visit([&](auto &diag) { diag.append(std::forward<Args>(args)...); }, inner);
85 return *this;
86 }
87
88 template <typename... Args> InFlightDiagnosticWrapper &&append(Args &&...args) && {
89 return std::move(append(std::forward<Args>(args)...));
90 }
91
93 mlir::Diagnostic &attachNote(std::optional<mlir::Location> noteLoc = std::nullopt) {
94 return std::visit([&](auto &diag) -> mlir::Diagnostic & {
95 return diag.attachNote(noteLoc);
96 }, inner);
97 }
98
100 mlir::Diagnostic *getUnderlyingDiagnostic() {
101 return std::visit([](auto &diag) -> mlir::Diagnostic * {
102 return diag.getUnderlyingDiagnostic();
103 }, inner);
104 }
105
107 void report() {
108 std::visit([](auto &diag) { diag.report(); }, inner);
109 }
110
112 void abandon() {
113 std::visit([](auto &diag) { diag.abandon(); }, inner);
114 }
115
118 operator mlir::LogicalResult() const {
119 return std::visit([](const auto &diag) -> mlir::LogicalResult { return diag; }, inner);
120 }
121
124 operator mlir::ParseResult() const { return mlir::ParseResult(mlir::LogicalResult(*this)); }
125
128 template <typename T> operator mlir::FailureOr<T>() const { return mlir::failure(); }
129
130 // Match move/copy semantics of InFlightDiagnostic
131 InFlightDiagnosticWrapper(InFlightDiagnosticWrapper &&) = default;
132 InFlightDiagnosticWrapper(const InFlightDiagnosticWrapper &) = delete;
133 InFlightDiagnosticWrapper &operator=(InFlightDiagnosticWrapper &&) = delete;
134 InFlightDiagnosticWrapper &operator=(const InFlightDiagnosticWrapper &) = delete;
135};
136
138using EmitErrorFn = llvm::function_ref<InFlightDiagnosticWrapper()>;
139
143
144inline OwningEmitErrorFn getEmitOpErrFn(mlir::Operation *op) {
145 return [op]() { return InFlightDiagnosticWrapper(op->emitOpError()); };
146}
147
148template <typename OpImplClass> inline OwningEmitErrorFn getEmitOpErrFn(OpImplClass *opImpl) {
149 return getEmitOpErrFn(opImpl->getOperation());
150}
151
152inline void ensure(bool condition, const llvm::Twine &errMsg) {
153 if (!condition) {
154 llvm::report_fatal_error(errMsg);
155 }
156}
157
169 llvm::function_ref<mlir::InFlightDiagnostic()> emitError, mlir::MLIRContext *ctx
170) {
171 if (emitError) {
172 return [emitError]() -> auto { return InFlightDiagnosticWrapper(emitError()); };
173 } else {
174 return [ctx]() -> auto { return InFlightDiagnosticWrapper(ctx); };
175 }
176}
177
179wrapNonNullableInFlightDiagnostic(llvm::function_ref<mlir::InFlightDiagnostic()> emitError) {
180 assert(emitError && "emitError must be non-null");
181 return [emitError]() -> auto { return InFlightDiagnosticWrapper(emitError()); };
182}
183
184} // namespace llzk
Wrapper around InFlightDiagnostic that can either be a regular InFlightDiagnostic or a special versio...
Definition ErrorHelper.h:26
InFlightDiagnosticWrapper & operator=(const InFlightDiagnosticWrapper &)=delete
InFlightDiagnosticWrapper & operator<<(Arg &&arg) &
Stream operator for new diagnostic arguments.
Definition ErrorHelper.h:74
InFlightDiagnosticWrapper && append(Args &&...args) &&
Append arguments to the diagnostic.
Definition ErrorHelper.h:88
mlir::Diagnostic & attachNote(std::optional< mlir::Location > noteLoc=std::nullopt)
Attaches a note to this diagnostic.
Definition ErrorHelper.h:93
InFlightDiagnosticWrapper(const mlir::Location &loc)
Constructor for DefaultAndFailInFlightDiagnostic from Location.
Definition ErrorHelper.h:70
InFlightDiagnosticWrapper && operator<<(Arg &&arg) &&
Stream operator for new diagnostic arguments.
Definition ErrorHelper.h:78
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.
Definition ErrorHelper.h:57
InFlightDiagnosticWrapper(mlir::MLIRContext *ctx)
Constructor for DefaultAndFailInFlightDiagnostic from MLIRContext.
Definition ErrorHelper.h:62
InFlightDiagnosticWrapper(const InFlightDiagnosticWrapper &)=delete
InFlightDiagnosticWrapper & operator=(InFlightDiagnosticWrapper &&)=delete
InFlightDiagnosticWrapper & append(Args &&...args) &
Append arguments to the diagnostic.
Definition ErrorHelper.h:83
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.