Teach the cursor visitor to walk all of the C and Objective-C

declarations that have enough source information to make such a walk
useful. This includes walking into variable initializers and enum
constants, the types behind typedefs, etc.

llvm-svn: 94124
This commit is contained in:
Douglas Gregor 2010-01-22 00:50:27 +00:00
parent 045f81981a
commit d824f8825b
3 changed files with 135 additions and 32 deletions

View File

@ -430,7 +430,7 @@ class ObjCInterfaceDecl : public ObjCContainerDecl {
/// Protocols referenced in interface header declaration
ObjCProtocolList ReferencedProtocols;
/// Instance variables in the interface.
/// Instance variables in the interface. This list is completely redundant.
ObjCList<ObjCIvarDecl> IVars;
/// List of categories defined for this class.

View File

@ -77,17 +77,28 @@ int main (int argc, const char * argv[]) {
// CHECK: c-index-api-loadTU-test.m:45:5: FunctionDecl=main:45:5 (Definition) [Extent=45:5:54:1]
// CHECK: c-index-api-loadTU-test.m:45:15: ParmDecl=argc:45:15 (Definition) [Extent=45:15:45:18]
// CHECK: c-index-api-loadTU-test.m:45:34: ParmDecl=argv:45:34 (Definition) [Extent=45:34:45:37]
// CHECK: c-index-api-loadTU-test.m:45:5: UnexposedStmt=main [Extent=45:5:54:1]
// CHECK: c-index-api-loadTU-test.m:45:5: UnexposedStmt=main [Extent=45:5:54:1]
// CHECK: c-index-api-loadTU-test.m:46:8: VarDecl=bee:46:8 (Definition) [Extent=46:8:46:10]
// CHECK: c-index-api-loadTU-test.m:46:2: ObjCClassRef=Baz:32:12 [Extent=46:2:46:4]
// CHECK: c-index-api-loadTU-test.m:46:8: UnexposedStmt=bee [Extent=46:8:46:10]
// CHECK: c-index-api-loadTU-test.m:47:5: VarDecl=a:47:5 (Definition) [Extent=47:5:47:17]
// CHECK: c-index-api-loadTU-test.m:47:2: TypeRef=id:0:0 [Extent=47:2:47:3]
// CHECK: c-index-api-loadTU-test.m:47:9: ObjCMessageExpr=foo:8:1 [Extent=47:9:47:17]
// CHECK: c-index-api-loadTU-test.m:47:10: DeclRefExpr=bee:46:8 [Extent=47:10:47:12]
// CHECK: c-index-api-loadTU-test.m:47:5: UnexposedStmt=a [Extent=47:5:47:17]
// CHECK: c-index-api-loadTU-test.m:48:12: VarDecl=c:48:12 (Definition) [Extent=48:12:48:25]
// CHECK: c-index-api-loadTU-test.m:48:2: TypeRef=id:0:0 [Extent=48:2:48:3]
// CHECK: c-index-api-loadTU-test.m:48:6: ObjCProtocolRef=SubP:28:1 [Extent=48:6:48:9]
// CHECK: c-index-api-loadTU-test.m:48:16: UnexposedExpr=fooC:9:1 [Extent=48:16:48:25]
// CHECK: c-index-api-loadTU-test.m:48:16: ObjCMessageExpr=fooC:9:1 [Extent=48:16:48:25]
// CHECK: c-index-api-loadTU-test.m:48:12: UnexposedStmt=c [Extent=48:12:48:25]
// 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: UnexposedExpr= [Extent=50:2:50:6]
// 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: UnexposedExpr=c:48:12 [Extent=50:6:50:6]
// 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]
@ -96,6 +107,8 @@ int main (int argc, const char * argv[]) {
// 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: UnexposedExpr=main:45:5 [Extent=53:3:53:6]
// 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:18: UnexposedExpr=bee:46:8 [Extent=53:18:53:35]
// CHECK: c-index-api-loadTU-test.m:53:33: DeclRefExpr=bee:46:8 [Extent=53:33:53:35]

View File

@ -178,14 +178,26 @@ public:
// Declaration visitors
bool VisitDeclContext(DeclContext *DC);
bool VisitTranslationUnitDecl(TranslationUnitDecl *D);
bool VisitTypedefDecl(TypedefDecl *D);
bool VisitTagDecl(TagDecl *D);
bool VisitEnumConstantDecl(EnumConstantDecl *D);
bool VisitDeclaratorDecl(DeclaratorDecl *DD);
bool VisitFunctionDecl(FunctionDecl *ND);
bool VisitFieldDecl(FieldDecl *D);
bool VisitVarDecl(VarDecl *);
bool VisitObjCMethodDecl(ObjCMethodDecl *ND);
bool VisitObjCContainerDecl(ObjCContainerDecl *D);
bool VisitObjCCategoryDecl(ObjCCategoryDecl *ND);
bool VisitObjCInterfaceDecl(ObjCInterfaceDecl *D);
bool VisitObjCMethodDecl(ObjCMethodDecl *ND);
bool VisitObjCProtocolDecl(ObjCProtocolDecl *PID);
bool VisitTagDecl(TagDecl *D);
bool VisitObjCInterfaceDecl(ObjCInterfaceDecl *D);
bool VisitObjCImplDecl(ObjCImplDecl *D);
bool VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D);
bool VisitObjCImplementationDecl(ObjCImplementationDecl *D);
// FIXME: ObjCPropertyDecl requires TypeSourceInfo, getter/setter locations,
// etc.
// FIXME: ObjCCompatibleAliasDecl requires aliased-class locations.
bool VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D);
bool VisitObjCClassDecl(ObjCClassDecl *D);
// Type visitors
// FIXME: QualifiedTypeLoc doesn't provide any location information
@ -314,11 +326,6 @@ bool CursorVisitor::VisitChildren(CXCursor Cursor) {
return false;
}
bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
llvm_unreachable("Translation units are visited directly by Visit()");
return false;
}
bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
for (DeclContext::decl_iterator
I = DC->decls_begin(), E = DC->decls_end(); I != E; ++I) {
@ -329,6 +336,28 @@ bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
return false;
}
bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
llvm_unreachable("Translation units are visited directly by Visit()");
return false;
}
bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
return Visit(TSInfo->getTypeLoc());
return false;
}
bool CursorVisitor::VisitTagDecl(TagDecl *D) {
return VisitDeclContext(D);
}
bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
if (Expr *Init = D->getInitExpr())
return Visit(MakeCXCursor(Init, StmtParent, TU));
return false;
}
bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
if (Visit(TSInfo->getTypeLoc()))
@ -348,6 +377,44 @@ bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
return false;
}
bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
if (VisitDeclaratorDecl(D))
return true;
if (Expr *BitWidth = D->getBitWidth())
return Visit(MakeCXCursor(BitWidth, StmtParent, TU));
return false;
}
bool CursorVisitor::VisitVarDecl(VarDecl *D) {
if (VisitDeclaratorDecl(D))
return true;
if (Expr *Init = D->getInit())
return Visit(MakeCXCursor(Init, StmtParent, TU));
return false;
}
bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *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;
}
bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
return VisitDeclContext(D);
}
@ -366,6 +433,16 @@ bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
return VisitObjCContainerDecl(ND);
}
bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
E = PID->protocol_end(); I != E; ++I, ++PL)
if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
return true;
return VisitObjCContainerDecl(PID);
}
bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
// Issue callbacks for super class.
if (D->getSuperClass() &&
@ -383,36 +460,49 @@ bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
return VisitObjCContainerDecl(D);
}
bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *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;
bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
return VisitObjCContainerDecl(D);
}
bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
E = PID->protocol_end(); I != E; ++I, ++PL)
bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
if (Visit(MakeCursorObjCClassRef(D->getCategoryDecl()->getClassInterface(),
D->getLocation(), TU)))
return true;
return VisitObjCImplDecl(D);
}
bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
#if 0
// Issue callbacks for super class.
// FIXME: No source location information!
if (D->getSuperClass() &&
Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
D->getSuperClassLoc(),
TU)))
return true;
#endif
return VisitObjCImplDecl(D);
}
bool CursorVisitor::VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D) {
ObjCForwardProtocolDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
for (ObjCForwardProtocolDecl::protocol_iterator I = D->protocol_begin(),
E = D->protocol_end();
I != E; ++I, ++PL)
if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
return true;
return VisitObjCContainerDecl(PID);
return false;
}
bool CursorVisitor::VisitTagDecl(TagDecl *D) {
return VisitDeclContext(D);
bool CursorVisitor::VisitObjCClassDecl(ObjCClassDecl *D) {
for (ObjCClassDecl::iterator C = D->begin(), CEnd = D->end(); C != CEnd; ++C)
if (Visit(MakeCursorObjCClassRef(C->getInterface(), C->getLocation(), TU)))
return true;
return false;
}
bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {