c-index-test.c revision 85e2db72137c28114d3981c044946a8c16ef6011
12b8ee6c2994f738e5162ff46b638974870f51662Steve Naroff/* c-index-test.c */
250398199fb10e196a8d92fbf7a062dbe42ed88fdSteve Naroff
350398199fb10e196a8d92fbf7a062dbe42ed88fdSteve Naroff#include "clang-c/Index.h"
489922f86f4e7da383af2a62ef04ad8b93b941220Steve Naroff#include <stdio.h>
5af08ddc8f1c53fed8d8d0ad82aa2a0bb7d654bd1Steve Naroff#include <string.h>
6af08ddc8f1c53fed8d8d0ad82aa2a0bb7d654bd1Steve Naroff
7ff9e18cb3863defa98257500ef49d93a9d2bc216Steve Naroffextern char *basename(const char *);
8ff9e18cb3863defa98257500ef49d93a9d2bc216Steve Naroff
9af08ddc8f1c53fed8d8d0ad82aa2a0bb7d654bd1Steve Naroffstatic void PrintCursor(CXCursor Cursor) {
1077128ddd3077fc045751a55bb3226802b15d5510Steve Naroff  if (clang_isInvalid(Cursor.kind))
1177128ddd3077fc045751a55bb3226802b15d5510Steve Naroff    printf("Invalid Cursor => %s\n", clang_getCursorKindSpelling(Cursor.kind));
12699a07d8a0b1579c5178b3baf4bcf9edb6b38108Steve Naroff  else {
13ff9e18cb3863defa98257500ef49d93a9d2bc216Steve Naroff    printf("%s=%s", clang_getCursorKindSpelling(Cursor.kind),
14ff9e18cb3863defa98257500ef49d93a9d2bc216Steve Naroff                      clang_getCursorSpelling(Cursor));
1585e2db72137c28114d3981c044946a8c16ef6011Steve Naroff    CXDecl DeclReferenced = clang_getCursorDecl(Cursor);
1685e2db72137c28114d3981c044946a8c16ef6011Steve Naroff    if (DeclReferenced)
1785e2db72137c28114d3981c044946a8c16ef6011Steve Naroff      printf(":%d:%d", clang_getDeclLine(DeclReferenced),
1885e2db72137c28114d3981c044946a8c16ef6011Steve Naroff                       clang_getDeclColumn(DeclReferenced));
19699a07d8a0b1579c5178b3baf4bcf9edb6b38108Steve Naroff  }
20af08ddc8f1c53fed8d8d0ad82aa2a0bb7d654bd1Steve Naroff}
2189922f86f4e7da383af2a62ef04ad8b93b941220Steve Naroff
22c857ea4d22e1e6dd9ede1f0e84d48b157c6924fdSteve Naroffstatic void DeclVisitor(CXDecl Dcl, CXCursor Cursor, CXClientData Filter)
23c857ea4d22e1e6dd9ede1f0e84d48b157c6924fdSteve Naroff{
24bce6f62ae7d2c15992617f64e30067803fb5b47fDaniel Dunbar  if (!Filter || (Cursor.kind == *(enum CXCursorKind *)Filter)) {
25ff9e18cb3863defa98257500ef49d93a9d2bc216Steve Naroff    printf("// CHECK: %s:%d:%d: ", basename(clang_getCursorSource(Cursor)),
26ff9e18cb3863defa98257500ef49d93a9d2bc216Steve Naroff                                 clang_getCursorLine(Cursor),
27ff9e18cb3863defa98257500ef49d93a9d2bc216Steve Naroff                                 clang_getCursorColumn(Cursor));
28af08ddc8f1c53fed8d8d0ad82aa2a0bb7d654bd1Steve Naroff    PrintCursor(Cursor);
29ff9e18cb3863defa98257500ef49d93a9d2bc216Steve Naroff    printf(" [Context=%s]\n", clang_getDeclSpelling(Dcl));
30bce6f62ae7d2c15992617f64e30067803fb5b47fDaniel Dunbar  }
31c857ea4d22e1e6dd9ede1f0e84d48b157c6924fdSteve Naroff}
32c857ea4d22e1e6dd9ede1f0e84d48b157c6924fdSteve Naroffstatic void TranslationUnitVisitor(CXTranslationUnit Unit, CXCursor Cursor,
33c857ea4d22e1e6dd9ede1f0e84d48b157c6924fdSteve Naroff                                   CXClientData Filter)
34c857ea4d22e1e6dd9ede1f0e84d48b157c6924fdSteve Naroff{
35c857ea4d22e1e6dd9ede1f0e84d48b157c6924fdSteve Naroff  if (!Filter || (Cursor.kind == *(enum CXCursorKind *)Filter)) {
36ff9e18cb3863defa98257500ef49d93a9d2bc216Steve Naroff    printf("// CHECK: %s:%d:%d: ", basename(clang_getCursorSource(Cursor)),
37ff9e18cb3863defa98257500ef49d93a9d2bc216Steve Naroff                                 clang_getCursorLine(Cursor),
38ff9e18cb3863defa98257500ef49d93a9d2bc216Steve Naroff                                 clang_getCursorColumn(Cursor));
39af08ddc8f1c53fed8d8d0ad82aa2a0bb7d654bd1Steve Naroff    PrintCursor(Cursor);
40ff9e18cb3863defa98257500ef49d93a9d2bc216Steve Naroff    printf(" [Context=%s]\n", basename(clang_getTranslationUnitSpelling(Unit)));
41ff9e18cb3863defa98257500ef49d93a9d2bc216Steve Naroff
42ff9e18cb3863defa98257500ef49d93a9d2bc216Steve Naroff    clang_loadDeclaration(Cursor.decl, DeclVisitor, 0);
43c857ea4d22e1e6dd9ede1f0e84d48b157c6924fdSteve Naroff
444ade6d6eae934f796ca43c81a5aa185e456dde9bSteve Naroff    if (Cursor.kind == CXCursor_FunctionDefn) {
454ade6d6eae934f796ca43c81a5aa185e456dde9bSteve Naroff      const char *startBuf, *endBuf;
464ade6d6eae934f796ca43c81a5aa185e456dde9bSteve Naroff      unsigned startLine, startColumn, endLine, endColumn;
474ade6d6eae934f796ca43c81a5aa185e456dde9bSteve Naroff      clang_getDefinitionSpellingAndExtent(Cursor, &startBuf, &endBuf,
484ade6d6eae934f796ca43c81a5aa185e456dde9bSteve Naroff                                           &startLine, &startColumn,
494ade6d6eae934f796ca43c81a5aa185e456dde9bSteve Naroff                                           &endLine, &endColumn);
50f7469a38ca835681a64959d71c4792d93a7b1d00Steve Naroff      {
51f7469a38ca835681a64959d71c4792d93a7b1d00Steve Naroff        /* Probe the entire body, looking for both decls and refs. */
52f7469a38ca835681a64959d71c4792d93a7b1d00Steve Naroff        unsigned curLine = startLine, curColumn = startColumn;
53f7469a38ca835681a64959d71c4792d93a7b1d00Steve Naroff        CXCursor Ref;
54f7469a38ca835681a64959d71c4792d93a7b1d00Steve Naroff
55f7469a38ca835681a64959d71c4792d93a7b1d00Steve Naroff        while (startBuf <= endBuf) {
56f7469a38ca835681a64959d71c4792d93a7b1d00Steve Naroff          if (*startBuf == '\n') {
57f7469a38ca835681a64959d71c4792d93a7b1d00Steve Naroff            startBuf++;
58f7469a38ca835681a64959d71c4792d93a7b1d00Steve Naroff            curLine++;
59f7469a38ca835681a64959d71c4792d93a7b1d00Steve Naroff            curColumn = 1;
60f7469a38ca835681a64959d71c4792d93a7b1d00Steve Naroff          } else if (*startBuf != '\t')
61f7469a38ca835681a64959d71c4792d93a7b1d00Steve Naroff            curColumn++;
62f7469a38ca835681a64959d71c4792d93a7b1d00Steve Naroff
63f7469a38ca835681a64959d71c4792d93a7b1d00Steve Naroff          Ref = clang_getCursor(Unit, clang_getCursorSource(Cursor),
64f7469a38ca835681a64959d71c4792d93a7b1d00Steve Naroff                                curLine, curColumn);
65f7469a38ca835681a64959d71c4792d93a7b1d00Steve Naroff          if (Ref.kind != CXCursor_FunctionDecl) {
66ff9e18cb3863defa98257500ef49d93a9d2bc216Steve Naroff            printf("// CHECK: %s:%d:%d: ", basename(clang_getCursorSource(Ref)),
67ff9e18cb3863defa98257500ef49d93a9d2bc216Steve Naroff                                             curLine, curColumn);
68f7469a38ca835681a64959d71c4792d93a7b1d00Steve Naroff            PrintCursor(Ref);
69ff9e18cb3863defa98257500ef49d93a9d2bc216Steve Naroff            printf(" [Context:%s]\n", clang_getDeclSpelling(Ref.decl));
70f7469a38ca835681a64959d71c4792d93a7b1d00Steve Naroff          }
714ade6d6eae934f796ca43c81a5aa185e456dde9bSteve Naroff          startBuf++;
724ade6d6eae934f796ca43c81a5aa185e456dde9bSteve Naroff        }
734ade6d6eae934f796ca43c81a5aa185e456dde9bSteve Naroff      }
744ade6d6eae934f796ca43c81a5aa185e456dde9bSteve Naroff    }
752d4d629d8a0de5112c7ae9d05c03ddbf6dcd956aSteve Naroff  }
7689922f86f4e7da383af2a62ef04ad8b93b941220Steve Naroff}
7750398199fb10e196a8d92fbf7a062dbe42ed88fdSteve Naroff
7850398199fb10e196a8d92fbf7a062dbe42ed88fdSteve Naroff/*
7950398199fb10e196a8d92fbf7a062dbe42ed88fdSteve Naroff * First sign of life:-)
8050398199fb10e196a8d92fbf7a062dbe42ed88fdSteve Naroff */
8150398199fb10e196a8d92fbf7a062dbe42ed88fdSteve Naroffint main(int argc, char **argv) {
82f7469a38ca835681a64959d71c4792d93a7b1d00Steve Naroff  if (argc != 3) {
83f7469a38ca835681a64959d71c4792d93a7b1d00Steve Naroff    printf("Incorrect usage of c-index-test (requires 3 arguments)\n");
84f7469a38ca835681a64959d71c4792d93a7b1d00Steve Naroff    return 0;
85f7469a38ca835681a64959d71c4792d93a7b1d00Steve Naroff  }
86f7469a38ca835681a64959d71c4792d93a7b1d00Steve Naroff  {
8750398199fb10e196a8d92fbf7a062dbe42ed88fdSteve Naroff  CXIndex Idx = clang_createIndex();
8850398199fb10e196a8d92fbf7a062dbe42ed88fdSteve Naroff  CXTranslationUnit TU = clang_createTranslationUnit(Idx, argv[1]);
89f7469a38ca835681a64959d71c4792d93a7b1d00Steve Naroff  enum CXCursorKind K = CXCursor_NotImplemented;
90f7469a38ca835681a64959d71c4792d93a7b1d00Steve Naroff
91f7469a38ca835681a64959d71c4792d93a7b1d00Steve Naroff  if (!strcmp(argv[2], "all")) {
92f7469a38ca835681a64959d71c4792d93a7b1d00Steve Naroff    clang_loadTranslationUnit(TU, TranslationUnitVisitor, 0);
93f7469a38ca835681a64959d71c4792d93a7b1d00Steve Naroff    return 1;
94f7469a38ca835681a64959d71c4792d93a7b1d00Steve Naroff  }
95f7469a38ca835681a64959d71c4792d93a7b1d00Steve Naroff  /* Perform some simple filtering. */
96f7469a38ca835681a64959d71c4792d93a7b1d00Steve Naroff  if (!strcmp(argv[2], "category")) K = CXCursor_ObjCCategoryDecl;
97f7469a38ca835681a64959d71c4792d93a7b1d00Steve Naroff  else if (!strcmp(argv[2], "interface")) K = CXCursor_ObjCInterfaceDecl;
98f7469a38ca835681a64959d71c4792d93a7b1d00Steve Naroff  else if (!strcmp(argv[2], "protocol")) K = CXCursor_ObjCProtocolDecl;
99f7469a38ca835681a64959d71c4792d93a7b1d00Steve Naroff  else if (!strcmp(argv[2], "function")) K = CXCursor_FunctionDecl;
100f7469a38ca835681a64959d71c4792d93a7b1d00Steve Naroff  else if (!strcmp(argv[2], "typedef")) K = CXCursor_TypedefDecl;
101f7469a38ca835681a64959d71c4792d93a7b1d00Steve Naroff
102f7469a38ca835681a64959d71c4792d93a7b1d00Steve Naroff  clang_loadTranslationUnit(TU, TranslationUnitVisitor, &K);
10350398199fb10e196a8d92fbf7a062dbe42ed88fdSteve Naroff  return 1;
104f7469a38ca835681a64959d71c4792d93a7b1d00Steve Naroff  }
10550398199fb10e196a8d92fbf7a062dbe42ed88fdSteve Naroff}
106