Clang — C ++ libclang: получение курсора из CXSourceLocation, возвращение неправильного курсора?

В настоящее время я пишу простой детектор клонов, используя libclang с C ++.

Программа хранит курсоры, используя структуру, содержащую указатель на модуль перевода и CXSourceLocation, полученные при вызове clang_getCursorLocation (курсора).

typedef struct {
CXTranslationUnit* tu;
CXSourceLocation srcLoc;
} t_cursorLocation;

Ради этой ошибки дочерняя функция посетителя посещает каждый узел и создает структуру из каждого курсора. Со структурой типа t_cursorLocation я написал эту функцию для получения соответствующего курсора:

CXCursor getCursor(t_cursorLocation *loc1) {
return clang_getCursor(*loc1->tu, loc1->srcLoc);
}

Однако в некоторых курсорах, когда я создаю структуру t_cursorLocation и использую ее для извлечения курсора, из которого он был создан, извлеченный курсор не равен курсору, из которого он возник. В качестве примера посмотрите функцию дочернего посетителя:

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;
}

Моя основная функция заключается в следующем:

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;
}

Исходный код, на котором я работал, выглядит следующим образом:

void goo() {
// nothing here
}

void foo() {
// do something
int a;
switch (a) {
case 0:
goo();
};
}

Однако выходные данные согласуются, что говорит о том, что это происходит только с определенными типами курсоров.

Это ошибка или я что-то упускаю или делаю неправильно?

Заранее спасибо,
Иаков

4

Решение

Либо я полностью упускаю вашу точку зрения, либо вы используете clang_equalCursors неправильный путь: когда оба курсора равны, clang_equalCursors возвращает ненулевое значение. Это означает, что я думаю, что вы проверяете неравенства курсоров вместо равенств.

Теперь позвольте мне объяснить, почему некоторые курсоры ведут себя иначе, чем другие. Каждый курсор имеет только одну исходную позицию. Однако в одном и том же месте источника может быть несколько курсоров. Подумайте, например, о следующей строке:

CXIndex index = clang_createIndex(0, 0);
//      ^

В отмеченной позиции выше должно быть как минимум два курсора:

  1. VarDecl: index
  2. DeclRefExpr: index = clang_createIndex(0,0)

Когда вы преобразуете исходное местоположение обратно в курсор, clang_getCursor дает вам наиболее конкретный (объявление переменной в данном случае). Я подозреваю, что это то, что происходит с вами в этом случае: getCursor(loc) возвращает вам только тот курсор, который вы посещаете, только если он наиболее конкретен в своем местоположении.

Попробуйте напечатать физическое местоположение каждого курсора (например, используя clang_getCursorExtent а также clang_getExpansionLocation) чтобы понять, что происходит.

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]