【问题标题】:How can I retrieve fully-qualified function names with libclang?如何使用 libclang 检索完全限定的函数名称?
【发布时间】:2016-10-27 19:24:41
【问题描述】:

我需要解析一个 C++ 代码文件并找到其中所有具有完全限定名称的函数调用。我正在使用 libclang 的 Python 绑定,因为它似乎比编写我自己的 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 获得函数的“短”名称,但我不知道如何找到它所属的类/命名空间。

【问题讨论】:

    标签: python c++ libclang


    【解决方案1】:

    您可以使用光标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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-11-12
      • 2023-03-08
      • 2012-10-12
      • 2014-10-20
      • 1970-01-01
      • 1970-01-01
      • 2018-02-08
      • 2013-06-21
      相关资源
      最近更新 更多