1from clang.cindex import Index, CursorKind, TypeKind
2
3kInput = """\
4// FIXME: Find nicer way to drop builtins and other cruft.
5int start_decl;
6
7struct s0 {
8  int a;
9  int b;
10};
11
12struct s1;
13
14void f0(int a0, int a1) {
15  int l0, l1;
16
17  if (a0)
18    return;
19
20  for (;;) {
21    break;
22  }
23}
24"""
25
26def test_get_children():
27    index = Index.create()
28    tu = index.parse('t.c', unsaved_files = [('t.c',kInput)])
29
30    # Skip until past start_decl.
31    it = tu.cursor.get_children()
32    while it.next().spelling != 'start_decl':
33        pass
34
35    tu_nodes = list(it)
36
37    assert len(tu_nodes) == 3
38
39    assert tu_nodes[0].kind == CursorKind.STRUCT_DECL
40    assert tu_nodes[0].spelling == 's0'
41    assert tu_nodes[0].is_definition() == True
42    assert tu_nodes[0].location.file.name == 't.c'
43    assert tu_nodes[0].location.line == 4
44    assert tu_nodes[0].location.column == 8
45    assert tu_nodes[0].hash > 0
46
47    s0_nodes = list(tu_nodes[0].get_children())
48    assert len(s0_nodes) == 2
49    assert s0_nodes[0].kind == CursorKind.FIELD_DECL
50    assert s0_nodes[0].spelling == 'a'
51    assert s0_nodes[0].type.kind == TypeKind.INT
52    assert s0_nodes[1].kind == CursorKind.FIELD_DECL
53    assert s0_nodes[1].spelling == 'b'
54    assert s0_nodes[1].type.kind == TypeKind.INT
55
56    assert tu_nodes[1].kind == CursorKind.STRUCT_DECL
57    assert tu_nodes[1].spelling == 's1'
58    assert tu_nodes[1].displayname == 's1'
59    assert tu_nodes[1].is_definition() == False
60
61    assert tu_nodes[2].kind == CursorKind.FUNCTION_DECL
62    assert tu_nodes[2].spelling == 'f0'
63    assert tu_nodes[2].displayname == 'f0(int, int)'
64    assert tu_nodes[2].is_definition() == True
65
66def test_underlying_type():
67    source = 'typedef int foo;'
68    index = Index.create()
69    tu = index.parse('test.c', unsaved_files=[('test.c', source)])
70    assert tu is not None
71
72    for cursor in tu.cursor.get_children():
73        if cursor.spelling == 'foo':
74            typedef = cursor
75            break
76
77    assert typedef.kind.is_declaration()
78    underlying = typedef.underlying_typedef_type
79    assert underlying.kind == TypeKind.INT
80
81def test_enum_type():
82    source = 'enum TEST { FOO=1, BAR=2 };'
83    index = Index.create()
84    tu = index.parse('test.c', unsaved_files=[('test.c', source)])
85    assert tu is not None
86
87    for cursor in tu.cursor.get_children():
88        if cursor.spelling == 'TEST':
89            enum = cursor
90            break
91
92    assert enum.kind == CursorKind.ENUM_DECL
93    enum_type = enum.enum_type
94    assert enum_type.kind == TypeKind.UINT
95