C ++ libclang:从CXSourceLocation检索游标返回错误的游标? [英] C++ libclang: Retrieving cursor from CXSourceLocation returning wrong cursor?

查看:971
本文介绍了C ++ libclang:从CXSourceLocation检索游标返回错误的游标?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



程序使用struct存储游标,包含指向翻译单元的指针和CXSourceLocation从调用clang_getCursorLocation(cursor)。

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

为了这个错误,子访问器函数访问每个节点并从每个光标创建一个struct 。使用类型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\\\

clang_getCString(clang_getCursorKindSpelling(cursor.kind)));
if(clang_equalCursors(cursor,c2)){
printf(Noooo - 游标不匹配!
//使用作为client_data传递的翻译单元来查看是否
//有区别
loc-> tu =& tu2;
c2 = getCursor(loc);
if(clang_equalCursors(cursor,c2)){
printf(FAILED ALSO!\\\
);
} else {
printf(PASSED ??? \\\
);
}
} else {
printf(We have a match!\\\
);
}
return CXChildVisit_Recurse;
}

我的主要功能如下:

  int main(int argc,char ** argv){
CXIndex index = clang_createIndex(0,0);
//初始化翻译单元
CXTranslationUnit tu = clang_parseTranslationUnit(index,0,
argv,argc,0,0,CXTranslationUnit_None);

//在traverseAST中设置客户端数据
CXClientData data =& tu; // NULL;
//获取翻译单元的根游标
CXCursor rootCursor = clang_getTranslationUnitCursor(tu);
clang_visitChildren(rootCursor,traverseAST,data);

clang_disposeTranslationUnit(tu);
clang_disposeIndex(index);

return 0;
}

我运行的虚拟源代码如下:

  void goo(){
//这里没有
}

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

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



这是一个错误,还是有一些我错过或做错了?




Jacob

解决方案

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



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

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

上面标记位置至少应有两个游标: / p>


  1. VarDecl: index

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

回到游标, clang_getCursor 给你最具体的一个(在这种情况下的变量声明)。我怀疑这是你在这种情况下发生了什么: getCursor(loc)只给你回来你正在访问的游标,如果它是最具体的在它的位置。 / p>

尝试打印每个光标的物理源位置(使用例如 clang_getCursorExtent clang_getExpansionLocation )了解


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

解决方案

Either I'm missing your point entirely, or you are using clang_equalCursors the wrong way: when both cursors are equals, clang_equalCursors returns a non-zero value. Which means I think you're testing cursors inequalities instead of equalities.

Now, let me try to explain why certain cursors apparently behave differently than others. Each cursor has only one source location. However, there might be several cursors at the same source location. Think for example about the following line:

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

There should be at least two cursors at the marked position above:

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

When you convert the source location back to a cursor, clang_getCursor gives you the most specific one (the variable declaration in this case). I suspect this is what happens to you in this case: getCursor(loc) only gives you back the cursor that you are visiting if it is the most specific at its location.

Try printing the physical source location of each cursor (using for example clang_getCursorExtent and clang_getExpansionLocation) to understand what happens.

这篇关于C ++ libclang:从CXSourceLocation检索游标返回错误的游标?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆