forked from OSchip/llvm-project
A little hack to identify unwanted concurrency in CIndex
llvm-svn: 97831
This commit is contained in:
parent
f5cc1cdc65
commit
0c7c2f8b4d
|
@ -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();
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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(
|
||||
|
|
Loading…
Reference in New Issue