1179337Syongariimport os
2179337Syongarifrom clang.cindex import Config
3179337Syongariif 'CLANG_LIBRARY_PATH' in os.environ:
4179337Syongari    Config.set_library_path(os.environ['CLANG_LIBRARY_PATH'])
5179337Syongari
6179337Syongariimport gc
7179337Syongariimport unittest
8179337Syongari
9179337Syongarifrom clang.cindex import CursorKind
10179337Syongarifrom clang.cindex import TranslationUnit
11179337Syongarifrom clang.cindex import TypeKind
12179337Syongarifrom .util import get_cursor
13179337Syongarifrom .util import get_tu
14179337Syongari
15179337Syongari
16179337SyongarikInput = """\
17179337Syongari
18179337Syongaritypedef int I;
19179337Syongari
20179337Syongaristruct teststruct {
21179337Syongari  int a;
22179337Syongari  I b;
23179337Syongari  long c;
24179337Syongari  unsigned long d;
25179337Syongari  signed long e;
26179337Syongari  const int f;
27179337Syongari  int *g;
28179337Syongari  int ***h;
29179337Syongari};
30179337Syongari
31179337Syongari"""
32179337Syongari
33179337Syongari
34179337SyongariconstarrayInput="""
35179337Syongaristruct teststruct {
36179337Syongari  void *A[2];
37179337Syongari};
38179337Syongari"""
39179337Syongari
40179337Syongari
41179337Syongariclass TestType(unittest.TestCase):
42179337Syongari    def test_a_struct(self):
43179337Syongari        tu = get_tu(kInput)
44179337Syongari
45179337Syongari        teststruct = get_cursor(tu, 'teststruct')
46179337Syongari        self.assertIsNotNone(teststruct, "Could not find teststruct.")
47179337Syongari        fields = list(teststruct.get_children())
48179337Syongari
49179337Syongari        self.assertEqual(fields[0].kind, CursorKind.FIELD_DECL)
50179337Syongari        self.assertIsNotNone(fields[0].translation_unit)
51179337Syongari        self.assertEqual(fields[0].spelling, 'a')
52179337Syongari        self.assertFalse(fields[0].type.is_const_qualified())
53179337Syongari        self.assertEqual(fields[0].type.kind, TypeKind.INT)
54179337Syongari        self.assertEqual(fields[0].type.get_canonical().kind, TypeKind.INT)
55179337Syongari        self.assertEqual(fields[0].type.get_typedef_name(), '')
56179337Syongari
57179337Syongari        self.assertEqual(fields[1].kind, CursorKind.FIELD_DECL)
58179337Syongari        self.assertIsNotNone(fields[1].translation_unit)
59179337Syongari        self.assertEqual(fields[1].spelling, 'b')
60179337Syongari        self.assertFalse(fields[1].type.is_const_qualified())
61179337Syongari        self.assertEqual(fields[1].type.kind, TypeKind.TYPEDEF)
62179337Syongari        self.assertEqual(fields[1].type.get_canonical().kind, TypeKind.INT)
63179337Syongari        self.assertEqual(fields[1].type.get_declaration().spelling, 'I')
64179337Syongari        self.assertEqual(fields[1].type.get_typedef_name(), 'I')
65179337Syongari
66179337Syongari        self.assertEqual(fields[2].kind, CursorKind.FIELD_DECL)
67179337Syongari        self.assertIsNotNone(fields[2].translation_unit)
68179337Syongari        self.assertEqual(fields[2].spelling, 'c')
69179337Syongari        self.assertFalse(fields[2].type.is_const_qualified())
70179337Syongari        self.assertEqual(fields[2].type.kind, TypeKind.LONG)
71179337Syongari        self.assertEqual(fields[2].type.get_canonical().kind, TypeKind.LONG)
72179337Syongari        self.assertEqual(fields[2].type.get_typedef_name(), '')
73179337Syongari
74179337Syongari        self.assertEqual(fields[3].kind, CursorKind.FIELD_DECL)
75179337Syongari        self.assertIsNotNone(fields[3].translation_unit)
76179337Syongari        self.assertEqual(fields[3].spelling, 'd')
77179337Syongari        self.assertFalse(fields[3].type.is_const_qualified())
78179337Syongari        self.assertEqual(fields[3].type.kind, TypeKind.ULONG)
79179337Syongari        self.assertEqual(fields[3].type.get_canonical().kind, TypeKind.ULONG)
80179337Syongari        self.assertEqual(fields[3].type.get_typedef_name(), '')
81179337Syongari
82179337Syongari        self.assertEqual(fields[4].kind, CursorKind.FIELD_DECL)
83179337Syongari        self.assertIsNotNone(fields[4].translation_unit)
84179337Syongari        self.assertEqual(fields[4].spelling, 'e')
85179337Syongari        self.assertFalse(fields[4].type.is_const_qualified())
86179337Syongari        self.assertEqual(fields[4].type.kind, TypeKind.LONG)
87179337Syongari        self.assertEqual(fields[4].type.get_canonical().kind, TypeKind.LONG)
88179337Syongari        self.assertEqual(fields[4].type.get_typedef_name(), '')
89179337Syongari
90179337Syongari        self.assertEqual(fields[5].kind, CursorKind.FIELD_DECL)
91179337Syongari        self.assertIsNotNone(fields[5].translation_unit)
92179337Syongari        self.assertEqual(fields[5].spelling, 'f')
93179337Syongari        self.assertTrue(fields[5].type.is_const_qualified())
94179337Syongari        self.assertEqual(fields[5].type.kind, TypeKind.INT)
95179337Syongari        self.assertEqual(fields[5].type.get_canonical().kind, TypeKind.INT)
96179337Syongari        self.assertEqual(fields[5].type.get_typedef_name(), '')
97179337Syongari
98179337Syongari        self.assertEqual(fields[6].kind, CursorKind.FIELD_DECL)
99179337Syongari        self.assertIsNotNone(fields[6].translation_unit)
100179337Syongari        self.assertEqual(fields[6].spelling, 'g')
101179337Syongari        self.assertFalse(fields[6].type.is_const_qualified())
102179337Syongari        self.assertEqual(fields[6].type.kind, TypeKind.POINTER)
103179337Syongari        self.assertEqual(fields[6].type.get_pointee().kind, TypeKind.INT)
104179337Syongari        self.assertEqual(fields[6].type.get_typedef_name(), '')
105179337Syongari
106179337Syongari        self.assertEqual(fields[7].kind, CursorKind.FIELD_DECL)
107179337Syongari        self.assertIsNotNone(fields[7].translation_unit)
108179337Syongari        self.assertEqual(fields[7].spelling, 'h')
109179337Syongari        self.assertFalse(fields[7].type.is_const_qualified())
110179337Syongari        self.assertEqual(fields[7].type.kind, TypeKind.POINTER)
111179337Syongari        self.assertEqual(fields[7].type.get_pointee().kind, TypeKind.POINTER)
112179337Syongari        self.assertEqual(fields[7].type.get_pointee().get_pointee().kind, TypeKind.POINTER)
113179337Syongari        self.assertEqual(fields[7].type.get_pointee().get_pointee().get_pointee().kind, TypeKind.INT)
114179337Syongari        self.assertEqual(fields[7].type.get_typedef_name(), '')
115179337Syongari
116179337Syongari    def test_references(self):
117179337Syongari        """Ensure that a Type maintains a reference to a TranslationUnit."""
118179337Syongari
119179337Syongari        tu = get_tu('int x;')
120179337Syongari        children = list(tu.cursor.get_children())
121179337Syongari        self.assertGreater(len(children), 0)
122179337Syongari
123179337Syongari        cursor = children[0]
124179337Syongari        t = cursor.type
125179337Syongari
126179337Syongari        self.assertIsInstance(t.translation_unit, TranslationUnit)
127179337Syongari
128179337Syongari        # Delete main TranslationUnit reference and force a GC.
129179337Syongari        del tu
130179337Syongari        gc.collect()
131179337Syongari        self.assertIsInstance(t.translation_unit, TranslationUnit)
132179337Syongari
133179337Syongari        # If the TU was destroyed, this should cause a segfault.
134179337Syongari        decl = t.get_declaration()
135179337Syongari
136179337Syongari    def testConstantArray(self):
137179337Syongari        tu = get_tu(constarrayInput)
138179337Syongari
139179337Syongari        teststruct = get_cursor(tu, 'teststruct')
140179337Syongari        self.assertIsNotNone(teststruct, "Didn't find teststruct??")
141179337Syongari        fields = list(teststruct.get_children())
142179337Syongari        self.assertEqual(fields[0].spelling, 'A')
143179337Syongari        self.assertEqual(fields[0].type.kind, TypeKind.CONSTANTARRAY)
144179337Syongari        self.assertIsNotNone(fields[0].type.get_array_element_type())
145179337Syongari        self.assertEqual(fields[0].type.get_array_element_type().kind, TypeKind.POINTER)
146179337Syongari        self.assertEqual(fields[0].type.get_array_size(), 2)
147179337Syongari
148179337Syongari    def test_equal(self):
149179337Syongari        """Ensure equivalence operators work on Type."""
150179337Syongari        source = 'int a; int b; void *v;'
151179337Syongari        tu = get_tu(source)
152179337Syongari
153179337Syongari        a = get_cursor(tu, 'a')
154179337Syongari        b = get_cursor(tu, 'b')
155179337Syongari        v = get_cursor(tu, 'v')
156179337Syongari
157179337Syongari        self.assertIsNotNone(a)
158179337Syongari        self.assertIsNotNone(b)
159179337Syongari        self.assertIsNotNone(v)
160179337Syongari
161179337Syongari        self.assertEqual(a.type, b.type)
162179337Syongari        self.assertNotEqual(a.type, v.type)
163179337Syongari
164179337Syongari        self.assertNotEqual(a.type, None)
165179337Syongari        self.assertNotEqual(a.type, 'foo')
166179337Syongari
167179337Syongari    def test_type_spelling(self):
168179337Syongari        """Ensure Type.spelling works."""
169179337Syongari        tu = get_tu('int c[5]; void f(int i[]); int x; int v[x];')
170179337Syongari        c = get_cursor(tu, 'c')
171179337Syongari        i = get_cursor(tu, 'i')
172179337Syongari        x = get_cursor(tu, 'x')
173179337Syongari        v = get_cursor(tu, 'v')
174179337Syongari        self.assertIsNotNone(c)
175179337Syongari        self.assertIsNotNone(i)
176179337Syongari        self.assertIsNotNone(x)
177179337Syongari        self.assertIsNotNone(v)
178179337Syongari        self.assertEqual(c.type.spelling, "int [5]")
179179337Syongari        self.assertEqual(i.type.spelling, "int []")
180179337Syongari        self.assertEqual(x.type.spelling, "int")
181179337Syongari        self.assertEqual(v.type.spelling, "int [x]")
182179337Syongari
183179337Syongari    def test_typekind_spelling(self):
184179337Syongari        """Ensure TypeKind.spelling works."""
185179337Syongari        tu = get_tu('int a;')
186179337Syongari        a = get_cursor(tu, 'a')
187179337Syongari
188179337Syongari        self.assertIsNotNone(a)
189179337Syongari        self.assertEqual(a.type.kind.spelling, 'Int')
190179337Syongari
191179337Syongari    def test_function_argument_types(self):
192179337Syongari        """Ensure that Type.argument_types() works as expected."""
193179337Syongari        tu = get_tu('void f(int, int);')
194179337Syongari        f = get_cursor(tu, 'f')
195179337Syongari        self.assertIsNotNone(f)
196179337Syongari
197179337Syongari        args = f.type.argument_types()
198179337Syongari        self.assertIsNotNone(args)
199179337Syongari        self.assertEqual(len(args), 2)
200179337Syongari
201179337Syongari        t0 = args[0]
202179337Syongari        self.assertIsNotNone(t0)
203179337Syongari        self.assertEqual(t0.kind, TypeKind.INT)
204179337Syongari
205179337Syongari        t1 = args[1]
206179337Syongari        self.assertIsNotNone(t1)
207179337Syongari        self.assertEqual(t1.kind, TypeKind.INT)
208179337Syongari
209179337Syongari        args2 = list(args)
210179337Syongari        self.assertEqual(len(args2), 2)
211179337Syongari        self.assertEqual(t0, args2[0])
212179337Syongari        self.assertEqual(t1, args2[1])
213179337Syongari
214179337Syongari    def test_argument_types_string_key(self):
215179337Syongari        """Ensure that non-int keys raise a TypeError."""
216179337Syongari        tu = get_tu('void f(int, int);')
217179337Syongari        f = get_cursor(tu, 'f')
218179337Syongari        self.assertIsNotNone(f)
219179337Syongari
220179337Syongari        args = f.type.argument_types()
221179337Syongari        self.assertEqual(len(args), 2)
222179337Syongari
223179337Syongari        with self.assertRaises(TypeError):
224179337Syongari            args['foo']
225179337Syongari
226179337Syongari    def test_argument_types_negative_index(self):
227179337Syongari        """Ensure that negative indexes on argument_types Raises an IndexError."""
228179337Syongari        tu = get_tu('void f(int, int);')
229179337Syongari        f = get_cursor(tu, 'f')
230179337Syongari        args = f.type.argument_types()
231179337Syongari
232179337Syongari        with self.assertRaises(IndexError):
233179337Syongari            args[-1]
234179337Syongari
235179337Syongari    def test_argument_types_overflow_index(self):
236179337Syongari        """Ensure that indexes beyond the length of Type.argument_types() raise."""
237179337Syongari        tu = get_tu('void f(int, int);')
238179337Syongari        f = get_cursor(tu, 'f')
239179337Syongari        args = f.type.argument_types()
240179337Syongari
241179337Syongari        with self.assertRaises(IndexError):
242179337Syongari            args[2]
243179337Syongari
244179337Syongari    def test_argument_types_invalid_type(self):
245179337Syongari        """Ensure that obtaining argument_types on a Type without them raises."""
246179337Syongari        tu = get_tu('int i;')
247179337Syongari        i = get_cursor(tu, 'i')
248179337Syongari        self.assertIsNotNone(i)
249179337Syongari
250179337Syongari        with self.assertRaises(Exception):
251179337Syongari            i.type.argument_types()
252179337Syongari
253179337Syongari    def test_is_pod(self):
254179337Syongari        """Ensure Type.is_pod() works."""
255179337Syongari        tu = get_tu('int i; void f();')
256179337Syongari        i = get_cursor(tu, 'i')
257179337Syongari        f = get_cursor(tu, 'f')
258179337Syongari
259179337Syongari        self.assertIsNotNone(i)
260179337Syongari        self.assertIsNotNone(f)
261179337Syongari
262179337Syongari        self.assertTrue(i.type.is_pod())
263179337Syongari        self.assertFalse(f.type.is_pod())
264179337Syongari
265179337Syongari    def test_function_variadic(self):
266179337Syongari        """Ensure Type.is_function_variadic works."""
267179337Syongari
268179337Syongari        source ="""
269179337Syongari#include <stdarg.h>
270179337Syongari
271179337Syongari    void foo(int a, ...);
272179337Syongari    void bar(int a, int b);
273179337Syongari    """
274179337Syongari
275179337Syongari        tu = get_tu(source)
276179337Syongari        foo = get_cursor(tu, 'foo')
277179337Syongari        bar = get_cursor(tu, 'bar')
278179337Syongari
279179337Syongari        self.assertIsNotNone(foo)
280179337Syongari        self.assertIsNotNone(bar)
281179337Syongari
282179337Syongari        self.assertIsInstance(foo.type.is_function_variadic(), bool)
283179337Syongari        self.assertTrue(foo.type.is_function_variadic())
284179337Syongari        self.assertFalse(bar.type.is_function_variadic())
285179337Syongari
286179337Syongari    def test_element_type(self):
287179337Syongari        """Ensure Type.element_type works."""
288179337Syongari        tu = get_tu('int c[5]; void f(int i[]); int x; int v[x];')
289179337Syongari        c = get_cursor(tu, 'c')
290179337Syongari        i = get_cursor(tu, 'i')
291179337Syongari        v = get_cursor(tu, 'v')
292179337Syongari        self.assertIsNotNone(c)
293179337Syongari        self.assertIsNotNone(i)
294179337Syongari        self.assertIsNotNone(v)
295179337Syongari
296179337Syongari        self.assertEqual(c.type.kind, TypeKind.CONSTANTARRAY)
297179337Syongari        self.assertEqual(c.type.element_type.kind, TypeKind.INT)
298179337Syongari        self.assertEqual(i.type.kind, TypeKind.INCOMPLETEARRAY)
299179337Syongari        self.assertEqual(i.type.element_type.kind, TypeKind.INT)
300179337Syongari        self.assertEqual(v.type.kind, TypeKind.VARIABLEARRAY)
301179337Syongari        self.assertEqual(v.type.element_type.kind, TypeKind.INT)
302179337Syongari
303179337Syongari    def test_invalid_element_type(self):
304179337Syongari        """Ensure Type.element_type raises if type doesn't have elements."""
305179337Syongari        tu = get_tu('int i;')
306179337Syongari        i = get_cursor(tu, 'i')
307179337Syongari        self.assertIsNotNone(i)
308179337Syongari        with self.assertRaises(Exception):
309179337Syongari            i.element_type
310179337Syongari
311179337Syongari    def test_element_count(self):
312179337Syongari        """Ensure Type.element_count works."""
313179337Syongari        tu = get_tu('int i[5]; int j;')
314179337Syongari        i = get_cursor(tu, 'i')
315179337Syongari        j = get_cursor(tu, 'j')
316179337Syongari
317179337Syongari        self.assertIsNotNone(i)
318179337Syongari        self.assertIsNotNone(j)
319179337Syongari
320179337Syongari        self.assertEqual(i.type.element_count, 5)
321179337Syongari
322179337Syongari        with self.assertRaises(Exception):
323179337Syongari            j.type.element_count
324179337Syongari
325179337Syongari    def test_is_volatile_qualified(self):
326179337Syongari        """Ensure Type.is_volatile_qualified works."""
327179337Syongari
328179337Syongari        tu = get_tu('volatile int i = 4; int j = 2;')
329179337Syongari
330179337Syongari        i = get_cursor(tu, 'i')
331179337Syongari        j = get_cursor(tu, 'j')
332179337Syongari
333179337Syongari        self.assertIsNotNone(i)
334179337Syongari        self.assertIsNotNone(j)
335179337Syongari
336179337Syongari        self.assertIsInstance(i.type.is_volatile_qualified(), bool)
337179337Syongari        self.assertTrue(i.type.is_volatile_qualified())
338179337Syongari        self.assertFalse(j.type.is_volatile_qualified())
339179337Syongari
340179337Syongari    def test_is_restrict_qualified(self):
341179337Syongari        """Ensure Type.is_restrict_qualified works."""
342179337Syongari
343179337Syongari        tu = get_tu('struct s { void * restrict i; void * j; };')
344179337Syongari
345179337Syongari        i = get_cursor(tu, 'i')
346179337Syongari        j = get_cursor(tu, 'j')
347179337Syongari
348179337Syongari        self.assertIsNotNone(i)
349179337Syongari        self.assertIsNotNone(j)
350179337Syongari
351179337Syongari        self.assertIsInstance(i.type.is_restrict_qualified(), bool)
352179337Syongari        self.assertTrue(i.type.is_restrict_qualified())
353179337Syongari        self.assertFalse(j.type.is_restrict_qualified())
354179337Syongari
355179337Syongari    def test_record_layout(self):
356179337Syongari        """Ensure Cursor.type.get_size, Cursor.type.get_align and
357179337Syongari        Cursor.type.get_offset works."""
358179337Syongari
359179337Syongari        source ="""
360179337Syongari    struct a {
361179337Syongari        long a1;
362179337Syongari        long a2:3;
363179337Syongari        long a3:4;
364179337Syongari        long long a4;
365179337Syongari    };
366179337Syongari    """
367179337Syongari        tries=[(['-target','i386-linux-gnu'],(4,16,0,32,35,64)),
368179337Syongari               (['-target','nvptx64-unknown-unknown'],(8,24,0,64,67,128)),
369179337Syongari               (['-target','i386-pc-win32'],(8,16,0,32,35,64)),
370179337Syongari               (['-target','msp430-none-none'],(2,14,0,32,35,48))]
371179337Syongari        for flags, values in tries:
372179337Syongari            align,total,a1,a2,a3,a4 = values
373179337Syongari
374179337Syongari            tu = get_tu(source, flags=flags)
375179337Syongari            teststruct = get_cursor(tu, 'a')
376179337Syongari            fields = list(teststruct.get_children())
377179337Syongari
378179337Syongari            self.assertEqual(teststruct.type.get_align(), align)
379179337Syongari            self.assertEqual(teststruct.type.get_size(), total)
380179337Syongari            self.assertEqual(teststruct.type.get_offset(fields[0].spelling), a1)
381179337Syongari            self.assertEqual(teststruct.type.get_offset(fields[1].spelling), a2)
382179337Syongari            self.assertEqual(teststruct.type.get_offset(fields[2].spelling), a3)
383179337Syongari            self.assertEqual(teststruct.type.get_offset(fields[3].spelling), a4)
384179337Syongari            self.assertEqual(fields[0].is_bitfield(), False)
385179337Syongari            self.assertEqual(fields[1].is_bitfield(), True)
386179337Syongari            self.assertEqual(fields[1].get_bitfield_width(), 3)
387179337Syongari            self.assertEqual(fields[2].is_bitfield(), True)
388179337Syongari            self.assertEqual(fields[2].get_bitfield_width(), 4)
389179337Syongari            self.assertEqual(fields[3].is_bitfield(), False)
390179337Syongari
391179337Syongari    def test_offset(self):
392179337Syongari        """Ensure Cursor.get_record_field_offset works in anonymous records"""
393179337Syongari        source="""
394179337Syongari    struct Test {
395179337Syongari      struct {int a;} typeanon;
396179337Syongari      struct {
397179337Syongari        int bariton;
398179337Syongari        union {
399179337Syongari          int foo;
400179337Syongari        };
401179337Syongari      };
402179337Syongari      int bar;
403179337Syongari    };"""
404179337Syongari        tries=[(['-target','i386-linux-gnu'],(4,16,0,32,64,96)),
405179337Syongari               (['-target','nvptx64-unknown-unknown'],(8,24,0,32,64,96)),
406179337Syongari               (['-target','i386-pc-win32'],(8,16,0,32,64,96)),
407179337Syongari               (['-target','msp430-none-none'],(2,14,0,32,64,96))]
408179337Syongari        for flags, values in tries:
409179337Syongari            align,total,f1,bariton,foo,bar = values
410179337Syongari            tu = get_tu(source)
411179337Syongari            teststruct = get_cursor(tu, 'Test')
412179337Syongari            children = list(teststruct.get_children())
413179337Syongari            fields = list(teststruct.type.get_fields())
414179337Syongari            self.assertEqual(children[0].kind, CursorKind.STRUCT_DECL)
415179337Syongari            self.assertNotEqual(children[0].spelling, "typeanon")
416179337Syongari            self.assertEqual(children[1].spelling, "typeanon")
417179337Syongari            self.assertEqual(fields[0].kind, CursorKind.FIELD_DECL)
418179337Syongari            self.assertEqual(fields[1].kind, CursorKind.FIELD_DECL)
419179337Syongari            self.assertTrue(fields[1].is_anonymous())
420179337Syongari            self.assertEqual(teststruct.type.get_offset("typeanon"), f1)
421179337Syongari            self.assertEqual(teststruct.type.get_offset("bariton"), bariton)
422179337Syongari            self.assertEqual(teststruct.type.get_offset("foo"), foo)
423179337Syongari            self.assertEqual(teststruct.type.get_offset("bar"), bar)
424179337Syongari
425179337Syongari    def test_decay(self):
426179337Syongari        """Ensure decayed types are handled as the original type"""
427179337Syongari
428179337Syongari        tu = get_tu("void foo(int a[]);")
429179337Syongari        foo = get_cursor(tu, 'foo')
430179337Syongari        a = foo.type.argument_types()[0]
431179337Syongari
432179337Syongari        self.assertEqual(a.kind, TypeKind.INCOMPLETEARRAY)
433179337Syongari        self.assertEqual(a.element_type.kind, TypeKind.INT)
434179337Syongari        self.assertEqual(a.get_canonical().kind, TypeKind.INCOMPLETEARRAY)
435179337Syongari
436179337Syongari    def test_addrspace(self):
437179337Syongari        """Ensure the address space can be queried"""
438179337Syongari        tu = get_tu('__attribute__((address_space(2))) int testInteger = 3;', 'c')
439179337Syongari
440179337Syongari        testInteger = get_cursor(tu, 'testInteger')
441179337Syongari
442179337Syongari        self.assertIsNotNone(testInteger, "Could not find testInteger.")
443179337Syongari        self.assertEqual(testInteger.type.get_address_space(), 2)
444179337Syongari
445179337Syongari    def test_template_arguments(self):
446179337Syongari        source = """
447179337Syongari        class Foo {
448179337Syongari        };
449179337Syongari        template <typename T>
450179337Syongari        class Template {
451179337Syongari        };
452179337Syongari        Template<Foo> instance;
453179337Syongari        int bar;
454179337Syongari        """
455179337Syongari        tu = get_tu(source, lang='cpp')
456179337Syongari
457179337Syongari        # Varible with a template argument.
458179337Syongari        cursor = get_cursor(tu, 'instance')
459179337Syongari        cursor_type = cursor.type
460179337Syongari        self.assertEqual(cursor.kind, CursorKind.VAR_DECL)
461179337Syongari        self.assertEqual(cursor_type.spelling, 'Template<Foo>')
462179337Syongari        self.assertEqual(cursor_type.get_num_template_arguments(), 1)
463179337Syongari        template_type = cursor_type.get_template_argument_type(0)
464179337Syongari        self.assertEqual(template_type.spelling, 'Foo')
465179337Syongari
466179337Syongari        # Variable without a template argument.
467179337Syongari        cursor = get_cursor(tu, 'bar')
468179337Syongari        self.assertEqual(cursor.get_num_template_arguments(), -1)
469179337Syongari