зеркало из https://github.com/microsoft/clang.git
Rework crash recovery cleanup in ASTUnit and CIndex to recover more memory during a Sema crash (we have just a handful of leaks left)
and to use the simplified cleanup registration API. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@128059 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
b995e04b90
Коммит
25a11e1c5f
|
@ -503,9 +503,11 @@ ASTUnit *ASTUnit::LoadFromASTFile(const std::string &Filename,
|
|||
llvm::OwningPtr<ASTUnit> AST(new ASTUnit(true));
|
||||
|
||||
// Recover resources if we crash before exiting this method.
|
||||
llvm::CrashRecoveryContextCleanupRegistrar
|
||||
ASTUnitCleanup(llvm::CrashRecoveryContextCleanup::
|
||||
create<ASTUnit>(AST.get()));
|
||||
llvm::CrashRecoveryContextCleanupRegistrar<ASTUnit>
|
||||
ASTUnitCleanup(AST.get());
|
||||
llvm::CrashRecoveryContextCleanupRegistrar<Diagnostic,
|
||||
llvm::CrashRecoveryContextReleaseRefCleanup<Diagnostic> >
|
||||
DiagCleanup(Diags.getPtr());
|
||||
|
||||
ConfigureDiags(Diags, 0, 0, *AST, CaptureDiagnostics);
|
||||
|
||||
|
@ -850,9 +852,8 @@ bool ASTUnit::Parse(llvm::MemoryBuffer *OverrideMainBuffer) {
|
|||
llvm::OwningPtr<CompilerInstance> Clang(new CompilerInstance());
|
||||
|
||||
// Recover resources if we crash before exiting this method.
|
||||
llvm::CrashRecoveryContextCleanupRegistrar
|
||||
CICleanup(llvm::CrashRecoveryContextCleanup::
|
||||
create<CompilerInstance>(Clang.get()));
|
||||
llvm::CrashRecoveryContextCleanupRegistrar<CompilerInstance>
|
||||
CICleanup(Clang.get());
|
||||
|
||||
Clang->setInvocation(&*Invocation);
|
||||
OriginalSourceFile = Clang->getFrontendOpts().Inputs[0].second;
|
||||
|
@ -945,8 +946,13 @@ bool ASTUnit::Parse(llvm::MemoryBuffer *OverrideMainBuffer) {
|
|||
PreprocessorOpts.PrecompiledPreambleBytes.second = false;
|
||||
}
|
||||
|
||||
llvm::OwningPtr<TopLevelDeclTrackerAction> Act;
|
||||
Act.reset(new TopLevelDeclTrackerAction(*this));
|
||||
llvm::OwningPtr<TopLevelDeclTrackerAction> Act(
|
||||
new TopLevelDeclTrackerAction(*this));
|
||||
|
||||
// Recover resources if we crash before exiting this method.
|
||||
llvm::CrashRecoveryContextCleanupRegistrar<TopLevelDeclTrackerAction>
|
||||
ActCleanup(Act.get());
|
||||
|
||||
if (!Act->BeginSourceFile(*Clang.get(), Clang->getFrontendOpts().Inputs[0].second,
|
||||
Clang->getFrontendOpts().Inputs[0].first))
|
||||
goto error;
|
||||
|
@ -1334,9 +1340,8 @@ llvm::MemoryBuffer *ASTUnit::getMainBufferWithPrecompiledPreamble(
|
|||
llvm::OwningPtr<CompilerInstance> Clang(new CompilerInstance());
|
||||
|
||||
// Recover resources if we crash before exiting this method.
|
||||
llvm::CrashRecoveryContextCleanupRegistrar
|
||||
CICleanup(llvm::CrashRecoveryContextCleanup::
|
||||
create<CompilerInstance>(Clang.get()));
|
||||
llvm::CrashRecoveryContextCleanupRegistrar<CompilerInstance>
|
||||
CICleanup(Clang.get());
|
||||
|
||||
Clang->setInvocation(&PreambleInvocation);
|
||||
OriginalSourceFile = Clang->getFrontendOpts().Inputs[0].second;
|
||||
|
@ -1570,6 +1575,10 @@ bool ASTUnit::LoadFromCompilerInvocation(bool PrecompilePreamble) {
|
|||
SimpleTimer ParsingTimer(WantTiming);
|
||||
ParsingTimer.setOutput("Parsing " + getMainFileName());
|
||||
|
||||
// Recover resources if we crash before exiting this method.
|
||||
llvm::CrashRecoveryContextCleanupRegistrar<llvm::MemoryBuffer>
|
||||
MemBufferCleanup(OverrideMainBuffer);
|
||||
|
||||
return Parse(OverrideMainBuffer);
|
||||
}
|
||||
|
||||
|
@ -1592,9 +1601,11 @@ ASTUnit *ASTUnit::LoadFromCompilerInvocation(CompilerInvocation *CI,
|
|||
AST->Invocation = CI;
|
||||
|
||||
// Recover resources if we crash before exiting this method.
|
||||
llvm::CrashRecoveryContextCleanupRegistrar
|
||||
ASTUnitCleanup(llvm::CrashRecoveryContextCleanup::
|
||||
create<ASTUnit>(AST.get()));
|
||||
llvm::CrashRecoveryContextCleanupRegistrar<ASTUnit>
|
||||
ASTUnitCleanup(AST.get());
|
||||
llvm::CrashRecoveryContextCleanupRegistrar<Diagnostic,
|
||||
llvm::CrashRecoveryContextReleaseRefCleanup<Diagnostic> >
|
||||
DiagCleanup(Diags.getPtr());
|
||||
|
||||
return AST->LoadFromCompilerInvocation(PrecompilePreamble)? 0 : AST.take();
|
||||
}
|
||||
|
@ -1621,13 +1632,19 @@ ASTUnit *ASTUnit::LoadFromCommandLine(const char **ArgBegin,
|
|||
ArgBegin);
|
||||
}
|
||||
|
||||
llvm::SmallVector<const char *, 16> Args;
|
||||
Args.push_back("<clang>"); // FIXME: Remove dummy argument.
|
||||
Args.insert(Args.end(), ArgBegin, ArgEnd);
|
||||
llvm::OwningPtr<std::vector<const char *> >
|
||||
Args(new std::vector<const char*>);
|
||||
|
||||
// Recover resources if we crash before exiting this function.
|
||||
llvm::CrashRecoveryContextCleanupRegistrar<
|
||||
std::vector<const char *> > CleanupArgs(Args.get());
|
||||
|
||||
Args->push_back("<clang>"); // FIXME: Remove dummy argument.
|
||||
Args->insert(Args->end(), ArgBegin, ArgEnd);
|
||||
|
||||
// FIXME: Find a cleaner way to force the driver into restricted modes. We
|
||||
// also want to force it to use clang.
|
||||
Args.push_back("-fsyntax-only");
|
||||
Args->push_back("-fsyntax-only");
|
||||
|
||||
llvm::SmallVector<StoredDiagnostic, 4> StoredDiagnostics;
|
||||
|
||||
|
@ -1645,7 +1662,7 @@ ASTUnit *ASTUnit::LoadFromCommandLine(const char **ArgBegin,
|
|||
TheDriver.setCheckInputsExist(false);
|
||||
|
||||
llvm::OwningPtr<driver::Compilation> C(
|
||||
TheDriver.BuildCompilation(Args.size(), Args.data()));
|
||||
TheDriver.BuildCompilation(Args->size(), Args->data()));
|
||||
|
||||
// Just print the cc1 options if -### was present.
|
||||
if (C->getArgs().hasArg(driver::options::OPT__HASH_HASH_HASH)) {
|
||||
|
@ -1724,9 +1741,14 @@ ASTUnit *ASTUnit::LoadFromCommandLine(const char **ArgBegin,
|
|||
AST->Invocation = CI;
|
||||
|
||||
// Recover resources if we crash before exiting this method.
|
||||
llvm::CrashRecoveryContextCleanupRegistrar
|
||||
ASTUnitCleanup(llvm::CrashRecoveryContextCleanup::
|
||||
create<ASTUnit>(AST.get()));
|
||||
llvm::CrashRecoveryContextCleanupRegistrar<ASTUnit>
|
||||
ASTUnitCleanup(AST.get());
|
||||
llvm::CrashRecoveryContextCleanupRegistrar<CompilerInvocation,
|
||||
llvm::CrashRecoveryContextReleaseRefCleanup<CompilerInvocation> >
|
||||
CICleanup(CI.getPtr());
|
||||
llvm::CrashRecoveryContextCleanupRegistrar<Diagnostic,
|
||||
llvm::CrashRecoveryContextReleaseRefCleanup<Diagnostic> >
|
||||
DiagCleanup(Diags.getPtr());
|
||||
|
||||
return AST->LoadFromCompilerInvocation(PrecompilePreamble) ? 0 : AST.take();
|
||||
}
|
||||
|
@ -2056,9 +2078,8 @@ void ASTUnit::CodeComplete(llvm::StringRef File, unsigned Line, unsigned Column,
|
|||
llvm::OwningPtr<CompilerInstance> Clang(new CompilerInstance());
|
||||
|
||||
// Recover resources if we crash before exiting this method.
|
||||
llvm::CrashRecoveryContextCleanupRegistrar
|
||||
CICleanup(llvm::CrashRecoveryContextCleanup::
|
||||
create<CompilerInstance>(Clang.get()));
|
||||
llvm::CrashRecoveryContextCleanupRegistrar<CompilerInstance>
|
||||
CICleanup(Clang.get());
|
||||
|
||||
Clang->setInvocation(&*CCInvocation);
|
||||
OriginalSourceFile = Clang->getFrontendOpts().Inputs[0].second;
|
||||
|
|
|
@ -2390,20 +2390,36 @@ static void clang_parseTranslationUnit_Impl(void *UserData) {
|
|||
|
||||
// Configure the diagnostics.
|
||||
DiagnosticOptions DiagOpts;
|
||||
llvm::IntrusiveRefCntPtr<Diagnostic> Diags;
|
||||
Diags = CompilerInstance::createDiagnostics(DiagOpts, num_command_line_args,
|
||||
command_line_args);
|
||||
llvm::IntrusiveRefCntPtr<Diagnostic>
|
||||
Diags(CompilerInstance::createDiagnostics(DiagOpts, num_command_line_args,
|
||||
command_line_args));
|
||||
|
||||
// Recover resources if we crash before exiting this function.
|
||||
llvm::CrashRecoveryContextCleanupRegistrar<Diagnostic,
|
||||
llvm::CrashRecoveryContextReleaseRefCleanup<Diagnostic> >
|
||||
DiagCleanup(Diags.getPtr());
|
||||
|
||||
llvm::OwningPtr<std::vector<ASTUnit::RemappedFile> >
|
||||
RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
|
||||
|
||||
// Recover resources if we crash before exiting this function.
|
||||
llvm::CrashRecoveryContextCleanupRegistrar<
|
||||
std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
|
||||
|
||||
llvm::SmallVector<ASTUnit::RemappedFile, 4> RemappedFiles;
|
||||
for (unsigned I = 0; I != num_unsaved_files; ++I) {
|
||||
llvm::StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
|
||||
const llvm::MemoryBuffer *Buffer
|
||||
= llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
|
||||
RemappedFiles.push_back(std::make_pair(unsaved_files[I].Filename,
|
||||
RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
|
||||
Buffer));
|
||||
}
|
||||
|
||||
llvm::SmallVector<const char *, 16> Args;
|
||||
llvm::OwningPtr<std::vector<const char *> >
|
||||
Args(new std::vector<const char*>());
|
||||
|
||||
// Recover resources if we crash before exiting this method.
|
||||
llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
|
||||
ArgsCleanup(Args.get());
|
||||
|
||||
// Since the Clang C library is primarily used by batch tools dealing with
|
||||
// (often very broken) source code, where spell-checking can have a
|
||||
|
@ -2419,9 +2435,9 @@ static void clang_parseTranslationUnit_Impl(void *UserData) {
|
|||
}
|
||||
}
|
||||
if (!FoundSpellCheckingArgument)
|
||||
Args.push_back("-fno-spell-checking");
|
||||
Args->push_back("-fno-spell-checking");
|
||||
|
||||
Args.insert(Args.end(), command_line_args,
|
||||
Args->insert(Args->end(), command_line_args,
|
||||
command_line_args + num_command_line_args);
|
||||
|
||||
// The 'source_filename' argument is optional. If the caller does not
|
||||
|
@ -2430,23 +2446,23 @@ static void clang_parseTranslationUnit_Impl(void *UserData) {
|
|||
// Put the source file after command_line_args otherwise if '-x' flag is
|
||||
// present it will be unused.
|
||||
if (source_filename)
|
||||
Args.push_back(source_filename);
|
||||
Args->push_back(source_filename);
|
||||
|
||||
// Do we need the detailed preprocessing record?
|
||||
if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
|
||||
Args.push_back("-Xclang");
|
||||
Args.push_back("-detailed-preprocessing-record");
|
||||
Args->push_back("-Xclang");
|
||||
Args->push_back("-detailed-preprocessing-record");
|
||||
}
|
||||
|
||||
unsigned NumErrors = Diags->getClient()->getNumErrors();
|
||||
llvm::OwningPtr<ASTUnit> Unit(
|
||||
ASTUnit::LoadFromCommandLine(Args.data(), Args.data() + Args.size(),
|
||||
ASTUnit::LoadFromCommandLine(Args->data(), Args->data() + Args->size(),
|
||||
Diags,
|
||||
CXXIdx->getClangResourcesPath(),
|
||||
CXXIdx->getOnlyLocalDecls(),
|
||||
/*CaptureDiagnostics=*/true,
|
||||
RemappedFiles.data(),
|
||||
RemappedFiles.size(),
|
||||
RemappedFiles->data(),
|
||||
RemappedFiles->size(),
|
||||
/*RemappedFilesKeepOriginalName=*/true,
|
||||
PrecompilePreamble,
|
||||
CompleteTranslationUnit,
|
||||
|
@ -2569,16 +2585,22 @@ static void clang_reparseTranslationUnit_Impl(void *UserData) {
|
|||
ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
|
||||
ASTUnit::ConcurrencyCheck Check(*CXXUnit);
|
||||
|
||||
llvm::SmallVector<ASTUnit::RemappedFile, 4> RemappedFiles;
|
||||
llvm::OwningPtr<std::vector<ASTUnit::RemappedFile> >
|
||||
RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
|
||||
|
||||
// Recover resources if we crash before exiting this function.
|
||||
llvm::CrashRecoveryContextCleanupRegistrar<
|
||||
std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
|
||||
|
||||
for (unsigned I = 0; I != num_unsaved_files; ++I) {
|
||||
llvm::StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
|
||||
const llvm::MemoryBuffer *Buffer
|
||||
= llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
|
||||
RemappedFiles.push_back(std::make_pair(unsaved_files[I].Filename,
|
||||
RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
|
||||
Buffer));
|
||||
}
|
||||
|
||||
if (!CXXUnit->Reparse(RemappedFiles.data(), RemappedFiles.size()))
|
||||
if (!CXXUnit->Reparse(RemappedFiles->data(), RemappedFiles->size()))
|
||||
RTUI->result = 0;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче