| /* c-index-test.c */ |
| |
| #include "clang-c/Index.h" |
| #include <stdio.h> |
| #include <string.h> |
| |
| extern char *basename(const char *); |
| |
| static void PrintCursor(CXCursor Cursor) { |
| if (clang_isInvalid(Cursor.kind)) |
| printf("Invalid Cursor => %s\n", clang_getCursorKindSpelling(Cursor.kind)); |
| else { |
| CXDecl DeclReferenced; |
| printf("%s=%s", clang_getCursorKindSpelling(Cursor.kind), |
| clang_getCursorSpelling(Cursor)); |
| DeclReferenced = clang_getCursorDecl(Cursor); |
| if (DeclReferenced) |
| printf(":%d:%d", clang_getDeclLine(DeclReferenced), |
| clang_getDeclColumn(DeclReferenced)); |
| } |
| } |
| |
| static void DeclVisitor(CXDecl Dcl, CXCursor Cursor, CXClientData Filter) |
| { |
| if (!Filter || (Cursor.kind == *(enum CXCursorKind *)Filter)) { |
| printf("// CHECK: %s:%d:%d: ", basename(clang_getCursorSource(Cursor)), |
| clang_getCursorLine(Cursor), |
| clang_getCursorColumn(Cursor)); |
| PrintCursor(Cursor); |
| printf(" [Context=%s]\n", clang_getDeclSpelling(Dcl)); |
| } |
| } |
| static void TranslationUnitVisitor(CXTranslationUnit Unit, CXCursor Cursor, |
| CXClientData Filter) |
| { |
| if (!Filter || (Cursor.kind == *(enum CXCursorKind *)Filter)) { |
| printf("// CHECK: %s:%d:%d: ", basename(clang_getCursorSource(Cursor)), |
| clang_getCursorLine(Cursor), |
| clang_getCursorColumn(Cursor)); |
| PrintCursor(Cursor); |
| printf(" [Context=%s]\n", basename(clang_getTranslationUnitSpelling(Unit))); |
| |
| clang_loadDeclaration(Cursor.decl, DeclVisitor, 0); |
| |
| if (Cursor.kind == CXCursor_FunctionDefn) { |
| const char *startBuf, *endBuf; |
| unsigned startLine, startColumn, endLine, endColumn; |
| clang_getDefinitionSpellingAndExtent(Cursor, &startBuf, &endBuf, |
| &startLine, &startColumn, |
| &endLine, &endColumn); |
| { |
| /* Probe the entire body, looking for both decls and refs. */ |
| unsigned curLine = startLine, curColumn = startColumn; |
| CXCursor Ref; |
| |
| while (startBuf <= endBuf) { |
| if (*startBuf == '\n') { |
| startBuf++; |
| curLine++; |
| curColumn = 1; |
| } else if (*startBuf != '\t') |
| curColumn++; |
| |
| Ref = clang_getCursor(Unit, clang_getCursorSource(Cursor), |
| curLine, curColumn); |
| if (Ref.kind != CXCursor_FunctionDecl) { |
| printf("// CHECK: %s:%d:%d: ", basename(clang_getCursorSource(Ref)), |
| curLine, curColumn); |
| PrintCursor(Ref); |
| printf(" [Context:%s]\n", clang_getDeclSpelling(Ref.decl)); |
| } |
| startBuf++; |
| } |
| } |
| } |
| } |
| } |
| |
| /* |
| * First sign of life:-) |
| */ |
| int main(int argc, char **argv) { |
| if (argc != 3) { |
| printf("Incorrect usage of c-index-test (requires 3 arguments)\n"); |
| return 0; |
| } |
| { |
| CXIndex Idx = clang_createIndex(); |
| CXTranslationUnit TU = clang_createTranslationUnit(Idx, argv[1]); |
| enum CXCursorKind K = CXCursor_NotImplemented; |
| |
| if (!strcmp(argv[2], "all")) { |
| clang_loadTranslationUnit(TU, TranslationUnitVisitor, 0); |
| clang_disposeTranslationUnit(TU); |
| return 1; |
| } |
| /* Perform some simple filtering. */ |
| if (!strcmp(argv[2], "category")) K = CXCursor_ObjCCategoryDecl; |
| else if (!strcmp(argv[2], "interface")) K = CXCursor_ObjCInterfaceDecl; |
| else if (!strcmp(argv[2], "protocol")) K = CXCursor_ObjCProtocolDecl; |
| else if (!strcmp(argv[2], "function")) K = CXCursor_FunctionDecl; |
| else if (!strcmp(argv[2], "typedef")) K = CXCursor_TypedefDecl; |
| |
| clang_loadTranslationUnit(TU, TranslationUnitVisitor, &K); |
| clang_disposeTranslationUnit(TU); |
| return 1; |
| } |
| } |