blob: e4cd245c9cb4e5dda1750ce20e7a98ce514f84de [file] [log] [blame]
Gregory Szorc0e1f4f82012-02-20 17:58:02 +00001from clang.cindex import Cursor
Gregory Szorc86057602012-02-17 07:44:46 +00002from clang.cindex import CursorKind
3from clang.cindex import Index
4from clang.cindex import TypeKind
Gregory Szorc86057602012-02-17 07:44:46 +00005from nose.tools import raises
Argyrios Kyrtzidis2312f5f2011-08-17 17:01:10 +00006
7kInput = """\
8
9typedef int I;
10
11struct teststruct {
12 int a;
13 I b;
14 long c;
15 unsigned long d;
16 signed long e;
17 const int f;
18 int *g;
19 int ***h;
20};
21
22"""
23
Gregory Szorc31cc38c2012-02-19 18:28:33 +000024def get_tu(source=kInput, lang='c'):
25 name = 't.c'
26 if lang == 'cpp':
27 name = 't.cpp'
28
Argyrios Kyrtzidis2312f5f2011-08-17 17:01:10 +000029 index = Index.create()
Gregory Szorc31cc38c2012-02-19 18:28:33 +000030 tu = index.parse(name, unsaved_files=[(name, source)])
31 assert tu is not None
32 return tu
33
Gregory Szorc0e1f4f82012-02-20 17:58:02 +000034def get_cursor(source, spelling):
35 children = []
36 if isinstance(source, Cursor):
37 children = source.get_children()
38 else:
39 # Assume TU
40 children = source.cursor.get_children()
41
42 for cursor in children:
Gregory Szorc826fce52012-02-20 17:45:30 +000043 if cursor.spelling == spelling:
44 return cursor
45
Gregory Szorc0e1f4f82012-02-20 17:58:02 +000046 # Recurse into children.
47 result = get_cursor(cursor, spelling)
48 if result is not None:
49 return result
50
Gregory Szorc826fce52012-02-20 17:45:30 +000051 return None
52
Gregory Szorc31cc38c2012-02-19 18:28:33 +000053def test_a_struct():
54 tu = get_tu(kInput)
Argyrios Kyrtzidis2312f5f2011-08-17 17:01:10 +000055
Gregory Szorc826fce52012-02-20 17:45:30 +000056 teststruct = get_cursor(tu, 'teststruct')
57 assert teststruct is not None, "Could not find teststruct."
58 fields = list(teststruct.get_children())
59 assert all(x.kind == CursorKind.FIELD_DECL for x in fields)
Argyrios Kyrtzidis2312f5f2011-08-17 17:01:10 +000060
Gregory Szorc826fce52012-02-20 17:45:30 +000061 assert fields[0].spelling == 'a'
62 assert not fields[0].type.is_const_qualified()
63 assert fields[0].type.kind == TypeKind.INT
64 assert fields[0].type.get_canonical().kind == TypeKind.INT
Argyrios Kyrtzidis2312f5f2011-08-17 17:01:10 +000065
Gregory Szorc826fce52012-02-20 17:45:30 +000066 assert fields[1].spelling == 'b'
67 assert not fields[1].type.is_const_qualified()
68 assert fields[1].type.kind == TypeKind.TYPEDEF
69 assert fields[1].type.get_canonical().kind == TypeKind.INT
70 assert fields[1].type.get_declaration().spelling == 'I'
Argyrios Kyrtzidis2312f5f2011-08-17 17:01:10 +000071
Gregory Szorc826fce52012-02-20 17:45:30 +000072 assert fields[2].spelling == 'c'
73 assert not fields[2].type.is_const_qualified()
74 assert fields[2].type.kind == TypeKind.LONG
75 assert fields[2].type.get_canonical().kind == TypeKind.LONG
Argyrios Kyrtzidis2312f5f2011-08-17 17:01:10 +000076
Gregory Szorc826fce52012-02-20 17:45:30 +000077 assert fields[3].spelling == 'd'
78 assert not fields[3].type.is_const_qualified()
79 assert fields[3].type.kind == TypeKind.ULONG
80 assert fields[3].type.get_canonical().kind == TypeKind.ULONG
Argyrios Kyrtzidis2312f5f2011-08-17 17:01:10 +000081
Gregory Szorc826fce52012-02-20 17:45:30 +000082 assert fields[4].spelling == 'e'
83 assert not fields[4].type.is_const_qualified()
84 assert fields[4].type.kind == TypeKind.LONG
85 assert fields[4].type.get_canonical().kind == TypeKind.LONG
Argyrios Kyrtzidis2312f5f2011-08-17 17:01:10 +000086
Gregory Szorc826fce52012-02-20 17:45:30 +000087 assert fields[5].spelling == 'f'
88 assert fields[5].type.is_const_qualified()
89 assert fields[5].type.kind == TypeKind.INT
90 assert fields[5].type.get_canonical().kind == TypeKind.INT
Argyrios Kyrtzidis2312f5f2011-08-17 17:01:10 +000091
Gregory Szorc826fce52012-02-20 17:45:30 +000092 assert fields[6].spelling == 'g'
93 assert not fields[6].type.is_const_qualified()
94 assert fields[6].type.kind == TypeKind.POINTER
95 assert fields[6].type.get_pointee().kind == TypeKind.INT
Argyrios Kyrtzidis2312f5f2011-08-17 17:01:10 +000096
Gregory Szorc826fce52012-02-20 17:45:30 +000097 assert fields[7].spelling == 'h'
98 assert not fields[7].type.is_const_qualified()
99 assert fields[7].type.kind == TypeKind.POINTER
100 assert fields[7].type.get_pointee().kind == TypeKind.POINTER
101 assert fields[7].type.get_pointee().get_pointee().kind == TypeKind.POINTER
102 assert fields[7].type.get_pointee().get_pointee().get_pointee().kind == TypeKind.INT
Douglas Gregor38d2d552011-10-19 05:50:34 +0000103
104constarrayInput="""
105struct teststruct {
106 void *A[2];
107};
108"""
109def testConstantArray():
Gregory Szorc31cc38c2012-02-19 18:28:33 +0000110 tu = get_tu(constarrayInput)
Douglas Gregor38d2d552011-10-19 05:50:34 +0000111
Gregory Szorc826fce52012-02-20 17:45:30 +0000112 teststruct = get_cursor(tu, 'teststruct')
113 assert teststruct is not None, "Didn't find teststruct??"
114 fields = list(teststruct.get_children())
115 assert fields[0].spelling == 'A'
116 assert fields[0].type.kind == TypeKind.CONSTANTARRAY
117 assert fields[0].type.get_array_element_type() is not None
118 assert fields[0].type.get_array_element_type().kind == TypeKind.POINTER
119 assert fields[0].type.get_array_size() == 2
Gregory Szorc96ad6332012-02-05 19:42:06 +0000120
Gregory Szorc7eb691a2012-02-20 17:44:49 +0000121def test_equal():
122 """Ensure equivalence operators work on Type."""
123 source = 'int a; int b; void *v;'
124 tu = get_tu(source)
125
Gregory Szorc826fce52012-02-20 17:45:30 +0000126 a = get_cursor(tu, 'a')
127 b = get_cursor(tu, 'b')
128 v = get_cursor(tu, 'v')
Gregory Szorc7eb691a2012-02-20 17:44:49 +0000129
130 assert a is not None
131 assert b is not None
132 assert v is not None
133
134 assert a.type == b.type
135 assert a.type != v.type
136
137 assert a.type != None
138 assert a.type != 'foo'
139
Gregory Szorc826fce52012-02-20 17:45:30 +0000140def test_function_argument_types():
141 """Ensure that Type.argument_types() works as expected."""
142 tu = get_tu('void f(int, int);')
143 f = get_cursor(tu, 'f')
144 assert f is not None
145
146 args = f.type.argument_types()
147 assert args is not None
148 assert len(args) == 2
149
150 t0 = args[0]
151 assert t0 is not None
152 assert t0.kind == TypeKind.INT
153
154 t1 = args[1]
155 assert t1 is not None
156 assert t1.kind == TypeKind.INT
157
158 args2 = list(args)
159 assert len(args2) == 2
160 assert t0 == args2[0]
161 assert t1 == args2[1]
162
163@raises(TypeError)
164def test_argument_types_string_key():
165 """Ensure that non-int keys raise a TypeError."""
166 tu = get_tu('void f(int, int);')
167 f = get_cursor(tu, 'f')
168 assert f is not None
169
170 args = f.type.argument_types()
171 assert len(args) == 2
172
173 args['foo']
174
175@raises(IndexError)
176def test_argument_types_negative_index():
177 """Ensure that negative indexes on argument_types Raises an IndexError."""
178 tu = get_tu('void f(int, int);')
179 f = get_cursor(tu, 'f')
180 args = f.type.argument_types()
181
182 args[-1]
183
184@raises(IndexError)
185def test_argument_types_overflow_index():
186 """Ensure that indexes beyond the length of Type.argument_types() raise."""
187 tu = get_tu('void f(int, int);')
188 f = get_cursor(tu, 'f')
189 args = f.type.argument_types()
190
191 args[2]
192
193@raises(Exception)
194def test_argument_types_invalid_type():
195 """Ensure that obtaining argument_types on a Type without them raises."""
196 tu = get_tu('int i;')
197 i = get_cursor(tu, 'i')
198 assert i is not None
199
200 i.type.argument_types()
201
Gregory Szorc96ad6332012-02-05 19:42:06 +0000202def test_is_pod():
Gregory Szorc82613452012-02-20 17:58:40 +0000203 """Ensure Type.is_pod() works."""
Gregory Szorc31cc38c2012-02-19 18:28:33 +0000204 tu = get_tu('int i; void f();')
Gregory Szorc826fce52012-02-20 17:45:30 +0000205 i = get_cursor(tu, 'i')
206 f = get_cursor(tu, 'f')
Gregory Szorc96ad6332012-02-05 19:42:06 +0000207
208 assert i is not None
209 assert f is not None
210
211 assert i.type.is_pod()
212 assert not f.type.is_pod()
Gregory Szorc86057602012-02-17 07:44:46 +0000213
Gregory Szorc31cc38c2012-02-19 18:28:33 +0000214def test_function_variadic():
215 """Ensure Type.is_function_variadic works."""
Gregory Szorc86057602012-02-17 07:44:46 +0000216
Gregory Szorc31cc38c2012-02-19 18:28:33 +0000217 source ="""
218#include <stdarg.h>
219
220void foo(int a, ...);
221void bar(int a, int b);
222"""
223
224 tu = get_tu(source)
Gregory Szorc826fce52012-02-20 17:45:30 +0000225 foo = get_cursor(tu, 'foo')
226 bar = get_cursor(tu, 'bar')
Gregory Szorc31cc38c2012-02-19 18:28:33 +0000227
228 assert foo is not None
229 assert bar is not None
230
231 assert isinstance(foo.type.is_function_variadic(), bool)
232 assert foo.type.is_function_variadic()
233 assert not bar.type.is_function_variadic()
234
235def test_element_type():
Gregory Szorc82613452012-02-20 17:58:40 +0000236 """Ensure Type.element_type works."""
Gregory Szorc31cc38c2012-02-19 18:28:33 +0000237 tu = get_tu('int i[5];')
Gregory Szorc826fce52012-02-20 17:45:30 +0000238 i = get_cursor(tu, 'i')
Gregory Szorc31cc38c2012-02-19 18:28:33 +0000239 assert i is not None
240
Gregory Szorc86057602012-02-17 07:44:46 +0000241 assert i.type.kind == TypeKind.CONSTANTARRAY
242 assert i.type.element_type.kind == TypeKind.INT
243
244@raises(Exception)
245def test_invalid_element_type():
246 """Ensure Type.element_type raises if type doesn't have elements."""
Gregory Szorc31cc38c2012-02-19 18:28:33 +0000247 tu = get_tu('int i;')
Gregory Szorc826fce52012-02-20 17:45:30 +0000248 i = get_cursor(tu, 'i')
Gregory Szorc31cc38c2012-02-19 18:28:33 +0000249 assert i is not None
Gregory Szorc86057602012-02-17 07:44:46 +0000250 i.element_type
Gregory Szorcbf8ca002012-02-17 07:47:38 +0000251
252def test_element_count():
Gregory Szorc82613452012-02-20 17:58:40 +0000253 """Ensure Type.element_count works."""
Gregory Szorc31cc38c2012-02-19 18:28:33 +0000254 tu = get_tu('int i[5]; int j;')
Gregory Szorc826fce52012-02-20 17:45:30 +0000255 i = get_cursor(tu, 'i')
256 j = get_cursor(tu, 'j')
Gregory Szorcbf8ca002012-02-17 07:47:38 +0000257
258 assert i is not None
259 assert j is not None
260
261 assert i.type.element_count == 5
262
263 try:
264 j.type.element_count
265 assert False
266 except:
267 assert True
Gregory Szorc0e1f4f82012-02-20 17:58:02 +0000268
269def test_is_volatile_qualified():
270 """Ensure Type.is_volatile_qualified works."""
271
272 tu = get_tu('volatile int i = 4; int j = 2;')
273
274 i = get_cursor(tu, 'i')
275 j = get_cursor(tu, 'j')
276
277 assert i is not None
278 assert j is not None
279
280 assert isinstance(i.type.is_volatile_qualified(), bool)
281 assert i.type.is_volatile_qualified()
282 assert not j.type.is_volatile_qualified()
283
284def test_is_restrict_qualified():
285 """Ensure Type.is_restrict_qualified works."""
286
287 tu = get_tu('struct s { void * restrict i; void * j };')
288
289 i = get_cursor(tu, 'i')
290 j = get_cursor(tu, 'j')
291
292 assert i is not None
293 assert j is not None
294
295 assert isinstance(i.type.is_restrict_qualified(), bool)
296 assert i.type.is_restrict_qualified()
297 assert not j.type.is_restrict_qualified()