aboutsummaryrefslogtreecommitdiff
path: root/lib/Lex/Preprocessor.cpp
diff options
context:
space:
mode:
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>2011-09-04 03:32:15 +0000
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>2011-09-04 03:32:15 +0000
commit7d100872341f233c81e1d7b72b40457e62c36862 (patch)
treed3c842889058206c8193e7630f19159ebcaaeab5 /lib/Lex/Preprocessor.cpp
parentc8c97a03eb0fdeb4f5fc9c4dea308ebbf46c2c93 (diff)
Support code-completion for C++ inline methods and ObjC buffering methods.
Previously we would cut off the source file buffer at the code-completion point; this impeded code-completion inside C++ inline methods and, recently, with buffering ObjC methods. Have the code-completion inserted into the source buffer so that it can be buffered along with a method body. When we actually hit the code-completion point the cut-off lexing or parsing. Fixes rdar://10056932&8319466 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@139086 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Lex/Preprocessor.cpp')
-rw-r--r--lib/Lex/Preprocessor.cpp51
1 files changed, 25 insertions, 26 deletions
diff --git a/lib/Lex/Preprocessor.cpp b/lib/Lex/Preprocessor.cpp
index e189a9da81..3175d0450e 100644
--- a/lib/Lex/Preprocessor.cpp
+++ b/lib/Lex/Preprocessor.cpp
@@ -59,7 +59,8 @@ Preprocessor::Preprocessor(Diagnostic &diags, LangOptions &opts,
SourceMgr(SM), HeaderInfo(Headers), TheModuleLoader(TheModuleLoader),
ExternalSource(0),
Identifiers(opts, IILookup), CodeComplete(0),
- CodeCompletionFile(0), SkipMainFilePreamble(0, true), CurPPLexer(0),
+ CodeCompletionFile(0), CodeCompletionOffset(0), CodeCompletionReached(0),
+ SkipMainFilePreamble(0, true), CurPPLexer(0),
CurDirLookup(0), Callbacks(0), MacroArgCache(0), Record(0), MIChainHead(0),
MICache(0)
{
@@ -73,7 +74,8 @@ Preprocessor::Preprocessor(Diagnostic &diags, LangOptions &opts,
Preprocessor::~Preprocessor() {
assert(BacktrackPositions.empty() && "EnableBacktrack/Backtrack imbalance!");
- assert(MacroExpandingLexersStack.empty() && MacroExpandedTokens.empty() &&
+ assert(((MacroExpandingLexersStack.empty() && MacroExpandedTokens.empty()) ||
+ isCodeCompletionReached()) &&
"Preprocessor::HandleEndOfTokenLexer should have cleared those");
while (!IncludeMacroStack.empty()) {
@@ -270,15 +272,13 @@ Preprocessor::macro_end(bool IncludeExternalMacros) const {
}
bool Preprocessor::SetCodeCompletionPoint(const FileEntry *File,
- unsigned TruncateAtLine,
- unsigned TruncateAtColumn) {
- using llvm::MemoryBuffer;
-
- CodeCompletionFile = File;
+ unsigned CompleteLine,
+ unsigned CompleteColumn) {
+ assert(File);
+ assert(CompleteLine && CompleteColumn && "Starts from 1:1");
+ assert(!CodeCompletionFile && "Already set");
- // Okay to clear out the code-completion point by passing NULL.
- if (!CodeCompletionFile)
- return false;
+ using llvm::MemoryBuffer;
// Load the actual file's contents.
bool Invalid = false;
@@ -288,7 +288,7 @@ bool Preprocessor::SetCodeCompletionPoint(const FileEntry *File,
// Find the byte position of the truncation point.
const char *Position = Buffer->getBufferStart();
- for (unsigned Line = 1; Line < TruncateAtLine; ++Line) {
+ for (unsigned Line = 1; Line < CompleteLine; ++Line) {
for (; *Position; ++Position) {
if (*Position != '\r' && *Position != '\n')
continue;
@@ -302,31 +302,30 @@ bool Preprocessor::SetCodeCompletionPoint(const FileEntry *File,
}
}
- Position += TruncateAtColumn - 1;
+ Position += CompleteColumn - 1;
- // Truncate the buffer.
+ // Insert '\0' at the code-completion point.
if (Position < Buffer->getBufferEnd()) {
- StringRef Data(Buffer->getBufferStart(),
- Position-Buffer->getBufferStart());
- MemoryBuffer *TruncatedBuffer
- = MemoryBuffer::getMemBufferCopy(Data, Buffer->getBufferIdentifier());
- SourceMgr.overrideFileContents(File, TruncatedBuffer);
+ CodeCompletionFile = File;
+ CodeCompletionOffset = Position - Buffer->getBufferStart();
+
+ MemoryBuffer *NewBuffer =
+ MemoryBuffer::getNewUninitMemBuffer(Buffer->getBufferSize() + 1,
+ Buffer->getBufferIdentifier());
+ char *NewBuf = (char*)NewBuffer->getBufferStart();
+ char *NewPos = std::copy(Buffer->getBufferStart(), Position, NewBuf);
+ *NewPos = '\0';
+ std::copy(Position, Buffer->getBufferEnd(), NewPos+1);
+ SourceMgr.overrideFileContents(File, NewBuffer);
}
return false;
}
-bool Preprocessor::isCodeCompletionFile(SourceLocation FileLoc) const {
- return CodeCompletionFile && FileLoc.isFileID() &&
- SourceMgr.getFileEntryForID(SourceMgr.getFileID(FileLoc))
- == CodeCompletionFile;
-}
-
void Preprocessor::CodeCompleteNaturalLanguage() {
- SetCodeCompletionPoint(0, 0, 0);
- getDiagnostics().setSuppressAllDiagnostics(true);
if (CodeComplete)
CodeComplete->CodeCompleteNaturalLanguage();
+ setCodeCompletionReached();
}
/// getSpelling - This method is used to get the spelling of a token into a