aboutsummaryrefslogtreecommitdiff
path: root/lib/Lex/Preprocessor.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-12-02 06:49:09 +0000
committerDouglas Gregor <dgregor@apple.com>2009-12-02 06:49:09 +0000
commit2968442603b029949246467253eeac8139a5b6d8 (patch)
treeff548e890078ba6293daa74c947dcdf57c410798 /lib/Lex/Preprocessor.cpp
parenta46e4d91d8f3eb341f2387768db66dcfe8dd0afa (diff)
Extend the source manager with the ability to override the contents of
files with the contents of an arbitrary memory buffer. Use this new functionality to drastically clean up the way in which we handle file truncation for code-completion: all of the truncation/completion logic is now encapsulated in the preprocessor where it belongs (<rdar://problem/7434737>). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@90300 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Lex/Preprocessor.cpp')
-rw-r--r--lib/Lex/Preprocessor.cpp60
1 files changed, 59 insertions, 1 deletions
diff --git a/lib/Lex/Preprocessor.cpp b/lib/Lex/Preprocessor.cpp
index 066909475f..c757820494 100644
--- a/lib/Lex/Preprocessor.cpp
+++ b/lib/Lex/Preprocessor.cpp
@@ -50,7 +50,8 @@ Preprocessor::Preprocessor(Diagnostic &diags, const LangOptions &opts,
bool OwnsHeaders)
: Diags(&diags), Features(opts), Target(target),FileMgr(Headers.getFileMgr()),
SourceMgr(SM), HeaderInfo(Headers), Identifiers(opts, IILookup),
- BuiltinInfo(Target), CurPPLexer(0), CurDirLookup(0), Callbacks(0) {
+ BuiltinInfo(Target), CodeCompletionFile(0), CurPPLexer(0), CurDirLookup(0),
+ Callbacks(0) {
ScratchBuf = new ScratchBuffer(SourceMgr);
CounterValue = 0; // __COUNTER__ starts at 0.
OwnsHeaderSearch = OwnsHeaders;
@@ -188,6 +189,63 @@ void Preprocessor::PrintStats() {
<< NumFastTokenPaste << " on the fast path.\n";
}
+bool Preprocessor::SetCodeCompletionPoint(const FileEntry *File,
+ unsigned TruncateAtLine,
+ unsigned TruncateAtColumn) {
+ using llvm::MemoryBuffer;
+
+ CodeCompletionFile = File;
+
+ // Okay to clear out the code-completion point by passing NULL.
+ if (!CodeCompletionFile)
+ return false;
+
+ // Load the actual file's contents.
+ const MemoryBuffer *Buffer = SourceMgr.getMemoryBufferForFile(File);
+ if (!Buffer)
+ return true;
+
+ // 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());
+ SourceMgr.overrideFileContents(File, TruncatedBuffer);
+ }
+
+ return false;
+}
+
+bool Preprocessor::isCodeCompletionFile(SourceLocation FileLoc) {
+ return CodeCompletionFile && FileLoc.isFileID() &&
+ SourceMgr.getFileEntryForID(SourceMgr.getFileID(FileLoc))
+ == CodeCompletionFile;
+}
+
//===----------------------------------------------------------------------===//
// Token Spelling
//===----------------------------------------------------------------------===//