Skip to content

Commit

Permalink
Teach ASTUnit to keep track of temporary files, then delete them when
Browse files Browse the repository at this point in the history
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
  • Loading branch information
DougGregor committed Feb 18, 2010
1 parent 7f71c68 commit 732a7de
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 17 deletions.
15 changes: 12 additions & 3 deletions include/clang/Frontend/ASTUnit.h
Expand Up @@ -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>
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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

Expand All @@ -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; }
Expand Down
6 changes: 3 additions & 3 deletions lib/Frontend/ASTUnit.cpp
Expand Up @@ -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 {
Expand Down
25 changes: 16 additions & 9 deletions tools/CIndex/CIndex.cpp
Expand Up @@ -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));
}
Expand Down Expand Up @@ -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;
}

Expand Down
12 changes: 10 additions & 2 deletions tools/CIndex/CIndexCodeCompletion.cpp
Expand Up @@ -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()
Expand All @@ -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,
Expand Down Expand Up @@ -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;
}
Expand Down

0 comments on commit 732a7de

Please sign in to comment.