]> granicus.if.org Git - clang/commitdiff
Teach ASTUnit to keep track of temporary files, then delete them when
authorDouglas Gregor <dgregor@apple.com>
Thu, 18 Feb 2010 23:35:40 +0000 (23:35 +0000)
committerDouglas Gregor <dgregor@apple.com>
Thu, 18 Feb 2010 23:35:40 +0000 (23:35 +0000)
the ASTUnit itself is destroyed. Fixes <rdar://problem/7649385>.

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

include/clang/Frontend/ASTUnit.h
lib/Frontend/ASTUnit.cpp
tools/CIndex/CIndex.cpp
tools/CIndex/CIndexCodeCompletion.cpp

index 71a895ffb9090062bea4a05e8f052396d9b3571b..626a162371bddc8b1a7523b483457b0afdfb705d 100644 (file)
@@ -19,6 +19,7 @@
 #include "clang/Basic/FileManager.h"
 #include "clang/Index/ASTLocation.h"
 #include "llvm/ADT/SmallVector.h"
+#include "llvm/System/Path.h"
 #include <string>
 #include <vector>
 #include <cassert>
@@ -52,7 +53,6 @@ class ASTUnit {
   llvm::OwningPtr<TargetInfo>       Target;
   llvm::OwningPtr<Preprocessor>     PP;
   llvm::OwningPtr<ASTContext>       Ctx;
-  bool                              tempFile;
 
   /// Optional owned invocation, just used to make the invocation used in
   /// LoadFromCommandLine available.
@@ -85,6 +85,10 @@ class ASTUnit {
   /// translation unit.
   llvm::SmallVector<StoredDiagnostic, 4> Diagnostics;
 
+  /// \brief Temporary files that should be removed when the ASTUnit is 
+  /// destroyed.
+  llvm::SmallVector<llvm::sys::Path, 4> TemporaryFiles;
+  
   ASTUnit(const ASTUnit&); // DO NOT IMPLEMENT
   ASTUnit &operator=(const ASTUnit &); // DO NOT IMPLEMENT
 
@@ -109,8 +113,13 @@ public:
   const std::string &getOriginalSourceFileName();
   const std::string &getPCHFileName();
 
-  void unlinkTemporaryFile() { tempFile = true; }
-
+  /// \brief Add a temporary file that the ASTUnit depends on.
+  ///
+  /// This file will be erased when the ASTUnit is destroyed.
+  void addTemporaryFile(const llvm::sys::Path &TempFile) {
+    TemporaryFiles.push_back(TempFile);
+  }
+                        
   bool getOnlyLocalDecls() const { return OnlyLocalDecls; }
 
   void setLastASTLocation(ASTLocation ALoc) { LastLoc = ALoc; }
index 345b9ba4d36d1dbc38b28f889fd5ff97dc19bca2..8874622a24daaf36698b29c3c0c7cc1bd1e54674 100644 (file)
 using namespace clang;
 
 ASTUnit::ASTUnit(bool _MainFileIsAST)
-  : tempFile(false), MainFileIsAST(_MainFileIsAST) {
+  : MainFileIsAST(_MainFileIsAST) {
 }
 ASTUnit::~ASTUnit() {
-  if (tempFile)
-    llvm::sys::Path(getPCHFileName()).eraseFromDisk();
+  for (unsigned I = 0, N = TemporaryFiles.size(); I != N; ++I)
+    TemporaryFiles[I].eraseFromDisk();
 }
 
 namespace {
index 5eddee45b2c28f11ab21ba87ddc583639ce3d8e6..f74daf8e8892f09a8a12a48a7ee7582e0a847dff 100644 (file)
@@ -966,9 +966,9 @@ clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
   llvm::SmallVector<ASTUnit::RemappedFile, 4> RemappedFiles;
   for (unsigned I = 0; I != num_unsaved_files; ++I) {
     const llvm::MemoryBuffer *Buffer
-    = llvm::MemoryBuffer::getMemBuffer(unsaved_files[I].Contents,
-                                       unsaved_files[I].Contents + unsaved_files[I].Length,
-                                       unsaved_files[I].Filename);
+      = llvm::MemoryBuffer::getMemBuffer(unsaved_files[I].Contents,
+                          unsaved_files[I].Contents + unsaved_files[I].Length,
+                                         unsaved_files[I].Filename);
     RemappedFiles.push_back(std::make_pair(unsaved_files[I].Filename,
                                            Buffer));
   }
@@ -1129,12 +1129,19 @@ clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
     }
   }
 
-  if (ATU)
-    ATU->unlinkTemporaryFile();
-
-  for (unsigned i = 0, e = TemporaryFiles.size(); i != e; ++i)
-    TemporaryFiles[i].eraseFromDisk();
-
+  if (ATU) {
+    // Make the translation unit responsible for destroying all temporary files.
+    for (unsigned i = 0, e = TemporaryFiles.size(); i != e; ++i)
+      ATU->addTemporaryFile(TemporaryFiles[i]);
+    ATU->addTemporaryFile(llvm::sys::Path(ATU->getPCHFileName()));
+  } else {
+    // Destroy all of the temporary files now; they can't be referenced any
+    // longer.
+    llvm::sys::Path(astTmpFile).eraseFromDisk();
+    for (unsigned i = 0, e = TemporaryFiles.size(); i != e; ++i)
+      TemporaryFiles[i].eraseFromDisk();
+  }
+  
   return ATU;
 }
 
index 08510f2e557f82c26cc62cc5fa0ab8d856493732..b646474c81409c5a5ff2aff3029494015f3a4e01 100644 (file)
@@ -195,6 +195,10 @@ struct AllocatedCXCodeCompleteResults : public CXCodeCompleteResults {
   
   /// \brief File manager, used for diagnostics.
   FileManager FileMgr;
+  
+  /// \brief Temporary files that should be removed once we have finished
+  /// with the code-completion results.
+  std::vector<llvm::sys::Path> TemporaryFiles;
 };
 
 AllocatedCXCodeCompleteResults::AllocatedCXCodeCompleteResults() 
@@ -205,6 +209,9 @@ AllocatedCXCodeCompleteResults::~AllocatedCXCodeCompleteResults() {
     delete (CodeCompletionString *)Results[I].CompletionString;
   delete [] Results;
   delete Buffer;
+  
+  for (unsigned I = 0, N = TemporaryFiles.size(); I != N; ++I)
+    TemporaryFiles[I].eraseFromDisk();
 }
   
 CXCodeCompleteResults *clang_codeComplete(CXIndex CIdx,
@@ -369,8 +376,9 @@ CXCodeCompleteResults *clang_codeComplete(CXIndex CIdx,
                             Results->FileMgr, Results->SourceMgr, 
                             Results->Diagnostics);
 
-  for (unsigned i = 0, e = TemporaryFiles.size(); i != e; ++i)
-    TemporaryFiles[i].eraseFromDisk();
+  // Make sure we delete temporary files when the code-completion results are
+  // destroyed.
+  Results->TemporaryFiles.swap(TemporaryFiles);
 
   return Results;
 }