From c857ea4d22e1e6dd9ede1f0e84d48b157c6924fd Mon Sep 17 00:00:00 2001 From: Steve Naroff Date: Wed, 2 Sep 2009 13:28:54 +0000 Subject: [PATCH] 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 --- include/clang-c/Index.h | 60 +++++++++++-------- tools/CIndex/CIndex.cpp | 99 +++++++++++++++++++++++++++---- tools/c-index-test/c-index-test.c | 37 ++++++++---- 3 files changed, 148 insertions(+), 48 deletions(-) diff --git a/include/clang-c/Index.h b/include/clang-c/Index.h index 91998037fd..0b605d512e 100644 --- a/include/clang-c/Index.h +++ b/include/clang-c/Index.h @@ -35,35 +35,47 @@ typedef void *CXTranslationUnit; /* A translation unit instance. */ typedef void *CXDecl; /* A specific declaration within a translation unit. */ -/* Cursors represent declarations and references (provides line/column info). */ +/* Cursors represent declarations, definitions, and references. */ enum CXCursorKind { CXCursor_Invalid = 0, /* Declarations */ CXCursor_FirstDecl = 1, - CXCursor_TypedefDecl = 1, - CXCursor_EnumDecl = 2, - CXCursor_EnumConstantDecl = 3, - CXCursor_RecordDecl = 4, /* struct/union/class */ - CXCursor_FieldDecl = 5, - CXCursor_FunctionDecl = 6, - CXCursor_VarDecl = 7, - CXCursor_ParmDecl = 8, - CXCursor_ObjCInterfaceDecl = 9, - CXCursor_ObjCCategoryDecl = 10, - CXCursor_ObjCProtocolDecl = 11, - CXCursor_ObjCPropertyDecl = 12, - CXCursor_ObjCIvarDecl = 13, - CXCursor_ObjCMethodDecl = 14, - CXCursor_LastDecl = 14, + CXCursor_TypedefDecl = 2, + CXCursor_StructDecl = 3, + CXCursor_UnionDecl = 4, + CXCursor_ClassDecl = 5, + CXCursor_EnumDecl = 6, + CXCursor_FieldDecl = 7, + CXCursor_EnumConstantDecl = 8, + CXCursor_FunctionDecl = 9, + CXCursor_VarDecl = 10, + CXCursor_ParmDecl = 11, + CXCursor_ObjCInterfaceDecl = 12, + CXCursor_ObjCCategoryDecl = 13, + CXCursor_ObjCProtocolDecl = 14, + CXCursor_ObjCPropertyDecl = 15, + CXCursor_ObjCIvarDecl = 16, + CXCursor_ObjCInstanceMethodDecl = 17, + CXCursor_ObjCClassMethodDecl = 18, + CXCursor_LastDecl = 18, + /* Definitions */ + CXCursor_FirstDefn = 32, + CXCursor_FunctionDefn = 32, + CXCursor_ObjCClassDefn = 33, + CXCursor_ObjCCategoryDefn = 34, + CXCursor_ObjCInstanceMethodDefn = 35, + CXCursor_ObjCClassMethodDefn = 36, + CXCursor_LastDefn = 36, + /* References */ - CXCursor_FirstRef = 19, - CXCursor_ObjCClassRef = 19, - CXCursor_ObjCProtocolRef = 20, - CXCursor_ObjCMessageRef = 21, - CXCursor_ObjCSelectorRef = 22, - CXCursor_LastRef = 23 + CXCursor_FirstRef = 40, + CXCursor_ObjCClassRef = 41, + CXCursor_ObjCProtocolRef = 42, + CXCursor_ObjCMessageRef = 43, + CXCursor_ObjCSelectorRef = 44, + CXCursor_LastRef = 44 }; /* A cursor into the CXTranslationUnit. */ @@ -131,9 +143,9 @@ void clang_loadTranslationUnit(CXTranslationUnit, CXTranslationUnitIterator, } } */ -typedef void (*CXDeclIterator)(CXTranslationUnit, CXDecl, void *clientData); +typedef void (*CXDeclIterator)(CXDecl, CXCursor, CXClientData); -void clang_loadDeclaration(CXDecl, CXDeclIterator); +void clang_loadDeclaration(CXDecl, CXDeclIterator, CXClientData); /* * CXEntity Operations. diff --git a/tools/CIndex/CIndex.cpp b/tools/CIndex/CIndex.cpp index 9577391288..5242de2360 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 @@ public: 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 @@ public: 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 { +// Declaration visitor. +class CDeclVisitor : public DeclVisitor { + 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(D)); + } + void VisitTagDecl(TagDecl *D) { + VisitDeclContext(dyn_cast(D)); + } + void VisitObjCImplementationDecl(ObjCImplementationDecl *D) { + VisitDeclContext(dyn_cast(D)); + } + void VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) { + VisitDeclContext(dyn_cast(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 @@ CXTranslationUnit clang_createTranslationUnit( } -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(CTUnit); @@ -117,8 +176,14 @@ void clang_loadTranslationUnit( 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(Dcl)); } // Some notes on CXEntity: @@ -167,9 +232,13 @@ const char *clang_getDeclSpelling(CXDecl AnonDecl) { assert(AnonDecl && "Passed null CXDecl"); NamedDecl *ND = static_cast(AnonDecl); + + if (ObjCMethodDecl *OMD = dyn_cast(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 @@ const char *clang_getKindSpelling(enum CXCursorKind Kind) 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 @@ const char *clang_getKindSpelling(enum CXCursorKind Kind) 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 ""; } } diff --git a/tools/c-index-test/c-index-test.c b/tools/c-index-test/c-index-test.c index 30700d8ae3..d96468f8c4 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 -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 @@ int main(int argc, char **argv) { 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; } -- 2.50.1