1 | import os |
2 | from clang.cindex import Config |
3 | if 'CLANG_LIBRARY_PATH' in os.environ: |
4 | Config.set_library_path(os.environ['CLANG_LIBRARY_PATH']) |
5 | |
6 | import ctypes |
7 | import gc |
8 | import unittest |
9 | |
10 | from clang.cindex import AvailabilityKind |
11 | from clang.cindex import CursorKind |
12 | from clang.cindex import TemplateArgumentKind |
13 | from clang.cindex import TranslationUnit |
14 | from clang.cindex import TypeKind |
15 | from .util import get_cursor |
16 | from .util import get_cursors |
17 | from .util import get_tu |
18 | |
19 | |
20 | kInput = """\ |
21 | struct s0 { |
22 | int a; |
23 | int b; |
24 | }; |
25 | |
26 | struct s1; |
27 | |
28 | void f0(int a0, int a1) { |
29 | int l0, l1; |
30 | |
31 | if (a0) |
32 | return; |
33 | |
34 | for (;;) { |
35 | break; |
36 | } |
37 | } |
38 | """ |
39 | |
40 | kParentTest = """\ |
41 | class C { |
42 | void f(); |
43 | } |
44 | |
45 | void C::f() { } |
46 | """ |
47 | |
48 | kTemplateArgTest = """\ |
49 | template <int kInt, typename T, bool kBool> |
50 | void foo(); |
51 | |
52 | template<> |
53 | void foo<-7, float, true>(); |
54 | """ |
55 | |
56 | class TestCursor(unittest.TestCase): |
57 | def test_get_children(self): |
58 | tu = get_tu(kInput) |
59 | |
60 | it = tu.cursor.get_children() |
61 | tu_nodes = list(it) |
62 | |
63 | self.assertEqual(len(tu_nodes), 3) |
64 | for cursor in tu_nodes: |
65 | self.assertIsNotNone(cursor.translation_unit) |
66 | |
67 | self.assertNotEqual(tu_nodes[0], tu_nodes[1]) |
68 | self.assertEqual(tu_nodes[0].kind, CursorKind.STRUCT_DECL) |
69 | self.assertEqual(tu_nodes[0].spelling, 's0') |
70 | self.assertEqual(tu_nodes[0].is_definition(), True) |
71 | self.assertEqual(tu_nodes[0].location.file.name, 't.c') |
72 | self.assertEqual(tu_nodes[0].location.line, 1) |
73 | self.assertEqual(tu_nodes[0].location.column, 8) |
74 | self.assertGreater(tu_nodes[0].hash, 0) |
75 | self.assertIsNotNone(tu_nodes[0].translation_unit) |
76 | |
77 | s0_nodes = list(tu_nodes[0].get_children()) |
78 | self.assertEqual(len(s0_nodes), 2) |
79 | self.assertEqual(s0_nodes[0].kind, CursorKind.FIELD_DECL) |
80 | self.assertEqual(s0_nodes[0].spelling, 'a') |
81 | self.assertEqual(s0_nodes[0].type.kind, TypeKind.INT) |
82 | self.assertEqual(s0_nodes[1].kind, CursorKind.FIELD_DECL) |
83 | self.assertEqual(s0_nodes[1].spelling, 'b') |
84 | self.assertEqual(s0_nodes[1].type.kind, TypeKind.INT) |
85 | |
86 | self.assertEqual(tu_nodes[1].kind, CursorKind.STRUCT_DECL) |
87 | self.assertEqual(tu_nodes[1].spelling, 's1') |
88 | self.assertEqual(tu_nodes[1].displayname, 's1') |
89 | self.assertEqual(tu_nodes[1].is_definition(), False) |
90 | |
91 | self.assertEqual(tu_nodes[2].kind, CursorKind.FUNCTION_DECL) |
92 | self.assertEqual(tu_nodes[2].spelling, 'f0') |
93 | self.assertEqual(tu_nodes[2].displayname, 'f0(int, int)') |
94 | self.assertEqual(tu_nodes[2].is_definition(), True) |
95 | |
96 | def test_references(self): |
97 | """Ensure that references to TranslationUnit are kept.""" |
98 | tu = get_tu('int x;') |
99 | cursors = list(tu.cursor.get_children()) |
100 | self.assertGreater(len(cursors), 0) |
101 | |
102 | cursor = cursors[0] |
103 | self.assertIsInstance(cursor.translation_unit, TranslationUnit) |
104 | |
105 | # Delete reference to TU and perform a full GC. |
106 | del tu |
107 | gc.collect() |
108 | self.assertIsInstance(cursor.translation_unit, TranslationUnit) |
109 | |
110 | # If the TU was destroyed, this should cause a segfault. |
111 | parent = cursor.semantic_parent |
112 | |
113 | def test_canonical(self): |
114 | source = 'struct X; struct X; struct X { int member; };' |
115 | tu = get_tu(source) |
116 | |
117 | cursors = [] |
118 | for cursor in tu.cursor.get_children(): |
119 | if cursor.spelling == 'X': |
120 | cursors.append(cursor) |
121 | |
122 | self.assertEqual(len(cursors), 3) |
123 | self.assertEqual(cursors[1].canonical, cursors[2].canonical) |
124 | |
125 | def test_is_const_method(self): |
126 | """Ensure Cursor.is_const_method works.""" |
127 | source = 'class X { void foo() const; void bar(); };' |
128 | tu = get_tu(source, lang='cpp') |
129 | |
130 | cls = get_cursor(tu, 'X') |
131 | foo = get_cursor(tu, 'foo') |
132 | bar = get_cursor(tu, 'bar') |
133 | self.assertIsNotNone(cls) |
134 | self.assertIsNotNone(foo) |
135 | self.assertIsNotNone(bar) |
136 | |
137 | self.assertTrue(foo.is_const_method()) |
138 | self.assertFalse(bar.is_const_method()) |
139 | |
140 | def test_is_converting_constructor(self): |
141 | """Ensure Cursor.is_converting_constructor works.""" |
142 | source = 'class X { explicit X(int); X(double); X(); };' |
143 | tu = get_tu(source, lang='cpp') |
144 | |
145 | xs = get_cursors(tu, 'X') |
146 | |
147 | self.assertEqual(len(xs), 4) |
148 | self.assertEqual(xs[0].kind, CursorKind.CLASS_DECL) |
149 | cs = xs[1:] |
150 | self.assertEqual(cs[0].kind, CursorKind.CONSTRUCTOR) |
151 | self.assertEqual(cs[1].kind, CursorKind.CONSTRUCTOR) |
152 | self.assertEqual(cs[2].kind, CursorKind.CONSTRUCTOR) |
153 | |
154 | self.assertFalse(cs[0].is_converting_constructor()) |
155 | self.assertTrue(cs[1].is_converting_constructor()) |
156 | self.assertFalse(cs[2].is_converting_constructor()) |
157 | |
158 | |
159 | def test_is_copy_constructor(self): |
160 | """Ensure Cursor.is_copy_constructor works.""" |
161 | source = 'class X { X(); X(const X&); X(X&&); };' |
162 | tu = get_tu(source, lang='cpp') |
163 | |
164 | xs = get_cursors(tu, 'X') |
165 | self.assertEqual(xs[0].kind, CursorKind.CLASS_DECL) |
166 | cs = xs[1:] |
167 | self.assertEqual(cs[0].kind, CursorKind.CONSTRUCTOR) |
168 | self.assertEqual(cs[1].kind, CursorKind.CONSTRUCTOR) |
169 | self.assertEqual(cs[2].kind, CursorKind.CONSTRUCTOR) |
170 | |
171 | self.assertFalse(cs[0].is_copy_constructor()) |
172 | self.assertTrue(cs[1].is_copy_constructor()) |
173 | self.assertFalse(cs[2].is_copy_constructor()) |
174 | |
175 | def test_is_default_constructor(self): |
176 | """Ensure Cursor.is_default_constructor works.""" |
177 | source = 'class X { X(); X(int); };' |
178 | tu = get_tu(source, lang='cpp') |
179 | |
180 | xs = get_cursors(tu, 'X') |
181 | self.assertEqual(xs[0].kind, CursorKind.CLASS_DECL) |
182 | cs = xs[1:] |
183 | self.assertEqual(cs[0].kind, CursorKind.CONSTRUCTOR) |
184 | self.assertEqual(cs[1].kind, CursorKind.CONSTRUCTOR) |
185 | |
186 | self.assertTrue(cs[0].is_default_constructor()) |
187 | self.assertFalse(cs[1].is_default_constructor()) |
188 | |
189 | def test_is_move_constructor(self): |
190 | """Ensure Cursor.is_move_constructor works.""" |
191 | source = 'class X { X(); X(const X&); X(X&&); };' |
192 | tu = get_tu(source, lang='cpp') |
193 | |
194 | xs = get_cursors(tu, 'X') |
195 | self.assertEqual(xs[0].kind, CursorKind.CLASS_DECL) |
196 | cs = xs[1:] |
197 | self.assertEqual(cs[0].kind, CursorKind.CONSTRUCTOR) |
198 | self.assertEqual(cs[1].kind, CursorKind.CONSTRUCTOR) |
199 | self.assertEqual(cs[2].kind, CursorKind.CONSTRUCTOR) |
200 | |
201 | self.assertFalse(cs[0].is_move_constructor()) |
202 | self.assertFalse(cs[1].is_move_constructor()) |
203 | self.assertTrue(cs[2].is_move_constructor()) |
204 | |
205 | def test_is_default_method(self): |
206 | """Ensure Cursor.is_default_method works.""" |
207 | source = 'class X { X() = default; }; class Y { Y(); };' |
208 | tu = get_tu(source, lang='cpp') |
209 | |
210 | xs = get_cursors(tu, 'X') |
211 | ys = get_cursors(tu, 'Y') |
212 | |
213 | self.assertEqual(len(xs), 2) |
214 | self.assertEqual(len(ys), 2) |
215 | |
216 | xc = xs[1] |
217 | yc = ys[1] |
218 | |
219 | self.assertTrue(xc.is_default_method()) |
220 | self.assertFalse(yc.is_default_method()) |
221 | |
222 | def test_is_mutable_field(self): |
223 | """Ensure Cursor.is_mutable_field works.""" |
224 | source = 'class X { int x_; mutable int y_; };' |
225 | tu = get_tu(source, lang='cpp') |
226 | |
227 | cls = get_cursor(tu, 'X') |
228 | x_ = get_cursor(tu, 'x_') |
229 | y_ = get_cursor(tu, 'y_') |
230 | self.assertIsNotNone(cls) |
231 | self.assertIsNotNone(x_) |
232 | self.assertIsNotNone(y_) |
233 | |
234 | self.assertFalse(x_.is_mutable_field()) |
235 | self.assertTrue(y_.is_mutable_field()) |
236 | |
237 | def test_is_static_method(self): |
238 | """Ensure Cursor.is_static_method works.""" |
239 | |
240 | source = 'class X { static void foo(); void bar(); };' |
241 | tu = get_tu(source, lang='cpp') |
242 | |
243 | cls = get_cursor(tu, 'X') |
244 | foo = get_cursor(tu, 'foo') |
245 | bar = get_cursor(tu, 'bar') |
246 | self.assertIsNotNone(cls) |
247 | self.assertIsNotNone(foo) |
248 | self.assertIsNotNone(bar) |
249 | |
250 | self.assertTrue(foo.is_static_method()) |
251 | self.assertFalse(bar.is_static_method()) |
252 | |
253 | def test_is_pure_virtual_method(self): |
254 | """Ensure Cursor.is_pure_virtual_method works.""" |
255 | source = 'class X { virtual void foo() = 0; virtual void bar(); };' |
256 | tu = get_tu(source, lang='cpp') |
257 | |
258 | cls = get_cursor(tu, 'X') |
259 | foo = get_cursor(tu, 'foo') |
260 | bar = get_cursor(tu, 'bar') |
261 | self.assertIsNotNone(cls) |
262 | self.assertIsNotNone(foo) |
263 | self.assertIsNotNone(bar) |
264 | |
265 | self.assertTrue(foo.is_pure_virtual_method()) |
266 | self.assertFalse(bar.is_pure_virtual_method()) |
267 | |
268 | def test_is_virtual_method(self): |
269 | """Ensure Cursor.is_virtual_method works.""" |
270 | source = 'class X { virtual void foo(); void bar(); };' |
271 | tu = get_tu(source, lang='cpp') |
272 | |
273 | cls = get_cursor(tu, 'X') |
274 | foo = get_cursor(tu, 'foo') |
275 | bar = get_cursor(tu, 'bar') |
276 | self.assertIsNotNone(cls) |
277 | self.assertIsNotNone(foo) |
278 | self.assertIsNotNone(bar) |
279 | |
280 | self.assertTrue(foo.is_virtual_method()) |
281 | self.assertFalse(bar.is_virtual_method()) |
282 | |
283 | def test_is_abstract_record(self): |
284 | """Ensure Cursor.is_abstract_record works.""" |
285 | source = 'struct X { virtual void x() = 0; }; struct Y : X { void x(); };' |
286 | tu = get_tu(source, lang='cpp') |
287 | |
288 | cls = get_cursor(tu, 'X') |
289 | self.assertTrue(cls.is_abstract_record()) |
290 | |
291 | cls = get_cursor(tu, 'Y') |
292 | self.assertFalse(cls.is_abstract_record()) |
293 | |
294 | def test_is_scoped_enum(self): |
295 | """Ensure Cursor.is_scoped_enum works.""" |
296 | source = 'class X {}; enum RegularEnum {}; enum class ScopedEnum {};' |
297 | tu = get_tu(source, lang='cpp') |
298 | |
299 | cls = get_cursor(tu, 'X') |
300 | regular_enum = get_cursor(tu, 'RegularEnum') |
301 | scoped_enum = get_cursor(tu, 'ScopedEnum') |
302 | self.assertIsNotNone(cls) |
303 | self.assertIsNotNone(regular_enum) |
304 | self.assertIsNotNone(scoped_enum) |
305 | |
306 | self.assertFalse(cls.is_scoped_enum()) |
307 | self.assertFalse(regular_enum.is_scoped_enum()) |
308 | self.assertTrue(scoped_enum.is_scoped_enum()) |
309 | |
310 | def test_underlying_type(self): |
311 | tu = get_tu('typedef int foo;') |
312 | typedef = get_cursor(tu, 'foo') |
313 | self.assertIsNotNone(typedef) |
314 | |
315 | self.assertTrue(typedef.kind.is_declaration()) |
316 | underlying = typedef.underlying_typedef_type |
317 | self.assertEqual(underlying.kind, TypeKind.INT) |
318 | |
319 | def test_semantic_parent(self): |
320 | tu = get_tu(kParentTest, 'cpp') |
321 | curs = get_cursors(tu, 'f') |
322 | decl = get_cursor(tu, 'C') |
323 | self.assertEqual(len(curs), 2) |
324 | self.assertEqual(curs[0].semantic_parent, curs[1].semantic_parent) |
325 | self.assertEqual(curs[0].semantic_parent, decl) |
326 | |
327 | def test_lexical_parent(self): |
328 | tu = get_tu(kParentTest, 'cpp') |
329 | curs = get_cursors(tu, 'f') |
330 | decl = get_cursor(tu, 'C') |
331 | self.assertEqual(len(curs), 2) |
332 | self.assertNotEqual(curs[0].lexical_parent, curs[1].lexical_parent) |
333 | self.assertEqual(curs[0].lexical_parent, decl) |
334 | self.assertEqual(curs[1].lexical_parent, tu.cursor) |
335 | |
336 | def test_enum_type(self): |
337 | tu = get_tu('enum TEST { FOO=1, BAR=2 };') |
338 | enum = get_cursor(tu, 'TEST') |
339 | self.assertIsNotNone(enum) |
340 | |
341 | self.assertEqual(enum.kind, CursorKind.ENUM_DECL) |
342 | enum_type = enum.enum_type |
343 | self.assertIn(enum_type.kind, (TypeKind.UINT, TypeKind.INT)) |
344 | |
345 | def test_enum_type_cpp(self): |
346 | tu = get_tu('enum TEST : long long { FOO=1, BAR=2 };', lang="cpp") |
347 | enum = get_cursor(tu, 'TEST') |
348 | self.assertIsNotNone(enum) |
349 | |
350 | self.assertEqual(enum.kind, CursorKind.ENUM_DECL) |
351 | self.assertEqual(enum.enum_type.kind, TypeKind.LONGLONG) |
352 | |
353 | def test_objc_type_encoding(self): |
354 | tu = get_tu('int i;', lang='objc') |
355 | i = get_cursor(tu, 'i') |
356 | |
357 | self.assertIsNotNone(i) |
358 | self.assertEqual(i.objc_type_encoding, 'i') |
359 | |
360 | def test_enum_values(self): |
361 | tu = get_tu('enum TEST { SPAM=1, EGG, HAM = EGG * 20};') |
362 | enum = get_cursor(tu, 'TEST') |
363 | self.assertIsNotNone(enum) |
364 | |
365 | self.assertEqual(enum.kind, CursorKind.ENUM_DECL) |
366 | |
367 | enum_constants = list(enum.get_children()) |
368 | self.assertEqual(len(enum_constants), 3) |
369 | |
370 | spam, egg, ham = enum_constants |
371 | |
372 | self.assertEqual(spam.kind, CursorKind.ENUM_CONSTANT_DECL) |
373 | self.assertEqual(spam.enum_value, 1) |
374 | self.assertEqual(egg.kind, CursorKind.ENUM_CONSTANT_DECL) |
375 | self.assertEqual(egg.enum_value, 2) |
376 | self.assertEqual(ham.kind, CursorKind.ENUM_CONSTANT_DECL) |
377 | self.assertEqual(ham.enum_value, 40) |
378 | |
379 | def test_enum_values_cpp(self): |
380 | tu = get_tu('enum TEST : long long { SPAM = -1, HAM = 0x10000000000};', lang="cpp") |
381 | enum = get_cursor(tu, 'TEST') |
382 | self.assertIsNotNone(enum) |
383 | |
384 | self.assertEqual(enum.kind, CursorKind.ENUM_DECL) |
385 | |
386 | enum_constants = list(enum.get_children()) |
387 | self.assertEqual(len(enum_constants), 2) |
388 | |
389 | spam, ham = enum_constants |
390 | |
391 | self.assertEqual(spam.kind, CursorKind.ENUM_CONSTANT_DECL) |
392 | self.assertEqual(spam.enum_value, -1) |
393 | self.assertEqual(ham.kind, CursorKind.ENUM_CONSTANT_DECL) |
394 | self.assertEqual(ham.enum_value, 0x10000000000) |
395 | |
396 | def test_annotation_attribute(self): |
397 | tu = get_tu('int foo (void) __attribute__ ((annotate("here be annotation attribute")));') |
398 | |
399 | foo = get_cursor(tu, 'foo') |
400 | self.assertIsNotNone(foo) |
401 | |
402 | for c in foo.get_children(): |
403 | if c.kind == CursorKind.ANNOTATE_ATTR: |
404 | self.assertEqual(c.displayname, "here be annotation attribute") |
405 | break |
406 | else: |
407 | self.fail("Couldn't find annotation") |
408 | |
409 | def test_annotation_template(self): |
410 | annotation = '__attribute__ ((annotate("annotation")))' |
411 | for source, kind in [ |
412 | ('int foo (T value) %s;', CursorKind.FUNCTION_TEMPLATE), |
413 | ('class %s foo {};', CursorKind.CLASS_TEMPLATE), |
414 | ]: |
415 | source = 'template<typename T> ' + (source % annotation) |
416 | tu = get_tu(source, lang="cpp") |
417 | |
418 | foo = get_cursor(tu, 'foo') |
419 | self.assertIsNotNone(foo) |
420 | self.assertEqual(foo.kind, kind) |
421 | |
422 | for c in foo.get_children(): |
423 | if c.kind == CursorKind.ANNOTATE_ATTR: |
424 | self.assertEqual(c.displayname, "annotation") |
425 | break |
426 | else: |
427 | self.fail("Couldn't find annotation for {}".format(kind)) |
428 | |
429 | def test_result_type(self): |
430 | tu = get_tu('int foo();') |
431 | foo = get_cursor(tu, 'foo') |
432 | |
433 | self.assertIsNotNone(foo) |
434 | t = foo.result_type |
435 | self.assertEqual(t.kind, TypeKind.INT) |
436 | |
437 | def test_result_type_objc_method_decl(self): |
438 | code = """\ |
439 | @interface Interface : NSObject |
440 | -(void)voidMethod; |
441 | @end |
442 | """ |
443 | tu = get_tu(code, lang='objc') |
444 | cursor = get_cursor(tu, 'voidMethod') |
445 | result_type = cursor.result_type |
446 | self.assertEqual(cursor.kind, CursorKind.OBJC_INSTANCE_METHOD_DECL) |
447 | self.assertEqual(result_type.kind, TypeKind.VOID) |
448 | |
449 | def test_availability(self): |
450 | tu = get_tu('class A { A(A const&) = delete; };', lang='cpp') |
451 | |
452 | # AvailabilityKind.AVAILABLE |
453 | cursor = get_cursor(tu, 'A') |
454 | self.assertEqual(cursor.kind, CursorKind.CLASS_DECL) |
455 | self.assertEqual(cursor.availability, AvailabilityKind.AVAILABLE) |
456 | |
457 | # AvailabilityKind.NOT_AVAILABLE |
458 | cursors = get_cursors(tu, 'A') |
459 | for c in cursors: |
460 | if c.kind == CursorKind.CONSTRUCTOR: |
461 | self.assertEqual(c.availability, AvailabilityKind.NOT_AVAILABLE) |
462 | break |
463 | else: |
464 | self.fail("Could not find cursor for deleted constructor") |
465 | |
466 | # AvailabilityKind.DEPRECATED |
467 | tu = get_tu('void test() __attribute__((deprecated));', lang='cpp') |
468 | cursor = get_cursor(tu, 'test') |
469 | self.assertEqual(cursor.availability, AvailabilityKind.DEPRECATED) |
470 | |
471 | # AvailabilityKind.NOT_ACCESSIBLE is only used in the code completion results |
472 | |
473 | def test_get_tokens(self): |
474 | """Ensure we can map cursors back to tokens.""" |
475 | tu = get_tu('int foo(int i);') |
476 | foo = get_cursor(tu, 'foo') |
477 | |
478 | tokens = list(foo.get_tokens()) |
479 | self.assertEqual(len(tokens), 6) |
480 | self.assertEqual(tokens[0].spelling, 'int') |
481 | self.assertEqual(tokens[1].spelling, 'foo') |
482 | |
483 | def test_get_token_cursor(self): |
484 | """Ensure we can map tokens to cursors.""" |
485 | tu = get_tu('class A {}; int foo(A var = A());', lang='cpp') |
486 | foo = get_cursor(tu, 'foo') |
487 | |
488 | for cursor in foo.walk_preorder(): |
489 | if cursor.kind.is_expression() and not cursor.kind.is_statement(): |
490 | break |
491 | else: |
492 | self.fail("Could not find default value expression") |
493 | |
494 | tokens = list(cursor.get_tokens()) |
495 | self.assertEqual(len(tokens), 4, [t.spelling for t in tokens]) |
496 | self.assertEqual(tokens[0].spelling, '=') |
497 | self.assertEqual(tokens[1].spelling, 'A') |
498 | self.assertEqual(tokens[2].spelling, '(') |
499 | self.assertEqual(tokens[3].spelling, ')') |
500 | t_cursor = tokens[1].cursor |
501 | self.assertEqual(t_cursor.kind, CursorKind.TYPE_REF) |
502 | r_cursor = t_cursor.referenced # should not raise an exception |
503 | self.assertEqual(r_cursor.kind, CursorKind.CLASS_DECL) |
504 | |
505 | def test_get_arguments(self): |
506 | tu = get_tu('void foo(int i, int j);') |
507 | foo = get_cursor(tu, 'foo') |
508 | arguments = list(foo.get_arguments()) |
509 | |
510 | self.assertEqual(len(arguments), 2) |
511 | self.assertEqual(arguments[0].spelling, "i") |
512 | self.assertEqual(arguments[1].spelling, "j") |
513 | |
514 | def test_get_num_template_arguments(self): |
515 | tu = get_tu(kTemplateArgTest, lang='cpp') |
516 | foos = get_cursors(tu, 'foo') |
517 | |
518 | self.assertEqual(foos[1].get_num_template_arguments(), 3) |
519 | |
520 | def test_get_template_argument_kind(self): |
521 | tu = get_tu(kTemplateArgTest, lang='cpp') |
522 | foos = get_cursors(tu, 'foo') |
523 | |
524 | self.assertEqual(foos[1].get_template_argument_kind(0), TemplateArgumentKind.INTEGRAL) |
525 | self.assertEqual(foos[1].get_template_argument_kind(1), TemplateArgumentKind.TYPE) |
526 | self.assertEqual(foos[1].get_template_argument_kind(2), TemplateArgumentKind.INTEGRAL) |
527 | |
528 | def test_get_template_argument_type(self): |
529 | tu = get_tu(kTemplateArgTest, lang='cpp') |
530 | foos = get_cursors(tu, 'foo') |
531 | |
532 | self.assertEqual(foos[1].get_template_argument_type(1).kind, TypeKind.FLOAT) |
533 | |
534 | def test_get_template_argument_value(self): |
535 | tu = get_tu(kTemplateArgTest, lang='cpp') |
536 | foos = get_cursors(tu, 'foo') |
537 | |
538 | self.assertEqual(foos[1].get_template_argument_value(0), -7) |
539 | self.assertEqual(foos[1].get_template_argument_value(2), True) |
540 | |
541 | def test_get_template_argument_unsigned_value(self): |
542 | tu = get_tu(kTemplateArgTest, lang='cpp') |
543 | foos = get_cursors(tu, 'foo') |
544 | |
545 | self.assertEqual(foos[1].get_template_argument_unsigned_value(0), 2 ** 32 - 7) |
546 | self.assertEqual(foos[1].get_template_argument_unsigned_value(2), True) |
547 | |
548 | def test_referenced(self): |
549 | tu = get_tu('void foo(); void bar() { foo(); }') |
550 | foo = get_cursor(tu, 'foo') |
551 | bar = get_cursor(tu, 'bar') |
552 | for c in bar.get_children(): |
553 | if c.kind == CursorKind.CALL_EXPR: |
554 | self.assertEqual(c.referenced.spelling, foo.spelling) |
555 | break |
556 | |
557 | def test_mangled_name(self): |
558 | kInputForMangling = """\ |
559 | int foo(int, int); |
560 | """ |
561 | tu = get_tu(kInputForMangling, lang='cpp') |
562 | foo = get_cursor(tu, 'foo') |
563 | |
564 | # Since libclang does not link in targets, we cannot pass a triple to it |
565 | # and force the target. To enable this test to pass on all platforms, accept |
566 | # all valid manglings. |
567 | # [c-index-test handles this by running the source through clang, emitting |
568 | # an AST file and running libclang on that AST file] |
569 | self.assertIn(foo.mangled_name, ('_Z3fooii', '__Z3fooii', '?foo@@YAHHH', '?foo@@YAHHH@Z')) |
570 | |