Robustify SourceManager::getLocation(), so that it returns an

end-of-line source location when given a column number beyond the
length of the line, or an end-of-file source location when given a
line number beyond the length of the file. Previously, we would return
an invalid location.

llvm-svn: 97299
This commit is contained in:
Douglas Gregor 2010-02-27 02:42:25 +00:00
parent af11dcf348
commit b8b9f28e24
2 changed files with 20 additions and 15 deletions

View File

@ -980,20 +980,6 @@ SourceLocation SourceManager::getLocation(const FileEntry *SourceFile,
if (Content->SourceLineCache == 0) if (Content->SourceLineCache == 0)
ComputeLineNumbers(Content, ContentCacheAlloc); ComputeLineNumbers(Content, ContentCacheAlloc);
if (Line > Content->NumLines)
return SourceLocation();
unsigned FilePos = Content->SourceLineCache[Line - 1];
const char *Buf = Content->getBuffer()->getBufferStart() + FilePos;
unsigned BufLength = Content->getBuffer()->getBufferEnd() - Buf;
unsigned i = 0;
// Check that the given column is valid.
while (i < BufLength-1 && i < Col-1 && Buf[i] != '\n' && Buf[i] != '\r')
++i;
if (i < Col-1)
return SourceLocation();
// Find the first file ID that corresponds to the given file. // Find the first file ID that corresponds to the given file.
FileID FirstFID; FileID FirstFID;
@ -1020,6 +1006,24 @@ SourceLocation SourceManager::getLocation(const FileEntry *SourceFile,
if (FirstFID.isInvalid()) if (FirstFID.isInvalid())
return SourceLocation(); return SourceLocation();
if (Line > Content->NumLines) {
unsigned Size = Content->getBuffer()->getBufferSize();
if (Size > 0)
--Size;
return getLocForStartOfFile(FirstFID).getFileLocWithOffset(Size);
}
unsigned FilePos = Content->SourceLineCache[Line - 1];
const char *Buf = Content->getBuffer()->getBufferStart() + FilePos;
unsigned BufLength = Content->getBuffer()->getBufferEnd() - Buf;
unsigned i = 0;
// Check that the given column is valid.
while (i < BufLength-1 && i < Col-1 && Buf[i] != '\n' && Buf[i] != '\r')
++i;
if (i < Col-1)
return getLocForStartOfFile(FirstFID).getFileLocWithOffset(FilePos + i);
return getLocForStartOfFile(FirstFID).getFileLocWithOffset(FilePos + Col - 1); return getLocForStartOfFile(FirstFID).getFileLocWithOffset(FilePos + Col - 1);
} }

View File

@ -61,4 +61,5 @@ void f(void *ptr) {
// CHECK: Literal: ""Hello"" [9:24 - 9:31] // CHECK: Literal: ""Hello"" [9:24 - 9:31]
// CHECK: Punctuation: ";" [9:31 - 9:32] // CHECK: Punctuation: ";" [9:31 - 9:32]
// CHECK: Punctuation: "}" [10:1 - 10:2] // CHECK: Punctuation: "}" [10:1 - 10:2]
// RUN: c-index-test -test-annotate-tokens=%s:4:1:165:32 %s | FileCheck %s
// RUN: c-index-test -test-annotate-tokens=%s:4:1:165:38 %s | FileCheck %s