summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>2012-03-28 02:17:59 +0000
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>2012-03-28 02:17:59 +0000
commit142bcb59c012504360881e8f744d9d4a8d92c2ac (patch)
treecf5f055e7ef9283b4839432a74cb559e39299648 /tools
parent82fe6aea407a5a09a6131452ce622087ba83880d (diff)
[libclang] For clang_saveTranslationUnit, if the AST to save has invalid nodes
due to compiler errors, use a crash recovery thread to do the AST writing for protection. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@153560 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'tools')
-rw-r--r--tools/libclang/CIndex.cpp57
1 files changed, 52 insertions, 5 deletions
diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp
index f15de4b758..b3a29ef105 100644
--- a/tools/libclang/CIndex.cpp
+++ b/tools/libclang/CIndex.cpp
@@ -2647,16 +2647,63 @@ CXTranslationUnit clang_parseTranslationUnit(CXIndex CIdx,
unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
return CXSaveTranslationUnit_None;
}
-
+
+namespace {
+
+struct SaveTranslationUnitInfo {
+ CXTranslationUnit TU;
+ const char *FileName;
+ unsigned options;
+ CXSaveError result;
+};
+
+}
+
+static void clang_saveTranslationUnit_Impl(void *UserData) {
+ SaveTranslationUnitInfo *STUI =
+ static_cast<SaveTranslationUnitInfo*>(UserData);
+
+ STUI->result = static_cast<ASTUnit *>(STUI->TU->TUData)->Save(STUI->FileName);
+}
+
int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
unsigned options) {
if (!TU)
return CXSaveError_InvalidTU;
-
- CXSaveError result = static_cast<ASTUnit *>(TU->TUData)->Save(FileName);
- if (getenv("LIBCLANG_RESOURCE_USAGE"))
+
+ ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
+ ASTUnit::ConcurrencyCheck Check(*CXXUnit);
+
+ SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
+
+ if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
+ getenv("LIBCLANG_NOTHREADS")) {
+ clang_saveTranslationUnit_Impl(&STUI);
+
+ if (getenv("LIBCLANG_RESOURCE_USAGE"))
+ PrintLibclangResourceUsage(TU);
+
+ return STUI.result;
+ }
+
+ // We have an AST that has invalid nodes due to compiler errors.
+ // Use a crash recovery thread for protection.
+
+ llvm::CrashRecoveryContext CRC;
+
+ if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
+ fprintf(stderr, "libclang: crash detected during AST saving: {\n");
+ fprintf(stderr, " 'filename' : '%s'\n", FileName);
+ fprintf(stderr, " 'options' : %d,\n", options);
+ fprintf(stderr, "}\n");
+
+ return CXSaveError_Unknown;
+
+ } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
PrintLibclangResourceUsage(TU);
- return result;
+ }
+
+ return STUI.result;
}
void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {