I'm using the libclang python bindings on some C code. I can't figure out how to get information about sizeof nodes. I can't find any relevant documentation. Experimentally:
sizeofnodes have the kindCursorKind.CXX_UNARY_EXPR.sizeof(type)has no child.sizeof expressionhas one child which isexpression.
Makes sense so far, but then what? How do I distinguish sizeof from other unary expressions? How do I obtain the type in sizeof(type)?
I'm using the libclang 10.0.0 and the corresponding Python bindings as shipped in Ubuntu 18.04 (python3-clang-10).
Here's a small C source file foo.c to experiment with:
#include <stddef.h>
size_t foo(void) {
return sizeof(unsigned short) + sizeof 1234;
}
A dump from the Clang AST parser shows all the information I'd expect.
$ 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
And here's the Python code I used to explore the Python data structure.
#!/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()