forked from OSchip/llvm-project
Teach the cursor visitor to walk statements and expressions, including
a few important subkinds. Now we're cookin' with gas! llvm-svn: 94116
This commit is contained in:
parent
60dbeebee8
commit
5e8cf37917
|
@ -87,3 +87,15 @@ int main (int argc, const char * argv[]) {
|
|||
// CHECK: c-index-api-loadTU-test.m:49:13: VarDecl=d:49:13 (Definition) [Extent=49:13:49:13]
|
||||
// CHECK: c-index-api-loadTU-test.m:49:2: TypeRef=id:0:0 [Extent=49:2:49:3]
|
||||
// CHECK: c-index-api-loadTU-test.m:49:6: ObjCProtocolRef=Proto:24:1 [Extent=49:6:49:10]
|
||||
// CHECK: c-index-api-loadTU-test.m:50:2: DeclRefExpr=d:49:13 [Extent=50:2:50:2]
|
||||
// CHECK: c-index-api-loadTU-test.m:50:6: DeclRefExpr=c:48:12 [Extent=50:6:50:6]
|
||||
// CHECK: c-index-api-loadTU-test.m:51:2: ObjCMessageExpr=pMethod:25:1 [Extent=51:2:51:12]
|
||||
// CHECK: c-index-api-loadTU-test.m:51:3: DeclRefExpr=d:49:13 [Extent=51:3:51:3]
|
||||
// CHECK: c-index-api-loadTU-test.m:52:2: ObjCMessageExpr=catMethodWithFloat::20:1 [Extent=52:2:52:43]
|
||||
// CHECK: c-index-api-loadTU-test.m:52:3: DeclRefExpr=bee:46:8 [Extent=52:3:52:5]
|
||||
// CHECK: c-index-api-loadTU-test.m:52:26: ObjCMessageExpr=floatMethod:21:1 [Extent=52:26:52:42]
|
||||
// CHECK: c-index-api-loadTU-test.m:52:27: DeclRefExpr=bee:46:8 [Extent=52:27:52:29]
|
||||
// CHECK: c-index-api-loadTU-test.m:53:3: CallExpr=main:45:5 [Extent=53:3:53:36]
|
||||
// CHECK: c-index-api-loadTU-test.m:53:3: DeclRefExpr=main:45:5 [Extent=53:3:53:6]
|
||||
// CHECK: c-index-api-loadTU-test.m:53:8: DeclRefExpr=someEnum:42:3 [Extent=53:8:53:15]
|
||||
// CHECK: c-index-api-loadTU-test.m:53:33: DeclRefExpr=bee:46:8 [Extent=53:33:53:35]
|
||||
|
|
|
@ -142,7 +142,8 @@ namespace {
|
|||
|
||||
// Cursor visitor.
|
||||
class CursorVisitor : public DeclVisitor<CursorVisitor, bool>,
|
||||
public TypeLocVisitor<CursorVisitor, bool>
|
||||
public TypeLocVisitor<CursorVisitor, bool>,
|
||||
public StmtVisitor<CursorVisitor, bool>
|
||||
{
|
||||
ASTUnit *TU;
|
||||
CXCursor Parent;
|
||||
|
@ -157,6 +158,7 @@ class CursorVisitor : public DeclVisitor<CursorVisitor, bool>,
|
|||
|
||||
using DeclVisitor<CursorVisitor, bool>::Visit;
|
||||
using TypeLocVisitor<CursorVisitor, bool>::Visit;
|
||||
using StmtVisitor<CursorVisitor, bool>::Visit;
|
||||
|
||||
public:
|
||||
CursorVisitor(ASTUnit *TU, CXCursorVisitor Visitor, CXClientData ClientData,
|
||||
|
@ -178,6 +180,7 @@ public:
|
|||
bool VisitTranslationUnitDecl(TranslationUnitDecl *D);
|
||||
bool VisitDeclaratorDecl(DeclaratorDecl *DD);
|
||||
bool VisitFunctionDecl(FunctionDecl *ND);
|
||||
bool VisitObjCContainerDecl(ObjCContainerDecl *D);
|
||||
bool VisitObjCCategoryDecl(ObjCCategoryDecl *ND);
|
||||
bool VisitObjCInterfaceDecl(ObjCInterfaceDecl *D);
|
||||
bool VisitObjCMethodDecl(ObjCMethodDecl *ND);
|
||||
|
@ -205,6 +208,10 @@ public:
|
|||
// implemented
|
||||
bool VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL);
|
||||
bool VisitTypeOfTypeLoc(TypeOfTypeLoc TL);
|
||||
|
||||
// Statement visitors
|
||||
bool VisitStmt(Stmt *S);
|
||||
bool VisitDeclStmt(DeclStmt *S);
|
||||
};
|
||||
|
||||
} // end anonymous namespace
|
||||
|
@ -247,6 +254,11 @@ bool CursorVisitor::Visit(CXCursor Cursor) {
|
|||
/// \returns true if the visitation should be aborted, false if it
|
||||
/// should continue.
|
||||
bool CursorVisitor::VisitChildren(CXCursor Cursor) {
|
||||
if (clang_isReference(Cursor.kind)) {
|
||||
// By definition, references have no children.
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set the Parent field to Cursor, then back to its old value once we're
|
||||
// done.
|
||||
class SetParentRAII {
|
||||
|
@ -276,6 +288,11 @@ bool CursorVisitor::VisitChildren(CXCursor Cursor) {
|
|||
return Visit(D);
|
||||
}
|
||||
|
||||
if (clang_isStatement(Cursor.kind))
|
||||
return Visit(getCursorStmt(Cursor));
|
||||
if (clang_isExpression(Cursor.kind))
|
||||
return Visit(getCursorExpr(Cursor));
|
||||
|
||||
if (clang_isTranslationUnit(Cursor.kind)) {
|
||||
ASTUnit *CXXUnit = getCursorASTUnit(Cursor);
|
||||
if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls()) {
|
||||
|
@ -294,7 +311,6 @@ bool CursorVisitor::VisitChildren(CXCursor Cursor) {
|
|||
}
|
||||
|
||||
// Nothing to visit at the moment.
|
||||
// FIXME: Traverse statements, declarations, etc. here.
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -325,21 +341,17 @@ bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
|
|||
if (VisitDeclaratorDecl(ND))
|
||||
return true;
|
||||
|
||||
// FIXME: This is wrong. We want to visit the body as a statement.
|
||||
if (ND->isThisDeclarationADefinition()) {
|
||||
return VisitDeclContext(ND);
|
||||
|
||||
#if 0
|
||||
// Not currently needed.
|
||||
CompoundStmt *Body = dyn_cast<CompoundStmt>(ND->getBody());
|
||||
CRefVisitor RVisit(CDecl, Callback, CData);
|
||||
RVisit.Visit(Body);
|
||||
#endif
|
||||
}
|
||||
if (ND->isThisDeclarationADefinition() &&
|
||||
Visit(MakeCXCursor(ND->getBody(), StmtParent, TU)))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
|
||||
return VisitDeclContext(D);
|
||||
}
|
||||
|
||||
bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
|
||||
if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
|
||||
TU)))
|
||||
|
@ -351,7 +363,7 @@ bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
|
|||
if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
|
||||
return true;
|
||||
|
||||
return VisitDeclContext(ND);
|
||||
return VisitObjCContainerDecl(ND);
|
||||
}
|
||||
|
||||
bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
|
||||
|
@ -368,13 +380,23 @@ bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
|
|||
if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
|
||||
return true;
|
||||
|
||||
return VisitDeclContext(D);
|
||||
return VisitObjCContainerDecl(D);
|
||||
}
|
||||
|
||||
bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
|
||||
// FIXME: Wrong in the same way that VisitFunctionDecl is wrong.
|
||||
if (ND->getBody())
|
||||
return VisitDeclContext(ND);
|
||||
// FIXME: We really need a TypeLoc covering Objective-C method declarations.
|
||||
// At the moment, we don't have information about locations in the return
|
||||
// type.
|
||||
for (ObjCMethodDecl::param_iterator P = ND->param_begin(),
|
||||
PEnd = ND->param_end();
|
||||
P != PEnd; ++P) {
|
||||
if (Visit(MakeCXCursor(*P, TU)))
|
||||
return true;
|
||||
}
|
||||
|
||||
if (ND->isThisDeclarationADefinition() &&
|
||||
Visit(MakeCXCursor(ND->getBody(), StmtParent, TU)))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -386,7 +408,7 @@ bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
|
|||
if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
|
||||
return true;
|
||||
|
||||
return VisitDeclContext(PID);
|
||||
return VisitObjCContainerDecl(PID);
|
||||
}
|
||||
|
||||
bool CursorVisitor::VisitTagDecl(TagDecl *D) {
|
||||
|
@ -517,9 +539,6 @@ bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL) {
|
|||
if (Visit(TL.getResultLoc()))
|
||||
return true;
|
||||
|
||||
// FIXME: For function definitions, this means that we'll end up
|
||||
// visiting the parameters twice, because VisitFunctionDecl is
|
||||
// walking the DeclContext.
|
||||
for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
|
||||
if (Visit(MakeCXCursor(TL.getArg(I), TU)))
|
||||
return true;
|
||||
|
@ -548,6 +567,26 @@ bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
|
|||
return false;
|
||||
}
|
||||
|
||||
bool CursorVisitor::VisitStmt(Stmt *S) {
|
||||
for (Stmt::child_iterator Child = S->child_begin(), ChildEnd = S->child_end();
|
||||
Child != ChildEnd; ++Child) {
|
||||
if (Visit(MakeCXCursor(*Child, StmtParent, TU)))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CursorVisitor::VisitDeclStmt(DeclStmt *S) {
|
||||
for (DeclStmt::decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
|
||||
D != DEnd; ++D) {
|
||||
if (Visit(MakeCXCursor(*D, TU)))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
CXString CIndexer::createCXString(const char *String, bool DupString){
|
||||
CXString Str;
|
||||
if (DupString) {
|
||||
|
|
Loading…
Reference in New Issue