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