我目前正在使用带有C的libclang编写一个简单的克隆检测器.
该程序使用结构存储游标,该结构包含指向转换单元的指针和从调用clang_getCursorLocation(游标)获得的CXSourceLocation.
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();
};
}
但是输出是一致的,这表明这只发生在某些光标种类上.
这是一个错误还是我缺少或做错了什么?
提前致谢,
雅各
最佳答案 要么我完全错过了你的观点,要么你正在以错误的方式使用clang_equalCursors:当两个游标都是等于时,clang_equalCursors返回一个非零值.这意味着我认为你正在测试游标不等式而不是等式.
现在,让我试着解释一下为什么某些游标的行为明显与其他游标不同.每个游标只有一个源位置.但是,在同一源位置可能有多个游标.想想以下几行:
CXIndex index = clang_createIndex(0, 0);
// ^
上面标记的位置应该至少有两个光标:
> VarDecl:index
> DeclRefExpr:index = clang_createIndex(0,0)
当您将源位置转换回游标时,clang_getCursor会为您提供最具体的位置(在本例中为变量声明).我怀疑这是在这种情况下发生的事情:getCursor(loc)只返回你正在访问的光标,如果它在其位置最具体.
尝试打印每个光标的物理源位置(例如使用clang_getCursorExtent和clang_getExpansionLocation)以了解会发生什么.