[NFC][Coroutines] Use structured binding with llvm::enumerate in CoroSplit (#116879)
[llvm-project.git] / clang / bindings / python / tests / cindex / test_cursor.py
blob4d989a7421e79057da46cf25cd51905c311be342
1 import os
3 from clang.cindex import (
4 AvailabilityKind,
5 BinaryOperator,
6 Config,
7 CursorKind,
8 StorageClass,
9 TemplateArgumentKind,
10 TranslationUnit,
11 TypeKind,
14 if "CLANG_LIBRARY_PATH" in os.environ:
15 Config.set_library_path(os.environ["CLANG_LIBRARY_PATH"])
17 import gc
18 import unittest
20 from .util import get_cursor, get_cursors, get_tu
22 kInput = """\
23 struct s0 {
24 int a;
25 int b;
28 struct s1;
30 void f0(int a0, int a1) {
31 int l0, l1;
33 if (a0)
34 return;
36 for (;;) {
37 break;
40 """
42 kParentTest = """\
43 class C {
44 void f();
47 void C::f() { }
48 """
50 kTemplateArgTest = """\
51 template <int kInt, typename T, bool kBool>
52 void foo();
54 template<>
55 void foo<-7, float, true>();
56 """
58 kBinops = """\
59 struct C {
60 int m;
63 void func(void){
64 int a, b;
65 int C::* p = &C::
67 C c;
68 c.*p;
70 C* pc;
71 pc->*p;
73 a * b;
74 a / b;
75 a % b;
76 a + b;
77 a - b;
79 a << b;
80 a >> b;
82 a < b;
83 a > b;
85 a <= b;
86 a >= b;
87 a == b;
88 a != b;
90 a & b;
91 a ^ b;
92 a | b;
94 a && b;
95 a || b;
97 a = b;
99 a *= b;
100 a /= b;
101 a %= b;
102 a += b;
103 a -= b;
105 a <<= b;
106 a >>= b;
108 a &= b;
109 a ^= b;
110 a |= b;
111 a , b;
117 class TestCursor(unittest.TestCase):
118 def test_get_children(self):
119 tu = get_tu(kInput)
121 it = tu.cursor.get_children()
122 tu_nodes = list(it)
124 self.assertEqual(len(tu_nodes), 3)
125 for cursor in tu_nodes:
126 self.assertIsNotNone(cursor.translation_unit)
128 self.assertNotEqual(tu_nodes[0], tu_nodes[1])
129 self.assertEqual(tu_nodes[0].kind, CursorKind.STRUCT_DECL)
130 self.assertEqual(tu_nodes[0].spelling, "s0")
131 self.assertEqual(tu_nodes[0].is_definition(), True)
132 self.assertEqual(tu_nodes[0].location.file.name, "t.c")
133 self.assertEqual(tu_nodes[0].location.line, 1)
134 self.assertEqual(tu_nodes[0].location.column, 8)
135 self.assertGreater(tu_nodes[0].hash, 0)
136 self.assertIsNotNone(tu_nodes[0].translation_unit)
138 s0_nodes = list(tu_nodes[0].get_children())
139 self.assertEqual(len(s0_nodes), 2)
140 self.assertEqual(s0_nodes[0].kind, CursorKind.FIELD_DECL)
141 self.assertEqual(s0_nodes[0].spelling, "a")
142 self.assertEqual(s0_nodes[0].type.kind, TypeKind.INT)
143 self.assertEqual(s0_nodes[1].kind, CursorKind.FIELD_DECL)
144 self.assertEqual(s0_nodes[1].spelling, "b")
145 self.assertEqual(s0_nodes[1].type.kind, TypeKind.INT)
147 self.assertEqual(tu_nodes[1].kind, CursorKind.STRUCT_DECL)
148 self.assertEqual(tu_nodes[1].spelling, "s1")
149 self.assertEqual(tu_nodes[1].displayname, "s1")
150 self.assertEqual(tu_nodes[1].is_definition(), False)
152 self.assertEqual(tu_nodes[2].kind, CursorKind.FUNCTION_DECL)
153 self.assertEqual(tu_nodes[2].spelling, "f0")
154 self.assertEqual(tu_nodes[2].displayname, "f0(int, int)")
155 self.assertEqual(tu_nodes[2].is_definition(), True)
157 def test_references(self):
158 """Ensure that references to TranslationUnit are kept."""
159 tu = get_tu("int x;")
160 cursors = list(tu.cursor.get_children())
161 self.assertGreater(len(cursors), 0)
163 cursor = cursors[0]
164 self.assertIsInstance(cursor.translation_unit, TranslationUnit)
166 # Delete reference to TU and perform a full GC.
167 del tu
168 gc.collect()
169 self.assertIsInstance(cursor.translation_unit, TranslationUnit)
171 # If the TU was destroyed, this should cause a segfault.
172 cursor.semantic_parent
174 def test_canonical(self):
175 source = "struct X; struct X; struct X { int member; };"
176 tu = get_tu(source)
178 cursors = []
179 for cursor in tu.cursor.get_children():
180 if cursor.spelling == "X":
181 cursors.append(cursor)
183 self.assertEqual(len(cursors), 3)
184 self.assertEqual(cursors[1].canonical, cursors[2].canonical)
186 def test_is_const_method(self):
187 """Ensure Cursor.is_const_method works."""
188 source = "class X { void foo() const; void bar(); };"
189 tu = get_tu(source, lang="cpp")
191 cls = get_cursor(tu, "X")
192 foo = get_cursor(tu, "foo")
193 bar = get_cursor(tu, "bar")
194 self.assertIsNotNone(cls)
195 self.assertIsNotNone(foo)
196 self.assertIsNotNone(bar)
198 self.assertTrue(foo.is_const_method())
199 self.assertFalse(bar.is_const_method())
201 def test_is_converting_constructor(self):
202 """Ensure Cursor.is_converting_constructor works."""
203 source = "class X { explicit X(int); X(double); X(); };"
204 tu = get_tu(source, lang="cpp")
206 xs = get_cursors(tu, "X")
208 self.assertEqual(len(xs), 4)
209 self.assertEqual(xs[0].kind, CursorKind.CLASS_DECL)
210 cs = xs[1:]
211 self.assertEqual(cs[0].kind, CursorKind.CONSTRUCTOR)
212 self.assertEqual(cs[1].kind, CursorKind.CONSTRUCTOR)
213 self.assertEqual(cs[2].kind, CursorKind.CONSTRUCTOR)
215 self.assertFalse(cs[0].is_converting_constructor())
216 self.assertTrue(cs[1].is_converting_constructor())
217 self.assertFalse(cs[2].is_converting_constructor())
219 def test_is_copy_constructor(self):
220 """Ensure Cursor.is_copy_constructor works."""
221 source = "class X { X(); X(const X&); X(X&&); };"
222 tu = get_tu(source, lang="cpp")
224 xs = get_cursors(tu, "X")
225 self.assertEqual(xs[0].kind, CursorKind.CLASS_DECL)
226 cs = xs[1:]
227 self.assertEqual(cs[0].kind, CursorKind.CONSTRUCTOR)
228 self.assertEqual(cs[1].kind, CursorKind.CONSTRUCTOR)
229 self.assertEqual(cs[2].kind, CursorKind.CONSTRUCTOR)
231 self.assertFalse(cs[0].is_copy_constructor())
232 self.assertTrue(cs[1].is_copy_constructor())
233 self.assertFalse(cs[2].is_copy_constructor())
235 def test_is_default_constructor(self):
236 """Ensure Cursor.is_default_constructor works."""
237 source = "class X { X(); X(int); };"
238 tu = get_tu(source, lang="cpp")
240 xs = get_cursors(tu, "X")
241 self.assertEqual(xs[0].kind, CursorKind.CLASS_DECL)
242 cs = xs[1:]
243 self.assertEqual(cs[0].kind, CursorKind.CONSTRUCTOR)
244 self.assertEqual(cs[1].kind, CursorKind.CONSTRUCTOR)
246 self.assertTrue(cs[0].is_default_constructor())
247 self.assertFalse(cs[1].is_default_constructor())
249 def test_is_move_constructor(self):
250 """Ensure Cursor.is_move_constructor works."""
251 source = "class X { X(); X(const X&); X(X&&); };"
252 tu = get_tu(source, lang="cpp")
254 xs = get_cursors(tu, "X")
255 self.assertEqual(xs[0].kind, CursorKind.CLASS_DECL)
256 cs = xs[1:]
257 self.assertEqual(cs[0].kind, CursorKind.CONSTRUCTOR)
258 self.assertEqual(cs[1].kind, CursorKind.CONSTRUCTOR)
259 self.assertEqual(cs[2].kind, CursorKind.CONSTRUCTOR)
261 self.assertFalse(cs[0].is_move_constructor())
262 self.assertFalse(cs[1].is_move_constructor())
263 self.assertTrue(cs[2].is_move_constructor())
265 def test_is_default_method(self):
266 """Ensure Cursor.is_default_method works."""
267 source = "class X { X() = default; }; class Y { Y(); };"
268 tu = get_tu(source, lang="cpp")
270 xs = get_cursors(tu, "X")
271 ys = get_cursors(tu, "Y")
273 self.assertEqual(len(xs), 2)
274 self.assertEqual(len(ys), 2)
276 xc = xs[1]
277 yc = ys[1]
279 self.assertTrue(xc.is_default_method())
280 self.assertFalse(yc.is_default_method())
282 def test_is_deleted_method(self):
283 source = "class X { X() = delete; }; class Y { Y(); };"
284 tu = get_tu(source, lang="cpp")
286 xs = get_cursors(tu, "X")
287 ys = get_cursors(tu, "Y")
289 self.assertEqual(len(xs), 2)
290 self.assertEqual(len(ys), 2)
292 xc = xs[1]
293 yc = ys[1]
295 self.assertTrue(xc.is_deleted_method())
296 self.assertFalse(yc.is_deleted_method())
298 def test_is_copy_assignment_operator_method(self):
299 source_with_copy_assignment_operators = """
300 struct Foo {
301 // Those are copy-assignment operators
302 bool operator=(const Foo&);
303 bool operator=(Foo&);
304 Foo operator=(Foo);
305 bool operator=(volatile Foo&);
306 bool operator=(const volatile Foo&);
308 // Positive-check that the recognition works for templated classes too
309 template <typename T>
310 class Bar {
311 bool operator=(const Bar&);
312 Bar operator=(const Bar);
313 bool operator=(Bar<T>&);
314 bool operator=(volatile Bar&);
315 bool operator=(const volatile Bar<T>&);
318 source_without_copy_assignment_operators = """
319 struct Foo {
320 // Those are not copy-assignment operators
321 template<typename T>
322 bool operator=(const T&);
323 bool operator=(const bool&);
324 bool operator=(char&);
325 bool operator=(volatile unsigned int&);
326 bool operator=(const volatile unsigned char&);
327 bool operator=(int);
328 bool operator=(Foo&&);
331 tu_with_copy_assignment_operators = get_tu(
332 source_with_copy_assignment_operators, lang="cpp"
334 tu_without_copy_assignment_operators = get_tu(
335 source_without_copy_assignment_operators, lang="cpp"
338 copy_assignment_operators_cursors = get_cursors(
339 tu_with_copy_assignment_operators, "operator="
341 non_copy_assignment_operators_cursors = get_cursors(
342 tu_without_copy_assignment_operators, "operator="
345 self.assertEqual(len(copy_assignment_operators_cursors), 10)
346 self.assertEqual(len(non_copy_assignment_operators_cursors), 7)
348 self.assertTrue(
349 all(
351 cursor.is_copy_assignment_operator_method()
352 for cursor in copy_assignment_operators_cursors
357 self.assertFalse(
358 any(
360 cursor.is_copy_assignment_operator_method()
361 for cursor in non_copy_assignment_operators_cursors
366 def test_is_move_assignment_operator_method(self):
367 """Ensure Cursor.is_move_assignment_operator_method works."""
368 source_with_move_assignment_operators = """
369 struct Foo {
370 // Those are move-assignment operators
371 bool operator=(const Foo&&);
372 bool operator=(Foo&&);
373 bool operator=(volatile Foo&&);
374 bool operator=(const volatile Foo&&);
376 // Positive-check that the recognition works for templated classes too
377 template <typename T>
378 class Bar {
379 bool operator=(const Bar&&);
380 bool operator=(Bar<T>&&);
381 bool operator=(volatile Bar&&);
382 bool operator=(const volatile Bar<T>&&);
385 source_without_move_assignment_operators = """
386 struct Foo {
387 // Those are not move-assignment operators
388 template<typename T>
389 bool operator=(const T&&);
390 bool operator=(const bool&&);
391 bool operator=(char&&);
392 bool operator=(volatile unsigned int&&);
393 bool operator=(const volatile unsigned char&&);
394 bool operator=(int);
395 bool operator=(Foo);
398 tu_with_move_assignment_operators = get_tu(
399 source_with_move_assignment_operators, lang="cpp"
401 tu_without_move_assignment_operators = get_tu(
402 source_without_move_assignment_operators, lang="cpp"
405 move_assignment_operators_cursors = get_cursors(
406 tu_with_move_assignment_operators, "operator="
408 non_move_assignment_operators_cursors = get_cursors(
409 tu_without_move_assignment_operators, "operator="
412 self.assertEqual(len(move_assignment_operators_cursors), 8)
413 self.assertTrue(len(non_move_assignment_operators_cursors), 7)
415 self.assertTrue(
416 all(
418 cursor.is_move_assignment_operator_method()
419 for cursor in move_assignment_operators_cursors
423 self.assertFalse(
424 any(
426 cursor.is_move_assignment_operator_method()
427 for cursor in non_move_assignment_operators_cursors
432 def test_is_explicit_method(self):
433 """Ensure Cursor.is_explicit_method works."""
434 source_with_explicit_methods = """
435 struct Foo {
436 // Those are explicit
437 explicit Foo(double);
438 explicit(true) Foo(char);
439 explicit operator double();
440 explicit(true) operator char();
443 source_without_explicit_methods = """
444 struct Foo {
445 // Those are not explicit
446 Foo(int);
447 explicit(false) Foo(float);
448 operator int();
449 explicit(false) operator float();
452 tu_with_explicit_methods = get_tu(source_with_explicit_methods, lang="cpp")
453 tu_without_explicit_methods = get_tu(
454 source_without_explicit_methods, lang="cpp"
457 explicit_methods_cursors = [
458 *get_cursors(tu_with_explicit_methods, "Foo")[1:],
459 get_cursor(tu_with_explicit_methods, "operator double"),
460 get_cursor(tu_with_explicit_methods, "operator char"),
463 non_explicit_methods_cursors = [
464 *get_cursors(tu_without_explicit_methods, "Foo")[1:],
465 get_cursor(tu_without_explicit_methods, "operator int"),
466 get_cursor(tu_without_explicit_methods, "operator float"),
469 self.assertEqual(len(explicit_methods_cursors), 4)
470 self.assertTrue(len(non_explicit_methods_cursors), 4)
472 self.assertTrue(
473 all([cursor.is_explicit_method() for cursor in explicit_methods_cursors])
475 self.assertFalse(
476 any(
477 [cursor.is_explicit_method() for cursor in non_explicit_methods_cursors]
481 def test_is_mutable_field(self):
482 """Ensure Cursor.is_mutable_field works."""
483 source = "class X { int x_; mutable int y_; };"
484 tu = get_tu(source, lang="cpp")
486 cls = get_cursor(tu, "X")
487 x_ = get_cursor(tu, "x_")
488 y_ = get_cursor(tu, "y_")
489 self.assertIsNotNone(cls)
490 self.assertIsNotNone(x_)
491 self.assertIsNotNone(y_)
493 self.assertFalse(x_.is_mutable_field())
494 self.assertTrue(y_.is_mutable_field())
496 def test_is_static_method(self):
497 """Ensure Cursor.is_static_method works."""
499 source = "class X { static void foo(); void bar(); };"
500 tu = get_tu(source, lang="cpp")
502 cls = get_cursor(tu, "X")
503 foo = get_cursor(tu, "foo")
504 bar = get_cursor(tu, "bar")
505 self.assertIsNotNone(cls)
506 self.assertIsNotNone(foo)
507 self.assertIsNotNone(bar)
509 self.assertTrue(foo.is_static_method())
510 self.assertFalse(bar.is_static_method())
512 def test_is_pure_virtual_method(self):
513 """Ensure Cursor.is_pure_virtual_method works."""
514 source = "class X { virtual void foo() = 0; virtual void bar(); };"
515 tu = get_tu(source, lang="cpp")
517 cls = get_cursor(tu, "X")
518 foo = get_cursor(tu, "foo")
519 bar = get_cursor(tu, "bar")
520 self.assertIsNotNone(cls)
521 self.assertIsNotNone(foo)
522 self.assertIsNotNone(bar)
524 self.assertTrue(foo.is_pure_virtual_method())
525 self.assertFalse(bar.is_pure_virtual_method())
527 def test_is_virtual_method(self):
528 """Ensure Cursor.is_virtual_method works."""
529 source = "class X { virtual void foo(); void bar(); };"
530 tu = get_tu(source, lang="cpp")
532 cls = get_cursor(tu, "X")
533 foo = get_cursor(tu, "foo")
534 bar = get_cursor(tu, "bar")
535 self.assertIsNotNone(cls)
536 self.assertIsNotNone(foo)
537 self.assertIsNotNone(bar)
539 self.assertTrue(foo.is_virtual_method())
540 self.assertFalse(bar.is_virtual_method())
542 def test_is_abstract_record(self):
543 """Ensure Cursor.is_abstract_record works."""
544 source = "struct X { virtual void x() = 0; }; struct Y : X { void x(); };"
545 tu = get_tu(source, lang="cpp")
547 cls = get_cursor(tu, "X")
548 self.assertTrue(cls.is_abstract_record())
550 cls = get_cursor(tu, "Y")
551 self.assertFalse(cls.is_abstract_record())
553 def test_is_scoped_enum(self):
554 """Ensure Cursor.is_scoped_enum works."""
555 source = "class X {}; enum RegularEnum {}; enum class ScopedEnum {};"
556 tu = get_tu(source, lang="cpp")
558 cls = get_cursor(tu, "X")
559 regular_enum = get_cursor(tu, "RegularEnum")
560 scoped_enum = get_cursor(tu, "ScopedEnum")
561 self.assertIsNotNone(cls)
562 self.assertIsNotNone(regular_enum)
563 self.assertIsNotNone(scoped_enum)
565 self.assertFalse(cls.is_scoped_enum())
566 self.assertFalse(regular_enum.is_scoped_enum())
567 self.assertTrue(scoped_enum.is_scoped_enum())
569 def test_get_definition(self):
570 """Ensure Cursor.get_definition works."""
571 tu = get_tu(
573 class A {
574 constexpr static int f(){return 3;}
576 struct B {
577 int b = A::f();
579 """,
580 lang="cpp",
582 curs = get_cursors(tu, "f")
583 self.assertEqual(len(curs), 4)
584 self.assertEqual(curs[0].kind, CursorKind.CXX_METHOD)
585 self.assertEqual(curs[1].get_definition(), curs[0])
586 self.assertEqual(curs[2].get_definition(), curs[0])
587 self.assertEqual(curs[3].get_definition(), curs[0])
589 def test_get_usr(self):
590 """Ensure Cursor.get_usr works."""
591 tu = get_tu(
593 int add(int, int);
594 int add(int a, int b) { return a + b; }
595 int add(float a, float b) { return a + b; }
596 """,
597 lang="cpp",
599 curs = get_cursors(tu, "add")
600 self.assertEqual(len(curs), 3)
601 self.assertEqual(curs[0].get_usr(), curs[1].get_usr())
602 self.assertNotEqual(curs[0].get_usr(), curs[2].get_usr())
604 def test_underlying_type(self):
605 tu = get_tu("typedef int foo;")
606 typedef = get_cursor(tu, "foo")
607 self.assertIsNotNone(typedef)
609 self.assertTrue(typedef.kind.is_declaration())
610 underlying = typedef.underlying_typedef_type
611 self.assertEqual(underlying.kind, TypeKind.INT)
613 def test_semantic_parent(self):
614 tu = get_tu(kParentTest, "cpp")
615 curs = get_cursors(tu, "f")
616 decl = get_cursor(tu, "C")
617 self.assertEqual(len(curs), 2)
618 self.assertEqual(curs[0].semantic_parent, curs[1].semantic_parent)
619 self.assertEqual(curs[0].semantic_parent, decl)
621 def test_lexical_parent(self):
622 tu = get_tu(kParentTest, "cpp")
623 curs = get_cursors(tu, "f")
624 decl = get_cursor(tu, "C")
625 self.assertEqual(len(curs), 2)
626 self.assertNotEqual(curs[0].lexical_parent, curs[1].lexical_parent)
627 self.assertEqual(curs[0].lexical_parent, decl)
628 self.assertEqual(curs[1].lexical_parent, tu.cursor)
630 def test_enum_type(self):
631 tu = get_tu("enum TEST { FOO=1, BAR=2 };")
632 enum = get_cursor(tu, "TEST")
633 self.assertIsNotNone(enum)
635 self.assertEqual(enum.kind, CursorKind.ENUM_DECL)
636 enum_type = enum.enum_type
637 self.assertIn(enum_type.kind, (TypeKind.UINT, TypeKind.INT))
639 def test_enum_type_cpp(self):
640 tu = get_tu("enum TEST : long long { FOO=1, BAR=2 };", lang="cpp")
641 enum = get_cursor(tu, "TEST")
642 self.assertIsNotNone(enum)
644 self.assertEqual(enum.kind, CursorKind.ENUM_DECL)
645 self.assertEqual(enum.enum_type.kind, TypeKind.LONGLONG)
647 def test_objc_type_encoding(self):
648 tu = get_tu("int i;", lang="objc")
649 i = get_cursor(tu, "i")
651 self.assertIsNotNone(i)
652 self.assertEqual(i.objc_type_encoding, "i")
654 def test_enum_values(self):
655 tu = get_tu("enum TEST { SPAM=1, EGG, HAM = EGG * 20};")
656 enum = get_cursor(tu, "TEST")
657 self.assertIsNotNone(enum)
659 self.assertEqual(enum.kind, CursorKind.ENUM_DECL)
661 enum_constants = list(enum.get_children())
662 self.assertEqual(len(enum_constants), 3)
664 spam, egg, ham = enum_constants
666 self.assertEqual(spam.kind, CursorKind.ENUM_CONSTANT_DECL)
667 self.assertEqual(spam.enum_value, 1)
668 self.assertEqual(egg.kind, CursorKind.ENUM_CONSTANT_DECL)
669 self.assertEqual(egg.enum_value, 2)
670 self.assertEqual(ham.kind, CursorKind.ENUM_CONSTANT_DECL)
671 self.assertEqual(ham.enum_value, 40)
673 def test_enum_values_cpp(self):
674 tu = get_tu(
675 "enum TEST : long long { SPAM = -1, HAM = 0x10000000000};", lang="cpp"
677 enum = get_cursor(tu, "TEST")
678 self.assertIsNotNone(enum)
680 self.assertEqual(enum.kind, CursorKind.ENUM_DECL)
682 enum_constants = list(enum.get_children())
683 self.assertEqual(len(enum_constants), 2)
685 spam, ham = enum_constants
687 self.assertEqual(spam.kind, CursorKind.ENUM_CONSTANT_DECL)
688 self.assertEqual(spam.enum_value, -1)
689 self.assertEqual(ham.kind, CursorKind.ENUM_CONSTANT_DECL)
690 self.assertEqual(ham.enum_value, 0x10000000000)
692 def test_enum_values_unsigned(self):
693 tu = get_tu("enum TEST : unsigned char { SPAM=0, HAM = 200};", lang="cpp")
694 enum = get_cursor(tu, "TEST")
695 self.assertIsNotNone(enum)
697 self.assertEqual(enum.kind, CursorKind.ENUM_DECL)
699 enum_constants = list(enum.get_children())
700 self.assertEqual(len(enum_constants), 2)
702 spam, ham = enum_constants
704 self.assertEqual(spam.kind, CursorKind.ENUM_CONSTANT_DECL)
705 self.assertEqual(spam.enum_value, 0)
706 self.assertEqual(ham.kind, CursorKind.ENUM_CONSTANT_DECL)
707 self.assertEqual(ham.enum_value, 200)
709 def test_annotation_attribute(self):
710 tu = get_tu(
711 'int foo (void) __attribute__ ((annotate("here be annotation attribute")));'
714 foo = get_cursor(tu, "foo")
715 self.assertIsNotNone(foo)
717 for c in foo.get_children():
718 if c.kind == CursorKind.ANNOTATE_ATTR:
719 self.assertEqual(c.displayname, "here be annotation attribute")
720 break
721 else:
722 self.fail("Couldn't find annotation")
724 def test_annotation_template(self):
725 annotation = '__attribute__ ((annotate("annotation")))'
726 for source, kind in [
727 ("int foo (T value) %s;", CursorKind.FUNCTION_TEMPLATE),
728 ("class %s foo {};", CursorKind.CLASS_TEMPLATE),
730 source = "template<typename T> " + (source % annotation)
731 tu = get_tu(source, lang="cpp")
733 foo = get_cursor(tu, "foo")
734 self.assertIsNotNone(foo)
735 self.assertEqual(foo.kind, kind)
737 for c in foo.get_children():
738 if c.kind == CursorKind.ANNOTATE_ATTR:
739 self.assertEqual(c.displayname, "annotation")
740 break
741 else:
742 self.fail("Couldn't find annotation for {}".format(kind))
744 def test_result_type(self):
745 tu = get_tu("int foo();")
746 foo = get_cursor(tu, "foo")
748 self.assertIsNotNone(foo)
749 t = foo.result_type
750 self.assertEqual(t.kind, TypeKind.INT)
752 def test_result_type_objc_method_decl(self):
753 code = """\
754 @interface Interface : NSObject
755 -(void)voidMethod;
756 @end
758 tu = get_tu(code, lang="objc")
759 cursor = get_cursor(tu, "voidMethod")
760 result_type = cursor.result_type
761 self.assertEqual(cursor.kind, CursorKind.OBJC_INSTANCE_METHOD_DECL)
762 self.assertEqual(result_type.kind, TypeKind.VOID)
764 def test_storage_class(self):
765 tu = get_tu(
767 extern int ex;
768 register int reg;
769 int count(int a, int b){
770 static int counter = 0;
771 return 0;
773 """,
774 lang="cpp",
776 cursor = get_cursor(tu, "ex")
777 self.assertEqual(cursor.storage_class, StorageClass.EXTERN)
778 cursor = get_cursor(tu, "counter")
779 self.assertEqual(cursor.storage_class, StorageClass.STATIC)
780 cursor = get_cursor(tu, "reg")
781 self.assertEqual(cursor.storage_class, StorageClass.REGISTER)
783 def test_availability(self):
784 tu = get_tu("class A { A(A const&) = delete; };", lang="cpp")
786 # AvailabilityKind.AVAILABLE
787 cursor = get_cursor(tu, "A")
788 self.assertEqual(cursor.kind, CursorKind.CLASS_DECL)
789 self.assertEqual(cursor.availability, AvailabilityKind.AVAILABLE)
791 # AvailabilityKind.NOT_AVAILABLE
792 cursors = get_cursors(tu, "A")
793 for c in cursors:
794 if c.kind == CursorKind.CONSTRUCTOR:
795 self.assertEqual(c.availability, AvailabilityKind.NOT_AVAILABLE)
796 break
797 else:
798 self.fail("Could not find cursor for deleted constructor")
800 # AvailabilityKind.DEPRECATED
801 tu = get_tu("void test() __attribute__((deprecated));", lang="cpp")
802 cursor = get_cursor(tu, "test")
803 self.assertEqual(cursor.availability, AvailabilityKind.DEPRECATED)
805 # AvailabilityKind.NOT_ACCESSIBLE is only used in the code completion results
807 def test_get_tokens(self):
808 """Ensure we can map cursors back to tokens."""
809 tu = get_tu("int foo(int i);")
810 foo = get_cursor(tu, "foo")
812 tokens = list(foo.get_tokens())
813 self.assertEqual(len(tokens), 6)
814 self.assertEqual(tokens[0].spelling, "int")
815 self.assertEqual(tokens[1].spelling, "foo")
817 def test_get_token_cursor(self):
818 """Ensure we can map tokens to cursors."""
819 tu = get_tu("class A {}; int foo(A var = A());", lang="cpp")
820 foo = get_cursor(tu, "foo")
822 for cursor in foo.walk_preorder():
823 if cursor.kind.is_expression() and not cursor.kind.is_statement():
824 break
825 else:
826 self.fail("Could not find default value expression")
828 tokens = list(cursor.get_tokens())
829 self.assertEqual(len(tokens), 4, [t.spelling for t in tokens])
830 self.assertEqual(tokens[0].spelling, "=")
831 self.assertEqual(tokens[1].spelling, "A")
832 self.assertEqual(tokens[2].spelling, "(")
833 self.assertEqual(tokens[3].spelling, ")")
834 t_cursor = tokens[1].cursor
835 self.assertEqual(t_cursor.kind, CursorKind.TYPE_REF)
836 r_cursor = t_cursor.referenced # should not raise an exception
837 self.assertEqual(r_cursor.kind, CursorKind.CLASS_DECL)
839 def test_get_field_offsetof(self):
840 tu = get_tu(
841 "struct myStruct {int a; char b; char c; short d; char e;};", lang="cpp"
843 c1 = get_cursor(tu, "myStruct")
844 c2 = get_cursor(tu, "a")
845 c3 = get_cursor(tu, "b")
846 c4 = get_cursor(tu, "c")
847 c5 = get_cursor(tu, "d")
848 c6 = get_cursor(tu, "e")
849 self.assertEqual(c1.get_field_offsetof(), -1)
850 self.assertEqual(c2.get_field_offsetof(), 0)
851 self.assertEqual(c3.get_field_offsetof(), 32)
852 self.assertEqual(c4.get_field_offsetof(), 40)
853 self.assertEqual(c5.get_field_offsetof(), 48)
854 self.assertEqual(c6.get_field_offsetof(), 64)
856 def test_get_arguments(self):
857 tu = get_tu("void foo(int i, int j);")
858 foo = get_cursor(tu, "foo")
859 arguments = list(foo.get_arguments())
861 self.assertEqual(len(arguments), 2)
862 self.assertEqual(arguments[0].spelling, "i")
863 self.assertEqual(arguments[1].spelling, "j")
865 def test_get_num_template_arguments(self):
866 tu = get_tu(kTemplateArgTest, lang="cpp")
867 foos = get_cursors(tu, "foo")
869 self.assertEqual(foos[1].get_num_template_arguments(), 3)
871 def test_get_template_argument_kind(self):
872 tu = get_tu(kTemplateArgTest, lang="cpp")
873 foos = get_cursors(tu, "foo")
875 self.assertEqual(
876 foos[1].get_template_argument_kind(0), TemplateArgumentKind.INTEGRAL
878 self.assertEqual(
879 foos[1].get_template_argument_kind(1), TemplateArgumentKind.TYPE
881 self.assertEqual(
882 foos[1].get_template_argument_kind(2), TemplateArgumentKind.INTEGRAL
885 def test_get_template_argument_type(self):
886 tu = get_tu(kTemplateArgTest, lang="cpp")
887 foos = get_cursors(tu, "foo")
889 self.assertEqual(foos[1].get_template_argument_type(1).kind, TypeKind.FLOAT)
891 def test_get_template_argument_value(self):
892 tu = get_tu(kTemplateArgTest, lang="cpp")
893 foos = get_cursors(tu, "foo")
895 self.assertEqual(foos[1].get_template_argument_value(0), -7)
896 self.assertEqual(foos[1].get_template_argument_value(2), True)
898 def test_get_template_argument_unsigned_value(self):
899 tu = get_tu(kTemplateArgTest, lang="cpp")
900 foos = get_cursors(tu, "foo")
902 self.assertEqual(foos[1].get_template_argument_unsigned_value(0), 2**32 - 7)
903 self.assertEqual(foos[1].get_template_argument_unsigned_value(2), True)
905 def test_referenced(self):
906 tu = get_tu("void foo(); void bar() { foo(); }")
907 foo = get_cursor(tu, "foo")
908 bar = get_cursor(tu, "bar")
909 for c in bar.get_children():
910 if c.kind == CursorKind.CALL_EXPR:
911 self.assertEqual(c.referenced.spelling, foo.spelling)
912 break
914 def test_mangled_name(self):
915 kInputForMangling = """\
916 int foo(int, int);
918 tu = get_tu(kInputForMangling, lang="cpp")
919 foo = get_cursor(tu, "foo")
921 # Since libclang does not link in targets, we cannot pass a triple to it
922 # and force the target. To enable this test to pass on all platforms, accept
923 # all valid manglings.
924 # [c-index-test handles this by running the source through clang, emitting
925 # an AST file and running libclang on that AST file]
926 self.assertIn(
927 foo.mangled_name, ("_Z3fooii", "__Z3fooii", "?foo@@YAHHH", "?foo@@YAHHH@Z")
930 def test_binop(self):
931 tu = get_tu(kBinops, lang="cpp")
933 operators = {
934 # not exposed yet
935 # ".*" : BinaryOperator.PtrMemD,
936 "->*": BinaryOperator.PtrMemI,
937 "*": BinaryOperator.Mul,
938 "/": BinaryOperator.Div,
939 "%": BinaryOperator.Rem,
940 "+": BinaryOperator.Add,
941 "-": BinaryOperator.Sub,
942 "<<": BinaryOperator.Shl,
943 ">>": BinaryOperator.Shr,
944 # tests do not run in C++2a mode so this operator is not available
945 # "<=>" : BinaryOperator.Cmp,
946 "<": BinaryOperator.LT,
947 ">": BinaryOperator.GT,
948 "<=": BinaryOperator.LE,
949 ">=": BinaryOperator.GE,
950 "==": BinaryOperator.EQ,
951 "!=": BinaryOperator.NE,
952 "&": BinaryOperator.And,
953 "^": BinaryOperator.Xor,
954 "|": BinaryOperator.Or,
955 "&&": BinaryOperator.LAnd,
956 "||": BinaryOperator.LOr,
957 "=": BinaryOperator.Assign,
958 "*=": BinaryOperator.MulAssign,
959 "/=": BinaryOperator.DivAssign,
960 "%=": BinaryOperator.RemAssign,
961 "+=": BinaryOperator.AddAssign,
962 "-=": BinaryOperator.SubAssign,
963 "<<=": BinaryOperator.ShlAssign,
964 ">>=": BinaryOperator.ShrAssign,
965 "&=": BinaryOperator.AndAssign,
966 "^=": BinaryOperator.XorAssign,
967 "|=": BinaryOperator.OrAssign,
968 ",": BinaryOperator.Comma,
971 for op, typ in operators.items():
972 c = get_cursor(tu, op)
973 assert c.binary_operator == typ
975 def test_from_result_null(self):
976 tu = get_tu("int a = 1+2;", lang="cpp")
977 op = next(next(tu.cursor.get_children()).get_children())
978 self.assertEqual(op.kind, CursorKind.BINARY_OPERATOR)
979 self.assertEqual(op.get_definition(), None)
981 def test_from_cursor_result_null(self):
982 tu = get_tu("")
983 self.assertEqual(tu.cursor.semantic_parent, None)