5 from clang.cindex import AvailabilityKind
6 from clang.cindex import CursorKind
7 from clang.cindex import TemplateArgumentKind
8 from clang.cindex import TranslationUnit
9 from clang.cindex import TypeKind
10 from .util import get_cursor
11 from .util import get_cursors
12 from .util import get_tu
23 void f0(int a0, int a1) {
43 kTemplateArgTest = """\
44 template <int kInt, typename T, bool kBool>
48 void foo<-7, float, true>();
51 class TestCursor(unittest.TestCase):
52 def test_get_children(self):
55 it = tu.cursor.get_children()
58 self.assertEqual(len(tu_nodes), 3)
59 for cursor in tu_nodes:
60 self.assertIsNotNone(cursor.translation_unit)
62 self.assertNotEqual(tu_nodes[0], tu_nodes[1])
63 self.assertEqual(tu_nodes[0].kind, CursorKind.STRUCT_DECL)
64 self.assertEqual(tu_nodes[0].spelling, 's0')
65 self.assertEqual(tu_nodes[0].is_definition(), True)
66 self.assertEqual(tu_nodes[0].location.file.name, 't.c')
67 self.assertEqual(tu_nodes[0].location.line, 1)
68 self.assertEqual(tu_nodes[0].location.column, 8)
69 self.assertGreater(tu_nodes[0].hash, 0)
70 self.assertIsNotNone(tu_nodes[0].translation_unit)
72 s0_nodes = list(tu_nodes[0].get_children())
73 self.assertEqual(len(s0_nodes), 2)
74 self.assertEqual(s0_nodes[0].kind, CursorKind.FIELD_DECL)
75 self.assertEqual(s0_nodes[0].spelling, 'a')
76 self.assertEqual(s0_nodes[0].type.kind, TypeKind.INT)
77 self.assertEqual(s0_nodes[1].kind, CursorKind.FIELD_DECL)
78 self.assertEqual(s0_nodes[1].spelling, 'b')
79 self.assertEqual(s0_nodes[1].type.kind, TypeKind.INT)
81 self.assertEqual(tu_nodes[1].kind, CursorKind.STRUCT_DECL)
82 self.assertEqual(tu_nodes[1].spelling, 's1')
83 self.assertEqual(tu_nodes[1].displayname, 's1')
84 self.assertEqual(tu_nodes[1].is_definition(), False)
86 self.assertEqual(tu_nodes[2].kind, CursorKind.FUNCTION_DECL)
87 self.assertEqual(tu_nodes[2].spelling, 'f0')
88 self.assertEqual(tu_nodes[2].displayname, 'f0(int, int)')
89 self.assertEqual(tu_nodes[2].is_definition(), True)
91 def test_references(self):
92 """Ensure that references to TranslationUnit are kept."""
94 cursors = list(tu.cursor.get_children())
95 self.assertGreater(len(cursors), 0)
98 self.assertIsInstance(cursor.translation_unit, TranslationUnit)
100 # Delete reference to TU and perform a full GC.
103 self.assertIsInstance(cursor.translation_unit, TranslationUnit)
105 # If the TU was destroyed, this should cause a segfault.
106 parent = cursor.semantic_parent
108 def test_canonical(self):
109 source = 'struct X; struct X; struct X { int member; };'
113 for cursor in tu.cursor.get_children():
114 if cursor.spelling == 'X':
115 cursors.append(cursor)
117 self.assertEqual(len(cursors), 3)
118 self.assertEqual(cursors[1].canonical, cursors[2].canonical)
120 def test_is_const_method(self):
121 """Ensure Cursor.is_const_method works."""
122 source = 'class X { void foo() const; void bar(); };'
123 tu = get_tu(source, lang='cpp')
125 cls = get_cursor(tu, 'X')
126 foo = get_cursor(tu, 'foo')
127 bar = get_cursor(tu, 'bar')
128 self.assertIsNotNone(cls)
129 self.assertIsNotNone(foo)
130 self.assertIsNotNone(bar)
132 self.assertTrue(foo.is_const_method())
133 self.assertFalse(bar.is_const_method())
135 def test_is_converting_constructor(self):
136 """Ensure Cursor.is_converting_constructor works."""
137 source = 'class X { explicit X(int); X(double); X(); };'
138 tu = get_tu(source, lang='cpp')
140 xs = get_cursors(tu, 'X')
142 self.assertEqual(len(xs), 4)
143 self.assertEqual(xs[0].kind, CursorKind.CLASS_DECL)
145 self.assertEqual(cs[0].kind, CursorKind.CONSTRUCTOR)
146 self.assertEqual(cs[1].kind, CursorKind.CONSTRUCTOR)
147 self.assertEqual(cs[2].kind, CursorKind.CONSTRUCTOR)
149 self.assertFalse(cs[0].is_converting_constructor())
150 self.assertTrue(cs[1].is_converting_constructor())
151 self.assertFalse(cs[2].is_converting_constructor())
154 def test_is_copy_constructor(self):
155 """Ensure Cursor.is_copy_constructor works."""
156 source = 'class X { X(); X(const X&); X(X&&); };'
157 tu = get_tu(source, lang='cpp')
159 xs = get_cursors(tu, 'X')
160 self.assertEqual(xs[0].kind, CursorKind.CLASS_DECL)
162 self.assertEqual(cs[0].kind, CursorKind.CONSTRUCTOR)
163 self.assertEqual(cs[1].kind, CursorKind.CONSTRUCTOR)
164 self.assertEqual(cs[2].kind, CursorKind.CONSTRUCTOR)
166 self.assertFalse(cs[0].is_copy_constructor())
167 self.assertTrue(cs[1].is_copy_constructor())
168 self.assertFalse(cs[2].is_copy_constructor())
170 def test_is_default_constructor(self):
171 """Ensure Cursor.is_default_constructor works."""
172 source = 'class X { X(); X(int); };'
173 tu = get_tu(source, lang='cpp')
175 xs = get_cursors(tu, 'X')
176 self.assertEqual(xs[0].kind, CursorKind.CLASS_DECL)
178 self.assertEqual(cs[0].kind, CursorKind.CONSTRUCTOR)
179 self.assertEqual(cs[1].kind, CursorKind.CONSTRUCTOR)
181 self.assertTrue(cs[0].is_default_constructor())
182 self.assertFalse(cs[1].is_default_constructor())
184 def test_is_move_constructor(self):
185 """Ensure Cursor.is_move_constructor works."""
186 source = 'class X { X(); X(const X&); X(X&&); };'
187 tu = get_tu(source, lang='cpp')
189 xs = get_cursors(tu, 'X')
190 self.assertEqual(xs[0].kind, CursorKind.CLASS_DECL)
192 self.assertEqual(cs[0].kind, CursorKind.CONSTRUCTOR)
193 self.assertEqual(cs[1].kind, CursorKind.CONSTRUCTOR)
194 self.assertEqual(cs[2].kind, CursorKind.CONSTRUCTOR)
196 self.assertFalse(cs[0].is_move_constructor())
197 self.assertFalse(cs[1].is_move_constructor())
198 self.assertTrue(cs[2].is_move_constructor())
200 def test_is_default_method(self):
201 """Ensure Cursor.is_default_method works."""
202 source = 'class X { X() = default; }; class Y { Y(); };'
203 tu = get_tu(source, lang='cpp')
205 xs = get_cursors(tu, 'X')
206 ys = get_cursors(tu, 'Y')
208 self.assertEqual(len(xs), 2)
209 self.assertEqual(len(ys), 2)
214 self.assertTrue(xc.is_default_method())
215 self.assertFalse(yc.is_default_method())
217 def test_is_mutable_field(self):
218 """Ensure Cursor.is_mutable_field works."""
219 source = 'class X { int x_; mutable int y_; };'
220 tu = get_tu(source, lang='cpp')
222 cls = get_cursor(tu, 'X')
223 x_ = get_cursor(tu, 'x_')
224 y_ = get_cursor(tu, 'y_')
225 self.assertIsNotNone(cls)
226 self.assertIsNotNone(x_)
227 self.assertIsNotNone(y_)
229 self.assertFalse(x_.is_mutable_field())
230 self.assertTrue(y_.is_mutable_field())
232 def test_is_static_method(self):
233 """Ensure Cursor.is_static_method works."""
235 source = 'class X { static void foo(); void bar(); };'
236 tu = get_tu(source, lang='cpp')
238 cls = get_cursor(tu, 'X')
239 foo = get_cursor(tu, 'foo')
240 bar = get_cursor(tu, 'bar')
241 self.assertIsNotNone(cls)
242 self.assertIsNotNone(foo)
243 self.assertIsNotNone(bar)
245 self.assertTrue(foo.is_static_method())
246 self.assertFalse(bar.is_static_method())
248 def test_is_pure_virtual_method(self):
249 """Ensure Cursor.is_pure_virtual_method works."""
250 source = 'class X { virtual void foo() = 0; virtual void bar(); };'
251 tu = get_tu(source, lang='cpp')
253 cls = get_cursor(tu, 'X')
254 foo = get_cursor(tu, 'foo')
255 bar = get_cursor(tu, 'bar')
256 self.assertIsNotNone(cls)
257 self.assertIsNotNone(foo)
258 self.assertIsNotNone(bar)
260 self.assertTrue(foo.is_pure_virtual_method())
261 self.assertFalse(bar.is_pure_virtual_method())
263 def test_is_virtual_method(self):
264 """Ensure Cursor.is_virtual_method works."""
265 source = 'class X { virtual void foo(); void bar(); };'
266 tu = get_tu(source, lang='cpp')
268 cls = get_cursor(tu, 'X')
269 foo = get_cursor(tu, 'foo')
270 bar = get_cursor(tu, 'bar')
271 self.assertIsNotNone(cls)
272 self.assertIsNotNone(foo)
273 self.assertIsNotNone(bar)
275 self.assertTrue(foo.is_virtual_method())
276 self.assertFalse(bar.is_virtual_method())
278 def test_is_abstract_record(self):
279 """Ensure Cursor.is_abstract_record works."""
280 source = 'struct X { virtual void x() = 0; }; struct Y : X { void x(); };'
281 tu = get_tu(source, lang='cpp')
283 cls = get_cursor(tu, 'X')
284 self.assertTrue(cls.is_abstract_record())
286 cls = get_cursor(tu, 'Y')
287 self.assertFalse(cls.is_abstract_record())
289 def test_is_scoped_enum(self):
290 """Ensure Cursor.is_scoped_enum works."""
291 source = 'class X {}; enum RegularEnum {}; enum class ScopedEnum {};'
292 tu = get_tu(source, lang='cpp')
294 cls = get_cursor(tu, 'X')
295 regular_enum = get_cursor(tu, 'RegularEnum')
296 scoped_enum = get_cursor(tu, 'ScopedEnum')
297 self.assertIsNotNone(cls)
298 self.assertIsNotNone(regular_enum)
299 self.assertIsNotNone(scoped_enum)
301 self.assertFalse(cls.is_scoped_enum())
302 self.assertFalse(regular_enum.is_scoped_enum())
303 self.assertTrue(scoped_enum.is_scoped_enum())
305 def test_underlying_type(self):
306 tu = get_tu('typedef int foo;')
307 typedef = get_cursor(tu, 'foo')
308 self.assertIsNotNone(typedef)
310 self.assertTrue(typedef.kind.is_declaration())
311 underlying = typedef.underlying_typedef_type
312 self.assertEqual(underlying.kind, TypeKind.INT)
314 def test_semantic_parent(self):
315 tu = get_tu(kParentTest, 'cpp')
316 curs = get_cursors(tu, 'f')
317 decl = get_cursor(tu, 'C')
318 self.assertEqual(len(curs), 2)
319 self.assertEqual(curs[0].semantic_parent, curs[1].semantic_parent)
320 self.assertEqual(curs[0].semantic_parent, decl)
322 def test_lexical_parent(self):
323 tu = get_tu(kParentTest, 'cpp')
324 curs = get_cursors(tu, 'f')
325 decl = get_cursor(tu, 'C')
326 self.assertEqual(len(curs), 2)
327 self.assertNotEqual(curs[0].lexical_parent, curs[1].lexical_parent)
328 self.assertEqual(curs[0].lexical_parent, decl)
329 self.assertEqual(curs[1].lexical_parent, tu.cursor)
331 def test_enum_type(self):
332 tu = get_tu('enum TEST { FOO=1, BAR=2 };')
333 enum = get_cursor(tu, 'TEST')
334 self.assertIsNotNone(enum)
336 self.assertEqual(enum.kind, CursorKind.ENUM_DECL)
337 enum_type = enum.enum_type
338 self.assertIn(enum_type.kind, (TypeKind.UINT, TypeKind.INT))
340 def test_enum_type_cpp(self):
341 tu = get_tu('enum TEST : long long { FOO=1, BAR=2 };', lang="cpp")
342 enum = get_cursor(tu, 'TEST')
343 self.assertIsNotNone(enum)
345 self.assertEqual(enum.kind, CursorKind.ENUM_DECL)
346 self.assertEqual(enum.enum_type.kind, TypeKind.LONGLONG)
348 def test_objc_type_encoding(self):
349 tu = get_tu('int i;', lang='objc')
350 i = get_cursor(tu, 'i')
352 self.assertIsNotNone(i)
353 self.assertEqual(i.objc_type_encoding, 'i')
355 def test_enum_values(self):
356 tu = get_tu('enum TEST { SPAM=1, EGG, HAM = EGG * 20};')
357 enum = get_cursor(tu, 'TEST')
358 self.assertIsNotNone(enum)
360 self.assertEqual(enum.kind, CursorKind.ENUM_DECL)
362 enum_constants = list(enum.get_children())
363 self.assertEqual(len(enum_constants), 3)
365 spam, egg, ham = enum_constants
367 self.assertEqual(spam.kind, CursorKind.ENUM_CONSTANT_DECL)
368 self.assertEqual(spam.enum_value, 1)
369 self.assertEqual(egg.kind, CursorKind.ENUM_CONSTANT_DECL)
370 self.assertEqual(egg.enum_value, 2)
371 self.assertEqual(ham.kind, CursorKind.ENUM_CONSTANT_DECL)
372 self.assertEqual(ham.enum_value, 40)
374 def test_enum_values_cpp(self):
375 tu = get_tu('enum TEST : long long { SPAM = -1, HAM = 0x10000000000};', lang="cpp")
376 enum = get_cursor(tu, 'TEST')
377 self.assertIsNotNone(enum)
379 self.assertEqual(enum.kind, CursorKind.ENUM_DECL)
381 enum_constants = list(enum.get_children())
382 self.assertEqual(len(enum_constants), 2)
384 spam, ham = enum_constants
386 self.assertEqual(spam.kind, CursorKind.ENUM_CONSTANT_DECL)
387 self.assertEqual(spam.enum_value, -1)
388 self.assertEqual(ham.kind, CursorKind.ENUM_CONSTANT_DECL)
389 self.assertEqual(ham.enum_value, 0x10000000000)
391 def test_annotation_attribute(self):
392 tu = get_tu('int foo (void) __attribute__ ((annotate("here be annotation attribute")));')
394 foo = get_cursor(tu, 'foo')
395 self.assertIsNotNone(foo)
397 for c in foo.get_children():
398 if c.kind == CursorKind.ANNOTATE_ATTR:
399 self.assertEqual(c.displayname, "here be annotation attribute")
402 self.fail("Couldn't find annotation")
404 def test_annotation_template(self):
405 annotation = '__attribute__ ((annotate("annotation")))'
406 for source, kind in [
407 ('int foo (T value) %s;', CursorKind.FUNCTION_TEMPLATE),
408 ('class %s foo {};', CursorKind.CLASS_TEMPLATE),
410 source = 'template<typename T> ' + (source % annotation)
411 tu = get_tu(source, lang="cpp")
413 foo = get_cursor(tu, 'foo')
414 self.assertIsNotNone(foo)
415 self.assertEqual(foo.kind, kind)
417 for c in foo.get_children():
418 if c.kind == CursorKind.ANNOTATE_ATTR:
419 self.assertEqual(c.displayname, "annotation")
422 self.fail("Couldn't find annotation for {}".format(kind))
424 def test_result_type(self):
425 tu = get_tu('int foo();')
426 foo = get_cursor(tu, 'foo')
428 self.assertIsNotNone(foo)
430 self.assertEqual(t.kind, TypeKind.INT)
432 def test_result_type_objc_method_decl(self):
434 @interface Interface : NSObject
438 tu = get_tu(code, lang='objc')
439 cursor = get_cursor(tu, 'voidMethod')
440 result_type = cursor.result_type
441 self.assertEqual(cursor.kind, CursorKind.OBJC_INSTANCE_METHOD_DECL)
442 self.assertEqual(result_type.kind, TypeKind.VOID)
444 def test_availability(self):
445 tu = get_tu('class A { A(A const&) = delete; };', lang='cpp')
447 # AvailabilityKind.AVAILABLE
448 cursor = get_cursor(tu, 'A')
449 self.assertEqual(cursor.kind, CursorKind.CLASS_DECL)
450 self.assertEqual(cursor.availability, AvailabilityKind.AVAILABLE)
452 # AvailabilityKind.NOT_AVAILABLE
453 cursors = get_cursors(tu, 'A')
455 if c.kind == CursorKind.CONSTRUCTOR:
456 self.assertEqual(c.availability, AvailabilityKind.NOT_AVAILABLE)
459 self.fail("Could not find cursor for deleted constructor")
461 # AvailabilityKind.DEPRECATED
462 tu = get_tu('void test() __attribute__((deprecated));', lang='cpp')
463 cursor = get_cursor(tu, 'test')
464 self.assertEqual(cursor.availability, AvailabilityKind.DEPRECATED)
466 # AvailabilityKind.NOT_ACCESSIBLE is only used in the code completion results
468 def test_get_tokens(self):
469 """Ensure we can map cursors back to tokens."""
470 tu = get_tu('int foo(int i);')
471 foo = get_cursor(tu, 'foo')
473 tokens = list(foo.get_tokens())
474 self.assertEqual(len(tokens), 6)
475 self.assertEqual(tokens[0].spelling, 'int')
476 self.assertEqual(tokens[1].spelling, 'foo')
478 def test_get_token_cursor(self):
479 """Ensure we can map tokens to cursors."""
480 tu = get_tu('class A {}; int foo(A var = A());', lang='cpp')
481 foo = get_cursor(tu, 'foo')
483 for cursor in foo.walk_preorder():
484 if cursor.kind.is_expression() and not cursor.kind.is_statement():
487 self.fail("Could not find default value expression")
489 tokens = list(cursor.get_tokens())
490 self.assertEqual(len(tokens), 4, [t.spelling for t in tokens])
491 self.assertEqual(tokens[0].spelling, '=')
492 self.assertEqual(tokens[1].spelling, 'A')
493 self.assertEqual(tokens[2].spelling, '(')
494 self.assertEqual(tokens[3].spelling, ')')
495 t_cursor = tokens[1].cursor
496 self.assertEqual(t_cursor.kind, CursorKind.TYPE_REF)
497 r_cursor = t_cursor.referenced # should not raise an exception
498 self.assertEqual(r_cursor.kind, CursorKind.CLASS_DECL)
500 def test_get_arguments(self):
501 tu = get_tu('void foo(int i, int j);')
502 foo = get_cursor(tu, 'foo')
503 arguments = list(foo.get_arguments())
505 self.assertEqual(len(arguments), 2)
506 self.assertEqual(arguments[0].spelling, "i")
507 self.assertEqual(arguments[1].spelling, "j")
509 def test_get_num_template_arguments(self):
510 tu = get_tu(kTemplateArgTest, lang='cpp')
511 foos = get_cursors(tu, 'foo')
513 self.assertEqual(foos[1].get_num_template_arguments(), 3)
515 def test_get_template_argument_kind(self):
516 tu = get_tu(kTemplateArgTest, lang='cpp')
517 foos = get_cursors(tu, 'foo')
519 self.assertEqual(foos[1].get_template_argument_kind(0), TemplateArgumentKind.INTEGRAL)
520 self.assertEqual(foos[1].get_template_argument_kind(1), TemplateArgumentKind.TYPE)
521 self.assertEqual(foos[1].get_template_argument_kind(2), TemplateArgumentKind.INTEGRAL)
523 def test_get_template_argument_type(self):
524 tu = get_tu(kTemplateArgTest, lang='cpp')
525 foos = get_cursors(tu, 'foo')
527 self.assertEqual(foos[1].get_template_argument_type(1).kind, TypeKind.FLOAT)
529 def test_get_template_argument_value(self):
530 tu = get_tu(kTemplateArgTest, lang='cpp')
531 foos = get_cursors(tu, 'foo')
533 self.assertEqual(foos[1].get_template_argument_value(0), -7)
534 self.assertEqual(foos[1].get_template_argument_value(2), True)
536 def test_get_template_argument_unsigned_value(self):
537 tu = get_tu(kTemplateArgTest, lang='cpp')
538 foos = get_cursors(tu, 'foo')
540 self.assertEqual(foos[1].get_template_argument_unsigned_value(0), 2 ** 32 - 7)
541 self.assertEqual(foos[1].get_template_argument_unsigned_value(2), True)
543 def test_referenced(self):
544 tu = get_tu('void foo(); void bar() { foo(); }')
545 foo = get_cursor(tu, 'foo')
546 bar = get_cursor(tu, 'bar')
547 for c in bar.get_children():
548 if c.kind == CursorKind.CALL_EXPR:
549 self.assertEqual(c.referenced.spelling, foo.spelling)
552 def test_mangled_name(self):
553 kInputForMangling = """\
556 tu = get_tu(kInputForMangling, lang='cpp')
557 foo = get_cursor(tu, 'foo')
559 # Since libclang does not link in targets, we cannot pass a triple to it
560 # and force the target. To enable this test to pass on all platforms, accept
561 # all valid manglings.
562 # [c-index-test handles this by running the source through clang, emitting
563 # an AST file and running libclang on that AST file]
564 self.assertIn(foo.mangled_name, ('_Z3fooii', '__Z3fooii', '?foo@@YAHHH', '?foo@@YAHHH@Z'))