summaryrefslogtreecommitdiffstats
path: root/clang/lib/Basic/SourceManager.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-09-22 21:11:38 +0000
committerDouglas Gregor <dgregor@apple.com>2009-09-22 21:11:38 +0000
commitea9b03e6e23408325145ca089e4d7d6386b65a2d (patch)
treea43f3c51bb90111c9d4a879c5efd9d7bf78755e5 /clang/lib/Basic/SourceManager.cpp
parent320a1c40831272686dca85e03e603b65345eb95c (diff)
downloadbcm5719-llvm-ea9b03e6e23408325145ca089e4d7d6386b65a2d.tar.gz
bcm5719-llvm-ea9b03e6e23408325145ca089e4d7d6386b65a2d.zip
Replace the -code-completion-dump option with
-code-completion-at=filename:line:column which performs code completion at the specified location by truncating the file at that position and enabling code completion. This approach makes it possible to run multiple tests from a single test file, and gives a more natural command-line interface. llvm-svn: 82571
Diffstat (limited to 'clang/lib/Basic/SourceManager.cpp')
-rw-r--r--clang/lib/Basic/SourceManager.cpp81
1 files changed, 79 insertions, 2 deletions
diff --git a/clang/lib/Basic/SourceManager.cpp b/clang/lib/Basic/SourceManager.cpp
index d1c47095a24..962cb4c42a8 100644
--- a/clang/lib/Basic/SourceManager.cpp
+++ b/clang/lib/Basic/SourceManager.cpp
@@ -41,9 +41,10 @@ unsigned ContentCache::getSizeBytesMapped() const {
/// getSize - Returns the size of the content encapsulated by this ContentCache.
/// This can be the size of the source file or the size of an arbitrary
/// scratch buffer. If the ContentCache encapsulates a source file, that
-/// file is not lazily brought in from disk to satisfy this query.
+/// file is not lazily brought in from disk to satisfy this query unless it
+/// needs to be truncated due to a truncateAt() call.
unsigned ContentCache::getSize() const {
- return Entry ? Entry->getSize() : Buffer->getBufferSize();
+ return Buffer ? Buffer->getBufferSize() : Entry->getSize();
}
const llvm::MemoryBuffer *ContentCache::getBuffer() const {
@@ -52,10 +53,54 @@ const llvm::MemoryBuffer *ContentCache::getBuffer() const {
// FIXME: Should we support a way to not have to do this check over
// and over if we cannot open the file?
Buffer = MemoryBuffer::getFile(Entry->getName(), 0, Entry->getSize());
+ if (isTruncated())
+ const_cast<ContentCache *>(this)->truncateAt(TruncateAtLine,
+ TruncateAtColumn);
}
return Buffer;
}
+void ContentCache::truncateAt(unsigned Line, unsigned Column) {
+ TruncateAtLine = Line;
+ TruncateAtColumn = Column;
+
+ if (!isTruncated() || !Buffer)
+ return;
+
+ // Find the byte position of the truncation point.
+ const char *Position = Buffer->getBufferStart();
+ for (unsigned Line = 1; Line < TruncateAtLine; ++Line) {
+ for (; *Position; ++Position) {
+ if (*Position != '\r' && *Position != '\n')
+ continue;
+
+ // Eat \r\n or \n\r as a single line.
+ if ((Position[1] == '\r' || Position[1] == '\n') &&
+ Position[0] != Position[1])
+ ++Position;
+ ++Position;
+ break;
+ }
+ }
+
+ for (unsigned Column = 1; Column < TruncateAtColumn; ++Column, ++Position) {
+ if (!*Position)
+ break;
+
+ if (*Position == '\t')
+ Column += 7;
+ }
+
+ // Truncate the buffer.
+ if (Position != Buffer->getBufferEnd()) {
+ MemoryBuffer *TruncatedBuffer
+ = MemoryBuffer::getMemBufferCopy(Buffer->getBufferStart(), Position,
+ Buffer->getBufferIdentifier());
+ delete Buffer;
+ Buffer = TruncatedBuffer;
+ }
+}
+
unsigned LineTableInfo::getLineTableFilenameID(const char *Ptr, unsigned Len) {
// Look up the filename in the string table, returning the pre-existing value
// if it exists.
@@ -287,6 +332,16 @@ SourceManager::getOrCreateContentCache(const FileEntry *FileEnt) {
EntryAlign = std::max(8U, EntryAlign);
Entry = ContentCacheAlloc.Allocate<ContentCache>(1, EntryAlign);
new (Entry) ContentCache(FileEnt);
+
+ if (FileEnt == TruncateFile) {
+ // If we had queued up a file truncation request, perform the truncation
+ // now.
+ Entry->truncateAt(TruncateAtLine, TruncateAtColumn);
+ TruncateFile = 0;
+ TruncateAtLine = 0;
+ TruncateAtColumn = 0;
+ }
+
return Entry;
}
@@ -1058,6 +1113,28 @@ bool SourceManager::isBeforeInTranslationUnit(SourceLocation LHS,
}
}
+void SourceManager::truncateFileAt(const FileEntry *Entry, unsigned Line,
+ unsigned Column) {
+ llvm::DenseMap<const FileEntry*, SrcMgr::ContentCache*>::iterator FI
+ = FileInfos.find(Entry);
+ if (FI != FileInfos.end()) {
+ FI->second->truncateAt(Line, Column);
+ return;
+ }
+
+ // We cannot perform the truncation until we actually see the file, so
+ // save the truncation information.
+ assert(TruncateFile == 0 && "Can't queue up multiple file truncations!");
+ TruncateFile = Entry;
+ TruncateAtLine = Line;
+ TruncateAtColumn = Column;
+}
+
+/// \brief Determine whether this file was truncated.
+bool SourceManager::isTruncatedFile(FileID FID) const {
+ return getSLocEntry(FID).getFile().getContentCache()->isTruncated();
+}
+
/// PrintStats - Print statistics to stderr.
///
void SourceManager::PrintStats() const {
OpenPOWER on IntegriCloud