diff --git a/mlir/include/mlir/IR/Diagnostics.h b/mlir/include/mlir/IR/Diagnostics.h --- a/mlir/include/mlir/IR/Diagnostics.h +++ b/mlir/include/mlir/IR/Diagnostics.h @@ -547,7 +547,8 @@ ~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. diff --git a/mlir/lib/IR/Diagnostics.cpp b/mlir/lib/IR/Diagnostics.cpp --- a/mlir/lib/IR/Diagnostics.cpp +++ b/mlir/lib/IR/Diagnostics.cpp @@ -409,7 +409,8 @@ 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); @@ -423,41 +424,52 @@ 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 = loc.dyn_cast()) { // 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); - if ((callLoc = callerLoc.dyn_cast())) - callerLoc = callLoc.getCaller(); + emitDiagnostic(loc, "called from", DiagnosticSeverity::Note); + if ((callLoc = loc.dyn_cast())) + loc = callLoc.getCaller(); else break; } } - // Emit each of the notes. - for (auto ¬e : 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 ¬e : 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.