python - 如何使用 libclang 检索完全限定的函数名称?

标签 python c++ libclang

我需要解析一个 C++ 代码文件并找到其中所有具有完全限定名称的函数调用。我正在使用 libclang 的 Python 绑定(bind),因为它似乎比编写我自己的 C++ 解析器更容易,即使文档很少。

示例 C++ 代码:

namespace a {
  namespace b {
    class Thing {
    public:
      Thing();
      void DoSomething();
      int DoAnotherThing();
    private:
      int thisThing;
    };
  }
}

int main()
{
  a::b::Thing *thing = new a::b::Thing();
  thing->DoSomething();
  return 0;
}

Python 脚本:

import clang.cindex
import sys

def find_function_calls(node):
  if node.kind == clang.cindex.CursorKind.CALL_EXPR:
    # What do I do here?
    pass
  for child in node.get_children():
    find_function_calls(child)

index = clang.cindex.Index.create()
tu = index.parse(sys.argv[1])
find_function_calls(tu.cursor)

我正在寻找的输出是被调用函数的完全限定名称列表:

a::b::Thing::Thing
a::b::Thing::DoSomething

我可以使用 node.spelling 获取函数的“短”名称,但我不知道如何找到它所属的类/命名空间。

最佳答案

您可以使用游标 referenced 属性来获取定义的句柄,然后您可以通过 semantic_parent 属性向上递归 AST(停在根或当光标种类是翻译单元时)构建完全限定名称。

import clang.cindex
from clang.cindex import CursorKind

def fully_qualified(c):
    if c is None:
        return ''
    elif c.kind == CursorKind.TRANSLATION_UNIT:
        return ''
    else:
        res = fully_qualified(c.semantic_parent)
        if res != '':
            return res + '::' + c.spelling
    return c.spelling

idx = clang.cindex.Index.create()
tu = idx.parse('tmp.cpp', args='-xc++ --std=c++11'.split())
for c in tu.cursor.walk_preorder():
    if c.kind == CursorKind.CALL_EXPR:
        print fully_qualified(c.referenced)

产生:

a::b::Thing::Thing
a::b::Thing::DoSomething

关于python - 如何使用 libclang 检索完全限定的函数名称?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40292703/

相关文章:

python - 如何获得星号 (*) 而不是数字 0 的结果?

python - 如何将一个 Sphinx 角色转换为另一个角色?

c++ - std::promise<T> 其中 T 在 Visual Studio 2017 中必须是默认可构造的?

C++ - 不编译对象 vector 的迭代器

python - 使用 Python 子进程模块创建 SQLite 数据库时出错

python - 在 Windows 上结束时如何暂停脚本?

c++ - 为什么类内初始化器只能使用 = 或 {}?

python - 为什么 Libclang 无法获得头文件中定义的函数的定义?

python - 使用 libclang 进行函数边界识别

c++ - 如何使用 clang 获取单个 cpp 文件的 AST?