c-index-test.c revision fbcb2b716bee88c754684bd189913ed9f8c09086
1/* c-index-test.c */ 2 3#include "clang-c/Index.h" 4#include <stdio.h> 5#include <string.h> 6 7extern char *basename(const char *); 8 9static void PrintCursor(CXCursor Cursor) { 10 if (clang_isInvalid(Cursor.kind)) 11 printf("Invalid Cursor => %s\n", clang_getCursorKindSpelling(Cursor.kind)); 12 else { 13 CXDecl DeclReferenced; 14 printf("%s=%s", clang_getCursorKindSpelling(Cursor.kind), 15 clang_getCursorSpelling(Cursor)); 16 DeclReferenced = clang_getCursorDecl(Cursor); 17 if (DeclReferenced) 18 printf(":%d:%d", clang_getDeclLine(DeclReferenced), 19 clang_getDeclColumn(DeclReferenced)); 20 } 21} 22 23static void DeclVisitor(CXDecl Dcl, CXCursor Cursor, CXClientData Filter) 24{ 25 if (!Filter || (Cursor.kind == *(enum CXCursorKind *)Filter)) { 26 printf("// CHECK: %s:%d:%d: ", basename(clang_getCursorSource(Cursor)), 27 clang_getCursorLine(Cursor), 28 clang_getCursorColumn(Cursor)); 29 PrintCursor(Cursor); 30 printf(" [Context=%s]\n", clang_getDeclSpelling(Dcl)); 31 } 32} 33static void TranslationUnitVisitor(CXTranslationUnit Unit, CXCursor Cursor, 34 CXClientData Filter) 35{ 36 if (!Filter || (Cursor.kind == *(enum CXCursorKind *)Filter)) { 37 printf("// CHECK: %s:%d:%d: ", basename(clang_getCursorSource(Cursor)), 38 clang_getCursorLine(Cursor), 39 clang_getCursorColumn(Cursor)); 40 PrintCursor(Cursor); 41 printf(" [Context=%s]\n", basename(clang_getTranslationUnitSpelling(Unit))); 42 43 clang_loadDeclaration(Cursor.decl, DeclVisitor, 0); 44 45 if (Cursor.kind == CXCursor_FunctionDefn) { 46 const char *startBuf, *endBuf; 47 unsigned startLine, startColumn, endLine, endColumn; 48 clang_getDefinitionSpellingAndExtent(Cursor, &startBuf, &endBuf, 49 &startLine, &startColumn, 50 &endLine, &endColumn); 51 { 52 /* Probe the entire body, looking for both decls and refs. */ 53 unsigned curLine = startLine, curColumn = startColumn; 54 CXCursor Ref; 55 56 while (startBuf < endBuf) { 57 if (*startBuf == '\n') { 58 startBuf++; 59 curLine++; 60 curColumn = 1; 61 } else if (*startBuf != '\t') 62 curColumn++; 63 64 CXLookupHint hint; 65 clang_initCXLookupHint(&hint); 66 hint.decl = Cursor.decl; 67 68 Ref = clang_getCursorWithHint(Unit, clang_getCursorSource(Cursor), 69 curLine, curColumn, &hint); 70 if (Ref.kind == CXCursor_NoDeclFound) { 71 /* Nothing found here; that's fine. */ 72 } else if (Ref.kind != CXCursor_FunctionDecl) { 73 printf("// CHECK: %s:%d:%d: ", basename(clang_getCursorSource(Ref)), 74 curLine, curColumn); 75 PrintCursor(Ref); 76 printf(" [Context:%s]\n", clang_getDeclSpelling(Ref.decl)); 77 } 78 startBuf++; 79 } 80 } 81 } 82 } 83} 84 85/* 86 * First sign of life:-) 87 */ 88int main(int argc, char **argv) { 89 if (argc != 3) { 90 printf("Incorrect usage of c-index-test (requires 3 arguments)\n"); 91 return 0; 92 } 93 { 94 CXIndex Idx; 95 CXTranslationUnit TU; 96 enum CXCursorKind K = CXCursor_NotImplemented; 97 98 Idx = clang_createIndex(/* excludeDeclsFromPCH */ !strcmp(argv[2], "local") ? 1 : 0, 99 /* displayDiagnostics */ 1); 100 101 TU = clang_createTranslationUnit(Idx, argv[1]); 102 103 if (!TU) { 104 fprintf(stderr, "Unable to load translation unit!\n"); 105 return 1; 106 } 107 108 if (!strcmp(argv[2], "all") || !strcmp(argv[2], "local")) { 109 clang_loadTranslationUnit(TU, TranslationUnitVisitor, 0); 110 clang_disposeTranslationUnit(TU); 111 return 1; 112 } 113 /* Perform some simple filtering. */ 114 if (!strcmp(argv[2], "category")) K = CXCursor_ObjCCategoryDecl; 115 else if (!strcmp(argv[2], "interface")) K = CXCursor_ObjCInterfaceDecl; 116 else if (!strcmp(argv[2], "protocol")) K = CXCursor_ObjCProtocolDecl; 117 else if (!strcmp(argv[2], "function")) K = CXCursor_FunctionDecl; 118 else if (!strcmp(argv[2], "typedef")) K = CXCursor_TypedefDecl; 119 120 clang_loadTranslationUnit(TU, TranslationUnitVisitor, &K); 121 clang_disposeTranslationUnit(TU); 122 return 1; 123 } 124} 125