blob: 86b81422590c09926d2685f9fbe6abc2d73ff192 [file] [log] [blame]
Gregory Szorc86057602012-02-17 07:44:46 +00001from clang.cindex import CursorKind
2from clang.cindex import Index
3from clang.cindex import TypeKind
Gregory Szorc86057602012-02-17 07:44:46 +00004from nose.tools import raises
Argyrios Kyrtzidis2312f5f2011-08-17 17:01:10 +00005
6kInput = """\
7
8typedef int I;
9
10struct teststruct {
11 int a;
12 I b;
13 long c;
14 unsigned long d;
15 signed long e;
16 const int f;
17 int *g;
18 int ***h;
19};
20
21"""
22
Gregory Szorc31cc38c2012-02-19 18:28:33 +000023def get_tu(source=kInput, lang='c'):
24 name = 't.c'
25 if lang == 'cpp':
26 name = 't.cpp'
27
Argyrios Kyrtzidis2312f5f2011-08-17 17:01:10 +000028 index = Index.create()
Gregory Szorc31cc38c2012-02-19 18:28:33 +000029 tu = index.parse(name, unsaved_files=[(name, source)])
30 assert tu is not None
31 return tu
32
Gregory Szorc826fce52012-02-20 17:45:30 +000033def get_cursor(tu, spelling):
34 for cursor in tu.cursor.get_children():
35 if cursor.spelling == spelling:
36 return cursor
37
38 return None
39
Gregory Szorc31cc38c2012-02-19 18:28:33 +000040def test_a_struct():
41 tu = get_tu(kInput)
Argyrios Kyrtzidis2312f5f2011-08-17 17:01:10 +000042
Gregory Szorc826fce52012-02-20 17:45:30 +000043 teststruct = get_cursor(tu, 'teststruct')
44 assert teststruct is not None, "Could not find teststruct."
45 fields = list(teststruct.get_children())
46 assert all(x.kind == CursorKind.FIELD_DECL for x in fields)
Argyrios Kyrtzidis2312f5f2011-08-17 17:01:10 +000047
Gregory Szorc826fce52012-02-20 17:45:30 +000048 assert fields[0].spelling == 'a'
49 assert not fields[0].type.is_const_qualified()
50 assert fields[0].type.kind == TypeKind.INT
51 assert fields[0].type.get_canonical().kind == TypeKind.INT
Argyrios Kyrtzidis2312f5f2011-08-17 17:01:10 +000052
Gregory Szorc826fce52012-02-20 17:45:30 +000053 assert fields[1].spelling == 'b'
54 assert not fields[1].type.is_const_qualified()
55 assert fields[1].type.kind == TypeKind.TYPEDEF
56 assert fields[1].type.get_canonical().kind == TypeKind.INT
57 assert fields[1].type.get_declaration().spelling == 'I'
Argyrios Kyrtzidis2312f5f2011-08-17 17:01:10 +000058
Gregory Szorc826fce52012-02-20 17:45:30 +000059 assert fields[2].spelling == 'c'
60 assert not fields[2].type.is_const_qualified()
61 assert fields[2].type.kind == TypeKind.LONG
62 assert fields[2].type.get_canonical().kind == TypeKind.LONG
Argyrios Kyrtzidis2312f5f2011-08-17 17:01:10 +000063
Gregory Szorc826fce52012-02-20 17:45:30 +000064 assert fields[3].spelling == 'd'
65 assert not fields[3].type.is_const_qualified()
66 assert fields[3].type.kind == TypeKind.ULONG
67 assert fields[3].type.get_canonical().kind == TypeKind.ULONG
Argyrios Kyrtzidis2312f5f2011-08-17 17:01:10 +000068
Gregory Szorc826fce52012-02-20 17:45:30 +000069 assert fields[4].spelling == 'e'
70 assert not fields[4].type.is_const_qualified()
71 assert fields[4].type.kind == TypeKind.LONG
72 assert fields[4].type.get_canonical().kind == TypeKind.LONG
Argyrios Kyrtzidis2312f5f2011-08-17 17:01:10 +000073
Gregory Szorc826fce52012-02-20 17:45:30 +000074 assert fields[5].spelling == 'f'
75 assert fields[5].type.is_const_qualified()
76 assert fields[5].type.kind == TypeKind.INT
77 assert fields[5].type.get_canonical().kind == TypeKind.INT
Argyrios Kyrtzidis2312f5f2011-08-17 17:01:10 +000078
Gregory Szorc826fce52012-02-20 17:45:30 +000079 assert fields[6].spelling == 'g'
80 assert not fields[6].type.is_const_qualified()
81 assert fields[6].type.kind == TypeKind.POINTER
82 assert fields[6].type.get_pointee().kind == TypeKind.INT
Argyrios Kyrtzidis2312f5f2011-08-17 17:01:10 +000083
Gregory Szorc826fce52012-02-20 17:45:30 +000084 assert fields[7].spelling == 'h'
85 assert not fields[7].type.is_const_qualified()
86 assert fields[7].type.kind == TypeKind.POINTER
87 assert fields[7].type.get_pointee().kind == TypeKind.POINTER
88 assert fields[7].type.get_pointee().get_pointee().kind == TypeKind.POINTER
89 assert fields[7].type.get_pointee().get_pointee().get_pointee().kind == TypeKind.INT
Douglas Gregor38d2d552011-10-19 05:50:34 +000090
91constarrayInput="""
92struct teststruct {
93 void *A[2];
94};
95"""
96def testConstantArray():
Gregory Szorc31cc38c2012-02-19 18:28:33 +000097 tu = get_tu(constarrayInput)
Douglas Gregor38d2d552011-10-19 05:50:34 +000098
Gregory Szorc826fce52012-02-20 17:45:30 +000099 teststruct = get_cursor(tu, 'teststruct')
100 assert teststruct is not None, "Didn't find teststruct??"
101 fields = list(teststruct.get_children())
102 assert fields[0].spelling == 'A'
103 assert fields[0].type.kind == TypeKind.CONSTANTARRAY
104 assert fields[0].type.get_array_element_type() is not None
105 assert fields[0].type.get_array_element_type().kind == TypeKind.POINTER
106 assert fields[0].type.get_array_size() == 2
Gregory Szorc96ad6332012-02-05 19:42:06 +0000107
Gregory Szorc7eb691a2012-02-20 17:44:49 +0000108def test_equal():
109 """Ensure equivalence operators work on Type."""
110 source = 'int a; int b; void *v;'
111 tu = get_tu(source)
112
Gregory Szorc826fce52012-02-20 17:45:30 +0000113 a = get_cursor(tu, 'a')
114 b = get_cursor(tu, 'b')
115 v = get_cursor(tu, 'v')
Gregory Szorc7eb691a2012-02-20 17:44:49 +0000116
117 assert a is not None
118 assert b is not None
119 assert v is not None
120
121 assert a.type == b.type
122 assert a.type != v.type
123
124 assert a.type != None
125 assert a.type != 'foo'
126
Gregory Szorc826fce52012-02-20 17:45:30 +0000127def test_function_argument_types():
128 """Ensure that Type.argument_types() works as expected."""
129 tu = get_tu('void f(int, int);')
130 f = get_cursor(tu, 'f')
131 assert f is not None
132
133 args = f.type.argument_types()
134 assert args is not None
135 assert len(args) == 2
136
137 t0 = args[0]
138 assert t0 is not None
139 assert t0.kind == TypeKind.INT
140
141 t1 = args[1]
142 assert t1 is not None
143 assert t1.kind == TypeKind.INT
144
145 args2 = list(args)
146 assert len(args2) == 2
147 assert t0 == args2[0]
148 assert t1 == args2[1]
149
150@raises(TypeError)
151def test_argument_types_string_key():
152 """Ensure that non-int keys raise a TypeError."""
153 tu = get_tu('void f(int, int);')
154 f = get_cursor(tu, 'f')
155 assert f is not None
156
157 args = f.type.argument_types()
158 assert len(args) == 2
159
160 args['foo']
161
162@raises(IndexError)
163def test_argument_types_negative_index():
164 """Ensure that negative indexes on argument_types Raises an IndexError."""
165 tu = get_tu('void f(int, int);')
166 f = get_cursor(tu, 'f')
167 args = f.type.argument_types()
168
169 args[-1]
170
171@raises(IndexError)
172def test_argument_types_overflow_index():
173 """Ensure that indexes beyond the length of Type.argument_types() raise."""
174 tu = get_tu('void f(int, int);')
175 f = get_cursor(tu, 'f')
176 args = f.type.argument_types()
177
178 args[2]
179
180@raises(Exception)
181def test_argument_types_invalid_type():
182 """Ensure that obtaining argument_types on a Type without them raises."""
183 tu = get_tu('int i;')
184 i = get_cursor(tu, 'i')
185 assert i is not None
186
187 i.type.argument_types()
188
Gregory Szorc96ad6332012-02-05 19:42:06 +0000189def test_is_pod():
Gregory Szorc31cc38c2012-02-19 18:28:33 +0000190 tu = get_tu('int i; void f();')
Gregory Szorc826fce52012-02-20 17:45:30 +0000191 i = get_cursor(tu, 'i')
192 f = get_cursor(tu, 'f')
Gregory Szorc96ad6332012-02-05 19:42:06 +0000193
194 assert i is not None
195 assert f is not None
196
197 assert i.type.is_pod()
198 assert not f.type.is_pod()
Gregory Szorc86057602012-02-17 07:44:46 +0000199
Gregory Szorc31cc38c2012-02-19 18:28:33 +0000200def test_function_variadic():
201 """Ensure Type.is_function_variadic works."""
Gregory Szorc86057602012-02-17 07:44:46 +0000202
Gregory Szorc31cc38c2012-02-19 18:28:33 +0000203 source ="""
204#include <stdarg.h>
205
206void foo(int a, ...);
207void bar(int a, int b);
208"""
209
210 tu = get_tu(source)
Gregory Szorc826fce52012-02-20 17:45:30 +0000211 foo = get_cursor(tu, 'foo')
212 bar = get_cursor(tu, 'bar')
Gregory Szorc31cc38c2012-02-19 18:28:33 +0000213
214 assert foo is not None
215 assert bar is not None
216
217 assert isinstance(foo.type.is_function_variadic(), bool)
218 assert foo.type.is_function_variadic()
219 assert not bar.type.is_function_variadic()
220
221def test_element_type():
222 tu = get_tu('int i[5];')
Gregory Szorc826fce52012-02-20 17:45:30 +0000223 i = get_cursor(tu, 'i')
Gregory Szorc31cc38c2012-02-19 18:28:33 +0000224 assert i is not None
225
Gregory Szorc86057602012-02-17 07:44:46 +0000226 assert i.type.kind == TypeKind.CONSTANTARRAY
227 assert i.type.element_type.kind == TypeKind.INT
228
229@raises(Exception)
230def test_invalid_element_type():
231 """Ensure Type.element_type raises if type doesn't have elements."""
Gregory Szorc31cc38c2012-02-19 18:28:33 +0000232 tu = get_tu('int i;')
Gregory Szorc826fce52012-02-20 17:45:30 +0000233 i = get_cursor(tu, 'i')
Gregory Szorc31cc38c2012-02-19 18:28:33 +0000234 assert i is not None
Gregory Szorc86057602012-02-17 07:44:46 +0000235 i.element_type
Gregory Szorcbf8ca002012-02-17 07:47:38 +0000236
237def test_element_count():
Gregory Szorc31cc38c2012-02-19 18:28:33 +0000238 tu = get_tu('int i[5]; int j;')
Gregory Szorc826fce52012-02-20 17:45:30 +0000239 i = get_cursor(tu, 'i')
240 j = get_cursor(tu, 'j')
Gregory Szorcbf8ca002012-02-17 07:47:38 +0000241
242 assert i is not None
243 assert j is not None
244
245 assert i.type.element_count == 5
246
247 try:
248 j.type.element_count
249 assert False
250 except:
251 assert True