问题
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.
Example C++ code:
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 script:
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
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.
回答1:
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)
Which produces:
a::b::Thing::Thing
a::b::Thing::DoSomething
来源:https://stackoverflow.com/questions/40292703/how-can-i-retrieve-fully-qualified-function-names-with-libclang