[cfe-commits] r127919 - /cfe/trunk/tools/libclang/CIndex.cpp
Ted Kremenek
kremenek at apple.com
Fri Mar 18 15:51:30 PDT 2011
Author: kremenek
Date: Fri Mar 18 17:51:30 2011
New Revision: 127919
URL: http://llvm.org/viewvc/llvm-project?rev=127919&view=rev
Log:
Run all functional logic of clang_annotateTokens() within a CrashRecoveryContext. Fixes <rdar://problem/9121698>.
Modified:
cfe/trunk/tools/libclang/CIndex.cpp
Modified: cfe/trunk/tools/libclang/CIndex.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndex.cpp?rev=127919&r1=127918&r2=127919&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CIndex.cpp (original)
+++ cfe/trunk/tools/libclang/CIndex.cpp Fri Mar 18 17:51:30 2011
@@ -4566,43 +4566,36 @@
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,
- Tokens[NumTokens - 1])));
+ 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
// region of interest to the corresponding cursors.
AnnotateTokensData Annotated;
-
+
// Relex the tokens within the source range to look for preprocessing
// directives.
SourceManager &SourceMgr = CXXUnit->getSourceManager();
@@ -4610,7 +4603,7 @@
= SourceMgr.getDecomposedLoc(RegionOfInterest.getBegin());
std::pair<FileID, unsigned> EndLocInfo
= SourceMgr.getDecomposedLoc(RegionOfInterest.getEnd());
-
+
llvm::StringRef Buffer;
bool Invalid = false;
if (BeginLocInfo.first == EndLocInfo.first &&
@@ -4621,13 +4614,13 @@
Buffer.begin(), Buffer.data() + BeginLocInfo.second,
Buffer.end());
Lex.SetCommentRetentionState(true);
-
+
// Lex tokens in raw mode until we hit the end of the range, to avoid
// entering #includes or expanding macros.
while (true) {
Token Tok;
Lex.LexFromRawLexer(Tok);
-
+
reprocess:
if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
// We have found a preprocessing directive. Gobble it up so that we
@@ -4637,49 +4630,44 @@
//
// 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);
} while (!Tok.isAtStartOfLine() && !Tok.is(tok::eof));
-
+
using namespace cxcursor;
CXCursor Cursor
- = MakePreprocessingDirectiveCursor(SourceRange(Locations.front(),
- Locations.back()),
+ = MakePreprocessingDirectiveCursor(SourceRange(Locations.front(),
+ Locations.back()),
TU);
for (unsigned I = 0, N = Locations.size(); I != N; ++I) {
Annotated[Locations[I].getRawEncoding()] = Cursor;
}
-
+
if (Tok.isAtStartOfLine())
goto reprocess;
-
+
continue;
}
-
+
if (Tok.is(tok::eof))
break;
}
}
-
+
// Annotate all of the source locations in the region of interest that map to
// a specific cursor.
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.
if (W.hasContextSensitiveKeywords()) {
@@ -4690,19 +4678,19 @@
if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
if (ObjCPropertyDecl *Property
- = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
+ = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
if (Property->getPropertyAttributesAsWritten() != 0 &&
llvm::StringSwitch<bool>(II->getName())
- .Case("readonly", true)
- .Case("assign", true)
- .Case("readwrite", true)
- .Case("retain", true)
- .Case("copy", true)
- .Case("nonatomic", true)
- .Case("atomic", true)
- .Case("getter", true)
- .Case("setter", true)
- .Default(false))
+ .Case("readonly", true)
+ .Case("assign", true)
+ .Case("readwrite", true)
+ .Case("retain", true)
+ .Case("copy", true)
+ .Case("nonatomic", true)
+ .Case("atomic", true)
+ .Case("getter", true)
+ .Case("setter", true)
+ .Default(false))
Tokens[I].int_data[0] = CXToken_Keyword;
}
continue;
@@ -4712,13 +4700,13 @@
Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
if (llvm::StringSwitch<bool>(II->getName())
- .Case("in", true)
- .Case("out", true)
- .Case("inout", true)
- .Case("oneway", true)
- .Case("bycopy", true)
- .Case("byref", true)
- .Default(false))
+ .Case("in", true)
+ .Case("out", true)
+ .Case("inout", true)
+ .Case("oneway", true)
+ .Case("bycopy", true)
+ .Case("byref", true)
+ .Default(false))
Tokens[I].int_data[0] = CXToken_Keyword;
continue;
}
@@ -4726,14 +4714,14 @@
if (Cursors[I].kind == CXCursor_CXXMethod) {
IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
if (CXXMethodDecl *Method
- = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(Cursors[I]))) {
+ = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(Cursors[I]))) {
if ((Method->hasAttr<FinalAttr>() ||
Method->hasAttr<OverrideAttr>()) &&
Method->getLocation().getRawEncoding() != Tokens[I].int_data[1] &&
llvm::StringSwitch<bool>(II->getName())
- .Case("final", true)
- .Case("override", true)
- .Default(false))
+ .Case("final", true)
+ .Case("override", true)
+ .Default(false))
Tokens[I].int_data[0] = CXToken_Keyword;
}
continue;
@@ -4753,18 +4741,47 @@
Record->getIdentifier() != II)
Tokens[I].int_data[0] = CXToken_Keyword;
} else if (ClassTemplateDecl *ClassTemplate
- = dyn_cast_or_null<ClassTemplateDecl>(D)) {
+ = dyn_cast_or_null<ClassTemplateDecl>(D)) {
CXXRecordDecl *Record = ClassTemplate->getTemplatedDecl();
if ((Record->hasAttr<FinalAttr>()) &&
Record->getIdentifier() != II)
- Tokens[I].int_data[0] = CXToken_Keyword;
+ Tokens[I].int_data[0] = CXToken_Keyword;
}
}
- continue;
+ continue;
}
}
}
}
+
+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"
//===----------------------------------------------------------------------===//
More information about the cfe-commits
mailing list