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