]> granicus.if.org Git - clang/commitdiff
When performing in-process code completion, don't free the remapped
authorDouglas Gregor <dgregor@apple.com>
Wed, 4 Aug 2010 17:07:00 +0000 (17:07 +0000)
committerDouglas Gregor <dgregor@apple.com>
Wed, 4 Aug 2010 17:07:00 +0000 (17:07 +0000)
file buffers until the code completion results are destroyed;
diagnostics may end up referring into the source.

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

lib/Frontend/ASTUnit.cpp
tools/libclang/CIndexCodeCompletion.cpp

index 5bffbacaf69127372eadd85639d3a55870256ac3..2d1708ccc6e783bd06c47cc7a0ce318654247145 100644 (file)
@@ -1213,6 +1213,7 @@ void ASTUnit::CodeComplete(llvm::StringRef File, unsigned Line, unsigned Column,
 
   // Remap files.
   PreprocessorOpts.clearRemappedFiles();
+  PreprocessorOpts.RetainRemappedFileBuffers = true;
   for (unsigned I = 0; I != NumRemappedFiles; ++I)
     PreprocessorOpts.addRemappedFile(RemappedFiles[I].first,
                                      RemappedFiles[I].second);
index f8fd470a1d8a8272deb76b43d95e30521f1525c2..2aa644b75795c972e0365b55de1a78c9129093e8 100644 (file)
@@ -224,10 +224,6 @@ struct AllocatedCXCodeCompleteResults : public CXCodeCompleteResults {
   AllocatedCXCodeCompleteResults();
   ~AllocatedCXCodeCompleteResults();
   
-  /// \brief The memory buffer from which we parsed the results. We
-  /// retain this buffer because the completion strings point into it.
-  llvm::MemoryBuffer *Buffer;
-
   /// \brief Diagnostics produced while performing code completion.
   llvm::SmallVector<StoredDiagnostic, 8> Diagnostics;
 
@@ -246,20 +242,23 @@ struct AllocatedCXCodeCompleteResults : public CXCodeCompleteResults {
   /// \brief Temporary files that should be removed once we have finished
   /// with the code-completion results.
   std::vector<llvm::sys::Path> TemporaryFiles;
+
+  /// \brief Temporary buffers that will be deleted once we have finished with the code-completion results.
+  llvm::SmallVector<const llvm::MemoryBuffer *, 1> TemporaryBuffers;
 };
 
 AllocatedCXCodeCompleteResults::AllocatedCXCodeCompleteResults() 
-  : CXCodeCompleteResults(), Buffer(0), Diag(new Diagnostic), 
-    SourceMgr(*Diag) { }
+  : CXCodeCompleteResults(), Diag(new Diagnostic), SourceMgr(*Diag) { }
   
 AllocatedCXCodeCompleteResults::~AllocatedCXCodeCompleteResults() {
   for (unsigned I = 0, N = NumResults; I != N; ++I)
     delete (CXStoredCodeCompletionString *)Results[I].CompletionString;
   delete [] Results;
-  delete Buffer;
   
   for (unsigned I = 0, N = TemporaryFiles.size(); I != N; ++I)
     TemporaryFiles[I].eraseFromDisk();
+  for (unsigned I = 0, N = TemporaryBuffers.size(); I != N; ++I)
+    delete TemporaryBuffers[I];
 }
   
 CXCodeCompleteResults *clang_codeComplete(CXIndex CIdx,
@@ -409,7 +408,6 @@ CXCodeCompleteResults *clang_codeComplete(CXIndex CIdx,
   AllocatedCXCodeCompleteResults *Results = new AllocatedCXCodeCompleteResults;
   Results->Results = 0;
   Results->NumResults = 0;
-  Results->Buffer = 0;
   // FIXME: Set Results->LangOpts!
   if (MemoryBuffer *F = MemoryBuffer::getFile(ResultsFile.c_str())) {
     llvm::SmallVector<CXCompletionResult, 4> CompletionResults;
@@ -445,7 +443,7 @@ CXCodeCompleteResults *clang_codeComplete(CXIndex CIdx,
     Results->NumResults = CompletionResults.size();
     memcpy(Results->Results, CompletionResults.data(),
            CompletionResults.size() * sizeof(CXCompletionResult));
-    Results->Buffer = F;
+    Results->TemporaryBuffers.push_back(F);
   }
 
   LoadSerializedDiagnostics(DiagnosticsFile, num_unsaved_files, unsaved_files,
@@ -602,11 +600,15 @@ CXCodeCompleteResults *clang_codeCompleteAt(CXTranslationUnit TU,
   AllocatedCXCodeCompleteResults *Results = new AllocatedCXCodeCompleteResults;
   Results->Results = 0;
   Results->NumResults = 0;
-  Results->Buffer = 0;
 
   // Create a code-completion consumer to capture the results.
   CaptureCompletionResults Capture(*Results);
 
+  // Make sure that we free the temporary buffers when the
+  // code-completion constructor is freed.
+  for (unsigned I = 0, N = RemappedFiles.size(); I != N; ++I)
+    Results->TemporaryBuffers.push_back(RemappedFiles[I].second);
+
   // Perform completion.
   AST->CodeComplete(complete_filename, complete_line, complete_column,
                     RemappedFiles.data(), RemappedFiles.size(), Capture,