如何通过python-clang区分结构体成员的bool与_Bool类型?
解决python-clang区分结构体成员中
bool与_Bool原始类型的问题 由于<stdbool.h>中bool是宏定义而非typedef,clang预处理后会将bool替换为_Bool,导致AST中无法直接通过类型游标区分原始写法。针对结构体成员token为空的情况,可通过以下方法获取源码中的原始类型:
利用游标定位源码位置
每个结构体成员的Cursor都带有extent属性,它包含了该成员在源码中的起始和结束SourceLocation。通过这两个位置,可以直接从原始源码文件中截取对应位置的文本,从而获取原始的类型写法。具体实现步骤
- 获取结构体成员游标
member_cursor的extent,得到start_loc和end_loc。 - 通过
start_loc.file.name获取源码文件路径,读取文件的全部内容。 - 利用
start_loc.offset和end_loc.offset计算出该成员声明在源码中的字符区间,截取这段文本。 - 对截取的文本进行简单处理(比如去除空白、拆分声明),提取出类型关键字部分,即可区分是
bool还是_Bool。
- 获取结构体成员游标
示例代码片段
import clang.cindex def get_original_member_type(member_cursor): # 获取成员的位置信息 extent = member_cursor.extent start_loc = extent.start end_loc = extent.end # 跳过非文件位置的情况 if not start_loc.file or not end_loc.file: return None # 读取源码文件 with open(start_loc.file.name, 'r') as f: source_content = f.read() # 截取成员声明的文本 member_text = source_content[start_loc.offset:end_loc.offset].strip() # 拆分声明,提取类型部分(简单处理,可根据实际情况优化) type_part = member_text.split()[0] return type_part # 初始化clang索引 index = clang.cindex.Index.create() tu = index.parse('test.c', args=['-std=c11']) # 遍历AST找到结构体成员 def traverse(cursor): if cursor.kind == clang.cindex.CursorKind.STRUCT_DECL: for child in cursor.get_children(): if child.kind == clang.cindex.CursorKind.FIELD_DECL: original_type = get_original_member_type(child) print(f"成员{child.spelling}的原始类型: {original_type}") for child in cursor.get_children(): traverse(child) traverse(tu.cursor)注意事项
- 确保clang在解析时加载了正确的头文件(比如通过
args=['-std=c11', '-I/path/to/include']指定),避免预处理异常。 - 若源码中有复杂的声明(比如带指针、数组修饰符),需要优化文本拆分逻辑,比如用正则匹配类型部分。
- 确保clang在解析时加载了正确的头文件(比如通过
内容的提问来源于stack exchange,提问作者Jani
相关产品推荐
相关产品推荐

