tools; remove old script for comparing cppcheck and clang asts
This commit is contained in:
parent
79b9dd5345
commit
417bc5c732
|
@ -1,101 +0,0 @@
|
||||||
// Dump the AST for a file.
|
|
||||||
//
|
|
||||||
// Compile with:
|
|
||||||
// g++ `llvm-config-3.8 --cxxflags --ldflags` -lclang -o clang-ast clang-ast.cpp
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <cstdlib>
|
|
||||||
#include <clang-c/Index.h>
|
|
||||||
|
|
||||||
std::ostream& operator<<(std::ostream& stream, const CXString& str)
|
|
||||||
{
|
|
||||||
stream << clang_getCString(str);
|
|
||||||
clang_disposeString(str);
|
|
||||||
return stream;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
if (argc == 1) {
|
|
||||||
std::cerr << "No source file\n";
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *argv1[] = { argv[0], "-std=c++11" };
|
|
||||||
|
|
||||||
CXIndex index = clang_createIndex(0, 0);
|
|
||||||
CXTranslationUnit unit = clang_parseTranslationUnit(
|
|
||||||
index,
|
|
||||||
argv[1], argv1, sizeof(argv1) / sizeof(argv1[0]),
|
|
||||||
nullptr, 0,
|
|
||||||
CXTranslationUnit_None);
|
|
||||||
if (unit == nullptr) {
|
|
||||||
std::cerr << "Unable to parse translation unit. Quitting." << std::endl;
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::cout << "<?xml version=\"1.0\"?>\n"
|
|
||||||
<< "<clang-ast>\n";
|
|
||||||
|
|
||||||
CXCursor cursor = clang_getTranslationUnitCursor(unit);
|
|
||||||
clang_visitChildren(
|
|
||||||
cursor,
|
|
||||||
[](CXCursor c, CXCursor parent, CXClientData client_data) {
|
|
||||||
switch (clang_getCursorKind(c)) {
|
|
||||||
case CXCursor_FunctionDecl:
|
|
||||||
case CXCursor_Constructor:
|
|
||||||
case CXCursor_Destructor:
|
|
||||||
case CXCursor_CXXMethod: {
|
|
||||||
CXSourceLocation location = clang_getCursorLocation(c);
|
|
||||||
CXString filename;
|
|
||||||
unsigned int line, column;
|
|
||||||
clang_getPresumedLocation(location, &filename, &line, &column);
|
|
||||||
|
|
||||||
std::cout << "<Function" /* << clang_getCursorKindSpelling(clang_getCursorKind(c)) */
|
|
||||||
<< " name=\"" << clang_getCursorSpelling(c) << '\"'
|
|
||||||
<< " filename=\"" << filename << '\"'
|
|
||||||
<< " line=\"" << line << '\"'
|
|
||||||
// << " column=\"" << column << '\"'
|
|
||||||
<< "/>\n";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case CXCursor_CallExpr: {
|
|
||||||
CXSourceLocation location = clang_getCursorLocation(c);
|
|
||||||
CXString filename;
|
|
||||||
unsigned int line, column;
|
|
||||||
clang_getPresumedLocation(location, &filename, &line, &column);
|
|
||||||
|
|
||||||
CXCursor ref = clang_getCursorReferenced(c);
|
|
||||||
CXSourceLocation locationRef = clang_getCursorLocation(ref);
|
|
||||||
CXString filenameRef;
|
|
||||||
unsigned int lineRef, columnRef;
|
|
||||||
clang_getPresumedLocation(locationRef, &filenameRef, &lineRef, &columnRef);
|
|
||||||
|
|
||||||
std::cout << "<CallExpr"
|
|
||||||
<< " name=\"" << clang_getCursorSpelling(c) << '\"'
|
|
||||||
<< " filename=\"" << filename << '\"'
|
|
||||||
<< " line=\"" << line << '\"'
|
|
||||||
// << " column=\"" << column << '\"'
|
|
||||||
<< " filenameRef=\"" << filenameRef << '\"'
|
|
||||||
<< " lineRef=\"" << lineRef << '\"'
|
|
||||||
<< "/>\n";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
//std::cout << "<" << clang_getCursorKindSpelling(clang_getCursorKind(c)) << " kind=\"" << clang_getCursorKind(c) << "\"/>\n";
|
|
||||||
break;
|
|
||||||
};
|
|
||||||
|
|
||||||
return CXChildVisit_Recurse;
|
|
||||||
},
|
|
||||||
nullptr);
|
|
||||||
|
|
||||||
std::cout << "</clang-ast>\n";
|
|
||||||
|
|
||||||
clang_disposeTranslationUnit(unit);
|
|
||||||
clang_disposeIndex(index);
|
|
||||||
|
|
||||||
return EXIT_SUCCESS;
|
|
||||||
}
|
|
|
@ -1,88 +0,0 @@
|
||||||
#!/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:
|
|
||||||
name = func.name
|
|
||||||
if func.type == 'Destructor':
|
|
||||||
name = '~' + name
|
|
||||||
s = '<Function'
|
|
||||||
s = s + ' name="' + 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...')
|
|
||||||
numberOfMissing = 0
|
|
||||||
numberOfExtra = 0
|
|
||||||
for func in ast1:
|
|
||||||
if func not in ast2:
|
|
||||||
numberOfMissing = numberOfMissing + 1
|
|
||||||
print('Missing Function ' + func)
|
|
||||||
for func in ast2:
|
|
||||||
if func not in ast1:
|
|
||||||
numberOfExtra = numberOfExtra + 1
|
|
||||||
print('Extra Function ' + func)
|
|
||||||
print('Number of missing functions: ' + str(numberOfMissing))
|
|
||||||
print('Number of extra functions: ' + str(numberOfExtra) + ' (clang AST currently only contains FunctionDecl and CXXMethod)')
|
|
Loading…
Reference in New Issue