[cfe-commits] r103687 - in /cfe/trunk: test/Index/load-stmts.cpp tools/libclang/CIndex.cpp
Ted Kremenek
kremenek at apple.com
Wed May 12 17:25:00 PDT 2010
Author: kremenek
Date: Wed May 12 19:25:00 2010
New Revision: 103687
URL: http://llvm.org/viewvc/llvm-project?rev=103687&view=rev
Log:
Specially handle CaseStmts in CursorVisitor because they can be nested and walking them
can blow out the stack.
Modified:
cfe/trunk/test/Index/load-stmts.cpp
cfe/trunk/tools/libclang/CIndex.cpp
Modified: cfe/trunk/test/Index/load-stmts.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/load-stmts.cpp?rev=103687&r1=103686&r2=103687&view=diff
==============================================================================
--- cfe/trunk/test/Index/load-stmts.cpp (original)
+++ cfe/trunk/test/Index/load-stmts.cpp Wed May 12 19:25:00 2010
@@ -54,6 +54,6 @@
// CHECK: load-stmts.cpp:8:13: DeclRefExpr=z4:8:13 Extent=[8:13 - 8:15]
// CHECK: <invalid loc>:0:0: UnexposedStmt= Extent=[8:21 - 10:4]
// CHECK: <invalid loc>:0:0: UnexposedStmt= Extent=[9:3 - 9:17]
-// CHECK: <invalid loc>:0:0: UnexposedStmt= Extent=[9:12 - 9:17]
// CHECK: load-stmts.cpp:9:8: UnexposedExpr= Extent=[9:8 - 9:10]
+// CHECK: <invalid loc>:0:0: UnexposedStmt= Extent=[9:12 - 9:17]
Modified: cfe/trunk/tools/libclang/CIndex.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndex.cpp?rev=103687&r1=103686&r2=103687&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CIndex.cpp (original)
+++ cfe/trunk/tools/libclang/CIndex.cpp Wed May 12 19:25:00 2010
@@ -239,6 +239,27 @@
/// \param R a half-open source range retrieved from the abstract syntax tree.
RangeComparisonResult CompareRegionOfInterest(SourceRange R);
+ class SetParentRAII {
+ CXCursor &Parent;
+ Decl *&StmtParent;
+ CXCursor OldParent;
+
+ public:
+ SetParentRAII(CXCursor &Parent, Decl *&StmtParent, CXCursor NewParent)
+ : Parent(Parent), StmtParent(StmtParent), OldParent(Parent)
+ {
+ Parent = NewParent;
+ if (clang_isDeclaration(Parent.kind))
+ StmtParent = getCursorDecl(Parent);
+ }
+
+ ~SetParentRAII() {
+ Parent = OldParent;
+ if (clang_isDeclaration(Parent.kind))
+ StmtParent = getCursorDecl(Parent);
+ }
+ };
+
public:
CursorVisitor(ASTUnit *TU, CXCursorVisitor Visitor, CXClientData ClientData,
unsigned MaxPCHLevel,
@@ -316,8 +337,10 @@
// FIXME: LabelStmt label?
bool VisitIfStmt(IfStmt *S);
bool VisitSwitchStmt(SwitchStmt *S);
+ bool VisitCaseStmt(CaseStmt *S);
bool VisitWhileStmt(WhileStmt *S);
bool VisitForStmt(ForStmt *S);
+// bool VisitSwitchCase(SwitchCase *S);
// Expression visitors
bool VisitBlockExpr(BlockExpr *B);
@@ -436,26 +459,7 @@
// Set the Parent field to Cursor, then back to its old value once we're
// done.
- class SetParentRAII {
- CXCursor &Parent;
- Decl *&StmtParent;
- CXCursor OldParent;
-
- public:
- SetParentRAII(CXCursor &Parent, Decl *&StmtParent, CXCursor NewParent)
- : Parent(Parent), StmtParent(StmtParent), OldParent(Parent)
- {
- Parent = NewParent;
- if (clang_isDeclaration(Parent.kind))
- StmtParent = getCursorDecl(Parent);
- }
-
- ~SetParentRAII() {
- Parent = OldParent;
- if (clang_isDeclaration(Parent.kind))
- StmtParent = getCursorDecl(Parent);
- }
- } SetParent(Parent, StmtParent, Cursor);
+ SetParentRAII SetParent(Parent, StmtParent, Cursor);
if (clang_isDeclaration(Cursor.kind)) {
Decl *D = getCursorDecl(Cursor);
@@ -888,13 +892,60 @@
bool CursorVisitor::VisitStmt(Stmt *S) {
for (Stmt::child_iterator Child = S->child_begin(), ChildEnd = S->child_end();
Child != ChildEnd; ++Child) {
- if (*Child && Visit(MakeCXCursor(*Child, StmtParent, TU)))
- return true;
+ if (Stmt *C = *Child)
+ if (Visit(MakeCXCursor(C, StmtParent, TU)))
+ return true;
}
return false;
}
+bool CursorVisitor::VisitCaseStmt(CaseStmt *S) {
+ // Specially handle CaseStmts because they can be nested, e.g.:
+ //
+ // case 1:
+ // case 2:
+ //
+ // In this case the second CaseStmt is the child of the first. Walking
+ // these recursively can blow out the stack.
+ CXCursor Cursor = MakeCXCursor(S, StmtParent, TU);
+ while (true) {
+ // Set the Parent field to Cursor, then back to its old value once we're
+ // done.
+ SetParentRAII SetParent(Parent, StmtParent, Cursor);
+
+ if (Stmt *LHS = S->getLHS())
+ if (Visit(MakeCXCursor(LHS, StmtParent, TU)))
+ return true;
+ if (Stmt *RHS = S->getRHS())
+ if (Visit(MakeCXCursor(RHS, StmtParent, TU)))
+ return true;
+ if (Stmt *SubStmt = S->getSubStmt()) {
+ if (!isa<CaseStmt>(SubStmt))
+ return Visit(MakeCXCursor(SubStmt, StmtParent, TU));
+
+ // Specially handle 'CaseStmt' so that we don't blow out the stack.
+ CaseStmt *CS = cast<CaseStmt>(SubStmt);
+ Cursor = MakeCXCursor(CS, StmtParent, TU);
+ if (RegionOfInterest.isValid()) {
+ SourceRange Range = CS->getSourceRange();
+ if (Range.isInvalid() || CompareRegionOfInterest(Range))
+ return false;
+ }
+
+ switch (Visitor(Cursor, Parent, ClientData)) {
+ case CXChildVisit_Break: return true;
+ case CXChildVisit_Continue: return false;
+ case CXChildVisit_Recurse:
+ // Perform tail-recursion manually.
+ S = CS;
+ continue;
+ }
+ }
+ return false;
+ }
+}
+
bool CursorVisitor::VisitDeclStmt(DeclStmt *S) {
for (DeclStmt::decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
D != DEnd; ++D) {
More information about the cfe-commits
mailing list