I am currently writing a simple clone detector using libclang with C++.
The program stores cursors using a struct, containing a pointer to the translation unit and the CXSourceLocation gained from calling clang_getCursorLocation(cursor).
typedef struct {
CXTranslationUnit* tu;
CXSourceLocation srcLoc;
} t_cursorLocation;
For the sake of this error, the child visitor function visits each node and creates a struct from each cursor. With a struct of type t_cursorLocation, I wrote this function to retrieve the corresponding cursor:
CXCursor getCursor(t_cursorLocation *loc1) {
return clang_getCursor(*loc1->tu, loc1->srcLoc);
}
However, with some cursors, when I create the t_cursorLocation struct and use it to retrieve the cursor from which is was created, the retrieved cursor does not equal the cursor from which it originated. As an example, see the child visitor function:
CXChildVisitResult traverseAST(CXCursor cursor, CXCursor parent,
CXClientData client_data) {
CXTranslationUnit tu = clang_Cursor_getTranslationUnit(cursor);
CXTranslationUnit tu2 = *((CXTranslationUnit *) client_data);
t_cursorLocation *loc = new t_cursorLocation();
loc->tu = &tu;
loc->srcLoc = clang_getCursorLocation(cursor);
CXCursor c2 = getCursor(loc);
printf("CursorKind\t%s\n",
clang_getCString(clang_getCursorKindSpelling(cursor.kind)));
if (clang_equalCursors(cursor, c2)) {
printf("Noooo - the cursors do not match! Next test.....");
// use translation unit passed as client_data to see if
// there's a difference
loc->tu = &tu2;
c2 = getCursor(loc);
if (clang_equalCursors(cursor, c2)) {
printf("FAILED ALSO!\n");
} else {
printf("PASSED???\n");
}
} else {
printf("We have a match!\n");
}
return CXChildVisit_Recurse;
}
My main function is as follows:
int main(int argc, char **argv) {
CXIndex index = clang_createIndex(0, 0);
// initialise the translation unit
CXTranslationUnit tu = clang_parseTranslationUnit(index, 0,
argv, argc, 0, 0, CXTranslationUnit_None);
// set the client data in traverseAST
CXClientData data = &tu;// NULL;
// get the root cursor for the translation unit
CXCursor rootCursor = clang_getTranslationUnitCursor(tu);
clang_visitChildren(rootCursor, traverseAST, data);
clang_disposeTranslationUnit(tu);
clang_disposeIndex(index);
return 0;
}
The dummy source code I ran this on is as follows:
void goo() {
// nothing here
}
void foo() {
// do something
int a;
switch (a) {
case 0:
goo();
};
}
However the output is consistent, which suggests that this only happens with certain cursor kinds.
Is this a bug or is there something I am missing or doing wrong?
Thanks in advance, Jacob