c-index-test.c revision fbcb2b716bee88c754684bd189913ed9f8c09086
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 {
13f393c3b770c86446b20e6fd4bcf08a31442d1b1dEric Christopher    CXDecl DeclReferenced;
14ff9e18cb3863defa98257500ef49d93a9d2bc216Steve Naroff    printf("%s=%s", clang_getCursorKindSpelling(Cursor.kind),
15ff9e18cb3863defa98257500ef49d93a9d2bc216Steve Naroff                      clang_getCursorSpelling(Cursor));
16f393c3b770c86446b20e6fd4bcf08a31442d1b1dEric Christopher    DeclReferenced = clang_getCursorDecl(Cursor);
1785e2db72137c28114d3981c044946a8c16ef6011Steve Naroff    if (DeclReferenced)
1885e2db72137c28114d3981c044946a8c16ef6011Steve Naroff      printf(":%d:%d", clang_getDeclLine(DeclReferenced),
1985e2db72137c28114d3981c044946a8c16ef6011Steve Naroff                       clang_getDeclColumn(DeclReferenced));
20699a07d8a0b1579c5178b3baf4bcf9edb6b38108Steve Naroff  }
21af08ddc8f1c53fed8d8d0ad82aa2a0bb7d654bd1Steve Naroff}
2289922f86f4e7da383af2a62ef04ad8b93b941220Steve Naroff
23f393c3b770c86446b20e6fd4bcf08a31442d1b1dEric Christopherstatic void DeclVisitor(CXDecl Dcl, CXCursor Cursor, CXClientData Filter)
24c857ea4d22e1e6dd9ede1f0e84d48b157c6924fdSteve Naroff{
25bce6f62ae7d2c15992617f64e30067803fb5b47fDaniel Dunbar  if (!Filter || (Cursor.kind == *(enum CXCursorKind *)Filter)) {
26ff9e18cb3863defa98257500ef49d93a9d2bc216Steve Naroff    printf("// CHECK: %s:%d:%d: ", basename(clang_getCursorSource(Cursor)),
27ff9e18cb3863defa98257500ef49d93a9d2bc216Steve Naroff                                 clang_getCursorLine(Cursor),
28ff9e18cb3863defa98257500ef49d93a9d2bc216Steve Naroff                                 clang_getCursorColumn(Cursor));
29af08ddc8f1c53fed8d8d0ad82aa2a0bb7d654bd1Steve Naroff    PrintCursor(Cursor);
30ff9e18cb3863defa98257500ef49d93a9d2bc216Steve Naroff    printf(" [Context=%s]\n", clang_getDeclSpelling(Dcl));
31bce6f62ae7d2c15992617f64e30067803fb5b47fDaniel Dunbar  }
32c857ea4d22e1e6dd9ede1f0e84d48b157c6924fdSteve Naroff}
33c857ea4d22e1e6dd9ede1f0e84d48b157c6924fdSteve Naroffstatic void TranslationUnitVisitor(CXTranslationUnit Unit, CXCursor Cursor,
34f393c3b770c86446b20e6fd4bcf08a31442d1b1dEric Christopher                                   CXClientData Filter)
35c857ea4d22e1e6dd9ede1f0e84d48b157c6924fdSteve Naroff{
36c857ea4d22e1e6dd9ede1f0e84d48b157c6924fdSteve Naroff  if (!Filter || (Cursor.kind == *(enum CXCursorKind *)Filter)) {
37ff9e18cb3863defa98257500ef49d93a9d2bc216Steve Naroff    printf("// CHECK: %s:%d:%d: ", basename(clang_getCursorSource(Cursor)),
38ff9e18cb3863defa98257500ef49d93a9d2bc216Steve Naroff                                 clang_getCursorLine(Cursor),
39ff9e18cb3863defa98257500ef49d93a9d2bc216Steve Naroff                                 clang_getCursorColumn(Cursor));
40af08ddc8f1c53fed8d8d0ad82aa2a0bb7d654bd1Steve Naroff    PrintCursor(Cursor);
41ff9e18cb3863defa98257500ef49d93a9d2bc216Steve Naroff    printf(" [Context=%s]\n", basename(clang_getTranslationUnitSpelling(Unit)));
42ff9e18cb3863defa98257500ef49d93a9d2bc216Steve Naroff
43ff9e18cb3863defa98257500ef49d93a9d2bc216Steve Naroff    clang_loadDeclaration(Cursor.decl, DeclVisitor, 0);
44c857ea4d22e1e6dd9ede1f0e84d48b157c6924fdSteve Naroff
454ade6d6eae934f796ca43c81a5aa185e456dde9bSteve Naroff    if (Cursor.kind == CXCursor_FunctionDefn) {
464ade6d6eae934f796ca43c81a5aa185e456dde9bSteve Naroff      const char *startBuf, *endBuf;
474ade6d6eae934f796ca43c81a5aa185e456dde9bSteve Naroff      unsigned startLine, startColumn, endLine, endColumn;
484ade6d6eae934f796ca43c81a5aa185e456dde9bSteve Naroff      clang_getDefinitionSpellingAndExtent(Cursor, &startBuf, &endBuf,
494ade6d6eae934f796ca43c81a5aa185e456dde9bSteve Naroff                                           &startLine, &startColumn,
504ade6d6eae934f796ca43c81a5aa185e456dde9bSteve Naroff                                           &endLine, &endColumn);
51f7469a38ca835681a64959d71c4792d93a7b1d00Steve Naroff      {
52f7469a38ca835681a64959d71c4792d93a7b1d00Steve Naroff        /* Probe the entire body, looking for both decls and refs. */
53f7469a38ca835681a64959d71c4792d93a7b1d00Steve Naroff        unsigned curLine = startLine, curColumn = startColumn;
54f7469a38ca835681a64959d71c4792d93a7b1d00Steve Naroff        CXCursor Ref;
55f393c3b770c86446b20e6fd4bcf08a31442d1b1dEric Christopher
566a6de8b4fc944ca1bfa4e47c516d049a0d627b0eSteve Naroff        while (startBuf < endBuf) {
57f7469a38ca835681a64959d71c4792d93a7b1d00Steve Naroff          if (*startBuf == '\n') {
58f7469a38ca835681a64959d71c4792d93a7b1d00Steve Naroff            startBuf++;
59f7469a38ca835681a64959d71c4792d93a7b1d00Steve Naroff            curLine++;
60f7469a38ca835681a64959d71c4792d93a7b1d00Steve Naroff            curColumn = 1;
61f7469a38ca835681a64959d71c4792d93a7b1d00Steve Naroff          } else if (*startBuf != '\t')
62f7469a38ca835681a64959d71c4792d93a7b1d00Steve Naroff            curColumn++;
63fbcb2b716bee88c754684bd189913ed9f8c09086Ted Kremenek
64fbcb2b716bee88c754684bd189913ed9f8c09086Ted Kremenek          CXLookupHint hint;
65fbcb2b716bee88c754684bd189913ed9f8c09086Ted Kremenek          clang_initCXLookupHint(&hint);
66fbcb2b716bee88c754684bd189913ed9f8c09086Ted Kremenek          hint.decl = Cursor.decl;
67f393c3b770c86446b20e6fd4bcf08a31442d1b1dEric Christopher
68fbcb2b716bee88c754684bd189913ed9f8c09086Ted Kremenek          Ref = clang_getCursorWithHint(Unit, clang_getCursorSource(Cursor),
69fbcb2b716bee88c754684bd189913ed9f8c09086Ted Kremenek                                        curLine, curColumn, &hint);
7002465750c8c3fa96b1e7e596b02297e24361dc4fDouglas Gregor          if (Ref.kind == CXCursor_NoDeclFound) {
718ce88a449c4ae09af2108f5c1203caa37145817dTed Kremenek            /* Nothing found here; that's fine. */
7202465750c8c3fa96b1e7e596b02297e24361dc4fDouglas Gregor          } else if (Ref.kind != CXCursor_FunctionDecl) {
73ff9e18cb3863defa98257500ef49d93a9d2bc216Steve Naroff            printf("// CHECK: %s:%d:%d: ", basename(clang_getCursorSource(Ref)),
74ff9e18cb3863defa98257500ef49d93a9d2bc216Steve Naroff                                             curLine, curColumn);
75f7469a38ca835681a64959d71c4792d93a7b1d00Steve Naroff            PrintCursor(Ref);
76ff9e18cb3863defa98257500ef49d93a9d2bc216Steve Naroff            printf(" [Context:%s]\n", clang_getDeclSpelling(Ref.decl));
77f7469a38ca835681a64959d71c4792d93a7b1d00Steve Naroff          }
784ade6d6eae934f796ca43c81a5aa185e456dde9bSteve Naroff          startBuf++;
794ade6d6eae934f796ca43c81a5aa185e456dde9bSteve Naroff        }
804ade6d6eae934f796ca43c81a5aa185e456dde9bSteve Naroff      }
814ade6d6eae934f796ca43c81a5aa185e456dde9bSteve Naroff    }
822d4d629d8a0de5112c7ae9d05c03ddbf6dcd956aSteve Naroff  }
8389922f86f4e7da383af2a62ef04ad8b93b941220Steve Naroff}
8450398199fb10e196a8d92fbf7a062dbe42ed88fdSteve Naroff
8550398199fb10e196a8d92fbf7a062dbe42ed88fdSteve Naroff/*
8650398199fb10e196a8d92fbf7a062dbe42ed88fdSteve Naroff * First sign of life:-)
8750398199fb10e196a8d92fbf7a062dbe42ed88fdSteve Naroff */
8850398199fb10e196a8d92fbf7a062dbe42ed88fdSteve Naroffint main(int argc, char **argv) {
89f7469a38ca835681a64959d71c4792d93a7b1d00Steve Naroff  if (argc != 3) {
90f7469a38ca835681a64959d71c4792d93a7b1d00Steve Naroff    printf("Incorrect usage of c-index-test (requires 3 arguments)\n");
91f7469a38ca835681a64959d71c4792d93a7b1d00Steve Naroff    return 0;
92f7469a38ca835681a64959d71c4792d93a7b1d00Steve Naroff  }
93f7469a38ca835681a64959d71c4792d93a7b1d00Steve Naroff  {
9485f5468d87c2e767ee632c16d01c7d9e31a1fcbdTed Kremenek  CXIndex Idx;
9585f5468d87c2e767ee632c16d01c7d9e31a1fcbdTed Kremenek  CXTranslationUnit TU;
9685f5468d87c2e767ee632c16d01c7d9e31a1fcbdTed Kremenek  enum CXCursorKind K = CXCursor_NotImplemented;
9785f5468d87c2e767ee632c16d01c7d9e31a1fcbdTed Kremenek
98e56b4baeba5097852e04bc41ca2e0396cf729955Steve Naroff  Idx = clang_createIndex(/* excludeDeclsFromPCH */ !strcmp(argv[2], "local") ? 1 : 0,
99e56b4baeba5097852e04bc41ca2e0396cf729955Steve Naroff                          /* displayDiagnostics */ 1);
10085f5468d87c2e767ee632c16d01c7d9e31a1fcbdTed Kremenek
101e56b4baeba5097852e04bc41ca2e0396cf729955Steve Naroff  TU = clang_createTranslationUnit(Idx, argv[1]);
10285f5468d87c2e767ee632c16d01c7d9e31a1fcbdTed Kremenek
1037d1d49d2971b20a97b3c2a301470b9eaaa130137Douglas Gregor  if (!TU) {
1047d1d49d2971b20a97b3c2a301470b9eaaa130137Douglas Gregor    fprintf(stderr, "Unable to load translation unit!\n");
1057d1d49d2971b20a97b3c2a301470b9eaaa130137Douglas Gregor    return 1;
1067d1d49d2971b20a97b3c2a301470b9eaaa130137Douglas Gregor  }
107f393c3b770c86446b20e6fd4bcf08a31442d1b1dEric Christopher
1087d1d49d2971b20a97b3c2a301470b9eaaa130137Douglas Gregor  if (!strcmp(argv[2], "all") || !strcmp(argv[2], "local")) {
109f7469a38ca835681a64959d71c4792d93a7b1d00Steve Naroff    clang_loadTranslationUnit(TU, TranslationUnitVisitor, 0);
110e19944c93961b7618f4f3f3185f698f46369ea54Steve Naroff    clang_disposeTranslationUnit(TU);
111f7469a38ca835681a64959d71c4792d93a7b1d00Steve Naroff    return 1;
112f393c3b770c86446b20e6fd4bcf08a31442d1b1dEric Christopher  }
113f7469a38ca835681a64959d71c4792d93a7b1d00Steve Naroff  /* Perform some simple filtering. */
114f7469a38ca835681a64959d71c4792d93a7b1d00Steve Naroff  if (!strcmp(argv[2], "category")) K = CXCursor_ObjCCategoryDecl;
115f7469a38ca835681a64959d71c4792d93a7b1d00Steve Naroff  else if (!strcmp(argv[2], "interface")) K = CXCursor_ObjCInterfaceDecl;
116f7469a38ca835681a64959d71c4792d93a7b1d00Steve Naroff  else if (!strcmp(argv[2], "protocol")) K = CXCursor_ObjCProtocolDecl;
117f7469a38ca835681a64959d71c4792d93a7b1d00Steve Naroff  else if (!strcmp(argv[2], "function")) K = CXCursor_FunctionDecl;
118f7469a38ca835681a64959d71c4792d93a7b1d00Steve Naroff  else if (!strcmp(argv[2], "typedef")) K = CXCursor_TypedefDecl;
119f393c3b770c86446b20e6fd4bcf08a31442d1b1dEric Christopher
120f7469a38ca835681a64959d71c4792d93a7b1d00Steve Naroff  clang_loadTranslationUnit(TU, TranslationUnitVisitor, &K);
121e19944c93961b7618f4f3f3185f698f46369ea54Steve Naroff  clang_disposeTranslationUnit(TU);
12250398199fb10e196a8d92fbf7a062dbe42ed88fdSteve Naroff  return 1;
123f7469a38ca835681a64959d71c4792d93a7b1d00Steve Naroff  }
12450398199fb10e196a8d92fbf7a062dbe42ed88fdSteve Naroff}
125