Clang Python Bindings:如何获取调用成员方法的变量类类型
获取Clang AST中成员调用的变量类类型
我之前用Clang Python绑定处理AST时也碰到过一模一样的问题!你现在拿到的void是方法的返回类型,要获取调用mymethod的变量var的类类型,得深入到AST的成员调用节点里去挖信息,咱们一步步来:
核心思路
在Clang的AST里,var.mymethod()对应的是CXXMemberCallExpr节点,这个节点本身包含了两部分关键信息:调用的成员表达式(也就是var.mymethod)和方法的返回值。我们需要从成员表达式里提取出var的类型。
具体步骤&代码示例
- 识别成员调用节点:遍历AST时,先判断当前节点是不是
CXX_MEMBER_CALL_EXPR类型 - 获取成员表达式:从调用节点中拿到
MemberRefExpr(也就是var.mymethod这个部分) - 提取基础变量节点:从成员表达式里获取
var对应的节点,再解析它的类型 - 处理指针/引用类型:如果
var是指针或引用,要先解引用拿到实际的类类型
下面是简化后的Python代码,你可以直接套到你的遍历逻辑里:
import clang.cindex def traverse_ast(node): if node.kind == clang.cindex.CursorKind.CXX_MEMBER_CALL_EXPR: # 拿到成员调用的表达式(var.mymethod) member_expr = node.get_callee() if member_expr.kind == clang.cindex.CursorKind.MEMBER_REF_EXPR: # 获取var对应的节点 base_node = member_expr.get_base() base_type = base_node.type # 处理指针或引用类型,解引用拿到实际类类型 if base_type.kind in [clang.cindex.TypeKind.POINTER, clang.cindex.TypeKind.LVALUE_REFERENCE]: base_type = base_type.get_pointee_type() # 检查是否是类/结构体类型 if base_type.kind == clang.cindex.TypeKind.RECORD: # 获取类的声明节点,拿到类名 class_decl = base_type.get_declaration() print(f"调用方法的变量类类型: {class_decl.spelling}") print(f"方法名: {member_expr.spelling}") print(f"方法返回类型: {node.result_type.spelling}") # 递归遍历所有子节点 for child in node.get_children(): traverse_ast(child) # 初始化Clang索引并解析你的测试文件 index = clang.cindex.Index.create() # 记得根据你的代码调整编译参数,比如-std=c++17之类的 tu = index.parse("your_test_code.cpp", args=["-std=c++11"]) traverse_ast(tu.cursor)
关键细节说明
get_callee():从CXXMemberCallExpr里拿到调用的成员表达式,这是获取变量类型的关键入口get_base():从成员表达式里提取出调用方法的基础对象(也就是var)get_pointee_type():如果var是指针(比如MyClass* var)或者引用(MyClass& var),用这个方法解引用,拿到实际的MyClass类型get_declaration():从RecordType里拿到类的声明节点,通过spelling属性就能获取类的名称
这样修改后,你应该就能得到var的类类型,而不是方法的返回类型了。
内容的提问来源于stack exchange,提问作者Folkert van Heusden
相关产品推荐
相关产品推荐

