From: Steve Naroff Date: Mon, 31 Aug 2009 00:59:03 +0000 (+0000) Subject: More fleshing out the C-based indexing API (under construction). X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=89922f86f4e7da383af2a62ef04ad8b93b941220;p=clang More fleshing out the C-based indexing API (under construction). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@80529 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/clang.xcodeproj/project.pbxproj b/clang.xcodeproj/project.pbxproj index 705ff04a32..6e17eb1a98 100644 --- a/clang.xcodeproj/project.pbxproj +++ b/clang.xcodeproj/project.pbxproj @@ -111,6 +111,7 @@ 9012911D1048068D0083456D /* ASTUnit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9012911C1048068D0083456D /* ASTUnit.cpp */; }; 90129121104812F90083456D /* CIndex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9012911F104812F90083456D /* CIndex.cpp */; }; 906BF4B00F83BA2E001071FA /* ConvertUTF.c in Sources */ = {isa = PBXBuildFile; fileRef = 906BF4AF0F83BA2E001071FA /* ConvertUTF.c */; }; + 90F9EFAA104ABDED00D09A15 /* c-index-test.c in Sources */ = {isa = PBXBuildFile; fileRef = 90F9EFA9104ABDED00D09A15 /* c-index-test.c */; }; 90FD6D7B103C3D49005F5B73 /* Analyzer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 90FD6D6D103C3D49005F5B73 /* Analyzer.cpp */; }; 90FD6D7C103C3D49005F5B73 /* ASTLocation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 90FD6D6E103C3D49005F5B73 /* ASTLocation.cpp */; }; 90FD6D7D103C3D49005F5B73 /* DeclReferenceMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 90FD6D70103C3D49005F5B73 /* DeclReferenceMap.cpp */; }; @@ -509,6 +510,7 @@ 9063F22A0F9E911F002F7251 /* TemplateKinds.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TemplateKinds.h; sourceTree = ""; }; 906BF4AE0F83BA16001071FA /* ConvertUTF.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ConvertUTF.h; sourceTree = ""; }; 906BF4AF0F83BA2E001071FA /* ConvertUTF.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ConvertUTF.c; sourceTree = ""; }; + 90F9EFA9104ABDED00D09A15 /* c-index-test.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "c-index-test.c"; path = "tools/c-index-test/c-index-test.c"; sourceTree = ""; }; 90FB99DE0F98FB1D008F9415 /* DeclContextInternals.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DeclContextInternals.h; path = clang/AST/DeclContextInternals.h; sourceTree = ""; }; 90FB99DF0F98FB1D008F9415 /* DeclVisitor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DeclVisitor.h; path = clang/AST/DeclVisitor.h; sourceTree = ""; }; 90FB99E00F98FB1D008F9415 /* ExternalASTSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ExternalASTSource.h; path = clang/AST/ExternalASTSource.h; sourceTree = ""; }; @@ -1042,6 +1044,14 @@ name = CIndex; sourceTree = ""; }; + 90F9EFA8104ABDC400D09A15 /* c-index-test */ = { + isa = PBXGroup; + children = ( + 90F9EFA9104ABDED00D09A15 /* c-index-test.c */, + ); + name = "c-index-test"; + sourceTree = ""; + }; 90FD6D5E103C3D03005F5B73 /* Index */ = { isa = PBXGroup; children = ( @@ -1481,6 +1491,7 @@ DEDFE61F0F7B3AE10035BD10 /* Tools */ = { isa = PBXGroup; children = ( + 90F9EFA8104ABDC400D09A15 /* c-index-test */, 9012911E104812DA0083456D /* CIndex */, 90FD6DB4103D9763005F5B73 /* index-test */, DEDFE6200F7B3AE90035BD10 /* clang-cc */, @@ -1867,6 +1878,7 @@ 90FD6DB6103D977E005F5B73 /* index-test.cpp in Sources */, 9012911D1048068D0083456D /* ASTUnit.cpp in Sources */, 90129121104812F90083456D /* CIndex.cpp in Sources */, + 90F9EFAA104ABDED00D09A15 /* c-index-test.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/include/clang-c/Index.h b/include/clang-c/Index.h index b96cb6cb14..2af3fee774 100644 --- a/include/clang-c/Index.h +++ b/include/clang-c/Index.h @@ -37,41 +37,46 @@ typedef void *CXIndex; /* An indexing instance. */ typedef void *CXTranslationUnit; /* A translation unit instance. */ -typedef void *CXCursor; /* An opaque cursor into the CXTranslationUnit. */ +typedef void *CXDecl; /* A specific declaration within a translation unit. */ /* Cursors represent declarations and references (provides line/column info). */ -enum CXCursorKind { - CXCursor_Declaration, - CXCursor_Reference, - CXCursor_ObjC_ClassRef, - CXCursor_ObjC_ProtocolRef, - CXCursor_ObjC_MessageRef, - CXCursor_ObjC_SelectorRef +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, + + /* References */ + CXCursor_FirstRef = 19, + CXCursor_ObjCClassRef = 19, + CXCursor_ObjCProtocolRef = 20, + CXCursor_ObjCMessageRef = 21, + CXCursor_ObjCSelectorRef = 22, + CXCursor_LastRef = 23 }; -typedef void *CXDecl; /* A specific declaration within a translation unit. */ - -enum CXDeclKind { /* The various kinds of declarations. */ - CXDecl_any, - CXDecl_typedef, - CXDecl_enum, - CXDecl_enum_constant, - CXDecl_record, - CXDecl_field, - CXDecl_function, - CXDecl_variable, - CXDecl_parameter, - CXDecl_ObjC_interface, - CXDecl_ObjC_category, - CXDecl_ObjC_protocol, - CXDecl_ObjC_property, - CXDecl_ObjC_instance_variable, - CXDecl_ObjC_instance_method, - CXDecl_ObjC_class_method, - CXDecl_ObjC_category_implementation, - CXDecl_ObjC_class_implementation, - CXDecl_ObjC_property_implementation -}; +/* A cursor into the CXTranslationUnit. */ +typedef struct { + enum CXCursorKind kind; + CXDecl decl; + + /* FIXME: Handle references. */ +} CXCursor; /* A unique token for looking up "visible" CXDecls from a CXTranslationUnit. */ typedef void *CXEntity; @@ -99,9 +104,8 @@ CXTranslationUnit clang_createTranslationUnit( clang_loadTranslationUnit(CXTranslationUnit, printObjCInterfaceNames); } */ -void clang_loadTranslationUnit( - CXTranslationUnit, void (*callback)(CXTranslationUnit, CXCursor) -); +typedef void (*CXTranslationUnitIterator)(CXTranslationUnit, CXCursor); +void clang_loadTranslationUnit(CXTranslationUnit, CXTranslationUnitIterator); /* Usage: clang_loadDeclaration(). Will load the declaration, issuing a @@ -128,7 +132,9 @@ void clang_loadTranslationUnit( } } */ -void clang_loadDeclaration(CXDecl, void (*callback)(CXDecl, CXCursor)); +typedef void (*CXDeclIterator)(CXTranslationUnit, CXDecl, void *clientData); + +void clang_loadDeclaration(CXDecl, CXDeclIterator); /* * CXEntity Operations. @@ -141,7 +147,6 @@ CXEntity clang_getEntity(const char *URI); */ CXCursor clang_getCursorFromDecl(CXDecl); CXEntity clang_getEntityFromDecl(CXDecl); -enum CXDeclKind clang_getDeclKind(CXDecl); const char *clang_getDeclSpelling(CXDecl); /* * CXCursor Operations. @@ -150,10 +155,12 @@ CXCursor clang_getCursor(CXTranslationUnit, const char *source_name, unsigned line, unsigned column); enum CXCursorKind clang_getCursorKind(CXCursor); +unsigned clang_isDeclaration(enum CXCursorKind); unsigned clang_getCursorLine(CXCursor); unsigned clang_getCursorColumn(CXCursor); const char *clang_getCursorSource(CXCursor); +const char *clang_getKindSpelling(enum CXCursorKind Kind); /* * If CXCursorKind == Cursor_Reference, then this will return the referenced declaration. diff --git a/tools/CIndex/CIndex.cpp b/tools/CIndex/CIndex.cpp index a02e80987b..9ef51b9db9 100644 --- a/tools/CIndex/CIndex.cpp +++ b/tools/CIndex/CIndex.cpp @@ -21,6 +21,68 @@ using namespace clang; using namespace idx; +namespace { + +// Translation Unit Visitor. +class TUVisitor : public DeclVisitor { + CXTranslationUnit TUnit; + CXTranslationUnitIterator Callback; +public: + TUVisitor(CXTranslationUnit CTU, CXTranslationUnitIterator cback) : + TUnit(CTU), Callback(cback) {} + + void VisitTranslationUnitDecl(TranslationUnitDecl *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 VisitTypedefDecl(TypedefDecl *ND) { + CXCursor C = { CXCursor_TypedefDecl, ND }; + Callback(TUnit, C); + } + void VisitTagDecl(TagDecl *ND) { + CXCursor C = { ND->isEnum() ? CXCursor_EnumDecl : CXCursor_RecordDecl, ND }; + Callback(TUnit, C); + } + void VisitFunctionDecl(FunctionDecl *ND) { + CXCursor C = { CXCursor_FunctionDecl, ND }; + Callback(TUnit, C); + } + void VisitObjCInterfaceDecl(ObjCInterfaceDecl *ND) { + CXCursor C = { CXCursor_ObjCInterfaceDecl, ND }; + Callback(TUnit, C); + } + void VisitObjCCategoryDecl(ObjCCategoryDecl *ND) { + CXCursor C = { CXCursor_ObjCCategoryDecl, ND }; + Callback(TUnit, C); + } + void VisitObjCProtocolDecl(ObjCProtocolDecl *ND) { + CXCursor C = { CXCursor_ObjCProtocolDecl, ND }; + Callback(TUnit, C); + } +}; + +// Top-level declaration visitor. +class TLDeclVisitor : public DeclVisitor { +public: + 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) { + } + void VisitFieldDecl(FieldDecl *ND) { + } + void VisitObjCIvarDecl(ObjCIvarDecl *ND) { + } +}; + +} + extern "C" { CXIndex clang_createIndex() @@ -40,33 +102,19 @@ CXTranslationUnit clang_createTranslationUnit( return ASTUnit::LoadFromPCHFile(astName, CXXIdx->getFileManager(), &ErrMsg); } -namespace { - -class IdxVisitor : public DeclVisitor { -public: - void VisitNamedDecl(NamedDecl *ND) { - printf("NamedDecl (%s:", ND->getDeclKindName()); - if (ND->getIdentifier()) - printf("%s)\n", ND->getIdentifier()->getName()); - else - printf(")\n"); - } -}; - -} void clang_loadTranslationUnit( - CXTranslationUnit CTUnit, void (*callback)(CXTranslationUnit, CXCursor)) + CXTranslationUnit CTUnit, CXTranslationUnitIterator callback) { assert(CTUnit && "Passed null CXTranslationUnit"); ASTUnit *CXXUnit = static_cast(CTUnit); ASTContext &Ctx = CXXUnit->getASTContext(); - IdxVisitor DVisit; + TUVisitor DVisit(CTUnit, callback); DVisit.Visit(Ctx.getTranslationUnitDecl()); } -void clang_loadDeclaration(CXDecl, void (*callback)(CXDecl, CXCursor)) +void clang_loadDeclaration(CXDecl, CXDeclIterator) { } @@ -106,34 +154,60 @@ CXEntity clang_getEntity(const char *URI) // CXCursor clang_getCursorFromDecl(CXDecl) { - return 0; + return CXCursor(); } CXEntity clang_getEntityFromDecl(CXDecl) { return 0; } -enum CXDeclKind clang_getDeclKind(CXDecl) -{ - return CXDecl_any; -} -const char *clang_getDeclSpelling(CXDecl) -{ - return ""; +const char *clang_getDeclSpelling(CXDecl AnonDecl) +{ + assert(AnonDecl && "Passed null CXDecl"); + NamedDecl *ND = static_cast(AnonDecl); + if (ND->getIdentifier()) + return ND->getIdentifier()->getName(); + else + return ""; +} +const char *clang_getKindSpelling(enum CXCursorKind Kind) +{ + switch (Kind) { + case CXCursor_FunctionDecl: return "FunctionDecl"; + case CXCursor_TypedefDecl: return "TypedefDecl"; + case CXCursor_EnumDecl: return "EnumDecl"; + case CXCursor_EnumConstantDecl: return "EnumConstantDecl"; + case CXCursor_RecordDecl: return "RecordDecl"; + case CXCursor_FieldDecl: return "FieldDecl"; + case CXCursor_VarDecl: return "VarDecl"; + case CXCursor_ParmDecl: return "ParmDecl"; + case CXCursor_ObjCInterfaceDecl: return "ObjCInterfaceDecl"; + case CXCursor_ObjCCategoryDecl: return "ObjCCategoryDecl"; + case CXCursor_ObjCProtocolDecl: return "ObjCProtocolDecl"; + case CXCursor_ObjCPropertyDecl: return "ObjCPropertyDecl"; + case CXCursor_ObjCIvarDecl: return "ObjCIvarDecl"; + case CXCursor_ObjCMethodDecl: return "ObjCMethodDecl"; + default: return ""; + } } + // // CXCursor Operations. // CXCursor clang_getCursor(CXTranslationUnit, const char *source_name, unsigned line, unsigned column) { - return 0; + return CXCursor(); } CXCursorKind clang_getCursorKind(CXCursor) { - return CXCursor_Declaration; + return CXCursor_Invalid; } +unsigned clang_isDeclaration(enum CXCursorKind K) +{ + return K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl; +} unsigned clang_getCursorLine(CXCursor) { return 0; diff --git a/tools/CIndex/CIndex.exports b/tools/CIndex/CIndex.exports index 41b67a2467..ac18cc8e32 100644 --- a/tools/CIndex/CIndex.exports +++ b/tools/CIndex/CIndex.exports @@ -7,7 +7,6 @@ _clang_getCursorKind _clang_getCursorLine _clang_getCursorSource _clang_getDeclarationName -_clang_getDeclKind _clang_getDeclSpelling _clang_getEntity _clang_getEntityFromDecl @@ -15,3 +14,5 @@ _clang_getURI _clang_loadDeclaration _clang_loadTranslationUnit _clang_createTranslationUnit +_clang_isDeclaration +_clang_getKindSpelling diff --git a/tools/c-index-test/c-index-test.c b/tools/c-index-test/c-index-test.c index 71bdcc5c64..3126b319ef 100644 --- a/tools/c-index-test/c-index-test.c +++ b/tools/c-index-test/c-index-test.c @@ -1,5 +1,12 @@ #include "clang-c/Index.h" +#include + +static void PrintDecls(CXTranslationUnit Unit, CXCursor Cursor) { + if (clang_isDeclaration(Cursor.kind)) + printf("%s => %s\n", clang_getKindSpelling(Cursor.kind), + clang_getDeclSpelling(Cursor.decl)); +} /* * First sign of life:-) @@ -7,6 +14,6 @@ int main(int argc, char **argv) { CXIndex Idx = clang_createIndex(); CXTranslationUnit TU = clang_createTranslationUnit(Idx, argv[1]); - clang_loadTranslationUnit(TU, 0); + clang_loadTranslationUnit(TU, PrintDecls); return 1; }