]> granicus.if.org Git - clang/commitdiff
When performing code-completion in the presence of a preamble, make
authorDouglas Gregor <dgregor@apple.com>
Fri, 20 Aug 2010 00:59:43 +0000 (00:59 +0000)
committerDouglas Gregor <dgregor@apple.com>
Fri, 20 Aug 2010 00:59:43 +0000 (00:59 +0000)
sure to (1) actually use the remapped files we were given rather
than old data, and (2) keep the remapped files alive until the
code-completion results are destroyed. Big thanks to Daniel for the
test case.

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

include/clang/Frontend/ASTUnit.h
lib/Frontend/ASTUnit.cpp
test/Index/crash-recovery-code-complete.c
tools/libclang/CIndexCodeCompletion.cpp

index 8f3b4d40f1a31956269dd7d8afc4672c4f1f01e8..e323170b08ffbc6fb90a1259736bc7bccfdb9fcb 100644 (file)
@@ -311,6 +311,7 @@ private:
                   unsigned MaxLines, bool &CreatedBuffer);
   
   llvm::MemoryBuffer *getMainBufferWithPrecompiledPreamble(
+                                         CompilerInvocation PreambleInvocation,
                                                      bool AllowRebuild = true,
                                                         unsigned MaxLines = 0);
   void RealizeTopLevelDeclsFromPreamble();
@@ -546,16 +547,16 @@ public:
   /// \param IncludeCodePatterns Whether to include code patterns (such as a 
   /// for loop) in the code-completion results.
   ///
-  /// FIXME: The Diag, LangOpts, SourceMgr, FileMgr, and
-  /// StoredDiagnostics parameters are all disgusting hacks. They will
-  /// go away.
+  /// FIXME: The Diag, LangOpts, SourceMgr, FileMgr, StoredDiagnostics, and
+  /// OwnedBuffers parameters are all disgusting hacks. They will go away.
   void CodeComplete(llvm::StringRef File, unsigned Line, unsigned Column,
                     RemappedFile *RemappedFiles, unsigned NumRemappedFiles,
                     bool IncludeMacros, bool IncludeCodePatterns,
                     CodeCompleteConsumer &Consumer,
                     Diagnostic &Diag, LangOptions &LangOpts,
                     SourceManager &SourceMgr, FileManager &FileMgr,
-                    llvm::SmallVectorImpl<StoredDiagnostic> &StoredDiagnostics);
+                    llvm::SmallVectorImpl<StoredDiagnostic> &StoredDiagnostics,
+              llvm::SmallVectorImpl<const llvm::MemoryBuffer *> &OwnedBuffers);
 
   /// \brief Save this translation unit to a file with the given name.
   ///
index 9c5fea4717a942a5c51c8a389aefa8048e40043b..1377e739ed624bf8431fb02a2348d1bb83427122 100644 (file)
@@ -940,9 +940,9 @@ static llvm::MemoryBuffer *CreatePaddedMainFileBuffer(llvm::MemoryBuffer *Old,
 /// buffer that should be used in place of the main file when doing so.
 /// Otherwise, returns a NULL pointer.
 llvm::MemoryBuffer *ASTUnit::getMainBufferWithPrecompiledPreamble(
+                                          CompilerInvocation PreambleInvocation,
                                                            bool AllowRebuild,
                                                            unsigned MaxLines) {
-  CompilerInvocation PreambleInvocation(*Invocation);
   FrontendOptions &FrontendOpts = PreambleInvocation.getFrontendOpts();
   PreprocessorOptions &PreprocessorOpts
     = PreambleInvocation.getPreprocessorOpts();
@@ -1312,7 +1312,8 @@ ASTUnit *ASTUnit::LoadFromCompilerInvocation(CompilerInvocation *CI,
   // FIXME: When C++ PCH is ready, allow use of it for a precompiled preamble.
   if (PrecompilePreamble && !CI->getLangOpts().CPlusPlus) {
     AST->PreambleRebuildCounter = 1;
-    OverrideMainBuffer = AST->getMainBufferWithPrecompiledPreamble();
+    OverrideMainBuffer
+      = AST->getMainBufferWithPrecompiledPreamble(*AST->Invocation);
   }
   
   llvm::Timer *ParsingTimer = 0;
@@ -1437,7 +1438,7 @@ bool ASTUnit::Reparse(RemappedFile *RemappedFiles, unsigned NumRemappedFiles) {
   // build a precompiled preamble, do so now.
   llvm::MemoryBuffer *OverrideMainBuffer = 0;
   if (!PreambleFile.empty() || PreambleRebuildCounter > 0)
-    OverrideMainBuffer = getMainBufferWithPrecompiledPreamble();
+    OverrideMainBuffer = getMainBufferWithPrecompiledPreamble(*Invocation);
     
   // Clear out the diagnostics state.
   if (!OverrideMainBuffer)
@@ -1663,7 +1664,8 @@ void ASTUnit::CodeComplete(llvm::StringRef File, unsigned Line, unsigned Column,
                            CodeCompleteConsumer &Consumer,
                            Diagnostic &Diag, LangOptions &LangOpts,
                            SourceManager &SourceMgr, FileManager &FileMgr,
-                   llvm::SmallVectorImpl<StoredDiagnostic> &StoredDiagnostics) {
+                   llvm::SmallVectorImpl<StoredDiagnostic> &StoredDiagnostics,
+             llvm::SmallVectorImpl<const llvm::MemoryBuffer *> &OwnedBuffers) {
   if (!Invocation.get())
     return;
 
@@ -1739,9 +1741,11 @@ void ASTUnit::CodeComplete(llvm::StringRef File, unsigned Line, unsigned Column,
   // Remap files.
   PreprocessorOpts.clearRemappedFiles();
   PreprocessorOpts.RetainRemappedFileBuffers = true;
-  for (unsigned I = 0; I != NumRemappedFiles; ++I)
+  for (unsigned I = 0; I != NumRemappedFiles; ++I) {
     PreprocessorOpts.addRemappedFile(RemappedFiles[I].first,
                                      RemappedFiles[I].second);
+    OwnedBuffers.push_back(RemappedFiles[I].second);
+  }
   
   // Use the code completion consumer we were given, but adding any cached
   // code-completion results.
@@ -1763,8 +1767,8 @@ void ASTUnit::CodeComplete(llvm::StringRef File, unsigned Line, unsigned Column,
     if (const FileStatus *CompleteFileStatus = CompleteFilePath.getFileStatus())
       if (const FileStatus *MainStatus = MainPath.getFileStatus())
         if (CompleteFileStatus->getUniqueID() == MainStatus->getUniqueID())
-          OverrideMainBuffer = getMainBufferWithPrecompiledPreamble(false, 
-                                                                    Line);
+          OverrideMainBuffer
+            = getMainBufferWithPrecompiledPreamble(CCInvocation, false, Line);
   }
 
   // If the main file has been overridden due to the use of a preamble,
@@ -1785,6 +1789,8 @@ void ASTUnit::CodeComplete(llvm::StringRef File, unsigned Line, unsigned Column,
       FullSourceLoc Loc(StoredDiagnostics[I].getLocation(), SourceMgr);
       StoredDiagnostics[I].setLocation(Loc);
     }
+    
+    OwnedBuffers.push_back(OverrideMainBuffer);
   } else {
     PreprocessorOpts.PrecompiledPreambleBytes.first = 0;
     PreprocessorOpts.PrecompiledPreambleBytes.second = false;
@@ -1802,7 +1808,6 @@ void ASTUnit::CodeComplete(llvm::StringRef File, unsigned Line, unsigned Column,
     CompletionTimer->stopTimer();
   
   // Steal back our resources. 
-  delete OverrideMainBuffer;
   Clang.takeFileManager();
   Clang.takeSourceManager();
   Clang.takeInvocation();
index be834fb81387f4bff304a45e05995cb6d7f1b409..71b98b639be09fe8d74745225e7b1d3e355ea2b7 100644 (file)
@@ -1,11 +1,10 @@
-// RUN: echo env CINDEXTEST_EDITING=1 \
+// RUN: env CINDEXTEST_EDITING=1 \
 // RUN:   not c-index-test -code-completion-at=%s:20:1 \
-// RUN:   -remap-file="%s;%S/Inputs/crash-recovery-code-complete-remap.c" \
+// RUN:   "-remap-file=%s;%S/Inputs/crash-recovery-code-complete-remap.c" \
 // RUN:   %s 2> %t.err
 // RUN: FileCheck < %t.err -check-prefix=CHECK-CODE-COMPLETE-CRASH %s
-// CHECK-CODE-COMPLETE-CRASH: Unable to reparse translation unit
+// CHECK-CODE-COMPLETE-CRASH: Unable to perform code completion!
 //
 // XFAIL: win32
-// XFAIL: *
 
 #warning parsing original file
index 53767c446779cbd31553e8ce131edff4948a0a7b..c2febf9b722d6f0a8f3cfd71aac58e9309a411a7 100644 (file)
@@ -624,11 +624,6 @@ void clang_codeCompleteAt_Impl(void *UserData) {
   // 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(), 
@@ -636,7 +631,8 @@ void clang_codeCompleteAt_Impl(void *UserData) {
                     (options & CXCodeComplete_IncludeCodePatterns),
                     Capture,
                     *Results->Diag, Results->LangOpts, Results->SourceMgr,
-                    Results->FileMgr, Results->Diagnostics);
+                    Results->FileMgr, Results->Diagnostics,
+                    Results->TemporaryBuffers);