Получение всех функций, вызываемых в указанной функции - PullRequest
0 голосов
/ 09 июля 2019

Я использую pycparser для разбора кода C. Моя цель состоит в том, чтобы, учитывая код C и имя функции, перечислить все функции, вызываемые в указанной функции.

Я посмотрел документацию для pycparser, но не смог найти ничего, что решило бы именно эту проблему.

Я хочу использовать ту же функциональность, что и cscope:

Functions called by this function: ksw_extd2_sse41

  File             Function          Line
0 ksw2_extd2_sse.c ksw_reset_extz     59 ksw_reset_extz(ez);
1 ksw2_extd2_sse.c _mm_set1_epi8      64 zero_ = _mm_set1_epi8(0);
2 ksw2_extd2_sse.c _mm_set1_epi8      65 q_ = _mm_set1_epi8(q);
3 ksw2_extd2_sse.c _mm_set1_epi8      66 q2_ = _mm_set1_epi8(q2);
4 ksw2_extd2_sse.c _mm_set1_epi8      67 qe_ = _mm_set1_epi8(q + e);
5 ksw2_extd2_sse.c _mm_set1_epi8      68 qe2_ = _mm_set1_epi8(q2 + e2);
6 ksw2_extd2_sse.c _mm_set1_epi8      69 sc_mch_ = _mm_set1_epi8(mat[0]);
7 ksw2_extd2_sse.c _mm_set1_epi8      70 sc_mis_ = _mm_set1_epi8(mat[1]);
8 ksw2_extd2_sse.c _mm_set1_epi8      71 sc_N_ = mat[m*m-1] == 0? _mm_set1_epi8(-e2) : _mm_set1_epi8(mat[m*m-1]);
9 ksw2_extd2_sse.c _mm_set1_epi8      72 m1_ = _mm_set1_epi8(m - 1);
a ksw2_extd2_sse.c kcalloc            92 mem = (uint8_t*)kcalloc(km, tlen_ * 8 + qlen_ + 1, 16);
b ksw2_extd2_sse.c memset             97 memset(u, -q - e, tlen_ * 16);
c ksw2_extd2_sse.c memset             98 memset(v, -q - e, tlen_ * 16);
d ksw2_extd2_sse.c memset             99 memset(x, -q - e, tlen_ * 16);
e ksw2_extd2_sse.c memset            100 memset(y, -q - e, tlen_ * 16);

* Lines 1-16 of 278, 263 more - press the space bar to display more *

Ответы [ 2 ]

1 голос
/ 14 июля 2019

Вложенный посетитель будет делать. Посетите FuncCall в FuncDef Visitor, как показано ниже.

Ваш код будет посещать только 1-й глубинный funccall.

class FuncCallVisitor(c_ast.NodeVisitor):
    def __init__(self):
        self.callees = []  
    def visit_FuncCall(self, node):
        self.callees.append(node.name.name)

        # nested funccall
        if node.args:
            self.visit(node.args)

class FuncDefVisitor(c_ast.NodeVisitor):
    def visit_FuncDef(self, node):
        fcv = FuncCallVisitor()
        fcv.visit(node.body)

        print(fcv.callees) # calles has all funccall in this funcdef
0 голосов
/ 10 июля 2019

Я решил это.Приведенный ниже класс посетителя печатает каждый вызов функции для всех функций в базе кода

class Visitor(c_ast.NodeVisitor):
    def visit_FuncDef(self, node):
        for stmt in node.body.block_items or []:
            if isinstance(stmt, c_ast.FuncCall):
                print (f"Function {node.decl.name} calls {stmt.name.name}")
...