shi*_*ing 79 c++ static-analysis call-graph
我正在尝试生成调用图,用它来找出所有可能执行特定函数的执行路径(这样我就不必手动计算出所有路径,因为有很多路径可以导致这个功能).例如:
path 1: A -> B -> C -> D
path 2: A -> B -> X -> Y -> D
path 3: A -> G -> M -> N -> O -> P -> S -> D
...
path n: ...
Run Code Online (Sandbox Code Playgroud)
我已经尝试过Codeviz和Doxygen,不知怎的,两个结果只显示目标函数的被调用者D.在我的例子中,D是一个类的成员函数,其对象将被包装在智能指针中.客户端将始终通过工厂获取智能指针对象以调用D.
有谁知道如何实现这一目标?
Joh*_*itb 109
static void D() { }
static void Y() { D(); }
static void X() { Y(); }
static void C() { D(); X(); }
static void B() { C(); }
static void S() { D(); }
static void P() { S(); }
static void O() { P(); }
static void N() { O(); }
static void M() { N(); }
static void G() { M(); }
static void A() { B(); G(); }
int main() {
A();
}
Run Code Online (Sandbox Code Playgroud)
然后
$ clang++ -S -emit-llvm main1.cpp -o - | opt -analyze -dot-callgraph
$ dot -Tpng -ocallgraph.png callgraph.dot
Run Code Online (Sandbox Code Playgroud)
产生一些闪亮的图片(有一个"外部节点",因为main有外部链接,也可能从外部调用翻译单元):

您可能希望对其进行后处理c++filt,以便您可以获取所涉及的函数和类的未编码名称.如下所示
#include <vector>
struct A {
A(int);
void f(); // not defined, prevents inlining it!
};
int main() {
std::vector<A> v;
v.push_back(42);
v[0].f();
}
$ clang++ -S -emit-llvm main1.cpp -o - |
opt -analyze -std-link-opts -dot-callgraph
$ cat callgraph.dot |
c++filt |
sed 's,>,\\>,g; s,-\\>,->,g; s,<,\\<,g' |
gawk '/external node/{id=$1} $1 != id' |
dot -Tpng -ocallgraph.png
Run Code Online (Sandbox Code Playgroud)
产生这种美丽(哦,我的,没有优化的尺寸太大了!)

这个神秘的未命名函数Node0x884c4e0是一个占位符,假定由任何定义未知的函数调用.
jpo*_*o38 15
你可以通过使用doxygen实现这一点(可以选择使用dot生成图形).
使用Johannes Schaub - litb main.cpp,它生成:
doxygen/dot可能比clang/opt更容易安装和运行.我没有设法自己安装它,这就是为什么我试图寻找替代解决方案!