[cfe-commits] r111597 - in /cfe/trunk: include/clang/Frontend/ASTUnit.h lib/Frontend/ASTUnit.cpp test/Index/crash-recovery-code-complete.c tools/libclang/CIndexCodeCompletion.cpp

Douglas Gregor dgregor at apple.com
Thu Aug 19 17:59:43 PDT 2010


Author: dgregor
Date: Thu Aug 19 19:59:43 2010
New Revision: 111597

URL: http://llvm.org/viewvc/llvm-project?rev=111597&view=rev
Log:
When performing code-completion in the presence of a preamble, make
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.

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

Modified: cfe/trunk/include/clang/Frontend/ASTUnit.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/ASTUnit.h?rev=111597&r1=111596&r2=111597&view=diff
==============================================================================
--- cfe/trunk/include/clang/Frontend/ASTUnit.h (original)
+++ cfe/trunk/include/clang/Frontend/ASTUnit.h Thu Aug 19 19:59:43 2010
@@ -311,6 +311,7 @@
                   unsigned MaxLines, bool &CreatedBuffer);
   
   llvm::MemoryBuffer *getMainBufferWithPrecompiledPreamble(
+                                         CompilerInvocation PreambleInvocation,
                                                      bool AllowRebuild = true,
                                                         unsigned MaxLines = 0);
   void RealizeTopLevelDeclsFromPreamble();
@@ -546,16 +547,16 @@
   /// \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.
   ///

Modified: cfe/trunk/lib/Frontend/ASTUnit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/ASTUnit.cpp?rev=111597&r1=111596&r2=111597&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/ASTUnit.cpp (original)
+++ cfe/trunk/lib/Frontend/ASTUnit.cpp Thu Aug 19 19:59:43 2010
@@ -940,9 +940,9 @@
 /// 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 @@
   // 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 @@
   // 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 @@
                            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 @@
   // 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 @@
     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 @@
       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 @@
     CompletionTimer->stopTimer();
   
   // Steal back our resources. 
-  delete OverrideMainBuffer;
   Clang.takeFileManager();
   Clang.takeSourceManager();
   Clang.takeInvocation();

Modified: cfe/trunk/test/Index/crash-recovery-code-complete.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/crash-recovery-code-complete.c?rev=111597&r1=111596&r2=111597&view=diff
==============================================================================
--- cfe/trunk/test/Index/crash-recovery-code-complete.c (original)
+++ cfe/trunk/test/Index/crash-recovery-code-complete.c Thu Aug 19 19:59:43 2010
@@ -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

Modified: cfe/trunk/tools/libclang/CIndexCodeCompletion.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndexCodeCompletion.cpp?rev=111597&r1=111596&r2=111597&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CIndexCodeCompletion.cpp (original)
+++ cfe/trunk/tools/libclang/CIndexCodeCompletion.cpp Thu Aug 19 19:59:43 2010
@@ -624,11 +624,6 @@
   // 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 @@
                     (options & CXCodeComplete_IncludeCodePatterns),
                     Capture,
                     *Results->Diag, Results->LangOpts, Results->SourceMgr,
-                    Results->FileMgr, Results->Diagnostics);
+                    Results->FileMgr, Results->Diagnostics,
+                    Results->TemporaryBuffers);
 
   
 





More information about the cfe-commits mailing list