我正在尝试使用 Clang 查找输入源文件的源代码级别的所有循环。我的代码目前可以识别源文件中的 for 循环并打印出行号。它似乎也找到了 while 循环,但它没有打印出行号。
这是相关的代码片段。
for (auto it = sourceCFG->begin(); it != sourceCFG->end(); ++it)
{
CFGBlock *block = *it;
if (block->getLoopTarget())
{
const Stmt *stmt = block->getLoopTarget();
printf("Loop entry point: %d\n", block->getBlockID());
for (auto it2 = block->begin(); it2 != block->end(); ++it2)
{
CFGElement elem = *it2;
if (elem.getKind() == CFGElement::Kind::Statement)
{
const Stmt *stmt = elem.castAs<CFGStmt>().getStmt();
SourceRange range = stmt->getSourceRange();
SourceManager &sm = context->getSourceManager();
range.dump(sm);
}
else {
printf("never show up anything\n");
}
}
}
}
输出如下
Loop entry point: 1
</home/weifan/llvm-tools/clang+llvm-16.0.3-x86_64-linux-gnu-ubuntu-22.04/test_bare_loops.cpp:50:17, col:18>
Loop entry point: 2
Loop entry point: 10
Loop entry point: 12
Loop entry point: 20
</home/weifan/llvm-tools/clang+llvm-16.0.3-x86_64-linux-gnu-ubuntu-22.04/test_bare_loops.cpp:26:17, col:18>
Loop entry point: 21
</home/weifan/llvm-tools/clang+llvm-16.0.3-x86_64-linux-gnu-ubuntu-22.04/test_bare_loops.cpp:27:18, col:19>
Loop entry point: 29
Loop entry point: 35
</home/weifan/llvm-tools/clang+llvm-16.0.3-x86_64-linux-gnu-ubuntu-
22.04/test_bare_loops.cpp:8:18, col:19>
我已经验证了SourceManager提供的行号的for循环入口点是一个for循环。 SourceManager 不提供的其余部分应该是 while 循环。另外,如果我使用
sourceCFG->dump()
,我确实可以看到一些CFGBlocks没有关联的代码片段,如下所示
[B2]
Preds (1): B3
Succs (1): B7
我在垃圾场里也没有看到任何
while
。
所以我的问题是:
非常感谢!
我对 clang/llvm/c++ 还很陌生
好吧,我太笨了,没有意识到我应该立即打电话给
SourceManager
,将Stmt
转储到const Stmt *stmt = block->getLoopTarget();
。这也会揭示 while 循环。