Please use GitHub pull requests for new patches. Avoid migrating existing patches. Phabricator shutdown timeline
Changeset View
Changeset View
Standalone View
Standalone View
mlir/lib/IR/Diagnostics.cpp
Show First 20 Lines • Show All 203 Lines • ▼ Show 20 Lines | |||||
namespace mlir { | namespace mlir { | ||||
namespace detail { | namespace detail { | ||||
struct DiagnosticEngineImpl { | struct DiagnosticEngineImpl { | ||||
/// Emit a diagnostic using the registered issue handle if present, or with | /// Emit a diagnostic using the registered issue handle if present, or with | ||||
/// the default behavior if not. | /// the default behavior if not. | ||||
void emit(Diagnostic diag); | void emit(Diagnostic diag); | ||||
/// Emit a diagnostic using the registered debugging handler if present, or | |||||
/// it'll be discarded. | |||||
void emitDebugging(Diagnostic diag); | |||||
/// A mutex to ensure that diagnostics emission is thread-safe. | /// A mutex to ensure that diagnostics emission is thread-safe. | ||||
llvm::sys::SmartMutex<true> mutex; | llvm::sys::SmartMutex<true> mutex; | ||||
/// These are the handlers used to report diagnostics. | /// These are the handlers used to report diagnostics. | ||||
llvm::SmallMapVector<DiagnosticEngine::HandlerID, DiagnosticEngine::HandlerTy, | llvm::SmallMapVector<DiagnosticEngine::HandlerID, DiagnosticEngine::HandlerTy, | ||||
2> | 2> | ||||
handlers; | handlers; | ||||
/// The handler to deal with debugging message. | |||||
DiagnosticEngine::HandlerTy debuggingHandler; | |||||
/// This is a unique identifier counter for diagnostic handlers in the | /// This is a unique identifier counter for diagnostic handlers in the | ||||
/// context. This id starts at 1 to allow for 0 to be used as a sentinel. | /// context. This id starts at 1 to allow for 0 to be used as a sentinel. | ||||
DiagnosticEngine::HandlerID uniqueHandlerId = 1; | DiagnosticEngine::HandlerID uniqueHandlerId = 1; | ||||
}; | }; | ||||
} // namespace detail | } // namespace detail | ||||
} // namespace mlir | } // namespace mlir | ||||
/// Emit a diagnostic using the registered issue handle if present, or with | /// Emit a diagnostic using the registered issue handle if present, or with | ||||
/// the default behavior if not. | /// the default behavior if not. | ||||
void DiagnosticEngineImpl::emit(Diagnostic diag) { | void DiagnosticEngineImpl::emit(Diagnostic diag) { | ||||
if (diag.getSeverity() == DiagnosticSeverity::Debugging) { | |||||
emitDebugging(std::move(diag)); | |||||
return; | |||||
} | |||||
llvm::sys::SmartScopedLock<true> lock(mutex); | llvm::sys::SmartScopedLock<true> lock(mutex); | ||||
// Try to process the given diagnostic on one of the registered handlers. | // Try to process the given diagnostic on one of the registered handlers. | ||||
// Handlers are walked in reverse order, so that the most recent handler is | // Handlers are walked in reverse order, so that the most recent handler is | ||||
// processed first. | // processed first. | ||||
for (auto &handlerIt : llvm::reverse(handlers)) | for (auto &handlerIt : llvm::reverse(handlers)) | ||||
if (succeeded(handlerIt.second(diag))) | if (succeeded(handlerIt.second(diag))) | ||||
return; | return; | ||||
// Otherwise, if this is an error we emit it to stderr. | // Otherwise, if this is an error we emit it to stderr. | ||||
if (diag.getSeverity() != DiagnosticSeverity::Error) | if (diag.getSeverity() != DiagnosticSeverity::Error) | ||||
return; | return; | ||||
auto &os = llvm::errs(); | auto &os = llvm::errs(); | ||||
if (!diag.getLocation().isa<UnknownLoc>()) | if (!diag.getLocation().isa<UnknownLoc>()) | ||||
os << diag.getLocation() << ": "; | os << diag.getLocation() << ": "; | ||||
os << "error: "; | os << "error: "; | ||||
// The default behavior for errors is to emit them to stderr. | // The default behavior for errors is to emit them to stderr. | ||||
os << diag << '\n'; | os << diag << '\n'; | ||||
os.flush(); | os.flush(); | ||||
} | } | ||||
/// Emit a debugging diagnostic using the debuggingHandler if present, or it'll | |||||
/// be dropped directly. | |||||
void DiagnosticEngineImpl::emitDebugging(Diagnostic diag) { | |||||
if (!debuggingHandler) | |||||
return; | |||||
llvm::sys::SmartScopedLock<true> lock(mutex); | |||||
// This is user registered debugging handler, it's supposed to return success | |||||
// and we have no knowledge what to do if it reuturns failure. | |||||
(void)debuggingHandler(diag); | |||||
} | |||||
//===----------------------------------------------------------------------===// | //===----------------------------------------------------------------------===// | ||||
// DiagnosticEngine | // DiagnosticEngine | ||||
//===----------------------------------------------------------------------===// | //===----------------------------------------------------------------------===// | ||||
DiagnosticEngine::DiagnosticEngine() : impl(new DiagnosticEngineImpl()) {} | DiagnosticEngine::DiagnosticEngine() : impl(new DiagnosticEngineImpl()) {} | ||||
DiagnosticEngine::~DiagnosticEngine() {} | DiagnosticEngine::~DiagnosticEngine() {} | ||||
/// Register a new handler for diagnostics to the engine. This function returns | /// Register a new handler for diagnostics to the engine. This function returns | ||||
/// a unique identifier for the registered handler, which can be used to | /// a unique identifier for the registered handler, which can be used to | ||||
/// unregister this handler at a later time. | /// unregister this handler at a later time. | ||||
auto DiagnosticEngine::registerHandler(const HandlerTy &handler) -> HandlerID { | auto DiagnosticEngine::registerHandler(const HandlerTy &handler) -> HandlerID { | ||||
llvm::sys::SmartScopedLock<true> lock(impl->mutex); | llvm::sys::SmartScopedLock<true> lock(impl->mutex); | ||||
auto uniqueID = impl->uniqueHandlerId++; | auto uniqueID = impl->uniqueHandlerId++; | ||||
impl->handlers.insert({uniqueID, handler}); | impl->handlers.insert({uniqueID, handler}); | ||||
return uniqueID; | return uniqueID; | ||||
} | } | ||||
DiagnosticEngine::HandlerTy | |||||
DiagnosticEngine::registerDebuggingHandler(const HandlerTy &handler) { | |||||
llvm::sys::SmartScopedLock<true> lock(impl->mutex); | |||||
HandlerTy old = impl->debuggingHandler; | |||||
impl->debuggingHandler = handler; | |||||
return old; | |||||
} | |||||
bool DiagnosticEngine::hasDebuggingHandler() const { | |||||
return impl->debuggingHandler != nullptr; | |||||
} | |||||
/// Erase the registered diagnostic handler with the given identifier. | /// Erase the registered diagnostic handler with the given identifier. | ||||
void DiagnosticEngine::eraseHandler(HandlerID handlerID) { | void DiagnosticEngine::eraseHandler(HandlerID handlerID) { | ||||
llvm::sys::SmartScopedLock<true> lock(impl->mutex); | llvm::sys::SmartScopedLock<true> lock(impl->mutex); | ||||
impl->handlers.erase(handlerID); | impl->handlers.erase(handlerID); | ||||
} | } | ||||
void DiagnosticEngine::eraseDebuggingHandler() { | |||||
llvm::sys::SmartScopedLock<true> lock(impl->mutex); | |||||
impl->debuggingHandler = nullptr; | |||||
} | |||||
/// Emit a diagnostic using the registered issue handler if present, or with | /// Emit a diagnostic using the registered issue handler if present, or with | ||||
/// the default behavior if not. | /// the default behavior if not. | ||||
void DiagnosticEngine::emit(Diagnostic diag) { | void DiagnosticEngine::emit(Diagnostic diag) { | ||||
assert(diag.getSeverity() != DiagnosticSeverity::Note && | assert(diag.getSeverity() != DiagnosticSeverity::Note && | ||||
"notes should not be emitted directly"); | "notes should not be emitted directly"); | ||||
impl->emit(std::move(diag)); | impl->emit(std::move(diag)); | ||||
} | } | ||||
Show All 39 Lines | |||||
/// Emit a remark message using this location. | /// Emit a remark message using this location. | ||||
InFlightDiagnostic mlir::emitRemark(Location loc) { | InFlightDiagnostic mlir::emitRemark(Location loc) { | ||||
return emitRemark(loc, {}); | return emitRemark(loc, {}); | ||||
} | } | ||||
InFlightDiagnostic mlir::emitRemark(Location loc, const Twine &message) { | InFlightDiagnostic mlir::emitRemark(Location loc, const Twine &message) { | ||||
return emitDiag(loc, DiagnosticSeverity::Remark, message); | return emitDiag(loc, DiagnosticSeverity::Remark, message); | ||||
} | } | ||||
/// Emit a debugging message using this location. | |||||
LogicalResult | |||||
mlir::emitDebugging(Location loc, | |||||
function_ref<void(Diagnostic &)> reasonCallback) { | |||||
if (!loc->getContext()->getDiagEngine().hasDebuggingHandler()) | |||||
return failure(); | |||||
reasonCallback( | |||||
emitDiag(loc, DiagnosticSeverity::Debugging, {}).getDiagnostic()); | |||||
return success(); | |||||
} | |||||
//===----------------------------------------------------------------------===// | //===----------------------------------------------------------------------===// | ||||
// ScopedDiagnosticHandler | // ScopedDiagnosticHandler | ||||
//===----------------------------------------------------------------------===// | //===----------------------------------------------------------------------===// | ||||
ScopedDiagnosticHandler::~ScopedDiagnosticHandler() { | ScopedDiagnosticHandler::~ScopedDiagnosticHandler() { | ||||
if (handlerID) | if (handlerID) | ||||
ctx->getDiagEngine().eraseHandler(handlerID); | ctx->getDiagEngine().eraseHandler(handlerID); | ||||
} | } | ||||
//===----------------------------------------------------------------------===// | //===----------------------------------------------------------------------===// | ||||
// ScopedDebuggingHandler | |||||
//===----------------------------------------------------------------------===// | |||||
ScopedDebuggingHandler::~ScopedDebuggingHandler() { | |||||
ctx->getDiagEngine().registerDebuggingHandler(old); | |||||
} | |||||
//===----------------------------------------------------------------------===// | |||||
// SourceMgrDiagnosticHandler | // SourceMgrDiagnosticHandler | ||||
//===----------------------------------------------------------------------===// | //===----------------------------------------------------------------------===// | ||||
namespace mlir { | namespace mlir { | ||||
namespace detail { | namespace detail { | ||||
struct SourceMgrDiagnosticHandlerImpl { | struct SourceMgrDiagnosticHandlerImpl { | ||||
/// Return the SrcManager buffer id for the specified file, or zero if none | /// Return the SrcManager buffer id for the specified file, or zero if none | ||||
/// can be found. | /// can be found. | ||||
unsigned getSourceMgrBufferIDForFile(llvm::SourceMgr &mgr, | unsigned getSourceMgrBufferIDForFile(llvm::SourceMgr &mgr, | ||||
▲ Show 20 Lines • Show All 60 Lines • ▼ Show 20 Lines | static llvm::SourceMgr::DiagKind getDiagKind(DiagnosticSeverity kind) { | ||||
case DiagnosticSeverity::Note: | case DiagnosticSeverity::Note: | ||||
return llvm::SourceMgr::DK_Note; | return llvm::SourceMgr::DK_Note; | ||||
case DiagnosticSeverity::Warning: | case DiagnosticSeverity::Warning: | ||||
return llvm::SourceMgr::DK_Warning; | return llvm::SourceMgr::DK_Warning; | ||||
case DiagnosticSeverity::Error: | case DiagnosticSeverity::Error: | ||||
return llvm::SourceMgr::DK_Error; | return llvm::SourceMgr::DK_Error; | ||||
case DiagnosticSeverity::Remark: | case DiagnosticSeverity::Remark: | ||||
return llvm::SourceMgr::DK_Remark; | return llvm::SourceMgr::DK_Remark; | ||||
case DiagnosticSeverity::Debugging: | |||||
// Debugging kind doesn't have equivalent type in SourceMgr and it's not to | |||||
// be here. | |||||
break; | |||||
} | } | ||||
llvm_unreachable("Unknown DiagnosticSeverity"); | llvm_unreachable("Unknown DiagnosticSeverity"); | ||||
} | } | ||||
SourceMgrDiagnosticHandler::SourceMgrDiagnosticHandler( | SourceMgrDiagnosticHandler::SourceMgrDiagnosticHandler( | ||||
llvm::SourceMgr &mgr, MLIRContext *ctx, raw_ostream &os, | llvm::SourceMgr &mgr, MLIRContext *ctx, raw_ostream &os, | ||||
ShouldShowLocFn &&shouldShowLocFn) | ShouldShowLocFn &&shouldShowLocFn) | ||||
: ScopedDiagnosticHandler(ctx), mgr(mgr), os(os), | : ScopedDiagnosticHandler(ctx), mgr(mgr), os(os), | ||||
▲ Show 20 Lines • Show All 192 Lines • ▼ Show 20 Lines | static StringRef getDiagKindStr(DiagnosticSeverity kind) { | ||||
case DiagnosticSeverity::Note: | case DiagnosticSeverity::Note: | ||||
return "note"; | return "note"; | ||||
case DiagnosticSeverity::Warning: | case DiagnosticSeverity::Warning: | ||||
return "warning"; | return "warning"; | ||||
case DiagnosticSeverity::Error: | case DiagnosticSeverity::Error: | ||||
return "error"; | return "error"; | ||||
case DiagnosticSeverity::Remark: | case DiagnosticSeverity::Remark: | ||||
return "remark"; | return "remark"; | ||||
case DiagnosticSeverity::Debugging: | |||||
return "debugging"; | |||||
} | } | ||||
llvm_unreachable("Unknown DiagnosticSeverity"); | llvm_unreachable("Unknown DiagnosticSeverity"); | ||||
} | } | ||||
/// Returns the expected diagnostics for the given source file. | /// Returns the expected diagnostics for the given source file. | ||||
Optional<MutableArrayRef<ExpectedDiag>> | Optional<MutableArrayRef<ExpectedDiag>> | ||||
SourceMgrDiagnosticVerifierHandlerImpl::getExpectedDiags(StringRef bufName) { | SourceMgrDiagnosticVerifierHandlerImpl::getExpectedDiags(StringRef bufName) { | ||||
auto expectedDiags = expectedDiagsPerFile.find(bufName); | auto expectedDiags = expectedDiagsPerFile.find(bufName); | ||||
▲ Show 20 Lines • Show All 287 Lines • ▼ Show 20 Lines | emitDiagnostics([&](Diagnostic diag) { | ||||
os << "warning: "; | os << "warning: "; | ||||
break; | break; | ||||
case DiagnosticSeverity::Note: | case DiagnosticSeverity::Note: | ||||
os << "note: "; | os << "note: "; | ||||
break; | break; | ||||
case DiagnosticSeverity::Remark: | case DiagnosticSeverity::Remark: | ||||
os << "remark: "; | os << "remark: "; | ||||
break; | break; | ||||
case DiagnosticSeverity::Debugging: | |||||
os << "debugging: "; | |||||
break; | |||||
} | } | ||||
os << diag << '\n'; | os << diag << '\n'; | ||||
}); | }); | ||||
} | } | ||||
/// A smart mutex to lock access to the internal state. | /// A smart mutex to lock access to the internal state. | ||||
llvm::sys::SmartMutex<true> mutex; | llvm::sys::SmartMutex<true> mutex; | ||||
Show All 29 Lines |