blob: 9bbed5aa940ed8e0eaaa678e5da115e57bbe0a98 [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
Gregory Szorc6e67eed2012-04-15 18:51:10 +0000135def test_typekind_spelling():
136 """Ensure TypeKind.spelling works."""
137 tu = get_tu('int a;')
138 a = get_cursor(tu, 'a')
139
140 assert a is not None
141 assert a.type.kind.spelling == 'Int'
142
Gregory Szorc826fce52012-02-20 17:45:30 +0000143def test_function_argument_types():
144 """Ensure that Type.argument_types() works as expected."""
145 tu = get_tu('void f(int, int);')
146 f = get_cursor(tu, 'f')
147 assert f is not None
148
149 args = f.type.argument_types()
150 assert args is not None
151 assert len(args) == 2
152
153 t0 = args[0]
154 assert t0 is not None
155 assert t0.kind == TypeKind.INT
156
157 t1 = args[1]
158 assert t1 is not None
159 assert t1.kind == TypeKind.INT
160
161 args2 = list(args)
162 assert len(args2) == 2
163 assert t0 == args2[0]
164 assert t1 == args2[1]
165
166@raises(TypeError)
167def test_argument_types_string_key():
168 """Ensure that non-int keys raise a TypeError."""
169 tu = get_tu('void f(int, int);')
170 f = get_cursor(tu, 'f')
171 assert f is not None
172
173 args = f.type.argument_types()
174 assert len(args) == 2
175
176 args['foo']
177
178@raises(IndexError)
179def test_argument_types_negative_index():
180 """Ensure that negative indexes on argument_types Raises an IndexError."""
181 tu = get_tu('void f(int, int);')
182 f = get_cursor(tu, 'f')
183 args = f.type.argument_types()
184
185 args[-1]
186
187@raises(IndexError)
188def test_argument_types_overflow_index():
189 """Ensure that indexes beyond the length of Type.argument_types() raise."""
190 tu = get_tu('void f(int, int);')
191 f = get_cursor(tu, 'f')
192 args = f.type.argument_types()
193
194 args[2]
195
196@raises(Exception)
197def test_argument_types_invalid_type():
198 """Ensure that obtaining argument_types on a Type without them raises."""
199 tu = get_tu('int i;')
200 i = get_cursor(tu, 'i')
201 assert i is not None
202
203 i.type.argument_types()
204
Gregory Szorc96ad6332012-02-05 19:42:06 +0000205def test_is_pod():
Gregory Szorc82613452012-02-20 17:58:40 +0000206 """Ensure Type.is_pod() works."""
Gregory Szorc31cc38c2012-02-19 18:28:33 +0000207 tu = get_tu('int i; void f();')
Gregory Szorc826fce52012-02-20 17:45:30 +0000208 i = get_cursor(tu, 'i')
209 f = get_cursor(tu, 'f')
Gregory Szorc96ad6332012-02-05 19:42:06 +0000210
211 assert i is not None
212 assert f is not None
213
214 assert i.type.is_pod()
215 assert not f.type.is_pod()
Gregory Szorc86057602012-02-17 07:44:46 +0000216
Gregory Szorc31cc38c2012-02-19 18:28:33 +0000217def test_function_variadic():
218 """Ensure Type.is_function_variadic works."""
Gregory Szorc86057602012-02-17 07:44:46 +0000219
Gregory Szorc31cc38c2012-02-19 18:28:33 +0000220 source ="""
221#include <stdarg.h>
222
223void foo(int a, ...);
224void bar(int a, int b);
225"""
226
227 tu = get_tu(source)
Gregory Szorc826fce52012-02-20 17:45:30 +0000228 foo = get_cursor(tu, 'foo')
229 bar = get_cursor(tu, 'bar')
Gregory Szorc31cc38c2012-02-19 18:28:33 +0000230
231 assert foo is not None
232 assert bar is not None
233
234 assert isinstance(foo.type.is_function_variadic(), bool)
235 assert foo.type.is_function_variadic()
236 assert not bar.type.is_function_variadic()
237
238def test_element_type():
Gregory Szorc82613452012-02-20 17:58:40 +0000239 """Ensure Type.element_type works."""
Gregory Szorc31cc38c2012-02-19 18:28:33 +0000240 tu = get_tu('int i[5];')
Gregory Szorc826fce52012-02-20 17:45:30 +0000241 i = get_cursor(tu, 'i')
Gregory Szorc31cc38c2012-02-19 18:28:33 +0000242 assert i is not None
243
Gregory Szorc86057602012-02-17 07:44:46 +0000244 assert i.type.kind == TypeKind.CONSTANTARRAY
245 assert i.type.element_type.kind == TypeKind.INT
246
247@raises(Exception)
248def test_invalid_element_type():
249 """Ensure Type.element_type raises if type doesn't have elements."""
Gregory Szorc31cc38c2012-02-19 18:28:33 +0000250 tu = get_tu('int i;')
Gregory Szorc826fce52012-02-20 17:45:30 +0000251 i = get_cursor(tu, 'i')
Gregory Szorc31cc38c2012-02-19 18:28:33 +0000252 assert i is not None
Gregory Szorc86057602012-02-17 07:44:46 +0000253 i.element_type
Gregory Szorcbf8ca002012-02-17 07:47:38 +0000254
255def test_element_count():
Gregory Szorc82613452012-02-20 17:58:40 +0000256 """Ensure Type.element_count works."""
Gregory Szorc31cc38c2012-02-19 18:28:33 +0000257 tu = get_tu('int i[5]; int j;')
Gregory Szorc826fce52012-02-20 17:45:30 +0000258 i = get_cursor(tu, 'i')
259 j = get_cursor(tu, 'j')
Gregory Szorcbf8ca002012-02-17 07:47:38 +0000260
261 assert i is not None
262 assert j is not None
263
264 assert i.type.element_count == 5
265
266 try:
267 j.type.element_count
268 assert False
269 except:
270 assert True
Gregory Szorc0e1f4f82012-02-20 17:58:02 +0000271
272def test_is_volatile_qualified():
273 """Ensure Type.is_volatile_qualified works."""
274
275 tu = get_tu('volatile int i = 4; int j = 2;')
276
277 i = get_cursor(tu, 'i')
278 j = get_cursor(tu, 'j')
279
280 assert i is not None
281 assert j is not None
282
283 assert isinstance(i.type.is_volatile_qualified(), bool)
284 assert i.type.is_volatile_qualified()
285 assert not j.type.is_volatile_qualified()
286
287def test_is_restrict_qualified():
288 """Ensure Type.is_restrict_qualified works."""
289
Anders Waldenborge1f61c02012-05-02 19:35:37 +0000290 tu = get_tu('struct s { void * restrict i; void * j; };')
Gregory Szorc0e1f4f82012-02-20 17:58:02 +0000291
292 i = get_cursor(tu, 'i')
293 j = get_cursor(tu, 'j')
294
295 assert i is not None
296 assert j is not None
297
298 assert isinstance(i.type.is_restrict_qualified(), bool)
299 assert i.type.is_restrict_qualified()
300 assert not j.type.is_restrict_qualified()
Argyrios Kyrtzidis411d33a2013-04-11 01:20:11 +0000301
302def test_record_layout():
303 """Ensure Cursor.type.get_size, Cursor.type.get_align and
304 Cursor.type.get_offset works."""
305
306 source ="""
307struct a {
308 long a1;
309 long a2:3;
310 long a3:4;
311 long long a4;
312};
313"""
314 tries=[(['-target','i386-linux-gnu'],(4,16,0,32,35,64)),
315 (['-target','nvptx64-unknown-unknown'],(8,24,0,64,67,128)),
316 (['-target','i386-pc-win32'],(8,16,0,32,35,64)),
317 (['-target','msp430-none-none'],(2,14,0,32,35,48))]
318 for flags, values in tries:
319 align,total,a1,a2,a3,a4 = values
320
321 tu = get_tu(source, flags=flags)
322 teststruct = get_cursor(tu, 'a')
323 fields = list(teststruct.get_children())
324
325 assert teststruct.type.get_align() == align
326 assert teststruct.type.get_size() == total
327 assert teststruct.type.get_offset(fields[0].spelling) == a1
328 assert teststruct.type.get_offset(fields[1].spelling) == a2
329 assert teststruct.type.get_offset(fields[2].spelling) == a3
330 assert teststruct.type.get_offset(fields[3].spelling) == a4
331 assert fields[0].is_bitfield() == False
332 assert fields[1].is_bitfield() == True
333 assert fields[1].get_bitfield_width() == 3
334 assert fields[2].is_bitfield() == True
335 assert fields[2].get_bitfield_width() == 4
336 assert fields[3].is_bitfield() == False
337
338def test_offset():
339 """Ensure Cursor.get_record_field_offset works in anonymous records"""
340 source="""
341struct Test {
342 struct {
343 int bariton;
344 union {
345 int foo;
346 };
347 };
348 int bar;
349};"""
350 tries=[(['-target','i386-linux-gnu'],(4,16,0,32,64)),
351 (['-target','nvptx64-unknown-unknown'],(8,24,0,32,64)),
352 (['-target','i386-pc-win32'],(8,16,0,32,64)),
353 (['-target','msp430-none-none'],(2,14,0,32,64))]
354 for flags, values in tries:
355 align,total,bariton,foo,bar = values
356 tu = get_tu(source)
357 teststruct = get_cursor(tu, 'Test')
358 fields = list(teststruct.get_children())
359 assert teststruct.type.get_offset("bariton") == bariton
360 assert teststruct.type.get_offset("foo") == foo
361 assert teststruct.type.get_offset("bar") == bar
362
363