]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - bindings/python/tests/cindex/test_type.py
Vendor import of clang tags/RELEASE_33/final r183502 (effectively, 3.3
[FreeBSD/FreeBSD.git] / bindings / python / tests / cindex / test_type.py
1 import gc
2
3 from clang.cindex import CursorKind
4 from clang.cindex import TranslationUnit
5 from clang.cindex import TypeKind
6 from nose.tools import raises
7 from .util import get_cursor
8 from .util import get_tu
9
10 kInput = """\
11
12 typedef int I;
13
14 struct 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
27 def test_a_struct():
28     tu = get_tu(kInput)
29
30     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)
34     assert all(x.translation_unit is not None for x in fields)
35
36     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
40
41     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'
46
47     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
51
52     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
56
57     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
61
62     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
66
67     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
71
72     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
78
79 def 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
99 constarrayInput="""
100 struct teststruct {
101   void *A[2];
102 };
103 """
104 def testConstantArray():
105     tu = get_tu(constarrayInput)
106
107     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
115
116 def test_equal():
117     """Ensure equivalence operators work on Type."""
118     source = 'int a; int b; void *v;'
119     tu = get_tu(source)
120
121     a = get_cursor(tu, 'a')
122     b = get_cursor(tu, 'b')
123     v = get_cursor(tu, 'v')
124
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
135 def 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
143 def 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)
167 def 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)
179 def 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)
188 def 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)
197 def 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
205 def test_is_pod():
206     """Ensure Type.is_pod() works."""
207     tu = get_tu('int i; void f();')
208     i = get_cursor(tu, 'i')
209     f = get_cursor(tu, 'f')
210
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()
216
217 def test_function_variadic():
218     """Ensure Type.is_function_variadic works."""
219
220     source ="""
221 #include <stdarg.h>
222
223 void foo(int a, ...);
224 void bar(int a, int b);
225 """
226
227     tu = get_tu(source)
228     foo = get_cursor(tu, 'foo')
229     bar = get_cursor(tu, 'bar')
230
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
238 def test_element_type():
239     """Ensure Type.element_type works."""
240     tu = get_tu('int i[5];')
241     i = get_cursor(tu, 'i')
242     assert i is not None
243
244     assert i.type.kind == TypeKind.CONSTANTARRAY
245     assert i.type.element_type.kind == TypeKind.INT
246
247 @raises(Exception)
248 def test_invalid_element_type():
249     """Ensure Type.element_type raises if type doesn't have elements."""
250     tu = get_tu('int i;')
251     i = get_cursor(tu, 'i')
252     assert i is not None
253     i.element_type
254
255 def test_element_count():
256     """Ensure Type.element_count works."""
257     tu = get_tu('int i[5]; int j;')
258     i = get_cursor(tu, 'i')
259     j = get_cursor(tu, 'j')
260
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
271
272 def 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
287 def test_is_restrict_qualified():
288     """Ensure Type.is_restrict_qualified works."""
289
290     tu = get_tu('struct s { void * restrict i; void * j; };')
291
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()
301
302 def test_record_layout():
303     """Ensure Cursor.type.get_size, Cursor.type.get_align and
304     Cursor.type.get_offset works."""
305
306     source ="""
307 struct 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
338 def test_offset():
339     """Ensure Cursor.get_record_field_offset works in anonymous records"""
340     source="""
341 struct 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