зеркало из https://github.com/microsoft/clang.git
Run all functional logic of clang_annotateTokens() within a CrashRecoveryContext. Fixes <rdar://problem/9121698>.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@127919 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
207f4d8543
Коммит
6628a614c5
|
@ -4566,37 +4566,30 @@ static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
|
|||
return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
|
||||
}
|
||||
|
||||
// This gets run a separate thread to avoid stack blowout.
|
||||
static void runAnnotateTokensWorker(void *UserData) {
|
||||
((AnnotateTokensWorker*)UserData)->AnnotateTokens();
|
||||
namespace {
|
||||
struct clang_annotateTokens_Data {
|
||||
CXTranslationUnit TU;
|
||||
ASTUnit *CXXUnit;
|
||||
CXToken *Tokens;
|
||||
unsigned NumTokens;
|
||||
CXCursor *Cursors;
|
||||
};
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
|
||||
void clang_annotateTokens(CXTranslationUnit TU,
|
||||
CXToken *Tokens, unsigned NumTokens,
|
||||
CXCursor *Cursors) {
|
||||
|
||||
if (NumTokens == 0 || !Tokens || !Cursors)
|
||||
return;
|
||||
|
||||
// Any token we don't specifically annotate will have a NULL cursor.
|
||||
CXCursor C = clang_getNullCursor();
|
||||
for (unsigned I = 0; I != NumTokens; ++I)
|
||||
Cursors[I] = C;
|
||||
|
||||
ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
|
||||
if (!CXXUnit)
|
||||
return;
|
||||
|
||||
ASTUnit::ConcurrencyCheck Check(*CXXUnit);
|
||||
// This gets run a separate thread to avoid stack blowout.
|
||||
static void clang_annotateTokensImpl(void *UserData) {
|
||||
CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
|
||||
ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
|
||||
CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
|
||||
const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
|
||||
CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
|
||||
|
||||
// Determine the region of interest, which contains all of the tokens.
|
||||
SourceRange RegionOfInterest;
|
||||
RegionOfInterest.setBegin(cxloc::translateSourceLocation(
|
||||
clang_getTokenLocation(TU, Tokens[0])));
|
||||
RegionOfInterest.setEnd(cxloc::translateSourceLocation(
|
||||
clang_getTokenLocation(TU,
|
||||
RegionOfInterest.setBegin(
|
||||
cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
|
||||
RegionOfInterest.setEnd(
|
||||
cxloc::translateSourceLocation(clang_getTokenLocation(TU,
|
||||
Tokens[NumTokens-1])));
|
||||
|
||||
// A mapping from the source locations found when re-lexing or traversing the
|
||||
|
@ -4637,7 +4630,7 @@ void clang_annotateTokens(CXTranslationUnit TU,
|
|||
//
|
||||
// FIXME: Some simple tests here could identify macro definitions and
|
||||
// #undefs, to provide specific cursor kinds for those.
|
||||
std::vector<SourceLocation> Locations;
|
||||
llvm::SmallVector<SourceLocation, 32> Locations;
|
||||
do {
|
||||
Locations.push_back(Tok.getLocation());
|
||||
Lex.LexFromRawLexer(Tok);
|
||||
|
@ -4668,17 +4661,12 @@ void clang_annotateTokens(CXTranslationUnit TU,
|
|||
AnnotateTokensWorker W(Annotated, Tokens, Cursors, NumTokens,
|
||||
TU, RegionOfInterest);
|
||||
|
||||
// Run the worker within a CrashRecoveryContext.
|
||||
// FIXME: We use a ridiculous stack size here because the data-recursion
|
||||
// algorithm uses a large stack frame than the non-data recursive version,
|
||||
// and AnnotationTokensWorker currently transforms the data-recursion
|
||||
// algorithm back into a traditional recursion by explicitly calling
|
||||
// VisitChildren(). We will need to remove this explicit recursive call.
|
||||
llvm::CrashRecoveryContext CRC;
|
||||
if (!RunSafely(CRC, runAnnotateTokensWorker, &W,
|
||||
GetSafetyThreadStackSize() * 2)) {
|
||||
fprintf(stderr, "libclang: crash detected while annotating tokens\n");
|
||||
}
|
||||
W.AnnotateTokens();
|
||||
|
||||
// If we ran into any entities that involve context-sensitive keywords,
|
||||
// take another pass through the tokens to mark them as such.
|
||||
|
@ -4765,6 +4753,35 @@ void clang_annotateTokens(CXTranslationUnit TU,
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
|
||||
void clang_annotateTokens(CXTranslationUnit TU,
|
||||
CXToken *Tokens, unsigned NumTokens,
|
||||
CXCursor *Cursors) {
|
||||
|
||||
if (NumTokens == 0 || !Tokens || !Cursors)
|
||||
return;
|
||||
|
||||
// Any token we don't specifically annotate will have a NULL cursor.
|
||||
CXCursor C = clang_getNullCursor();
|
||||
for (unsigned I = 0; I != NumTokens; ++I)
|
||||
Cursors[I] = C;
|
||||
|
||||
ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
|
||||
if (!CXXUnit)
|
||||
return;
|
||||
|
||||
ASTUnit::ConcurrencyCheck Check(*CXXUnit);
|
||||
|
||||
clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
|
||||
llvm::CrashRecoveryContext CRC;
|
||||
if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
|
||||
GetSafetyThreadStackSize() * 2)) {
|
||||
fprintf(stderr, "libclang: crash detected while annotating tokens\n");
|
||||
}
|
||||
}
|
||||
|
||||
} // end: extern "C"
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
|
Загрузка…
Ссылка в новой задаче