| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320 |
- function libclangParse2sqlite(dbname, source_file_name, ...)
- {
- auto db = SQLite3(dbname);
- db.exec_dml([==[
- CREATE TABLE IF NOT EXISTS function_file (
- id INTEGER PRIMARY KEY,
- file_name VARCHAR UNIQUE NOT NULL
- );
- ]==]);
- db.exec_dml([==[
- CREATE TABLE IF NOT EXISTS function_declaration (
- id INTEGER PRIMARY KEY,
- name VARCHAR NOT NULL,
- ftype VARCHAR NOT NULL,
- return_type VARCHAR NOT NULL,
- linkage_type INTEGER,
- file_id INTEGER NOT NULL REFERENCES function_file(id),
- line INTEGER,
- col INTEGER,
- UNIQUE(file_id, name, line, col)
- );
- ]==]);
- db.exec_dml([==[
- CREATE INDEX IF NOT EXISTS function_declaration_name_file_idx ON function_declaration(name, file_id);
- ]==]);
- db.exec_dml([==[
- CREATE TABLE IF NOT EXISTS function_param (
- id INTEGER PRIMARY KEY,
- function_id INTEGER NOT NULL REFERENCES function_declaration(id),
- name VARCHAR,
- type VARCHAR NOT NULL,
- kind_id INTEGER,
- UNIQUE(function_id, name)
- );
- ]==]);
- db.exec_dml([==[
- CREATE TABLE IF NOT EXISTS function_calling (
- id INTEGER PRIMARY KEY,
- caller_id INTEGER NOT NULL REFERENCES function_declaration(id),
- callee_id INTEGER NOT NULL REFERENCES function_declaration(id),
- file_id INTEGER NOT NULL REFERENCES function_file(id),
- line INTEGER,
- col INTEGER,
- UNIQUE(file_id, caller_id, callee_id, line, col)
- );
- ]==]);
- db.exec_dml([==[
- CREATE INDEX IF NOT EXISTS function_calling_caller_idx ON function_calling(caller_id);
- CREATE INDEX IF NOT EXISTS function_calling_callee_idx ON function_calling(callee_id);
- ]==]);
- auto stmt_get_file_id = db.prepare("SELECT id FROM function_file WHERE file_name = ?;");
- auto stmt_get_func_decl_id = db.prepare("SELECT id FROM function_declaration WHERE file_id = ? AND name=? AND line=? AND col=?;");
- auto stmt_insert_file = db.prepare("INSERT OR IGNORE INTO function_file (file_name) VALUES (?);");
- auto stmt_insert_function = db.prepare("INSERT OR IGNORE INTO function_declaration (name, ftype, return_type, linkage_type, file_id, line, col) VALUES (?, ?, ?, ?, ?, ?, ?);");
- auto stmt_insert_call = db.prepare("INSERT OR IGNORE INTO function_calling (caller_id, callee_id, file_id, line, col) VALUES (?, ?, ?, ?, ?);");
- auto stmt_insert_param = db.prepare("INSERT OR IGNORE INTO function_param (function_id, name, type, kind_id) VALUES (?, ?, ?, ?);");
- local function cleanBackwardPath(path)
- {
- while(path.find("/../") > 0)
- {
- path = path.gsub("/[^/.]+/%.%.", "");
- }
- return path;
- }
- local function add_funcfile(file_name)
- {
- local id = null;
- file_name = cleanBackwardPath(file_name);
-
- stmt_get_file_id.bind(1, file_name);
- if (stmt_get_file_id.next_row()) {
- id = stmt_get_file_id.col(0);
- }
- stmt_get_file_id.reset();
- if(id) {
- return id;
- }
- stmt_insert_file.bind(1, file_name);
- local rc = stmt_insert_file.step();
- if (rc != db.SQLITE_DONE) {
- print("Can't insert: %d : %s\n", rc, db.errmsg());
- os.exit(-1);
- }
- stmt_insert_file.reset();
- return db.last_row_id();
- }
- local function add_funcdecl(file_name, line, col, func_name, func_type, return_type, linkage_type)
- {
- local file_id = add_funcfile(file_name);
- stmt_insert_function.bind(1, func_name);
- stmt_insert_function.bind(2, func_type);
- stmt_insert_function.bind(3, return_type);
- stmt_insert_function.bind(4, linkage_type);
- stmt_insert_function.bind(5, file_id);
- stmt_insert_function.bind(6, line);
- stmt_insert_function.bind(7, col);
- local rc = stmt_insert_function.step();
- if (rc != db.SQLITE_DONE) {
- print("Can't insert: %d : %s\n", rc, db.errmsg());
- os.exit(-1);
- }
- stmt_insert_function.reset();
- }
- local function get_func_decl_id(file_id, func_name, line, col)
- {
- local id = null;
- stmt_get_func_decl_id.bind(1, file_id);
- stmt_get_func_decl_id.bind(2, func_name);
- stmt_get_func_decl_id.bind(3, line);
- stmt_get_func_decl_id.bind(4, col);
- if (stmt_get_func_decl_id.next_row()) {
- id = stmt_get_func_decl_id.col(0);
- }
- stmt_get_func_decl_id.reset();
- return id;
- }
- local function add_funcparam(file_name, line, col, func_name, param_name, param_type, type_kind)
- {
- local file_id = add_funcfile(file_name);
- local func_id = get_func_decl_id(file_id, func_name, line, col);
- stmt_insert_param.bind(1, func_id);
- stmt_insert_param.bind(2, param_name);
- stmt_insert_param.bind(3, param_type);
- stmt_insert_param.bind(4, type_kind);
- local rc = stmt_insert_param.step();
- if (rc != db.SQLITE_DONE) {
- print("Can't insert: %d : %s\n", rc, db.errmsg());
- os.exit(-1);
- }
- stmt_insert_param.reset();
- }
- local function add_funccall(file_name, line, col, from_func, from_line, from_col, to_func_file, to_func_line, to_func_col, to_func)
- {
- local file_id = add_funcfile(file_name);
- local from_func_id = get_func_decl_id(file_id, from_func, from_line, from_col);
-
- local to_file_id = add_funcfile(to_func_file);
- local to_func_id = get_func_decl_id(to_file_id, to_func, to_func_line, to_func_col);
-
- stmt_insert_call.bind(1, from_func_id);
- stmt_insert_call.bind(2, to_func_id);
- stmt_insert_call.bind(3, file_id);
- stmt_insert_call.bind(4, line);
- stmt_insert_call.bind(5, col);
- local rc = stmt_insert_call.step();
- if (rc != db.SQLITE_DONE) {
- print("Can't insert: %d : %s\n", rc, db.errmsg());
- os.exit(-1);
- }
- stmt_insert_call.reset();
- }
- db.exec_dml("BEGIN;");
- auto libclang = new LibClang();
- local function libclangVisitor(...)
- {
- //print("Hello!");
- //print(vargv.join("\t"));
- //try
- {
- local vtype = vargv[0];
- switch(vtype)
- {
- case "CallExpr":
- //vtype, file_name, line, col, from_func, from_line, from_col, to_func_file, to_func_line, to_func_col, to_func
- add_funccall(vargv[1], vargv[2], vargv[3], vargv[4], vargv[5], vargv[6], vargv[7], vargv[8], vargv[9], vargv[10]);
- break;
- case "FuncDecl":
- //vtype, file_name, line, col, func_name, func_type, return_type, linkage_type
- add_funcdecl(vargv[1], vargv[2], vargv[3], vargv[4], vargv[5], vargv[6], vargv[7]);
- break;
- case "FuncParam":
- //vtype, file_name, line, col, func_name, param_name, param_type, type_kind
- add_funcparam(vargv[1], vargv[2], vargv[3], vargv[4], vargv[5], vargv[6], vargv[7]);
- break;
- }
- }
- //catch(e)
- {
- //print(e);
- }
- }
- //libclang.parseTranslationUnit(libclangVisitor, source_file_name, "-I.", "-I/home/mingo/local/clang-3.6/include");
- auto call_args = [libclang, libclangVisitor, source_file_name];
- foreach(p in vargv)
- {
- call_args.append(p);
- }
- libclang.parseTranslationUnit.acall(call_args);
- libclang.close();
- db.exec_dml([==[
- CREATE VIEW IF NOT EXISTS "function_calling_list_view" AS
- SELECT
- a."id",
- d.name AS caller,
- c.name AS callee,
- b.file_name,
- a."line",
- a."col",
- a."caller_id",
- a."callee_id",
- a."file_id"
- FROM "function_calling" AS a
- LEFT JOIN "function_file" AS b ON a."file_id" = b."id"
- LEFT JOIN "function_declaration" AS c ON a."callee_id" = c."id"
- LEFT JOIN "function_declaration" AS d ON a."caller_id" = d."id";
- CREATE VIEW IF NOT EXISTS "function_declaration_list_view" AS
- SELECT
- a."id",
- a."name",
- a."ftype",
- a."return_type",
- a."linkage_type",
- b.file_name,
- a."line",
- a."col",
- a."file_id"
- FROM "function_declaration" AS a
- LEFT JOIN "function_file" AS b ON a."file_id" = b."id";
- CREATE VIEW IF NOT EXISTS "function_param_list_view" AS
- SELECT
- a."id",
- b."name" AS function_name,
- a."name" AS param_name,
- a."type",
- a."kind_id",
- a."function_id"
- FROM "function_param" AS a
- LEFT JOIN "function_declaration" AS b ON a."function_id" = b."id";
- CREATE VIEW IF NOT EXISTS function_calling_count_view AS
- SELECT b.id, b.name, COUNT(*) AS calls, c.file_name
- FROM function_calling a
- LEFT JOIN function_declaration b
- ON a.callee_id = b.id
- LEFT JOIN function_file c
- ON b.file_id = c.id
- GROUP BY a.callee_id
- ORDER BY 3 DESC, 2 ASC;
- ]==]);
- /*
- db.exec_dml([==[
- CREATE VIEW IF NOT EXISTS functions_of_interest_view AS
- WITH
- source_file AS(
- SELECT id FROM function_file WHERE file_name = 'SOURCE_FILE_NAME'
- )
- SELECT caller_id as fid FROM function_calling a, source_file as b WHERE a.file_id = b.id
- UNION
- SELECT callee_id as fid FROM function_calling a, source_file as b WHERE a.file_id = b.id
- UNION
- SELECT a.id as fid FROM function_declaration a, source_file as b WHERE a.file_id = b.id;
- ]==].gsub("SOURCE_FILE_NAME", source_file_name));
- db.exec_dml([==[
- -- remove function parameter not in use
- DELETE FROM function_param
- WHERE function_id NOT IN(
- SELECT fid FROM functions_of_interest_view
- );
- -- remove functio_declaration not in use
- DELETE FROM function_declaration
- WHERE id NOT IN(
- SELECT fid FROM functions_of_interest_view
- );
- -- remove function_file not in use
- DELETE FROM function_file
- WHERE id NOT IN(
- SELECT DISTINCT file_id FROM function_declaration
- );
- ]==]);
- */
- db.exec_dml("COMMIT;");
- stmt_insert_param.finalize();
- stmt_insert_call.finalize();
- stmt_insert_function.finalize();
- stmt_get_func_decl_id.finalize();
- stmt_insert_file.finalize();
- stmt_get_file_id.finalize();
- db.close();
- }
- //libclangParse2sqlite("c2sqlite.db", "c2sqlite.c", "-I.", "-I/home/mingo/local/clang-3.6/include");
|