1from clang.cindex import *
2
3def tu_from_source(source, all_warnings=False):
4    args = []
5    if all_warnings:
6        args = ['-Wall', '-Wextra']
7
8    index = Index.create()
9    tu = index.parse('INPUT.c', args=args,
10            unsaved_files = [('INPUT.c', source)])
11    return tu
12
13# FIXME: We need support for invalid translation units to test better.
14
15def test_diagnostic_warning():
16    tu = tu_from_source("""int f0() {}\n""")
17    assert len(tu.diagnostics) == 1
18    assert tu.diagnostics[0].severity == Diagnostic.Warning
19    assert tu.diagnostics[0].location.line == 1
20    assert tu.diagnostics[0].location.column == 11
21    assert (tu.diagnostics[0].spelling ==
22            'control reaches end of non-void function')
23
24def test_diagnostic_note():
25    # FIXME: We aren't getting notes here for some reason.
26    index = Index.create()
27    tu = tu_from_source("""#define A x\nvoid *A = 1;\n""")
28    assert len(tu.diagnostics) == 1
29    assert tu.diagnostics[0].severity == Diagnostic.Warning
30    assert tu.diagnostics[0].location.line == 2
31    assert tu.diagnostics[0].location.column == 7
32    assert 'incompatible' in tu.diagnostics[0].spelling
33#    assert tu.diagnostics[1].severity == Diagnostic.Note
34#    assert tu.diagnostics[1].location.line == 1
35#    assert tu.diagnostics[1].location.column == 11
36#    assert tu.diagnostics[1].spelling == 'instantiated from'
37
38def test_diagnostic_fixit():
39    index = Index.create()
40    tu = tu_from_source("""struct { int f0; } x = { f0 : 1 };""")
41    assert len(tu.diagnostics) == 1
42    assert tu.diagnostics[0].severity == Diagnostic.Warning
43    assert tu.diagnostics[0].location.line == 1
44    assert tu.diagnostics[0].location.column == 26
45    assert tu.diagnostics[0].spelling.startswith('use of GNU old-style')
46    assert len(tu.diagnostics[0].fixits) == 1
47    assert tu.diagnostics[0].fixits[0].range.start.line == 1
48    assert tu.diagnostics[0].fixits[0].range.start.column == 26
49    assert tu.diagnostics[0].fixits[0].range.end.line == 1
50    assert tu.diagnostics[0].fixits[0].range.end.column == 30
51    assert tu.diagnostics[0].fixits[0].value == '.f0 = '
52
53def test_diagnostic_range():
54    index = Index.create()
55    tu = tu_from_source("""void f() { int i = "a" + 1; }""")
56    assert len(tu.diagnostics) == 1
57    assert tu.diagnostics[0].severity == Diagnostic.Warning
58    assert tu.diagnostics[0].location.line == 1
59    assert tu.diagnostics[0].location.column == 16
60    assert tu.diagnostics[0].spelling.startswith('incompatible pointer to')
61    assert len(tu.diagnostics[0].fixits) == 0
62    assert len(tu.diagnostics[0].ranges) == 1
63    assert tu.diagnostics[0].ranges[0].start.line == 1
64    assert tu.diagnostics[0].ranges[0].start.column == 20
65    assert tu.diagnostics[0].ranges[0].end.line == 1
66    assert tu.diagnostics[0].ranges[0].end.column == 27
67    try:
68      tu.diagnostics[0].ranges[1].start.line
69    except IndexError:
70      assert True
71    else:
72      assert False
73
74def test_diagnostic_category():
75    # Ensure that category properties work.
76    index = Index.create()
77    tu = tu_from_source("""int f(int i) { return 7; }""", all_warnings=True)
78    assert len(tu.diagnostics) == 1
79    d = tu.diagnostics[0]
80
81    assert d.severity == Diagnostic.Warning
82    assert d.location.line == 1
83    assert d.location.column == 11
84
85    assert d.category_number == 2
86    assert d.category_name == 'Semantic Issue'
87
88def test_diagnostic_option():
89    # Ensure that category option properties work.
90    index = Index.create()
91    tu = tu_from_source("""int f(int i) { return 7; }""", all_warnings=True)
92    assert len(tu.diagnostics) == 1
93    d = tu.diagnostics[0]
94
95    assert d.option == '-Wunused-parameter'
96    assert d.disable_option == '-Wno-unused-parameter'
97
98