[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