diff options
Diffstat (limited to 'mlir/lib/IR/Diagnostics.cpp')
| -rw-r--r-- | mlir/lib/IR/Diagnostics.cpp | 146 |
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()); +} |

