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
This commit is contained in:
River Riddle 2019-05-14 09:29:30 -07:00 committed by Mehdi Amini
parent ed47f59c2f
commit 6264fccd3a
1 changed files with 16 additions and 3 deletions

View File

@ -361,10 +361,12 @@ void SourceMgrDiagnosticHandler::emitDiagnostic(Diagnostic &diag) {
if (auto callLoc = loc.dyn_cast<CallSiteLoc>()) {
// 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<CallSiteLoc>()) {
for (unsigned curDepth = 0; curDepth < callStackLimit; ++curDepth) {
emitDiagnostic(callerLoc, "called from", DiagnosticSeverity::Note);
callerLoc = callLoc->getCaller();
if ((callLoc = callerLoc.dyn_cast<CallSiteLoc>()))
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);
}