From 732a7dec07e5869f6b1de0faabc899e1a2449a6d Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Thu, 18 Feb 2010 23:35:40 +0000 Subject: [PATCH] Teach ASTUnit to keep track of temporary files, then delete them when the ASTUnit itself is destroyed. Fixes . git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@96628 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Frontend/ASTUnit.h | 15 ++++++++++++--- lib/Frontend/ASTUnit.cpp | 6 +++--- tools/CIndex/CIndex.cpp | 25 ++++++++++++++++--------- tools/CIndex/CIndexCodeCompletion.cpp | 12 ++++++++++-- 4 files changed, 41 insertions(+), 17 deletions(-) diff --git a/include/clang/Frontend/ASTUnit.h b/include/clang/Frontend/ASTUnit.h index 71a895ffb..626a16237 100644 --- a/include/clang/Frontend/ASTUnit.h +++ b/include/clang/Frontend/ASTUnit.h @@ -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 #include #include @@ -52,7 +53,6 @@ class ASTUnit { llvm::OwningPtr Target; llvm::OwningPtr PP; llvm::OwningPtr 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 Diagnostics; + /// \brief Temporary files that should be removed when the ASTUnit is + /// destroyed. + llvm::SmallVector TemporaryFiles; + ASTUnit(const ASTUnit&); // DO NOT IMPLEMENT ASTUnit &operator=(const ASTUnit &); // DO NOT IMPLEMENT @@ -109,8 +113,13 @@ class ASTUnit { 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; } diff --git a/lib/Frontend/ASTUnit.cpp b/lib/Frontend/ASTUnit.cpp index 345b9ba4d..8874622a2 100644 --- a/lib/Frontend/ASTUnit.cpp +++ b/lib/Frontend/ASTUnit.cpp @@ -36,11 +36,11 @@ 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 { diff --git a/tools/CIndex/CIndex.cpp b/tools/CIndex/CIndex.cpp index 5eddee45b..f74daf8e8 100644 --- a/tools/CIndex/CIndex.cpp +++ b/tools/CIndex/CIndex.cpp @@ -966,9 +966,9 @@ clang_createTranslationUnitFromSourceFile(CXIndex CIdx, llvm::SmallVector 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; } diff --git a/tools/CIndex/CIndexCodeCompletion.cpp b/tools/CIndex/CIndexCodeCompletion.cpp index 08510f2e5..b646474c8 100644 --- a/tools/CIndex/CIndexCodeCompletion.cpp +++ b/tools/CIndex/CIndexCodeCompletion.cpp @@ -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 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; }