代码之家  ›  专栏  ›  技术社区  ›  Gilles 'SO- stop being evil'

Python clang绑定:识别节点的sizeof并获取类型

  •  0
  • Gilles 'SO- stop being evil'  · 技术社区  · 4 年前

    我在一些C代码上使用libclangpython绑定。我想不出如何获取有关 sizeof 节点。我找不到任何相关文件。实验上:

    • 大小 节点具有 CursorKind.CXX_UNARY_EXPR .
    • sizeof(type) 他没有孩子。 sizeof expression 有一个孩子 expression .

    到目前为止还说得通,但后来呢?我怎么分辨 大小 从其他一元表达式?如何获取输入 sizeof(类型) ?

    我使用的是libclang10.0.0和ubuntu18.04中附带的相应Python绑定( python3-clang-10 ).

    这是一个小的C源文件 foo.c 试验:

    #include <stddef.h>
    size_t foo(void) {
        return sizeof(unsigned short) + sizeof 1234;
    }
    

    来自clangast解析器的转储显示了我所期望的所有信息。

    $ clang -Xclang -ast-dump -fsyntax-only foo.c | tail -n 5
        `-ReturnStmt 0x97ad48 <line:3:5, col:44>
          `-BinaryOperator 0x97ad28 <col:12, col:44> 'unsigned long' '+'
            |-UnaryExprOrTypeTraitExpr 0x97acc8 <col:12, col:33> 'unsigned long' sizeof 'unsigned short'
            `-UnaryExprOrTypeTraitExpr 0x97ad08 <col:37, col:44> 'unsigned long' sizeof
              `-IntegerLiteral 0x97ace8 <col:44> 'int' 1234
    

    下面是我用来探索Python数据结构的Python代码。

    #!/usr/bin/env python3
    import clang.cindex
    from clang.cindex import CursorKind
    
    def explore_attrs(node):
        for attr in sorted(dir(node)):
            try:
                value = getattr(node, attr)
            except AssertionError as e: # Skip attributes whose accessor only works with specific kinds
                continue
            if callable(value): continue
            if value is None: continue
            print(attr, repr(value))
    
    def explore(node):
        """Print information about an AST node."""
        print('Children:', [(child.kind, child.spelling) for child in node.get_children()])
        print('Arguments:', list(node.get_arguments()))
        print('Definition:', node.get_definition())
        explore_attrs(node)
    
    def main():
        index = clang.cindex.Index.create()
        tu = index.parse('foo.c')
        for node in tu.cursor.walk_preorder():
            if node.kind == CursorKind.RETURN_STMT:
                children = list(node.get_children())
                # Expect sizeof(...) + sizeof(...)
                assert children[0].kind == CursorKind.BINARY_OPERATOR
                lhs, rhs = children[0].get_children()
                explore(lhs)
                print()
                explore(rhs)
    
    main()
    
    0 回复  |  直到 4 年前