Improve shutdown logic.

We should follow the shutdown procedure from FrontendAction::EndSourceFile
which ensures clang is properly torn down.

This patch allows us to write a module file without having to explicitly
call CompilerInstance::clearOutputFiles.
This commit is contained in:
Vassil Vassilev 2019-12-07 18:55:25 +02:00 committed by SFT
parent e5d9141fcd
commit ad6a1b47cd
2 changed files with 56 additions and 3 deletions

View File

@ -315,6 +315,10 @@ namespace cling {
Transaction* Initialize(bool NoRuntime, bool SyntaxOnly,
llvm::SmallVectorImpl<llvm::StringRef>& Globals);
///\ Shut down the interpreter runtime.
///
void ShutDown();
///\brief The target constructor to be called from both the delegating
/// constructors. parentInterp might be nullptr.
///

View File

@ -393,13 +393,12 @@ namespace cling {
if (m_Executor)
m_Executor->shuttingDown();
if (CompilerInstance* CI = getCIOrNull())
CI->getDiagnostics().getClient()->EndSourceFile();
// LookupHelper's ~Parser needs the PP from IncrParser's CI, so do this
// first:
m_LookupHelper.reset();
ShutDown();
// We want to keep the callback alive during the shutdown of Sema, CodeGen
// and the ASTContext. For that to happen we shut down the IncrementalParser
// explicitly, before the implicit destruction (through the unique_ptr) of
@ -575,6 +574,56 @@ namespace cling {
return T;
}
void Interpreter::ShutDown() {
// Model the shutdown actions done in FrontendAction::EndSourceFile
if (CompilerInstance* CI = getCIOrNull()) {
CI->getDiagnostics().getClient()->EndSourceFile();
if (CI->hasPreprocessor())
CI->getPreprocessor().EndSourceFile();
bool DisableFree = CI->getFrontendOpts().DisableFree;
if (DisableFree) {
CI->resetAndLeakSema();
CI->resetAndLeakASTContext();
BuryPointer(CI->takeASTConsumer().get());
} else {
CI->setSema(nullptr);
CI->setASTContext(nullptr);
CI->setASTConsumer(nullptr);
}
if (CI->getFrontendOpts().ShowStats) {
llvm::errs() << "\nSTATISTICS \n";
CI->getPreprocessor().PrintStats();
CI->getPreprocessor().getIdentifierTable().PrintStats();
CI->getPreprocessor().getHeaderSearchInfo().PrintStats();
CI->getSourceManager().PrintStats();
llvm::errs() << "\n";
}
// Cleanup the output streams, and erase the output files if instructed by
// the FrontendAction.
bool shouldEraseOutputFiles = CI->getDiagnostics().hasErrorOccurred();
CI->clearOutputFiles(/*EraseFiles=*/shouldEraseOutputFiles);
LangOptions& LO = CI->getLangOpts();
if (!LO.getCompilingModule() != clang::LangOptions::CMK_None) {
if (DisableFree) {
CI->resetAndLeakPreprocessor();
CI->resetAndLeakSourceManager();
CI->resetAndLeakFileManager();
} else {
CI->setPreprocessor(nullptr);
CI->setSourceManager(nullptr);
CI->setFileManager(nullptr);
}
}
LO.setCompilingModule(clang::LangOptions::CMK_None);
}
}
void Interpreter::AddIncludePaths(llvm::StringRef PathStr, const char* Delm) {
CompilerInstance* CI = getCI();
HeaderSearchOptions& HOpts = CI->getHeaderSearchOpts();