首先需搭建LLVM/Clang开发环境并配置CMake,接着通过继承ASTFrontendAction定义MallocFindAction,使用MatchFinder结合AST Matcher查找名为"malloc"的函数调用,匹配结果在MallocCallHandler::run中处理并输出位置信息,主函数利用CommonOptionsParser解析参数后通过ClangTool运行自定义Action,最终实现基于AST的静态分析工具。

想用C++基于LLVM/Clang的LibTooling写一个自己的静态分析工具,核心是利用Clang提供的AST(抽象语法树)遍历和匹配能力来识别代码中的特定模式。整个过程不复杂,但需要理解Clang的架构和LibTooling的基本使用方式。
你需要先准备好LLVM和Clang的开发环境:
提示:可以从LLVM源码的examples/目录找参考,比如HowToUseLibTooling。
LibTooling的核心是定义一个FrontendAction,在其中注册对AST的操作。通常你会继承ASTFrontendAction,并在CreateASTConsumer中返回一个自定义的ASTConsumer。
立即学习“C++免费学习笔记(深入)”;
更推荐使用MatchFinder配合声明式匹配规则(AST Matchers),它能让你用类似正则的方式描述代码结构。
示例:查找所有函数调用表达式中名为 "malloc" 的调用
class MallocCallHandler : public MatchFinder::MatchCallback {
public:
virtual void run(const MatchFinder::MatchResult &Result) {
const CallExpr *Call = Result.Nodes.getNodeAs<CallExpr>("mallocCall");
const FunctionDecl *Func = Result.Nodes.getNodeAs<FunctionDecl>("func");
if (Call && Func) {
SourceManager &SM = *Result.SourceManager;
llvm::outs() << "Found malloc call in function: " << Func->getName()
<< " at " << SM.getSpellingLineNumber(Call->getBeginLoc())
<< ":" << SM.getSpellingColumnNumber(Call->getBeginLoc())
<< "\n";
}
}
};
class MallocFindAction : public ASTFrontendAction {
public:
MallocFindAction() {}
std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
StringRef file) override {
std::unique_ptr<ASTConsumer> Consumer = std::make_unique<ASTConsumer>();
Finder.addMatcher(
callExpr(callee(functionDecl(hasName("malloc")))).bind("mallocCall"),
&Handler
);
return Consumer;
}
void ExecuteAction() override {
// 获取当前编译单元的ASTContext
ASTContext &Context = getCompilerInstance().getASTContext();
Finder.matchAST(Context);
}
private:
MallocCallHandler Handler;
MatchFinder Finder;
};主函数中使用CommonOptionsParser解析命令行参数,然后创建ClangTool并运行你的Action。
int main(int argc, const char **argv) {
CommonOptionsParser OptionsParser(argc, argv, llvm::cl::GeneralCategory);
ClangTool Tool(OptionsParser.getCompilations(),
OptionsParser.getSourcePathList());
MallocFindActionFactory Factory; // 需要包装成Factory
return Tool.run(&Factory);
}注意:ClangTool::run需要的是FrontendActionFactory,你可以用newFrontendActionFactory
除了匹配简单调用,你还可以:
你可以把匹配器写得非常精确,比如只匹配全局作用域下的函数,或排除系统头文件中的调用:
callExpr(
callee(functionDecl(hasName("malloc"))),
unless(isExpansionInSystemHeader())
).bind("mallocCall")基本上就这些。写一个基础的静态分析工具,关键在于掌握AST结构、熟悉常用Matcher,并通过回调提取所需信息。后续可以逐步加入诊断报告(DiagnosticBuilder)、修复建议(FixItHint)等功能,变成完整的Clang-Tidy式检查。
以上就是c++++如何使用LLVM/Clang LibTooling_c++编写自己的静态分析工具的详细内容,更多请关注php中文网其它相关文章!
c++怎么学习?c++怎么入门?c++在哪学?c++怎么学才快?不用担心,这里为大家提供了c++速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号