From 6264fccd3a4af9edc37f9b6d0f37763e61800ba5 Mon Sep 17 00:00:00 2001 From: River Riddle Date: Tue, 14 May 2019 09:29:30 -0700 Subject: [PATCH] When converting a location to an SMLoc, advance to the first non-whitespace if the column is unknown(zero). This also fixes a small bug with call stack printing. Example: /tmp/file_C.py:21:5: error: 'foo.bar' op attribute 'something' raise app.UsageError('Too many command-line arguments.') ^ /tmp/file_D.py:20:3: note: called from if len(argv) > 1: ^ /tmp/file_E.py:19:1: note: called from def main(argv): ^ /tmp/file_F.py:24:3: note: called from app.run(main) ^ -- PiperOrigin-RevId: 248151212 --- mlir/lib/IR/Diagnostics.cpp | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/mlir/lib/IR/Diagnostics.cpp b/mlir/lib/IR/Diagnostics.cpp index 0a0ecb8c51a8..5283cf086da3 100644 --- a/mlir/lib/IR/Diagnostics.cpp +++ b/mlir/lib/IR/Diagnostics.cpp @@ -361,10 +361,12 @@ void SourceMgrDiagnosticHandler::emitDiagnostic(Diagnostic &diag) { if (auto callLoc = loc.dyn_cast()) { // Print the call stack while valid, or until the limit is reached. Location callerLoc = callLoc->getCaller(); - for (unsigned currentDepth = 0; currentDepth < callStackLimit && callLoc; - ++currentDepth, callLoc = callerLoc.dyn_cast()) { + for (unsigned curDepth = 0; curDepth < callStackLimit; ++curDepth) { emitDiagnostic(callerLoc, "called from", DiagnosticSeverity::Note); - callerLoc = callLoc->getCaller(); + if ((callLoc = callerLoc.dyn_cast())) + callerLoc = callLoc->getCaller(); + else + break; } } @@ -425,6 +427,17 @@ llvm::SMLoc SourceMgrDiagnosticHandler::convertLocToSMLoc(FileLineColLoc loc) { if (lineNo || position + columnNo > end) return llvm::SMLoc::getFromPointer(membuf->getBufferStart()); + // If the column is zero, try to skip to the first non-whitespace character. + if (columnNo == 0) { + auto isNewline = [](char c) { return c == '\n' || c == '\r'; }; + auto isWhitespace = [](char c) { return c == ' ' || c == '\t'; }; + + // Look for a valid non-whitespace character before the next line. + for (auto *newPos = position; newPos < end && !isNewline(*newPos); ++newPos) + if (!isWhitespace(*newPos)) + return llvm::SMLoc::getFromPointer(newPos); + } + // Otherwise return the right pointer. return llvm::SMLoc::getFromPointer(position + columnNo); }