forked from OSchip/llvm-project
libclang: Put clang_reparseTranslationUnit inside a crash recovery context.
llvm-svn: 111451
This commit is contained in:
parent
25b6068b8f
commit
79acdd9402
|
@ -273,7 +273,11 @@ private:
|
|||
/// This is meant to avoid thrashing during reparsing, by not allowing the
|
||||
/// code-completion cache to be updated on every reparse.
|
||||
unsigned CacheCodeCompletionCoolDown;
|
||||
|
||||
|
||||
/// \brief Bit used by CIndex to mark when a translation unit may be in an
|
||||
/// inconsistent state, and is not safe to free.
|
||||
unsigned UnsafeToFree : 1;
|
||||
|
||||
/// \brief Cache any "global" code-completion results, so that we can avoid
|
||||
/// recomputing them with each completion.
|
||||
void CacheCodeCompletionResults();
|
||||
|
@ -329,6 +333,9 @@ public:
|
|||
|
||||
bool isMainFileAST() const { return MainFileIsAST; }
|
||||
|
||||
bool isUnsafeToFree() const { return UnsafeToFree; }
|
||||
void setUnsafeToFree(bool Value) { UnsafeToFree = Value; }
|
||||
|
||||
const Diagnostic &getDiagnostics() const { return *Diagnostics; }
|
||||
Diagnostic &getDiagnostics() { return *Diagnostics; }
|
||||
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
#warning parsing remapped file
|
||||
|
||||
#pragma clang __debug crash
|
|
@ -0,0 +1,10 @@
|
|||
// RUN: env CINDEXTEST_EDITING=1 \
|
||||
// RUN: not c-index-test -test-load-source-reparse 1 local \
|
||||
// RUN: -remap-file="%s;%S/Inputs/crash-recovery-reparse-remap.c" \
|
||||
// RUN: %s 2> %t.err
|
||||
// RUN: FileCheck < %t.err -check-prefix=CHECK-REPARSE-SOURCE-CRASH %s
|
||||
// CHECK-REPARSE-SOURCE-CRASH: Unable to reparse translation unit
|
||||
//
|
||||
// XFAIL: win32
|
||||
|
||||
#warning parsing original file
|
|
@ -1510,20 +1510,39 @@ int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
|
|||
}
|
||||
|
||||
void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
|
||||
if (CTUnit)
|
||||
if (CTUnit) {
|
||||
// If the translation unit has been marked as unsafe to free, just discard
|
||||
// it.
|
||||
if (static_cast<ASTUnit *>(CTUnit)->isUnsafeToFree())
|
||||
return;
|
||||
|
||||
delete static_cast<ASTUnit *>(CTUnit);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
|
||||
return CXReparse_None;
|
||||
}
|
||||
|
||||
int clang_reparseTranslationUnit(CXTranslationUnit TU,
|
||||
unsigned num_unsaved_files,
|
||||
struct CXUnsavedFile *unsaved_files,
|
||||
unsigned options) {
|
||||
struct ReparseTranslationUnitInfo {
|
||||
CXTranslationUnit TU;
|
||||
unsigned num_unsaved_files;
|
||||
struct CXUnsavedFile *unsaved_files;
|
||||
unsigned options;
|
||||
int result;
|
||||
};
|
||||
void clang_reparseTranslationUnit_Impl(void *UserData) {
|
||||
ReparseTranslationUnitInfo *RTUI =
|
||||
static_cast<ReparseTranslationUnitInfo*>(UserData);
|
||||
CXTranslationUnit TU = RTUI->TU;
|
||||
unsigned num_unsaved_files = RTUI->num_unsaved_files;
|
||||
struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files;
|
||||
unsigned options = RTUI->options;
|
||||
(void) options;
|
||||
RTUI->result = 1;
|
||||
|
||||
if (!TU)
|
||||
return 1;
|
||||
return;
|
||||
|
||||
llvm::SmallVector<ASTUnit::RemappedFile, 4> RemappedFiles;
|
||||
for (unsigned I = 0; I != num_unsaved_files; ++I) {
|
||||
|
@ -1534,9 +1553,27 @@ int clang_reparseTranslationUnit(CXTranslationUnit TU,
|
|||
Buffer));
|
||||
}
|
||||
|
||||
return static_cast<ASTUnit *>(TU)->Reparse(RemappedFiles.data(),
|
||||
RemappedFiles.size())? 1 : 0;
|
||||
if (!static_cast<ASTUnit *>(TU)->Reparse(RemappedFiles.data(),
|
||||
RemappedFiles.size()))
|
||||
RTUI->result = 0;
|
||||
}
|
||||
int clang_reparseTranslationUnit(CXTranslationUnit TU,
|
||||
unsigned num_unsaved_files,
|
||||
struct CXUnsavedFile *unsaved_files,
|
||||
unsigned options) {
|
||||
ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files,
|
||||
options, 0 };
|
||||
llvm::CrashRecoveryContext CRC;
|
||||
|
||||
if (!CRC.RunSafely(clang_reparseTranslationUnit_Impl, &RTUI)) {
|
||||
// FIXME: Find a way to report the crash.
|
||||
static_cast<ASTUnit *>(TU)->setUnsafeToFree(true);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return RTUI.result;
|
||||
}
|
||||
|
||||
|
||||
CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
|
||||
if (!CTUnit)
|
||||
|
|
Loading…
Reference in New Issue