compare-ast-clang-and-cppcheck: Added script that compares the clang and cppcheck AST. For now it only checks if the SymbolDatabase contains the proper function objects.
This commit is contained in:
parent
f44f726e10
commit
aff108a16f
|
@ -47,7 +47,7 @@ int main(int argc, char **argv)
|
||||||
unsigned int line, column;
|
unsigned int line, column;
|
||||||
clang_getPresumedLocation(location, &filename, &line, &column);
|
clang_getPresumedLocation(location, &filename, &line, &column);
|
||||||
|
|
||||||
std::cout << "<" << clang_getCursorKindSpelling(clang_getCursorKind(c))
|
std::cout << "<Function" /* << clang_getCursorKindSpelling(clang_getCursorKind(c)) */
|
||||||
<< " name=\"" << clang_getCursorSpelling(c) << '\"'
|
<< " name=\"" << clang_getCursorSpelling(c) << '\"'
|
||||||
<< " filename=\"" << filename << '\"'
|
<< " filename=\"" << filename << '\"'
|
||||||
<< " line=\"" << line << '\"'
|
<< " line=\"" << line << '\"'
|
||||||
|
|
|
@ -0,0 +1,79 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
#
|
||||||
|
# Compare the AST of Cppcheck and Clang
|
||||||
|
#
|
||||||
|
# Example usage:
|
||||||
|
# cd cppcheck/tools
|
||||||
|
# g++ `llvm-config-3.8 --cxxflags --ldflags` -lclang -o clang-ast clang-ast.cpp
|
||||||
|
# python compare-ast-clang-and-cppcheck.py lib/token.cpp
|
||||||
|
#
|
||||||
|
# If you get such output:
|
||||||
|
# - <Function...>
|
||||||
|
# Then that means there is a missing function in the Cppcheck SymbolDatabase
|
||||||
|
#
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
sys.path.insert(0, '../addons')
|
||||||
|
import cppcheckdata
|
||||||
|
|
||||||
|
CLANG_AST = './clang-ast'
|
||||||
|
CPPCHECK = '../cppcheck'
|
||||||
|
|
||||||
|
def clang_ast(sourcefile):
|
||||||
|
p = subprocess.Popen([CLANG_AST,sourcefile], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||||
|
comm = p.communicate()
|
||||||
|
ret = []
|
||||||
|
for line in comm[0].split('\n'):
|
||||||
|
while len(line)>1 and line[-1] in ' \r\n':
|
||||||
|
line = line[:-1]
|
||||||
|
if line.find('/usr/') > 0:
|
||||||
|
continue
|
||||||
|
if line.startswith('<Function'):
|
||||||
|
ret.append(line)
|
||||||
|
ret.sort()
|
||||||
|
return ret
|
||||||
|
|
||||||
|
|
||||||
|
def cppcheck_ast(sourcefile):
|
||||||
|
subprocess.call([CPPCHECK, '--dump', '--max-configs=1', sourcefile])
|
||||||
|
data = cppcheckdata.parsedump(sourcefile + '.dump')
|
||||||
|
cfg = data.configurations[0]
|
||||||
|
ret = []
|
||||||
|
for func in cfg.functions:
|
||||||
|
s = '<Function'
|
||||||
|
s = s + ' name="' + func.name + '"'
|
||||||
|
s = s + ' filename="' + func.tokenDef.file + '"'
|
||||||
|
s = s + ' line="' + str(func.tokenDef.linenr) + '"'
|
||||||
|
s = s + '/>'
|
||||||
|
ret.append(s)
|
||||||
|
for scope in cfg.scopes:
|
||||||
|
if scope.type != 'Function':
|
||||||
|
continue
|
||||||
|
argStart = scope.bodyStart
|
||||||
|
while argStart and argStart.str != '(':
|
||||||
|
argStart = argStart.previous
|
||||||
|
s = '<Function'
|
||||||
|
s = s + ' name="' + scope.className + '"'
|
||||||
|
s = s + ' filename="' + argStart.file + '"'
|
||||||
|
s = s + ' line="' + str(argStart.linenr) + '"'
|
||||||
|
s = s + '/>'
|
||||||
|
if s not in ret:
|
||||||
|
ret.append(s)
|
||||||
|
ret.sort()
|
||||||
|
return ret
|
||||||
|
|
||||||
|
print('Clang AST...')
|
||||||
|
ast1 = clang_ast(sys.argv[1])
|
||||||
|
print('Cppcheck AST...')
|
||||||
|
ast2 = cppcheck_ast(sys.argv[1])
|
||||||
|
|
||||||
|
#for func in ast2:
|
||||||
|
# print(func)
|
||||||
|
|
||||||
|
print('Compare...')
|
||||||
|
for func in ast1:
|
||||||
|
if func not in ast2:
|
||||||
|
print('- ' + func)
|
||||||
|
#for func in ast2:
|
||||||
|
# if func not in ast1:
|
||||||
|
# print('+ ' + func)
|
Loading…
Reference in New Issue