[cfe-commits] r111451 - in /cfe/trunk: include/clang/Frontend/ASTUnit.h test/Index/Inputs/crash-recovery-reparse-remap.c test/Index/crash-recovery-reparse.c tools/libclang/CIndex.cpp
Daniel Dunbar
daniel at zuster.org
Wed Aug 18 16:09:31 PDT 2010
Author: ddunbar
Date: Wed Aug 18 18:09:31 2010
New Revision: 111451
URL: http://llvm.org/viewvc/llvm-project?rev=111451&view=rev
Log:
libclang: Put clang_reparseTranslationUnit inside a crash recovery context.
Added:
cfe/trunk/test/Index/Inputs/crash-recovery-reparse-remap.c
cfe/trunk/test/Index/crash-recovery-reparse.c
Modified:
cfe/trunk/include/clang/Frontend/ASTUnit.h
cfe/trunk/tools/libclang/CIndex.cpp
Modified: cfe/trunk/include/clang/Frontend/ASTUnit.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/ASTUnit.h?rev=111451&r1=111450&r2=111451&view=diff
==============================================================================
--- cfe/trunk/include/clang/Frontend/ASTUnit.h (original)
+++ cfe/trunk/include/clang/Frontend/ASTUnit.h Wed Aug 18 18:09:31 2010
@@ -273,7 +273,11 @@
/// 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 @@
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; }
Added: cfe/trunk/test/Index/Inputs/crash-recovery-reparse-remap.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/Inputs/crash-recovery-reparse-remap.c?rev=111451&view=auto
==============================================================================
--- cfe/trunk/test/Index/Inputs/crash-recovery-reparse-remap.c (added)
+++ cfe/trunk/test/Index/Inputs/crash-recovery-reparse-remap.c Wed Aug 18 18:09:31 2010
@@ -0,0 +1,3 @@
+#warning parsing remapped file
+
+#pragma clang __debug crash
Added: cfe/trunk/test/Index/crash-recovery-reparse.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/crash-recovery-reparse.c?rev=111451&view=auto
==============================================================================
--- cfe/trunk/test/Index/crash-recovery-reparse.c (added)
+++ cfe/trunk/test/Index/crash-recovery-reparse.c Wed Aug 18 18:09:31 2010
@@ -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
Modified: cfe/trunk/tools/libclang/CIndex.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndex.cpp?rev=111451&r1=111450&r2=111451&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CIndex.cpp (original)
+++ cfe/trunk/tools/libclang/CIndex.cpp Wed Aug 18 18:09:31 2010
@@ -1510,20 +1510,39 @@
}
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 @@
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)
More information about the cfe-commits
mailing list