]> granicus.if.org Git - clang/commitdiff
A little hack to identify unwanted concurrency in CIndex
authorDouglas Gregor <dgregor@apple.com>
Fri, 5 Mar 2010 21:16:25 +0000 (21:16 +0000)
committerDouglas Gregor <dgregor@apple.com>
Fri, 5 Mar 2010 21:16:25 +0000 (21:16 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@97831 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Frontend/ASTUnit.h
lib/Frontend/ASTUnit.cpp
tools/CIndex/CIndex.cpp

index 626a162371bddc8b1a7523b483457b0afdfb705d..dca71cffecaf4f3f9fdd526ba3223cb8328c539e 100644 (file)
@@ -88,11 +88,49 @@ class ASTUnit {
   /// \brief Temporary files that should be removed when the ASTUnit is 
   /// destroyed.
   llvm::SmallVector<llvm::sys::Path, 4> TemporaryFiles;
+
+#ifndef NDEBUG
+  /// \brief Simple hack to allow us to assert that ASTUnit is not being
+  /// used concurrently, which is not supported.
+  ///
+  /// Clients should create instances of the ConcurrencyCheck class whenever
+  /// using the ASTUnit in a way that isn't intended to be concurrent, which is
+  /// just about any usage.
+  unsigned int ConcurrencyCheckValue;
+  static const unsigned int CheckLocked = 28573289;
+  static const unsigned int CheckUnlocked = 9803453;
+#endif
   
   ASTUnit(const ASTUnit&); // DO NOT IMPLEMENT
   ASTUnit &operator=(const ASTUnit &); // DO NOT IMPLEMENT
-
+  
 public:
+  class ConcurrencyCheck {
+#ifndef NDEBUG
+    volatile ASTUnit &Self;
+#endif
+    
+  public:
+    explicit ConcurrencyCheck(ASTUnit &Self)
+#ifndef NDEBUG
+      : Self(Self) 
+#endif
+    { 
+#ifndef NDEBUG
+      assert(Self.ConcurrencyCheckValue == CheckUnlocked && 
+             "Concurrent access to ASTUnit!");
+      Self.ConcurrencyCheckValue = CheckLocked;
+#endif
+    }
+    
+#ifndef NDEBUG
+    ~ConcurrencyCheck() {
+      Self.ConcurrencyCheckValue = CheckUnlocked;
+    }
+#endif
+  };
+  friend class ConcurrencyCheck;
+  
   ASTUnit(bool MainFileIsAST);
   ~ASTUnit();
 
index ef14df10345ecafec0bcc1f59d21931ad29e78ba..4ea1ccc943b6bc4dbee52c6997b6062aafbcd51e 100644 (file)
 using namespace clang;
 
 ASTUnit::ASTUnit(bool _MainFileIsAST)
-  : MainFileIsAST(_MainFileIsAST) {
+  : MainFileIsAST(_MainFileIsAST), ConcurrencyCheckValue(CheckUnlocked) {
 }
 ASTUnit::~ASTUnit() {
+#ifndef NDEBUG
+  ConcurrencyCheckValue = CheckLocked;
+#endif
   for (unsigned I = 0, N = TemporaryFiles.size(); I != N; ++I)
     TemporaryFiles[I].eraseFromDisk();
 }
index 6fc7b530307da13dbd92a68b7c0580edcd7a34ee..de835475a652bb8f5d4bc50791950bee1f203db8 100644 (file)
@@ -1527,6 +1527,8 @@ CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
 
   ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU);
 
+  ASTUnit::ConcurrencyCheck Check(*CXXUnit);
+
   SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
   CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
   if (SLoc.isValid()) {
@@ -2052,6 +2054,8 @@ void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
   if (!CXXUnit || !Tokens || !NumTokens)
     return;
 
+  ASTUnit::ConcurrencyCheck Check(*CXXUnit);
+  
   SourceRange R = cxloc::translateCXSourceRange(Range);
   if (R.isInvalid())
     return;
@@ -2175,6 +2179,8 @@ void clang_annotateTokens(CXTranslationUnit TU,
   if (!CXXUnit || !Tokens)
     return;
 
+  ASTUnit::ConcurrencyCheck Check(*CXXUnit);
+
   // Annotate all of the source locations in the region of interest that map
   SourceRange RegionOfInterest;
   RegionOfInterest.setBegin(