A little hack to identify unwanted concurrency in CIndex

llvm-svn: 97831
This commit is contained in:
Douglas Gregor 2010-03-05 21:16:25 +00:00
parent f5cc1cdc65
commit 0c7c2f8b4d
3 changed files with 49 additions and 2 deletions

View 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();

View File

@ -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();
}

View 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(