From bdf6062bc10aa3b73b16402b440b8073310acd06 Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Fri, 5 Mar 2010 21:16:25 +0000 Subject: [PATCH] A little hack to identify unwanted concurrency in CIndex git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@97831 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Frontend/ASTUnit.h | 40 +++++++++++++++++++++++++++++++- lib/Frontend/ASTUnit.cpp | 5 +++- tools/CIndex/CIndex.cpp | 6 +++++ 3 files changed, 49 insertions(+), 2 deletions(-) diff --git a/include/clang/Frontend/ASTUnit.h b/include/clang/Frontend/ASTUnit.h index 626a162371..dca71cffec 100644 --- a/include/clang/Frontend/ASTUnit.h +++ b/include/clang/Frontend/ASTUnit.h @@ -88,11 +88,49 @@ class ASTUnit { /// \brief Temporary files that should be removed when the ASTUnit is /// destroyed. llvm::SmallVector 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(); diff --git a/lib/Frontend/ASTUnit.cpp b/lib/Frontend/ASTUnit.cpp index ef14df1034..4ea1ccc943 100644 --- a/lib/Frontend/ASTUnit.cpp +++ b/lib/Frontend/ASTUnit.cpp @@ -36,9 +36,12 @@ 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(); } diff --git a/tools/CIndex/CIndex.cpp b/tools/CIndex/CIndex.cpp index 6fc7b53030..de835475a6 100644 --- a/tools/CIndex/CIndex.cpp +++ b/tools/CIndex/CIndex.cpp @@ -1527,6 +1527,8 @@ CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) { ASTUnit *CXXUnit = static_cast(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( -- 2.40.0