libclang: Put clang_parseTranslationUnit inside a crash recovery context.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@111387 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/test/Index/crash-recovery.c b/test/Index/crash-recovery.c
new file mode 100644
index 0000000..73920c2
--- /dev/null
+++ b/test/Index/crash-recovery.c
@@ -0,0 +1,7 @@
+// RUN: not c-index-test -test-load-source all %s 2> %t.err
+// RUN: FileCheck < %t.err -check-prefix=CHECK-LOAD-SOURCE-CRASH %s
+// CHECK-LOAD-SOURCE-CRASH: Unable to load translation unit
+//
+// XFAIL: win32
+
+#pragma clang __debug crash
diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp
index e0720e7..829873e 100644
--- a/tools/libclang/CIndex.cpp
+++ b/tools/libclang/CIndex.cpp
@@ -1209,16 +1209,31 @@
unsaved_files, num_unsaved_files,
CXTranslationUnit_DetailedPreprocessingRecord);
}
+
+struct ParseTranslationUnitInfo {
+ CXIndex CIdx;
+ const char *source_filename;
+ const char **command_line_args;
+ int num_command_line_args;
+ struct CXUnsavedFile *unsaved_files;
+ unsigned num_unsaved_files;
+ unsigned options;
+ CXTranslationUnit result;
+};
+void clang_parseTranslationUnit_Impl(void *UserData) {
+ ParseTranslationUnitInfo *PTUI =
+ static_cast<ParseTranslationUnitInfo*>(UserData);
+ CXIndex CIdx = PTUI->CIdx;
+ const char *source_filename = PTUI->source_filename;
+ const char **command_line_args = PTUI->command_line_args;
+ int num_command_line_args = PTUI->num_command_line_args;
+ struct CXUnsavedFile *unsaved_files = PTUI->unsaved_files;
+ unsigned num_unsaved_files = PTUI->num_unsaved_files;
+ unsigned options = PTUI->options;
+ PTUI->result = 0;
-CXTranslationUnit clang_parseTranslationUnit(CXIndex CIdx,
- const char *source_filename,
- const char **command_line_args,
- int num_command_line_args,
- struct CXUnsavedFile *unsaved_files,
- unsigned num_unsaved_files,
- unsigned options) {
if (!CIdx)
- return 0;
+ return;
CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
@@ -1307,7 +1322,8 @@
}
}
- return Unit.take();
+ PTUI->result = Unit.take();
+ return;
}
// Build up the arguments for invoking 'clang'.
@@ -1343,7 +1359,7 @@
std::vector<llvm::sys::Path> TemporaryFiles;
std::vector<std::string> RemapArgs;
if (RemapFiles(num_unsaved_files, unsaved_files, RemapArgs, TemporaryFiles))
- return 0;
+ return;
// The pointers into the elements of RemapArgs are stable because we
// won't be adding anything to RemapArgs after this point.
@@ -1459,7 +1475,26 @@
TemporaryFiles[i].eraseFromDisk();
}
- return ATU;
+ PTUI->result = ATU;
+}
+CXTranslationUnit clang_parseTranslationUnit(CXIndex CIdx,
+ const char *source_filename,
+ const char **command_line_args,
+ int num_command_line_args,
+ struct CXUnsavedFile *unsaved_files,
+ unsigned num_unsaved_files,
+ unsigned options) {
+ ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args,
+ num_command_line_args, unsaved_files, num_unsaved_files,
+ options, 0 };
+ llvm::CrashRecoveryContext CRC;
+
+ if (!CRC.RunSafely(clang_parseTranslationUnit_Impl, &PTUI)) {
+ // FIXME: Find a way to report the crash.
+ return 0;
+ }
+
+ return PTUI.result;
}
unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
@@ -1473,7 +1508,7 @@
return static_cast<ASTUnit *>(TU)->Save(FileName);
}
-
+
void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
if (CTUnit)
delete static_cast<ASTUnit *>(CTUnit);