Flesh out CXCursorKind...
- More declaration types (distinguish between struct/union/class, instance/class methods).
- Add definition types (class, category, function, instance/class method, etc.).
Add client data to clang_loadDeclaration() and implement.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@80787 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/tools/CIndex/CIndex.cpp b/tools/CIndex/CIndex.cpp
index 9577391..5242de2 100644
--- a/tools/CIndex/CIndex.cpp
+++ b/tools/CIndex/CIndex.cpp
@@ -15,6 +15,7 @@
#include "clang/Index/Program.h"
#include "clang/Index/Indexer.h"
#include "clang/AST/DeclVisitor.h"
+#include "clang/AST/Decl.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Frontend/ASTUnit.h"
@@ -51,10 +52,24 @@
Call(CXCursor_TypedefDecl, ND);
}
void VisitTagDecl(TagDecl *ND) {
- Call(ND->isEnum() ? CXCursor_EnumDecl : CXCursor_RecordDecl, ND);
+ switch (ND->getTagKind()) {
+ case TagDecl::TK_struct:
+ Call(CXCursor_StructDecl, ND);
+ break;
+ case TagDecl::TK_class:
+ Call(CXCursor_ClassDecl, ND);
+ break;
+ case TagDecl::TK_union:
+ Call(CXCursor_UnionDecl, ND);
+ break;
+ case TagDecl::TK_enum:
+ Call(CXCursor_EnumDecl, ND);
+ break;
+ }
}
void VisitFunctionDecl(FunctionDecl *ND) {
- Call(CXCursor_FunctionDecl, ND);
+ Call(ND->isThisDeclarationADefinition() ? CXCursor_FunctionDefn
+ : CXCursor_FunctionDecl, ND);
}
void VisitObjCInterfaceDecl(ObjCInterfaceDecl *ND) {
Call(CXCursor_ObjCInterfaceDecl, ND);
@@ -65,21 +80,65 @@
void VisitObjCProtocolDecl(ObjCProtocolDecl *ND) {
Call(CXCursor_ObjCProtocolDecl, ND);
}
+ void VisitObjCImplementationDecl(ObjCImplementationDecl *ND) {
+ Call(CXCursor_ObjCClassDefn, ND);
+ }
+ void VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *ND) {
+ Call(CXCursor_ObjCCategoryDefn, ND);
+ }
};
-// Top-level declaration visitor.
-class TLDeclVisitor : public DeclVisitor<TLDeclVisitor> {
+// Declaration visitor.
+class CDeclVisitor : public DeclVisitor<CDeclVisitor> {
+ CXDecl CDecl;
+ CXDeclIterator Callback;
+ CXClientData CData;
+
+ void Call(enum CXCursorKind CK, NamedDecl *ND) {
+ CXCursor C = { CK, ND };
+ Callback(CDecl, C, CData);
+ }
public:
+ CDeclVisitor(CXDecl C, CXDeclIterator cback, CXClientData D) :
+ CDecl(C), Callback(cback), CData(D) {}
+
+ void VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
+ VisitDeclContext(dyn_cast<DeclContext>(D));
+ }
+ void VisitTagDecl(TagDecl *D) {
+ VisitDeclContext(dyn_cast<DeclContext>(D));
+ }
+ void VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
+ VisitDeclContext(dyn_cast<DeclContext>(D));
+ }
+ void VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
+ VisitDeclContext(dyn_cast<DeclContext>(D));
+ }
void VisitDeclContext(DeclContext *DC) {
for (DeclContext::decl_iterator
I = DC->decls_begin(), E = DC->decls_end(); I != E; ++I)
Visit(*I);
}
void VisitEnumConstantDecl(EnumConstantDecl *ND) {
+ Call(CXCursor_EnumConstantDecl, ND);
}
void VisitFieldDecl(FieldDecl *ND) {
+ Call(CXCursor_FieldDecl, ND);
+ }
+ void VisitObjCPropertyDecl(ObjCPropertyDecl *ND) {
+ Call(CXCursor_ObjCPropertyDecl, ND);
}
void VisitObjCIvarDecl(ObjCIvarDecl *ND) {
+ Call(CXCursor_ObjCIvarDecl, ND);
+ }
+ void VisitObjCMethodDecl(ObjCMethodDecl *ND) {
+ if (ND->getBody()) {
+ Call(ND->isInstanceMethod() ? CXCursor_ObjCInstanceMethodDefn
+ : CXCursor_ObjCClassMethodDefn, ND);
+ // FIXME: load body.
+ } else
+ Call(ND->isInstanceMethod() ? CXCursor_ObjCInstanceMethodDecl
+ : CXCursor_ObjCClassMethodDecl, ND);
}
};
@@ -105,9 +164,9 @@
}
-void clang_loadTranslationUnit(
- CXTranslationUnit CTUnit, CXTranslationUnitIterator callback,
- CXClientData CData)
+void clang_loadTranslationUnit(CXTranslationUnit CTUnit,
+ CXTranslationUnitIterator callback,
+ CXClientData CData)
{
assert(CTUnit && "Passed null CXTranslationUnit");
ASTUnit *CXXUnit = static_cast<ASTUnit *>(CTUnit);
@@ -117,8 +176,14 @@
DVisit.Visit(Ctx.getTranslationUnitDecl());
}
-void clang_loadDeclaration(CXDecl, CXDeclIterator)
+void clang_loadDeclaration(CXDecl Dcl,
+ CXDeclIterator callback,
+ CXClientData CData)
{
+ assert(Dcl && "Passed null CXDecl");
+
+ CDeclVisitor DVisit(Dcl, callback, CData);
+ DVisit.Visit(static_cast<Decl *>(Dcl));
}
// Some notes on CXEntity:
@@ -167,9 +232,13 @@
{
assert(AnonDecl && "Passed null CXDecl");
NamedDecl *ND = static_cast<NamedDecl *>(AnonDecl);
+
+ if (ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND)) {
+ return OMD->getSelector().getAsString().c_str();
+ }
if (ND->getIdentifier())
return ND->getIdentifier()->getName();
- else
+ else
return "";
}
const char *clang_getKindSpelling(enum CXCursorKind Kind)
@@ -179,7 +248,9 @@
case CXCursor_TypedefDecl: return "TypedefDecl";
case CXCursor_EnumDecl: return "EnumDecl";
case CXCursor_EnumConstantDecl: return "EnumConstantDecl";
- case CXCursor_RecordDecl: return "RecordDecl";
+ case CXCursor_StructDecl: return "StructDecl";
+ case CXCursor_UnionDecl: return "UnionDecl";
+ case CXCursor_ClassDecl: return "ClassDecl";
case CXCursor_FieldDecl: return "FieldDecl";
case CXCursor_VarDecl: return "VarDecl";
case CXCursor_ParmDecl: return "ParmDecl";
@@ -188,7 +259,13 @@
case CXCursor_ObjCProtocolDecl: return "ObjCProtocolDecl";
case CXCursor_ObjCPropertyDecl: return "ObjCPropertyDecl";
case CXCursor_ObjCIvarDecl: return "ObjCIvarDecl";
- case CXCursor_ObjCMethodDecl: return "ObjCMethodDecl";
+ case CXCursor_ObjCInstanceMethodDecl: return "ObjCInstanceMethodDecl";
+ case CXCursor_ObjCClassMethodDecl: return "ObjCClassMethodDecl";
+ case CXCursor_FunctionDefn: return "FunctionDefn";
+ case CXCursor_ObjCInstanceMethodDefn: return "ObjCInstanceMethodDefn";
+ case CXCursor_ObjCClassMethodDefn: return "ObjCClassMethodDefn";
+ case CXCursor_ObjCClassDefn: return "ObjCClassDefn";
+ case CXCursor_ObjCCategoryDefn: return "ObjCCategoryDefn";
default: return "<not implemented>";
}
}
diff --git a/tools/c-index-test/c-index-test.c b/tools/c-index-test/c-index-test.c
index 30700d8..d96468f 100644
--- a/tools/c-index-test/c-index-test.c
+++ b/tools/c-index-test/c-index-test.c
@@ -3,16 +3,28 @@
#include "clang-c/Index.h"
#include <stdio.h>
-static void PrintDecls(CXTranslationUnit Unit, CXCursor Cursor,
- CXClientData Filter) {
- if (clang_isDeclaration(Cursor.kind)) {
- if (Cursor.kind == *(enum CXCursorKind *)Filter) {
- printf("%s => %s", clang_getKindSpelling(Cursor.kind),
- clang_getDeclSpelling(Cursor.decl));
- printf(" (%s,%d:%d)\n", clang_getCursorSource(Cursor),
- clang_getCursorLine(Cursor),
- clang_getCursorColumn(Cursor));
- }
+static void DeclVisitor(CXDecl Dcl, CXCursor Cursor, CXClientData Filter)
+{
+ if (!Filter || (Cursor.kind == *(enum CXCursorKind *)Filter)) {
+ printf("%s => %s", clang_getKindSpelling(Cursor.kind),
+ clang_getDeclSpelling(Cursor.decl));
+ printf(" (%s,%d:%d)\n", clang_getCursorSource(Cursor),
+ clang_getCursorLine(Cursor),
+ clang_getCursorColumn(Cursor));
+ }
+}
+static void TranslationUnitVisitor(CXTranslationUnit Unit, CXCursor Cursor,
+ CXClientData Filter)
+{
+ if (!Filter || (Cursor.kind == *(enum CXCursorKind *)Filter)) {
+ printf("%s => %s", clang_getKindSpelling(Cursor.kind),
+ clang_getDeclSpelling(Cursor.decl));
+ printf(" (%s,%d:%d)\n", clang_getCursorSource(Cursor),
+ clang_getCursorLine(Cursor),
+ clang_getCursorColumn(Cursor));
+
+ enum CXCursorKind filterData = CXCursor_FieldDecl;
+ clang_loadDeclaration(Cursor.decl, DeclVisitor, 0);
}
}
@@ -23,8 +35,7 @@
CXIndex Idx = clang_createIndex();
CXTranslationUnit TU = clang_createTranslationUnit(Idx, argv[1]);
- /* Use client data to only print ObjC interfaces */
- enum CXCursorKind filterData = CXCursor_ObjCInterfaceDecl;
- clang_loadTranslationUnit(TU, PrintDecls, &filterData);
+ enum CXCursorKind filterData = CXCursor_StructDecl;
+ clang_loadTranslationUnit(TU, TranslationUnitVisitor, 0);
return 1;
}