summaryrefslogtreecommitdiffstats
path: root/mlir/lib/IR/Diagnostics.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'mlir/lib/IR/Diagnostics.cpp')
-rw-r--r--mlir/lib/IR/Diagnostics.cpp146
1 files changed, 114 insertions, 32 deletions
diff --git a/mlir/lib/IR/Diagnostics.cpp b/mlir/lib/IR/Diagnostics.cpp
index 0311fa16420..b266183bb8d 100644
--- a/mlir/lib/IR/Diagnostics.cpp
+++ b/mlir/lib/IR/Diagnostics.cpp
@@ -17,6 +17,7 @@
#include "mlir/IR/Diagnostics.h"
#include "mlir/IR/Location.h"
+#include "mlir/IR/Types.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/Mutex.h"
#include "llvm/Support/raw_ostream.h"
@@ -24,9 +25,86 @@
using namespace mlir;
using namespace mlir::detail;
+//===----------------------------------------------------------------------===//
+// DiagnosticArgument
+//===----------------------------------------------------------------------===//
+
+// Construct from a Type.
+DiagnosticArgument::DiagnosticArgument(Type val)
+ : kind(DiagnosticArgumentKind::Type),
+ opaqueVal(reinterpret_cast<intptr_t>(val.getAsOpaquePointer())) {}
+
+/// Returns this argument as a Type.
+Type DiagnosticArgument::getAsType() const {
+ assert(getKind() == DiagnosticArgumentKind::Type);
+ return Type::getFromOpaquePointer(reinterpret_cast<const void *>(opaqueVal));
+}
+
+/// Outputs this argument to a stream.
+void DiagnosticArgument::print(raw_ostream &os) const {
+ switch (kind) {
+ case DiagnosticArgumentKind::Integer:
+ os << getAsInteger();
+ break;
+ case DiagnosticArgumentKind::String:
+ os << getAsString();
+ break;
+ case DiagnosticArgumentKind::Type:
+ os << getAsType();
+ break;
+ case DiagnosticArgumentKind::Unsigned:
+ os << getAsUnsigned();
+ break;
+ }
+}
+
+//===----------------------------------------------------------------------===//
+// Diagnostic
+//===----------------------------------------------------------------------===//
+
+/// Outputs this diagnostic to a stream.
+void Diagnostic::print(raw_ostream &os) const {
+ for (auto &arg : getArguments())
+ arg.print(os);
+}
+
+/// Convert the diagnostic to a string.
+std::string Diagnostic::str() const {
+ std::string str;
+ llvm::raw_string_ostream os(str);
+ print(os);
+ return os.str();
+}
+
+//===----------------------------------------------------------------------===//
+// InFlightDiagnostic
+//===----------------------------------------------------------------------===//
+
+/// Allow an inflight diagnostic to be converted to 'failure', otherwise
+/// 'success' if this is an empty diagnostic.
+InFlightDiagnostic::operator LogicalResult() const {
+ return failure(isInFlight());
+}
+
+/// Reports the diagnostic to the engine.
+void InFlightDiagnostic::report() {
+ if (isInFlight()) {
+ owner->emit(*impl);
+ impl.reset();
+ }
+}
+
+//===----------------------------------------------------------------------===//
+// DiagnosticEngineImpl
+//===----------------------------------------------------------------------===//
+
namespace mlir {
namespace detail {
struct DiagnosticEngineImpl {
+ /// Emit a diagnostic using the registered issue handle if present, or with
+ /// the default behavior if not.
+ void emit(Location loc, StringRef msg, DiagnosticSeverity severity);
+
/// A mutex to ensure that diagnostics emission is thread-safe.
llvm::sys::SmartMutex<true> mutex;
@@ -37,42 +115,18 @@ struct DiagnosticEngineImpl {
} // namespace detail
} // namespace mlir
-//===----------------------------------------------------------------------===//
-// DiagnosticEngine
-//===----------------------------------------------------------------------===//
-
-DiagnosticEngine::DiagnosticEngine() : impl(new DiagnosticEngineImpl()) {}
-DiagnosticEngine::~DiagnosticEngine() {}
-
-/// Register a diagnostic handler with this engine. The handler is
-/// passed location information if present (nullptr if not) along with a
-/// message and a severity that indicates whether this is an error, warning,
-/// etc.
-void DiagnosticEngine::setHandler(const HandlerTy &handler) {
- llvm::sys::SmartScopedLock<true> lock(impl->mutex);
- impl->handler = handler;
-}
-
-/// Return the current diagnostic handler, or null if none is present.
-auto DiagnosticEngine::getHandler() -> HandlerTy {
- llvm::sys::SmartScopedLock<true> lock(impl->mutex);
- return impl->handler;
-}
-
/// Emit a diagnostic using the registered issue handle if present, or with
-/// the default behavior if not. The MLIR compiler should not generally
-/// interact with this, it should use methods on Operation instead.
-void DiagnosticEngine::emit(Location loc, const Twine &msg,
- DiagnosticSeverity severity) {
- /// Lock access to the diagnostic engine.
- llvm::sys::SmartScopedLock<true> lock(impl->mutex);
+/// the default behavior if not.
+void DiagnosticEngineImpl::emit(Location loc, StringRef msg,
+ DiagnosticSeverity severity) {
+ // Lock access to the handler.
+ llvm::sys::SmartScopedLock<true> lock(mutex);
// If we had a handler registered, emit the diagnostic using it.
- if (impl->handler) {
+ if (handler) {
// TODO(b/131756158) FusedLoc should be handled by the diagnostic handler
// instead of here.
- // Check to see if we are emitting a diagnostic on a fused
- // location.
+ // Check to see if we are emitting a diagnostic on a fused location.
if (auto fusedLoc = loc.dyn_cast<FusedLoc>()) {
auto fusedLocs = fusedLoc->getLocations();
@@ -85,7 +139,7 @@ void DiagnosticEngine::emit(Location loc, const Twine &msg,
return;
}
- return impl->handler(loc, msg.str(), severity);
+ return handler(loc, msg, severity);
}
// Otherwise, if this is an error we emit it to stderr.
@@ -101,3 +155,31 @@ void DiagnosticEngine::emit(Location loc, const Twine &msg,
os << msg << '\n';
os.flush();
}
+
+//===----------------------------------------------------------------------===//
+// DiagnosticEngine
+//===----------------------------------------------------------------------===//
+
+DiagnosticEngine::DiagnosticEngine() : impl(new DiagnosticEngineImpl()) {}
+DiagnosticEngine::~DiagnosticEngine() {}
+
+/// Set the diagnostic handler for this engine. The handler is passed
+/// location information if present (nullptr if not) along with a message and
+/// a severity that indicates whether this is an error, warning, etc. Note
+/// that this replaces any existing handler.
+void DiagnosticEngine::setHandler(const HandlerTy &handler) {
+ llvm::sys::SmartScopedLock<true> lock(impl->mutex);
+ impl->handler = handler;
+}
+
+/// Return the current diagnostic handler, or null if none is present.
+auto DiagnosticEngine::getHandler() -> HandlerTy {
+ llvm::sys::SmartScopedLock<true> lock(impl->mutex);
+ return impl->handler;
+}
+
+/// Emit a diagnostic using the registered issue handler if present, or with
+/// the default behavior if not.
+void DiagnosticEngine::emit(const Diagnostic &diag) {
+ impl->emit(diag.getLocation(), diag.str(), diag.getSeverity());
+}
OpenPOWER on IntegriCloud