c-index-test.c revision 4ade6d6eae934f796ca43c81a5aa185e456dde9b
1/* c-index-test.c */
2
3#include "clang-c/Index.h"
4#include <stdio.h>
5#include <string.h>
6
7static void PrintCursor(CXCursor Cursor) {
8  if (clang_isInvalid(Cursor.kind))
9    printf("Invalid Cursor => %s\n", clang_getCursorKindSpelling(Cursor.kind));
10  else
11    printf("%s => %s ", clang_getCursorKindSpelling(Cursor.kind),
12                        clang_getCursorSpelling(Cursor));
13}
14
15static void DeclVisitor(CXDecl Dcl, CXCursor Cursor, CXClientData Filter)
16{
17  if (!Filter || (Cursor.kind == *(enum CXCursorKind *)Filter)) {
18    PrintCursor(Cursor);
19    printf("(Context: %s", clang_getDeclSpelling(Dcl));
20    printf(" Source:  %s (%d:%d))\n", clang_getCursorSource(Cursor),
21                                      clang_getCursorLine(Cursor),
22                                      clang_getCursorColumn(Cursor));
23  }
24}
25static void TranslationUnitVisitor(CXTranslationUnit Unit, CXCursor Cursor,
26                                   CXClientData Filter)
27{
28  if (!Filter || (Cursor.kind == *(enum CXCursorKind *)Filter)) {
29    PrintCursor(Cursor);
30    printf("(Context: %s", clang_getTranslationUnitSpelling(Unit));
31    printf(" Source:  %s (%d:%d))\n", clang_getCursorSource(Cursor),
32                                      clang_getCursorLine(Cursor),
33                                      clang_getCursorColumn(Cursor));
34
35    if (Cursor.kind == CXCursor_FunctionDefn) {
36      const char *startBuf, *endBuf;
37      unsigned startLine, startColumn, endLine, endColumn;
38      clang_getDefinitionSpellingAndExtent(Cursor, &startBuf, &endBuf,
39                                           &startLine, &startColumn,
40                                           &endLine, &endColumn);
41      /* Probe the entire body, looking for "refs". */
42      unsigned curLine = startLine, curColumn = startColumn;
43      while (startBuf <= endBuf) {
44        if (*startBuf == '\n') {
45          startBuf++;
46          curLine++;
47          curColumn = 1;
48        }
49        CXCursor Ref = clang_getCursor(Unit, clang_getCursorSource(Cursor),
50                                       curLine, curColumn);
51        if (Ref.kind != CXCursor_FunctionDecl) {
52          PrintCursor(Ref);
53          printf("(Context: %s", clang_getDeclSpelling(Ref.decl));
54          printf(" Source:  %s (%d:%d))\n", clang_getCursorSource(Ref),
55                                            curLine, curColumn);
56        }
57        startBuf++;
58        curColumn++;
59      }
60    }
61    clang_loadDeclaration(Cursor.decl, DeclVisitor, 0);
62  }
63}
64
65/*
66 * First sign of life:-)
67 */
68int main(int argc, char **argv) {
69  CXIndex Idx = clang_createIndex();
70  CXTranslationUnit TU = clang_createTranslationUnit(Idx, argv[1]);
71
72  if (argc == 2) {
73    /* malloc - returns a cursor of type CXCursor_FunctionDecl */
74    CXCursor C = clang_getCursor(TU, "/usr/include/stdlib.h", 169, 7);
75    PrintCursor(C);
76    /* methodSignature - returns a cursor of type ObjCInstanceMethodDecl */
77    C = clang_getCursor(TU, "/System/Library/Frameworks/Foundation.framework/Headers/NSInvocation.h", 22, 1);
78    PrintCursor(C);
79    C = clang_getCursor(TU, "Large.m", 5, 18);
80    PrintCursor(C);
81  } else if (argc == 3) {
82    enum CXCursorKind K = CXCursor_NotImplemented;
83
84    if (!strcmp(argv[2], "all")) {
85      clang_loadTranslationUnit(TU, TranslationUnitVisitor, 0);
86      return 1;
87    }
88    if (!strcmp(argv[2], "category")) K = CXCursor_ObjCCategoryDecl;
89    else if (!strcmp(argv[2], "interface")) K = CXCursor_ObjCInterfaceDecl;
90    else if (!strcmp(argv[2], "protocol")) K = CXCursor_ObjCProtocolDecl;
91    else if (!strcmp(argv[2], "function")) K = CXCursor_FunctionDecl;
92    else if (!strcmp(argv[2], "typedef")) K = CXCursor_TypedefDecl;
93
94    clang_loadTranslationUnit(TU, TranslationUnitVisitor, &K);
95  }
96  return 1;
97}
98