【问题标题】:C++ libclang: Retrieving cursor from CXSourceLocation returning wrong cursor?C++ libclang:从返回错误光标的 CXSourceLocation 检索光标?
【发布时间】:2013-02-27 02:21:05
【问题描述】:

我目前正在使用带有 C++ 的 libclang 编写一个简单的克隆检测器。

程序使用结构存储游标,其中包含指向翻译单元的指针和调用 clang_getCursorLocation(cursor) 获得的 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();
    };
}

但是输出是一致的,这表明这只发生在某些游标类型上。

这是一个错误还是我遗漏了什么或做错了什么?

提前致谢, 雅各布

【问题讨论】:

    标签: c++ clang libclang


    【解决方案1】:

    要么我完全错过了你的观点,要么你以错误的方式使用clang_equalCursors:当两个光标相等时,clang_equalCursors 返回一个非零值。这意味着我认为您正在测试游标不等式而不是等式。

    现在,让我尝试解释为什么某些游标的行为显然与其他游标不同。每个光标只有一个源位置。但是,同一源位置可能有多个游标。例如考虑以下行:

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

    上面标记的位置应该至少有两个光标:

    1. 变量声明:index
    2. DeclRefExpr:index = clang_createIndex(0,0)

    当您将源位置转换回光标时,clang_getCursor 会为您提供最具体的位置(在本例中为变量声明)。我怀疑这就是在这种情况下发生在您身上的事情:getCursor(loc) 仅在您正在访问的光标所在位置最具体时才返回给您。

    尝试打印每个光标的物理源位置(例如使用clang_getCursorExtentclang_getExpansionLocation)以了解发生了什么。

    【讨论】:

    • 嗨弗朗西斯科。感谢您的快速回复和澄清!这是一个很大的帮助
    • 没问题。还有一件事:你不应该忘记使用clang_disposeString释放CXStrings 分配的内存
    猜你喜欢
    • 1970-01-01
    • 2020-09-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多