Home | History | Annotate | Download | only in cindex
      1 import gc
      2 
      3 from clang.cindex import CursorKind
      4 from clang.cindex import TranslationUnit
      5 from clang.cindex import TypeKind
      6 from nose.tools import raises
      7 from .util import get_cursor
      8 from .util import get_tu
      9 
     10 kInput = """\
     11 
     12 typedef int I;
     13 
     14 struct teststruct {
     15   int a;
     16   I b;
     17   long c;
     18   unsigned long d;
     19   signed long e;
     20   const int f;
     21   int *g;
     22   int ***h;
     23 };
     24 
     25 """
     26 
     27 def test_a_struct():
     28     tu = get_tu(kInput)
     29 
     30     teststruct = get_cursor(tu, 'teststruct')
     31     assert teststruct is not None, "Could not find teststruct."
     32     fields = list(teststruct.get_children())
     33     assert all(x.kind == CursorKind.FIELD_DECL for x in fields)
     34     assert all(x.translation_unit is not None for x in fields)
     35 
     36     assert fields[0].spelling == 'a'
     37     assert not fields[0].type.is_const_qualified()
     38     assert fields[0].type.kind == TypeKind.INT
     39     assert fields[0].type.get_canonical().kind == TypeKind.INT
     40 
     41     assert fields[1].spelling == 'b'
     42     assert not fields[1].type.is_const_qualified()
     43     assert fields[1].type.kind == TypeKind.TYPEDEF
     44     assert fields[1].type.get_canonical().kind == TypeKind.INT
     45     assert fields[1].type.get_declaration().spelling == 'I'
     46 
     47     assert fields[2].spelling == 'c'
     48     assert not fields[2].type.is_const_qualified()
     49     assert fields[2].type.kind == TypeKind.LONG
     50     assert fields[2].type.get_canonical().kind == TypeKind.LONG
     51 
     52     assert fields[3].spelling == 'd'
     53     assert not fields[3].type.is_const_qualified()
     54     assert fields[3].type.kind == TypeKind.ULONG
     55     assert fields[3].type.get_canonical().kind == TypeKind.ULONG
     56 
     57     assert fields[4].spelling == 'e'
     58     assert not fields[4].type.is_const_qualified()
     59     assert fields[4].type.kind == TypeKind.LONG
     60     assert fields[4].type.get_canonical().kind == TypeKind.LONG
     61 
     62     assert fields[5].spelling == 'f'
     63     assert fields[5].type.is_const_qualified()
     64     assert fields[5].type.kind == TypeKind.INT
     65     assert fields[5].type.get_canonical().kind == TypeKind.INT
     66 
     67     assert fields[6].spelling == 'g'
     68     assert not fields[6].type.is_const_qualified()
     69     assert fields[6].type.kind == TypeKind.POINTER
     70     assert fields[6].type.get_pointee().kind == TypeKind.INT
     71 
     72     assert fields[7].spelling == 'h'
     73     assert not fields[7].type.is_const_qualified()
     74     assert fields[7].type.kind == TypeKind.POINTER
     75     assert fields[7].type.get_pointee().kind == TypeKind.POINTER
     76     assert fields[7].type.get_pointee().get_pointee().kind == TypeKind.POINTER
     77     assert fields[7].type.get_pointee().get_pointee().get_pointee().kind == TypeKind.INT
     78 
     79 def test_references():
     80     """Ensure that a Type maintains a reference to a TranslationUnit."""
     81 
     82     tu = get_tu('int x;')
     83     children = list(tu.cursor.get_children())
     84     assert len(children) > 0
     85 
     86     cursor = children[0]
     87     t = cursor.type
     88 
     89     assert isinstance(t.translation_unit, TranslationUnit)
     90 
     91     # Delete main TranslationUnit reference and force a GC.
     92     del tu
     93     gc.collect()
     94     assert isinstance(t.translation_unit, TranslationUnit)
     95 
     96     # If the TU was destroyed, this should cause a segfault.
     97     decl = t.get_declaration()
     98 
     99 constarrayInput="""
    100 struct teststruct {
    101   void *A[2];
    102 };
    103 """
    104 def testConstantArray():
    105     tu = get_tu(constarrayInput)
    106 
    107     teststruct = get_cursor(tu, 'teststruct')
    108     assert teststruct is not None, "Didn't find teststruct??"
    109     fields = list(teststruct.get_children())
    110     assert fields[0].spelling == 'A'
    111     assert fields[0].type.kind == TypeKind.CONSTANTARRAY
    112     assert fields[0].type.get_array_element_type() is not None
    113     assert fields[0].type.get_array_element_type().kind == TypeKind.POINTER
    114     assert fields[0].type.get_array_size() == 2
    115 
    116 def test_equal():
    117     """Ensure equivalence operators work on Type."""
    118     source = 'int a; int b; void *v;'
    119     tu = get_tu(source)
    120 
    121     a = get_cursor(tu, 'a')
    122     b = get_cursor(tu, 'b')
    123     v = get_cursor(tu, 'v')
    124 
    125     assert a is not None
    126     assert b is not None
    127     assert v is not None
    128 
    129     assert a.type == b.type
    130     assert a.type != v.type
    131 
    132     assert a.type != None
    133     assert a.type != 'foo'
    134 
    135 def test_typekind_spelling():
    136     """Ensure TypeKind.spelling works."""
    137     tu = get_tu('int a;')
    138     a = get_cursor(tu, 'a')
    139 
    140     assert a is not None
    141     assert a.type.kind.spelling == 'Int'
    142 
    143 def test_function_argument_types():
    144     """Ensure that Type.argument_types() works as expected."""
    145     tu = get_tu('void f(int, int);')
    146     f = get_cursor(tu, 'f')
    147     assert f is not None
    148 
    149     args = f.type.argument_types()
    150     assert args is not None
    151     assert len(args) == 2
    152 
    153     t0 = args[0]
    154     assert t0 is not None
    155     assert t0.kind == TypeKind.INT
    156 
    157     t1 = args[1]
    158     assert t1 is not None
    159     assert t1.kind == TypeKind.INT
    160 
    161     args2 = list(args)
    162     assert len(args2) == 2
    163     assert t0 == args2[0]
    164     assert t1 == args2[1]
    165 
    166 @raises(TypeError)
    167 def test_argument_types_string_key():
    168     """Ensure that non-int keys raise a TypeError."""
    169     tu = get_tu('void f(int, int);')
    170     f = get_cursor(tu, 'f')
    171     assert f is not None
    172 
    173     args = f.type.argument_types()
    174     assert len(args) == 2
    175 
    176     args['foo']
    177 
    178 @raises(IndexError)
    179 def test_argument_types_negative_index():
    180     """Ensure that negative indexes on argument_types Raises an IndexError."""
    181     tu = get_tu('void f(int, int);')
    182     f = get_cursor(tu, 'f')
    183     args = f.type.argument_types()
    184 
    185     args[-1]
    186 
    187 @raises(IndexError)
    188 def test_argument_types_overflow_index():
    189     """Ensure that indexes beyond the length of Type.argument_types() raise."""
    190     tu = get_tu('void f(int, int);')
    191     f = get_cursor(tu, 'f')
    192     args = f.type.argument_types()
    193 
    194     args[2]
    195 
    196 @raises(Exception)
    197 def test_argument_types_invalid_type():
    198     """Ensure that obtaining argument_types on a Type without them raises."""
    199     tu = get_tu('int i;')
    200     i = get_cursor(tu, 'i')
    201     assert i is not None
    202 
    203     i.type.argument_types()
    204 
    205 def test_is_pod():
    206     """Ensure Type.is_pod() works."""
    207     tu = get_tu('int i; void f();')
    208     i = get_cursor(tu, 'i')
    209     f = get_cursor(tu, 'f')
    210 
    211     assert i is not None
    212     assert f is not None
    213 
    214     assert i.type.is_pod()
    215     assert not f.type.is_pod()
    216 
    217 def test_function_variadic():
    218     """Ensure Type.is_function_variadic works."""
    219 
    220     source ="""
    221 #include <stdarg.h>
    222 
    223 void foo(int a, ...);
    224 void bar(int a, int b);
    225 """
    226 
    227     tu = get_tu(source)
    228     foo = get_cursor(tu, 'foo')
    229     bar = get_cursor(tu, 'bar')
    230 
    231     assert foo is not None
    232     assert bar is not None
    233 
    234     assert isinstance(foo.type.is_function_variadic(), bool)
    235     assert foo.type.is_function_variadic()
    236     assert not bar.type.is_function_variadic()
    237 
    238 def test_element_type():
    239     """Ensure Type.element_type works."""
    240     tu = get_tu('int i[5];')
    241     i = get_cursor(tu, 'i')
    242     assert i is not None
    243 
    244     assert i.type.kind == TypeKind.CONSTANTARRAY
    245     assert i.type.element_type.kind == TypeKind.INT
    246 
    247 @raises(Exception)
    248 def test_invalid_element_type():
    249     """Ensure Type.element_type raises if type doesn't have elements."""
    250     tu = get_tu('int i;')
    251     i = get_cursor(tu, 'i')
    252     assert i is not None
    253     i.element_type
    254 
    255 def test_element_count():
    256     """Ensure Type.element_count works."""
    257     tu = get_tu('int i[5]; int j;')
    258     i = get_cursor(tu, 'i')
    259     j = get_cursor(tu, 'j')
    260 
    261     assert i is not None
    262     assert j is not None
    263 
    264     assert i.type.element_count == 5
    265 
    266     try:
    267         j.type.element_count
    268         assert False
    269     except:
    270         assert True
    271 
    272 def test_is_volatile_qualified():
    273     """Ensure Type.is_volatile_qualified works."""
    274 
    275     tu = get_tu('volatile int i = 4; int j = 2;')
    276 
    277     i = get_cursor(tu, 'i')
    278     j = get_cursor(tu, 'j')
    279 
    280     assert i is not None
    281     assert j is not None
    282 
    283     assert isinstance(i.type.is_volatile_qualified(), bool)
    284     assert i.type.is_volatile_qualified()
    285     assert not j.type.is_volatile_qualified()
    286 
    287 def test_is_restrict_qualified():
    288     """Ensure Type.is_restrict_qualified works."""
    289 
    290     tu = get_tu('struct s { void * restrict i; void * j; };')
    291 
    292     i = get_cursor(tu, 'i')
    293     j = get_cursor(tu, 'j')
    294 
    295     assert i is not None
    296     assert j is not None
    297 
    298     assert isinstance(i.type.is_restrict_qualified(), bool)
    299     assert i.type.is_restrict_qualified()
    300     assert not j.type.is_restrict_qualified()
    301