forked from OSchip/llvm-project
Teach ASTUnit to keep track of temporary files, then delete them when
the ASTUnit itself is destroyed. Fixes <rdar://problem/7649385>. llvm-svn: 96628
This commit is contained in:
parent
60b3326435
commit
6cb5ba4c4f
|
@ -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; }
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue