Reputation: 59
I am using pycparser to parse a C code. My goal is that given a C code and a function name, list out all the functions called in the specified function.
I looked at the documentation for the pycparser but I couldn't find anything to solve specifically this problem.
I want the same functionality as 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 *
Upvotes: 0
Views: 942
Reputation: 11
Nested visitor will do. Visit FuncCall in FuncDef Visitor like below.
your code will visit only 1-depth 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
Upvotes: 1
Reputation: 59
I solved it. The below visitor class prints each function call for all the functions in the code base
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}")
Upvotes: 0