blob: f3dadf999bd84492a8a55910710c27217c70e181 [file] [log] [blame]
Gregory Szorca63ef1f2012-05-15 19:51:02 +00001import gc
2
Gregory Szorc86057602012-02-17 07:44:46 +00003from clang.cindex import CursorKind
Gregory Szorca63ef1f2012-05-15 19:51:02 +00004from clang.cindex import TranslationUnit
Gregory Szorc86057602012-02-17 07:44:46 +00005from clang.cindex import TypeKind
Gregory Szorc86057602012-02-17 07:44:46 +00006from nose.tools import raises
Gregory Szorc1f1988f2012-03-10 22:19:05 +00007from .util import get_cursor
8from .util import get_tu
Argyrios Kyrtzidis2312f5f2011-08-17 17:01:10 +00009
10kInput = """\
11
12typedef int I;
13
14struct teststruct {
15 int a;
16 I b;
17 long c;
18 unsigned long d;
19 signed long e;
20 const int f;
21 int *g;
22 int ***h;
23};
24
25"""
26
Gregory Szorc31cc38c2012-02-19 18:28:33 +000027def test_a_struct():
28 tu = get_tu(kInput)
Argyrios Kyrtzidis2312f5f2011-08-17 17:01:10 +000029
Gregory Szorc826fce52012-02-20 17:45:30 +000030 teststruct = get_cursor(tu, 'teststruct')
31 assert teststruct is not None, "Could not find teststruct."
32 fields = list(teststruct.get_children())
33 assert all(x.kind == CursorKind.FIELD_DECL for x in fields)
Gregory Szorca63ef1f2012-05-15 19:51:02 +000034 assert all(x.translation_unit is not None for x in fields)
Argyrios Kyrtzidis2312f5f2011-08-17 17:01:10 +000035
Gregory Szorc826fce52012-02-20 17:45:30 +000036 assert fields[0].spelling == 'a'
37 assert not fields[0].type.is_const_qualified()
38 assert fields[0].type.kind == TypeKind.INT
39 assert fields[0].type.get_canonical().kind == TypeKind.INT
Argyrios Kyrtzidis2312f5f2011-08-17 17:01:10 +000040
Gregory Szorc826fce52012-02-20 17:45:30 +000041 assert fields[1].spelling == 'b'
42 assert not fields[1].type.is_const_qualified()
43 assert fields[1].type.kind == TypeKind.TYPEDEF
44 assert fields[1].type.get_canonical().kind == TypeKind.INT
45 assert fields[1].type.get_declaration().spelling == 'I'
Argyrios Kyrtzidis2312f5f2011-08-17 17:01:10 +000046
Gregory Szorc826fce52012-02-20 17:45:30 +000047 assert fields[2].spelling == 'c'
48 assert not fields[2].type.is_const_qualified()
49 assert fields[2].type.kind == TypeKind.LONG
50 assert fields[2].type.get_canonical().kind == TypeKind.LONG
Argyrios Kyrtzidis2312f5f2011-08-17 17:01:10 +000051
Gregory Szorc826fce52012-02-20 17:45:30 +000052 assert fields[3].spelling == 'd'
53 assert not fields[3].type.is_const_qualified()
54 assert fields[3].type.kind == TypeKind.ULONG
55 assert fields[3].type.get_canonical().kind == TypeKind.ULONG
Argyrios Kyrtzidis2312f5f2011-08-17 17:01:10 +000056
Gregory Szorc826fce52012-02-20 17:45:30 +000057 assert fields[4].spelling == 'e'
58 assert not fields[4].type.is_const_qualified()
59 assert fields[4].type.kind == TypeKind.LONG
60 assert fields[4].type.get_canonical().kind == TypeKind.LONG
Argyrios Kyrtzidis2312f5f2011-08-17 17:01:10 +000061
Gregory Szorc826fce52012-02-20 17:45:30 +000062 assert fields[5].spelling == 'f'
63 assert fields[5].type.is_const_qualified()
64 assert fields[5].type.kind == TypeKind.INT
65 assert fields[5].type.get_canonical().kind == TypeKind.INT
Argyrios Kyrtzidis2312f5f2011-08-17 17:01:10 +000066
Gregory Szorc826fce52012-02-20 17:45:30 +000067 assert fields[6].spelling == 'g'
68 assert not fields[6].type.is_const_qualified()
69 assert fields[6].type.kind == TypeKind.POINTER
70 assert fields[6].type.get_pointee().kind == TypeKind.INT
Argyrios Kyrtzidis2312f5f2011-08-17 17:01:10 +000071
Gregory Szorc826fce52012-02-20 17:45:30 +000072 assert fields[7].spelling == 'h'
73 assert not fields[7].type.is_const_qualified()
74 assert fields[7].type.kind == TypeKind.POINTER
75 assert fields[7].type.get_pointee().kind == TypeKind.POINTER
76 assert fields[7].type.get_pointee().get_pointee().kind == TypeKind.POINTER
77 assert fields[7].type.get_pointee().get_pointee().get_pointee().kind == TypeKind.INT
Douglas Gregor38d2d552011-10-19 05:50:34 +000078
Gregory Szorca63ef1f2012-05-15 19:51:02 +000079def test_references():
80 """Ensure that a Type maintains a reference to a TranslationUnit."""
81
82 tu = get_tu('int x;')
83 children = list(tu.cursor.get_children())
84 assert len(children) > 0
85
86 cursor = children[0]
87 t = cursor.type
88
89 assert isinstance(t.translation_unit, TranslationUnit)
90
91 # Delete main TranslationUnit reference and force a GC.
92 del tu
93 gc.collect()
94 assert isinstance(t.translation_unit, TranslationUnit)
95
96 # If the TU was destroyed, this should cause a segfault.
97 decl = t.get_declaration()
98
Douglas Gregor38d2d552011-10-19 05:50:34 +000099constarrayInput="""
100struct teststruct {
101 void *A[2];
102};
103"""
104def testConstantArray():
Gregory Szorc31cc38c2012-02-19 18:28:33 +0000105 tu = get_tu(constarrayInput)
Douglas Gregor38d2d552011-10-19 05:50:34 +0000106
Gregory Szorc826fce52012-02-20 17:45:30 +0000107 teststruct = get_cursor(tu, 'teststruct')
108 assert teststruct is not None, "Didn't find teststruct??"
109 fields = list(teststruct.get_children())
110 assert fields[0].spelling == 'A'
111 assert fields[0].type.kind == TypeKind.CONSTANTARRAY
112 assert fields[0].type.get_array_element_type() is not None
113 assert fields[0].type.get_array_element_type().kind == TypeKind.POINTER
114 assert fields[0].type.get_array_size() == 2
Gregory Szorc96ad6332012-02-05 19:42:06 +0000115
Gregory Szorc7eb691a2012-02-20 17:44:49 +0000116def test_equal():
117 """Ensure equivalence operators work on Type."""
118 source = 'int a; int b; void *v;'
119 tu = get_tu(source)
120
Gregory Szorc826fce52012-02-20 17:45:30 +0000121 a = get_cursor(tu, 'a')
122 b = get_cursor(tu, 'b')
123 v = get_cursor(tu, 'v')
Gregory Szorc7eb691a2012-02-20 17:44:49 +0000124
125 assert a is not None
126 assert b is not None
127 assert v is not None
128
129 assert a.type == b.type
130 assert a.type != v.type
131
132 assert a.type != None
133 assert a.type != 'foo'
134
Argyrios Kyrtzidisc23cb2d2013-10-03 16:19:27 +0000135def test_type_spelling():
136 """Ensure Type.spelling works."""
137 tu = get_tu('int c[5]; int i[]; int x; int v[x];')
138 c = get_cursor(tu, 'c')
139 i = get_cursor(tu, 'i')
140 x = get_cursor(tu, 'x')
141 v = get_cursor(tu, 'v')
142 assert c is not None
143 assert i is not None
144 assert x is not None
145 assert v is not None
146 assert c.type.spelling == "int [5]"
147 assert i.type.spelling == "int []"
148 assert x.type.spelling == "int"
149 assert v.type.spelling == "int [x]"
150
Gregory Szorc6e67eed2012-04-15 18:51:10 +0000151def test_typekind_spelling():
152 """Ensure TypeKind.spelling works."""
153 tu = get_tu('int a;')
154 a = get_cursor(tu, 'a')
155
156 assert a is not None
157 assert a.type.kind.spelling == 'Int'
158
Gregory Szorc826fce52012-02-20 17:45:30 +0000159def test_function_argument_types():
160 """Ensure that Type.argument_types() works as expected."""
161 tu = get_tu('void f(int, int);')
162 f = get_cursor(tu, 'f')
163 assert f is not None
164
165 args = f.type.argument_types()
166 assert args is not None
167 assert len(args) == 2
168
169 t0 = args[0]
170 assert t0 is not None
171 assert t0.kind == TypeKind.INT
172
173 t1 = args[1]
174 assert t1 is not None
175 assert t1.kind == TypeKind.INT
176
177 args2 = list(args)
178 assert len(args2) == 2
179 assert t0 == args2[0]
180 assert t1 == args2[1]
181
182@raises(TypeError)
183def test_argument_types_string_key():
184 """Ensure that non-int keys raise a TypeError."""
185 tu = get_tu('void f(int, int);')
186 f = get_cursor(tu, 'f')
187 assert f is not None
188
189 args = f.type.argument_types()
190 assert len(args) == 2
191
192 args['foo']
193
194@raises(IndexError)
195def test_argument_types_negative_index():
196 """Ensure that negative indexes on argument_types Raises an IndexError."""
197 tu = get_tu('void f(int, int);')
198 f = get_cursor(tu, 'f')
199 args = f.type.argument_types()
200
201 args[-1]
202
203@raises(IndexError)
204def test_argument_types_overflow_index():
205 """Ensure that indexes beyond the length of Type.argument_types() raise."""
206 tu = get_tu('void f(int, int);')
207 f = get_cursor(tu, 'f')
208 args = f.type.argument_types()
209
210 args[2]
211
212@raises(Exception)
213def test_argument_types_invalid_type():
214 """Ensure that obtaining argument_types on a Type without them raises."""
215 tu = get_tu('int i;')
216 i = get_cursor(tu, 'i')
217 assert i is not None
218
219 i.type.argument_types()
220
Gregory Szorc96ad6332012-02-05 19:42:06 +0000221def test_is_pod():
Gregory Szorc82613452012-02-20 17:58:40 +0000222 """Ensure Type.is_pod() works."""
Gregory Szorc31cc38c2012-02-19 18:28:33 +0000223 tu = get_tu('int i; void f();')
Gregory Szorc826fce52012-02-20 17:45:30 +0000224 i = get_cursor(tu, 'i')
225 f = get_cursor(tu, 'f')
Gregory Szorc96ad6332012-02-05 19:42:06 +0000226
227 assert i is not None
228 assert f is not None
229
230 assert i.type.is_pod()
231 assert not f.type.is_pod()
Gregory Szorc86057602012-02-17 07:44:46 +0000232
Gregory Szorc31cc38c2012-02-19 18:28:33 +0000233def test_function_variadic():
234 """Ensure Type.is_function_variadic works."""
Gregory Szorc86057602012-02-17 07:44:46 +0000235
Gregory Szorc31cc38c2012-02-19 18:28:33 +0000236 source ="""
237#include <stdarg.h>
238
239void foo(int a, ...);
240void bar(int a, int b);
241"""
242
243 tu = get_tu(source)
Gregory Szorc826fce52012-02-20 17:45:30 +0000244 foo = get_cursor(tu, 'foo')
245 bar = get_cursor(tu, 'bar')
Gregory Szorc31cc38c2012-02-19 18:28:33 +0000246
247 assert foo is not None
248 assert bar is not None
249
250 assert isinstance(foo.type.is_function_variadic(), bool)
251 assert foo.type.is_function_variadic()
252 assert not bar.type.is_function_variadic()
253
254def test_element_type():
Gregory Szorc82613452012-02-20 17:58:40 +0000255 """Ensure Type.element_type works."""
Argyrios Kyrtzidis4c4f6fe2013-07-23 17:36:21 +0000256 tu = get_tu('int c[5]; int i[]; int x; int v[x];')
257 c = get_cursor(tu, 'c')
Gregory Szorc826fce52012-02-20 17:45:30 +0000258 i = get_cursor(tu, 'i')
Argyrios Kyrtzidis4c4f6fe2013-07-23 17:36:21 +0000259 v = get_cursor(tu, 'v')
260 assert c is not None
Gregory Szorc31cc38c2012-02-19 18:28:33 +0000261 assert i is not None
Argyrios Kyrtzidis4c4f6fe2013-07-23 17:36:21 +0000262 assert v is not None
Gregory Szorc31cc38c2012-02-19 18:28:33 +0000263
Argyrios Kyrtzidis4c4f6fe2013-07-23 17:36:21 +0000264 assert c.type.kind == TypeKind.CONSTANTARRAY
265 assert c.type.element_type.kind == TypeKind.INT
266 assert i.type.kind == TypeKind.INCOMPLETEARRAY
Gregory Szorc86057602012-02-17 07:44:46 +0000267 assert i.type.element_type.kind == TypeKind.INT
Argyrios Kyrtzidis4c4f6fe2013-07-23 17:36:21 +0000268 assert v.type.kind == TypeKind.VARIABLEARRAY
269 assert v.type.element_type.kind == TypeKind.INT
Gregory Szorc86057602012-02-17 07:44:46 +0000270
271@raises(Exception)
272def test_invalid_element_type():
273 """Ensure Type.element_type raises if type doesn't have elements."""
Gregory Szorc31cc38c2012-02-19 18:28:33 +0000274 tu = get_tu('int i;')
Gregory Szorc826fce52012-02-20 17:45:30 +0000275 i = get_cursor(tu, 'i')
Gregory Szorc31cc38c2012-02-19 18:28:33 +0000276 assert i is not None
Gregory Szorc86057602012-02-17 07:44:46 +0000277 i.element_type
Gregory Szorcbf8ca002012-02-17 07:47:38 +0000278
279def test_element_count():
Gregory Szorc82613452012-02-20 17:58:40 +0000280 """Ensure Type.element_count works."""
Gregory Szorc31cc38c2012-02-19 18:28:33 +0000281 tu = get_tu('int i[5]; int j;')
Gregory Szorc826fce52012-02-20 17:45:30 +0000282 i = get_cursor(tu, 'i')
283 j = get_cursor(tu, 'j')
Gregory Szorcbf8ca002012-02-17 07:47:38 +0000284
285 assert i is not None
286 assert j is not None
287
288 assert i.type.element_count == 5
289
290 try:
291 j.type.element_count
292 assert False
293 except:
294 assert True
Gregory Szorc0e1f4f82012-02-20 17:58:02 +0000295
296def test_is_volatile_qualified():
297 """Ensure Type.is_volatile_qualified works."""
298
299 tu = get_tu('volatile int i = 4; int j = 2;')
300
301 i = get_cursor(tu, 'i')
302 j = get_cursor(tu, 'j')
303
304 assert i is not None
305 assert j is not None
306
307 assert isinstance(i.type.is_volatile_qualified(), bool)
308 assert i.type.is_volatile_qualified()
309 assert not j.type.is_volatile_qualified()
310
311def test_is_restrict_qualified():
312 """Ensure Type.is_restrict_qualified works."""
313
Anders Waldenborge1f61c02012-05-02 19:35:37 +0000314 tu = get_tu('struct s { void * restrict i; void * j; };')
Gregory Szorc0e1f4f82012-02-20 17:58:02 +0000315
316 i = get_cursor(tu, 'i')
317 j = get_cursor(tu, 'j')
318
319 assert i is not None
320 assert j is not None
321
322 assert isinstance(i.type.is_restrict_qualified(), bool)
323 assert i.type.is_restrict_qualified()
324 assert not j.type.is_restrict_qualified()
Argyrios Kyrtzidis411d33a2013-04-11 01:20:11 +0000325
326def test_record_layout():
327 """Ensure Cursor.type.get_size, Cursor.type.get_align and
328 Cursor.type.get_offset works."""
329
330 source ="""
331struct a {
332 long a1;
333 long a2:3;
334 long a3:4;
335 long long a4;
336};
337"""
338 tries=[(['-target','i386-linux-gnu'],(4,16,0,32,35,64)),
339 (['-target','nvptx64-unknown-unknown'],(8,24,0,64,67,128)),
340 (['-target','i386-pc-win32'],(8,16,0,32,35,64)),
341 (['-target','msp430-none-none'],(2,14,0,32,35,48))]
342 for flags, values in tries:
343 align,total,a1,a2,a3,a4 = values
344
345 tu = get_tu(source, flags=flags)
346 teststruct = get_cursor(tu, 'a')
347 fields = list(teststruct.get_children())
348
349 assert teststruct.type.get_align() == align
350 assert teststruct.type.get_size() == total
351 assert teststruct.type.get_offset(fields[0].spelling) == a1
352 assert teststruct.type.get_offset(fields[1].spelling) == a2
353 assert teststruct.type.get_offset(fields[2].spelling) == a3
354 assert teststruct.type.get_offset(fields[3].spelling) == a4
355 assert fields[0].is_bitfield() == False
356 assert fields[1].is_bitfield() == True
357 assert fields[1].get_bitfield_width() == 3
358 assert fields[2].is_bitfield() == True
359 assert fields[2].get_bitfield_width() == 4
360 assert fields[3].is_bitfield() == False
361
362def test_offset():
363 """Ensure Cursor.get_record_field_offset works in anonymous records"""
364 source="""
365struct Test {
Pirama Arumuga Nainar33337ca2015-05-06 11:48:57 -0700366 struct {int a;} typeanon;
Argyrios Kyrtzidis411d33a2013-04-11 01:20:11 +0000367 struct {
368 int bariton;
369 union {
370 int foo;
371 };
372 };
373 int bar;
374};"""
Pirama Arumuga Nainar33337ca2015-05-06 11:48:57 -0700375 tries=[(['-target','i386-linux-gnu'],(4,16,0,32,64,96)),
376 (['-target','nvptx64-unknown-unknown'],(8,24,0,32,64,96)),
377 (['-target','i386-pc-win32'],(8,16,0,32,64,96)),
378 (['-target','msp430-none-none'],(2,14,0,32,64,96))]
Argyrios Kyrtzidis411d33a2013-04-11 01:20:11 +0000379 for flags, values in tries:
Pirama Arumuga Nainar33337ca2015-05-06 11:48:57 -0700380 align,total,f1,bariton,foo,bar = values
Argyrios Kyrtzidis411d33a2013-04-11 01:20:11 +0000381 tu = get_tu(source)
382 teststruct = get_cursor(tu, 'Test')
Pirama Arumuga Nainar33337ca2015-05-06 11:48:57 -0700383 children = list(teststruct.get_children())
384 fields = list(teststruct.type.get_fields())
385 assert children[0].kind == CursorKind.STRUCT_DECL
386 assert children[0].spelling != "typeanon"
387 assert children[1].spelling == "typeanon"
388 assert fields[0].kind == CursorKind.FIELD_DECL
389 assert fields[1].kind == CursorKind.FIELD_DECL
390 assert fields[1].is_anonymous()
391 assert teststruct.type.get_offset("typeanon") == f1
Argyrios Kyrtzidis411d33a2013-04-11 01:20:11 +0000392 assert teststruct.type.get_offset("bariton") == bariton
393 assert teststruct.type.get_offset("foo") == foo
394 assert teststruct.type.get_offset("bar") == bar
395
396
Argyrios Kyrtzidis7a97f7b2013-09-16 17:26:23 +0000397def test_decay():
398 """Ensure decayed types are handled as the original type"""
399
400 tu = get_tu("void foo(int a[]);")
401 foo = get_cursor(tu, 'foo')
402 a = foo.type.argument_types()[0]
403
404 assert a.kind == TypeKind.INCOMPLETEARRAY
405 assert a.element_type.kind == TypeKind.INT
406 assert a.get_canonical().kind == TypeKind.INCOMPLETEARRAY