]> granicus.if.org Git - clang/commitdiff
[Basic] getColumnNumber returns location of CR+LF on Windows
authorChih-Hung Hsieh <chh@google.com>
Thu, 6 Apr 2017 18:36:50 +0000 (18:36 +0000)
committerChih-Hung Hsieh <chh@google.com>
Thu, 6 Apr 2017 18:36:50 +0000 (18:36 +0000)
When fixing a Clang-Tidy bug in D31406,
reuse of FileID enabled the missing highlightRange function.
Assertion in highlightRange failed because the end-of-range column
number was 2 + the last column of a line on Windows.
This fix is required to enable D31406.

Differential Revision: https://reviews.llvm.org/D31713

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@299681 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Basic/SourceManager.cpp

index 380ca373e69b1171702ec1d083d0a69f69600f53..156aa0b11f7d0571d7bd3a427547499d49cc775b 100644 (file)
@@ -1136,6 +1136,7 @@ unsigned SourceManager::getColumnNumber(FileID FID, unsigned FilePos,
     return 1;
   }
 
+  const char *Buf = MemBuf->getBufferStart();
   // See if we just calculated the line number for this FilePos and can use
   // that to lookup the start of the line instead of searching for it.
   if (LastLineNoFileIDQuery == FID &&
@@ -1144,11 +1145,19 @@ unsigned SourceManager::getColumnNumber(FileID FID, unsigned FilePos,
     unsigned *SourceLineCache = LastLineNoContentCache->SourceLineCache;
     unsigned LineStart = SourceLineCache[LastLineNoResult - 1];
     unsigned LineEnd = SourceLineCache[LastLineNoResult];
-    if (FilePos >= LineStart && FilePos < LineEnd)
+    if (FilePos >= LineStart && FilePos < LineEnd) {
+      // LineEnd is the LineStart of the next line.
+      // A line ends with separator LF or CR+LF on Windows.
+      // FilePos might point to the last separator,
+      // but we need a column number at most 1 + the last column.
+      if (FilePos + 1 == LineEnd && FilePos > LineStart) {
+        if (Buf[FilePos - 1] == '\r' || Buf[FilePos - 1] == '\n')
+          --FilePos;
+      }
       return FilePos - LineStart + 1;
+    }
   }
 
-  const char *Buf = MemBuf->getBufferStart();
   unsigned LineStart = FilePos;
   while (LineStart && Buf[LineStart-1] != '\n' && Buf[LineStart-1] != '\r')
     --LineStart;