[mlir][Diagnostics] Don't print note source line if it is the same as the previous diagnostic

Summary: This revision updates the SourceMgrDiagnosticHandler to not print the source location of a note if it is the same location as the previously printed diagnostic. This helps avoid redundancy, and potential confusion, when looking at the diagnostic output.

Differential Revision: https://reviews.llvm.org/D76787
This commit is contained in:
River Riddle 2020-03-29 21:38:11 -07:00
parent 05f0e598ab
commit 3d44f48edc
3 changed files with 34 additions and 21 deletions

View file

@ -547,7 +547,8 @@ public:
~SourceMgrDiagnosticHandler();
/// Emit the given diagnostic information with the held source manager.
void emitDiagnostic(Location loc, Twine message, DiagnosticSeverity kind);
void emitDiagnostic(Location loc, Twine message, DiagnosticSeverity kind,
bool displaySourceLine = true);
protected:
/// Emit the given diagnostic with the held source manager.

View file

@ -435,7 +435,8 @@ SourceMgrDiagnosticHandler::SourceMgrDiagnosticHandler(llvm::SourceMgr &mgr,
SourceMgrDiagnosticHandler::~SourceMgrDiagnosticHandler() {}
void SourceMgrDiagnosticHandler::emitDiagnostic(Location loc, Twine message,
DiagnosticSeverity kind) {
DiagnosticSeverity kind,
bool displaySourceLine) {
// Extract a file location from this loc.
auto fileLoc = getFileLineColLoc(loc);
@ -449,41 +450,52 @@ void SourceMgrDiagnosticHandler::emitDiagnostic(Location loc, Twine message,
return mgr.PrintMessage(os, llvm::SMLoc(), getDiagKind(kind), strOS.str());
}
// Otherwise, try to convert the file location to an SMLoc.
auto smloc = convertLocToSMLoc(*fileLoc);
if (smloc.isValid())
return mgr.PrintMessage(os, smloc, getDiagKind(kind), message);
// Otherwise if we are displaying the source line, try to convert the file
// location to an SMLoc.
if (displaySourceLine) {
auto smloc = convertLocToSMLoc(*fileLoc);
if (smloc.isValid())
return mgr.PrintMessage(os, smloc, getDiagKind(kind), message);
}
// If the conversion was unsuccessful, create a diagnostic with the file
// information.
llvm::SMDiagnostic diag(fileLoc->getFilename(), getDiagKind(kind),
message.str());
// information. We manually combine the line and column to avoid asserts in
// the constructor of SMDiagnostic that takes a location.
std::string locStr;
llvm::raw_string_ostream locOS(locStr);
locOS << fileLoc->getFilename() << ":" << fileLoc->getLine() << ":"
<< fileLoc->getColumn();
llvm::SMDiagnostic diag(locOS.str(), getDiagKind(kind), message.str());
diag.print(nullptr, os);
}
/// Emit the given diagnostic with the held source manager.
void SourceMgrDiagnosticHandler::emitDiagnostic(Diagnostic &diag) {
// Emit the diagnostic.
auto loc = diag.getLocation();
Location loc = diag.getLocation();
emitDiagnostic(loc, diag.str(), diag.getSeverity());
// If the diagnostic location was a call site location, then print the call
// stack as well.
if (auto callLoc = getCallSiteLoc(loc)) {
// Print the call stack while valid, or until the limit is reached.
Location callerLoc = callLoc->getCaller();
loc = callLoc->getCaller();
for (unsigned curDepth = 0; curDepth < callStackLimit; ++curDepth) {
emitDiagnostic(callerLoc, "called from", DiagnosticSeverity::Note);
callLoc = getCallSiteLoc(callerLoc);
if (!callLoc)
emitDiagnostic(loc, "called from", DiagnosticSeverity::Note);
if ((callLoc = getCallSiteLoc(loc)))
loc = callLoc->getCaller();
else
break;
callerLoc = callLoc->getCaller();
}
}
// Emit each of the notes.
for (auto &note : diag.getNotes())
emitDiagnostic(note.getLocation(), note.str(), note.getSeverity());
// Emit each of the notes. Only display the source code if the location is
// different from the previous location.
for (auto &note : diag.getNotes()) {
emitDiagnostic(note.getLocation(), note.str(), note.getSeverity(),
/*displaySourceLine=*/loc != note.getLocation());
loc = note.getLocation();
}
}
/// Get a memory buffer for the given file, or nullptr if one is not found.

View file

@ -5,9 +5,9 @@
// Emit the first available call stack in the fused location.
func @constant_out_of_range() {
// CHECK: mysource1: error: 'std.constant' op requires attribute's type ('i64') to match op's return type ('i1')
// CHECK-NEXT: mysource2: note: called from
// CHECK-NEXT: mysource3: note: called from
// CHECK: mysource1:0:0: error: 'std.constant' op requires attribute's type ('i64') to match op's return type ('i1')
// CHECK-NEXT: mysource2:1:0: note: called from
// CHECK-NEXT: mysource3:2:0: note: called from
%x = "std.constant"() {value = 100} : () -> i1 loc(fused["bar", callsite("foo"("mysource1":0:0) at callsite("mysource2":1:0 at "mysource3":2:0))])
return
}