如何使用libclang检索标准函数名称? [英] How can I retrieve fully-qualified function names with libclang?

查看:244
本文介绍了如何使用libclang检索标准函数名称?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要解析一个C ++代码文件,并使用完全限定的名称查找其中的所有函数调用.我使用libclang的Python绑定是因为,即使文档很稀疏,这似乎比编写自己的C ++解析器还容易.

I need to parse a C++ code file and find all the function calls in it with fully-qualified names. I'm using libclang's Python bindings because it seems easier than writing my own C++ parser, even if the documentation is sparse.

示例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)

我正在寻找的输出是被调用的函数的标准名称的列表:

The output I'm looking for is a list of fully-qualified names of functions that were called:

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

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

I can get the function's "short" name by using node.spelling, but I don't know how to find the class/namespace that it belongs to.

推荐答案

您可以使用光标referenced属性获取该定义的句柄,然后可以通过semantic_parent属性递归AST(停止(在根目录或光标类型是翻译单元时)以构建完全限定的名称.

You can use the cursor referenced property to get a handle to the definition, and then you can recurse up the AST via the semantic_parent property (stopping at the root or when the cursor kind is translation unit) to build the fully qualified name.

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

这篇关于如何使用libclang检索标准函数名称?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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