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 c[5]; int i[]; int x; int v[x];') 241 c = get_cursor(tu, 'c') 242 i = get_cursor(tu, 'i') 243 v = get_cursor(tu, 'v') 244 assert c is not None 245 assert i is not None 246 assert v is not None 247 248 assert c.type.kind == TypeKind.CONSTANTARRAY 249 assert c.type.element_type.kind == TypeKind.INT 250 assert i.type.kind == TypeKind.INCOMPLETEARRAY 251 assert i.type.element_type.kind == TypeKind.INT 252 assert v.type.kind == TypeKind.VARIABLEARRAY 253 assert v.type.element_type.kind == TypeKind.INT 254 255 @raises(Exception) 256 def test_invalid_element_type(): 257 """Ensure Type.element_type raises if type doesn't have elements.""" 258 tu = get_tu('int i;') 259 i = get_cursor(tu, 'i') 260 assert i is not None 261 i.element_type 262 263 def test_element_count(): 264 """Ensure Type.element_count works.""" 265 tu = get_tu('int i[5]; int j;') 266 i = get_cursor(tu, 'i') 267 j = get_cursor(tu, 'j') 268 269 assert i is not None 270 assert j is not None 271 272 assert i.type.element_count == 5 273 274 try: 275 j.type.element_count 276 assert False 277 except: 278 assert True 279 280 def test_is_volatile_qualified(): 281 """Ensure Type.is_volatile_qualified works.""" 282 283 tu = get_tu('volatile int i = 4; int j = 2;') 284 285 i = get_cursor(tu, 'i') 286 j = get_cursor(tu, 'j') 287 288 assert i is not None 289 assert j is not None 290 291 assert isinstance(i.type.is_volatile_qualified(), bool) 292 assert i.type.is_volatile_qualified() 293 assert not j.type.is_volatile_qualified() 294 295 def test_is_restrict_qualified(): 296 """Ensure Type.is_restrict_qualified works.""" 297 298 tu = get_tu('struct s { void * restrict i; void * j; };') 299 300 i = get_cursor(tu, 'i') 301 j = get_cursor(tu, 'j') 302 303 assert i is not None 304 assert j is not None 305 306 assert isinstance(i.type.is_restrict_qualified(), bool) 307 assert i.type.is_restrict_qualified() 308 assert not j.type.is_restrict_qualified() 309 310 def test_record_layout(): 311 """Ensure Cursor.type.get_size, Cursor.type.get_align and 312 Cursor.type.get_offset works.""" 313 314 source =""" 315 struct a { 316 long a1; 317 long a2:3; 318 long a3:4; 319 long long a4; 320 }; 321 """ 322 tries=[(['-target','i386-linux-gnu'],(4,16,0,32,35,64)), 323 (['-target','nvptx64-unknown-unknown'],(8,24,0,64,67,128)), 324 (['-target','i386-pc-win32'],(8,16,0,32,35,64)), 325 (['-target','msp430-none-none'],(2,14,0,32,35,48))] 326 for flags, values in tries: 327 align,total,a1,a2,a3,a4 = values 328 329 tu = get_tu(source, flags=flags) 330 teststruct = get_cursor(tu, 'a') 331 fields = list(teststruct.get_children()) 332 333 assert teststruct.type.get_align() == align 334 assert teststruct.type.get_size() == total 335 assert teststruct.type.get_offset(fields[0].spelling) == a1 336 assert teststruct.type.get_offset(fields[1].spelling) == a2 337 assert teststruct.type.get_offset(fields[2].spelling) == a3 338 assert teststruct.type.get_offset(fields[3].spelling) == a4 339 assert fields[0].is_bitfield() == False 340 assert fields[1].is_bitfield() == True 341 assert fields[1].get_bitfield_width() == 3 342 assert fields[2].is_bitfield() == True 343 assert fields[2].get_bitfield_width() == 4 344 assert fields[3].is_bitfield() == False 345 346 def test_offset(): 347 """Ensure Cursor.get_record_field_offset works in anonymous records""" 348 source=""" 349 struct Test { 350 struct { 351 int bariton; 352 union { 353 int foo; 354 }; 355 }; 356 int bar; 357 };""" 358 tries=[(['-target','i386-linux-gnu'],(4,16,0,32,64)), 359 (['-target','nvptx64-unknown-unknown'],(8,24,0,32,64)), 360 (['-target','i386-pc-win32'],(8,16,0,32,64)), 361 (['-target','msp430-none-none'],(2,14,0,32,64))] 362 for flags, values in tries: 363 align,total,bariton,foo,bar = values 364 tu = get_tu(source) 365 teststruct = get_cursor(tu, 'Test') 366 fields = list(teststruct.get_children()) 367 assert teststruct.type.get_offset("bariton") == bariton 368 assert teststruct.type.get_offset("foo") == foo 369 assert teststruct.type.get_offset("bar") == bar 370 371 372