aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSergio Martins <sergio.martins@kdab.com>2019-06-10 14:44:33 +0100
committerSergio Martins <sergio.martins@kdab.com>2019-06-10 14:44:33 +0100
commit3901d72b120a4c1d80a42a22610fdebb35d27c45 (patch)
treee16788ca8f4b2c177c10a091ecd26e44bda2416b
parente50222c243b9eb067a319393b6a858de55a7e565 (diff)
WIP: Start processing the AST
-rwxr-xr-xdev-scripts/miniAstDumper.py75
-rw-r--r--src/MiniAstDumper.cpp59
2 files changed, 99 insertions, 35 deletions
diff --git a/dev-scripts/miniAstDumper.py b/dev-scripts/miniAstDumper.py
index 8f6652aa..e16acd4e 100755
--- a/dev-scripts/miniAstDumper.py
+++ b/dev-scripts/miniAstDumper.py
@@ -1,11 +1,24 @@
#!/usr/bin/env python
-import cbor, sys, time
+import cbor, sys, time, os
+
+class SourceLocation:
+ def __init__(self):
+ self.filename = ""
+ self.lineNumber = -1
+ self.columnNumber = -1
+
+ def asString(self):
+ return self.filename + ":" + str(self.lineNumber) + ":" + str(self.columnNumber)
+
+ def dump(self):
+ print(self.asString())
class FunctionCall:
def __init__(self):
self.callee_name = ""
+ self.loc_start = SourceLocation()
class CXXMethod:
def __init__(self):
@@ -28,6 +41,21 @@ class GlobalAST:
_globalAST = GlobalAST()
+def parse_loc(cborLoc, file_map, tu_cwd):
+ loc = SourceLocation()
+ loc.filename = file_map[str(cborLoc['fileId'])]
+
+ # Make absolute
+ if not loc.filename.startswith('/'): # TODO windows
+ loc.filename = tu_cwd + '/' + loc.filename
+
+ # Normalize
+ loc.filename = os.path.normpath(loc.filename)
+
+ loc.lineNumber = cborLoc['line']
+ loc.columnNumber = cborLoc['column']
+ return loc
+
def read_file(filename):
f = open(filename, 'rb')
contents = f.read()
@@ -41,36 +69,67 @@ def read_cbor(filename):
def load_cbor(filename, globalAST):
cborData = read_cbor(filename)
+ file_map = {}
+
+ current_tu_cwd = cborData['cwd']
+
+ # populate the file map
+ if 'files' in cborData:
+ for fileId in cborData['files'].keys():
+ file_map[fileId] = cborData['files'][fileId]
+
+
if 'stuff' in cborData:
for stuff in cborData['stuff']:
if 'type' in stuff:
if stuff['type'] == 31: # CXXRecordDecl
cxxclass = CXXClass()
- cxxclass.id = stuff['id']
+ # cxxclass.id = stuff['id']
cxxclass.qualified_name = stuff['name']
if 'methods' in stuff:
for m in stuff['methods']:
method = CXXMethod()
- methods.id = m['id']
- methods.qualified_name = m['name']
+ method.id = m['id']
+ method.qualified_name = m['name']
cxxclass.methods.append(method)
-
-
globalAST.cxx_classes.append(cxxclass)
elif stuff['type'] == 48: # CallExpr
funccall = FunctionCall()
funccall.callee_name = stuff['calleeName']
+ funccall.loc_start = parse_loc(stuff['loc'], file_map, current_tu_cwd)
globalAST.function_calls.append(funccall)
+def get_class_by_name(qualified_name):
+ result = []
+ for c in _globalAST.cxx_classes:
+ if c.qualified_name == qualified_name:
+ result.append(c)
+ return result
+def get_calls_by_name(callee_name):
+ result = []
+ for f in _globalAST.function_calls:
+ if f.callee_name == callee_name:
+ result.append(f)
+ return result
load_cbor(sys.argv[1], _globalAST)
+#string_class = get_class_by_name("QString")[0]
+
+for f in get_calls_by_name("QObject::connect"):
+ print(f.loc_start.dump())
+
+#for f in _globalAST.function_calls:
+ # print(f.callee_name)
+
+#for m in string_class.methods:
+ # print(m.qualified_name)
-for c in _globalAST.cxx_classes:
- print(c.qualified_name)
+#for c in _globalAST.cxx_classes:
+ # print(c.qualified_name)
#print(cborData)
diff --git a/src/MiniAstDumper.cpp b/src/MiniAstDumper.cpp
index d1a44772..a53b5fb7 100644
--- a/src/MiniAstDumper.cpp
+++ b/src/MiniAstDumper.cpp
@@ -29,6 +29,8 @@
#include <clang/Frontend/FrontendPluginRegistry.h>
#include <fstream>
+#include <unistd.h>
+#include <limits.h>
using namespace clang;
using namespace std;
@@ -58,21 +60,26 @@ MiniASTDumperConsumer::MiniASTDumperConsumer(CompilerInstance &ci)
m_cborBuf = reinterpret_cast<uint8_t*>(malloc(m_bufferSize));
cbor_encoder_init(&m_cborEncoder, m_cborBuf, m_bufferSize, 0);
- cbor_encoder_create_map(&m_cborEncoder, &m_cborRootMapEncoder, 3);
- cbor_encode_text_stringz(&m_cborRootMapEncoder, "tu");
- cbor_encode_text_stringz(&m_cborRootMapEncoder, m_currentCppFile.c_str());
- cbor_encode_text_stringz(&m_cborRootMapEncoder, "stuff");
- cbor_encoder_create_array(&m_cborRootMapEncoder, &m_cborStuffArray, CborIndefiniteLength);
+ cborCreateMap(&m_cborEncoder, &m_cborRootMapEncoder, 4);
+ cborEncodeString(m_cborRootMapEncoder, "tu");
+ cborEncodeString(m_cborRootMapEncoder, m_currentCppFile.c_str());
+
+ char cwd[4096]; // TODO: Just use std::filesystem::current_path
+ cborEncodeString(m_cborRootMapEncoder, "cwd");
+ cborEncodeString(m_cborRootMapEncoder, std::string(getcwd(cwd, sizeof(cwd))).c_str());
+
+ cborEncodeString(m_cborRootMapEncoder, "stuff");
+ cborCreateArray(&m_cborRootMapEncoder, &m_cborStuffArray, CborIndefiniteLength);
}
MiniASTDumperConsumer::~MiniASTDumperConsumer()
{
- cbor_encoder_close_container(&m_cborRootMapEncoder, &m_cborStuffArray);
+ cborCloseContainer(&m_cborRootMapEncoder, &m_cborStuffArray);
- cbor_encode_text_stringz(&m_cborRootMapEncoder, "files");
+ cborEncodeString(m_cborRootMapEncoder, "files");
dumpFileMap(&m_cborRootMapEncoder);
- cbor_encoder_close_container(&m_cborEncoder, &m_cborRootMapEncoder);
+ cborCloseContainer(&m_cborEncoder, &m_cborRootMapEncoder);
size_t size = cbor_encoder_get_buffer_size(&m_cborEncoder, m_cborBuf);
@@ -135,7 +142,7 @@ void MiniASTDumperConsumer::HandleTranslationUnit(ASTContext &ctx)
void MiniASTDumperConsumer::dumpCXXMethodDecl(CXXMethodDecl *method, CborEncoder *encoder)
{
CborEncoder recordMap;
- cbor_encoder_create_map(encoder, &recordMap, 2);
+ cborCreateMap(encoder, &recordMap, 2);
cborEncodeString(recordMap, "name");
cborEncodeString(recordMap, method->getQualifiedNameAsString().c_str());
@@ -143,13 +150,13 @@ void MiniASTDumperConsumer::dumpCXXMethodDecl(CXXMethodDecl *method, CborEncoder
cborEncodeString(recordMap, "id");
cborEncodeInt(recordMap, int64_t(method));
- cbor_encoder_close_container(encoder, &recordMap);
+ cborCloseContainer(encoder, &recordMap);
}
void MiniASTDumperConsumer::dumpCXXRecordDecl(CXXRecordDecl *rec, CborEncoder *encoder)
{
CborEncoder recordMap;
- cbor_encoder_create_map(encoder, &recordMap, CborIndefiniteLength);
+ cborCreateMap(encoder, &recordMap, CborIndefiniteLength);
cborEncodeString(recordMap, "type");
cborEncodeInt(recordMap, rec->getDeclKind());
@@ -157,51 +164,49 @@ void MiniASTDumperConsumer::dumpCXXRecordDecl(CXXRecordDecl *rec, CborEncoder *e
cborEncodeString(recordMap, "name");
cborEncodeString(recordMap, rec->getQualifiedNameAsString().c_str());
- cborEncodeString(recordMap, "id");
- cborEncodeInt(recordMap, int64_t(rec));
-
cborEncodeString(recordMap, "loc");
dumpLocation(clazy::getLocStart(rec), &recordMap);
if (clazy::isQObject(rec)) { // TODO: Use flags
cborEncodeString(recordMap, "isQObject");
- cbor_encode_boolean(&recordMap, true);
+ cborEncodeBool(recordMap, true);
}
cborEncodeString(recordMap, "methods");
CborEncoder cborMethodList;
- cbor_encoder_create_array(&recordMap, &cborMethodList, CborIndefiniteLength);
+ cborCreateArray(&recordMap, &cborMethodList, CborIndefiniteLength);
for (auto method : rec->methods()) {
dumpCXXMethodDecl(method, &cborMethodList);
}
- cbor_encoder_close_container(encoder, &cborMethodList);*/
- cbor_encoder_close_container(&m_cborStuffArray, &recordMap);
+ cborCloseContainer(&recordMap, &cborMethodList);
+ cborCloseContainer(&m_cborStuffArray, &recordMap);
}
void MiniASTDumperConsumer::dumpCallExpr(CallExpr *callExpr, CborEncoder *encoder)
{
- if (!callExpr->getDirectCallee())
+ FunctionDecl *func = callExpr->getDirectCallee();
+ if (!func || !func->getDeclName().isIdentifier())
return;
CborEncoder callMap;
- cbor_encoder_create_map(encoder, &callMap, 3);
+ cborCreateMap(encoder, &callMap, 3);
- cborEncodeString(callMap, "type"); // TODO: replace with ID
+ cborEncodeString(callMap, "type");
cborEncodeInt(callMap, callExpr->getStmtClass());
cborEncodeString(callMap, "calleeName"); // TODO: replace with ID
- cborEncodeString(callMap, clazy::name(callExpr->getDirectCallee()).str().c_str());
+ cborEncodeString(callMap, func->getQualifiedNameAsString().c_str());
cborEncodeString(callMap, "loc");
dumpLocation(clazy::getLocStart(callExpr), &callMap);
- cbor_encoder_close_container(encoder, &callMap);
+ cborCloseContainer(encoder, &callMap);
}
void MiniASTDumperConsumer::dumpLocation(SourceLocation loc, CborEncoder *encoder)
{
CborEncoder locMap;
- cbor_encoder_create_map(encoder, &locMap, 3);
+ cborCreateMap(encoder, &locMap, 3);
auto &sm = m_ci.getSourceManager();
const FileID fileId = sm.getFileID(loc);
@@ -217,20 +222,20 @@ void MiniASTDumperConsumer::dumpLocation(SourceLocation loc, CborEncoder *encode
cborEncodeString(locMap, "column");
cborEncodeInt(locMap, ploc.getColumn());
- cbor_encoder_close_container(encoder, &locMap);
+ cborCloseContainer(encoder, &locMap);
}
void MiniASTDumperConsumer::dumpFileMap(CborEncoder *encoder)
{
CborEncoder fileMap;
- cbor_encoder_create_map(encoder, &fileMap, m_fileIds.size());
+ cborCreateMap(encoder, &fileMap, m_fileIds.size());
for (auto it : m_fileIds) {
cborEncodeString(fileMap, std::to_string(it.first).c_str());
cborEncodeString(fileMap, it.second.c_str());
}
- cbor_encoder_close_container(encoder, &fileMap);
+ cborCloseContainer(encoder, &fileMap);
}
void MiniASTDumperConsumer::cborEncodeString(CborEncoder &enc, const char *str)