TranslationUnit now owns IdentifierTable, TargetInfo, and Selectors objects
when it is constructed via deserialization. This is done by recording a flag
indicating that this is the case, and it deletes these objects by getting
the references stored in the ASTContext object. This fixes some memory
leaks that occurs when we deserialize translation units from bitcode files.
The rationale between having TranslationUnit sometimes own these objects and
sometimes not is that a TranslationUnit object can be constructed from
state generated by the parser (Preprocessor; semantic analyzer, etc.), and thus
in these cases won't own the IdentifierTable or Selectors, etc. During
deserialization, there is no Preprocessor, so somebody needs to own these
objects in order for them to be properly reclaimed.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@50149 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/Driver/ASTConsumers.cpp b/Driver/ASTConsumers.cpp
index eaee94e..2f04ab7 100644
--- a/Driver/ASTConsumers.cpp
+++ b/Driver/ASTConsumers.cpp
@@ -826,20 +826,24 @@
class ASTSerializer : public ASTConsumer {
protected:
Diagnostic &Diags;
- TranslationUnit TU;
+ const LangOptions& lang;
+ TranslationUnit* TU;
+
public:
ASTSerializer(Diagnostic& diags, const LangOptions& LO)
- : Diags(diags), TU(LO) {}
+ : Diags(diags), lang(LO), TU(0) {}
+
+ virtual ~ASTSerializer() { delete TU; }
virtual void Initialize(ASTContext &Context) {
- TU.setContext(&Context);
+ if (!TU) TU = new TranslationUnit(Context, lang);
}
virtual void HandleTopLevelDecl(Decl *D) {
if (Diags.hasErrorOccurred())
return;
- TU.AddTopLevelDecl(D);
+ if (TU) TU->AddTopLevelDecl(D);
}
};
@@ -851,7 +855,7 @@
: ASTSerializer(diags,LO), FName(F) {}
~SingleFileSerializer() {
- EmitASTBitcodeFile(TU,FName);
+ EmitASTBitcodeFile(TU, FName);
}
};
@@ -863,7 +867,11 @@
: ASTSerializer(diags,LO), EmitDir(dir) {}
~BuildSerializer() {
- SourceManager& SourceMgr = TU.getASTContext()->getSourceManager();
+
+ if (!TU)
+ return;
+
+ SourceManager& SourceMgr = TU->getContext().getSourceManager();
unsigned ID = SourceMgr.getMainFileID();
assert (ID && "MainFileID not set!");
const FileEntry* FE = SourceMgr.getFileEntryForID(ID);
@@ -887,7 +895,7 @@
sprintf(&buf[0], "%s-%llX.ast", FE->getName(), (uint64_t) FE->getInode());
FName.appendComponent(&buf[0]);
- EmitASTBitcodeFile(TU,FName);
+ EmitASTBitcodeFile(TU, FName);
// Now emit the sources.